<?xml version='1.0' encoding="UTF-8"?>
<!-- $Header: /var/cvsroot/gentoo/xml/htdocs/doc/en/usb-guide.xml,v 1.7 2005/08/25 11:24:46 fox2mike Exp $ -->

<!DOCTYPE guide SYSTEM "/dtd/guide.dtd">

<guide link="/doc/en/usb-guide.xml">
<title>Gentoo Linux USB Guide</title>

<author title="Author">
  <mail link="fox2mike@gentoo.org">Shyam Mani</mail>
</author>

<abstract>
This document helps a user setup USB on a Gentoo system and configure various
USB devices as well.
</abstract>

<!-- The content of this document is licensed under the CC-BY-SA license -->
<!-- See http://creativecommons.org/licenses/by-sa/2.5 -->
<license/>

<version>1.5</version>
<date>2005-08-25</date>

<chapter>
<title>Introduction</title>
<section>
<title>What is USB?</title>
<body>

<p>
USB stands for Universal Serial Bus and is basically an external interface
standard that enables communication between the computer and various other
peripherals. Some of the most commonly used USB devices today are keyboards,
mice, pen drives, digital cameras, external CD &amp; DVD writers, printers etc.
</p>

<p>
There are currently two versions of USB in use, i.e. USB 1.1 and USB 2.0.
Since USB has always been backward compatible with its previous versions,
USB 2.0 is backwards compatible with USB 1.1. The latest USB devices are
typically USB 2.0 compatible. USB 2.0 supports a maximum data transmission
speed of 480 Mbps or 60 MBps and this is the major difference between the two
standards. Another advantage with USB is that the devices are all
<e>hot-pluggable</e>, which means that you do not have to restart your system
in order for you to be able to use these devices.
</p>

</body>
</section>
<section>
<title>A Technical Perspective</title>
<body>

<p>
Before we go onto the exact configuration options in the kernel, it would
be apt to look at USB in a little more detail. If you're in a hurry or want
to skip this section, please go to <uri link="#kernel">Kernel Configuration</uri>.
</p>

<p>
A USB system has a host controller, hubs, a <e>root hub</e> amongst others
and can support up to 127 USB devices including the hubs. The host controller
is nothing but the hardware interface between the USB device and the
operating system. There are a couple of HCI (Host Controller Interface)
in use today and they are the OHCI (Open HCI) by Compaq, UHCI (Universal HCI)
and EHCI (Enhanced HCI), both from Intel. The OHCI/UHCI are the two industry
standard USB 1.1 interfaces whereas the EHCI is for USB 2.0.
</p>

<p>
The hardware vendor provides an interface for the programmer that allows
the system to interact with the hardware and this is called the HCD or Host
Controller Device. It is through this HCD that the device interacts with the
system software. The following diagram should make things easier to comprehend.
</p>

<pre caption="General USB Architecture">
<comment>(Software consists of other components as well like the device driver, but
for the sake of simplicity, they are not shown)</comment>

    + ----  Hardware  ----   + ----  Software  ---- +
    |                        |                      |
    | [USB Dev] -+-> {EHCI} -+--->  ( EHCD )        |
    |            |           |                      |  User
    |            `-> {UHCI} -+--->  ( UHCD )        |
    |                        |                      |
    + ----  Hardware  ----   + ----  Software  ---- +
</pre>

<p>
A USB device can either use a custom driver or use one already present in
the system and this is based on the concept of a device <e>class</e>. This
means that if a device belongs to a certain <e>class</e>, then other devices
belonging to the same <e>class</e> can make use of the same device driver.
Some of these <e>classes</e> are the USB HID (Human Interface Devices) class
which covers input devices like keyboards and mice, the USB Mass Storage
devices class which covers devices like pen drives, digital cameras, audio
players etc and the USB CDC (Communication Devices Class) which essentially
covers USB modems and similar devices.
</p>

</body>
</section>
<section>
<title>What's on your machine?</title>
<body>

<p>
It is very simple to find out whether your machine has USB 2.0 support or not.
We make use of the <c>lspci</c> command for this purpose.
</p>

<note>
The <c>lspci</c> tool is a part of the <c>sys-apps/pciutils</c> package. If
you do not have this installed, please <c>emerge pciutils</c>. Please note
that you have to be root while running the <c>lspci</c> command.
</note>

<pre caption="Various lspci outputs">
<comment>(In system that is USB 1.1 compliant, note the UHCI only)</comment>

# <i>lspci -v | grep USB</i>
0000:00:04.2 USB Controller: Intel Corp. 82371AB/EB/MB PIIX4 USB (rev 01) (prog-if 00 [UHCI])

<comment>(A system that is USB 2.0 compliant, note the EHCI and UHCI)</comment>

00:1d.0 USB Controller: Intel Corp. 82801DB USB (Hub #1) (rev 01) (prog-if 00 [UHCI])
00:1d.1 USB Controller: Intel Corp. 82801DB USB (Hub #2) (rev 01) (prog-if 00 [UHCI])
00:1d.2 USB Controller: Intel Corp. 82801DB USB (Hub #3) (rev 01) (prog-if 00 [UHCI])
00:1d.7 USB Controller: Intel Corp. 82801DB USB EHCI Controller (rev 01) (prog-if 20 [EHCI])
</pre>

<p>
So using the <c>lspci</c> command, we can find out if the system supports
USB 2.0. This is useful as we will be enabling the corresponding options in
the kernel.
</p>

</body>
</section>
</chapter>

<chapter id="kernel">
<title>Kernel Configuration</title>
<section>
<title>Getting the kernel</title>
<body>

<note>
Since the 2005.0 release, Gentoo Linux uses 2.6 as the default kernel. Unless
you are specifically using the 2.4 profile, <c>gentoo-sources</c> will be a
2.6 kernel on <e>most</e> architectures. Please check your kernel version and
then proceed with the configuration accordingly.
</note>

<p>
First emerge the kernel sources of your choice. Here we'll use the
<c>gentoo-sources</c>. For more information on the various kernel sources
available on Portage, please look up the <uri
link="/doc/en/gentoo-kernel.xml">Gentoo Linux Kernel Guide</uri>.
</p>

<pre caption="Getting the kernel sources">
# <i>emerge gentoo-sources</i>
</pre>

<p>
Now, lets get on with the task of configuring the kernel.
</p>

<pre caption="Heading over to the source">
# <i>cd /usr/src/linux</i>
# <i>make menuconfig</i>
</pre>

<note>
The above example assumes that <path>/usr/src/linux</path> symlink points to
the kernel sources you want to use. Please ensure the same before proceeding.
</note>

</body>
</section>
<section id="2.6.xconfig">
<title>Config options for the 2.6.x kernel</title>
<body>

<p>
Now we will look at some of the options we will have to enable in the 2.6
kernel to ensure proper USB support for our devices. If you are using a 2.4
kernel, please proceed with <uri link="#2.4.xconfig">Config options for the
2.4.x kernel</uri>.
</p>

<note>
Examples in this document will show configuration options for basic USB
support as well as those needed commonly, for example a USB mass storage
device (most cameras and USB pen drives). If you have a specific USB device
that needs to be configured, please look up your device's manual or search
online to see if that device has support built-in into the kernel or custom
drivers that you can use. Please note that for the sake of ease, all examples
have the options compiled into the kernel. If you would like to have a modular
kernel, ensure that you note down the various modules and adjust your config
files accordingly.
</note>

<pre caption="make menuconfig options for 2.6 kernels">
Device Drivers  ---&gt;
  SCSI device support  ---&gt;

<comment>(Although SCSI will be enabled automatically when selecting USB Mass Storage,
we need to enable disk support.)</comment>
---   SCSI support type (disk, tape, CD-ROM)
&lt;*&gt;   SCSI disk support

<comment>(Then move back a level and go into USB support)</comment>
USB support  ---&gt;

<comment>(This is the root hub and is required for USB support.
If you'd like to compile this as a module, it will be called usbcore.)</comment>
&lt;*&gt; Support for Host-side USB

<comment>(Enable this option to see your USB devices in /proc/bus/usb.
This is recommended.)</comment>
 [*]   USB device filesystem

<comment>(Select at least one of the HCDs. If you are unsure, picking all is fine.)</comment>
--- USB Host Controller Drivers
&lt;*&gt; EHCI HCD (USB 2.0) support
&lt; &gt; OHCI HCD support
&lt;*&gt; UHCI HCD (most Intel and VIA) support

<comment>(Moving a little further down, we come to CDC and mass storage.)</comment>
&lt; &gt; USB Modem (CDC ACM) support
&lt;*&gt; USB Printer support
&lt;*&gt; USB Mass Storage support
 [*]   USB Mass Storage Write-Protected Media Detection (EXPERIMENTAL)

<comment>(Then the HID bits.
You have to select HID input support if you have a USB keyboard,
mouse, joystick or any other USB input device)</comment>
--- USB Input Devices
&lt;*&gt; USB Human Interface Device (full HID) support
 [*]   HID input layer support

<comment>(If you have a USB Network Card like the RTL8150, you'll need this)</comment>
USB Network Adapters  --->
    &lt;*&gt; USB RTL8150 based ethernet device support (EXPERIMENTAL)

<comment>(If you have a serial to USB converter like the Prolific 2303, you'll need this)</comment>
USB Serial Converter support  --->
    &lt;*&gt; USB Serial Converter support
    &lt;*&gt; USB Prolific 2303 Single Port Serial Driver (NEW)
</pre>

<p>
Now that your options are set, you can (re)compile the kernel and USB support
should be functional once you reboot into the new kernel. You can now proceed
to <uri link="#postkern">Seeing USB at work</uri> and see if everything is
working as it should.
</p>

</body>
</section>
<section id="2.4.xconfig">
<title>Config options for the 2.4.x kernel</title>
<body>

<p>
We will look at the options the we will have to enable in the 2.4 kernel to
ensure proper USB support for our devices. If you are using a 2.6 kernel,
please look at <uri link="#2.6.xconfig">Config options for the 2.6.x
kernel</uri>.
</p>

<note>
Examples in this document will show configuration options for basic USB
support as well as those needed commonly, for example a USB mass storage
device (most cameras and USB pen drives). If you have a specific USB device
that needs to be configured, please look up your device's manual or search
online to see if that device has support built-in into the kernel or custom
drivers that you can use. Please note that for the sake of ease, all examples
have the options compiled into the kernel. If you would like to have a modular
kernel, ensure that you note down the various modules and adjust your config
files accordingly.
</note>

<pre caption="make menuconfig options for 2.4 kernels">
<comment>(This immediate config is only for those who have USB input devices.
Input core support is needed by USB HID later.)</comment>
Input core support  ---&gt;
   &lt;*&gt; Input core support
   &lt; &gt;   Keyboard support
   &lt; &gt;   Mouse support
   &lt; &gt;   Event interface support

USB support  ---&gt;

<comment>(This is the root hub and is required for USB support.
If you'd like to compile this as a module, it will be called usbcore.o)</comment>
&lt;*&gt; Support for USB

<comment>(Enable this option to see your USB devices in /proc/bus/usb.
This is recommended.)</comment>
 [*]   Preliminary USB device filesystem

<comment>(Select at least one of the HCDs. If you are unsure, picking all is fine.)</comment>
--- USB Host Controller Drivers
&lt;*&gt;   UHCI Alternate Driver (JE) support
&lt; &gt;   OHCI (Compaq, iMacs, OPTi, SiS, ALi, ...) support

<comment>(This is the device section. Select only what you need.)</comment>
--- USB Device Class drivers
&lt; &gt;   USB Audio support
&lt;*&gt;   USB Mass Storage support
&lt; &gt;   USB Modem (CDC ACM) support
&lt;*&gt;   USB Printer support

<comment>(Followed by the HID section. This is needed if you have an USB based input device.)</comment>
--- USB Human Interface Devices (HID)
&lt;*&gt;   USB Human Interface Device (full HID) support
 [*]     HID input layer support

<comment>(If you have a serial to USB converter like the Prolific 2303, you'll need this)</comment>
USB Serial Converter support  --->
    &lt;*&gt; USB Serial Converter support
    &lt;*&gt; USB Prolific 2303 Single Port Serial Driver (NEW)
</pre>

<p>
Now that the options are set, you can (re)compile the kernel and USB support
should be functional once you reboot into the new kernel.
</p>

</body>
</section>
</chapter>

<chapter id="postkern">
<title>Seeing USB at work</title>
<section>
<title>dmesg is your friend!</title>
<body>

<p>
The time has finally come to play with those USB devices :) So let's get
started. In this chapter, we'll see how the system responds to various USB
devices. We'll start by plugging in a USB 512 MB Memory Stick/Pen Drive. You
could use some other similar mass storage device. We will primarily use
<c>dmesg</c> to see what is happening and how the system responds to the
device.
</p>

<note>
<c>dmesg</c> will generally give a lot of output up front before coming to the
info we need, as it reads the kernel ring buffer that has all the boot up
messages as well. The output in the following examples have only the relevant
portion(s) and extra spaces in between to enable better readability. If needed
please use a <c>dmesg | more</c> or <c>dmesg | less</c> to see the output
better in your system.
</note>

<pre caption="dmesg output for Memory Stick">
<comment>(Plug in Memory Stick into available USB port and then..)</comment>
# <i>dmesg | less</i>

<comment>(The device is picked up as a USB 1.1 and allocated an address.
Also says what HCD it is using.)</comment>
usb 1-1: new full speed USB device using uhci_hcd and address 2

<comment>(SCSI emulation automatically kicks in)</comment>
scsi0 : SCSI emulation for USB Mass Storage devices
usb-storage: device found at 2

<comment>(Now the device information including model number is retrieved)</comment>
usb-storage: waiting for device to settle before scanning
  Vendor: JetFlash  Model: TS512MJF2A        Rev: 1.00
  Type:   Direct-Access                      ANSI SCSI revision: 02
SCSI device sda: 1003600 512-byte hdwr sectors (514 MB)

<comment>(The write-protect sense is EXPERIMENTAL code in the later kernels)</comment>
sda: Write Protect is off
sda: Mode Sense: 0b 00 00 08
sda: assuming drive cache: write through
SCSI device sda: 1003600 512-byte hdwr sectors (514 MB)
/dev/scsi/host0/bus0/target0/lun0: p1
Attached scsi removable disk sda at scsi0, channel 0, id 0, lun 0
Attached scsi generic sg0 at scsi0, channel 0, id 0, lun 0,  type 0
usb-storage: device scan complete
<comment>(At this point, the device is generally accessible by mounting /dev/sda1)</comment>

<comment>(When the device is disconnected, the system acknowledges the same)</comment>
usb 1-1: USB disconnect, address 2
</pre>

<p>
Once the device is connected and mounted, you can access it like a normal hard
disk. Usual operations like <c>cp</c>, <c>mv</c>, <c>rm</c>, etc work fine. You
could also create a filesystem on the USB stick/format it.
</p>

<pre caption="Accessing the Memory Stick">
# <i>mount /dev/sda1 /mnt/usb</i>
# <i>df -h</i>
Filesystem            Size  Used Avail Use% Mounted on
/dev/hda8             9.4G  7.5G  1.9G  80% /
/dev/hda9              11G  8.1G  2.4G  78% /usr
none                  189M     0  189M   0% /dev/shm
/dev/sda1             490M   34M  457M   7% /mnt/usb
</pre>

<note>
Digital cameras can be accessed the same way as memory sticks. I have a Nikon
Coolpix 5200 and this is the way I access it. Cameras these days usually have
two modes to transfer pictures; USB mass storage and PTP (Picture Transfer
Protocol). The camera is set to USB mass storage mode and hence the procedure is
exactly the same as that of accessing a memory stick because of which I have not
explained in detail about it. Please note that this may NOT work in all cases
and with all digital cameras that have USB support.
</note>

<p>
How would a USB mouse show up in case you had one? It will show up as an HID
device.
</p>

<pre caption="USB Optical Mouse">
# <i>dmesg | grep USB</i>
drivers/usb/input/hid-core.c: v2.0:USB HID core driver
usb 1-1: new low speed USB device using address 2
input: USB HID v1.10 Mouse [Logitech USB-PS/2 Optical Mouse] on usb-0000:00:07.2-1
</pre>

<p>
Another nifty command you can use to see the status of your USB ports is
<c>lsusb</c>. This is part of <c>sys-apps/usbutils</c> and will be covered in
the next chapter.
</p>

</body>
</section>
</chapter>

<chapter>
<title>Userspace USB</title>
<section>
<title>Nifty tools</title>
<body>

<p>
So far we've seen how much support exists on the kernel/system side for USB on
Linux. Now we'll take a peek into what kind of support is provided by Gentoo
for USB in the userspace.
</p>

<p>
One of the most useful tools around is <c>lsusb</c>. This lists all the usb
devices connected to the system. Installing it is a breeze.
</p>

<pre caption="Installing usbutils">
# <i>emerge usbutils</i>
</pre>

<p>
Once installed, you can just run <c>lsusb</c> to get simple info on the USB
devices attached to the machine.
</p>

<note>
You have to be root in most cases to run <c>lsusb</c>.
</note>

<warn>
<c>lsusb</c> reads the information for the USB devices from
<path>/proc/bus/usb</path>. If you have not enabled that in your kernel,
chances are that <c>lsusb</c> may not work at all. Please ensure you have
<path>/proc</path> filesystem support enabled in your kernel and that
<c>usbfs</c> is mounted at <path>/proc/bus/usb</path> (which should happen
automatically).
</warn>

<pre caption="lsusb at work">
# <i>lsusb</i>
<comment>(This is the 512 MB Memory Stick from Transcend)</comment>
Bus 001 Device 003: ID 0c76:0005 JMTek, LLC. USBdisk
<comment>(This is the Optical Mouse)</comment>
Bus 001 Device 002: ID 046d:c00e Logitech, Inc. Optical Mouse
<comment>(This is the root hub)</comment>
Bus 001 Device 001: ID 0000:0000
</pre>

<p>
If you are one of those types who love to see lots of information, you have
the option of running <c>lsusb -v</c>. Try that and see the amount of info it
gives out. Another good option is that <c>lsusb</c> dumps the current physical
USB hierarchy as a tree and thus makes it easier to understand the exact
device map. The command is <c>lsusb -t</c>. For example,
</p>

<pre caption="lsusb showing USB hierarchy">
# <i>lsusb -t</i>
Bus#  1
`-Dev#   1 Vendor 0x0000 Product 0x0000
  |-Dev#   2 Vendor 0x046d Product 0xc00e
  `-Dev#   3 Vendor 0x0c76 Product 0x0005
</pre>

<p>
You can easily correlate the outputs of <c>lsusb</c> and <c>lsusb -t</c>,
which helps debugging as well as understanding how USB works.
</p>

</body>
</section>
<section>
<title>Hot or Cold plug??</title>
<body>

<p>
Gentoo uses two packages, <c>sys-apps/hotplug</c> and <c>sys-apps/coldplug</c>
to do some magic with <e>hot-pluggable</e> devices. Just like any other magic
trick, there is a simple logic behind this one too. We shall now see what that
is, and in the process hopefully we will be able to understand these twins
better.
</p>

<p>
Firmware can be defined as the software on a piece of hardware that is loaded
and executed but can't be modified easily. Many devices have firmware in them
to ensure that they work properly and often firmware may contain code that is
critical to ensure that the hardware performs as expected. Firmware is present
in a wide variety of computer devices ranging from ROM chips to state of the
art USB and PCMCIA cards. When a device is plugged in, the firmware (which may,
in some cases, be the driver as well) is read and loaded onto memory after
which the device can be used by the system.
</p>

<p>
To cut the long story short, Gentoo uses <c>sys-apps/hotplug</c> to handle
the firmware side of things in <e>hot-pluggable</e> devices.
<c>sys-apps/hotplug</c> will use the required firmware to make that device
usable. The firmware should be put in the <path>/lib/firmware</path> directory
and is picked up from there. Getting it is simple; the usual emerge will do.
</p>

<pre caption="Installing hotplug">
# <i>emerge hotplug</i>
</pre>

<p>
Now the obvious question would be, what is coldplug and why is it needed?
<c>sys-apps/coldplug</c> does what hotplug does, but it does it for
<e>hot-pluggable</e> devices that are already connected at boot time. A good
example of this would be a USB Network card. Earlier, hotplug was the package
responsible for handling both, but then it was split into hotplug and coldplug,
with coldplug doing all the work. Install it if you have <e>hot-pluggable</e>
devices that you need activated on boot up.
</p>

<pre caption="Installing coldplug">
# <i>emerge coldplug</i>
<comment>(And you can add it to the boot runlevel)</comment>
# <i>rc-update add coldplug boot</i>
 * coldplug added to runlevel boot
 * rc-update complete.
</pre>

<note>
The above initscript does what hotplug's initscript used to do (for already
attached hot-pluggable devices). The current <path>/etc/init.d/hotplug</path>
script does nothing more than check if the CONFIG_HOTPLUG is enabled for the
current kernel.
</note>

</body>
</section>
</chapter>

<chapter>
<title>And thanks to...</title>
<section>
<title>References</title>
<body>

<p>
A good number of online documents helped me during the development of this
document and there are some that are highly technical but truly interesting. 
I thought they all deserve some credit, so here we go!
</p>

<ul>
  <li><uri link="http://www.usb.org">The Official USB Website</uri></li>
  <li><uri link="http://www.usb.org/faq">The USB FAQ</uri></li>
  <li>
    <uri
    link="http://h18000.www1.hp.com/productinfo/development/openhci.html">Compaq's
    OHCI Standard</uri>
  </li>
  <li>
    <uri link="http://developer.intel.com/technology/usb/uhci11d.htm">Intel's
    UHCI Standard</uri>
  </li>
  <li>
    <uri link="http://www.intel.com/technology/usb/ehcispec.htm">Intel's EHCI
    Standard</uri>
  </li>
</ul>

</body>
</section>
</chapter>
</guide>
