This first proposed patch for solving the isochronous stream problem adds a mechanism for seeing whether or not an URB is currently being given back for a particular endpoint. The mechanism isn't perfect. It doesn't use any synchronization, so it's possible that a CPU may think a giveback is still in progress even after it has finished. This shouldn't matter. If an isochronous queue empties out and then the driver starts a new stream within a few milliseconds -- quickly enough that the change to giveback_in_progress hasn't propagated to all the CPUs -- there won't be any harm in scheduling the new stream as a continuation of the old one. Alan Stern drivers/usb/core/hcd.c | 3 +++ include/linux/usb.h | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) Index: usb-3.11/include/linux/usb.h =================================================================== --- usb-3.11.orig/include/linux/usb.h +++ usb-3.11/include/linux/usb.h @@ -68,9 +68,10 @@ struct usb_host_endpoint { void *hcpriv; struct ep_device *ep_dev; /* For sysfs info */ - unsigned char *extra; /* Extra descriptors */ - int extralen; - int enabled; + unsigned char *extra; /* Extra descriptors */ + int extralen; + int enabled; + bool giveback_in_progress; }; /* host-side wrapper for one interface setting's parsed descriptors */ Index: usb-3.11/drivers/usb/core/hcd.c =================================================================== --- usb-3.11.orig/drivers/usb/core/hcd.c +++ usb-3.11/drivers/usb/core/hcd.c @@ -1638,6 +1638,7 @@ int usb_hcd_unlink_urb (struct urb *urb, static void __usb_hcd_giveback_urb(struct urb *urb) { struct usb_hcd *hcd = bus_to_hcd(urb->dev->bus); + struct usb_host_endpoint *ep = urb->ep; int status = urb->unlinked; unsigned long flags; @@ -1653,6 +1654,7 @@ static void __usb_hcd_giveback_urb(struc /* pass ownership to the completion handler */ urb->status = status; + ep->giveback_in_progress = true; /* * We disable local IRQs here avoid possible deadlock because @@ -1668,6 +1670,7 @@ static void __usb_hcd_giveback_urb(struc urb->complete(urb); local_irq_restore(flags); + ep->giveback_in_progress = false; atomic_dec(&urb->use_count); if (unlikely(atomic_read(&urb->reject))) wake_up(&usb_kill_urb_queue); -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html