Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 11 Apr 2009 11:17:42 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 160485 for review
Message-ID:  <200904111117.n3BBHgdO016099@repoman.freebsd.org>

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

Change 160485 by hselasky@hselasky_laptop001 on 2009/04/11 11:17:31

	
	USB CORE:
	 - fix a bug in the USB power daemon code where
	 connection of multiple HUBs in series would
	 result in incorrect device suspend.
	
	Bug reported by: Nicolas xxx@wanadoo.fr

Affected files ...

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

Differences ...

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

@@ -1786,12 +1786,10 @@
 static void
 usb2_dev_suspend_peer(struct usb2_device *udev)
 {
-	struct usb2_device *hub;
 	struct usb2_device *child;
 	int err;
 	uint8_t x;
 	uint8_t nports;
-	uint8_t suspend_parent;
 
 repeat:
 	/* be NULL safe */
@@ -1808,16 +1806,15 @@
 
 	DPRINTF("udev=%p\n", udev);
 
-	/* check if all devices on the parent hub are suspended */
-	hub = udev->parent_hub;
-	if (hub != NULL) {
-		nports = hub->hub->nports;
-		suspend_parent = 1;
+	/* check if the current device is a HUB */
+	if (udev->hub != NULL) {
+		nports = udev->hub->nports;
 
+		/* check if all devices on the HUB are suspended */
 		for (x = 0; x != nports; x++) {
 
-			child = usb2_bus_port_get_device(hub->bus,
-			    hub->hub->ports + x);
+			child = usb2_bus_port_get_device(udev->bus,
+			    udev->hub->ports + x);
 
 			if (child == NULL)
 				continue;
@@ -1825,16 +1822,9 @@
 			if (child->pwr_save.suspended)
 				continue;
 
-			if (child == udev)
-				continue;
-
-			/* another device on the HUB is not suspended */
-			suspend_parent = 0;
-
-			break;
+			DPRINTFN(1, "Port %u is busy on the HUB!\n", x + 1);
+			return;
 		}
-	} else {
-		suspend_parent = 0;
 	}
 
 	sx_xlock(udev->default_sx + 1);
@@ -1877,11 +1867,9 @@
 		DPRINTFN(0, "Suspending port failed\n");
 		return;
 	}
-	if (suspend_parent) {
-		udev = udev->parent_hub;
-		goto repeat;
-	}
-	return;
+
+	udev = udev->parent_hub;
+	goto repeat;
 }
 
 /*------------------------------------------------------------------------*



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