USB problems

From: John Birrell <jb_at_cimlogic.com.au>
Date: Tue, 28 Dec 2004 12:09:38 +1100
[ I'm not sure who the maintainer for FreeBSD's code is these days. ]

I've been encountering a number of problems with the USB implementation
in current. Although this message refers to current, I think the problems
are in RELENG_5 too.

1. The USB sub-system doesn't handle loading and unloading drivers properly.
   If a driver is unloaded when a USB device is still attached, the next
   time the driver is loaded, the kernel panics. This might not be such
   a problem to normal users because they don't have a need to do that, but
   during driver development when you want to load and unload repeatedly,
   it's a pain.

2. I have two devices that are based on Philips' ISP1581 USB 2.0 controller.
   Both are MPEG encoders and one has a TV tuner. The one without the
   tuner is Philips' USB-MPEG2 evaluation board which has example firmware
   on-board as a reference design. It isn't possible to use either of these
   boards with FreeBSD's USB implementation because of the over-zealous
   firmware code which stalls the control endpoint at every opportunity.

   The Windows driver that Philips' supply without source code appears to
   have no problems talking to the device. When I do the same things with
   FreeBSD, the continual control endpoint stalls result in not being
   able to even get the string descriptors for manufacturer and product
   (the firmware code stalls those requests).

   I think what is happening is that the uhci (and ehci etc) drivers are
   detecting the stall and not processing the data that is actually
   returned with the stall status. When I move the code:

   if (nstatus & UHCI_TD_ACTIVE)
      break;

   in uhci_idone() to the bottom of the loop, it returns the actlen
   properly (I think). At least I can get the data from the device despite
   the stall.

3. The usbd_bulk_transfer function calls tsleep() to wait for streaming
   data to become available. On current, this bumps into a KASSERT in
   msleep because Giant is not locked and no mutex has been supplied.
   In my driver, I need to run an 'encoder' thread which calls
   usbd_bulk_transfer() to gobble the incoming MPEG data stream. While
   this is going on, there is no syscall in progress because the
   application is off doing other things. It might be looking at the
   mmaped buffer or it may not.

   For FreeBSD, usbd_bulk_transfer() needs to change to allow the driver
   to specify it's mutex. I don't know what the implications are for
   uhci given that it hasn't been converted to use mutexes. Can anyone
   comment on that?

Where do we stand making architectural changes to the USB code given the
efforts to stay in sync with NetBSD/OpenBSD?

I'd love to get rid of the attach_args structure and just pass a
usbd_device_handle into the drivers, with struct usbd_device containing
a couple of extra variables for use during matching.

I'd like to remove the subdevs array from struct usbd_device under
FreeBSD because the parent/child device tree should only be managed by
bus routines. The relationship between a USB device and it's device_t
should just be a field in struct usbd_device and it should be cleared
when there is no device_t. Leaving a device_t hanging around when a
driver had been unloaded is what is causing the panics I am seeing.

I think that the uhub driver should have a uhub_driver_added routine rather
than using the generic one. I'd really like to see the uhub code re-match
vendor/product codes when a new driver is added, and if the new driver
matches, then uhub should detach ugen and use the new driver. Similarly,
when a driver is unloaded, if a USB device is still present, it should go
back to ugen.

-- 
John Birrell
Received on Tue Dec 28 2004 - 00:09:41 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:25 UTC