Commit 8b3ab0ed authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman
Browse files

USB: OHCI: no shortcut for unlinking URBS from a dead controller

When an URB is unlinked from a dead controller, ohci-hcd gives back
the URB with no regard for cleaning up the internal data structures.
This won't play nicely with the upcoming changes to the TD done

Therefore make ohci_urb_dequeue() call finish_unlinks(), which uses
td_done() to do a proper cleanup, rather than calling finish_urb()
directly.  Also, remove the checks that urb_priv is non-NULL; the
driver guarantees that urb_priv will never be NULL for a valid URB.
Signed-off-by: default avatarAlan Stern <>
Signed-off-by: default avatarGreg Kroah-Hartman <>
parent 95d9a01d
......@@ -300,30 +300,24 @@ static int ohci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
unsigned long flags;
int rc;
urb_priv_t *urb_priv;
spin_lock_irqsave (&ohci->lock, flags);
rc = usb_hcd_check_unlink_urb(hcd, urb, status);
if (rc) {
; /* Do nothing */
} else if (ohci->rh_state == OHCI_RH_RUNNING) {
urb_priv_t *urb_priv;
if (rc == 0) {
/* Unless an IRQ completed the unlink while it was being
* handed to us, flag it for unlink and giveback, and force
* some upcoming INTR_SF to call finish_unlinks()
urb_priv = urb->hcpriv;
if (urb_priv) {
if (urb_priv->ed->state == ED_OPER)
start_ed_unlink (ohci, urb_priv->ed);
if (urb_priv->ed->state == ED_OPER)
start_ed_unlink(ohci, urb_priv->ed);
if (ohci->rh_state != OHCI_RH_RUNNING) {
/* With HC dead, we can clean up right away */
finish_unlinks(ohci, 0);
} else {
* with HC dead, we won't respect hc queue pointers
* any more ... just clean up every urb's memory.
if (urb->hcpriv)
finish_urb(ohci, urb, status);
spin_unlock_irqrestore (&ohci->lock, flags);
return rc;
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