Index: usb.c =================================================================== RCS file: /cvs/src/sys/dev/usb/usb.c,v retrieving revision 1.95 diff -u -p -r1.95 usb.c --- usb.c 31 Mar 2014 16:18:06 -0000 1.95 +++ usb.c 9 May 2014 13:10:39 -0000 @@ -1,4 +1,4 @@ -/* $OpenBSD: usb.c,v 1.95 2014/03/31 16:18:06 mpi Exp $ */ +/* $OpenBSD: usb.c,v 1.94 2014/03/08 11:49:19 mpi Exp $ */ /* $NetBSD: usb.c,v 1.77 2003/01/01 00:10:26 thorpej Exp $ */ /* @@ -92,7 +92,6 @@ struct usb_softc { struct device sc_dev; /* base device */ struct usbd_bus *sc_bus; /* USB controller */ struct usbd_port sc_port; /* dummy port for root hub */ - int sc_speed; struct usb_task sc_explore_task; @@ -126,9 +125,6 @@ void usb_attach(struct device *, struc int usb_detach(struct device *, int); int usb_activate(struct device *, int); -int usb_attach_roothub(struct usb_softc *); -void usb_detach_roothub(struct usb_softc *); - struct cfdriver usb_cd = { NULL, "usb", DV_DULL }; @@ -151,7 +147,10 @@ void usb_attach(struct device *parent, struct device *self, void *aux) { struct usb_softc *sc = (struct usb_softc *)self; + struct usbd_device *dev; + usbd_status err; int usbrev; + int speed; if (usb_nbuses == 0) { rw_init(&usbpalock, "usbpalock"); @@ -172,13 +171,13 @@ usb_attach(struct device *parent, struct switch (usbrev) { case USBREV_1_0: case USBREV_1_1: - sc->sc_speed = USB_SPEED_FULL; + speed = USB_SPEED_FULL; break; case USBREV_2_0: - sc->sc_speed = USB_SPEED_HIGH; + speed = USB_SPEED_HIGH; break; case USBREV_3_0: - sc->sc_speed = USB_SPEED_SUPER; + speed = USB_SPEED_SUPER; break; default: printf(", not supported\n"); @@ -207,10 +206,17 @@ usb_attach(struct device *parent, struct return; } - - - if (!usb_attach_roothub(sc)) { - struct usbd_device *dev = sc->sc_bus->root_hub; + err = usbd_new_device(&sc->sc_dev, sc->sc_bus, 0, speed, 0, + &sc->sc_port); + if (!err) { + dev = sc->sc_port.device; + if (dev->hub == NULL) { + sc->sc_bus->dying = 1; + printf("%s: root device is not a hub\n", + sc->sc_dev.dv_xname); + return; + } + sc->sc_bus->root_hub = dev; #if 1 /* * Turning this code off will delay attachment of USB devices @@ -220,8 +226,11 @@ usb_attach(struct device *parent, struct if (cold && (sc->sc_dev.dv_cfdata->cf_flags & 1)) dev->hub->explore(sc->sc_bus->root_hub); #endif + } else { + printf("%s: root hub problem, error=%d\n", + sc->sc_dev.dv_xname, err); + sc->sc_bus->dying = 1; } - if (cold) sc->sc_bus->use_polling--; @@ -234,41 +243,6 @@ usb_attach(struct device *parent, struct } } -int -usb_attach_roothub(struct usb_softc *sc) -{ - struct usbd_device *dev; - - if (usbd_new_device(&sc->sc_dev, sc->sc_bus, 0, sc->sc_speed, 0, - &sc->sc_port)) { - printf("%s: root hub problem\n", sc->sc_dev.dv_xname); - sc->sc_bus->dying = 1; - return (1); - } - - dev = sc->sc_port.device; - if (dev->hub == NULL) { - printf("%s: root device is not a hub\n", sc->sc_dev.dv_xname); - sc->sc_bus->dying = 1; - return (1); - } - sc->sc_bus->root_hub = dev; - - return (0); -} - -void -usb_detach_roothub(struct usb_softc *sc) -{ - /* Make all devices disconnect. */ - if (sc->sc_port.device != NULL) - usb_disconnect_port(&sc->sc_port, (struct device *)sc); - - usb_rem_wait_task(sc->sc_bus->root_hub, &sc->sc_explore_task); - - sc->sc_bus->root_hub = NULL; -} - void usb_create_task_threads(void *arg) { @@ -892,22 +866,23 @@ int usb_activate(struct device *self, int act) { struct usb_softc *sc = (struct usb_softc *)self; - int rv = 0; + struct usbd_device *dev = sc->sc_port.device; + int i, rv = 0, r; switch (act) { - case DVACT_QUIESCE: - sc->sc_bus->dying = 1; - if (sc->sc_bus->root_hub != NULL) - usb_detach_roothub(sc); - break; - case DVACT_WAKEUP: - sc->sc_bus->dying = 0; - if (!usb_attach_roothub(sc)) - usb_needs_explore(sc->sc_bus->root_hub, 0); - break; case DVACT_DEACTIVATE: - rv = config_activate_children(self, act); sc->sc_bus->dying = 1; + if (dev != NULL && dev->cdesc != NULL && + dev->subdevs != NULL) { + for (i = 0; dev->subdevs[i]; i++) { + r = config_deactivate(dev->subdevs[i]); + if (r) + rv = r; + } + } + break; + case DVACT_RESUME: + usb_needs_explore(sc->sc_bus->root_hub, 0); break; default: rv = config_activate_children(self, act); @@ -926,7 +901,11 @@ usb_detach(struct device *self, int flag sc->sc_bus->dying = 1; if (sc->sc_bus->root_hub != NULL) { - usb_detach_roothub(sc); + /* Make all devices disconnect. */ + if (sc->sc_port.device != NULL) + usb_disconnect_port(&sc->sc_port, self); + + usb_rem_wait_task(sc->sc_bus->root_hub, &sc->sc_explore_task); if (--usb_nbuses == 0) { usb_run_tasks = usb_run_abort_tasks = 0;