summaryrefslogtreecommitdiff
path: root/sys/dev/usb/uhub.c
diff options
context:
space:
mode:
authorFederico G. Schwindt <fgsch@cvs.openbsd.org>1999-11-07 21:30:21 +0000
committerFederico G. Schwindt <fgsch@cvs.openbsd.org>1999-11-07 21:30:21 +0000
commit8a585a5da59b075490abbc480dedab8c55ae6bda (patch)
tree8f31d43a47eea2f44fba3f09f6a0dfd648135915 /sys/dev/usb/uhub.c
parent2acdd01a3952b5e93a21f5a2b0db395cef5c55be (diff)
sync with NetBSD.
Diffstat (limited to 'sys/dev/usb/uhub.c')
-rw-r--r--sys/dev/usb/uhub.c100
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);