diff options
author | Federico G. Schwindt <fgsch@cvs.openbsd.org> | 1999-11-07 21:30:21 +0000 |
---|---|---|
committer | Federico G. Schwindt <fgsch@cvs.openbsd.org> | 1999-11-07 21:30:21 +0000 |
commit | 8a585a5da59b075490abbc480dedab8c55ae6bda (patch) | |
tree | 8f31d43a47eea2f44fba3f09f6a0dfd648135915 /sys/dev/usb/uhub.c | |
parent | 2acdd01a3952b5e93a21f5a2b0db395cef5c55be (diff) |
sync with NetBSD.
Diffstat (limited to 'sys/dev/usb/uhub.c')
-rw-r--r-- | sys/dev/usb/uhub.c | 100 |
1 files changed, 61 insertions, 39 deletions
diff --git a/sys/dev/usb/uhub.c b/sys/dev/usb/uhub.c index 4c3352028cb..517d48a29e3 100644 --- a/sys/dev/usb/uhub.c +++ b/sys/dev/usb/uhub.c @@ -1,5 +1,5 @@ -/* $OpenBSD: uhub.c,v 1.5 1999/09/27 18:03:55 fgsch Exp $ */ -/* $NetBSD: uhub.c,v 1.29 1999/09/15 10:25:31 augustss Exp $ */ +/* $OpenBSD: uhub.c,v 1.6 1999/11/07 21:30:19 fgsch Exp $ */ +/* $NetBSD: uhub.c,v 1.32 1999/10/13 08:10:56 augustss Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -51,6 +51,7 @@ #elif defined(__FreeBSD__) #include <sys/module.h> #include <sys/bus.h> +#include "bus_if.h" #endif #include <sys/proc.h> @@ -61,7 +62,7 @@ #include <dev/usb/usbdi_util.h> #include <dev/usb/usbdivar.h> -#ifdef USB_DEBUG +#ifdef UHUB_DEBUG #define DPRINTF(x) if (usbdebug) logprintf x #define DPRINTFN(n,x) if (usbdebug>(n)) logprintf x extern int usbdebug; @@ -82,13 +83,42 @@ usbd_status uhub_init_port __P((struct usbd_port *)); usbd_status uhub_explore __P((usbd_device_handle hub)); void uhub_intr __P((usbd_request_handle, usbd_private_handle, usbd_status)); -USB_DECLARE_DRIVER_NAME(usb, uhub); +#if defined(__FreeBSD__) +static bus_child_detached_t uhub_child_detached; +#endif + +USB_DECLARE_DRIVER_INIT(uhub, + DEVMETHOD(bus_child_detached, uhub_child_detached)); + +/* + * We need two attachment points: + * hub to usb and hub to hub + * Every other driver only connects to hubs + */ #if defined(__NetBSD__) || defined(__OpenBSD__) +/* Create the driver instance for the hub connected to hub case */ struct cfattach uhub_uhub_ca = { sizeof(struct uhub_softc), uhub_match, uhub_attach, uhub_detach, uhub_activate }; +#elif defined(__FreeBSD__) +/* Create the driver instance for the hub connected to usb case. */ +devclass_t uhubroot_devclass; + +static device_method_t uhubroot_methods[] = { + DEVMETHOD(device_probe, uhub_match), + DEVMETHOD(device_attach, uhub_attach), + + /* detach is not allowed for a root hub */ + {0,0} +}; + +static driver_t uhubroot_driver = { + "uhub", + uhubroot_methods, + sizeof(struct uhub_softc) +}; #endif USB_MATCH(uhub) @@ -163,7 +193,6 @@ USB_ATTACH(uhub) printf("%s: %d port%s with %d removable, %s powered\n", USBDEVNAME(sc->sc_dev), nports, nports != 1 ? "s" : "", nremov, dev->self_powered ? "self" : "bus"); - hub = malloc(sizeof(*hub) + (nports-1) * sizeof(struct usbd_port), M_USBDEV, M_NOWAIT); @@ -179,6 +208,7 @@ USB_ATTACH(uhub) dev->self_powered, dev->powersrc->parent, dev->powersrc->parent ? dev->powersrc->parent->self_powered : 0)); + if (!dev->self_powered && dev->powersrc->parent && !dev->powersrc->parent->self_powered) { printf("%s: bus powered hub connected to bus powered hub, " @@ -375,9 +405,8 @@ uhub_explore(dev) if (up->device) { /* Disconnected */ DPRINTF(("uhub_explore: device %d disappeared " - "on port %d\n", - up->device->address, port)); - usb_disconnect_port(up); + "on port %d\n", up->device->address, port)); + usb_disconnect_port(up, USBDEV(sc->sc_dev)); usbd_clear_port_feature(dev, port, UHF_C_PORT_CONNECTION); } @@ -405,25 +434,17 @@ uhub_explore(dev) "error=%s\n", usbd_errstr(r))); /* Avoid addressing problems by disabling. */ /* usbd_reset_port(dev, port, &up->status); */ -/* XXX - * What should we do. The device may or may not be at its - * assigned address. In any case we'd like to ignore it. - * Maybe the port should be disabled until the device is - * disconnected. - */ - if (r == USBD_SET_ADDR_FAILED || 1) {/* XXX */ - /* The unit refused to accept a new - * address, and since we cannot leave - * at 0 we have to disable the port - * instead. */ - printf("%s: device problem, disabling " - "port %d\n", - USBDEVNAME(sc->sc_dev), port); - usbd_clear_port_feature(dev, port, - UHF_PORT_ENABLE); - /* Make sure we don't try to restart it. */ - up->restartcnt = USBD_RESTART_MAX; - } + + /* + * The unit refused to accept a new address, or had + * some other serious problem. Since we cannot leave + * at 0 we have to disable the port instead. + */ + printf("%s: device problem, disabling port %d\n", + USBDEVNAME(sc->sc_dev), port); + usbd_clear_port_feature(dev, port, UHF_PORT_ENABLE); + /* Make sure we don't try to restart it infinitely. */ + up->restartcnt = USBD_RESTART_MAX; } else { if (up->device->hub) up->device->hub->explore(up->device); @@ -432,6 +453,7 @@ uhub_explore(dev) return (USBD_NORMAL_COMPLETION); } +#if defined(__NetBSD__) || defined(__OpenBSD__) int uhub_activate(self, act) device_ptr_t self; @@ -459,36 +481,36 @@ uhub_activate(self, act) } return (0); } +#endif /* * Called from process context when the hub is gone. * Detach all devices on active ports. */ -int -uhub_detach(self, flags) - device_ptr_t self; - int flags; +USB_DETACH(uhub) { - struct uhub_softc *sc = (struct uhub_softc *)self; + USB_DETACH_START(uhub, sc); usbd_device_handle dev = sc->sc_hub; struct usbd_port *rup; - int p, nports; + int port, nports; +#if defined(__NetBSD__) || defined(__OpenBSD__) DPRINTF(("uhub_detach: sc=%p flags=%d\n", sc, flags)); +#elif defined(__FreeBSD__) + DPRINTF(("uhub_detach: sc=%port\n", sc)); +#endif - if (!dev->hub) { - /* Must be partially working */ + if (!dev->hub) /* Must be partially working */ return (0); - } usbd_abort_pipe(sc->sc_ipipe); usbd_close_pipe(sc->sc_ipipe); nports = dev->hub->hubdesc.bNbrPorts; - for(p = 0; p < nports; p++) { - rup = &dev->hub->ports[p]; + for(port = 0; port < nports; port++) { + rup = &dev->hub->ports[port]; if (rup->device) - usb_disconnect_port(rup); + usb_disconnect_port(rup, self); } free(dev->hub, M_USBDEV); |