diff options
Diffstat (limited to 'sys/dev/usb/usb_subr.c')
| -rw-r--r-- | sys/dev/usb/usb_subr.c | 76 |
1 files changed, 51 insertions, 25 deletions
diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c index 46c2e8b0ac99..5ac7b95691a4 100644 --- a/sys/dev/usb/usb_subr.c +++ b/sys/dev/usb/usb_subr.c @@ -1,4 +1,4 @@ -/* $NetBSD: usb_subr.c,v 1.56 1999/11/18 23:32:32 augustss Exp $ */ +/* $NetBSD: usb_subr.c,v 1.63 2000/01/19 00:23:58 augustss Exp $ */ /* $FreeBSD$ */ /* @@ -344,7 +344,7 @@ usbd_reset_port(dev, port, ps) err = usbd_get_port_status(dev, port, ps); if (err) { DPRINTF(("usbd_reset_port: get status failed %d\n", - err)); + err)); return (err); } } while ((UGETW(ps->wPortChange) & UPS_C_PORT_RESET) == 0 && --n > 0); @@ -356,7 +356,7 @@ usbd_reset_port(dev, port, ps) #ifdef USB_DEBUG if (err) DPRINTF(("usbd_reset_port: clear port feature failed %d\n", - err)); + err)); #endif /* Wait for the device to recover from reset. */ @@ -395,7 +395,7 @@ usbd_find_idesc(cd, ifaceidx, altidx) return (d); } } - return (0); + return (NULL); } usb_endpoint_descriptor_t * @@ -413,9 +413,9 @@ usbd_find_edesc(cd, ifaceidx, altidx, endptidx) d = usbd_find_idesc(cd, ifaceidx, altidx); if (d == NULL) - return (0); + return (NULL); if (endptidx >= d->bNumEndpoints) /* quick exit */ - return (0); + return (NULL); curidx = -1; for (p = (char *)d + d->bLength; p < end; ) { @@ -424,14 +424,14 @@ usbd_find_edesc(cd, ifaceidx, altidx, endptidx) break; p += e->bLength; if (p <= end && e->bDescriptorType == UDESC_INTERFACE) - return (0); + return (NULL); if (p <= end && e->bDescriptorType == UDESC_ENDPOINT) { curidx++; if (curidx == endptidx) return (e); } } - return (0); + return (NULL); } usbd_status @@ -453,15 +453,15 @@ usbd_fill_iface_data(dev, ifaceidx, altidx) ifc->index = ifaceidx; ifc->altindex = altidx; nendpt = ifc->idesc->bNumEndpoints; - DPRINTFN(10,("usbd_fill_iface_data: found idesc n=%d\n", nendpt)); + DPRINTFN(4,("usbd_fill_iface_data: found idesc nendpt=%d\n", nendpt)); if (nendpt != 0) { ifc->endpoints = malloc(nendpt * sizeof(struct usbd_endpoint), M_USB, M_NOWAIT); - if (ifc->endpoints == 0) + if (ifc->endpoints == NULL) return (USBD_NOMEM); } else - ifc->endpoints = 0; - ifc->priv = 0; + ifc->endpoints = NULL; + ifc->priv = NULL; p = (char *)ifc->idesc + ifc->idesc->bLength; end = (char *)dev->cdesc + UGETW(dev->cdesc->wTotalLength); #define ed ((usb_endpoint_descriptor_t *)p) @@ -475,11 +475,15 @@ usbd_fill_iface_data(dev, ifaceidx, altidx) if (p + ed->bLength <= end && ed->bLength != 0 && ed->bDescriptorType == UDESC_ENDPOINT) goto found; - if (ed->bDescriptorType == UDESC_INTERFACE || - ed->bLength == 0) + if (ed->bLength == 0 || + ed->bDescriptorType == UDESC_INTERFACE) 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")); goto bad; found: ifc->endpoints[endpt].edesc = ed; @@ -491,7 +495,8 @@ usbd_fill_iface_data(dev, ifaceidx, altidx) return (USBD_NORMAL_COMPLETION); bad: - free(ifc->endpoints, M_USB); + if (ifc->endpoints != NULL) + free(ifc->endpoints, M_USB); return (USBD_INVAL); } @@ -640,7 +645,7 @@ usbd_set_config_index(dev, index, msg) nifc = cdp->bNumInterface; dev->ifaces = malloc(nifc * sizeof(struct usbd_interface), M_USB, M_NOWAIT); - if (dev->ifaces == 0) { + if (dev->ifaces == NULL) { err = USBD_NOMEM; goto bad; } @@ -666,10 +671,11 @@ usbd_set_config_index(dev, index, msg) /* XXX add function for alternate settings */ usbd_status -usbd_setup_pipe(dev, iface, ep, pipe) +usbd_setup_pipe(dev, iface, ep, ival, pipe) usbd_device_handle dev; usbd_interface_handle iface; struct usbd_endpoint *ep; + int ival; usbd_pipe_handle *pipe; { usbd_pipe_handle p; @@ -688,6 +694,7 @@ usbd_setup_pipe(dev, iface, ep, pipe) p->intrxfer = 0; p->running = 0; p->repeat = 0; + p->interval = ival; SIMPLEQ_INIT(&p->queue); err = dev->bus->methods->open_pipe(p); if (err) { @@ -769,6 +776,7 @@ usbd_probe_and_attach(parent, dev, port, addr) uaa.release = UGETW(dd->bcdDevice); /* First try with device specific drivers. */ + DPRINTF(("usbd_probe_and_attach: trying device specific drivers\n")); dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch); if (dv) { dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT); @@ -781,6 +789,8 @@ usbd_probe_and_attach(parent, dev, port, addr) DPRINTF(("usbd_probe_and_attach: no device specific driver found\n")); + DPRINTF(("usbd_probe_and_attach: looping over %d configurations\n", + dd->bNumConfigurations)); /* Next try with interface drivers. */ for (confi = 0; confi < dd->bNumConfigurations; confi++) { DPRINTFN(1,("usbd_probe_and_attach: trying config idx=%d\n", @@ -829,7 +839,7 @@ usbd_probe_and_attach(parent, dev, port, addr) ifaces[i] = 0; /* consumed */ #if defined(__FreeBSD__) - /* create another device for the next iface */ + /* create another child for the next iface */ bdev = device_add_child(parent, NULL, -1); device_set_ivars(bdev, &uaa); if (!bdev) { @@ -947,7 +957,8 @@ usbd_new_device(parent, bus, depth, lowspeed, port, up) dev->cookie.cookie = ++usb_cookie_no; /* Establish the the default pipe. */ - err = usbd_setup_pipe(dev, 0, &dev->def_ep, &dev->default_pipe); + err = usbd_setup_pipe(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL, + &dev->default_pipe); if (err) { usbd_remove_device(dev, up); return (err); @@ -992,8 +1003,7 @@ usbd_new_device(parent, bus, depth, lowspeed, port, up) USETW(dev->def_ep_desc.wMaxPacketSize, dd->bMaxPacketSize); - /* Get the full device descriptor. */ - err = usbd_get_device_desc(dev, dd); + err = usbd_reload_device_desc(dev); if (err) { DPRINTFN(-1, ("usbd_new_device: addr=%d, getting full desc " "failed\n", addr)); @@ -1001,13 +1011,11 @@ usbd_new_device(parent, bus, depth, lowspeed, port, up) return (err); } - /* Figure out what's wrong with this device. */ - dev->quirks = usbd_find_quirk(dd); - /* Set the address */ err = usbd_set_address(dev, addr); + DPRINTFN(5,("usbd_new_device: setting device address=%d\n", addr)); if (err) { - DPRINTFN(-1,("usb_new_device: set address %d failed\n",addr)); + DPRINTFN(-1,("usb_new_device: set address %d failed\n", addr)); err = USBD_SET_ADDR_FAILED; usbd_remove_device(dev, up); return (err); @@ -1035,6 +1043,23 @@ usbd_new_device(parent, bus, depth, lowspeed, port, up) return (USBD_NORMAL_COMPLETION); } +usbd_status +usbd_reload_device_desc(dev) + usbd_device_handle dev; +{ + usbd_status err; + + /* Get the full device descriptor. */ + err = usbd_get_device_desc(dev, &dev->ddesc); + if (err) + return (err); + + /* Figure out what's wrong with this device. */ + dev->quirks = usbd_find_quirk(&dev->ddesc); + + return (USBD_NORMAL_COMPLETION); +} + void usbd_remove_device(dev, up) usbd_device_handle dev; @@ -1277,6 +1302,7 @@ usb_disconnect_port(up, parent) } } + /*usbd_add_event(USB_EVENT_DETACH, dev);*/ dev->bus->devices[dev->address] = NULL; up->device = NULL; usb_free_device(dev); |
