Linux scsi command queue - linux

I'm a newbie here at this forum. I'm currently stuck with a problem.
I'm a beginner to Linux kernel drivers, and currently involved in developing a Linux SCSI device driver for a block mass storage device. The development platform is on a high-end machine with Fedora 14. The setup is 1 host to one LU/device. To make the long story short, the driver is working in the sense that it initializes without problems, it can detect the device and send scsi frames to it, it can read and write to the device, and I can do stable Iometer read and write tests through the driver. All of that when there is only 1 outstanding command at a time (no queueing).
The problem is, I couldn't get queuing to work. The upper SCSI layers doesn't send me (LLD) more than one commands to be outstanding unless I scsi_done() the first command. I expect that the upper layer can call queuecommand() more than once before I send the commands to the device for processing, then for the device to interrupt me for the response and for LLD to close the command with scsi_done(). Without queuing, our speed is very slow.
I've already tweaked values I thought are connected to queuing, like setting .can_queue and .cmd_per_lun to my target queue_depth in both scsi_host and scsi_host_template. Basically I've played with various values including 1, but to no avail. I also did disable and enable tagging if this has any effect, but still no change. So far I don't remember doing much with scsi_device in the driver, except in slave_configure. Is there anything I'm missing and can still do in driver level? I can't believe Linux would have no support for command queuing. I'm missing something here.

Related

How to get the usage record of USB device on Linux

I want to write a linux inspection tool to check the usb device usage records on a certain machine. Parsing the dmesg method can obtain the usb usage record from the system startup to the present, and does not use dmesg -c to clear the dmesg information. So the point of the question is whether there is a place on the Linux system that records all USB usage records in the system, just like the Windows system writes this in the registry.
Linux doesn't natively provide this functionality. It isn't seen as an intrinsically important feature to have, and as mentioned, it can be done easily with a udev rule for those who want it. It's generally assumed that anyone with physical access to the machine can read any unencrypted data on it and execute arbitrary code on it if it's running, so logging USB devices isn't really an effective security measure.
If you want to see the recent history, you can check the kernel log (often /var/log/kern.log) to read the recent and older entries that the kernel has output when a USB device has been inserted. Do note that these are rotated periodically, so they won't provide the entire history of the system.

How to keep wifi link up when an embedded linux device suspends to RAM

Environment:
I have an embedded linux system running with an ARM based iMX7 processor. It runs on a build from yocto linux which is very much based on Fedora.
Scenario:
My system uses Suspend To RAM feature which is linux system power saving mode that is explained quite well in this link. This is done to save power at a certain stage.
Objective:
Now, I need to keep the wifi link open during this stage. And as I read from some discussions like this, it seems to be possible to do so.
How can I do this?
Read up on similar discussions:
Reading through this discussion, it explains how to do this on a intel based desktop linux computer. But I don't have the /etc/NetworkManager on my embedded linux device. Probably there is a different way to do it on a Fedora based embdded linux system.
Can I get some suggestions on how to do this or even how to approach this?
None of the articles you quoted even suggest that it is possible to leave WiFi on - in fact one of them says it can't be done. All they provide is various tricks to make the wake-up faster.
Depends on the hardware but very likely, leaving it on is really impossible. Suspend-to-ram includes a hardware command that switches the CPU clock off, places its interconnect buses into idle state, and disables main power to all the peripherals (leaving only standby power to those peripherals that support standby mode).
I don't know if your WiFi device has support for running on standby power nor whether the embedded hardware you have has the ability to provide that power to it while the CPU is off. If that ability exists, it will likely be accessible as a kernel driver parameter.
You may be able to save some startup time when waking up from standby by providing a static configuration for your WiFi device rather than using the default automatic connection (which involves searching for a router to connect to, obtaining an IP address, etc.).
You can't just keep wifi active during sleep/resume. You can optimise reconnection speed but I believe NM and connman both do that already.

What causes Linux to issue a CLEAR_TT_BUFFER command?

I'm writing a library that interfaces to a Full Speed USB device using libusb. It seens to be working fine, but when I run the code inside GDB or Valgrind, I see in Wireshark that there are CLEAR_TT_BUFFER commands being send to the USB hub (I presume it's the internal one, since I have the device directly attached to the PC), and some packets seem to be lost (this shouldn't happen, as I'm using bulk transfer).
So the question is, what (under which conditions) is issuing those commands, and how do I prevent/detect them?

Is there a way to ask the Linux Kernel to re-run its PCI initialization code?

I'm looking for either a kernel mode call that I can make from a driver, a userland utility, or a system call that will ask the Kernel to look at the PCI bus and either completely re-run its initialization, or initialize a specific device. Specifically, I need the Kernel to recognize a device that was added to the bus after boot and then configure its address space, interrupt, and other configuration parameters, and finally enable the device so that I can load the driver for it (unless this all happens as part of the driver load).
I'm stuck on the 2.4.x series Kernel for this, and am currently working with 2.4.20, but will be moving to 2.4.37 if it matters. The distro is a stripped down Red Hat 7.3 running in a ram disk, but I can add in whatever tools are needed to get this working (as long as they play nice with 2.4 series).
If some background would help clarify what I'm trying to do: From a cold boot, once in Linux I use GPIO to program an FPGA. Part of the FPGA, once programmed, implements a simple PCI device. Currently, after programming the FPGA, I reboot the system and Linux recognizes the device after coming up and loads the driver for it.
Instead of needing that reboot, I'd like to simply ask the Kernel to do whatever it does during boot up to find PCI devices (I have the Kernel configured to find PCI devices on its own, instead of asking the BIOS for that information, so the BIOS won't need to know about this device (I hope)).
I believe that Linux is capable of seeing the device after it is programmed but before a reboot, because scanpci will show the device after I program it, as will lspci -H 1. I just need a way to get it into /proc/pci, configured and enabled.
This below command will help the user to rescan it complete root hub.
echo "1" > /sys/class/pci_bus/0000\:00/rescan
You could speed up the reboot with kexec, if you don't figure out how to get the PCI scan redone. You could ask this on the LKML, if you haven't already.
unloading/reloading the module doesn't help, does it?
http://www.linuxjournal.com/article/5633 suggests you should be able to do it with 2.4 kernels using pcihpfs.
If that isn't working, maybe the driver doesn't support hotplug?
It would probably crash the system if you reconfigured the addresses of other PCI devices while they are in use.
A better way would be to just configure the new card. If your kernel has support for Cardus devices, it already knows how to configure a newly-inserted PCI device (which is what Cardbus is). You just need to figure out how to get the kernel to do it...
It should be possible for a kernel module to do this. Even if you can't get built-in hotplug code, you should be able to set the pci resources using calls to pci_bus_write_config_dword() and friends. There is probably some IRQ routing setup to do as well.

Problem reading from a device with libusb

The situation is this: I have a USB device (a custom device I'm trying to talk to) with two endpoints, one writing to the device, one reading from the device. Both are bulk transfers. Every communication transaction takes the form of (1) Write a command to the device (2) Read the response. I'm using libusb (version 0.1 rather than the 1.0 beta) to actually perform the communications.
On Windows, all is well. I can connect the device, claim the interface and communicate happily. However, in Ubuntu (a standard Hardy desktop install), whilst I can connect to the device and write to it, all read operations fail with the error "error submitting URB: Invalid argument" reported from libusb (error code -22).
If I check /var/log/messages I see a warning message logged for the same time as the read was attempted: "sysfs: duplicate filename 'usbdev4.3_ep81' can not be created" - which tallies with the device (it is indeed on that bus and it's endpoint 81 I'm trying to read from).
So... anyone seen a similar problem using libusb, or have any idea how to fix it?
Turns out it was a misconfiguration in the descriptors on the device itself. lsusb -v showed an extra interface which was never used, which had a single isochronous endpoint 0x81. Since this was never used (and had never been tested as far as I could see, so quite possibly not even defined correctly) I removed it from the device descriptors completely (in the firmware).
And now I have a fully working device. Why linux refused to read from the device but Windows worked fine I don't know, but it definitely sent me on a wild goose chase.
I haven't used libusb in quite some time -- but the sysfs error indicates that this is likely to be a kernel problem rather than a libusb one, so I'd start by trying to track that one down. (Not much point in trying to work with libusb until you're sure your kernel is talking to the device correctly).
Does the patch at http://kerneltrap.org/mailarchive/linux-usb-devel/2007/10/17/345922 apply to your kernel? (If so, does it fix the issue?)
I had to do some hacking to udev rules to get the device created with the right permissions for libusb to work. Like so:
SUBSYSTEM=="usb" ATTRS{idVendor}=="0a81", ATTRS{idProduct}=="0701", \
MODE="0666" SYMLINK+="missile_launcher"
(This was an usb missile launcher I was writing a driver for.
Also this snippet was required to not clash with the kernel.
if(LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP)
{
// Detach kernel driver (usbhid) from device interface. (Linux hack)
usb_detach_kernel_driver_np(launcher, 0);
usb_detach_kernel_driver_np(launcher, 1);
}
I'm not sure how this relates to your problem, but atleast there are two possible points of failure that might be involved.
You can try WinDriver it's a commercial tool but have free full function evaluation (somehow time limited). You can check with WinDriver and if problem is reproducible it's might be device or your protocol fault. You did not give enough information to determine or analyze.

Resources