1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * epautoconf.c -- endpoint autoconfiguration for usb gadget drivers
4 *
5 * Copyright (C) 2004 David Brownell
6 *
7 * Ported to U-Boot by: Thomas Smits <ts.smits@gmail.com> and
8 * Remy Bohmer <linux@bohmer.net>
9 */
10
11 #include <linux/usb/ch9.h>
12 #include <linux/errno.h>
13 #include <linux/usb/gadget.h>
14 #include <asm/unaligned.h>
15
16 #define isdigit(c) ('0' <= (c) && (c) <= '9')
17
18 /* we must assign addresses for configurable endpoints (like net2280) */
19 static unsigned epnum;
20
21 /* #define MANY_ENDPOINTS */
22 #ifdef MANY_ENDPOINTS
23 /* more than 15 configurable endpoints */
24 static unsigned in_epnum;
25 #endif
26
27 /*
28 * This should work with endpoints from controller drivers sharing the
29 * same endpoint naming convention. By example:
30 *
31 * - ep1, ep2, ... address is fixed, not direction or type
32 * - ep1in, ep2out, ... address and direction are fixed, not type
33 * - ep1-bulk, ep2-bulk, ... address and type are fixed, not direction
34 * - ep1in-bulk, ep2out-iso, ... all three are fixed
35 * - ep-* ... no functionality restrictions
36 *
37 * Type suffixes are "-bulk", "-iso", or "-int". Numbers are decimal.
38 * Less common restrictions are implied by gadget_is_*().
39 *
40 * NOTE: each endpoint is unidirectional, as specified by its USB
41 * descriptor; and isn't specific to a configuration or altsetting.
42 */
ep_matches(struct usb_gadget * gadget,struct usb_ep * ep,struct usb_endpoint_descriptor * desc)43 static int ep_matches(
44 struct usb_gadget *gadget,
45 struct usb_ep *ep,
46 struct usb_endpoint_descriptor *desc
47 )
48 {
49 u8 type;
50 const char *tmp;
51 u16 max;
52
53 /* endpoint already claimed? */
54 if (NULL != ep->driver_data)
55 return 0;
56
57 /* only support ep0 for portable CONTROL traffic */
58 type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
59 if (USB_ENDPOINT_XFER_CONTROL == type)
60 return 0;
61
62 /* some other naming convention */
63 if ('e' != ep->name[0])
64 return 0;
65
66 /* type-restriction: "-iso", "-bulk", or "-int".
67 * direction-restriction: "in", "out".
68 */
69 if ('-' != ep->name[2]) {
70 tmp = strrchr(ep->name, '-');
71 if (tmp) {
72 switch (type) {
73 case USB_ENDPOINT_XFER_INT:
74 /* bulk endpoints handle interrupt transfers,
75 * except the toggle-quirky iso-synch kind
76 */
77 if ('s' == tmp[2]) /* == "-iso" */
78 return 0;
79 break;
80 case USB_ENDPOINT_XFER_BULK:
81 if ('b' != tmp[1]) /* != "-bulk" */
82 return 0;
83 break;
84 case USB_ENDPOINT_XFER_ISOC:
85 if ('s' != tmp[2]) /* != "-iso" */
86 return 0;
87 }
88 } else {
89 tmp = ep->name + strlen(ep->name);
90 }
91
92 /* direction-restriction: "..in-..", "out-.." */
93 tmp--;
94 if (!isdigit(*tmp)) {
95 if (desc->bEndpointAddress & USB_DIR_IN) {
96 if ('n' != *tmp)
97 return 0;
98 } else {
99 if ('t' != *tmp)
100 return 0;
101 }
102 }
103 }
104
105 /* endpoint maxpacket size is an input parameter, except for bulk
106 * where it's an output parameter representing the full speed limit.
107 * the usb spec fixes high speed bulk maxpacket at 512 bytes.
108 */
109 max = 0x7ff & le16_to_cpu(get_unaligned(&desc->wMaxPacketSize));
110 switch (type) {
111 case USB_ENDPOINT_XFER_INT:
112 /* INT: limit 64 bytes full speed, 1024 high speed */
113 if (!gadget->is_dualspeed && max > 64)
114 return 0;
115 /* FALLTHROUGH */
116
117 case USB_ENDPOINT_XFER_ISOC:
118 /* ISO: limit 1023 bytes full speed, 1024 high speed */
119 if (ep->maxpacket < max)
120 return 0;
121 if (!gadget->is_dualspeed && max > 1023)
122 return 0;
123
124 /* BOTH: "high bandwidth" works only at high speed */
125 if ((get_unaligned(&desc->wMaxPacketSize) &
126 __constant_cpu_to_le16(3<<11))) {
127 if (!gadget->is_dualspeed)
128 return 0;
129 /* configure your hardware with enough buffering!! */
130 }
131 break;
132 }
133
134 /* MATCH!! */
135
136 /* report address */
137 if (isdigit(ep->name[2])) {
138 u8 num = dectoul(&ep->name[2], NULL);
139 desc->bEndpointAddress |= num;
140 #ifdef MANY_ENDPOINTS
141 } else if (desc->bEndpointAddress & USB_DIR_IN) {
142 if (++in_epnum > 15)
143 return 0;
144 desc->bEndpointAddress = USB_DIR_IN | in_epnum;
145 #endif
146 } else {
147 if (++epnum > 15)
148 return 0;
149 desc->bEndpointAddress |= epnum;
150 }
151
152 /* report (variable) full speed bulk maxpacket */
153 if (USB_ENDPOINT_XFER_BULK == type) {
154 int size = ep->maxpacket;
155
156 /* min() doesn't work on bitfields with gcc-3.5 */
157 if (size > 64)
158 size = 64;
159 put_unaligned(cpu_to_le16(size), &desc->wMaxPacketSize);
160 }
161
162 if (gadget->ops->ep_conf)
163 return gadget->ops->ep_conf(gadget, ep, desc);
164
165 return 1;
166 }
167
168 /**
169 * usb_ep_autoconfig - choose an endpoint matching the descriptor
170 * @gadget: The device to which the endpoint must belong.
171 * @desc: Endpoint descriptor, with endpoint direction and transfer mode
172 * initialized. For periodic transfers, the maximum packet
173 * size must also be initialized. This is modified on success.
174 *
175 * By choosing an endpoint to use with the specified descriptor, this
176 * routine simplifies writing gadget drivers that work with multiple
177 * USB device controllers. The endpoint would be passed later to
178 * usb_ep_enable(), along with some descriptor.
179 *
180 * That second descriptor won't always be the same as the first one.
181 * For example, isochronous endpoints can be autoconfigured for high
182 * bandwidth, and then used in several lower bandwidth altsettings.
183 * Also, high and full speed descriptors will be different.
184 *
185 * Be sure to examine and test the results of autoconfiguration on your
186 * hardware. This code may not make the best choices about how to use the
187 * USB controller, and it can't know all the restrictions that may apply.
188 * Some combinations of driver and hardware won't be able to autoconfigure.
189 *
190 * On success, this returns an un-claimed usb_ep, and modifies the endpoint
191 * descriptor bEndpointAddress. For bulk endpoints, the wMaxPacket value
192 * is initialized as if the endpoint were used at full speed. To prevent
193 * the endpoint from being returned by a later autoconfig call, claim it
194 * by assigning ep->driver_data to some non-null value.
195 *
196 * On failure, this returns a null endpoint descriptor.
197 */
usb_ep_autoconfig(struct usb_gadget * gadget,struct usb_endpoint_descriptor * desc)198 struct usb_ep *usb_ep_autoconfig(
199 struct usb_gadget *gadget,
200 struct usb_endpoint_descriptor *desc
201 )
202 {
203 struct usb_ep *ep;
204
205 if (gadget->ops->match_ep) {
206 ep = gadget->ops->match_ep(gadget, desc, NULL);
207 if (ep && ep_matches(gadget, ep, desc))
208 return ep;
209 }
210
211 /* Second, look at endpoints until an unclaimed one looks usable */
212 list_for_each_entry(ep, &gadget->ep_list, ep_list) {
213 if (ep_matches(gadget, ep, desc))
214 return ep;
215 }
216
217 /* Fail */
218 return NULL;
219 }
220
221 /**
222 * usb_ep_autoconfig_reset - reset endpoint autoconfig state
223 * @gadget: device for which autoconfig state will be reset
224 *
225 * Use this for devices where one configuration may need to assign
226 * endpoint resources very differently from the next one. It clears
227 * state such as ep->driver_data and the record of assigned endpoints
228 * used by usb_ep_autoconfig().
229 */
usb_ep_autoconfig_reset(struct usb_gadget * gadget)230 void usb_ep_autoconfig_reset(struct usb_gadget *gadget)
231 {
232 struct usb_ep *ep;
233
234 list_for_each_entry(ep, &gadget->ep_list, ep_list) {
235 ep->driver_data = NULL;
236 }
237 #ifdef MANY_ENDPOINTS
238 in_epnum = 0;
239 #endif
240 epnum = 0;
241 }
242