# $Id: openbsd-usb_powerup_retry.diff,v 1.2 2005/10/07 02:26:25 jcs Exp $ # # retry usb port setup a few times before giving up to allow slowly attaching # devices like my 3g ipod to attach correctly # # by joshua stein # Index: uhub.c =================================================================== RCS file: /cvs/src/sys/dev/usb/uhub.c,v retrieving revision 1.29 diff -u -r1.29 uhub.c --- uhub.c 12 Dec 2004 05:21:14 -0000 1.29 +++ uhub.c 16 Feb 2005 02:20:24 -0000 @@ -334,6 +334,7 @@ int speed; int port; int change, status, reconnect; + int retry; DPRINTFN(10, ("uhub_explore dev=%p addr=%d\n", dev, dev->address)); @@ -466,30 +467,35 @@ speed = USB_SPEED_LOW; else speed = USB_SPEED_FULL; - /* Get device info and set its address. */ - err = usbd_new_device(USBDEV(sc->sc_dev), dev->bus, - dev->depth + 1, speed, port, up); - /* XXX retry a few times? */ - if (err) { - DPRINTFN(-1,("uhub_explore: usb_new_device failed, " - "error=%s\n", usbd_errstr(err))); - /* Avoid addressing problems by disabling. */ - /* usbd_reset_port(dev, port, &up->status); */ - /* - * The unit refused to accept a new address, or had + for (retry = 1; retry <= USB_PORT_POWERUP_RETRY; retry++) { + /* Get device info and set its address. */ + err = usbd_new_device(USBDEV(sc->sc_dev), dev->bus, + dev->depth + 1, speed, port, up); + + if (err) + usbd_delay_ms(dev, USB_PORT_POWERUP_DELAY * + retry); + else { + /* The port set up succeeded, reset error + * count. */ + up->restartcnt = 0; + + if (up->device->hub) + up->device->hub->explore(up->device); + + break; + } + } + + if (err) { + /* The unit refused to accept a new address, or had * some other serious problem. Since we cannot leave * at 0 we have to disable the port instead. */ - printf("%s: device problem, disabling port %d\n", - USBDEVNAME(sc->sc_dev), port); + printf("%s: device problem (%s), disabling port %d\n", + USBDEVNAME(sc->sc_dev), usbd_errstr(err), port); usbd_clear_port_feature(dev, port, UHF_PORT_ENABLE); - } else { - /* The port set up succeeded, reset error count. */ - up->restartcnt = 0; - - if (up->device->hub) - up->device->hub->explore(up->device); } } return (USBD_NORMAL_COMPLETION); Index: usb.h =================================================================== RCS file: /cvs/src/sys/dev/usb/usb.h,v retrieving revision 1.23 diff -u -r1.23 usb.h --- usb.h 16 Nov 2003 20:30:07 -0000 1.23 +++ usb.h 16 Feb 2005 02:20:24 -0000 @@ -515,6 +515,7 @@ #define USB_PORT_ROOT_RESET_DELAY 250 /* ms */ #define USB_PORT_RESET_RECOVERY 250 /* ms */ #define USB_PORT_POWERUP_DELAY 300 /* ms */ +#define USB_PORT_POWERUP_RETRY 3 #define USB_SET_ADDRESS_SETTLE 10 /* ms */ #define USB_RESUME_DELAY (50*5) /* ms */ #define USB_RESUME_WAIT 50 /* ms */