diff options
author | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2012-12-04 18:27:50 -0500 |
---|---|---|
committer | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2013-01-03 17:10:32 -0500 |
commit | 2d4fa940f99663c82ba55b2244638833b388e4e2 (patch) | |
tree | f350a0a9da069bb165727b2a80b13d049dea4183 /drivers/usb/core | |
parent | 0fe51aa5eee51db7c7ecd201d42a977ad79c58b6 (diff) |
USB: Prepare for refactoring by adding extra udev checks.
The next patch will refactor the hub port code to rip out the recursive
call to hub_port_reset on a failed hot reset. In preparation for that,
make sure all code paths can deal with being called with a NULL udev.
The usb_device will not be valid if warm reset was issued because a port
transitioned to the Inactive or Compliance Mode on a device connect.
This patch should have no effect on current behavior.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Diffstat (limited to 'drivers/usb/core')
-rw-r--r-- | drivers/usb/core/hub.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 855bb0d6313d..c3368f978c44 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -2584,6 +2584,9 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1, | |||
2584 | return -ENOTCONN; | 2584 | return -ENOTCONN; |
2585 | 2585 | ||
2586 | if ((portstatus & USB_PORT_STAT_ENABLE)) { | 2586 | if ((portstatus & USB_PORT_STAT_ENABLE)) { |
2587 | if (!udev) | ||
2588 | return 0; | ||
2589 | |||
2587 | if (hub_is_wusb(hub)) | 2590 | if (hub_is_wusb(hub)) |
2588 | udev->speed = USB_SPEED_WIRELESS; | 2591 | udev->speed = USB_SPEED_WIRELESS; |
2589 | else if (hub_is_superspeed(hub->hdev)) | 2592 | else if (hub_is_superspeed(hub->hdev)) |
@@ -2627,13 +2630,15 @@ static void hub_port_finish_reset(struct usb_hub *hub, int port1, | |||
2627 | struct usb_hcd *hcd; | 2630 | struct usb_hcd *hcd; |
2628 | /* TRSTRCY = 10 ms; plus some extra */ | 2631 | /* TRSTRCY = 10 ms; plus some extra */ |
2629 | msleep(10 + 40); | 2632 | msleep(10 + 40); |
2630 | update_devnum(udev, 0); | 2633 | if (udev) { |
2631 | hcd = bus_to_hcd(udev->bus); | 2634 | update_devnum(udev, 0); |
2632 | /* The xHC may think the device is already reset, | 2635 | hcd = bus_to_hcd(udev->bus); |
2633 | * so ignore the status. | 2636 | /* The xHC may think the device is already |
2634 | */ | 2637 | * reset, so ignore the status. |
2635 | if (hcd->driver->reset_device) | 2638 | */ |
2636 | hcd->driver->reset_device(hcd, udev); | 2639 | if (hcd->driver->reset_device) |
2640 | hcd->driver->reset_device(hcd, udev); | ||
2641 | } | ||
2637 | } | 2642 | } |
2638 | /* FALL THROUGH */ | 2643 | /* FALL THROUGH */ |
2639 | case -ENOTCONN: | 2644 | case -ENOTCONN: |
@@ -2647,7 +2652,7 @@ static void hub_port_finish_reset(struct usb_hub *hub, int port1, | |||
2647 | clear_port_feature(hub->hdev, port1, | 2652 | clear_port_feature(hub->hdev, port1, |
2648 | USB_PORT_FEAT_C_PORT_LINK_STATE); | 2653 | USB_PORT_FEAT_C_PORT_LINK_STATE); |
2649 | } | 2654 | } |
2650 | if (!warm) | 2655 | if (!warm && udev) |
2651 | usb_set_device_state(udev, *status | 2656 | usb_set_device_state(udev, *status |
2652 | ? USB_STATE_NOTATTACHED | 2657 | ? USB_STATE_NOTATTACHED |
2653 | : USB_STATE_DEFAULT); | 2658 | : USB_STATE_DEFAULT); |