diff options
Diffstat (limited to 'sys/dev/usb/usb_subr.c')
-rw-r--r-- | sys/dev/usb/usb_subr.c | 80 |
1 files changed, 59 insertions, 21 deletions
diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c index 4883a38aa17..66cb1fd6248 100644 --- a/sys/dev/usb/usb_subr.c +++ b/sys/dev/usb/usb_subr.c @@ -1,5 +1,5 @@ -/* $OpenBSD: usb_subr.c,v 1.19 2002/05/02 20:08:04 nate Exp $ */ -/* $NetBSD: usb_subr.c,v 1.87 2001/08/15 00:04:59 augustss Exp $ */ +/* $OpenBSD: usb_subr.c,v 1.20 2002/05/07 18:08:04 nate Exp $ */ +/* $NetBSD: usb_subr.c,v 1.98 2002/02/20 20:30:13 christos Exp $ */ /* $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $ */ /* @@ -352,6 +352,9 @@ usbd_reset_port(usbd_device_handle dev, int port, usb_port_status_t *ps) err)); return (err); } + /* If the device disappeared, just give up. */ + if (!(UGETW(ps->wPortStatus) & UPS_CURRENT_CONNECT_STATUS)) + return (USBD_NORMAL_COMPLETION); } while ((UGETW(ps->wPortChange) & UPS_C_PORT_RESET) == 0 && --n > 0); if (n == 0) return (USBD_TIMEOUT); @@ -475,13 +478,36 @@ usbd_fill_iface_data(usbd_device_handle dev, int ifaceidx, int altidx) break; } /* passed end, or bad desc */ - DPRINTF(("usbd_fill_iface_data: bad descriptor(s): %s\n", - ed->bLength == 0 ? "0 length" : - ed->bDescriptorType == UDESC_INTERFACE ? "iface desc": - "out of data")); + printf("usbd_fill_iface_data: bad descriptor(s): %s\n", + ed->bLength == 0 ? "0 length" : + ed->bDescriptorType == UDESC_INTERFACE ? "iface desc": + "out of data"); goto bad; found: ifc->endpoints[endpt].edesc = ed; + if (dev->speed == USB_SPEED_HIGH) { + u_int mps; + /* Control and bulk endpoints have max packet + limits. */ + switch (UE_GET_XFERTYPE(ed->bmAttributes)) { + case UE_CONTROL: + mps = USB_2_MAX_CTRL_PACKET; + goto check; + case UE_BULK: + mps = USB_2_MAX_BULK_PACKET; + check: + if (UGETW(ed->wMaxPacketSize) != mps) { + USETW(ed->wMaxPacketSize, mps); +#ifdef DIAGNOSTIC + printf("usbd_fill_iface_data: bad max " + "packet size\n"); +#endif + } + break; + default: + break; + } + } ifc->endpoints[endpt].refcnt = 0; p += ed->bLength; } @@ -725,7 +751,6 @@ usbd_setup_pipe(usbd_device_handle dev, usbd_interface_handle iface, p->repeat = 0; p->interval = ival; SIMPLEQ_INIT(&p->queue); - usb_callout_init(p->abort_handle); err = dev->bus->methods->open_pipe(p); if (err) { DPRINTFN(-1,("usbd_setup_pipe: endpoint=0x%x failed, error=" @@ -745,6 +770,7 @@ usbd_setup_pipe(usbd_device_handle dev, usbd_interface_handle iface, void usbd_kill_pipe(usbd_pipe_handle pipe) { + usbd_abort_pipe(pipe); pipe->methods->close(pipe); pipe->endpoint->refcnt--; free(pipe, M_USB); @@ -927,16 +953,17 @@ usbd_probe_and_attach(device_ptr_t parent, usbd_device_handle dev, */ usbd_status usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth, - int lowspeed, int port, struct usbd_port *up) + int speed, int port, struct usbd_port *up) { usbd_device_handle dev; + struct usbd_device *hub; usb_device_descriptor_t *dd; usbd_status err; int addr; int i; - DPRINTF(("usbd_new_device bus=%p port=%d depth=%d lowspeed=%d\n", - bus, port, depth, lowspeed)); + DPRINTF(("usbd_new_device bus=%p port=%d depth=%d speed=%d\n", + bus, port, depth, speed)); addr = usbd_getnewaddr(bus); if (addr < 0) { printf("%s: No free USB addresses, new device ignored.\n", @@ -947,7 +974,7 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth, dev = malloc(sizeof *dev, M_USB, M_NOWAIT); if (dev == NULL) return (USBD_NOMEM); - memset(dev, 0, sizeof(*dev)); + memset(dev, 0, sizeof *dev); dev->bus = bus; @@ -965,9 +992,15 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth, dev->quirks = &usbd_no_quirk; dev->address = USB_START_ADDR; dev->ddesc.bMaxPacketSize = 0; - dev->lowspeed = lowspeed != 0; dev->depth = depth; dev->powersrc = up; + dev->myhub = up->parent; + for (hub = up->parent; + hub != NULL && hub->speed != USB_SPEED_HIGH; + hub = hub->myhub) + ; + dev->myhighhub = hub; + dev->speed = speed; dev->langid = USBD_NOLANG; dev->cookie.cookie = ++usb_cookie_no; @@ -996,11 +1029,22 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth, return (err); } + if (speed == USB_SPEED_HIGH) { + /* Max packet size must be 64 (sec 5.5.3). */ + if (dd->bMaxPacketSize != USB_2_MAX_CTRL_PACKET) { +#ifdef DIAGNOSTIC + printf("usbd_new_device: addr=%d bad max packet size\n", + addr); +#endif + dd->bMaxPacketSize = USB_2_MAX_CTRL_PACKET; + } + } + DPRINTF(("usbd_new_device: adding unit addr=%d, rev=%02x, class=%d, " - "subclass=%d, protocol=%d, maxpacket=%d, len=%d, ls=%d\n", + "subclass=%d, protocol=%d, maxpacket=%d, len=%d, speed=%d\n", addr,UGETW(dd->bcdUSB), dd->bDeviceClass, dd->bDeviceSubClass, dd->bDeviceProtocol, dd->bMaxPacketSize, dd->bLength, - dev->lowspeed)); + dev->speed)); if (dd->bDescriptorType != UDESC_DEVICE) { /* Illegal device descriptor */ @@ -1203,7 +1247,7 @@ usbd_fill_deviceinfo(usbd_device_handle dev, struct usb_device_info *di, di->udi_protocol = dev->ddesc.bDeviceProtocol; di->udi_config = dev->config; di->udi_power = dev->self_powered ? 0 : dev->power; - di->udi_lowspeed = dev->lowspeed; + di->udi_speed = dev->speed; if (dev->subdevs != NULL) { for (i = 0; dev->subdevs[i] && @@ -1306,13 +1350,7 @@ usb_disconnect_port(struct usbd_port *up, device_ptr_t parent) if (up->portno != 0) printf(" port %d", up->portno); printf(" (addr %d) disconnected\n", dev->address); -#if defined(__NetBSD__) || defined(__OpenBSD__) config_detach(dev->subdevs[i], DETACH_FORCE); -#elif defined(__FreeBSD__) - device_delete_child(device_get_parent(dev->subdevs[i]), - dev->subdevs[i]); -#endif - } } |