login
Header Space

 
 

PLEASE TEST: usb diff

Score:
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: <tech@...>
Date: Wednesday, May 14, 2008 - 9:08 pm

Hi,

  If you have a USB device that, when plugged before booting, shows a
"device problem, disabling port" message, please test the diff below.
  If you don't have such device, please test the diff below too.
  Report any errors or changes to me.
  Thanks,

  f.-

Index: sys/dev/usb/usb_subr.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/usb_subr.c,v
retrieving revision 1.64
diff -u -p -r1.64 usb_subr.c
--- sys/dev/usb/usb_subr.c	4 Nov 2007 05:52:36 -0000	1.64
+++ sys/dev/usb/usb_subr.c	15 May 2008 00:59:24 -0000
@@ -979,6 +979,7 @@ usbd_new_device(struct device *parent, u
 	usbd_device_handle dev, adev;
 	struct usbd_device *hub;
 	usb_device_descriptor_t *dd;
+	usb_port_status_t ps;
 	usbd_status err;
 	int addr;
 	int i;
@@ -1049,15 +1050,40 @@ usbd_new_device(struct device *parent, u
 		return (err);
 	}
 
+	/* Set the address. Do this early; some devices need that. */
+	/* 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;
+		if ((i % 4) == 0)
+			usbd_reset_port(up->parent, port, &ps);
+		else
+			usbd_delay_ms(dev, 200);
+	}
+	if (err) {
+		DPRINTFN(-1,("usbd_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 < 5; i++) {
+	for (i = 0; i < 15; i++) {
 		/* Get the first 8 bytes of the device descriptor. */
 		err = usbd_get_desc(dev, UDESC_DEVICE, 0, USB_MAX_IPACKET, dd);
 		if (!err)
 			break;
-		/* progressively increase the delay */
-		usbd_delay_ms(dev, 200 * (i + 1));
+		if ((i % 4) == 0)
+			usbd_reset_port(up->parent, port, &ps);
+		else
+			usbd_delay_ms(dev, 200);
 	}
 	if (err) {
 		DPRINTFN(-1, ("usbd_new_device: addr=%d, getting first desc "
@@ -1106,21 +1132,6 @@ usbd_new_device(struct device *parent, u
 		usbd_remove_device(dev, up);
 		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,("usbd_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;
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
PLEASE TEST: usb diff, Federico G. Schwindt, (Wed May 14, 9:08 pm)
Re: PLEASE TEST: usb diff, Marc Balmer, (Fri May 16, 10:28 am)
speck-geostationary