Date: Sun, 15 Jun 2003 00:51:17 -0500 From: Craig Boston <craig@xfoil.gank.org> To: ticso@cicely.de, Bernd Walter <ticso@cicely12.cicely.de> Cc: current@FreeBSD.org Subject: Re: O(/E)HCI detach support patch Message-ID: <200306150051.17232.craig@xfoil.gank.org> In-Reply-To: <200306142124.39356.craig@xfoil.gank.org> References: <1055260269.91337.127.camel@owen1492.uf.corelab.com> <200306141902.52925.craig@xfoil.gank.org> <200306142124.39356.craig@xfoil.gank.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Below is a preliminary patch that seems to at least keep the machine from
panicing when detaching USB cards :)
It's still highly experimental, so use at your own risk. It works well enough
for me to plug in / unplug my cardbus card repeatedly (even with devices
attached to it). Theoretically this should also make the usb kernel module
unloadable, however that is untested.
WARNING: There may still be edge conditions or memory leaks lurking about, and
users of this patch are likely to be eaten by a grue.
Unplugging it while one of the devices is actively being used is probably a
very bad idea. I tried not to make the code too divergant from the NetBSD
path but probably wasn't 100% successful.
If the formatting gets mangled in the mail and anyone wants to try this patch,
mail me and I'll send it as a file. Feedback / comments / advice are much
appreciated.
Index: ehci_pci.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/ehci_pci.c,v
retrieving revision 1.2
diff -u -r1.2 ehci_pci.c
--- ehci_pci.c 12 Jun 2003 05:29:15 -0000 1.2
+++ ehci_pci.c 14 Jun 2003 21:48:26 -0000
@@ -263,9 +263,7 @@
if (err) {
device_printf(self, "USB init failed err=%d\n", err);
-#if 0 /* TODO */
ehci_pci_detach(self);
-#endif
return EIO;
}
return 0;
@@ -317,6 +315,7 @@
/* Device interface */
DEVMETHOD(device_probe, ehci_pci_probe),
DEVMETHOD(device_attach, ehci_pci_attach),
+ DEVMETHOD(device_detach, ehci_pci_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
/* Bus interface */
Index: ohci_pci.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/ohci_pci.c,v
retrieving revision 1.31
diff -u -r1.31 ohci_pci.c
--- ohci_pci.c 12 Jun 2003 05:29:15 -0000 1.31
+++ ohci_pci.c 15 Jun 2003 04:25:32 -0000
@@ -299,6 +299,7 @@
/* Device interface */
DEVMETHOD(device_probe, ohci_pci_probe),
DEVMETHOD(device_attach, ohci_pci_attach),
+ DEVMETHOD(device_detach, ohci_pci_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
/* Bus interface */
Index: uhci_pci.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/uhci_pci.c,v
retrieving revision 1.47
diff -u -r1.47 uhci_pci.c
--- uhci_pci.c 12 Jun 2003 05:29:15 -0000 1.47
+++ uhci_pci.c 15 Jun 2003 05:18:25 -0000
@@ -392,6 +392,7 @@
/* Device interface */
DEVMETHOD(device_probe, uhci_pci_probe),
DEVMETHOD(device_attach, uhci_pci_attach),
+ DEVMETHOD(device_detach, uhci_pci_detach),
DEVMETHOD(device_suspend, uhci_pci_suspend),
DEVMETHOD(device_resume, uhci_pci_resume),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
Index: uhub.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/uhub.c,v
retrieving revision 1.47
diff -u -r1.47 uhub.c
--- uhub.c 8 Aug 2002 12:05:50 -0000 1.47
+++ uhub.c 15 Jun 2003 04:39:13 -0000
@@ -87,6 +87,7 @@
Static usbd_status uhub_explore(usbd_device_handle hub);
Static void uhub_intr(usbd_xfer_handle, usbd_private_handle,usbd_status);
+Static int uhub_dummy_detach(device_t);
#if defined(__FreeBSD__)
Static bus_driver_added_t uhub_driver_added;
@@ -123,8 +124,7 @@
Static device_method_t uhubroot_methods[] = {
DEVMETHOD(device_probe, uhub_match),
DEVMETHOD(device_attach, uhub_attach),
-
- /* detach is not allowed for a root hub */
+ DEVMETHOD(device_detach, uhub_dummy_detach),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
@@ -535,6 +535,16 @@
return (0);
}
#endif
+
+/*
+ * Dummy detach for root hub when devices are being torn down
+ * Don't need to detach child devices since they're already gone
+ */
+Static int
+uhub_dummy_detach(device_t dev)
+{
+ return 0;
+}
/*
* Called from process context when the hub is gone.
Index: usb.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/usb.c,v
retrieving revision 1.87
diff -u -r1.87 usb.c
--- usb.c 14 Apr 2003 14:04:07 -0000 1.87
+++ usb.c 15 Jun 2003 05:20:58 -0000
@@ -121,6 +121,10 @@
struct proc *sc_event_thread;
+#if defined(__FreeBSD__)
+ dev_t dev;
+#endif
+
char sc_dying;
};
@@ -175,7 +179,8 @@
USB_DECLARE_DRIVER_INIT(usb,
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
- DEVMETHOD(device_shutdown, bus_generic_shutdown)
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+ DEVMETHOD(device_detach, usb_detach)
);
#if defined(__FreeBSD__)
@@ -295,8 +300,8 @@
usb_create_event_thread(sc);
/* The per controller devices (used for usb_discover) */
/* XXX This is redundant now, but old usbd's will want it */
- make_dev(&usb_cdevsw, device_get_unit(self), UID_ROOT, GID_OPERATOR,
- 0660, "usb%d", device_get_unit(self));
+ sc->dev = make_dev(&usb_cdevsw, device_get_unit(self), UID_ROOT,
+ GID_OPERATOR, 0660, "usb%d", device_get_unit(self));
if (!global_init_done) {
/* The device spitting out events */
make_dev(&usb_cdevsw, USB_DEV_MINOR, UID_ROOT, GID_OPERATOR,
@@ -850,20 +855,26 @@
}
return (rv);
}
+#endif
-int
-usb_detach(device_ptr_t self, int flags)
+USB_DETACH(usb)
{
+#if defined(__NetBSD__) || defined(__OpenBSD__)
struct usb_softc *sc = (struct usb_softc *)self;
+#elif defined(__FreeBSD__)
+ struct usb_softc *sc = device_get_softc(self);
+#endif
struct usb_event ue;
DPRINTF(("usb_detach: start\n"));
sc->sc_dying = 1;
+#if !defined(__FreeBSD__)
/* Make all devices disconnect. */
if (sc->sc_port.device != NULL)
usb_disconnect_port(&sc->sc_port, self);
+#endif
/* Kill off event thread. */
if (sc->sc_event_thread != NULL) {
@@ -890,17 +901,12 @@
ue.u.ue_ctrlr.ue_bus = USBDEVUNIT(sc->sc_dev);
usb_add_event(USB_EVENT_CTRLR_DETACH, &ue);
- return (0);
-}
-#elif defined(__FreeBSD__)
-int
-usb_detach(device_t self)
-{
- DPRINTF(("%s: unload, prevented\n", USBDEVNAME(self)));
+#if defined(__FreeBSD__)
+ destroy_dev(sc->dev);
+#endif
- return (EINVAL);
+ return (0);
}
-#endif
#if defined(__FreeBSD__)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200306150051.17232.craig>
