summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/usb/uhub.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/sys/dev/usb/uhub.c b/sys/dev/usb/uhub.c
index a3ce7d2bd1c..eb27e59053c 100644
--- a/sys/dev/usb/uhub.c
+++ b/sys/dev/usb/uhub.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uhub.c,v 1.52 2009/11/13 18:06:57 deraadt Exp $ */
+/* $OpenBSD: uhub.c,v 1.53 2010/09/21 12:25:34 sasano Exp $ */
/* $NetBSD: uhub.c,v 1.64 2003/02/08 03:32:51 ichiro Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhub.c,v 1.18 1999/11/17 22:33:43 n_hibma Exp $ */
@@ -65,7 +65,8 @@ struct uhub_softc {
struct device 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 */
+ u_int8_t *sc_statusbuf; /* per port status buffer */
+ size_t sc_statuslen; /* status bufferlen */
u_char sc_running;
};
#define UHUB_PROTO(sc) ((sc)->sc_hub->ddesc.bDeviceProtocol)
@@ -234,9 +235,14 @@ uhub_attach(struct device *parent, struct device *self, void *aux)
goto bad;
}
+ sc->sc_statuslen = (nports + 1 + 7) / 8;
+ sc->sc_statusbuf = malloc(sc->sc_statuslen, M_USBDEV, M_NOWAIT);
+ if (!sc->sc_statusbuf)
+ goto bad;
+
err = usbd_open_pipe_intr(iface, ed->bEndpointAddress,
- USBD_SHORT_XFER_OK, &sc->sc_ipipe, sc, sc->sc_status,
- sizeof(sc->sc_status), uhub_intr, UHUB_INTR_INTERVAL);
+ USBD_SHORT_XFER_OK, &sc->sc_ipipe, sc, sc->sc_statusbuf,
+ sc->sc_statuslen, uhub_intr, UHUB_INTR_INTERVAL);
if (err) {
printf("%s: cannot open interrupt pipe\n",
sc->sc_dev.dv_xname);
@@ -325,6 +331,8 @@ uhub_attach(struct device *parent, struct device *self, void *aux)
return;
bad:
+ if (sc->sc_statusbuf)
+ free(sc->sc_statusbuf, M_USBDEV);
if (hub->ports)
free(hub->ports, M_USBDEV);
if (hub)
@@ -352,7 +360,7 @@ uhub_explore(usbd_device_handle dev)
if (dev->depth > USB_HUB_MAX_DEPTH)
return (USBD_TOO_DEEP);
- for(port = 1; port <= hd->bNbrPorts; port++) {
+ for (port = 1; port <= hd->bNbrPorts; port++) {
up = &dev->hub->ports[port-1];
err = usbd_get_port_status(dev, port, &up->status);
if (err) {
@@ -563,6 +571,8 @@ uhub_detach(struct device *self, int flags)
if (hub->ports[0].tt)
free(hub->ports[0].tt, M_USBDEV);
+ if (sc->sc_statusbuf)
+ free(sc->sc_statusbuf, M_USBDEV);
if (hub->ports)
free(hub->ports, M_USBDEV);
free(hub, M_USBDEV);
@@ -587,4 +597,6 @@ uhub_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
usbd_clear_endpoint_stall_async(sc->sc_ipipe);
else if (status == USBD_NORMAL_COMPLETION)
usb_needs_explore(sc->sc_hub);
+ else
+ DPRINTFN(8, ("uhub_intr: unknown status, %d\n", status));
}