aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorSergei Shtylyov <sshtylyov@ru.mvista.com>2009-02-24 18:23:34 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-03-24 19:20:35 -0400
commit5d67a851bca63d30cde0474bfc4fc4f03db1a1b8 (patch)
tree0f794a88f098fd527a835335c46ef552230dda8e /drivers/usb
parentb2bdf3a789162aa6ff9c6f139bee9cc7954bc5b4 (diff)
USB: musb: rewrite host periodic endpoint allocation
The current MUSB host code doesn't make use of all the available FIFOs in for periodic transfers since it wrongly assumes the RX and TX sides of any given hw_ep always share one FIFO. Change: use 'in_qh' and 'out_qh' fields of the 'struct musb_hw_ep' to check the endpoint's business; get rid of the now-unused 'periodic' array in the 'struct musb'. Also optimize a loop induction variable in the endpoint lookup code. (Based on a previous patch from Ajay Kumar Gupta <ajay.gupta@ti.com>) [ dbrownell@users.sourceforge.net: clarify description and origin of this fix; whitespace ] Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Cc: Felipe Balbi <felipe.balbi@nokia.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/musb/musb_core.h1
-rw-r--r--drivers/usb/musb/musb_host.c28
2 files changed, 11 insertions, 18 deletions
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 630946a2d9f..adf1806007f 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -331,7 +331,6 @@ struct musb {
331 struct list_head control; /* of musb_qh */ 331 struct list_head control; /* of musb_qh */
332 struct list_head in_bulk; /* of musb_qh */ 332 struct list_head in_bulk; /* of musb_qh */
333 struct list_head out_bulk; /* of musb_qh */ 333 struct list_head out_bulk; /* of musb_qh */
334 struct musb_qh *periodic[32]; /* tree of interrupt+iso */
335#endif 334#endif
336 335
337 /* called with IRQs blocked; ON/nonzero implies starting a session, 336 /* called with IRQs blocked; ON/nonzero implies starting a session,
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 6dbbd0786a6..9489c859868 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -395,7 +395,6 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status)
395 * de-allocated if it's tracked and allocated; 395 * de-allocated if it's tracked and allocated;
396 * and where we'd update the schedule tree... 396 * and where we'd update the schedule tree...
397 */ 397 */
398 musb->periodic[ep->epnum] = NULL;
399 kfree(qh); 398 kfree(qh);
400 qh = NULL; 399 qh = NULL;
401 break; 400 break;
@@ -1711,31 +1710,27 @@ static int musb_schedule(
1711 1710
1712 /* else, periodic transfers get muxed to other endpoints */ 1711 /* else, periodic transfers get muxed to other endpoints */
1713 1712
1714 /* FIXME this doesn't consider direction, so it can only 1713 /*
1715 * work for one half of the endpoint hardware, and assumes 1714 * We know this qh hasn't been scheduled, so all we need to do
1716 * the previous cases handled all non-shared endpoints...
1717 */
1718
1719 /* we know this qh hasn't been scheduled, so all we need to do
1720 * is choose which hardware endpoint to put it on ... 1715 * is choose which hardware endpoint to put it on ...
1721 * 1716 *
1722 * REVISIT what we really want here is a regular schedule tree 1717 * REVISIT what we really want here is a regular schedule tree
1723 * like e.g. OHCI uses, but for now musb->periodic is just an 1718 * like e.g. OHCI uses.
1724 * array of the _single_ logical endpoint associated with a
1725 * given physical one (identity mapping logical->physical).
1726 *
1727 * that simplistic approach makes TT scheduling a lot simpler;
1728 * there is none, and thus none of its complexity...
1729 */ 1719 */
1730 best_diff = 4096; 1720 best_diff = 4096;
1731 best_end = -1; 1721 best_end = -1;
1732 1722
1733 for (epnum = 1; epnum < musb->nr_endpoints; epnum++) { 1723 for (epnum = 1, hw_ep = musb->endpoints + 1;
1724 epnum < musb->nr_endpoints;
1725 epnum++, hw_ep++) {
1734 int diff; 1726 int diff;
1735 1727
1736 if (musb->periodic[epnum]) 1728 if (is_in || hw_ep->is_shared_fifo) {
1729 if (hw_ep->in_qh != NULL)
1730 continue;
1731 } else if (hw_ep->out_qh != NULL)
1737 continue; 1732 continue;
1738 hw_ep = &musb->endpoints[epnum]; 1733
1739 if (hw_ep == musb->bulk_ep) 1734 if (hw_ep == musb->bulk_ep)
1740 continue; 1735 continue;
1741 1736
@@ -1764,7 +1759,6 @@ static int musb_schedule(
1764 idle = 1; 1759 idle = 1;
1765 qh->mux = 0; 1760 qh->mux = 0;
1766 hw_ep = musb->endpoints + best_end; 1761 hw_ep = musb->endpoints + best_end;
1767 musb->periodic[best_end] = qh;
1768 DBG(4, "qh %p periodic slot %d\n", qh, best_end); 1762 DBG(4, "qh %p periodic slot %d\n", qh, best_end);
1769success: 1763success:
1770 if (head) { 1764 if (head) {