diff options
author | kevlo <kevlo@FreeBSD.org> | 2007-05-08 03:25:05 +0000 |
---|---|---|
committer | kevlo <kevlo@FreeBSD.org> | 2007-05-08 03:25:05 +0000 |
commit | 872320ec7590f3fe30f5abbbbcf2262b10c3cac4 (patch) | |
tree | 7c8d05d4c85bcfa8d71e4d0e4484d1d321836528 | |
parent | d4d5d36cfcdb27651bcdacae4415c01475b6ca78 (diff) | |
download | FreeBSD-src-872320ec7590f3fe30f5abbbbcf2262b10c3cac4.zip FreeBSD-src-872320ec7590f3fe30f5abbbbcf2262b10c3cac4.tar.gz |
Do not set address early. It fix problems when SET_ADDR_FAILED happens
on the hubs.
Reviewed by: imp
-rw-r--r-- | sys/dev/usb/usb_subr.c | 51 |
1 files changed, 27 insertions, 24 deletions
diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c index 4c5d5ca..1512e85 100644 --- a/sys/dev/usb/usb_subr.c +++ b/sys/dev/usb/usb_subr.c @@ -1085,11 +1085,12 @@ usbd_new_device(device_t parent, usbd_bus_handle bus, int depth, return (err); } - /* Set the address. Do this early; some devices need that. */ + dd = &dev->ddesc; /* Try a few times in case the device is slow (i.e. outside specs.) */ DPRINTFN(5,("usbd_new_device: setting device address=%d\n", addr)); for (i = 0; i < 15; i++) { - err = usbd_set_address(dev, addr); + /* Get the first 8 bytes of the device descriptor. */ + err = usbd_get_desc(dev, UDESC_DEVICE, 0, USB_MAX_IPACKET, dd); if (!err) break; usbd_delay_ms(dev, 200); @@ -1098,30 +1099,8 @@ usbd_new_device(device_t parent, usbd_bus_handle bus, int depth, "failed - trying a port reset\n", addr)); usbd_reset_port(up->parent, port, &ps); } - } - if (err) { - DPRINTFN(-1,("usb_new_device: set address %d failed\n", addr)); - err = USBD_SET_ADDR_FAILED; - usbd_remove_device(dev, up); - return (err); - } - /* Allow device time to set new address */ - usbd_delay_ms(dev, USB_SET_ADDRESS_SETTLE); - dev->address = addr; /* New device address now */ - bus->devices[addr] = dev; - /* Re-establish the default pipe with the new address. */ - usbd_kill_pipe(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); } - - dd = &dev->ddesc; - /* Get the first 8 bytes of the device descriptor. */ - err = usbd_get_desc(dev, UDESC_DEVICE, 0, USB_MAX_IPACKET, dd); if (err) { DPRINTFN(-1, ("usbd_new_device: addr=%d, getting first desc " "failed\n", addr)); @@ -1179,6 +1158,30 @@ usbd_new_device(device_t parent, usbd_bus_handle bus, int depth, return (err); } + /* Set the address */ + DPRINTFN(5,("usbd_new_device: setting device address=%d\n", addr)); + err = usbd_set_address(dev, addr); + if (err) { + DPRINTFN(-1,("usb_new_device: set address %d failed\n", addr)); + err = USBD_SET_ADDR_FAILED; + usbd_remove_device(dev, up); + return (err); + } + + /* Allow device time to set new address */ + usbd_delay_ms(dev, USB_SET_ADDRESS_SETTLE); + dev->address = addr; /* New device address now */ + bus->devices[addr] = dev; + + /* Re-establish the default pipe with the new address. */ + usbd_kill_pipe(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); + } + /* Assume 100mA bus powered for now. Changed when configured. */ dev->power = USB_MIN_POWER; dev->self_powered = 0; |