Subject: Re: kern/32011 usb HC detach race condition
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Matthew Orgass <darkstar@city-net.com>
List: netbsd-bugs
Date: 11/21/2006 18:40:02
The following reply was made to PR kern/32011; it has been noted by GNATS.
From: Matthew Orgass <darkstar@city-net.com>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: kern/32011 usb HC detach race condition
Date: Tue, 21 Nov 2006 10:59:42 -0500 (EST)
An alternate patch that also add sc_dying setting to uhci, moves it in
ehci and ohci, removes it from usb_detach (where it is unnecessary),
and includes the patch above.
Index: sys/dev/usb/uhci.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/uhci.c,v
retrieving revision 1.204
diff -u -p -r1.204 uhci.c
--- sys/dev/usb/uhci.c 31 Oct 2006 20:43:31 -0000 1.204
+++ sys/dev/usb/uhci.c 21 Nov 2006 16:34:54 -0000
@@ -573,6 +573,7 @@ uhci_activate(device_ptr_t self, enum de
return (EOPNOTSUPP);
case DVACT_DEACTIVATE:
+ sc->sc_dying = 1;
if (sc->sc_child != NULL)
rv = config_deactivate(sc->sc_child);
break;
Index: sys/dev/usb/ehci.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/ehci.c,v
retrieving revision 1.114
diff -u -p -r1.114 ehci.c
--- sys/dev/usb/ehci.c 31 Oct 2006 20:43:31 -0000 1.114
+++ sys/dev/usb/ehci.c 21 Nov 2006 16:34:59 -0000
@@ -983,9 +983,9 @@ ehci_activate(device_ptr_t self, enum de
return (EOPNOTSUPP);
case DVACT_DEACTIVATE:
+ sc->sc_dying = 1;
if (sc->sc_child != NULL)
rv = config_deactivate(sc->sc_child);
- sc->sc_dying = 1;
break;
}
return (rv);
Index: sys/dev/usb/ohci.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/ohci.c,v
retrieving revision 1.178
diff -u -p -r1.178 ohci.c
--- sys/dev/usb/ohci.c 31 Oct 2006 20:43:31 -0000 1.178
+++ sys/dev/usb/ohci.c 21 Nov 2006 16:35:04 -0000
@@ -374,9 +374,9 @@ ohci_activate(device_ptr_t self, enum de
return (EOPNOTSUPP);
case DVACT_DEACTIVATE:
+ sc->sc_dying = 1;
if (sc->sc_child != NULL)
rv = config_deactivate(sc->sc_child);
- sc->sc_dying = 1;
break;
}
return (rv);
Index: sys/dev/usb/usb.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/usb.c,v
retrieving revision 1.90
diff -u -p -r1.90 usb.c
--- sys/dev/usb/usb.c 31 Oct 2006 20:43:31 -0000 1.90
+++ sys/dev/usb/usb.c 21 Nov 2006 16:35:06 -0000
@@ -848,21 +848,17 @@ usb_detach(device_ptr_t self, int flags
DPRINTF(("usb_detach: start\n"));
- sc->sc_dying = 1;
+ /* Kill off event thread. */
+ while (sc->sc_event_thread != NULL) {
+ wakeup(&sc->sc_bus->needs_explore);
+ tsleep(sc, PWAIT, "usbdet", hz * 60);
+ }
+ DPRINTF(("usb_detach: event thread dead\n"));
/* Make all devices disconnect. */
if (sc->sc_port.device != NULL)
usb_disconnect_port(&sc->sc_port, self);
- /* Kill off event thread. */
- if (sc->sc_event_thread != NULL) {
- wakeup(&sc->sc_bus->needs_explore);
- if (tsleep(sc, PWAIT, "usbdet", hz * 60))
- printf("%s: event thread didn't die\n",
- USBDEVNAME(sc->sc_dev));
- DPRINTF(("usb_detach: event thread dead\n"));
- }
-
usbd_finish();
#ifdef USB_USE_SOFTINTR