Commit 21d554cc authored by David Brownell's avatar David Brownell Committed by Greg Kroah-Hartman

[PATCH] USB: ohci unlink tweaks

Minor unlink tweaks, including a case where SMP could oops
if it were abused, as if from 'usbtest' or 'stir4200'.
parent 976942da
...@@ -233,7 +233,7 @@ static int ohci_urb_enqueue ( ...@@ -233,7 +233,7 @@ static int ohci_urb_enqueue (
spin_lock (&urb->lock); spin_lock (&urb->lock);
if (urb->status != -EINPROGRESS) { if (urb->status != -EINPROGRESS) {
spin_unlock (&urb->lock); spin_unlock (&urb->lock);
urb->hcpriv = urb_priv;
finish_urb (ohci, urb, 0); finish_urb (ohci, urb, 0);
retval = 0; retval = 0;
goto fail; goto fail;
......
...@@ -1073,10 +1073,12 @@ dl_done_list (struct ohci_hcd *ohci, struct td *td, struct pt_regs *regs) ...@@ -1073,10 +1073,12 @@ dl_done_list (struct ohci_hcd *ohci, struct td *td, struct pt_regs *regs)
finish_urb (ohci, urb, regs); finish_urb (ohci, urb, regs);
/* clean schedule: unlink EDs that are no longer busy */ /* clean schedule: unlink EDs that are no longer busy */
if (list_empty (&ed->td_list) && ed->state == ED_OPER) if (list_empty (&ed->td_list)) {
start_ed_unlink (ohci, ed); if (ed->state == ED_OPER)
start_ed_unlink (ohci, ed);
/* ... reenabling halted EDs only after fault cleanup */ /* ... reenabling halted EDs only after fault cleanup */
else if ((ed->hwINFO & (ED_SKIP | ED_DEQUEUE)) == ED_SKIP) { } else if ((ed->hwINFO & (ED_SKIP | ED_DEQUEUE)) == ED_SKIP) {
td = list_entry (ed->td_list.next, struct td, td_list); td = list_entry (ed->td_list.next, struct td, td_list);
if (!(td->hwINFO & TD_DONE)) { if (!(td->hwINFO & TD_DONE)) {
ed->hwINFO &= ~ED_SKIP; ed->hwINFO &= ~ED_SKIP;
......
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