From: <Brad.Hards@dao.defence.gov.au> To: linux-usb@suse.com Date: Tue, 10 Aug 1999 16:19:33 +1000 Subject: [linux-usb] HOWTO-usb-0.6 [23K] I think I have a high volume web-site coming online. I'll post a link when I get it sorted. So just a text version this time. I still need some words from someone with a EZUSB setup, and I am still trying to get my USB Zip drive to stop oopsing the kernel (trying the root hub tonight....) Brad ------------------------------------- How to get USB devices working under Linux Brad Hards $Revision: 0.6 $ This document is an early draft of a step-by-step guide to getting USB devices working on a Linux system _________________________________________________________________ Basic USB Configuration You need a late version kernel. Kernel versions 2.2.7 and later contain the USB code. You should, in an ideal world, be running the current 2.3.x kernel, ideally with any pre-patches for the next kernel. It is possible to use the 2.3.x USB code with a 2.2.x kernel - see later in this document for details. USB code is in fairly early development, so the changes between each version (and the bugs) tend to change fairly fast. Support on the mailing list for anything except the lastest version is scant at best. The mailing list is <[1]linux-usb@suse.com>. To subscribe, send a mail message to <[2]majordomo@suse.com> with content of subscribe linux-usb. If you want to stop getting mailing list content, send a mail message to <[3]majordomo@suse.com> with content of unsubscribe linux-usb. You need to configure USB into your kernel. Use of make menuconfig is recommended. Under USB drivers - not for the faint of heart , you need to select Support for USB (EXPERIMENTAL!) . You also need to select one of UHCI (intel PIIX4 and others) support, OHCI (compaq and some others) support or OHCI-HCD (other OHCI opt. Virt. Root Hub) support. Use of more than one of UHCI, OHCI, and OHCI-HCD at the same time is not expected to fully work (UHCI might work). Which one you select is dependent on what kind of motherboard or adapter you have. Intel and Via motherboards are UHCI. Compaq and NEC motherboards, iMacs and any adapter using Opti chips (just about all of them) are OHCI, and you can use OHCI or OHCI-HCD, at your option. If you do not know what kind of controller to choose, check your motherboard documentation. You can als look at /proc/pci for a hint - if the USB entry is of the form 0xHHHH, where HHHH are hex digits (e.g. something like I/O at 0xe400), then it is UHCI. If it is of the form 32 bit memory at 0xHH000000, where HH are hex digits (e.g. something like 32 bit memory at 0xee000000), then it is OHCI. Failing that, just try one. You also need to select whichever devices you want to use, for example USB mouse support for a USB mouse, USB keyboard support for a USB keyboard, USB hub support for a hub, USB Abstract Control Model support for a POTS or ISDN modem, Preliminary USB Printer support for a USB printer, USB SCSI Support for mass storage devices, and EZUSB Firmware downloader for downloading into an Anchor Chips USB microcontroller kit. You should be able to use modules, kernel only, or split modules and kernel code. I strongly recommend selecting hub support, although it is not strictly needed if you are only plugging devices into the root hub. USB audio parsing support does not work at this time. Devices not listed in this document are not working at the time of writing, although developers are always welcome to contribute to the current codebase. If you want to use a stable kernel (2.2.x), you can replace the code in the drivers/usb directory with the code from a developmental kernel (2.3.x). You will need to uncomment the line in arch/i386/config.in that says: # source drivers/usb/Config.in . Other architectures will need something similar. You also need to add a few extra definitions near the top of the drivers/usb/usb.h : #if LINUX_VERSION_CODE < 0x020300 #define DECLARE_WAIT_QUEUE_HEAD(w) struct wait_queue *w = NULL #define DECLARE_WAITQUEUE(w,c) struct wait_queue w = {(c), NULL} #define wait_queue_head_t struct wait_queue * #define init_waitqueue_head(w) *(w) = 0 #define DECLARE_MUTEX_LOCKED(sem) struct semaphore sem = MUTEX_LOCKED #endif Rebuild the kernel and the modules (if you configured to build as modules), and install the new kernel and the new modules. Reboot the system. If you are using modules, you need to load the modules in a certain order. Load usbcore.o first, followed by any drivers mouse.o, keyboard.o, hub.o, etc, with the host controller (e.g. usb-uhci.o or usb-ohci.o) added last. Inspect the kernel logs. You should see lines like the following (assuming use of UHCI and an external hub) ....... Jul 19 20:46:02 rachel kernel: USB HID boot protocol mouse registered. ....... Jul 19 20:46:02 rachel kernel: uhci_control_thread at c01b8c5c Jul 19 20:46:02 rachel kernel: New bus registered Jul 19 20:46:02 rachel kernel: USB hub driver registered Jul 19 20:46:02 rachel kernel: uhci_connect_change: called for 0 ....... Jul 19 20:46:02 rachel kernel: USB hub found Jul 19 20:46:02 rachel kernel: hub: 4-ports detected Jul 19 20:46:02 rachel kernel: hub: individual port power switching Jul 19 20:46:02 rachel kernel: hub: standalone hub Jul 19 20:46:02 rachel kernel: hub: individual port over current protection Jul 19 20:46:02 rachel kernel: hub: power on to power good time: 100ms Jul 19 20:46:02 rachel kernel: hub: hub controller current requirement: 100mA Jul 19 20:46:02 rachel kernel: hub: port 1 is removable Jul 19 20:46:02 rachel kernel: hub: port 2 is removable Jul 19 20:46:02 rachel kernel: hub: port 3 is removable Jul 19 20:46:02 rachel kernel: hub: port 4 is removable Jul 19 20:46:02 rachel kernel: hub: local power source is good Jul 19 20:46:02 rachel kernel: hub: no over current condition exists Jul 19 20:46:02 rachel kernel: enabling power on all ports Jul 19 20:46:02 rachel kernel: uhci_connect_change: called for 1 ....... Jul 19 20:46:02 rachel kernel: hub: port 3 connection change ....... OHCI and OHCI-HCD should give similar results. Don't worry about failing transfers, this is a minor bug that shouldn't affect anything. If there isn't anything that could be USB related (lines that mention hubs, usb, ohci or uhci), likely causes are use of the wrong driver (UHCI when you needed OHCI or OHCI when you needed UHCI), not physically installing the hardware, a BIOS configuration that disables USB or stuffing up the configuration or installation of the kernel. _________________________________________________________________ Mouse Configuration Firstly check that your mouse is being correctly sensed by the kernel. If you type more /proc/interrupts , you should see a line that refers to USB - typically ohci-usb or usb . If you click the mouse a few times, and then have a look at /proc/interrupts the count associated should increase (by two per click, one for down and one for up). This count is a bit difficult to do with UHCI, since you have to subtract the number of seconds that have elapsed between the checks of /proc/interupts, and if you are using a USB keyboard, you need to adjust for the key-presses as well. Check /proc/misc. You should see something like [bradh@rachel bradh]$ more /proc/misc 32 USB Mouse 1 psaux You need to set up a /dev entry for the mouse. Use the following command: mknod /dev/usbmouse c 10 32 If you want to use the mouse under X, you need to: * edit the XF86Config file (usually /usr/X11R6/lib/X11/XF86Config). Add the following (anywhere sensible, ideally in the Input devices area). Section "Xinput" SubSection "Mouse" DeviceName "USB Mouse" Protocol "IMPS/2" Port "/dev/usbmouse" AlwaysCore EndSubSection EndSection * Restart the X server. If you don't have any mouse support at this point, remember that Ctrl-Alt-1 will get you a virtual terminal that you can use to kill the xserver and start debugging from the error messages If you want to use the mouse under gpm, run gpm -m /dev/usbmouse -t ps2 (as superuser remember). You can make this the default if you edit the initialisation files. These are typically named something like rc.d and are in /etc/rc.d/ on RedHat distributions. _________________________________________________________________ Keyboard Configuration You may not need any operating system support at all to use a USB keyboard if you have a PC architecture. There are several BIOSs available where the BIOS can provide USB support from a keyboard plugged into the root hub on the motherboard. This may or may not work though other hubs and does not normally work with add-in boards, so you might want to add in support anyway. Check that your keyboard is being correctly sensed by the kernel. If you type more /proc/interrupts , you should see a line that refers to USB - typically ohci-usb or usb . If you type on the keyboard and then have a look at /proc/interrupts the count should increase, although you may need to subtract the number of seconds that have elapsed if you are using UHCI. At this point, you should be able to use your USB keyboard just as for a normal keyboard. Be aware that LILO is not USB aware, and that unless your BIOS supports a USB keyboard, you may not be able to select a non-default boot image using the USB keyboard. _________________________________________________________________ Hub Support Hubs should work without other configuration. If the device works when plugged into the root hub and not when plugged into an add-on hub, make sure that you installed the hub module (if you built as modules). Also check that you are not plugging a high powered device into a bus-powered hub. _________________________________________________________________ Printer Support You need to set up a /dev entry for the printer. Use the following command: mknod /dev/usblp c 63 0 You should now be able to use this device in a normal /etc/printcap entry. I recommend use of automated tools to generate such files, such as RedHat's control panel print-tool. If this does not appear to work, make sure that the major device number for the printer has not changed (63 is an experimental range number). Either check through the source code, or have a look in /proc/devices. Also check that you have actually loaded the module, and double-check the /etc/printcap entry - especially that the device file matches the one you just created. _________________________________________________________________ Abstract Control Model Support You need to set up a /dev entry for the ACM device. Use the following command: mknod /dev/usbacm c 10 32 You should now be able to use a terminal emulator program to attach to this /dev/usbacm and connect to your modem or other terminal device. This is currently embrionic only. Note that this is the same major device number and minor device number as the USB mouse device driver. So you need to change the device numbers for either the mouse or the ACM driver if you wish to use both of these devices. _________________________________________________________________ CPiA imager support Support for CPiA cameras is included in the normal distribution, but is not included in the normal Config.in in the linux/drivers/usb directory. You need to add a line like dep_tristate 'USB CPiA camera support' CONFIG_USB_CPIA $CONFIG_USB $CONFIG_VI DEO_DEV into this Config.in. Now reconfigure your kernel to support this device and also enable Video For Linux support (under Character Devices if using menuconfig). You need to set up a /dev entry for the CPiA camera. Use the following command: mknod /dev/video0 c 81 0 ln -s /dev/video0 /dev/video To use the device, you need some video tools. There are a fairly wide range of tools available. [4]http://millenium.diads.com/bdirks has a package that is a generally named something like apps19990527.tgz, depending on the date of release. It has both X and text-mode tools. Using the text mode tools will allow you to do things like ./vctrl 320x240x24 ./vcat | rawtoppm -bgr 320 240 | xv - These tools default to using /dev/video if not otherwise specified, hence the symbolic link made previously. At this stage, the CPiA camera can only do black and white images. If you want to work on it, you should check the Vision CPiA website at [5]http://home.eunet.no/~jtotland/vision _________________________________________________________________ Mass Storage Devices To be added. _________________________________________________________________ USB /proc driver To get /proc support for the USB system, you currently need to select Preliminary /proc/bus/usb support. Then recompile and reinstall as detailed above. There are currently two interfaces to the /proc support for USB. They are /proc/bus/usb/drivers and /proc/bus/usb/devices. /proc/bus/usb/drivers just lists the currently registered drivers (even if the driver is not being used by any device). This is most useful when testing module installation, and checking for USB support in an unknown kernel. Here is an example of its use: [bradh@rachel bradh]$ more /proc/bus/usb/drivers hub printer keyboard mouse /proc/bus/usb/devices lists information about the devices currently attached to the USB bus. This is very useful when trying to figure out if the device is correctly enumerated. Here is an example of its use, showing the root hub, a hub, a keyboard, a mouse and a printer adapter: T: Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= -1 Spd=12 If#= 0 MxCh= 2 Driver=(root hub) T: Lev=01 Prnt=00 Port=00 Cnt=01 Dev#= 1 Spd=12 If#= 0 MxCh= 4 Driver=hub D: Ver= 1.00 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=0451 ProdID=1446 Rev= 1.00 C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=100mA I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 E: Ad=81(I) Atr=03(Int.) MxPS= 1 Ivl=255ms T: Lev=02 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 If#= 0 MxCh= 0 Driver=print er D: Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=0729 ProdID=1284 Rev= 1.04 C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr= 98mA I: If#= 0 Alt= 0 #EPs= 1 Cls=07(print) Sub=01 Prot=01 E: Ad=01(O) Atr=02(Bulk) MxPS= 64 Ivl= 0ms I: If#= 0 Alt= 1 #EPs= 2 Cls=07(print) Sub=01 Prot=02 E: Ad=01(O) Atr=02(Bulk) MxPS= 64 Ivl= 0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl= 0ms I: If#= 0 Alt= 2 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=ff 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= 4 Ivl= 1ms T: Lev=02 Prnt=01 Port=01 Cnt=02 Dev#= 3 Spd=1.5 If#= 0 MxCh= 0 Driver=keybo ard D: Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=045e ProdID=000b Rev= 0.82 C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr=100mA I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=01 E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl= 10ms T: Lev=02 Prnt=01 Port=02 Cnt=03 Dev#= 4 Spd=1.5 If#= 0 MxCh= 0 Driver=mouse D: Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=046d ProdID=c001 Rev= 1.10 C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr= 50mA I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=02 E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl= 10ms The information in the /proc/bus/usb/devices output is arranged in groups: * The line that starts with T: is the topology. Lev indicates the level of the device, starting at level 00 for the root hub, level 01 for any device attached to the root hub, level 02 for devices attached to hubs at level 01, and so on. Prnt is the parent device for this device (always 00 for the root hub and any device attached to the root hub). Port is the port on the parent device, starting at 00 for the first port on each device. Prnt/Port is unique per bus. Cnt indicates what number device this is, at this level, based on the enumeration order within that level of the topology, starting at 01 for the first device. Dev# indicates what number device this is, irrespective of level, based on the bus enumeration order. Spd indicates what speed this device is running at, in Mbps (either 1.5 or 12 with the current version of USB). If# indicates what number interface is currently selected. MxCh indicates how many devices can be connected to this device, and is 00 for anything except a hub. Driver indicates which device driver is being used for this device - an entry of (none) indicates that no driver is being used. * The line that starts with D: is information from the device descriptor. Ver indicates which USB specification version the device claims to meet. Cls indicates which device class the device is claiming to meet, in both hexadecimal and as a string. A Cls entry of 00(>ifc) indicates that the device class specification compliance is interface dependent, and the interface descriptor should be read for device class information. Sub indicates which sub-class (within the Cls entry), the device meets. MxPS indicates how big the packets from Endpoint 0 are. #Cfgs indicates how many configurations this device has. * Much like D:, the line that starts with P: is information from the device descriptor, and is seperated mainly because it wouldn't all fit on one line. Vendor indicates the Vendor Identification code for the device, and ProdID indicates the Product Identification code for the device. Rev indicates the product revision number. * Refer to the USB specification clause 9.7.1 for further information on device descriptors. * The line that starts with C: is information from the configuration descriptor - the number of C:lines per device is given by #Cfgs, and the entry followed by an asterisk is the current configuration. #If indicates how many interfaces the device has. Cfg# indicates which configuration is being described. Atr is a hexadecimal indication of the device attributes (0x80 for bus-powered, 0x40 for self-powered, 0x20 for remote wake-up capable). MPwr is the maximum power draw for this device configuration, in milliamps. Refer to USB specification clause 9.7.2 for further information on configuration descriptors. * The line that starts with I: is information from the interface descriptor - the number of I: lines per C: line is given by the #If entry. If# indicates which interface is being described within a given device configuration. Alt indicates which alternate setting of this interface is being described. #EP indicates how many endpoints there are within the alternate setting for this endpoint. Cls indicates which class the alternate setting of the interface corresponds to, in both hexadecimal and as a character string. Sub indicates which sub-class the alternate setting of the interface belongs to. Prot indicates which interface protocol (within a class and sub-class tuple) the alternate setting of the interface conforms to. See USB specification clause 9.7.3 for further information. * The line that starts with E: is information from the interface descriptor - the number of E: lines per I: line is given by the #EP entry. Endpoint 0 is not displayed. Ad indicates the endpoint address, with a letter to indicate whether the endpoint is an In or Out endpoint. Atr indicate the attribute (transfer type) associated with the endpoint, followed by a string translating the transfer type. MxPS indicates the maximum packet size this endpoint is capable of sending or receiving, as appropriate. For isochronous transfers, MxPS indicates how much bandwidth needs to be reserved. Ivl indicates the interval, in milliseconds, between polling of interrupt endpoints. Ivl is ignored for bulk and control transfers, and is set to 1 for isochronous transfers. See USB specification clause 9.7.4 for further information on endpoint descriptors. Refer to linux/Documentation/proc_usb_format.txt for more information on using the /proc/bus/usb information. _________________________________________________________________ Frequently Asked Questions There certain questions that keep reappearing. This section tries to answer those questions. _________________________________________________________________ How do I write a driver You study the kernel source. You find a driver that is similar to what you need to do, and you adapt it till it works. In this context, similar is in terms of what transfers you need to do, not in what the device looks like. _________________________________________________________________ What is a good book on USB I have only read one, and thought it was very poor. I suggest that you get the specifications from [6]http://www.usb.org, which are at no cost, are quite readable, and are up to date. _________________________________________________________________ I have a vendor specific device, here is the descriptors The descriptors are essential, but not sufficient, to write a driver. You need the low level design detail from the vendor. In addition, don't be surprised if the descriptor is not specification compliant - all bets are off with vendor devices. Remember that descriptors are just data bytes from the device, and reprogramming the device can make any text appear, irrespective of what the device is really capable of. _________________________________________________________________ What major and minor numbers should I use for my driver? Use a major number in the experimental or demonstration ranges. There is no official major number assigned for USB at this time. Use whatever minor number you like. _________________________________________________________________ How do I make USB work on my Sony Vaio laptop? You need to turn off the BIOS option for Plug-n-Pray operating system support. Then it should work fine. _________________________________________________________________ Corrections Please send comments on this document to the author, preferably by E-Mail (<[7]brad.hards@dao.defence.gov.au>), including the version number: ($Revision: 0.6 $). References 1. mailto:linux-usb@suse.com 2. mailto:majordomo@suse.com 3. mailto:majordomo@suse.com 4. http://millenium.diads.com/bdirks 5. http://home.eunet.no/~jtotland/vision 6. http://www.usb.org/ 7. mailto:brad.hards@dao.defence.gov.au --------------------------------------------------------------------- To unsubscribe, e-mail: linux-usb-unsubscribe@suse.com For additional commands, e-mail: linux-usb-help@suse.com