diff options
-rw-r--r-- | drivers/tty/tty_io.c | 11 | ||||
-rw-r--r-- | drivers/usb/core/hub.c | 5 | ||||
-rw-r--r-- | drivers/usb/core/quirks.c | 4 | ||||
-rw-r--r-- | drivers/usb/core/usb.c | 6 | ||||
-rw-r--r-- | drivers/usb/host/hwa-hc.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/xhci-pci.c | 4 | ||||
-rw-r--r-- | drivers/usb/host/xhci.c | 42 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 3 | ||||
-rw-r--r-- | drivers/usb/misc/appledisplay.c | 1 | ||||
-rw-r--r-- | drivers/usb/serial/console.c | 2 | ||||
-rw-r--r-- | include/linux/tty.h | 1 | ||||
-rw-r--r-- | include/linux/usb.h | 4 |
12 files changed, 70 insertions, 15 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index ee80dfbd5442..687250ec8032 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -1373,7 +1373,13 @@ err_release_lock: | |||
1373 | return ERR_PTR(retval); | 1373 | return ERR_PTR(retval); |
1374 | } | 1374 | } |
1375 | 1375 | ||
1376 | static void tty_free_termios(struct tty_struct *tty) | 1376 | /** |
1377 | * tty_save_termios() - save tty termios data in driver table | ||
1378 | * @tty: tty whose termios data to save | ||
1379 | * | ||
1380 | * Locking: Caller guarantees serialisation with tty_init_termios(). | ||
1381 | */ | ||
1382 | void tty_save_termios(struct tty_struct *tty) | ||
1377 | { | 1383 | { |
1378 | struct ktermios *tp; | 1384 | struct ktermios *tp; |
1379 | int idx = tty->index; | 1385 | int idx = tty->index; |
@@ -1392,6 +1398,7 @@ static void tty_free_termios(struct tty_struct *tty) | |||
1392 | } | 1398 | } |
1393 | *tp = tty->termios; | 1399 | *tp = tty->termios; |
1394 | } | 1400 | } |
1401 | EXPORT_SYMBOL_GPL(tty_save_termios); | ||
1395 | 1402 | ||
1396 | /** | 1403 | /** |
1397 | * tty_flush_works - flush all works of a tty/pty pair | 1404 | * tty_flush_works - flush all works of a tty/pty pair |
@@ -1491,7 +1498,7 @@ static void release_tty(struct tty_struct *tty, int idx) | |||
1491 | WARN_ON(!mutex_is_locked(&tty_mutex)); | 1498 | WARN_ON(!mutex_is_locked(&tty_mutex)); |
1492 | if (tty->ops->shutdown) | 1499 | if (tty->ops->shutdown) |
1493 | tty->ops->shutdown(tty); | 1500 | tty->ops->shutdown(tty); |
1494 | tty_free_termios(tty); | 1501 | tty_save_termios(tty); |
1495 | tty_driver_remove_tty(tty->driver, tty); | 1502 | tty_driver_remove_tty(tty->driver, tty); |
1496 | tty->port->itty = NULL; | 1503 | tty->port->itty = NULL; |
1497 | if (tty->link) | 1504 | if (tty->link) |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 0f9381b69a3b..f76b2e0aba9d 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -2251,7 +2251,7 @@ static int usb_enumerate_device_otg(struct usb_device *udev) | |||
2251 | /* descriptor may appear anywhere in config */ | 2251 | /* descriptor may appear anywhere in config */ |
2252 | err = __usb_get_extra_descriptor(udev->rawdescriptors[0], | 2252 | err = __usb_get_extra_descriptor(udev->rawdescriptors[0], |
2253 | le16_to_cpu(udev->config[0].desc.wTotalLength), | 2253 | le16_to_cpu(udev->config[0].desc.wTotalLength), |
2254 | USB_DT_OTG, (void **) &desc); | 2254 | USB_DT_OTG, (void **) &desc, sizeof(*desc)); |
2255 | if (err || !(desc->bmAttributes & USB_OTG_HNP)) | 2255 | if (err || !(desc->bmAttributes & USB_OTG_HNP)) |
2256 | return 0; | 2256 | return 0; |
2257 | 2257 | ||
@@ -5163,7 +5163,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
5163 | /* Handle notifying userspace about hub over-current events */ | 5163 | /* Handle notifying userspace about hub over-current events */ |
5164 | static void port_over_current_notify(struct usb_port *port_dev) | 5164 | static void port_over_current_notify(struct usb_port *port_dev) |
5165 | { | 5165 | { |
5166 | static char *envp[] = { NULL, NULL, NULL }; | 5166 | char *envp[3]; |
5167 | struct device *hub_dev; | 5167 | struct device *hub_dev; |
5168 | char *port_dev_path; | 5168 | char *port_dev_path; |
5169 | 5169 | ||
@@ -5187,6 +5187,7 @@ static void port_over_current_notify(struct usb_port *port_dev) | |||
5187 | if (!envp[1]) | 5187 | if (!envp[1]) |
5188 | goto exit; | 5188 | goto exit; |
5189 | 5189 | ||
5190 | envp[2] = NULL; | ||
5190 | kobject_uevent_env(&hub_dev->kobj, KOBJ_CHANGE, envp); | 5191 | kobject_uevent_env(&hub_dev->kobj, KOBJ_CHANGE, envp); |
5191 | 5192 | ||
5192 | kfree(envp[1]); | 5193 | kfree(envp[1]); |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 0690fcff0ea2..514c5214ddb2 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
@@ -333,6 +333,10 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
333 | /* Midiman M-Audio Keystation 88es */ | 333 | /* Midiman M-Audio Keystation 88es */ |
334 | { USB_DEVICE(0x0763, 0x0192), .driver_info = USB_QUIRK_RESET_RESUME }, | 334 | { USB_DEVICE(0x0763, 0x0192), .driver_info = USB_QUIRK_RESET_RESUME }, |
335 | 335 | ||
336 | /* SanDisk Ultra Fit and Ultra Flair */ | ||
337 | { USB_DEVICE(0x0781, 0x5583), .driver_info = USB_QUIRK_NO_LPM }, | ||
338 | { USB_DEVICE(0x0781, 0x5591), .driver_info = USB_QUIRK_NO_LPM }, | ||
339 | |||
336 | /* M-Systems Flash Disk Pioneers */ | 340 | /* M-Systems Flash Disk Pioneers */ |
337 | { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, | 341 | { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, |
338 | 342 | ||
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 79d8bd7a612e..4ebfbd737905 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -832,14 +832,14 @@ EXPORT_SYMBOL_GPL(usb_get_current_frame_number); | |||
832 | */ | 832 | */ |
833 | 833 | ||
834 | int __usb_get_extra_descriptor(char *buffer, unsigned size, | 834 | int __usb_get_extra_descriptor(char *buffer, unsigned size, |
835 | unsigned char type, void **ptr) | 835 | unsigned char type, void **ptr, size_t minsize) |
836 | { | 836 | { |
837 | struct usb_descriptor_header *header; | 837 | struct usb_descriptor_header *header; |
838 | 838 | ||
839 | while (size >= sizeof(struct usb_descriptor_header)) { | 839 | while (size >= sizeof(struct usb_descriptor_header)) { |
840 | header = (struct usb_descriptor_header *)buffer; | 840 | header = (struct usb_descriptor_header *)buffer; |
841 | 841 | ||
842 | if (header->bLength < 2) { | 842 | if (header->bLength < 2 || header->bLength > size) { |
843 | printk(KERN_ERR | 843 | printk(KERN_ERR |
844 | "%s: bogus descriptor, type %d length %d\n", | 844 | "%s: bogus descriptor, type %d length %d\n", |
845 | usbcore_name, | 845 | usbcore_name, |
@@ -848,7 +848,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size, | |||
848 | return -1; | 848 | return -1; |
849 | } | 849 | } |
850 | 850 | ||
851 | if (header->bDescriptorType == type) { | 851 | if (header->bDescriptorType == type && header->bLength >= minsize) { |
852 | *ptr = header; | 852 | *ptr = header; |
853 | return 0; | 853 | return 0; |
854 | } | 854 | } |
diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c index 684d6f074c3a..09a8ebd95588 100644 --- a/drivers/usb/host/hwa-hc.c +++ b/drivers/usb/host/hwa-hc.c | |||
@@ -640,7 +640,7 @@ static int hwahc_security_create(struct hwahc *hwahc) | |||
640 | top = itr + itr_size; | 640 | top = itr + itr_size; |
641 | result = __usb_get_extra_descriptor(usb_dev->rawdescriptors[index], | 641 | result = __usb_get_extra_descriptor(usb_dev->rawdescriptors[index], |
642 | le16_to_cpu(usb_dev->actconfig->desc.wTotalLength), | 642 | le16_to_cpu(usb_dev->actconfig->desc.wTotalLength), |
643 | USB_DT_SECURITY, (void **) &secd); | 643 | USB_DT_SECURITY, (void **) &secd, sizeof(*secd)); |
644 | if (result == -1) { | 644 | if (result == -1) { |
645 | dev_warn(dev, "BUG? WUSB host has no security descriptors\n"); | 645 | dev_warn(dev, "BUG? WUSB host has no security descriptors\n"); |
646 | return 0; | 646 | return 0; |
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index a9515265db4d..a9ec7051f286 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -139,6 +139,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) | |||
139 | pdev->device == 0x43bb)) | 139 | pdev->device == 0x43bb)) |
140 | xhci->quirks |= XHCI_SUSPEND_DELAY; | 140 | xhci->quirks |= XHCI_SUSPEND_DELAY; |
141 | 141 | ||
142 | if (pdev->vendor == PCI_VENDOR_ID_AMD && | ||
143 | (pdev->device == 0x15e0 || pdev->device == 0x15e1)) | ||
144 | xhci->quirks |= XHCI_SNPS_BROKEN_SUSPEND; | ||
145 | |||
142 | if (pdev->vendor == PCI_VENDOR_ID_AMD) | 146 | if (pdev->vendor == PCI_VENDOR_ID_AMD) |
143 | xhci->quirks |= XHCI_TRUST_TX_LENGTH; | 147 | xhci->quirks |= XHCI_TRUST_TX_LENGTH; |
144 | 148 | ||
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index c928dbbff881..dae3be1b9c8f 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -968,6 +968,7 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup) | |||
968 | unsigned int delay = XHCI_MAX_HALT_USEC; | 968 | unsigned int delay = XHCI_MAX_HALT_USEC; |
969 | struct usb_hcd *hcd = xhci_to_hcd(xhci); | 969 | struct usb_hcd *hcd = xhci_to_hcd(xhci); |
970 | u32 command; | 970 | u32 command; |
971 | u32 res; | ||
971 | 972 | ||
972 | if (!hcd->state) | 973 | if (!hcd->state) |
973 | return 0; | 974 | return 0; |
@@ -1021,11 +1022,28 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup) | |||
1021 | command = readl(&xhci->op_regs->command); | 1022 | command = readl(&xhci->op_regs->command); |
1022 | command |= CMD_CSS; | 1023 | command |= CMD_CSS; |
1023 | writel(command, &xhci->op_regs->command); | 1024 | writel(command, &xhci->op_regs->command); |
1025 | xhci->broken_suspend = 0; | ||
1024 | if (xhci_handshake(&xhci->op_regs->status, | 1026 | if (xhci_handshake(&xhci->op_regs->status, |
1025 | STS_SAVE, 0, 10 * 1000)) { | 1027 | STS_SAVE, 0, 10 * 1000)) { |
1026 | xhci_warn(xhci, "WARN: xHC save state timeout\n"); | 1028 | /* |
1027 | spin_unlock_irq(&xhci->lock); | 1029 | * AMD SNPS xHC 3.0 occasionally does not clear the |
1028 | return -ETIMEDOUT; | 1030 | * SSS bit of USBSTS and when driver tries to poll |
1031 | * to see if the xHC clears BIT(8) which never happens | ||
1032 | * and driver assumes that controller is not responding | ||
1033 | * and times out. To workaround this, its good to check | ||
1034 | * if SRE and HCE bits are not set (as per xhci | ||
1035 | * Section 5.4.2) and bypass the timeout. | ||
1036 | */ | ||
1037 | res = readl(&xhci->op_regs->status); | ||
1038 | if ((xhci->quirks & XHCI_SNPS_BROKEN_SUSPEND) && | ||
1039 | (((res & STS_SRE) == 0) && | ||
1040 | ((res & STS_HCE) == 0))) { | ||
1041 | xhci->broken_suspend = 1; | ||
1042 | } else { | ||
1043 | xhci_warn(xhci, "WARN: xHC save state timeout\n"); | ||
1044 | spin_unlock_irq(&xhci->lock); | ||
1045 | return -ETIMEDOUT; | ||
1046 | } | ||
1029 | } | 1047 | } |
1030 | spin_unlock_irq(&xhci->lock); | 1048 | spin_unlock_irq(&xhci->lock); |
1031 | 1049 | ||
@@ -1078,7 +1096,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) | |||
1078 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); | 1096 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); |
1079 | 1097 | ||
1080 | spin_lock_irq(&xhci->lock); | 1098 | spin_lock_irq(&xhci->lock); |
1081 | if (xhci->quirks & XHCI_RESET_ON_RESUME) | 1099 | if ((xhci->quirks & XHCI_RESET_ON_RESUME) || xhci->broken_suspend) |
1082 | hibernated = true; | 1100 | hibernated = true; |
1083 | 1101 | ||
1084 | if (!hibernated) { | 1102 | if (!hibernated) { |
@@ -4496,6 +4514,14 @@ static u16 xhci_calculate_u1_timeout(struct xhci_hcd *xhci, | |||
4496 | { | 4514 | { |
4497 | unsigned long long timeout_ns; | 4515 | unsigned long long timeout_ns; |
4498 | 4516 | ||
4517 | /* Prevent U1 if service interval is shorter than U1 exit latency */ | ||
4518 | if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) { | ||
4519 | if (xhci_service_interval_to_ns(desc) <= udev->u1_params.mel) { | ||
4520 | dev_dbg(&udev->dev, "Disable U1, ESIT shorter than exit latency\n"); | ||
4521 | return USB3_LPM_DISABLED; | ||
4522 | } | ||
4523 | } | ||
4524 | |||
4499 | if (xhci->quirks & XHCI_INTEL_HOST) | 4525 | if (xhci->quirks & XHCI_INTEL_HOST) |
4500 | timeout_ns = xhci_calculate_intel_u1_timeout(udev, desc); | 4526 | timeout_ns = xhci_calculate_intel_u1_timeout(udev, desc); |
4501 | else | 4527 | else |
@@ -4552,6 +4578,14 @@ static u16 xhci_calculate_u2_timeout(struct xhci_hcd *xhci, | |||
4552 | { | 4578 | { |
4553 | unsigned long long timeout_ns; | 4579 | unsigned long long timeout_ns; |
4554 | 4580 | ||
4581 | /* Prevent U2 if service interval is shorter than U2 exit latency */ | ||
4582 | if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) { | ||
4583 | if (xhci_service_interval_to_ns(desc) <= udev->u2_params.mel) { | ||
4584 | dev_dbg(&udev->dev, "Disable U2, ESIT shorter than exit latency\n"); | ||
4585 | return USB3_LPM_DISABLED; | ||
4586 | } | ||
4587 | } | ||
4588 | |||
4555 | if (xhci->quirks & XHCI_INTEL_HOST) | 4589 | if (xhci->quirks & XHCI_INTEL_HOST) |
4556 | timeout_ns = xhci_calculate_intel_u2_timeout(udev, desc); | 4590 | timeout_ns = xhci_calculate_intel_u2_timeout(udev, desc); |
4557 | else | 4591 | else |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 260b259b72bc..c3515bad5dbb 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -1850,6 +1850,7 @@ struct xhci_hcd { | |||
1850 | #define XHCI_ZERO_64B_REGS BIT_ULL(32) | 1850 | #define XHCI_ZERO_64B_REGS BIT_ULL(32) |
1851 | #define XHCI_DEFAULT_PM_RUNTIME_ALLOW BIT_ULL(33) | 1851 | #define XHCI_DEFAULT_PM_RUNTIME_ALLOW BIT_ULL(33) |
1852 | #define XHCI_RESET_PLL_ON_DISCONNECT BIT_ULL(34) | 1852 | #define XHCI_RESET_PLL_ON_DISCONNECT BIT_ULL(34) |
1853 | #define XHCI_SNPS_BROKEN_SUSPEND BIT_ULL(35) | ||
1853 | 1854 | ||
1854 | unsigned int num_active_eps; | 1855 | unsigned int num_active_eps; |
1855 | unsigned int limit_active_eps; | 1856 | unsigned int limit_active_eps; |
@@ -1879,6 +1880,8 @@ struct xhci_hcd { | |||
1879 | void *dbc; | 1880 | void *dbc; |
1880 | /* platform-specific data -- must come last */ | 1881 | /* platform-specific data -- must come last */ |
1881 | unsigned long priv[0] __aligned(sizeof(s64)); | 1882 | unsigned long priv[0] __aligned(sizeof(s64)); |
1883 | /* Broken Suspend flag for SNPS Suspend resume issue */ | ||
1884 | u8 broken_suspend; | ||
1882 | }; | 1885 | }; |
1883 | 1886 | ||
1884 | /* Platform specific overrides to generic XHCI hc_driver ops */ | 1887 | /* Platform specific overrides to generic XHCI hc_driver ops */ |
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index 85b48c6ddc7e..39ca31b4de46 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c | |||
@@ -51,6 +51,7 @@ static const struct usb_device_id appledisplay_table[] = { | |||
51 | { APPLEDISPLAY_DEVICE(0x921c) }, | 51 | { APPLEDISPLAY_DEVICE(0x921c) }, |
52 | { APPLEDISPLAY_DEVICE(0x921d) }, | 52 | { APPLEDISPLAY_DEVICE(0x921d) }, |
53 | { APPLEDISPLAY_DEVICE(0x9222) }, | 53 | { APPLEDISPLAY_DEVICE(0x9222) }, |
54 | { APPLEDISPLAY_DEVICE(0x9226) }, | ||
54 | { APPLEDISPLAY_DEVICE(0x9236) }, | 55 | { APPLEDISPLAY_DEVICE(0x9236) }, |
55 | 56 | ||
56 | /* Terminating entry */ | 57 | /* Terminating entry */ |
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index 17940589c647..7d289302ff6c 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c | |||
@@ -101,7 +101,6 @@ static int usb_console_setup(struct console *co, char *options) | |||
101 | cflag |= PARENB; | 101 | cflag |= PARENB; |
102 | break; | 102 | break; |
103 | } | 103 | } |
104 | co->cflag = cflag; | ||
105 | 104 | ||
106 | /* | 105 | /* |
107 | * no need to check the index here: if the index is wrong, console | 106 | * no need to check the index here: if the index is wrong, console |
@@ -164,6 +163,7 @@ static int usb_console_setup(struct console *co, char *options) | |||
164 | serial->type->set_termios(tty, port, &dummy); | 163 | serial->type->set_termios(tty, port, &dummy); |
165 | 164 | ||
166 | tty_port_tty_set(&port->port, NULL); | 165 | tty_port_tty_set(&port->port, NULL); |
166 | tty_save_termios(tty); | ||
167 | tty_kref_put(tty); | 167 | tty_kref_put(tty); |
168 | } | 168 | } |
169 | tty_port_set_initialized(&port->port, 1); | 169 | tty_port_set_initialized(&port->port, 1); |
diff --git a/include/linux/tty.h b/include/linux/tty.h index 414db2bce715..392138fe59b6 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
@@ -556,6 +556,7 @@ extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx); | |||
556 | extern void tty_release_struct(struct tty_struct *tty, int idx); | 556 | extern void tty_release_struct(struct tty_struct *tty, int idx); |
557 | extern int tty_release(struct inode *inode, struct file *filp); | 557 | extern int tty_release(struct inode *inode, struct file *filp); |
558 | extern void tty_init_termios(struct tty_struct *tty); | 558 | extern void tty_init_termios(struct tty_struct *tty); |
559 | extern void tty_save_termios(struct tty_struct *tty); | ||
559 | extern int tty_standard_install(struct tty_driver *driver, | 560 | extern int tty_standard_install(struct tty_driver *driver, |
560 | struct tty_struct *tty); | 561 | struct tty_struct *tty); |
561 | 562 | ||
diff --git a/include/linux/usb.h b/include/linux/usb.h index 4cdd515a4385..5e49e82c4368 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h | |||
@@ -407,11 +407,11 @@ struct usb_host_bos { | |||
407 | }; | 407 | }; |
408 | 408 | ||
409 | int __usb_get_extra_descriptor(char *buffer, unsigned size, | 409 | int __usb_get_extra_descriptor(char *buffer, unsigned size, |
410 | unsigned char type, void **ptr); | 410 | unsigned char type, void **ptr, size_t min); |
411 | #define usb_get_extra_descriptor(ifpoint, type, ptr) \ | 411 | #define usb_get_extra_descriptor(ifpoint, type, ptr) \ |
412 | __usb_get_extra_descriptor((ifpoint)->extra, \ | 412 | __usb_get_extra_descriptor((ifpoint)->extra, \ |
413 | (ifpoint)->extralen, \ | 413 | (ifpoint)->extralen, \ |
414 | type, (void **)ptr) | 414 | type, (void **)ptr, sizeof(**(ptr))) |
415 | 415 | ||
416 | /* ----------------------------------------------------------------------- */ | 416 | /* ----------------------------------------------------------------------- */ |
417 | 417 | ||