提交 6969408d 编写于 作者: M Mathias Nyman 提交者: Greg Kroah-Hartman

xhci: refactor xhci_urb_enqueue

Use switch instead of several if statements
Signed-off-by: NMathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
上级 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 spin_lock_irqsave(&xhci->lock, flags);
* atomic context to this function, which may allocate memory.
*/ if (xhci->xhc_state & XHCI_STATE_DYING) {
spin_lock_irqsave(&xhci->lock, flags); xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for non-responsive xHCI host.\n",
if (xhci->xhc_state & XHCI_STATE_DYING) urb->ep->desc.bEndpointAddress, urb);
goto dying; 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,
slot_id, ep_index);
} }
if (ret) ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb,
goto free_priv; slot_id, ep_index);
spin_unlock_irqrestore(&xhci->lock, flags); break;
} else if (usb_endpoint_xfer_int(&urb->ep->desc)) {
spin_lock_irqsave(&xhci->lock, flags);
if (xhci->xhc_state & XHCI_STATE_DYING) case USB_ENDPOINT_XFER_INT:
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% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册