Subject: USB device attachment
To: None <tech-kern@netbsd.org>
From: Lennart Augustsson <lennart@augustsson.net>
List: tech-kern
Date: 07/23/1999 15:35:20
This probably only of interest to USB freaks and autoconf aficionados.

I've been thinking about the way usb devices attach, and I've
come to the conclusion that it's not ideal.

Here's how it works now: the USB devices form a tree with
hubs as the nodes that branch out (i.e. the interior nodes).
USB devices always attach to hubs.  An example:


                           uhub0  (root)
                          /  |  \
                         /   |   \
                        /    |    \
                    uhub1  ugen0   |\
                    / | \          | \
                   /  |  \         |  \
                  /   |   \     ukbd1  ums1
               ums0 ukbd1  ulp0

There are really three different kinds of scenarios for
a USB device (not counting hubs):
  1. The device as a whole is claimed by a driver.  This
     happens with an ordinary e.g. printer.  Illustrated
     by ums0, ukbd0, and ulpt0.
  2. The device is not claimed, but some of its interfaces
     (subparts of the device) are.  This can happen for
     compound devices.  I have a keyboard&mouse combo that
     appears as one USB device, but it has two interfaces
     that are claimed by the keyboard and mouse drivers.
     Illustrated by ukbd1&ums1.
  3. No specific driver claimed the device, the generic
     driver then takes it.  Illustrated by ugen0.

There are two problems with this approach.

First, a minor one: It looks funny to have all the interfaces of a
compound device (ukbd1&ums1) attach to the hub when in reality they
are the same USB device.  But the current solution works, even if
it's not the prettiest one.

Second, what about LKMs?  Assume that a new device is plugged in.
If it is a new kind of device it will become an ugen device.
A little later a LKM driver for this device is loaded.  But now
it is too late.  The ugen driver will already have claimed the
device and AFAIK a LKM cannot grab a device that there is already
a driver for.  This point is, IMO, really bad, because it means
that LKMs cannot be used in a nice way.


So I propose a restructuring:  Every USB device, except hubs,
will have the same "device driver", udev.  Attaching to this
driver are then the specific drivers for a device.
Our example now becomes

                           uhub0  (root)
                          /  |  \
                         /   |   \
                        /    |    \
                    uhub1  udev3  udev4
                    / | \          | \
                   /  |  \         |  \
                  /   |   \     ukbd1  ums1
              udev0 udev1 udev2
                |     |    |
               ums0 ukbd1 ulp0

Note that the compound device is now handled in a more
logical way.  And, more importantly, the ugen0 driver has
been replaced by udev3.  The udev driver will thus replace
the generic driver (and provide the same functionality),
but if a more specific driver shows up later (as a LKM)
it can attach to the udev and claim the device.

I think this is a cleaner design.  The drawback is the
proliferation of devices (which don't have to have device nodes).

You could even take this a step further and have a udev device
for each hub as well, but I think that is overdoing it. :)

Comments?


--

        -- Lennart