From owner-freebsd-current@FreeBSD.ORG Tue Dec 28 01:09:41 2004 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 86E2816A4CE for ; Tue, 28 Dec 2004 01:09:41 +0000 (GMT) Received: from freebsd3.cimlogic.com.au (adsl-20-121.swiftdsl.com.au [218.214.20.121]) by mx1.FreeBSD.org (Postfix) with ESMTP id 310AB43D48 for ; Tue, 28 Dec 2004 01:09:40 +0000 (GMT) (envelope-from jb@cimlogic.com.au) Received: by freebsd3.cimlogic.com.au (Postfix, from userid 102) id D3D726AA01; Tue, 28 Dec 2004 12:09:38 +1100 (EST) Date: Tue, 28 Dec 2004 12:09:38 +1100 From: John Birrell To: current@freebsd.org Message-ID: <20041228010938.GA39686@freebsd3.cimlogic.com.au> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.2.1i Subject: USB problems X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 28 Dec 2004 01:09:41 -0000 [ 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