aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/core
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/core')
-rw-r--r--drivers/usb/core/devices.c2
-rw-r--r--drivers/usb/core/hcd.c18
-rw-r--r--drivers/usb/core/hub.c18
-rw-r--r--drivers/usb/core/message.c8
-rw-r--r--drivers/usb/core/sysfs.c6
5 files changed, 37 insertions, 15 deletions
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
index 96f11715cd2..355dffcc23b 100644
--- a/drivers/usb/core/devices.c
+++ b/drivers/usb/core/devices.c
@@ -494,7 +494,7 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,
return 0;
/* allocate 2^1 pages = 8K (on i386);
* should be more than enough for one device */
- pages_start = (char *)__get_free_pages(GFP_KERNEL, 1);
+ pages_start = (char *)__get_free_pages(GFP_NOIO, 1);
if (!pages_start)
return -ENOMEM;
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 0495fa65122..80995ef0868 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1684,6 +1684,24 @@ int usb_hcd_alloc_bandwidth(struct usb_device *udev,
}
}
if (cur_alt && new_alt) {
+ struct usb_interface *iface = usb_ifnum_to_if(udev,
+ cur_alt->desc.bInterfaceNumber);
+
+ if (iface->resetting_device) {
+ /*
+ * The USB core just reset the device, so the xHCI host
+ * and the device will think alt setting 0 is installed.
+ * However, the USB core will pass in the alternate
+ * setting installed before the reset as cur_alt. Dig
+ * out the alternate setting 0 structure, or the first
+ * alternate setting if a broken device doesn't have alt
+ * setting 0.
+ */
+ cur_alt = usb_altnum_to_altsetting(iface, 0);
+ if (!cur_alt)
+ cur_alt = &iface->altsetting[0];
+ }
+
/* Drop all the endpoints in the current alt setting */
for (i = 0; i < cur_alt->desc.bNumEndpoints; i++) {
ret = hcd->driver->drop_endpoint(hcd, udev,
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 0cec6caf6e9..35cc8b9ba1f 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3347,6 +3347,9 @@ static void hub_events(void)
USB_PORT_FEAT_C_SUSPEND);
udev = hdev->children[i-1];
if (udev) {
+ /* TRSMRCY = 10 msec */
+ msleep(10);
+
usb_lock_device(udev);
ret = remote_wakeup(hdev->
children[i-1]);
@@ -3692,19 +3695,14 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
usb_enable_interface(udev, intf, true);
ret = 0;
} else {
- /* We've just reset the device, so it will think alt
- * setting 0 is installed. For usb_set_interface() to
- * work properly, we need to set the current alternate
- * interface setting to 0 (or the first alt setting, if
- * the device doesn't have alt setting 0).
+ /* Let the bandwidth allocation function know that this
+ * device has been reset, and it will have to use
+ * alternate setting 0 as the current alternate setting.
*/
- intf->cur_altsetting =
- usb_find_alt_setting(config, i, 0);
- if (!intf->cur_altsetting)
- intf->cur_altsetting =
- &config->intf_cache[i]->altsetting[0];
+ intf->resetting_device = 1;
ret = usb_set_interface(udev, desc->bInterfaceNumber,
desc->bAlternateSetting);
+ intf->resetting_device = 0;
}
if (ret < 0) {
dev_err(&udev->dev, "failed to restore interface %d "
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 1b994846e8e..9bc95fec793 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -906,11 +906,11 @@ char *usb_cache_string(struct usb_device *udev, int index)
if (index <= 0)
return NULL;
- buf = kmalloc(MAX_USB_STRING_SIZE, GFP_KERNEL);
+ buf = kmalloc(MAX_USB_STRING_SIZE, GFP_NOIO);
if (buf) {
len = usb_string(udev, index, buf, MAX_USB_STRING_SIZE);
if (len > 0) {
- smallbuf = kmalloc(++len, GFP_KERNEL);
+ smallbuf = kmalloc(++len, GFP_NOIO);
if (!smallbuf)
return buf;
memcpy(smallbuf, buf, len);
@@ -1731,7 +1731,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
if (cp) {
nintf = cp->desc.bNumInterfaces;
new_interfaces = kmalloc(nintf * sizeof(*new_interfaces),
- GFP_KERNEL);
+ GFP_NOIO);
if (!new_interfaces) {
dev_err(&dev->dev, "Out of memory\n");
return -ENOMEM;
@@ -1740,7 +1740,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
for (; n < nintf; ++n) {
new_interfaces[n] = kzalloc(
sizeof(struct usb_interface),
- GFP_KERNEL);
+ GFP_NOIO);
if (!new_interfaces[n]) {
dev_err(&dev->dev, "Out of memory\n");
ret = -ENOMEM;
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 485edf937f2..5f3908f6e2d 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -115,6 +115,12 @@ show_speed(struct device *dev, struct device_attribute *attr, char *buf)
case USB_SPEED_HIGH:
speed = "480";
break;
+ case USB_SPEED_VARIABLE:
+ speed = "480";
+ break;
+ case USB_SPEED_SUPER:
+ speed = "5000";
+ break;
default:
speed = "unknown";
}