ChangeSet 1.1673.8.46, 2004/03/30 08:55:44-08:00, david-b@pacbell.net [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'. drivers/usb/host/ohci-hcd.c | 2 +- drivers/usb/host/ohci-q.c | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c --- a/drivers/usb/host/ohci-hcd.c Wed Apr 14 14:36:19 2004 +++ b/drivers/usb/host/ohci-hcd.c Wed Apr 14 14:36:19 2004 @@ -233,7 +233,7 @@ spin_lock (&urb->lock); if (urb->status != -EINPROGRESS) { spin_unlock (&urb->lock); - + urb->hcpriv = urb_priv; finish_urb (ohci, urb, 0); retval = 0; goto fail; diff -Nru a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c --- a/drivers/usb/host/ohci-q.c Wed Apr 14 14:36:19 2004 +++ b/drivers/usb/host/ohci-q.c Wed Apr 14 14:36:19 2004 @@ -1073,10 +1073,12 @@ finish_urb (ohci, urb, regs); /* clean schedule: unlink EDs that are no longer busy */ - if (list_empty (&ed->td_list) && ed->state == ED_OPER) - start_ed_unlink (ohci, ed); + if (list_empty (&ed->td_list)) { + if (ed->state == ED_OPER) + start_ed_unlink (ohci, ed); + /* ... 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); if (!(td->hwINFO & TD_DONE)) { ed->hwINFO &= ~ED_SKIP;