summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/uhub.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/usb/uhub.c')
-rw-r--r--sys/dev/usb/uhub.c88
1 files changed, 23 insertions, 65 deletions
diff --git a/sys/dev/usb/uhub.c b/sys/dev/usb/uhub.c
index 0d0876b51fa..4c3352028cb 100644
--- a/sys/dev/usb/uhub.c
+++ b/sys/dev/usb/uhub.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: uhub.c,v 1.4 1999/08/31 07:42:50 fgsch Exp $ */
-/* $NetBSD: uhub.c,v 1.23 1999/08/23 22:55:14 augustss Exp $ */
+/* $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 $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -54,6 +54,8 @@
#endif
#include <sys/proc.h>
+#include <machine/bus.h>
+
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdi_util.h>
@@ -69,7 +71,7 @@ extern int usbdebug;
#endif
struct uhub_softc {
- bdevice sc_dev; /* base device */
+ USBBASEDEVICE sc_dev; /* base device */
usbd_device_handle sc_hub; /* USB device */
usbd_pipe_handle sc_ipipe; /* interrupt pipe */
u_int8_t sc_status[1]; /* XXX more ports */
@@ -77,7 +79,6 @@ struct uhub_softc {
};
usbd_status uhub_init_port __P((struct usbd_port *));
-void uhub_disconnect_port __P((struct usbd_port *up));
usbd_status uhub_explore __P((usbd_device_handle hub));
void uhub_intr __P((usbd_request_handle, usbd_private_handle, usbd_status));
@@ -181,8 +182,7 @@ USB_ATTACH(uhub)
if (!dev->self_powered && dev->powersrc->parent &&
!dev->powersrc->parent->self_powered) {
printf("%s: bus powered hub connected to bus powered hub, "
- "ignored\n",
- USBDEVNAME(sc->sc_dev));
+ "ignored\n", USBDEVNAME(sc->sc_dev));
goto bad;
}
@@ -377,7 +377,7 @@ uhub_explore(dev)
DPRINTF(("uhub_explore: device %d disappeared "
"on port %d\n",
up->device->address, port));
- uhub_disconnect_port(up);
+ usb_disconnect_port(up);
usbd_clear_port_feature(dev, port,
UHF_C_PORT_CONNECTION);
}
@@ -396,7 +396,7 @@ uhub_explore(dev)
continue;
/* Get device info and set its address. */
- r = usbd_new_device(&sc->sc_dev, dev->bus,
+ r = usbd_new_device(USBDEV(sc->sc_dev), dev->bus,
dev->depth + 1, status & UPS_LOW_SPEED,
port, up);
/* XXX retry a few times? */
@@ -432,71 +432,29 @@ uhub_explore(dev)
return (USBD_NORMAL_COMPLETION);
}
-/*
- * The general mechanism for detaching drivers works as follows: Each
- * driver is responsible for maintaining a reference count on the
- * number of outstanding references to its softc (e.g. from
- * processing hanging in a read or write). The detach method of the
- * driver decrements this counter and flags in the softc that the
- * driver is dying and then wakes any sleepers. It then sleeps on the
- * softc. Each place that can sleep must maintain the reference
- * count. When the reference count drops to -1 (0 is the normal value
- * of the reference count) the a wakeup on the softc is performed
- * signaling to the detach waiter that all references are gone.
- */
-
-/*
- * Called from process context when we discover that a port has
- * been disconnected.
- */
-void
-uhub_disconnect_port(up)
- struct usbd_port *up;
-{
- usbd_device_handle dev = up->device;
- char *hubname;
- int i;
-
- DPRINTFN(3,("uhub_disconnect: up=%p dev=%p port=%d\n",
- up, dev, up->portno));
-
- if (!dev->cdesc) {
- /* Partially attached device, just drop it. */
- dev->bus->devices[dev->address] = 0;
- up->device = 0;
- return;
- }
-
- hubname = USBDEVNAME(*up->parent->subdevs[0]);
- for (i = 0; dev->subdevs[i]; i++) {
- printf("%s: at %s port %d (addr %d) disconnected\n",
- USBDEVNAME(*dev->subdevs[i]), hubname,
- up->portno, dev->address);
- config_detach(dev->subdevs[i], DETACH_FORCE);
- }
-
- dev->bus->devices[dev->address] = 0;
- up->device = 0;
- usb_free_device(dev);
-
-#if defined(__FreeBSD__)
- device_delete_child(
- device_get_parent(((struct softc *)dev->softc)->sc_dev),
- ((struct softc *)dev->softc)->sc_dev);
-#endif
-}
-
int
uhub_activate(self, act)
- bdevice *self;
+ device_ptr_t self;
enum devact act;
{
+ struct uhub_softc *sc = (struct uhub_softc *)self;
+ usbd_device_handle devhub = sc->sc_hub;
+ int nports, p, i;
+
switch (act) {
case DVACT_ACTIVATE:
return (EOPNOTSUPP);
break;
case DVACT_DEACTIVATE:
+ nports = devhub->hub->hubdesc.bNbrPorts;
+ for(p = 0; p < nports; p++) {
+ usbd_device_handle dev = devhub->hub->ports[p].device;
+ if (dev) {
+ for (i = 0; dev->subdevs[i]; i++)
+ config_deactivate(dev->subdevs[i]);
+ }
+ }
break;
}
return (0);
@@ -508,7 +466,7 @@ uhub_activate(self, act)
*/
int
uhub_detach(self, flags)
- bdevice *self;
+ device_ptr_t self;
int flags;
{
struct uhub_softc *sc = (struct uhub_softc *)self;
@@ -530,7 +488,7 @@ uhub_detach(self, flags)
for(p = 0; p < nports; p++) {
rup = &dev->hub->ports[p];
if (rup->device)
- uhub_disconnect_port(rup);
+ usb_disconnect_port(rup);
}
free(dev->hub, M_USBDEV);