Date: Thu, 5 Jul 2007 02:55:53 GMT From: Victor Liu <victor.liu@gmail.com> To: freebsd-gnats-submit@FreeBSD.org Subject: usb/114310: USB hub attachment panics kernel during libusb device scan Message-ID: <200707050255.l652trbP013836@www.freebsd.org> Resent-Message-ID: <200707050300.l6530Ao8025080@freefall.freebsd.org>
index | next in thread | raw e-mail
>Number: 114310
>Category: usb
>Synopsis: USB hub attachment panics kernel during libusb device scan
>Confidential: no
>Severity: critical
>Priority: medium
>Responsible: freebsd-usb
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Thu Jul 05 03:00:09 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator: Victor Liu
>Release: 5.4-RELEASE
>Organization:
Fastsoft
>Environment:
FreeBSD xxxxxxxxxxxxxxxxxxxxxxxxx 5.4-RELEASE FreeBSD 5.4-RELEASE #44: Mon Jul 2 18:25:07 PDT 2007 root@xxxxxxxxxxxxxxxxxxxxxxxxx:/usr/src/sys/i386/compile/xxxxxxxxxxxxx i386
>Description:
When attaching a USB hub (anything from a generic DLink to a keyboard with integrated hub) while a userspace libusb query is going on, the kernel panics (trap 12, fault virtual address = 0xdeadc0e6) at usbd_device_fillinfo:1350; p->device is 0xdeadc0de.
I have experimented several times, I think the cause is during hub attachment, there is a tsleep when waiting for power to settle (uhub.c:288). In this time, libusb's usb_find_devices happens to request an ioctl for a device exploration. At this point, the port structures of the hub are not yet initialized.
I have a temporary fix that just initializes p->device to NULL before the sleep, but this doesn't solve a similar problem exists during hub detachment (which I haven't been able to narrow it down much further).
>How-To-Repeat:
Run a program that continuously polls for USB devices using libusb's usb_find_devices(), while attaching a USB hub. This won't cause it to crash everytime, but it is likely that out of 20 attachments, there will be at least one panic.
A piece of code along the lines of
while(1){
DPRINTF(("before usb_init\n"));
usb_init();
DPRINTF(("before usb_find_busses\n"));
usb_find_busses();
DPRINTF(("before usb_find_devices\n"));
usb_find_devices();
}
should do the trick of producing something like the log.
>Fix:
Proposed patch (only a hackish fix for the attachment problem):
@@ -284,6 +284,15 @@
goto bad;
}
+ // Fixes crash on hub attachment
+ // Need to init device to NULL before delay sleep;
+ // otherwise exploration could hit an uninit'd port
+ for (p = 0; p < nports; p++) {
+ struct usbd_port *up = &hub->ports[p];
+ up->device = NULL;
+ }
+ // end changes
+
/* Wait with power off for a while. */
usbd_delay_ms(dev, USB_POWER_DOWN_TIME);
>Release-Note:
>Audit-Trail:
>Unformatted:
home |
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200707050255.l652trbP013836>
