[PATCH 1/2] USB: check port changes before hub runtime suspend

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



It is very common that hub status endpoint has a long 'bInterval',
for example, it may be 11(128ms for HS device) or 12(256ms for HS
device), so the device connection change may be reported a bit
later via status pipe.

So there may have device connection changes happened already on the
downstream ports, and no status URB completes when it is killed
in hub auto-suspend path, which may miss the connection change event
and let hub suspend successfully.

This patch introduces check_ports_changed() to check port change event
in auto-suspend path, and recover hub state and return -EBUSY if
change events are found.

The disadvantage is that some delay may be introduced in hub auto-suspend
path.

Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxxxxx>
---
 drivers/usb/core/hub.c |   24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 6dc41c6..382dc41 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3158,6 +3158,21 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
 
 #endif
 
+static int check_ports_changed(struct usb_hub *hub)
+{
+	int port1;
+
+	for (port1 = 1; port1 <= hub->hdev->maxchild; ++port1) {
+		u16 portstatus, portchange;
+		int status;
+
+		status = hub_port_status(hub, port1, &portstatus, &portchange);
+		if (!status && portchange)
+			return 1;
+	}
+	return 0;
+}
+
 static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
 {
 	struct usb_hub		*hub = usb_get_intfdata (intf);
@@ -3192,6 +3207,15 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
 
 	/* stop khubd and related activity */
 	hub_quiesce(hub, HUB_SUSPEND);
+
+	if (PMSG_IS_AUTO(msg)) {
+		/* check if there are changes pending on hub ports */
+		if (check_ports_change(hub)) {
+			hub_activate(hub, HUB_RESUME);
+			return -EBUSY;
+		}
+	}
+
 	return 0;
 }
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux