David Brownell
<dbrownell@users.sourceforge.net>
Last Update:
24 June 2003
This is a short writeup explaining what USB 2.0 changed and what's going on with it in Linux. It starts by talking about user visible changes (including usbfs information) followed by driver-visible ones. Finally it summarizes the current state of Linux USB 2.0 driver support in recent 2.4 and 2.5 kernels. If you want assistance getting this working on your hardware, try the linux-usb-users (or linux-usb-devel) mailing lists at http://www.linux-usb.org.
If you're a 2.4 user, use 2.4.22-pre1 or later. That closely matches the Linux 2.6.0-test EHCI code, which seems to resolve the worst problems reported. (VT6202 problems still seem to remain, especially on 2.4 kernels.) Remember this is still classified as 'experimental'.
Some older Linux distributions ship 2.4.18 kernels with EHCI code based on much older code, similar to what was in 2.5.2; the newer code supports more hardware, fixes bugs, is smaller, and has other goodness. In 2003, distributions with more current drivers are also available.
You should probably know that "USB" is an abbreviation of the Universal Serial Bus, which is widely used for peripherals in modern desktop systems. (It's not "universal" in the sense that you'd want it instead of HyperTransport!) PCs typically support one or more USB controllers (one per "USB bus") each of which can support up to 127 different devices. "Legacy free" PCs omit non-USB peripheral support (like RS-232 serial lines, and PS/2 ports). USB is asymmetric, even at the level of its cabling (so you can't hook things up incorrectly), and it supports "hotplugging" for all its peripherals (so you don't have to configure them by hand). Those features both help reduce end-user setup and configuration problems, which was a major goal for USB technology.
Today, most devices and systems support USB version 1.1, which supported two device speeds: low speed at 1.5 Mbit/sec, and full speed at 12 Mbit/sec. USB 2.0 is appearing in current product designs, and one of its main features is adding a new speed: high speed, at 480 Mbit/sec.
To put it another way: USB 1.1 was OK for low speed devices like mice and keyboards, and even for medium speed ones like Ethernet (10 Mbit/sec) adapters, or consumer electronics gadgets that only exchange a few megabytes of data (like many digital still cameras and MP3 players). USB 2.0 "full speed" or "low speed" is effectively just the familiar old "USB 1.1". You need USB 2.0 high speed to get reasonable speed for multiple large transfers as with some PC peripherals like disk drives (including MP3 jukeboxes :) or high resolution webcams (USB video), or get concurrent use from a bunch of 100BaseT networking adapters.
OK, it's faster! ... but what else will a Linux user notice about USB 2.0? We'll go from the outside in: starting from what you'll see with product boxes, and then working toward what you'll see with normal Linux user mode tools. (More technical details are in later sections.) One thing you won't notice is designed-in compatibility problems. Apart from some constraints on how you set up high speed devices, all your USB 1.1 hardware works just fine with USB 2.0 systems.
One thing that you should watch for, and use to your advantage, is a new testing and branding program. Earlier USB devices sometimes had compatibility problems, and the tighter electrical requirements of USB 2.0 could have aggravated that issue. Instead, there are new USB 2.0 logos and a testing program that must be passed before devices are allowed to use them. That is, this isn't purely a marketing gimmick, there's actually some value wrapped up in this logo. Here are the new and old USB logos:
![]() |
New USB 2.0 Logo high speed labeled by the top stripe ... the two-color version highlights that in red, sometimes it's one-color. |
![]() |
Old USB 1.1 Logo (no compatibility testing done) |
Be cautious about "high speed" devices that for any reason don't display that new logo. Those devices may not work very well, and it'll be your fault for encouraging vendors that sell nonconformant devices.
One big win for the USB 2.0 upgrade is that cables don't need to change. With the possible exception of some low quality cables that may not even handle USB 1.1 very well, you can keep using your existing USB cables. There was no need to switch to optical signal transmission, or anything similarly incompatible. There are new "Mini-B" cables, that can help eliminate the need for proprietary connectors on many small USB peripherals.
USB 2.0 hubs are special. Not only do they support high speed devices (older USB 1.1 hubs can't), but also because they all include "transaction translator" support that helps prevent full and low speed devices from wasting most of the USB bandwidth. See the next section, on backwards compatibility, for how this impacts end users with high speed buses whose devices may not all operate at high speed.
There is also an evolution of USB 2.0 called USB "On The Go" (OTG) which supports some point-to-point peer style hookups, like a digital camera or PDA connecting to a USB printer, for devices (maybe portable) that are often used without a PC. That won't be discussed here, in part because USB OTG products don't exist yet. They're expected to start appearing later in 2002. For more information, see this information from Philips Semiconductors.
You can connect USB 2.0 devices to USB 1.1 hosts and hubs, and they should work just fine ... but at 12 Mbit/sec, not at 480 Mbit/sec.
To get "high speed" behavior you'll need an updated host controller. It must support "USB 2.0 high speed", through the "EHCI" standard. Today you can get those as PCI cards, usually with a three or five port controller from NEC, or sometimes a four port one from Philips or VIA. More importantly, essentially all current generation PC motherboard silicon includes an EHCI controller built in. Linux users have reported success on most of these, with chips from ALI, Intel, NVidia, SiS, VIA, and others. (That's in alphabetical order; I'm not intending to slight any vendors.) See the section on Linux support (later) for more specific information.
You may also need newer hubs with USB 2.0 support. Probably the most important aspect of such hubs is how they support trees of devices that mix both high speed and full (or low) speed devices. The short version of the story is that to get high speed transfers out of a high-speed capable device, you must hook it up through an EHCI controller (that's using an EHCI driver!), and any hubs between the host and the device must only be USB 2.0 hubs.
That is, a tree of USB devices can start out with a high speed root hub, but if you plug in any USB 1.1 hubs to that tree, USB devices on branches below that hub will only operate at slower full/low (USB 1.1) speeds ... even if it's a USB 2.0 device. For now the lesson is that if you want to use a device at high speed, double check it after cabling things up. You can do this with "usbfs".
Beyond those general issues, Linux users will notice a few changes if they poke around through what the kernel tells them about their hardware.
You may know "usbfs" through its original, and somewhat confusing name, of "usbdevfs". The name changed because it was completely unrelated to "devfs".
If you use "usbfs" (perhaps through scripts like usbtree or tools like usbview) you will notice a few minor changes. Most notably, the USB version for some devices will be "2.0", and those devices will report their speed as "480Mb/s" when they're running at high speed. (In compatibility mode, at full speed, they'll say "12Mb/s".) Here's what usbtree shows for some full speed devices hooked up to an USB 2.0 controller. Several are connected through a USB 2.0 hub, and there's a USB 1.1 hub (with no devices) hooked up to another root hub port.
/: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=ohci-hcd/2p, 12M
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ohci-hcd/3p, 12M
|__ Port 1: Dev 2, If 0, Class=hub, Driver=hub/4p, 12M
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci-hcd/5p, 480M
|__ Port 2: Dev 2, If 0, Class=hub, Driver=hub/4p, 480M
|__ Port 1: Dev 3, If 0, Class=>ifc, Driver=pegasus, 12M
|__ Port 4: Dev 8, If 0, Class=hub, Driver=hub/3p, 12M
|__ Port 1: Dev 9, If 0, Class=HID, Driver=hid, 12M
|
Some of the endpoint descriptors may change. Maximum packet sizes can be bigger, and polling intervals for periodic transfers will sometimes be measured in microseconds (like 250us), not milliseconds (like 2ms), and you may even see NAK rates for bulk endpoints. For example, this descriptor is for one USB 2.0 CD-RW when it's running at high speed:
T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 2 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=05ab ProdID=0060 Rev= 2.10 S: Manufacturer=In-System Design S: Product=USB Storage Adapter S: SerialNumber=2201010A0247C8AB C:* #Ifs= 1 Cfg#= 2 Atr=c0 MxPwr= 98mA I: If#= 0 Alt= 0 #EPs= 3 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=125us E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=03(Int.) MxPS= 2 Ivl=32ms |
Here's the descriptor for the same CD-RW when there's no EHCI driver, so it's running at full speed (may not be a good idea to burn CDs at this speed though):
T: Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=05ab ProdID=0060 Rev= 2.10 S: Manufacturer=In-System Design S: Product=USB Storage Adapter S: SerialNumber=2201010A0247C8AB C:* #Ifs= 1 Cfg#= 2 Atr=c0 MxPwr= 98mA I: If#= 0 Alt= 0 #EPs= 3 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage E: Ad=01(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=83(I) Atr=03(Int.) MxPS= 2 Ivl=32ms |
Other than that "480Mb/s" speed rating, most of that per-device usbfs information will only be interesting to folk working with device drivers. That "480Mb/s" in the descriptor for your device will be a sign that you've cabled it up correctly (so it runs at high speed). But there are also differences you may notice if you look at the root hub support for each of your systems USB busses.
Perhaps the most curious thing is that when you plug in a full (or low) speed device to a connector on your high speed USB controller, it will be connecting to a different bus than when you plug in a high speed device to that same USB "A" socket on your PC! In the CD-RW example above, the bus number changed. Sometimes the port number will also change. (OK, so maybe you wouldn't have noticed.)
That's because of how the controllers work. Here's how /proc/bus/usb/devices looks on one system with a five port NEC EHCI based controller, and nothing hooked up to it. I added some whitespace and highlighting so you can see what's going on a bit better:
T: Bus=03 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 3 B: Alloc= 0/900 us ( 0%), #Int= 0, #Iso= 0 D: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=0000 ProdID=0000 Rev= 2.05 S: Manufacturer=Linux 2.5.8 ohci-hcd S: Product=NEC Corporation USB S: SerialNumber=00:0b.0 C:* #Ifs= 1 Cfg#= 1 Atr=40 MxPwr= 0mA I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=255ms T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2 B: Alloc= 0/900 us ( 0%), #Int= 0, #Iso= 0 D: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=0000 ProdID=0000 Rev= 2.05 S: Manufacturer=Linux 2.5.8 ohci-hcd S: Product=NEC Corporation USB (#2) S: SerialNumber=00:0b.1 C:* #Ifs= 1 Cfg#= 1 Atr=40 MxPwr= 0mA I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=255ms T: Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=480 MxCh= 5 B: Alloc= 0/800 us ( 0%), #Int= 0, #Iso= 0 D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=01 MxPS= 8 #Cfgs= 1 P: Vendor=0000 ProdID=0000 Rev= 2.05 S: Manufacturer=Linux 2.5.8 ehci-hcd S: Product=NEC Corporation USB 2.0 S: SerialNumber=00:0b.2 C:* #Ifs= 1 Cfg#= 1 Atr=40 MxPwr= 0mA I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub E: Ad=81(I) Atr=03(Int.) MxPS= 2 Ivl=256ms |
Yes, three USB buses on one controller card! (The PCI card is 00:0b but each bus has a different PCI function number.) And it looks like there's a total of ten ports (sum the "MxCh" entries saying how many children the root hubs have), not five ... how can that be?
The answer is that the two OHCI "companion controllers" are used along with the EHCI controller, and a silicon switch connects each port to only one controller at a time. When an EHCI driver runs, all ports start out connected to EHCI. When EHCI detects a full or low speed device on a port, that port is switched over to one of the companion controllers. High speed devices it keeps for itself ... so each port seems to connect to either EHCI or its companion controller (never both!) based on whether it runs at high speed or not. If there's no EHCI driver there to handle high speed devices, then everything gets treated as full or low speed since the switch won't connect things to the EHCI controller. (Companion controllers won't necessarily be OHCI; some are UHCI.)
So to fully use a USB 2.0 host controller you must still use an OHCI or UHCI host controller driver, as you've likely been doing already. And if that's the only driver you have, you can still use hardware that includes USB 2.0 support ... it just won't be as fast until you upgrade to an OS version with USB 2.0 support. In the big picture that's a great migration story for the core USB 2.0 technology: the hardware can upgrade, and the software follows later when it's convenient for end users. (Much like most vendors' stories for migrating from one generation of CPU, or instruction set, to the next one.)
OK, this section talks about what makes USB 2.0 tricky. And it's not all that user visible, so you can safely skip reading it if you're one of the many Linux users who just wants a top quality OS (or a Free one) and aren't very concerned about all the underlying technology.
If you're writing a device driver, you may want to know about this, since it can affect how you write your driver. At this writing, not all transaction translator features are used by Linux. Also, since those code paths aren't used much yet, a number of shortcuts have been taken, which limit throughput. (Someone will surely provide a patch to remove those shortcuts if/when they become troublesome.)
USB 2.0 gets some of its backward compatibility through a technique called split transactions that's used in many other buses. Many disk interface technologies, for example, support concurrent requests to different devices (like USB does), and split their requests into a "start" phase, disconnecting, and reconnecting later for a "complete" phase. That lets the bus be used for other purposes while some slow I/O completes ... like a disk drive seeking and reading several sectors, or (in the USB case) like a 1.5 MBit/sec mouse delivering its motion event.
In the case of a USB 2.0 host talking to a USB 1.1 device, it does so either through a companion controller (so it's really acting as a USB 1.1 host), or through a transaction translator in a USB 2.0 hub. The host talks to the translator at high speed, and then the translator performs the full or low speed I/O to that USB 1.1 device. It buffers data in either direction as required, and later sends the results back to the host at high speed. A hub can have just one translator, or one per port. With just one translator, a hub can only use as much bandwidth as a USB 1.1 host can. With more translators, each port can use that much bandwidth.
So for example, each of six ports on the hub might have a full speed webcam, each of which is using ten megabits per second of I/O at the same time. With less capable hubs, only one port on that hub might be able to operate at that speed at a time, supporting only the bandwidth of a USB 1.1 bus.
From the perspective of a Linux USB 2.0 host, there are two ways it talks to USB 1.1 devices through transaction translators. Some requests do this almost transparently, like control requests and (full speed only) bulk data transfer. In those cases, the host must tell the EHCI controller that it's talking through a transaction translator, and maybe be ready to recover from some errors, but for most purposes there's control and bulk requests are completely "hands off". That means many USB 1.1 device drivers will continue to work just fine through a USB 2.0 hub ... many network adapters, modems, digital still cameras, MP3 players, disk drives, and similar devices won't need anything more.
Then there are the requests that need a lot of hands-on attention: periodic transfers like interrupt and (full speed only) isochronous ones. Because these are all reserved-bandwidth transacton types, they can't be automated as readily as control and bulk (which can opportunistically make progress whenever periodic transfers aren't active). The result is a lot of hub-related complexity in the EHCI driver, making sure that the periodic transfers are safely scheduled and that transaction translators don't get overcommited. Periodic transfers are already the most complex type in USB (though their API got simpler in the Linux kernel 2.5 series), so to some extent it's just one more consideration when scheduling,
For example, suppost a USB 1.1 periodic transfer is to be worked on every eight frames (milliseconds). That's going to go through a specific transaction translator; the transfer needs a time when that translator isn't in use, and when there's also bus bandwidth. The EHCI driver needs to schedule a "start split" (a bit in an 's-mask') sometime in one microframe, and a "complete split" (bits in a 'c-mask') in some later microframe, and ensure that between the start and completion no other request uses that translator. Isochronous transfers can be bigger, and are managed by EHCI using a different type of data structure, but in both cases you can see that there's a fair amount of housekeeping involved in tracking what requests are active.
The most visible change was the addition of "high speed" devices and transfers. In a Linux USB device driver, you can tell if the device is high speed (and thus whether its transfers will be at high speed!) by testing whether dev->speed == USB_SPEED_HIGH. You've been able to do that since about the 2.4.10 kernel, but you probably didn't have high speed devices to work with then.
The rules for full and low speed transfers have not changed, but some rules changed for high speed transfers. (You may have noticed some of those changes when comparing the high speed and full speed usbfs information shown above for the CD-RW.) In a few cases drivers need to have code that knows which rules apply, but mostly the changes will be transparent to correctly written drivers. Those changes include:
There are also protocol changes that should be invisible to most device drivers ... except in some cases for the host or device controller drivers, or the hub driver:
When Linux start to be embedded more widely inside USB devices (not just USB hosts) the USB "function" or "target" drivers will need a new kind of USB programming interface. That will also support USB 2.0; higher speed targets will benefit from the capabilities of Linux more than most USB 1.1 targets (even including Linux-based PDAs). The current Linux-USB programming interface has a host side model: one master talking to many targets (like a web client talking to many servers).
A new device side "USB Gadget" API is available, standard with the 2.5 kernel and also available for 2.4 systems.. While it should resemble the current programming interfaces (at least in terms of submitting URBs) it must treat USB busses very differently from a host side API. That's because implementing the target function only involves talking to a single USB Host (like a web server only responding to one client at a time). Also, target side drivers can never initiate control requests, they can only respond to them.
People have been using USB 2.0 with usb-storage devices from Linux hosts since June 2001. But it was only towards the end of that year, a short while before Linus created the 2.5 development branch, that other USB 2.0 devices (notably, hubs) began to be available. So while some changes for USB 2.0 were rolling into 2.4 kernels through the year 2001, largely done by about 2.4.10, the most tricky stuff (the ehci-hcd driver) stayed separate until the 2.5 kernel branched. All current Linux distributions include EHCI support, and the end-user bug reports have been helping to stabilize that driver.
At this writing the "ehci-hcd" driver is not as well proven as the OHCI or UHCI drivers, so it's still labeled experimental, but it's just fine for many purposes.
In terms of functionality, the latest driver:
You'll find that most PCI USB 2.0 add-in cards (and CardBus/PCMCIA ones) use the NEC silicon or the VT62x2, though there are other vendors. The Adaptec card that does both USB 2.0 and FireWire has been a problem for some people too, perhaps because of the built-in PCI bridge.
Some folk have problems with the CardBus versions, because Linux hasn't always managed to get the IRQs assigned correctly on their particular laptop make/model. (IRQs are a general problem, BIOS and ACPI problems abound.) Once such BIOS/PCI level problems get resolved, the ehci-hcd driver works with those CardBus configurations too. It may be very important to use an external power supply for the CardBus adapter. (It seems like CardBus can't supply all of the power needed by bus-powered USB devices.)
If you're using a CardBus adapter with an older driver version, you may need to manually remove the driver (with rmmod) before a CardBus eject (including cardctl eject) or system shutdown; the CardBus shutdown doesn't shut down drivers when it should, so that's the only "clean shutdown" solution..
See the linux/Documentation/usb/ehci.txt file in your Linux kernel source distribution for some more information. As always with drivers still in development, if you have any problems, try the latest code (preferably in the 2.5 kernel, otherwise in the latest 2.4 code) to see if the problem has been fixed yet. And if not, report problems to the linux-usb-devel mailing list.
High speed storage devices, and to some extent hubs, seem to be the most USB 2.0 devices so far. High speed scanners and printers are available, and there are early reports of success using them. (If you're interested in what USB 2.0 devices are available on the market, http://usb-20.com is a website specializing in selling you such devices. A site that's been established a bit longer is http://www.usbstuff.com, which also includes USB 1.1 products.)
Most full and Low speed (USB 1.1) devices will work when connected to USB 2.0 root hubs, using their current drivers, since they'll be handled by the companion controllers. Many of them should also work when connected to USB 2.0 external hubs, subject to the restrictions desribed earlier. (Which, for the latest code, amounts to no webcam or audio support yet.)
| Device | Driver | Comments |
|---|---|---|
| USB 2.0 hubs | hub (usbcore) | USB 2.0 hubs work, but haven't been widely stressed (especially in terms of faults happening during transaction translation). Warning: don't unplug these hubs with the 2.4.19 code ... a patch is of course available! |
| Disks, CD-RW, etc | usb-storage | Linux USB 2.0 support seems to work pretty well for the usb-storage devices that now exist, though it's slower on 2.4 since the usb-storage driver does not queue its USB requests. (Where "slower" still tops 10 MByte/sec on most hardware.) Starting with about 2.5.45, storage uses the new usb_sg_submit() call to queue all I/Os in a scatterlist at once, so nothing should be in the way of letting your hardware achieve 20+ MByte/sec (except maybe bugs that aren't yet fixed, or slow disks). |
| BackPack USB Drives | usb-storage | Micro-Solutions has provided software to set up their devices with hotplugging, so that you can easily connect theeir drives to Linux. Available in several formats, including RPM. |
| Archos MP3 Jukebox | usb-storage | Older kernels may need a tweak to usb-storage error handling, or a workaround: start the Archos and let it boot up before you load or hotplug the usb-storage module.. |
| ASIX AX88172 (10/100 Ethernet Adapter) | ax8817x | A variety of products, including the D-Link DUB-E100, Hawking UF200, and Netgear FA120 all use this technology. Running at high speed, all of them should give much better throughput than similar full-speed products. This driver is part of the 2.4.22 and 2.5.73 kernels. |
| IOGear Host-to-Host Link | usbnet (patch needed) | Press Release |
| Orange iBOT2 WebCam | ovfx2, evolved from ov511 | This is the first USB 2.0 webcam announced. |
| Cypress EZ-USB FX2 | custom ... depends on what your firmware makes it do | These are 8051 microcontrollers with support for high speed transfers, designed for use inside USB devices and with custom firmware. The fxload software lets you download that firmware. For the start of one interesting Linux-based example (hosted at sf.net), see the SR-1 software radio. |
| NetChip 2280 | custom ... depends on what your firmware makes it do | These are PCI based controllers with support for high speed transfers, designed for use inside USB devices and with custom firmware. Linux-USB gadget support is available, so you can implement that firmware under Linux. One such driver implemens a network interface, and others are under development. |
Regardless of what type of high speed device you use, USB hotplugging works the same as it always has on Linux.
User mode device drivers should be able to use the usbfs APIs as usual. They may be able to tell that they're talking to USB 2.0 devices by details in the device descriptors (such as 512 byte bulk packets); the Java USB APIs expose such information more directly. The libusb APIs (in C) don't yet.