diff options
Diffstat (limited to 'drivers/usb/core/hub.c')
-rw-r--r-- | drivers/usb/core/hub.c | 44 |
1 files changed, 19 insertions, 25 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 38cc4bae0a82..cbb146736f57 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -104,6 +104,8 @@ static int usb_reset_and_verify_device(struct usb_device *udev); static inline char *portspeed(struct usb_hub *hub, int portstatus) { + if (hub_is_superspeedplus(hub->hdev)) + return "10.0 Gb/s"; if (hub_is_superspeed(hub->hdev)) return "5.0 Gb/s"; if (portstatus & USB_PORT_STAT_HIGH_SPEED) @@ -1050,14 +1052,11 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) /* Continue a partial initialization */ if (type == HUB_INIT2 || type == HUB_INIT3) { - device_lock(hub->intfdev); + device_lock(&hdev->dev); /* Was the hub disconnected while we were waiting? */ - if (hub->disconnected) { - device_unlock(hub->intfdev); - kref_put(&hub->kref, hub_release); - return; - } + if (hub->disconnected) + goto disconnected; if (type == HUB_INIT2) goto init2; goto init3; @@ -1260,7 +1259,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) queue_delayed_work(system_power_efficient_wq, &hub->init_work, msecs_to_jiffies(delay)); - device_unlock(hub->intfdev); + device_unlock(&hdev->dev); return; /* Continues at init3: below */ } else { msleep(delay); @@ -1279,12 +1278,12 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) /* Scan all ports that need attention */ kick_hub_wq(hub); - /* Allow autosuspend if it was suppressed */ - if (type <= HUB_INIT3) + if (type == HUB_INIT2 || type == HUB_INIT3) { + /* Allow autosuspend if it was suppressed */ + disconnected: usb_autopm_put_interface_async(to_usb_interface(hub->intfdev)); - - if (type == HUB_INIT2 || type == HUB_INIT3) - device_unlock(hub->intfdev); + device_unlock(&hdev->dev); + } kref_put(&hub->kref, hub_release); } @@ -1313,8 +1312,6 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type) struct usb_device *hdev = hub->hdev; int i; - cancel_delayed_work_sync(&hub->init_work); - /* hub_wq and related activity won't re-trigger */ hub->quiescing = 1; @@ -1826,10 +1823,8 @@ descriptor_error: dev_info(&intf->dev, "USB hub found\n"); hub = kzalloc(sizeof(*hub), GFP_KERNEL); - if (!hub) { - dev_dbg(&intf->dev, "couldn't kmalloc hub struct\n"); + if (!hub) return -ENOMEM; - } kref_init(&hub->kref); hub->intfdev = &intf->dev; @@ -2080,7 +2075,7 @@ static void choose_devnum(struct usb_device *udev) struct usb_bus *bus = udev->bus; /* be safe when more hub events are proceed in parallel */ - mutex_lock(&bus->usb_address0_mutex); + mutex_lock(&bus->devnum_next_mutex); if (udev->wusb) { devnum = udev->portnum + 1; BUG_ON(test_bit(devnum, bus->devmap.devicemap)); @@ -2098,7 +2093,7 @@ static void choose_devnum(struct usb_device *udev) set_bit(devnum, bus->devmap.devicemap); udev->devnum = devnum; } - mutex_unlock(&bus->usb_address0_mutex); + mutex_unlock(&bus->devnum_next_mutex); } static void release_devnum(struct usb_device *udev) @@ -3109,7 +3104,7 @@ static int usb_disable_remote_wakeup(struct usb_device *udev) USB_CTRL_SET_TIMEOUT); else return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - USB_REQ_CLEAR_FEATURE, USB_RECIP_INTERFACE, + USB_REQ_SET_FEATURE, USB_RECIP_INTERFACE, USB_INTRF_FUNC_SUSPEND, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); } @@ -4364,7 +4359,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, if (oldspeed == USB_SPEED_LOW) delay = HUB_LONG_RESET_TIME; - mutex_lock(&hdev->bus->usb_address0_mutex); + mutex_lock(hcd->address0_mutex); /* Reset the device; full speed may morph to high speed */ /* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */ @@ -4650,7 +4645,7 @@ fail: hub_port_disable(hub, port1, 0); update_devnum(udev, devnum); /* for disconnect processing */ } - mutex_unlock(&hdev->bus->usb_address0_mutex); + mutex_unlock(hcd->address0_mutex); return retval; } @@ -5340,11 +5335,10 @@ static int descriptors_changed(struct usb_device *udev, } buf = kmalloc(len, GFP_NOIO); - if (buf == NULL) { - dev_err(&udev->dev, "no mem to re-read configs after reset\n"); + if (!buf) /* assume the worst */ return 1; - } + for (index = 0; index < udev->descriptor.bNumConfigurations; index++) { old_length = le16_to_cpu(udev->config[index].desc.wTotalLength); length = usb_get_descriptor(udev, USB_DT_CONFIG, index, buf, |