From 758045cd971ef8e461cc89911ca8dd6283c055ad Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Tue, 24 Jan 2012 13:53:18 -0800 Subject: [PATCH] --- yaml --- r: 289441 b: refs/heads/master c: 714b07be3bbf94d2dc9838723d63fc827fdbef12 h: refs/heads/master i: 289439: 02cb5b4043d2ad32099aae314a2fac163a9162c4 v: v3 --- [refs] | 2 +- trunk/drivers/usb/core/hub.c | 59 +++++++++++++++++++++--------------- 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/[refs] b/[refs] index 03747d2fb919..3e6cb3e12e96 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 4296c70a5ec316903ef037ed15f154dd3d354ad7 +refs/heads/master: 714b07be3bbf94d2dc9838723d63fc827fdbef12 diff --git a/trunk/drivers/usb/core/hub.c b/trunk/drivers/usb/core/hub.c index b3137fa65f2a..ba9509454ed5 100644 --- a/trunk/drivers/usb/core/hub.c +++ b/trunk/drivers/usb/core/hub.c @@ -3488,6 +3488,39 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, hcd->driver->relinquish_port(hcd, port1); } +/* Returns 1 if there was a remote wakeup and a connect status change. */ +static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port, + u16 portchange) +{ + struct usb_device *hdev; + struct usb_device *udev; + int connect_change = 0; + int ret; + + hdev = hub->hdev; + if (!(portchange & USB_PORT_STAT_C_SUSPEND)) + return 0; + clear_port_feature(hdev, port, USB_PORT_FEAT_C_SUSPEND); + + udev = hdev->children[port-1]; + if (udev) { + /* TRSMRCY = 10 msec */ + msleep(10); + + usb_lock_device(udev); + ret = usb_remote_wakeup(udev); + usb_unlock_device(udev); + if (ret < 0) + connect_change = 1; + } else { + ret = -ENODEV; + hub_port_disable(hub, port, 1); + } + dev_dbg(hub->intfdev, "resume on port %d, status %d\n", + port, ret); + return connect_change; +} + static void hub_events(void) { struct list_head *tmp; @@ -3621,31 +3654,9 @@ static void hub_events(void) } } - if (portchange & USB_PORT_STAT_C_SUSPEND) { - struct usb_device *udev; + if (hub_handle_remote_wakeup(hub, i, portchange)) + connect_change = 1; - clear_port_feature(hdev, i, - USB_PORT_FEAT_C_SUSPEND); - udev = hdev->children[i-1]; - if (udev) { - /* TRSMRCY = 10 msec */ - msleep(10); - - usb_lock_device(udev); - ret = usb_remote_wakeup(hdev-> - children[i-1]); - usb_unlock_device(udev); - if (ret < 0) - connect_change = 1; - } else { - ret = -ENODEV; - hub_port_disable(hub, i, 1); - } - dev_dbg (hub_dev, - "resume on port %d, status %d\n", - i, ret); - } - if (portchange & USB_PORT_STAT_C_OVERCURRENT) { u16 status = 0; u16 unused;