blob: f000c73319f49eb08fc4d933a7b6c468f7e3baed [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * epautoconf.c -- endpoint autoconfiguration for usb gadget drivers
3 *
4 * Copyright (C) 2004 David Brownell
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
Linus Torvalds1da177e2005-04-16 15:20:36 -070010 */
11
12#include <linux/kernel.h>
Sebastian Andrzej Siewiordc995fc2012-09-06 20:11:12 +020013#include <linux/module.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070014#include <linux/types.h>
15#include <linux/device.h>
16
17#include <linux/ctype.h>
18#include <linux/string.h>
19
David Brownell5f848132006-12-16 15:34:53 -080020#include <linux/usb/ch9.h>
David Brownell9454a572007-10-04 18:05:17 -070021#include <linux/usb/gadget.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070022
23#include "gadget_chips.h"
24
Michal Nazarewicz28824b12010-05-05 12:53:13 +020025static int
Linus Torvalds1da177e2005-04-16 15:20:36 -070026ep_matches (
27 struct usb_gadget *gadget,
28 struct usb_ep *ep,
Tatyana Brokhmana59d6b92011-06-28 16:33:53 +030029 struct usb_endpoint_descriptor *desc,
30 struct usb_ss_ep_comp_descriptor *ep_comp
Linus Torvalds1da177e2005-04-16 15:20:36 -070031)
32{
33 u8 type;
Linus Torvalds1da177e2005-04-16 15:20:36 -070034 u16 max;
Tatyana Brokhmana59d6b92011-06-28 16:33:53 +030035 int num_req_streams = 0;
36
Linus Torvalds1da177e2005-04-16 15:20:36 -070037 /* endpoint already claimed? */
Robert Baldygacc476b42015-07-31 16:00:13 +020038 if (ep->claimed)
Linus Torvalds1da177e2005-04-16 15:20:36 -070039 return 0;
David Brownella3536782006-07-06 15:48:53 -070040
Felipe Balbic3505f02013-11-08 12:39:29 -060041 type = usb_endpoint_type(desc);
Robert Baldyga26bf9562015-08-06 14:11:09 +020042 max = 0x7ff & usb_endpoint_maxp(desc);
43
44 if (usb_endpoint_dir_in(desc) && !ep->caps.dir_in)
45 return 0;
46 if (usb_endpoint_dir_out(desc) && !ep->caps.dir_out)
47 return 0;
48
49 if (max > ep->maxpacket_limit)
50 return 0;
51
52 /* "high bandwidth" works only at high speed */
53 if (!gadget_is_dualspeed(gadget) && usb_endpoint_maxp(desc) & (3<<11))
54 return 0;
55
Robert Baldygab86f33a2015-07-31 16:00:49 +020056 switch (type) {
57 case USB_ENDPOINT_XFER_CONTROL:
58 /* only support ep0 for portable CONTROL traffic */
Linus Torvalds1da177e2005-04-16 15:20:36 -070059 return 0;
Robert Baldygab86f33a2015-07-31 16:00:49 +020060 case USB_ENDPOINT_XFER_ISOC:
61 if (!ep->caps.type_iso)
62 return 0;
Robert Baldyga26bf9562015-08-06 14:11:09 +020063 /* ISO: limit 1023 bytes full speed,
64 * 1024 high/super speed
65 */
66 if (!gadget_is_dualspeed(gadget) && max > 1023)
67 return 0;
Robert Baldygab86f33a2015-07-31 16:00:49 +020068 break;
69 case USB_ENDPOINT_XFER_BULK:
70 if (!ep->caps.type_bulk)
71 return 0;
Robert Baldyga26bf9562015-08-06 14:11:09 +020072 if (ep_comp && gadget_is_superspeed(gadget)) {
73 /* Get the number of required streams from the
74 * EP companion descriptor and see if the EP
75 * matches it
76 */
Tatyana Brokhmana59d6b92011-06-28 16:33:53 +030077 num_req_streams = ep_comp->bmAttributes & 0x1f;
78 if (num_req_streams > ep->max_streams)
79 return 0;
Tatyana Brokhmana59d6b92011-06-28 16:33:53 +030080 }
Robert Baldyga26bf9562015-08-06 14:11:09 +020081 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -070082 case USB_ENDPOINT_XFER_INT:
Robert Baldyga26bf9562015-08-06 14:11:09 +020083 /* Bulk endpoints handle interrupt transfers,
84 * except the toggle-quirky iso-synch kind
85 */
86 if (!ep->caps.type_int && !ep->caps.type_bulk)
87 return 0;
88 /* INT: limit 64 bytes full speed,
89 * 1024 high/super speed
90 */
Michal Nazarewiczd327ab52011-11-19 18:27:37 +010091 if (!gadget_is_dualspeed(gadget) && max > 64)
Linus Torvalds1da177e2005-04-16 15:20:36 -070092 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070093 break;
94 }
95
96 /* MATCH!! */
97
Linus Torvalds1da177e2005-04-16 15:20:36 -070098 return 1;
99}
100
Michal Nazarewicz28824b12010-05-05 12:53:13 +0200101static struct usb_ep *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102find_ep (struct usb_gadget *gadget, const char *name)
103{
104 struct usb_ep *ep;
105
106 list_for_each_entry (ep, &gadget->ep_list, ep_list) {
107 if (0 == strcmp (ep->name, name))
108 return ep;
109 }
110 return NULL;
111}
112
113/**
Tatyana Brokhmana59d6b92011-06-28 16:33:53 +0300114 * usb_ep_autoconfig_ss() - choose an endpoint matching the ep
115 * descriptor and ep companion descriptor
116 * @gadget: The device to which the endpoint must belong.
117 * @desc: Endpoint descriptor, with endpoint direction and transfer mode
118 * initialized. For periodic transfers, the maximum packet
119 * size must also be initialized. This is modified on
120 * success.
121 * @ep_comp: Endpoint companion descriptor, with the required
122 * number of streams. Will be modified when the chosen EP
123 * supports a different number of streams.
124 *
125 * This routine replaces the usb_ep_autoconfig when needed
126 * superspeed enhancments. If such enhancemnets are required,
127 * the FD should call usb_ep_autoconfig_ss directly and provide
128 * the additional ep_comp parameter.
129 *
130 * By choosing an endpoint to use with the specified descriptor,
131 * this routine simplifies writing gadget drivers that work with
132 * multiple USB device controllers. The endpoint would be
133 * passed later to usb_ep_enable(), along with some descriptor.
134 *
135 * That second descriptor won't always be the same as the first one.
136 * For example, isochronous endpoints can be autoconfigured for high
137 * bandwidth, and then used in several lower bandwidth altsettings.
138 * Also, high and full speed descriptors will be different.
139 *
140 * Be sure to examine and test the results of autoconfiguration
141 * on your hardware. This code may not make the best choices
142 * about how to use the USB controller, and it can't know all
143 * the restrictions that may apply. Some combinations of driver
144 * and hardware won't be able to autoconfigure.
145 *
146 * On success, this returns an un-claimed usb_ep, and modifies the endpoint
147 * descriptor bEndpointAddress. For bulk endpoints, the wMaxPacket value
148 * is initialized as if the endpoint were used at full speed and
149 * the bmAttribute field in the ep companion descriptor is
150 * updated with the assigned number of streams if it is
151 * different from the original value. To prevent the endpoint
152 * from being returned by a later autoconfig call, claim it by
Robert Baldygacc476b42015-07-31 16:00:13 +0200153 * assigning ep->claimed to true.
Tatyana Brokhmana59d6b92011-06-28 16:33:53 +0300154 *
155 * On failure, this returns a null endpoint descriptor.
156 */
157struct usb_ep *usb_ep_autoconfig_ss(
158 struct usb_gadget *gadget,
159 struct usb_endpoint_descriptor *desc,
160 struct usb_ss_ep_comp_descriptor *ep_comp
161)
162{
163 struct usb_ep *ep;
164 u8 type;
165
166 type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
167
Robert Baldyga596c1542015-08-06 14:11:10 +0200168 if (gadget->ops->match_ep) {
169 ep = gadget->ops->match_ep(gadget, desc, ep_comp);
170 if (ep)
171 goto found_ep;
172 }
173
Tatyana Brokhmana59d6b92011-06-28 16:33:53 +0300174 /* First, apply chip-specific "best usage" knowledge.
175 * This might make a good usb_gadget_ops hook ...
176 */
Mian Yousaf Kaukabe9ab4d02015-05-16 22:33:37 +0200177 if (gadget_is_net2280(gadget)) {
178 char name[8];
Tatyana Brokhmana59d6b92011-06-28 16:33:53 +0300179
Mian Yousaf Kaukabe9ab4d02015-05-16 22:33:37 +0200180 if (type == USB_ENDPOINT_XFER_INT) {
181 /* ep-e, ep-f are PIO with only 64 byte fifos */
182 ep = find_ep(gadget, "ep-e");
183 if (ep && ep_matches(gadget, ep, desc, ep_comp))
184 goto found_ep;
185 ep = find_ep(gadget, "ep-f");
186 if (ep && ep_matches(gadget, ep, desc, ep_comp))
187 goto found_ep;
188 }
189
190 /* USB3380: use same address for usb and hardware endpoints */
191 snprintf(name, sizeof(name), "ep%d%s", usb_endpoint_num(desc),
192 usb_endpoint_dir_in(desc) ? "in" : "out");
193 ep = find_ep(gadget, name);
194 if (ep && ep_matches(gadget, ep, desc, ep_comp))
195 goto found_ep;
Tatyana Brokhmana59d6b92011-06-28 16:33:53 +0300196 } else if (gadget_is_goku (gadget)) {
197 if (USB_ENDPOINT_XFER_INT == type) {
198 /* single buffering is enough */
199 ep = find_ep(gadget, "ep3-bulk");
200 if (ep && ep_matches(gadget, ep, desc, ep_comp))
Sebastian Andrzej Siewior609ca222012-02-06 18:46:35 +0100201 goto found_ep;
Tatyana Brokhmana59d6b92011-06-28 16:33:53 +0300202 } else if (USB_ENDPOINT_XFER_BULK == type
203 && (USB_DIR_IN & desc->bEndpointAddress)) {
204 /* DMA may be available */
205 ep = find_ep(gadget, "ep2-bulk");
206 if (ep && ep_matches(gadget, ep, desc,
207 ep_comp))
Sebastian Andrzej Siewior609ca222012-02-06 18:46:35 +0100208 goto found_ep;
Tatyana Brokhmana59d6b92011-06-28 16:33:53 +0300209 }
210
211#ifdef CONFIG_BLACKFIN
212 } else if (gadget_is_musbhdrc(gadget)) {
213 if ((USB_ENDPOINT_XFER_BULK == type) ||
214 (USB_ENDPOINT_XFER_ISOC == type)) {
215 if (USB_DIR_IN & desc->bEndpointAddress)
216 ep = find_ep (gadget, "ep5in");
217 else
218 ep = find_ep (gadget, "ep6out");
219 } else if (USB_ENDPOINT_XFER_INT == type) {
220 if (USB_DIR_IN & desc->bEndpointAddress)
221 ep = find_ep(gadget, "ep1in");
222 else
223 ep = find_ep(gadget, "ep2out");
224 } else
225 ep = NULL;
226 if (ep && ep_matches(gadget, ep, desc, ep_comp))
Sebastian Andrzej Siewior609ca222012-02-06 18:46:35 +0100227 goto found_ep;
Tatyana Brokhmana59d6b92011-06-28 16:33:53 +0300228#endif
229 }
230
231 /* Second, look at endpoints until an unclaimed one looks usable */
232 list_for_each_entry (ep, &gadget->ep_list, ep_list) {
233 if (ep_matches(gadget, ep, desc, ep_comp))
Sebastian Andrzej Siewior609ca222012-02-06 18:46:35 +0100234 goto found_ep;
Tatyana Brokhmana59d6b92011-06-28 16:33:53 +0300235 }
236
237 /* Fail */
238 return NULL;
Sebastian Andrzej Siewior609ca222012-02-06 18:46:35 +0100239found_ep:
Robert Baldyga5dbe1352015-07-31 16:00:51 +0200240
241 /*
242 * If the protocol driver hasn't yet decided on wMaxPacketSize
243 * and wants to know the maximum possible, provide the info.
244 */
245 if (desc->wMaxPacketSize == 0)
246 desc->wMaxPacketSize = cpu_to_le16(ep->maxpacket_limit);
247
248 /* report address */
249 desc->bEndpointAddress &= USB_DIR_IN;
250 if (isdigit(ep->name[2])) {
251 u8 num = simple_strtoul(&ep->name[2], NULL, 10);
252 desc->bEndpointAddress |= num;
253 } else if (desc->bEndpointAddress & USB_DIR_IN) {
254 if (++gadget->in_epnum > 15)
255 return NULL;
256 desc->bEndpointAddress = USB_DIR_IN | gadget->in_epnum;
257 } else {
258 if (++gadget->out_epnum > 15)
259 return NULL;
260 desc->bEndpointAddress |= gadget->out_epnum;
261 }
262
263 /* report (variable) full speed bulk maxpacket */
264 if ((type == USB_ENDPOINT_XFER_BULK) && !ep_comp) {
265 int size = ep->maxpacket_limit;
266
267 /* min() doesn't work on bitfields with gcc-3.5 */
268 if (size > 64)
269 size = 64;
270 desc->wMaxPacketSize = cpu_to_le16(size);
271 }
272
273 ep->address = desc->bEndpointAddress;
Sebastian Andrzej Siewior609ca222012-02-06 18:46:35 +0100274 ep->desc = NULL;
275 ep->comp_desc = NULL;
Robert Baldygacc476b42015-07-31 16:00:13 +0200276 ep->claimed = true;
Sebastian Andrzej Siewior609ca222012-02-06 18:46:35 +0100277 return ep;
Tatyana Brokhmana59d6b92011-06-28 16:33:53 +0300278}
Sebastian Andrzej Siewiordc995fc2012-09-06 20:11:12 +0200279EXPORT_SYMBOL_GPL(usb_ep_autoconfig_ss);
Tatyana Brokhmana59d6b92011-06-28 16:33:53 +0300280
281/**
282 * usb_ep_autoconfig() - choose an endpoint matching the
283 * descriptor
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284 * @gadget: The device to which the endpoint must belong.
285 * @desc: Endpoint descriptor, with endpoint direction and transfer mode
286 * initialized. For periodic transfers, the maximum packet
287 * size must also be initialized. This is modified on success.
288 *
289 * By choosing an endpoint to use with the specified descriptor, this
290 * routine simplifies writing gadget drivers that work with multiple
291 * USB device controllers. The endpoint would be passed later to
292 * usb_ep_enable(), along with some descriptor.
293 *
294 * That second descriptor won't always be the same as the first one.
295 * For example, isochronous endpoints can be autoconfigured for high
296 * bandwidth, and then used in several lower bandwidth altsettings.
297 * Also, high and full speed descriptors will be different.
298 *
299 * Be sure to examine and test the results of autoconfiguration on your
300 * hardware. This code may not make the best choices about how to use the
301 * USB controller, and it can't know all the restrictions that may apply.
302 * Some combinations of driver and hardware won't be able to autoconfigure.
303 *
304 * On success, this returns an un-claimed usb_ep, and modifies the endpoint
305 * descriptor bEndpointAddress. For bulk endpoints, the wMaxPacket value
306 * is initialized as if the endpoint were used at full speed. To prevent
307 * the endpoint from being returned by a later autoconfig call, claim it
Robert Baldygacc476b42015-07-31 16:00:13 +0200308 * by assigning ep->claimed to true.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309 *
310 * On failure, this returns a null endpoint descriptor.
311 */
Tatyana Brokhmana59d6b92011-06-28 16:33:53 +0300312struct usb_ep *usb_ep_autoconfig(
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313 struct usb_gadget *gadget,
314 struct usb_endpoint_descriptor *desc
315)
316{
Tatyana Brokhmana59d6b92011-06-28 16:33:53 +0300317 return usb_ep_autoconfig_ss(gadget, desc, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318}
Sebastian Andrzej Siewiordc995fc2012-09-06 20:11:12 +0200319EXPORT_SYMBOL_GPL(usb_ep_autoconfig);
Tatyana Brokhmana59d6b92011-06-28 16:33:53 +0300320
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321/**
322 * usb_ep_autoconfig_reset - reset endpoint autoconfig state
323 * @gadget: device for which autoconfig state will be reset
324 *
325 * Use this for devices where one configuration may need to assign
326 * endpoint resources very differently from the next one. It clears
Robert Baldygacc476b42015-07-31 16:00:13 +0200327 * state such as ep->claimed and the record of assigned endpoints
Linus Torvalds1da177e2005-04-16 15:20:36 -0700328 * used by usb_ep_autoconfig().
329 */
Michal Nazarewicz28824b12010-05-05 12:53:13 +0200330void usb_ep_autoconfig_reset (struct usb_gadget *gadget)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700331{
332 struct usb_ep *ep;
333
334 list_for_each_entry (ep, &gadget->ep_list, ep_list) {
Robert Baldygacc476b42015-07-31 16:00:13 +0200335 ep->claimed = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336 }
Sebastian Andrzej Siewiore87bb712012-09-06 20:11:11 +0200337 gadget->in_epnum = 0;
338 gadget->out_epnum = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700339}
Sebastian Andrzej Siewiordc995fc2012-09-06 20:11:12 +0200340EXPORT_SYMBOL_GPL(usb_ep_autoconfig_reset);