aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-06-17 19:39:54 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-06-17 19:39:54 -0400
commit19ea9d668a1f9f1e5e6752549150795a6693e6ad (patch)
treebb621fb9e2c91291c69895018d47a938639b9ddb
parent1be627dfa74d9eee1eca1bc48653e461366a2bb9 (diff)
parentf16443a034c7aa359ddf6f0f9bc40d01ca31faea (diff)
Merge tag 'usb-4.12-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB fixes from Greg KH: "Here are some small gadget and xhci USB fixes for 4.12-rc6. Nothing major, but one of the gadget patches does fix a reported oops, and the xhci ones resolve reported problems. All have been in linux-next with no reported issues" * tag 'usb-4.12-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: USB: gadgetfs, dummy-hcd, net2280: fix locking for callbacks usb: xhci: ASMedia ASM1042A chipset need shorts TX quirk usb: xhci: Fix USB 3.1 supported protocol parsing USB: gadget: fix GPF in gadgetfs usb: gadget: composite: make sure to reactivate function on unbind
-rw-r--r--drivers/usb/gadget/composite.c11
-rw-r--r--drivers/usb/gadget/legacy/inode.c9
-rw-r--r--drivers/usb/gadget/udc/dummy_hcd.c13
-rw-r--r--drivers/usb/gadget/udc/net2280.c9
-rw-r--r--drivers/usb/host/xhci-mem.c7
-rw-r--r--drivers/usb/host/xhci-pci.c3
6 files changed, 24 insertions, 28 deletions
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 49d685ad0da9..45b554032332 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -315,6 +315,9 @@ void usb_remove_function(struct usb_configuration *c, struct usb_function *f)
315 list_del(&f->list); 315 list_del(&f->list);
316 if (f->unbind) 316 if (f->unbind)
317 f->unbind(c, f); 317 f->unbind(c, f);
318
319 if (f->bind_deactivated)
320 usb_function_activate(f);
318} 321}
319EXPORT_SYMBOL_GPL(usb_remove_function); 322EXPORT_SYMBOL_GPL(usb_remove_function);
320 323
@@ -956,12 +959,8 @@ static void remove_config(struct usb_composite_dev *cdev,
956 959
957 f = list_first_entry(&config->functions, 960 f = list_first_entry(&config->functions,
958 struct usb_function, list); 961 struct usb_function, list);
959 list_del(&f->list); 962
960 if (f->unbind) { 963 usb_remove_function(config, f);
961 DBG(cdev, "unbind function '%s'/%p\n", f->name, f);
962 f->unbind(config, f);
963 /* may free memory for "f" */
964 }
965 } 964 }
966 list_del(&config->list); 965 list_del(&config->list);
967 if (config->unbind) { 966 if (config->unbind) {
diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c
index b9ca0a26cbd9..684900fcfe24 100644
--- a/drivers/usb/gadget/legacy/inode.c
+++ b/drivers/usb/gadget/legacy/inode.c
@@ -1183,8 +1183,10 @@ dev_release (struct inode *inode, struct file *fd)
1183 1183
1184 /* closing ep0 === shutdown all */ 1184 /* closing ep0 === shutdown all */
1185 1185
1186 if (dev->gadget_registered) 1186 if (dev->gadget_registered) {
1187 usb_gadget_unregister_driver (&gadgetfs_driver); 1187 usb_gadget_unregister_driver (&gadgetfs_driver);
1188 dev->gadget_registered = false;
1189 }
1188 1190
1189 /* at this point "good" hardware has disconnected the 1191 /* at this point "good" hardware has disconnected the
1190 * device from USB; the host won't see it any more. 1192 * device from USB; the host won't see it any more.
@@ -1677,9 +1679,10 @@ static void
1677gadgetfs_suspend (struct usb_gadget *gadget) 1679gadgetfs_suspend (struct usb_gadget *gadget)
1678{ 1680{
1679 struct dev_data *dev = get_gadget_data (gadget); 1681 struct dev_data *dev = get_gadget_data (gadget);
1682 unsigned long flags;
1680 1683
1681 INFO (dev, "suspended from state %d\n", dev->state); 1684 INFO (dev, "suspended from state %d\n", dev->state);
1682 spin_lock (&dev->lock); 1685 spin_lock_irqsave(&dev->lock, flags);
1683 switch (dev->state) { 1686 switch (dev->state) {
1684 case STATE_DEV_SETUP: // VERY odd... host died?? 1687 case STATE_DEV_SETUP: // VERY odd... host died??
1685 case STATE_DEV_CONNECTED: 1688 case STATE_DEV_CONNECTED:
@@ -1690,7 +1693,7 @@ gadgetfs_suspend (struct usb_gadget *gadget)
1690 default: 1693 default:
1691 break; 1694 break;
1692 } 1695 }
1693 spin_unlock (&dev->lock); 1696 spin_unlock_irqrestore(&dev->lock, flags);
1694} 1697}
1695 1698
1696static struct usb_gadget_driver gadgetfs_driver = { 1699static struct usb_gadget_driver gadgetfs_driver = {
diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c
index ccabb51cb98d..7635fd7cc328 100644
--- a/drivers/usb/gadget/udc/dummy_hcd.c
+++ b/drivers/usb/gadget/udc/dummy_hcd.c
@@ -442,23 +442,16 @@ static void set_link_state(struct dummy_hcd *dum_hcd)
442 /* Report reset and disconnect events to the driver */ 442 /* Report reset and disconnect events to the driver */
443 if (dum->driver && (disconnect || reset)) { 443 if (dum->driver && (disconnect || reset)) {
444 stop_activity(dum); 444 stop_activity(dum);
445 spin_unlock(&dum->lock);
446 if (reset) 445 if (reset)
447 usb_gadget_udc_reset(&dum->gadget, dum->driver); 446 usb_gadget_udc_reset(&dum->gadget, dum->driver);
448 else 447 else
449 dum->driver->disconnect(&dum->gadget); 448 dum->driver->disconnect(&dum->gadget);
450 spin_lock(&dum->lock);
451 } 449 }
452 } else if (dum_hcd->active != dum_hcd->old_active) { 450 } else if (dum_hcd->active != dum_hcd->old_active) {
453 if (dum_hcd->old_active && dum->driver->suspend) { 451 if (dum_hcd->old_active && dum->driver->suspend)
454 spin_unlock(&dum->lock);
455 dum->driver->suspend(&dum->gadget); 452 dum->driver->suspend(&dum->gadget);
456 spin_lock(&dum->lock); 453 else if (!dum_hcd->old_active && dum->driver->resume)
457 } else if (!dum_hcd->old_active && dum->driver->resume) {
458 spin_unlock(&dum->lock);
459 dum->driver->resume(&dum->gadget); 454 dum->driver->resume(&dum->gadget);
460 spin_lock(&dum->lock);
461 }
462 } 455 }
463 456
464 dum_hcd->old_status = dum_hcd->port_status; 457 dum_hcd->old_status = dum_hcd->port_status;
@@ -983,7 +976,9 @@ static int dummy_udc_stop(struct usb_gadget *g)
983 struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g); 976 struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g);
984 struct dummy *dum = dum_hcd->dum; 977 struct dummy *dum = dum_hcd->dum;
985 978
979 spin_lock_irq(&dum->lock);
986 dum->driver = NULL; 980 dum->driver = NULL;
981 spin_unlock_irq(&dum->lock);
987 982
988 return 0; 983 return 0;
989} 984}
diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c
index 6cf07857eaca..f2cbd7f8005e 100644
--- a/drivers/usb/gadget/udc/net2280.c
+++ b/drivers/usb/gadget/udc/net2280.c
@@ -2470,11 +2470,8 @@ static void stop_activity(struct net2280 *dev, struct usb_gadget_driver *driver)
2470 nuke(&dev->ep[i]); 2470 nuke(&dev->ep[i]);
2471 2471
2472 /* report disconnect; the driver is already quiesced */ 2472 /* report disconnect; the driver is already quiesced */
2473 if (driver) { 2473 if (driver)
2474 spin_unlock(&dev->lock);
2475 driver->disconnect(&dev->gadget); 2474 driver->disconnect(&dev->gadget);
2476 spin_lock(&dev->lock);
2477 }
2478 2475
2479 usb_reinit(dev); 2476 usb_reinit(dev);
2480} 2477}
@@ -3348,8 +3345,6 @@ next_endpoints:
3348 BIT(PCI_RETRY_ABORT_INTERRUPT)) 3345 BIT(PCI_RETRY_ABORT_INTERRUPT))
3349 3346
3350static void handle_stat1_irqs(struct net2280 *dev, u32 stat) 3347static void handle_stat1_irqs(struct net2280 *dev, u32 stat)
3351__releases(dev->lock)
3352__acquires(dev->lock)
3353{ 3348{
3354 struct net2280_ep *ep; 3349 struct net2280_ep *ep;
3355 u32 tmp, num, mask, scratch; 3350 u32 tmp, num, mask, scratch;
@@ -3390,14 +3385,12 @@ __acquires(dev->lock)
3390 if (disconnect || reset) { 3385 if (disconnect || reset) {
3391 stop_activity(dev, dev->driver); 3386 stop_activity(dev, dev->driver);
3392 ep0_start(dev); 3387 ep0_start(dev);
3393 spin_unlock(&dev->lock);
3394 if (reset) 3388 if (reset)
3395 usb_gadget_udc_reset 3389 usb_gadget_udc_reset
3396 (&dev->gadget, dev->driver); 3390 (&dev->gadget, dev->driver);
3397 else 3391 else
3398 (dev->driver->disconnect) 3392 (dev->driver->disconnect)
3399 (&dev->gadget); 3393 (&dev->gadget);
3400 spin_lock(&dev->lock);
3401 return; 3394 return;
3402 } 3395 }
3403 } 3396 }
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 1f1687e888d6..fddf2731f798 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -2119,11 +2119,12 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports,
2119{ 2119{
2120 u32 temp, port_offset, port_count; 2120 u32 temp, port_offset, port_count;
2121 int i; 2121 int i;
2122 u8 major_revision; 2122 u8 major_revision, minor_revision;
2123 struct xhci_hub *rhub; 2123 struct xhci_hub *rhub;
2124 2124
2125 temp = readl(addr); 2125 temp = readl(addr);
2126 major_revision = XHCI_EXT_PORT_MAJOR(temp); 2126 major_revision = XHCI_EXT_PORT_MAJOR(temp);
2127 minor_revision = XHCI_EXT_PORT_MINOR(temp);
2127 2128
2128 if (major_revision == 0x03) { 2129 if (major_revision == 0x03) {
2129 rhub = &xhci->usb3_rhub; 2130 rhub = &xhci->usb3_rhub;
@@ -2137,7 +2138,9 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports,
2137 return; 2138 return;
2138 } 2139 }
2139 rhub->maj_rev = XHCI_EXT_PORT_MAJOR(temp); 2140 rhub->maj_rev = XHCI_EXT_PORT_MAJOR(temp);
2140 rhub->min_rev = XHCI_EXT_PORT_MINOR(temp); 2141
2142 if (rhub->min_rev < minor_revision)
2143 rhub->min_rev = minor_revision;
2141 2144
2142 /* Port offset and count in the third dword, see section 7.2 */ 2145 /* Port offset and count in the third dword, see section 7.2 */
2143 temp = readl(addr + 2); 2146 temp = readl(addr + 2);
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index fcf1f3f63e7a..1bcf971141c0 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -201,6 +201,9 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
201 if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && 201 if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
202 pdev->device == 0x1042) 202 pdev->device == 0x1042)
203 xhci->quirks |= XHCI_BROKEN_STREAMS; 203 xhci->quirks |= XHCI_BROKEN_STREAMS;
204 if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
205 pdev->device == 0x1142)
206 xhci->quirks |= XHCI_TRUST_TX_LENGTH;
204 207
205 if (pdev->vendor == PCI_VENDOR_ID_TI && pdev->device == 0x8241) 208 if (pdev->vendor == PCI_VENDOR_ID_TI && pdev->device == 0x8241)
206 xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_7; 209 xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_7;