From owner-freebsd-current@FreeBSD.ORG Wed Sep 8 17:39:19 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 0859416A4CE; Wed, 8 Sep 2004 17:39:19 +0000 (GMT) Received: from harmony.village.org (rover.village.org [168.103.84.182]) by mx1.FreeBSD.org (Postfix) with ESMTP id 6113B43D54; Wed, 8 Sep 2004 17:39:18 +0000 (GMT) (envelope-from imp@bsdimp.com) Received: from localhost (warner@rover2.village.org [10.0.0.1]) by harmony.village.org (8.13.1/8.13.1) with ESMTP id i88Habw0049990; Wed, 8 Sep 2004 11:36:38 -0600 (MDT) (envelope-from imp@bsdimp.com) Date: Wed, 08 Sep 2004 11:37:07 -0600 (MDT) Message-Id: <20040908.113707.54185659.imp@bsdimp.com> To: roam@ringlet.net From: "M. Warner Losh" In-Reply-To: <20040908150943.GA1924@straylight.m.ringlet.net> References: <20040908150943.GA1924@straylight.m.ringlet.net> X-Mailer: Mew version 3.3 on Emacs 21.3 / Mule 5.0 (SAKAKI) Mime-Version: 1.0 Content-Type: Multipart/Mixed; boundary="--Next_Part(Wed_Sep__8_11:37:07_2004_385)--" Content-Transfer-Encoding: 7bit cc: freebsd-hackers@freebsd.org cc: freebsd-current@freebsd.org Subject: Re: [PATCH] Fix USB panics 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: Wed, 08 Sep 2004 17:39:19 -0000 ----Next_Part(Wed_Sep__8_11:37:07_2004_385)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Peter, thanks again for the excellent anaylsis of the problem. I introduced this when I cleaned up the load a driver will now cause usb to attach a device case. You are correct as far as I can tell and can test. Here's the patch that I've come up with. Does it work for you? Warner ----Next_Part(Wed_Sep__8_11:37:07_2004_385)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename=usb-diff ? P ? PP Index: uhub.c =================================================================== RCS file: /home/ncvs/src/sys/dev/usb/uhub.c,v retrieving revision 1.62 diff -u -r1.62 uhub.c --- uhub.c 15 Aug 2004 23:39:18 -0000 1.62 +++ uhub.c 8 Sep 2004 17:34:21 -0000 @@ -90,7 +90,6 @@ Static void uhub_intr(usbd_xfer_handle, usbd_private_handle,usbd_status); #if defined(__FreeBSD__) -Static bus_child_detached_t uhub_child_detached; Static bus_child_location_str_t uhub_child_location_str; Static bus_child_pnpinfo_str_t uhub_child_pnpinfo_str; #endif @@ -110,7 +109,6 @@ uhub_match, uhub_attach, uhub_detach, uhub_activate); #elif defined(__FreeBSD__) USB_DECLARE_DRIVER_INIT(uhub, - DEVMETHOD(bus_child_detached, uhub_child_detached), DEVMETHOD(bus_child_pnpinfo_str, uhub_child_pnpinfo_str), DEVMETHOD(bus_child_location_str, uhub_child_location_str), DEVMETHOD(bus_driver_added, bus_generic_driver_added), @@ -123,7 +121,6 @@ devclass_t uhubroot_devclass; Static device_method_t uhubroot_methods[] = { - DEVMETHOD(bus_child_detached, uhub_child_detached), DEVMETHOD(bus_child_location_str, uhub_child_location_str), DEVMETHOD(bus_child_pnpinfo_str, uhub_child_pnpinfo_str), DEVMETHOD(bus_driver_added, bus_generic_driver_added), @@ -378,15 +375,17 @@ DPRINTFN(3,("uhub_explore: %s port %d status 0x%04x 0x%04x\n", USBDEVNAME(sc->sc_dev), port, status, change)); if (change & UPS_C_PORT_ENABLED) { - DPRINTF(("uhub_explore: C_PORT_ENABLED\n")); + DPRINTF(("uhub_explore: C_PORT_ENABLED 0x%x\n", change)); usbd_clear_port_feature(dev, port, UHF_C_PORT_ENABLE); if (change & UPS_C_CONNECT_STATUS) { + printf("Change is 0x%x\n", change); /* Ignore the port error if the device vanished. */ } else if (status & UPS_PORT_ENABLED) { printf("%s: illegal enable change, port %d\n", USBDEVNAME(sc->sc_dev), port); } else { + printf("up->restartcnt is %d change is %x\n", up->restartcnt, change); /* Port error condition. */ if (up->restartcnt) /* no message first time */ printf("%s: port error, restarting " @@ -398,7 +397,7 @@ else printf("%s: port error, giving up " "port %d\n", - USBDEVNAME(sc->sc_dev), port); + USBDEVNAME(sc->sc_dev), port); } } if (!(change & UPS_C_CONNECT_STATUS)) { @@ -683,35 +682,6 @@ iface->idesc->bInterfaceSubClass); } return (0); -} - -/* Called when a device has been detached from it */ -Static void -uhub_child_detached(device_t self, device_t child) -{ - struct uhub_softc *sc = device_get_softc(self); - usbd_device_handle devhub = sc->sc_hub; - usbd_device_handle dev; - int nports; - int port; - int i; - - if (!devhub->hub) - /* should never happen; children are only created after init */ - panic("hub not fully initialised, but child deleted?"); - - nports = devhub->hub->hubdesc.bNbrPorts; - for (port = 0; port < nports; port++) { - dev = devhub->hub->ports[port].device; - if (dev == NULL || dev->subdevs == NULL) - continue; - for (i = 0; dev->subdevs[i]; i++) { - if (dev->subdevs[i] == child) { - dev->subdevs[i] = NULL; - return; - } - } - } } #endif Index: usb_subr.c =================================================================== RCS file: /home/ncvs/src/sys/dev/usb/usb_subr.c,v retrieving revision 1.69 diff -u -r1.69 usb_subr.c --- usb_subr.c 15 Aug 2004 23:39:18 -0000 1.69 +++ usb_subr.c 8 Sep 2004 17:34:21 -0000 @@ -905,6 +905,10 @@ if (dv) { return (USBD_NORMAL_COMPLETION); } + /* + * Free subdevs so we can reallocate it larger for the number of + * interfaces + */ tmpdv = dev->subdevs; dev->subdevs = NULL; free(tmpdv, M_USB); @@ -1016,9 +1020,6 @@ if (dv != NULL) { return (USBD_NORMAL_COMPLETION); } - tmpdv = dev->subdevs; - dev->subdevs = 0; - free(tmpdv, M_USB); /* * The generic attach failed, but leave the device as it is. @@ -1346,11 +1347,13 @@ di->udi_speed = dev->speed; if (dev->subdevs != NULL) { - for (i = 0; dev->subdevs[i] && - i < USB_MAX_DEVNAMES; i++) { - strncpy(di->udi_devnames[i], USBDEVPTRNAME(dev->subdevs[i]), - USB_MAX_DEVNAMELEN); - di->udi_devnames[i][USB_MAX_DEVNAMELEN-1] = '\0'; + for (i = 0; dev->subdevs[i] && i < USB_MAX_DEVNAMES; i++) { + if (device_is_attached(dev->subdevs[i])) + strlcpy(di->udi_devnames[i], + USBDEVPTRNAME(dev->subdevs[i]), + USB_MAX_DEVNAMELEN); + else + di->udi_devnames[i][0] = 0; } } else { i = 0; ----Next_Part(Wed_Sep__8_11:37:07_2004_385)----