The urb_dequeue() method "forgets" to unlink 'struct musb_qh' from the control/ bulk schedule list when an URB being cancelled is the only one queued to its endpoint, which will cause musb_advance_schedule() to "block" once it reaches 'struct musb_qh' with now empty URB list, and so URBs queued for other control/ bulk endpoints after the one being dequeued will not be served. Hence add code to unlink and free 'struct musb_qh' if its URB list emptied to this method and remove now useless check from musb_advance_schedule()...
Signed-off-by: Sergei Shtylyov <[email protected]> --- This patch replaces a part of the patch originallly posted by Ajay Kumar Gupta (http://marc.info/?l=linux-usb&m=122284678326862) that however dealt with the issue incorrectly... drivers/usb/musb/musb_host.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) Index: mainline/drivers/usb/musb/musb_host.c =================================================================== --- mainline.orig/drivers/usb/musb/musb_host.c +++ mainline/drivers/usb/musb/musb_host.c @@ -432,7 +432,7 @@ musb_advance_schedule(struct musb *musb, else qh = musb_giveback(qh, urb, urb->status); - if (qh && qh->is_ready && !list_empty(&qh->hep->urb_list)) { + if (qh != NULL && qh->is_ready) { DBG(4, "... next ep%d %cX urb %p\n", hw_ep->epnum, is_in ? 'R' : 'T', next_urb(qh)); @@ -2136,7 +2136,12 @@ static int musb_urb_dequeue(struct usb_h ret = 0; qh->is_ready = 0; __musb_giveback(musb, urb, 0); - qh->is_ready = ready; + if (list_empty(&qh->hep->urb_list)) { + qh->hep->hcpriv = NULL; + list_del(&qh->ring); + kfree(qh); + } else + qh->is_ready = ready; } else ret = musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN); done: _______________________________________________ Davinci-linux-open-source mailing list [email protected] http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
