aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-hcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/xhci-hcd.c')
-rw-r--r--drivers/usb/host/xhci-hcd.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c
index 8719a3f6851d..592e742c5f35 100644
--- a/drivers/usb/host/xhci-hcd.c
+++ b/drivers/usb/host/xhci-hcd.c
@@ -782,6 +782,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
782{ 782{
783 unsigned long flags; 783 unsigned long flags;
784 int ret; 784 int ret;
785 u32 temp;
785 struct xhci_hcd *xhci; 786 struct xhci_hcd *xhci;
786 struct xhci_td *td; 787 struct xhci_td *td;
787 unsigned int ep_index; 788 unsigned int ep_index;
@@ -794,6 +795,17 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
794 ret = usb_hcd_check_unlink_urb(hcd, urb, status); 795 ret = usb_hcd_check_unlink_urb(hcd, urb, status);
795 if (ret || !urb->hcpriv) 796 if (ret || !urb->hcpriv)
796 goto done; 797 goto done;
798 temp = xhci_readl(xhci, &xhci->op_regs->status);
799 if (temp == 0xffffffff) {
800 xhci_dbg(xhci, "HW died, freeing TD.\n");
801 td = (struct xhci_td *) urb->hcpriv;
802
803 usb_hcd_unlink_urb_from_ep(hcd, urb);
804 spin_unlock_irqrestore(&xhci->lock, flags);
805 usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, -ESHUTDOWN);
806 kfree(td);
807 return ret;
808 }
797 809
798 xhci_dbg(xhci, "Cancel URB %p\n", urb); 810 xhci_dbg(xhci, "Cancel URB %p\n", urb);
799 xhci_dbg(xhci, "Event ring:\n"); 811 xhci_dbg(xhci, "Event ring:\n");