Starting a command-line mp3 player on a system with USB speakers,
and then trying to stop it with control-C, didn't work; at best it
didn't stop right away, at worst kernel panics.

It turned out that if a request is stopped half-way using
usb_unlink_urb, the completion routine never gets run, and so
FLG_URB0RUNNING etc. never get cleared.

The problem is somewhat rare, and timing-dependent, because often
the request will actually complete before all this code gets run.

What should I do to get this patch integrated in the mainline sources?

-- 
- Geoffrey Keating <[EMAIL PROTECTED]> <[EMAIL PROTECTED]>

===File ~/patches/kernel-usbaudio-interrupt.patch===========
--- linux-2.4.14/drivers/usb/audio.c    Mon Nov  5 12:16:13 2001
+++ linux-2.4.14/drivers/usb/audio.c    Wed Feb 20 12:27:53 2002
@@ -1107,6 +1107,8 @@ static int usbin_start(struct usb_audiod
        return 0;
 }
 
+static void usbout_completed(struct urb *urb);
+
 static void usbout_stop(struct usb_audiodev *as)
 {
        struct usbout *u = &as->usbout;
@@ -1124,14 +1126,26 @@ static void usbout_stop(struct usb_audio
                i = u->flags;
                spin_unlock_irqrestore(&as->lock, flags);
                if (notkilled && signal_pending(current)) {
-                       if (i & FLG_URB0RUNNING)
+                       if (i & FLG_URB0RUNNING) {
                                usb_unlink_urb(&u->durb[0].urb);
-                       if (i & FLG_URB1RUNNING)
+                               if (u->durb[0].urb.status == -ENOENT)
+                                       usbout_completed (&u->durb[0].urb);
+                       }
+                       if (i & FLG_URB1RUNNING) {
                                usb_unlink_urb(&u->durb[1].urb);
-                       if (i & FLG_SYNC0RUNNING)
+                               if (u->durb[1].urb.status == -ENOENT)
+                                       usbout_completed (&u->durb[1].urb);
+                       }
+                       if (i & FLG_SYNC0RUNNING) {
                                usb_unlink_urb(&u->surb[0].urb);
-                       if (i & FLG_SYNC1RUNNING)
+                               if (u->surb[0].urb.status == -ENOENT)
+                                       usbout_completed (&u->surb[0].urb);
+                       }
+                       if (i & FLG_SYNC1RUNNING) {
                                usb_unlink_urb(&u->surb[1].urb);
+                               if (u->surb[1].urb.status == -ENOENT)
+                                       usbout_completed (&u->surb[1].urb);
+                       }
                        notkilled = 0;
                }
        }
============================================================

_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to