diff options
author | Denys Dmytriyenko <denis@denix.org> | 2009-03-17 14:32:59 -0400 |
---|---|---|
committer | Denys Dmytriyenko <denis@denix.org> | 2009-03-17 14:32:59 -0400 |
commit | 709c4d66e0b107ca606941b988bad717c0b45d9b (patch) | |
tree | 37ee08b1eb308f3b2b6426d5793545c38396b838 /packages/linux/linux-omap-2.6.27/musb-fix-multiple-bulk-transfers.diff | |
parent | fa6cd5a3b993f16c27de4ff82b42684516d433ba (diff) |
rename packages/ to recipes/ per earlier agreement
See links below for more details:
http://thread.gmane.org/gmane.comp.handhelds.openembedded/21326
http://thread.gmane.org/gmane.comp.handhelds.openembedded/21816
Signed-off-by: Denys Dmytriyenko <denis@denix.org>
Acked-by: Mike Westerhof <mwester@dls.net>
Acked-by: Philip Balister <philip@balister.org>
Acked-by: Khem Raj <raj.khem@gmail.com>
Acked-by: Marcin Juszkiewicz <hrw@openembedded.org>
Acked-by: Koen Kooi <koen@openembedded.org>
Acked-by: Frans Meulenbroeks <fransmeulenbroeks@gmail.com>
Diffstat (limited to 'packages/linux/linux-omap-2.6.27/musb-fix-multiple-bulk-transfers.diff')
-rw-r--r-- | packages/linux/linux-omap-2.6.27/musb-fix-multiple-bulk-transfers.diff | 194 |
1 files changed, 0 insertions, 194 deletions
diff --git a/packages/linux/linux-omap-2.6.27/musb-fix-multiple-bulk-transfers.diff b/packages/linux/linux-omap-2.6.27/musb-fix-multiple-bulk-transfers.diff deleted file mode 100644 index 7435a2e413..0000000000 --- a/packages/linux/linux-omap-2.6.27/musb-fix-multiple-bulk-transfers.diff +++ /dev/null @@ -1,194 +0,0 @@ -From: Ajay Kumar Gupta <ajay.gupta@ti.com> -To: linux-usb@vger.kernel.org -Cc: linux-omap@vger.kernel.org, felipe.balbi@nokia.com, -Subject: [PATCH] MUSB: Fix for kernel panic with multiple bulk transfer -Date: Wed, 1 Oct 2008 13:08:56 +0530 - -Fixes kernel panic when multiple copy is performed among more than two mass -storage media and transfer is aborted.musb_advance_schedule(), -musb_urb_dequeue(),musb_cleanup_urb() and musb_h_disable() functions have -been modified to correct urb handling associated with bulk and control -endpoints which are multiplexed on one hardware endpoint. - -musb_advance_schedule() has been removed from musb_cleanup_urb() and added -to musb_urb_dequeue(). musb_h_disable() has been modified to take care of -multiple qh on same hw_ep scenario. - -Signed-off-by: Ajay Kumar Gupta <ajay.gupta@ti.com> -CC: Romit Dasgupta <romit@ti.com> ---- -Suggestions welcome to move while loop doing kfree(qh) from -musb_advance_schedule() and musb_h_disable() to musb_giveback(). - - drivers/usb/musb/musb_host.c | 105 ++++++++++++++++++++++++++++++----------- - 1 files changed, 77 insertions(+), 28 deletions(-) - -diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c -index 8b4be01..c2474de 100644 ---- a/drivers/usb/musb/musb_host.c -+++ b/drivers/usb/musb/musb_host.c -@@ -427,8 +427,17 @@ musb_advance_schedule(struct musb *musb, struct urb *urb, - qh = musb_giveback(qh, urb, 0); - else - qh = musb_giveback(qh, urb, urb->status); -+ while (qh && qh->is_ready && list_empty(&qh->hep->urb_list)) { -+ struct list_head *head; -+ head = qh->ring.prev; -+ list_del(&qh->ring); -+ qh->hep->hcpriv = NULL; -+ kfree(qh); -+ qh = first_qh(head); -+ } - -- if (qh && qh->is_ready && !list_empty(&qh->hep->urb_list)) { -+ -+ if (qh && qh->is_ready) { - DBG(4, "... next ep%d %cX urb %p\n", - hw_ep->epnum, is_in ? 'R' : 'T', - next_urb(qh)); -@@ -1964,8 +1973,6 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh, int is_in) - /* flush cpu writebuffer */ - csr = musb_readw(epio, MUSB_TXCSR); - } -- if (status == 0) -- musb_advance_schedule(ep->musb, urb, ep, is_in); - return status; - } - -@@ -2026,13 +2033,24 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) - /* NOTE: qh is invalid unless !list_empty(&hep->urb_list) */ - if (ret < 0 || (sched && qh != first_qh(sched))) { - int ready = qh->is_ready; -- -+ int type = urb->pipe; - ret = 0; - qh->is_ready = 0; - __musb_giveback(musb, urb, 0); -- qh->is_ready = ready; -- } else -+ -+ if (list_empty(&qh->hep->urb_list) && list_empty(&qh->ring)) -+ list_del(&qh->ring); -+ else -+ qh->is_ready = ready; -+ if (usb_pipeisoc(type)) -+ musb->periodic[qh->hw_ep->epnum] = NULL; -+ } else { - ret = musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN); -+ if (!ret) { -+ musb_advance_schedule(qh->hw_ep->musb, urb, qh->hw_ep, -+ urb->pipe & USB_DIR_IN); -+ } -+ } - done: - spin_unlock_irqrestore(&musb->lock, flags); - return ret; -@@ -2046,14 +2064,17 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) - unsigned long flags; - struct musb *musb = hcd_to_musb(hcd); - u8 is_in = epnum & USB_DIR_IN; -- struct musb_qh *qh = hep->hcpriv; -+ struct musb_qh *qh, *qh_for_curr_urb; - struct urb *urb, *tmp; - struct list_head *sched; -- -- if (!qh) -- return; -+ int i; - - spin_lock_irqsave(&musb->lock, flags); -+ qh = hep->hcpriv; -+ if (!qh) { -+ spin_unlock_irqrestore(&musb->lock, flags); -+ return; -+ } - - switch (qh->type) { - case USB_ENDPOINT_XFER_CONTROL: -@@ -2065,6 +2086,13 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) - else - sched = &musb->out_bulk; - break; -+ case USB_ENDPOINT_XFER_ISOC: -+ case USB_ENDPOINT_XFER_INT: -+ for (i = 0; i < musb->nr_endpoints; i++) { -+ if (musb->periodic[i] == qh) -+ sched = &qh->ring; -+ break; -+ } - default: - /* REVISIT when we get a schedule tree, periodic transfers - * won't always be at the head of a singleton queue... -@@ -2073,26 +2101,47 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) - break; - } - -- /* NOTE: qh is invalid unless !list_empty(&hep->urb_list) */ -- - /* kick first urb off the hardware, if needed */ -- qh->is_ready = 0; -- if (!sched || qh == first_qh(sched)) { -+ if (sched) { -+ qh_for_curr_urb = qh; - urb = next_urb(qh); -- -- /* make software (then hardware) stop ASAP */ -- if (!urb->unlinked) -- urb->status = -ESHUTDOWN; -- -- /* cleanup */ -- musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN); -- } else -- urb = NULL; -- -- /* then just nuke all the others */ -- list_for_each_entry_safe_from(urb, tmp, &hep->urb_list, urb_list) -- musb_giveback(qh, urb, -ESHUTDOWN); -- -+ if (urb) { -+ /* make software (then hardware) stop ASAP */ -+ if (!urb->unlinked) -+ urb->status = -ESHUTDOWN; -+ /* cleanup first urb of first qh; */ -+ if (qh == first_qh(sched)) { -+ musb_cleanup_urb(urb, qh, -+ urb->pipe & USB_DIR_IN); -+ } -+ qh = musb_giveback(qh, urb, -ESHUTDOWN); -+ if (qh == qh_for_curr_urb) { -+ list_for_each_entry_safe_from(urb, tmp, -+ &hep->urb_list, urb_list) { -+ qh = musb_giveback(qh, tmp, -ESHUTDOWN); -+ if (qh != qh_for_curr_urb) -+ break; -+ } -+ } -+ } -+ /* pick the next candidate and go */ -+ if (qh && qh->is_ready) { -+ while (qh && qh->is_ready && -+ list_empty(&qh->hep->urb_list)) { -+ struct list_head *head; -+ head = qh->ring.prev; -+ list_del(&qh->ring); -+ qh->hep->hcpriv = NULL; -+ kfree(qh); -+ qh = first_qh(head); -+ } -+ if (qh && qh->is_ready) { -+ epnum = qh->hep->desc.bEndpointAddress; -+ is_in = epnum & USB_DIR_IN; -+ musb_start_urb(musb, is_in, qh); -+ } -+ } -+ } - spin_unlock_irqrestore(&musb->lock, flags); - } - --- -1.5.6 - --- -To unsubscribe from this list: send the line "unsubscribe linux-omap" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html |