diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-06-17 19:39:54 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-06-17 19:39:54 -0400 |
commit | 19ea9d668a1f9f1e5e6752549150795a6693e6ad (patch) | |
tree | bb621fb9e2c91291c69895018d47a938639b9ddb | |
parent | 1be627dfa74d9eee1eca1bc48653e461366a2bb9 (diff) | |
parent | f16443a034c7aa359ddf6f0f9bc40d01ca31faea (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.c | 11 | ||||
-rw-r--r-- | drivers/usb/gadget/legacy/inode.c | 9 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/dummy_hcd.c | 13 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/net2280.c | 9 | ||||
-rw-r--r-- | drivers/usb/host/xhci-mem.c | 7 | ||||
-rw-r--r-- | drivers/usb/host/xhci-pci.c | 3 |
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 | } |
319 | EXPORT_SYMBOL_GPL(usb_remove_function); | 322 | EXPORT_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 | |||
1677 | gadgetfs_suspend (struct usb_gadget *gadget) | 1679 | gadgetfs_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 | ||
1696 | static struct usb_gadget_driver gadgetfs_driver = { | 1699 | static 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 | ||
3350 | static void handle_stat1_irqs(struct net2280 *dev, u32 stat) | 3347 | static 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; |