Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 Aug 2010 15:28:10 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 182321 for review
Message-ID:  <201008121528.o7CFSA8q057122@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@182321?ac=10

Change 182321 by hselasky@hselasky_laptop001 on 2010/08/12 15:27:40

	USB core (HUB):
		- Fix problem with selective suspend feature. The
		problem was introduced in r208008. We need to issue
		the remote wakeup feature before setting that
		the USB device is suspended. Else the request
		will time out. The issue was probably not
		caught because USB debug prints are turned
		off by default.

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb/usb_hub.c#57 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb/usb_hub.c#57 (text+ko) ====

@@ -2328,6 +2328,23 @@
 		}
 	}
 
+	if (usb_peer_can_wakeup(udev) &&
+	    usb_device_20_compatible(udev)) {
+
+		/*
+		 * This request needs to be done before we set
+		 * "udev->flags.self_suspended":
+		 */
+
+		/* allow device to do remote wakeup */
+		err = usbd_req_set_device_feature(udev,
+		    NULL, UF_DEVICE_REMOTE_WAKEUP);
+		if (err) {
+			DPRINTFN(0, "Setting device "
+			    "remote wakeup failed\n");
+		}
+	}
+
 	USB_BUS_LOCK(udev->bus);
 	/*
 	 * Checking for suspend condition and setting suspended bit
@@ -2345,6 +2362,18 @@
 	USB_BUS_UNLOCK(udev->bus);
 
 	if (err != 0) {
+
+		if (usb_peer_can_wakeup(udev) &&
+		    usb_device_20_compatible(udev)) {
+			/* allow device to do remote wakeup */
+			err = usbd_req_clear_device_feature(udev,
+			    NULL, UF_DEVICE_REMOTE_WAKEUP);
+			if (err) {
+				DPRINTFN(0, "Setting device "
+				    "remote wakeup failed\n");
+			}
+		}
+
 		if (udev->flags.usb_mode == USB_MODE_DEVICE) {
 			/* resume parent HUB first */
 			usb_dev_resume_peer(udev->parent_hub);
@@ -2370,17 +2399,6 @@
 
 	usbd_sr_unlock(udev);
 
-	if (usb_peer_can_wakeup(udev) &&
-	    usb_device_20_compatible(udev)) {
-		/* allow device to do remote wakeup */
-		err = usbd_req_set_device_feature(udev,
-		    NULL, UF_DEVICE_REMOTE_WAKEUP);
-		if (err) {
-			DPRINTFN(0, "Setting device "
-			    "remote wakeup failed\n");
-		}
-	}
-
 	if (udev->bus->methods->device_suspend != NULL) {
 		usb_timeout_t temp;
 



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