aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2012-01-24 16:53:18 -0500
committerSarah Sharp <sarah.a.sharp@linux.intel.com>2012-02-14 15:12:25 -0500
commit714b07be3bbf94d2dc9838723d63fc827fdbef12 (patch)
treef1cc2f85151f14dcc70e73b94c8ef8e364dc1276 /drivers
parent4296c70a5ec316903ef037ed15f154dd3d354ad7 (diff)
USB: Refactor hub remote wake handling.
Refactor the code to check for a remote wakeup on a port into its own function. Keep the behavior the same, and set connect_change in hub_events if the device disconnected on resume. Cleanup references to hdev->children[i-1] to use a common variable. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/core/hub.c59
1 files changed, 35 insertions, 24 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index b3137fa65f2a..ba9509454ed5 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3488,6 +3488,39 @@ done:
3488 hcd->driver->relinquish_port(hcd, port1); 3488 hcd->driver->relinquish_port(hcd, port1);
3489} 3489}
3490 3490
3491/* Returns 1 if there was a remote wakeup and a connect status change. */
3492static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port,
3493 u16 portchange)
3494{
3495 struct usb_device *hdev;
3496 struct usb_device *udev;
3497 int connect_change = 0;
3498 int ret;
3499
3500 hdev = hub->hdev;
3501 if (!(portchange & USB_PORT_STAT_C_SUSPEND))
3502 return 0;
3503 clear_port_feature(hdev, port, USB_PORT_FEAT_C_SUSPEND);
3504
3505 udev = hdev->children[port-1];
3506 if (udev) {
3507 /* TRSMRCY = 10 msec */
3508 msleep(10);
3509
3510 usb_lock_device(udev);
3511 ret = usb_remote_wakeup(udev);
3512 usb_unlock_device(udev);
3513 if (ret < 0)
3514 connect_change = 1;
3515 } else {
3516 ret = -ENODEV;
3517 hub_port_disable(hub, port, 1);
3518 }
3519 dev_dbg(hub->intfdev, "resume on port %d, status %d\n",
3520 port, ret);
3521 return connect_change;
3522}
3523
3491static void hub_events(void) 3524static void hub_events(void)
3492{ 3525{
3493 struct list_head *tmp; 3526 struct list_head *tmp;
@@ -3621,31 +3654,9 @@ static void hub_events(void)
3621 } 3654 }
3622 } 3655 }
3623 3656
3624 if (portchange & USB_PORT_STAT_C_SUSPEND) { 3657 if (hub_handle_remote_wakeup(hub, i, portchange))
3625 struct usb_device *udev; 3658 connect_change = 1;
3626 3659
3627 clear_port_feature(hdev, i,
3628 USB_PORT_FEAT_C_SUSPEND);
3629 udev = hdev->children[i-1];
3630 if (udev) {
3631 /* TRSMRCY = 10 msec */
3632 msleep(10);
3633
3634 usb_lock_device(udev);
3635 ret = usb_remote_wakeup(hdev->
3636 children[i-1]);
3637 usb_unlock_device(udev);
3638 if (ret < 0)
3639 connect_change = 1;
3640 } else {
3641 ret = -ENODEV;
3642 hub_port_disable(hub, i, 1);
3643 }
3644 dev_dbg (hub_dev,
3645 "resume on port %d, status %d\n",
3646 i, ret);
3647 }
3648
3649 if (portchange & USB_PORT_STAT_C_OVERCURRENT) { 3660 if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
3650 u16 status = 0; 3661 u16 status = 0;
3651 u16 unused; 3662 u16 unused;