|
@@ -1085,8 +1085,11 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
|
|
|
if (urb->dev->speed == USB_SPEED_FULL) {
|
|
|
ret = xhci_check_maxpacket(xhci, slot_id,
|
|
|
ep_index, urb);
|
|
|
- if (ret < 0)
|
|
|
+ if (ret < 0) {
|
|
|
+ xhci_urb_free_priv(xhci, urb_priv);
|
|
|
+ urb->hcpriv = NULL;
|
|
|
return ret;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/* We have a spinlock and interrupts disabled, so we must pass
|
|
@@ -1097,6 +1100,8 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
|
|
|
goto dying;
|
|
|
ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb,
|
|
|
slot_id, ep_index);
|
|
|
+ if (ret)
|
|
|
+ goto free_priv;
|
|
|
spin_unlock_irqrestore(&xhci->lock, flags);
|
|
|
} else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) {
|
|
|
spin_lock_irqsave(&xhci->lock, flags);
|
|
@@ -1117,6 +1122,8 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
|
|
|
ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb,
|
|
|
slot_id, ep_index);
|
|
|
}
|
|
|
+ if (ret)
|
|
|
+ goto free_priv;
|
|
|
spin_unlock_irqrestore(&xhci->lock, flags);
|
|
|
} else if (usb_endpoint_xfer_int(&urb->ep->desc)) {
|
|
|
spin_lock_irqsave(&xhci->lock, flags);
|
|
@@ -1124,6 +1131,8 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
|
|
|
goto dying;
|
|
|
ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb,
|
|
|
slot_id, ep_index);
|
|
|
+ if (ret)
|
|
|
+ goto free_priv;
|
|
|
spin_unlock_irqrestore(&xhci->lock, flags);
|
|
|
} else {
|
|
|
spin_lock_irqsave(&xhci->lock, flags);
|
|
@@ -1131,18 +1140,22 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
|
|
|
goto dying;
|
|
|
ret = xhci_queue_isoc_tx_prepare(xhci, GFP_ATOMIC, urb,
|
|
|
slot_id, ep_index);
|
|
|
+ if (ret)
|
|
|
+ goto free_priv;
|
|
|
spin_unlock_irqrestore(&xhci->lock, flags);
|
|
|
}
|
|
|
exit:
|
|
|
return ret;
|
|
|
dying:
|
|
|
- xhci_urb_free_priv(xhci, urb_priv);
|
|
|
- urb->hcpriv = NULL;
|
|
|
xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for "
|
|
|
"non-responsive xHCI host.\n",
|
|
|
urb->ep->desc.bEndpointAddress, urb);
|
|
|
+ ret = -ESHUTDOWN;
|
|
|
+free_priv:
|
|
|
+ xhci_urb_free_priv(xhci, urb_priv);
|
|
|
+ urb->hcpriv = NULL;
|
|
|
spin_unlock_irqrestore(&xhci->lock, flags);
|
|
|
- return -ESHUTDOWN;
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
/* Get the right ring for the given URB.
|