Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 8 Dec 2008 15:13:30 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 154341 for review
Message-ID:  <200812081513.mB8FDUZo067845@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=154341

Change 154341 by hselasky@hselasky_laptop001 on 2008/12/08 15:12:49

	
	Do a better job getting non-compliant USB
	devices up and running.

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.c#36 edit
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_request.c#25 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.c#36 (text+ko) ====

@@ -1454,7 +1454,11 @@
 	if (err) {
 		DPRINTFN(0, "getting device descriptor "
 		    "at addr %d failed!\n", udev->address);
-		goto done;
+		/* XXX try to re-enumerate the device */
+		err = usb2_req_re_enumerate(udev, &Giant);
+		if (err) {
+			goto done;
+		}
 	}
 	DPRINTF("adding unit addr=%d, rev=%02x, class=%d, "
 	    "subclass=%d, protocol=%d, maxpacket=%d, len=%d, speed=%d\n",

==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_request.c#25 (text+ko) ====

@@ -613,7 +613,8 @@
 		}
 		USETW(req.wLength, min_len);
 
-		err = usb2_do_request(udev, mtx, &req, desc);
+		err = usb2_do_request_flags(udev, mtx, &req,
+		    desc, 0, NULL, 1000);
 
 		if (err) {
 			if (!retries) {
@@ -1328,6 +1329,7 @@
 	struct usb2_device *parent_hub;
 	usb2_error_t err;
 	uint8_t old_addr;
+	uint8_t do_retry = 1;
 
 	if (udev->flags.usb2_mode != USB_MODE_HOST) {
 		return (USB_ERR_INVAL);
@@ -1337,6 +1339,7 @@
 	if (parent_hub == NULL) {
 		return (USB_ERR_INVAL);
 	}
+retry:
 	err = usb2_req_reset_port(parent_hub, mtx, udev->port_no);
 	if (err) {
 		DPRINTFN(0, "addr=%d, port reset failed\n", old_addr);
@@ -1357,9 +1360,8 @@
 	err = usb2_req_set_address(udev, mtx, old_addr);
 	if (err) {
 		/* XXX ignore any errors! */
-		DPRINTFN(0, "addr=%d, set address failed\n",
+		DPRINTFN(0, "addr=%d, set address failed! (ignored)\n",
 		    old_addr);
-		err = 0;
 	}
 	/* restore device address */
 	udev->address = old_addr;
@@ -1383,6 +1385,14 @@
 		goto done;
 	}
 done:
+	if (err && do_retry) {
+		/* give the USB firmware some time to load */
+		usb2_pause_mtx(mtx, 500);
+		/* no more retries after this retry */
+		do_retry = 0;
+		/* try again */
+		goto retry;
+	}
 	/* restore address */
 	udev->address = old_addr;
 	return (err);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200812081513.mB8FDUZo067845>