summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>2004-03-19 08:19:52 +0000
committerjulian <julian@FreeBSD.org>2004-03-19 08:19:52 +0000
commit9efe31118956f24f0fc12006dd24116af5c3b174 (patch)
tree3f60fa58394fee4c4e20e23d5eddaa7418e44b9e /sys
parenta0128abb0aea6f9d590dbe3e603f7c3f235cd069 (diff)
downloadFreeBSD-src-9efe31118956f24f0fc12006dd24116af5c3b174.zip
FreeBSD-src-9efe31118956f24f0fc12006dd24116af5c3b174.tar.gz
Diff reduction to NetBSD
Bring over sundry small fixes from NetBSD Obtained from: NetBSD MFC after: 1 week
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/usb/usb_subr.c57
1 files changed, 35 insertions, 22 deletions
diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c
index db7d6a4..3ac498a 100644
--- a/sys/dev/usb/usb_subr.c
+++ b/sys/dev/usb/usb_subr.c
@@ -3,6 +3,7 @@
/* Also already have from NetBSD:
* $NetBSD: usb_subr.c,v 1.102 2003/01/01 16:21:50 augustss Exp $
* $NetBSD: usb_subr.c,v 1.103 2003/01/10 11:19:13 augustss Exp $
+ * $NetBSD: usb_subr.c,v 1.111 2004/03/15 10:35:04 augustss Exp $
*/
#include <sys/cdefs.h>
@@ -587,7 +588,7 @@ usbd_set_config_index(usbd_device_handle dev, int index, int msg)
usb_status_t ds;
usb_config_descriptor_t cd, *cdp;
usbd_status err;
- int ifcidx, nifc, len, selfpowered, power;
+ int i, ifcidx, nifc, len, selfpowered, power;
DPRINTFN(5,("usbd_set_config_index: dev=%p index=%d\n", dev, index));
@@ -623,8 +624,14 @@ usbd_set_config_index(usbd_device_handle dev, int index, int msg)
cdp = malloc(len, M_USB, M_NOWAIT);
if (cdp == NULL)
return (USBD_NOMEM);
- /* Get the full descriptor. */
- err = usbd_get_desc(dev, UDESC_CONFIG, index, len, cdp);
+
+ /* Get the full descriptor. Try a few times for slow devices. */
+ for (i = 0; i < 3; i++) {
+ err = usbd_get_desc(dev, UDESC_CONFIG, index, len, cdp);
+ if (!err)
+ break;
+ usbd_delay_ms(dev, 200);
+ }
if (err)
goto bad;
if (cdp->bDescriptorType != UDESC_CONFIG) {
@@ -775,8 +782,14 @@ usbd_setup_pipe(usbd_device_handle dev, usbd_interface_handle iface,
return (err);
}
/* Clear any stall and make sure DATA0 toggle will be used next. */
- if (UE_GET_ADDR(ep->edesc->bEndpointAddress) != USB_CONTROL_ENDPOINT)
- usbd_clear_endpoint_stall(p);
+ if (UE_GET_ADDR(ep->edesc->bEndpointAddress) != USB_CONTROL_ENDPOINT) {
+ err = usbd_clear_endpoint_stall(p);
+ /* Some devices reject this command, so ignore a STALL. */
+ if (err && err != USBD_STALLED) {
+ printf("usbd_setup_pipe: failed to start endpoint, %s\n", usbd_errstr(err));
+ return (err);
+ }
+ }
*pipe = p;
return (USBD_NORMAL_COMPLETION);
}
@@ -1030,6 +1043,21 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
}
up->device = dev;
+
+ /* Set the address. Do this early; some devices need that. */
+ 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));
+ 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;
+
dd = &dev->ddesc;
/* Try a few times in case the device is slow (i.e. outside specs.) */
for (i = 0; i < 15; i++) {
@@ -1089,21 +1117,6 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
return (err);
}
- /* 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));
- 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;
-
/* Assume 100mA bus powered for now. Changed when configured. */
dev->power = USB_MIN_POWER;
dev->self_powered = 0;
@@ -1111,14 +1124,14 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
DPRINTF(("usbd_new_device: new dev (addr %d), dev=%p, parent=%p\n",
addr, dev, parent));
+ usbd_add_dev_event(USB_EVENT_DEVICE_ATTACH, dev);
+
err = usbd_probe_and_attach(parent, dev, port, addr);
if (err) {
usbd_remove_device(dev, up);
return (err);
}
- usbd_add_dev_event(USB_EVENT_DEVICE_ATTACH, dev);
-
return (USBD_NORMAL_COMPLETION);
}
OpenPOWER on IntegriCloud