Last updated 11 April 2008.
The scope of this project is to develop a driver which will allow use of USB devices which report themselves to be in the USB Mass Storage class. This generally includes, but is not limited to, hard drives, CD-ROMs, floppy drives, and flash readers. Also, support for non-class-compliant devices will be added as documentation becomes available from vendors.
Support for USB Mass Storage class devices under Linux is stable, but (as with all of the Linux kernel) is always under constant development. However, there are no known significant issues at this time.
Note that, since USB devices can be removed at any time, the integrity of your data is not guaranteed. Always be sure to umount and sync your device before disconnecting it.
There are several devices on the market which one would expect to be in the Mass Storage class, but they are not. Some of these devices are supported, while support for others are still pending. Please see the section below on Tested Hardware for more details.
Many people have asked about USB 2.0 support. USB 2.0 increases the speed of the bus, but does not change the logical protocol used to communicate with target devices. Thus, specification compliant USB 2.0 targets (such as those based around the ISD-300 chip) work perfectly with the existing usb-storage driver. Users do, however, need a driver for the USB 2.0 controller card -- those drivers are available in current kernels.
The design and implementation of the usb-storage driver is, at best, less than clear. While the comments in the code explain what is being done, it is almost never clear why it is being done that way. Some common questions are addressed here. Someday, someone will put together a 'Design Philosophy' page.
The basic theory is that when a device is attached, a control thread is spawned to handle it. That thread is registered as a virtual SCSI controller, and the SCSI core and top-level drivers probe for devices.
The threads used to be persistant across device insertion/removal, along with the SCSI node, in 2.4.x kernels. This is done so that a device which is removed can be re-attached and be granted the same /dev node as before, creating persistance between connections of the target unit.
In 2.6.x kernels, the control threads are no longer persistent. They are created and destroyed (along with the SCSI data structures and device nodes) as devices are inserted and removed.
At this point, experienced kernel hackers will be wondering why a thread is used instead of a 'bottom-half' handler. Good question. The basic answer is this: It's easier to see the communication flow with the target when using a thread. Any given transaction with a device (a READ_10 command, for example) can involve more than 20 different USB requests. Yes, it could be done another way... but this is how I decided to do it.
The control thread gets commands from the SCSI mid-layer code. The control thread takes this command and, after sanity checking several things, sends the command to the 'protocol' handler. This handler is responsible for re-writing the command (if necessary) into a form which the device will accept. For example, ATAPI devices do not support 6-byte commands. Thus, they must be re-written into 10-byte variants.
Once the protocol handler has re-written the command, it is sent to the transport handler. This section of the code is responsible for sending the command to the device, exchanging data, and then getting the status of the device. Note that betweent the protocol handler and the transport handler is a small piece of code which attempts to determine if a REQUEST_SENSE command should be issued.
After the command has been handled, the scsi_done() function is called to signal the SCSI layers that the command has been completed. We're ready for our next command.
Complicating the picture slightly are:
It is clear to me (from my experience) that the testing performed on many USB target devices centers around interoperability with either MacOS or a Microsoft product. Unfortunately, this means that many fully-legal behaviors which are fully supported by the specification are not properly handled. This means that these devices do not work with Linux.
To avoid this, I offer two things. First, device vendors can send me pre-production units for testing to determine if their unit works with Linux and, if not, what needs to be changed. This service is generally available at little or no cost for simple testing and reporting. I am also available as a paid consultant for larger projects.
The second thing I offer is this: A list of bad behaviors I've seen from targets. I originally put this list together for the USB-IF Mass Storage Working Group. However, it is of value to all device vendors.
This is a sample list of some of the devices I have in my collection; this list is not exhaustive. These devices get most of my attention. Since they are in my possession, I am able to develop, test, and release relatively quickly. Note that these work to varying degrees. Some of these do not work at all yet, but may be supported in later versions of the driver.
Please note that devices in this category are somewhat second-class. Without having the device in my possession, it is very difficult to test and debug. However, they have been tested to at least some degree.
For a user-maintained database of tested devices (with comments), please see the Working Device List.
I would like to thank the following corporations for their support, either via technical information, product samples, or both.
The usb-storage driver is maintained by Matthew Dharm (mdharm-usb (at) one-eyed-alien.net) with the assistance of the members of the usb-storage mailing list, located at usb-storage (at) lists.one-eyed-alien.net. This list is archived in public by pipermail. End-user questions should be directed to the general linux-usb mailing list, located at linux-usb-users (at) lists.sourceforge.net. If you would like to assist in development, please contact the usb-storage mailing list.
Some people who have also contributed code to this project are:
The source code is provided with the standard linux kernel distribution.