USB fixes for 4.11-rc5
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. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCWN/NGw8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ymNQQCeNiONvY70Y99hWFDX+PL896fV1rYAoNchYIZY V4NYSVr43W4uk7jrUQD5 =NUT1 -----END PGP SIGNATURE----- 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()
This commit is contained in:
commit
a9f6b6b8cd
|
@ -520,8 +520,10 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
|
|||
*/
|
||||
tbuf_size = max_t(u16, sizeof(struct usb_hub_descriptor), wLength);
|
||||
tbuf = kzalloc(tbuf_size, GFP_KERNEL);
|
||||
if (!tbuf)
|
||||
return -ENOMEM;
|
||||
if (!tbuf) {
|
||||
status = -ENOMEM;
|
||||
goto err_alloc;
|
||||
}
|
||||
|
||||
bufp = tbuf;
|
||||
|
||||
|
@ -734,6 +736,7 @@ error:
|
|||
}
|
||||
|
||||
kfree(tbuf);
|
||||
err_alloc:
|
||||
|
||||
/* any errors get returned through the urb completion */
|
||||
spin_lock_irq(&hcd_root_hub_lock);
|
||||
|
|
|
@ -344,6 +344,7 @@ MODULE_DEVICE_TABLE(acpi, usb_xhci_acpi_match);
|
|||
static struct platform_driver usb_xhci_driver = {
|
||||
.probe = xhci_plat_probe,
|
||||
.remove = xhci_plat_remove,
|
||||
.shutdown = usb_hcd_platform_shutdown,
|
||||
.driver = {
|
||||
.name = "xhci-hcd",
|
||||
.pm = DEV_PM_OPS,
|
||||
|
|
|
@ -1989,6 +1989,9 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
|
|||
case TRB_NORMAL:
|
||||
td->urb->actual_length = requested - remaining;
|
||||
goto finish_td;
|
||||
case TRB_STATUS:
|
||||
td->urb->actual_length = requested;
|
||||
goto finish_td;
|
||||
default:
|
||||
xhci_warn(xhci, "WARN: unexpected TRB Type %d\n",
|
||||
trb_type);
|
||||
|
|
|
@ -1477,6 +1477,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
|
|||
struct xhci_ring *ep_ring;
|
||||
struct xhci_virt_ep *ep;
|
||||
struct xhci_command *command;
|
||||
struct xhci_virt_device *vdev;
|
||||
|
||||
xhci = hcd_to_xhci(hcd);
|
||||
spin_lock_irqsave(&xhci->lock, flags);
|
||||
|
@ -1485,15 +1486,27 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
|
|||
|
||||
/* Make sure the URB hasn't completed or been unlinked already */
|
||||
ret = usb_hcd_check_unlink_urb(hcd, urb, status);
|
||||
if (ret || !urb->hcpriv)
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
/* give back URB now if we can't queue it for cancel */
|
||||
vdev = xhci->devs[urb->dev->slot_id];
|
||||
urb_priv = urb->hcpriv;
|
||||
if (!vdev || !urb_priv)
|
||||
goto err_giveback;
|
||||
|
||||
ep_index = xhci_get_endpoint_index(&urb->ep->desc);
|
||||
ep = &vdev->eps[ep_index];
|
||||
ep_ring = xhci_urb_to_transfer_ring(xhci, urb);
|
||||
if (!ep || !ep_ring)
|
||||
goto err_giveback;
|
||||
|
||||
temp = readl(&xhci->op_regs->status);
|
||||
if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_HALTED)) {
|
||||
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
|
||||
"HW died, freeing TD.");
|
||||
urb_priv = urb->hcpriv;
|
||||
for (i = urb_priv->num_tds_done;
|
||||
i < urb_priv->num_tds && xhci->devs[urb->dev->slot_id];
|
||||
i < urb_priv->num_tds;
|
||||
i++) {
|
||||
td = &urb_priv->td[i];
|
||||
if (!list_empty(&td->td_list))
|
||||
|
@ -1501,23 +1514,9 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
|
|||
if (!list_empty(&td->cancelled_td_list))
|
||||
list_del_init(&td->cancelled_td_list);
|
||||
}
|
||||
|
||||
usb_hcd_unlink_urb_from_ep(hcd, urb);
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
usb_hcd_giveback_urb(hcd, urb, -ESHUTDOWN);
|
||||
xhci_urb_free_priv(urb_priv);
|
||||
return ret;
|
||||
goto err_giveback;
|
||||
}
|
||||
|
||||
ep_index = xhci_get_endpoint_index(&urb->ep->desc);
|
||||
ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index];
|
||||
ep_ring = xhci_urb_to_transfer_ring(xhci, urb);
|
||||
if (!ep_ring) {
|
||||
ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
urb_priv = urb->hcpriv;
|
||||
i = urb_priv->num_tds_done;
|
||||
if (i < urb_priv->num_tds)
|
||||
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)
|
|||
done:
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
return ret;
|
||||
|
||||
err_giveback:
|
||||
if (urb_priv)
|
||||
xhci_urb_free_priv(urb_priv);
|
||||
usb_hcd_unlink_urb_from_ep(hcd, urb);
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
usb_hcd_giveback_urb(hcd, urb, -ESHUTDOWN);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Drop an endpoint from a new bandwidth configuration for this device.
|
||||
|
|
|
@ -136,7 +136,7 @@ static int isp1301_remove(struct i2c_client *client)
|
|||
static struct i2c_driver isp1301_driver = {
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.of_match_table = of_match_ptr(isp1301_of_match),
|
||||
.of_match_table = isp1301_of_match,
|
||||
},
|
||||
.probe = isp1301_probe,
|
||||
.remove = isp1301_remove,
|
||||
|
|
Loading…
Reference in New Issue