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;