summaryrefslogtreecommitdiff
path: root/sys/dev/usb
diff options
context:
space:
mode:
authormlelstv <mlelstv@NetBSD.org>2007-05-20 09:24:55 +0000
committermlelstv <mlelstv@NetBSD.org>2007-05-20 09:24:55 +0000
commite9fd5309a11b35ef784dddced7b07b463ebbc6f4 (patch)
treef78156f91cc8f1c00711be85b9916bb96ea26d11 /sys/dev/usb
parenta5e5b20e9044474165870408a5ce3681eb67c9ce (diff)
Retry set_address function for very slow (out of spec) devices, just
like FreeBSD.
Diffstat (limited to 'sys/dev/usb')
-rw-r--r--sys/dev/usb/usb_subr.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c
index 7623be70a37..125ee8988ba 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.146 2007/03/30 16:52:12 christos Exp $ */
+/* $NetBSD: usb_subr.c,v 1.147 2007/05/20 09:24:55 mlelstv Exp $ */
/* $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $ */
/*
@@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.146 2007/03/30 16:52:12 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.147 2007/05/20 09:24:55 mlelstv Exp $");
#include "opt_compat_netbsd.h"
#include "opt_usbverbose.h"
@@ -1044,8 +1044,19 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
}
/* Set the address. Do this early; some devices need that. */
- err = usbd_set_address(dev, addr);
+ /* 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);
+ if (!err)
+ break;
+ usbd_delay_ms(dev, 200);
+ if ((i % 3) == 3) {
+ DPRINTFN(-1,("usbd_new_device: set address %d "
+ "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;