diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-04-01 14:50:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-04-01 14:50:25 -0400 |
commit | a9f6b6b8cd2f5c935e9cd78b322897c08fe3ad82 (patch) | |
tree | 34f3bac8d88c25cc84ff9d5ad61be731de4c5950 | |
parent | b3ff4fac96295e0a92bdcee34887fad5cbb63d3b (diff) | |
parent | a7f12a21f6b32bdd8d76d3af81eef9e72ce41ec0 (diff) |
Merge tag 'usb-4.11-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB fixes from Greg KH:
"Here are some small USB fixes for 4.11-rc5.
The usual xhci fixes are here, as well as a fix for yet-another-bug-
found-by-KASAN, those developers are doing great stuff here.
And there's a phy build warning fix that showed up in 4.11-rc1.
All of these have been in linux-next with no reported issues"
* tag 'usb-4.11-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
usb: phy: isp1301: Fix build warning when CONFIG_OF is disabled
xhci: Manually give back cancelled URB if we can't queue it for cancel
xhci: Set URB actual length for stopped control transfers
xhci: plat: Register shutdown for xhci_plat
USB: fix linked-list corruption in rh_call_control()
-rw-r--r-- | drivers/usb/core/hcd.c | 7 | ||||
-rw-r--r-- | drivers/usb/host/xhci-plat.c | 1 | ||||
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 3 | ||||
-rw-r--r-- | drivers/usb/host/xhci.c | 43 | ||||
-rw-r--r-- | drivers/usb/phy/phy-isp1301.c | 2 |
5 files changed, 35 insertions, 21 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 612fab6e54fb..79bdca5cb9c7 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -520,8 +520,10 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) | |||
520 | */ | 520 | */ |
521 | tbuf_size = max_t(u16, sizeof(struct usb_hub_descriptor), wLength); | 521 | tbuf_size = max_t(u16, sizeof(struct usb_hub_descriptor), wLength); |
522 | tbuf = kzalloc(tbuf_size, GFP_KERNEL); | 522 | tbuf = kzalloc(tbuf_size, GFP_KERNEL); |
523 | if (!tbuf) | 523 | if (!tbuf) { |
524 | return -ENOMEM; | 524 | status = -ENOMEM; |
525 | goto err_alloc; | ||
526 | } | ||
525 | 527 | ||
526 | bufp = tbuf; | 528 | bufp = tbuf; |
527 | 529 | ||
@@ -734,6 +736,7 @@ error: | |||
734 | } | 736 | } |
735 | 737 | ||
736 | kfree(tbuf); | 738 | kfree(tbuf); |
739 | err_alloc: | ||
737 | 740 | ||
738 | /* any errors get returned through the urb completion */ | 741 | /* any errors get returned through the urb completion */ |
739 | spin_lock_irq(&hcd_root_hub_lock); | 742 | spin_lock_irq(&hcd_root_hub_lock); |
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index bd02a6cd8e2c..6ed468fa7d5e 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c | |||
@@ -344,6 +344,7 @@ MODULE_DEVICE_TABLE(acpi, usb_xhci_acpi_match); | |||
344 | static struct platform_driver usb_xhci_driver = { | 344 | static struct platform_driver usb_xhci_driver = { |
345 | .probe = xhci_plat_probe, | 345 | .probe = xhci_plat_probe, |
346 | .remove = xhci_plat_remove, | 346 | .remove = xhci_plat_remove, |
347 | .shutdown = usb_hcd_platform_shutdown, | ||
347 | .driver = { | 348 | .driver = { |
348 | .name = "xhci-hcd", | 349 | .name = "xhci-hcd", |
349 | .pm = DEV_PM_OPS, | 350 | .pm = DEV_PM_OPS, |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index d9936c771fa0..a3309aa02993 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -1989,6 +1989,9 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
1989 | case TRB_NORMAL: | 1989 | case TRB_NORMAL: |
1990 | td->urb->actual_length = requested - remaining; | 1990 | td->urb->actual_length = requested - remaining; |
1991 | goto finish_td; | 1991 | goto finish_td; |
1992 | case TRB_STATUS: | ||
1993 | td->urb->actual_length = requested; | ||
1994 | goto finish_td; | ||
1992 | default: | 1995 | default: |
1993 | xhci_warn(xhci, "WARN: unexpected TRB Type %d\n", | 1996 | xhci_warn(xhci, "WARN: unexpected TRB Type %d\n", |
1994 | trb_type); | 1997 | trb_type); |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 50aee8b7718b..953fd8f62df0 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -1477,6 +1477,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
1477 | struct xhci_ring *ep_ring; | 1477 | struct xhci_ring *ep_ring; |
1478 | struct xhci_virt_ep *ep; | 1478 | struct xhci_virt_ep *ep; |
1479 | struct xhci_command *command; | 1479 | struct xhci_command *command; |
1480 | struct xhci_virt_device *vdev; | ||
1480 | 1481 | ||
1481 | xhci = hcd_to_xhci(hcd); | 1482 | xhci = hcd_to_xhci(hcd); |
1482 | spin_lock_irqsave(&xhci->lock, flags); | 1483 | spin_lock_irqsave(&xhci->lock, flags); |
@@ -1485,15 +1486,27 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
1485 | 1486 | ||
1486 | /* Make sure the URB hasn't completed or been unlinked already */ | 1487 | /* Make sure the URB hasn't completed or been unlinked already */ |
1487 | ret = usb_hcd_check_unlink_urb(hcd, urb, status); | 1488 | ret = usb_hcd_check_unlink_urb(hcd, urb, status); |
1488 | if (ret || !urb->hcpriv) | 1489 | if (ret) |
1489 | goto done; | 1490 | goto done; |
1491 | |||
1492 | /* give back URB now if we can't queue it for cancel */ | ||
1493 | vdev = xhci->devs[urb->dev->slot_id]; | ||
1494 | urb_priv = urb->hcpriv; | ||
1495 | if (!vdev || !urb_priv) | ||
1496 | goto err_giveback; | ||
1497 | |||
1498 | ep_index = xhci_get_endpoint_index(&urb->ep->desc); | ||
1499 | ep = &vdev->eps[ep_index]; | ||
1500 | ep_ring = xhci_urb_to_transfer_ring(xhci, urb); | ||
1501 | if (!ep || !ep_ring) | ||
1502 | goto err_giveback; | ||
1503 | |||
1490 | temp = readl(&xhci->op_regs->status); | 1504 | temp = readl(&xhci->op_regs->status); |
1491 | if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_HALTED)) { | 1505 | if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_HALTED)) { |
1492 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, | 1506 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, |
1493 | "HW died, freeing TD."); | 1507 | "HW died, freeing TD."); |
1494 | urb_priv = urb->hcpriv; | ||
1495 | for (i = urb_priv->num_tds_done; | 1508 | for (i = urb_priv->num_tds_done; |
1496 | i < urb_priv->num_tds && xhci->devs[urb->dev->slot_id]; | 1509 | i < urb_priv->num_tds; |
1497 | i++) { | 1510 | i++) { |
1498 | td = &urb_priv->td[i]; | 1511 | td = &urb_priv->td[i]; |
1499 | if (!list_empty(&td->td_list)) | 1512 | if (!list_empty(&td->td_list)) |
@@ -1501,23 +1514,9 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
1501 | if (!list_empty(&td->cancelled_td_list)) | 1514 | if (!list_empty(&td->cancelled_td_list)) |
1502 | list_del_init(&td->cancelled_td_list); | 1515 | list_del_init(&td->cancelled_td_list); |
1503 | } | 1516 | } |
1504 | 1517 | goto err_giveback; | |
1505 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
1506 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
1507 | usb_hcd_giveback_urb(hcd, urb, -ESHUTDOWN); | ||
1508 | xhci_urb_free_priv(urb_priv); | ||
1509 | return ret; | ||
1510 | } | 1518 | } |
1511 | 1519 | ||
1512 | ep_index = xhci_get_endpoint_index(&urb->ep->desc); | ||
1513 | ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index]; | ||
1514 | ep_ring = xhci_urb_to_transfer_ring(xhci, urb); | ||
1515 | if (!ep_ring) { | ||
1516 | ret = -EINVAL; | ||
1517 | goto done; | ||
1518 | } | ||
1519 | |||
1520 | urb_priv = urb->hcpriv; | ||
1521 | i = urb_priv->num_tds_done; | 1520 | i = urb_priv->num_tds_done; |
1522 | if (i < urb_priv->num_tds) | 1521 | if (i < urb_priv->num_tds) |
1523 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, | 1522 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, |
@@ -1554,6 +1553,14 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
1554 | done: | 1553 | done: |
1555 | spin_unlock_irqrestore(&xhci->lock, flags); | 1554 | spin_unlock_irqrestore(&xhci->lock, flags); |
1556 | return ret; | 1555 | return ret; |
1556 | |||
1557 | err_giveback: | ||
1558 | if (urb_priv) | ||
1559 | xhci_urb_free_priv(urb_priv); | ||
1560 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
1561 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
1562 | usb_hcd_giveback_urb(hcd, urb, -ESHUTDOWN); | ||
1563 | return ret; | ||
1557 | } | 1564 | } |
1558 | 1565 | ||
1559 | /* Drop an endpoint from a new bandwidth configuration for this device. | 1566 | /* Drop an endpoint from a new bandwidth configuration for this device. |
diff --git a/drivers/usb/phy/phy-isp1301.c b/drivers/usb/phy/phy-isp1301.c index b3b33cf7ddf6..f333024660b4 100644 --- a/drivers/usb/phy/phy-isp1301.c +++ b/drivers/usb/phy/phy-isp1301.c | |||
@@ -136,7 +136,7 @@ static int isp1301_remove(struct i2c_client *client) | |||
136 | static struct i2c_driver isp1301_driver = { | 136 | static struct i2c_driver isp1301_driver = { |
137 | .driver = { | 137 | .driver = { |
138 | .name = DRV_NAME, | 138 | .name = DRV_NAME, |
139 | .of_match_table = of_match_ptr(isp1301_of_match), | 139 | .of_match_table = isp1301_of_match, |
140 | }, | 140 | }, |
141 | .probe = isp1301_probe, | 141 | .probe = isp1301_probe, |
142 | .remove = isp1301_remove, | 142 | .remove = isp1301_remove, |