1 From: Ajay Kumar Gupta <ajay.gupta@ti.com>
2 To: linux-usb@vger.kernel.org
3 Cc: linux-omap@vger.kernel.org, david-b@pacbell.net, me@felipebalbi.com,
4 Ajay Kumar Gupta <ajay.gupta@ti.com>
5 Subject: [PATCH] MUSB: BULK request on different available endpoints
6 Date: Tue, 7 Oct 2008 11:12:24 +0530
8 Fixes co-working issue of usb serial device with usb/net devices while
9 oter endpoints are free and can be used.This patch implements the policy
10 that if endpoint resources are available then different BULK request goes
11 to different endpoint otherwise they are multiplexed to one reserved
12 endpoint as currently done.
14 NAK limit scheme has to be added for multiplexed BULK request scenario
15 to avoid endpoint starvation due to usb/net devices.
17 musb->periodic[] flag setting is also updated.It use to set this flag for
18 an endpoint even when only rx or tx is used.Now flag setting is done on
19 rx/tx basis of an endpoint.
21 Signed-off-by: Ajay Kumar Gupta <ajay.gupta@ti.com>
23 drivers/usb/musb/musb_host.c | 94 ++++++++++++++++++++++++------------------
24 drivers/usb/musb/musb_host.h | 1 +
25 2 files changed, 55 insertions(+), 40 deletions(-)
27 --- /tmp/musb_host.c 2008-10-07 10:10:49.000000000 +0200
28 +++ git/drivers/usb/musb/musb_host.c 2008-10-07 10:13:59.000000000 +0200
33 + case USB_ENDPOINT_XFER_CONTROL:
34 + case USB_ENDPOINT_XFER_BULK:
35 + /* fifo policy for these lists, except that NAKing
36 + * should rotate a qh to the end (for fairness).
39 + head = qh->ring.prev;
40 + list_del(&qh->ring);
42 + qh = first_qh(head);
45 case USB_ENDPOINT_XFER_ISOC:
46 case USB_ENDPOINT_XFER_INT:
47 /* this is where periodic bandwidth should be
48 * de-allocated if it's tracked and allocated;
49 * and where we'd update the schedule tree...
51 - musb->periodic[ep->epnum] = NULL;
53 + musb->periodic[2 * ep->epnum - 2] = NULL;
55 + musb->periodic[2 * ep->epnum - 1] = NULL;
60 - case USB_ENDPOINT_XFER_CONTROL:
61 - case USB_ENDPOINT_XFER_BULK:
62 - /* fifo policy for these lists, except that NAKing
63 - * should rotate a qh to the end (for fairness).
65 - head = qh->ring.prev;
66 - list_del(&qh->ring);
68 - qh = first_qh(head);
73 @@ -1728,22 +1733,9 @@
76 /* use fixed hardware for control and bulk */
78 - case USB_ENDPOINT_XFER_CONTROL:
79 + if (qh->type == USB_ENDPOINT_XFER_CONTROL) {
80 head = &musb->control;
81 hw_ep = musb->control_ep;
83 - case USB_ENDPOINT_XFER_BULK:
84 - hw_ep = musb->bulk_ep;
86 - head = &musb->in_bulk;
88 - head = &musb->out_bulk;
92 - idle = list_empty(head);
93 - list_add_tail(&qh->ring, head);
98 for (epnum = 1; epnum < musb->nr_endpoints; epnum++) {
101 - if (musb->periodic[epnum])
102 + if ((is_in && musb->periodic[2 * epnum - 2]) ||
103 + (!is_in && musb->periodic[2 * epnum - 1]))
105 hw_ep = &musb->endpoints[epnum];
106 if (hw_ep == musb->bulk_ep)
107 @@ -1789,19 +1782,36 @@
109 diff = hw_ep->max_packet_sz_tx - maxpacket;
111 - if (diff > 0 && best_diff > diff) {
112 + if (diff >= 0 && best_diff > diff) {
118 + /* use bulk reserved ep1 if no other ep is free*/
119 + if (best_end < 0 && qh->type == USB_ENDPOINT_XFER_BULK) {
120 + hw_ep = musb->bulk_ep;
122 + head = &musb->in_bulk;
124 + head = &musb->out_bulk;
126 + } else if (best_end < 0)
131 hw_ep = musb->endpoints + best_end;
132 - musb->periodic[best_end] = qh;
133 - DBG(4, "qh %p periodic slot %d\n", qh, best_end);
135 + musb->periodic[2 * best_end - 2] = qh;
137 + musb->periodic[2 * best_end - 1] = qh;
138 + DBG(4, "qh %p periodic slot %d%s\n", qh, best_end, is_in ? "Rx" : "Tx");
141 + idle = list_empty(head);
142 + list_add_tail(&qh->ring, head);
146 qh->hep->hcpriv = qh;
148 @@ -2065,11 +2075,13 @@
149 sched = &musb->control;
151 case USB_ENDPOINT_XFER_BULK:
152 - if (usb_pipein(urb->pipe))
153 - sched = &musb->in_bulk;
155 - sched = &musb->out_bulk;
157 + if (qh->mux == 1) {
158 + if (usb_pipein(urb->pipe))
159 + sched = &musb->in_bulk;
161 + sched = &musb->out_bulk;
165 /* REVISIT when we get a schedule tree, periodic
166 * transfers won't always be at the head of a
167 @@ -2131,11 +2143,13 @@
168 sched = &musb->control;
170 case USB_ENDPOINT_XFER_BULK:
172 - sched = &musb->in_bulk;
174 - sched = &musb->out_bulk;
176 + if (qh->mux == 1) {
178 + sched = &musb->in_bulk;
180 + sched = &musb->out_bulk;
183 case USB_ENDPOINT_XFER_ISOC:
184 case USB_ENDPOINT_XFER_INT:
185 for (i = 0; i < musb->nr_endpoints; i++) {
186 --- /tmp/musb_host.h 2008-10-07 08:59:38.000000000 +0200
187 +++ git/drivers/usb/musb/musb_host.h 2008-10-07 10:10:54.000000000 +0200
190 struct list_head ring; /* of musb_qh */
191 /* struct musb_qh *next; */ /* for periodic tree */
193 + u8 mux; /* qh multiplexed to hw_ep */
195 unsigned offset; /* in urb->transfer_buffer */
196 unsigned segsize; /* current xfer fragment */