Commit 6969408d authored by Mathias Nyman's avatar Mathias Nyman Committed by Greg Kroah-Hartman

xhci: refactor xhci_urb_enqueue

Use switch instead of several if statements
Signed-off-by: default avatarMathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 7e64b037
...@@ -1334,7 +1334,7 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) ...@@ -1334,7 +1334,7 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct xhci_hcd *xhci = hcd_to_xhci(hcd);
unsigned long flags; unsigned long flags;
int ret = 0; int ret = 0;
unsigned int slot_id, ep_index; unsigned int slot_id, ep_index, ep_state;
struct urb_priv *urb_priv; struct urb_priv *urb_priv;
int num_tds; int num_tds;
...@@ -1348,8 +1348,7 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) ...@@ -1348,8 +1348,7 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
if (!HCD_HW_ACCESSIBLE(hcd)) { if (!HCD_HW_ACCESSIBLE(hcd)) {
if (!in_interrupt()) if (!in_interrupt())
xhci_dbg(xhci, "urb submitted during PCI suspend\n"); xhci_dbg(xhci, "urb submitted during PCI suspend\n");
ret = -ESHUTDOWN; return -ESHUTDOWN;
goto exit;
} }
if (usb_endpoint_xfer_isoc(&urb->ep->desc)) if (usb_endpoint_xfer_isoc(&urb->ep->desc))
...@@ -1386,69 +1385,51 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) ...@@ -1386,69 +1385,51 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
return ret; return ret;
} }
} }
}
/* We have a spinlock and interrupts disabled, so we must pass
* atomic context to this function, which may allocate memory.
*/
spin_lock_irqsave(&xhci->lock, flags); spin_lock_irqsave(&xhci->lock, flags);
if (xhci->xhc_state & XHCI_STATE_DYING)
goto dying; if (xhci->xhc_state & XHCI_STATE_DYING) {
xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for non-responsive xHCI host.\n",
urb->ep->desc.bEndpointAddress, urb);
ret = -ESHUTDOWN;
goto free_priv;
}
switch (usb_endpoint_type(&urb->ep->desc)) {
case USB_ENDPOINT_XFER_CONTROL:
ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb, ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb,
slot_id, ep_index); slot_id, ep_index);
if (ret) break;
goto free_priv; case USB_ENDPOINT_XFER_BULK:
spin_unlock_irqrestore(&xhci->lock, flags); ep_state = xhci->devs[slot_id]->eps[ep_index].ep_state;
} else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) { if (ep_state & (EP_GETTING_STREAMS | EP_GETTING_NO_STREAMS)) {
spin_lock_irqsave(&xhci->lock, flags); xhci_warn(xhci, "WARN: Can't enqueue URB, ep in streams transition state %x\n",
if (xhci->xhc_state & XHCI_STATE_DYING) ep_state);
goto dying;
if (xhci->devs[slot_id]->eps[ep_index].ep_state &
EP_GETTING_STREAMS) {
xhci_warn(xhci, "WARN: Can't enqueue URB while bulk ep "
"is transitioning to using streams.\n");
ret = -EINVAL;
} else if (xhci->devs[slot_id]->eps[ep_index].ep_state &
EP_GETTING_NO_STREAMS) {
xhci_warn(xhci, "WARN: Can't enqueue URB while bulk ep "
"is transitioning to "
"not having streams.\n");
ret = -EINVAL; ret = -EINVAL;
} else { break;
}
ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb,
slot_id, ep_index); slot_id, ep_index);
} break;
if (ret)
goto free_priv;
spin_unlock_irqrestore(&xhci->lock, flags); case USB_ENDPOINT_XFER_INT:
} else if (usb_endpoint_xfer_int(&urb->ep->desc)) {
spin_lock_irqsave(&xhci->lock, flags);
if (xhci->xhc_state & XHCI_STATE_DYING)
goto dying;
ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb, ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb,
slot_id, ep_index); slot_id, ep_index);
if (ret) break;
goto free_priv;
spin_unlock_irqrestore(&xhci->lock, flags); case USB_ENDPOINT_XFER_ISOC:
} else {
spin_lock_irqsave(&xhci->lock, flags);
if (xhci->xhc_state & XHCI_STATE_DYING)
goto dying;
ret = xhci_queue_isoc_tx_prepare(xhci, GFP_ATOMIC, urb, ret = xhci_queue_isoc_tx_prepare(xhci, GFP_ATOMIC, urb,
slot_id, ep_index); slot_id, ep_index);
if (ret)
goto free_priv;
spin_unlock_irqrestore(&xhci->lock, flags);
} }
exit:
return ret; if (ret) {
dying:
xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for "
"non-responsive xHCI host.\n",
urb->ep->desc.bEndpointAddress, urb);
ret = -ESHUTDOWN;
free_priv: free_priv:
xhci_urb_free_priv(urb_priv); xhci_urb_free_priv(urb_priv);
urb->hcpriv = NULL; urb->hcpriv = NULL;
}
spin_unlock_irqrestore(&xhci->lock, flags); spin_unlock_irqrestore(&xhci->lock, flags);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment