|
@@ -2896,10 +2896,12 @@ static int port_is_suspended(struct usb_hub *hub, unsigned portstatus)
|
|
|
*/
|
|
|
static int check_port_resume_type(struct usb_device *udev,
|
|
|
struct usb_hub *hub, int port1,
|
|
|
- int status, unsigned portchange, unsigned portstatus)
|
|
|
+ int status, u16 portchange, u16 portstatus)
|
|
|
{
|
|
|
struct usb_port *port_dev = hub->ports[port1 - 1];
|
|
|
+ int retries = 3;
|
|
|
|
|
|
+ retry:
|
|
|
/* Is a warm reset needed to recover the connection? */
|
|
|
if (status == 0 && udev->reset_resume
|
|
|
&& hub_port_warm_reset_required(hub, port1, portstatus)) {
|
|
@@ -2907,10 +2909,17 @@ static int check_port_resume_type(struct usb_device *udev,
|
|
|
}
|
|
|
/* Is the device still present? */
|
|
|
else if (status || port_is_suspended(hub, portstatus) ||
|
|
|
- !port_is_power_on(hub, portstatus) ||
|
|
|
- !(portstatus & USB_PORT_STAT_CONNECTION)) {
|
|
|
+ !port_is_power_on(hub, portstatus)) {
|
|
|
if (status >= 0)
|
|
|
status = -ENODEV;
|
|
|
+ } else if (!(portstatus & USB_PORT_STAT_CONNECTION)) {
|
|
|
+ if (retries--) {
|
|
|
+ usleep_range(200, 300);
|
|
|
+ status = hub_port_status(hub, port1, &portstatus,
|
|
|
+ &portchange);
|
|
|
+ goto retry;
|
|
|
+ }
|
|
|
+ status = -ENODEV;
|
|
|
}
|
|
|
|
|
|
/* Can't do a normal resume if the port isn't enabled,
|