Commit be7ed2533d4acb9bc67989c4ffddb5814202ba02

Authored by Marek Vasut
1 parent b959655f18
Exists in master and in 55 other branches 8qm-imx_v2020.04_5.4.70_2.3.0, emb_lf_v2022.04, emb_lf_v2023.04, emb_lf_v2024.04, imx_v2015.04_4.1.15_1.0.0_ga, pitx_8mp_lf_v2020.04, smarc-8m-android-10.0.0_2.6.0, smarc-8m-android-11.0.0_2.0.0, smarc-8mp-android-11.0.0_2.0.0, smarc-emmc-imx_v2014.04_3.10.53_1.1.0_ga, smarc-emmc-imx_v2014.04_3.14.28_1.0.0_ga, smarc-imx-l5.0.0_1.0.0-ga, smarc-imx6_v2018.03_4.14.98_2.0.0_ga, smarc-imx7_v2017.03_4.9.11_1.0.0_ga, smarc-imx7_v2018.03_4.14.98_2.0.0_ga, smarc-imx_v2014.04_3.14.28_1.0.0_ga, smarc-imx_v2015.04_4.1.15_1.0.0_ga, smarc-imx_v2017.03_4.9.11_1.0.0_ga, smarc-imx_v2017.03_4.9.88_2.0.0_ga, smarc-imx_v2017.03_o8.1.0_1.3.0_8m, smarc-imx_v2018.03_4.14.78_1.0.0_ga, smarc-m6.0.1_2.1.0-ga, smarc-n7.1.2_2.0.0-ga, smarc-rel_imx_4.1.15_2.0.0_ga, smarc_8m-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8m-imx_v2019.04_4.19.35_1.1.0, smarc_8m_00d0-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8mm-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8mm-imx_v2019.04_4.19.35_1.1.0, smarc_8mm-imx_v2020.04_5.4.24_2.1.0, smarc_8mp_lf_v2020.04, smarc_8mq-imx_v2020.04_5.4.24_2.1.0, smarc_8mq_lf_v2020.04, ti-u-boot-2015.07, v2013.10, v2013.10-smarct33, v2013.10-smartmen, v2014.01, v2014.04, v2014.04-smarct33, v2014.04-smarct33-emmc, v2014.04-smartmen, v2014.07, v2014.07-smarct33, v2014.07-smartmen, v2015.07-smarct33, v2015.07-smarct33-emmc, v2015.07-smarct4x, v2016.05-dlt, v2016.05-smarct3x, v2016.05-smarct3x-emmc, v2016.05-smarct4x, v2017.01-smarct3x, v2017.01-smarct3x-emmc, v2017.01-smarct4x

usb: mv_udc: Make use of struct ehci_ctrl

The usb_lowlevel_init() call already fills and passes back struct
ehci_ctrl , which readily contains correctly determined address of
the port register block address computed from values from controller
configuration registers. Leverage this and make use of this value
as this makes the code mode universal, but also gets us rid of the
CONFIG_USB_REG_BASE configuration option.

Moreover, this patch cleans up the usb_gadget_register_driver() call
a little by correcting the error handling. Note the usb_lowlevel_init()
and mvudc_probe() are now called in reversed order, but this has no
impact on the code.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Fabio Estevam <fabio.estevam@freescale.com>
Cc: Lei Wen <leiwen@marvell.com>
Cc: Otavio Salvador <otavio@ossystems.com.br>
Cc: Stefano Babic <sbabic@denx.de>

Showing 2 changed files with 26 additions and 21 deletions Inline Diff

drivers/usb/gadget/mv_udc.c
1 /* 1 /*
2 * Copyright 2011, Marvell Semiconductor Inc. 2 * Copyright 2011, Marvell Semiconductor Inc.
3 * Lei Wen <leiwen@marvell.com> 3 * Lei Wen <leiwen@marvell.com>
4 * 4 *
5 * SPDX-License-Identifier: GPL-2.0+ 5 * SPDX-License-Identifier: GPL-2.0+
6 * 6 *
7 * Back ported to the 8xx platform (from the 8260 platform) by 7 * Back ported to the 8xx platform (from the 8260 platform) by
8 * Murray.Jensen@cmst.csiro.au, 27-Jan-01. 8 * Murray.Jensen@cmst.csiro.au, 27-Jan-01.
9 */ 9 */
10 10
11 #include <common.h> 11 #include <common.h>
12 #include <command.h> 12 #include <command.h>
13 #include <config.h> 13 #include <config.h>
14 #include <net.h> 14 #include <net.h>
15 #include <malloc.h> 15 #include <malloc.h>
16 #include <asm/io.h> 16 #include <asm/io.h>
17 #include <linux/types.h> 17 #include <linux/types.h>
18 #include <usb/mv_udc.h> 18 #include <usb/mv_udc.h>
19 19
20 #if CONFIG_USB_MAX_CONTROLLER_COUNT > 1 20 #if CONFIG_USB_MAX_CONTROLLER_COUNT > 1
21 #error This driver only supports one single controller. 21 #error This driver only supports one single controller.
22 #endif 22 #endif
23 23
24 #ifndef DEBUG 24 #ifndef DEBUG
25 #define DBG(x...) do {} while (0) 25 #define DBG(x...) do {} while (0)
26 #else 26 #else
27 #define DBG(x...) printf(x) 27 #define DBG(x...) printf(x)
28 static const char *reqname(unsigned r) 28 static const char *reqname(unsigned r)
29 { 29 {
30 switch (r) { 30 switch (r) {
31 case USB_REQ_GET_STATUS: return "GET_STATUS"; 31 case USB_REQ_GET_STATUS: return "GET_STATUS";
32 case USB_REQ_CLEAR_FEATURE: return "CLEAR_FEATURE"; 32 case USB_REQ_CLEAR_FEATURE: return "CLEAR_FEATURE";
33 case USB_REQ_SET_FEATURE: return "SET_FEATURE"; 33 case USB_REQ_SET_FEATURE: return "SET_FEATURE";
34 case USB_REQ_SET_ADDRESS: return "SET_ADDRESS"; 34 case USB_REQ_SET_ADDRESS: return "SET_ADDRESS";
35 case USB_REQ_GET_DESCRIPTOR: return "GET_DESCRIPTOR"; 35 case USB_REQ_GET_DESCRIPTOR: return "GET_DESCRIPTOR";
36 case USB_REQ_SET_DESCRIPTOR: return "SET_DESCRIPTOR"; 36 case USB_REQ_SET_DESCRIPTOR: return "SET_DESCRIPTOR";
37 case USB_REQ_GET_CONFIGURATION: return "GET_CONFIGURATION"; 37 case USB_REQ_GET_CONFIGURATION: return "GET_CONFIGURATION";
38 case USB_REQ_SET_CONFIGURATION: return "SET_CONFIGURATION"; 38 case USB_REQ_SET_CONFIGURATION: return "SET_CONFIGURATION";
39 case USB_REQ_GET_INTERFACE: return "GET_INTERFACE"; 39 case USB_REQ_GET_INTERFACE: return "GET_INTERFACE";
40 case USB_REQ_SET_INTERFACE: return "SET_INTERFACE"; 40 case USB_REQ_SET_INTERFACE: return "SET_INTERFACE";
41 default: return "*UNKNOWN*"; 41 default: return "*UNKNOWN*";
42 } 42 }
43 } 43 }
44 #endif 44 #endif
45 45
46 #define PAGE_SIZE 4096 46 #define PAGE_SIZE 4096
47 #define QH_MAXNUM 32 47 #define QH_MAXNUM 32
48 static struct usb_endpoint_descriptor ep0_out_desc = { 48 static struct usb_endpoint_descriptor ep0_out_desc = {
49 .bLength = sizeof(struct usb_endpoint_descriptor), 49 .bLength = sizeof(struct usb_endpoint_descriptor),
50 .bDescriptorType = USB_DT_ENDPOINT, 50 .bDescriptorType = USB_DT_ENDPOINT,
51 .bEndpointAddress = 0, 51 .bEndpointAddress = 0,
52 .bmAttributes = USB_ENDPOINT_XFER_CONTROL, 52 .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
53 }; 53 };
54 54
55 static struct usb_endpoint_descriptor ep0_in_desc = { 55 static struct usb_endpoint_descriptor ep0_in_desc = {
56 .bLength = sizeof(struct usb_endpoint_descriptor), 56 .bLength = sizeof(struct usb_endpoint_descriptor),
57 .bDescriptorType = USB_DT_ENDPOINT, 57 .bDescriptorType = USB_DT_ENDPOINT,
58 .bEndpointAddress = USB_DIR_IN, 58 .bEndpointAddress = USB_DIR_IN,
59 .bmAttributes = USB_ENDPOINT_XFER_CONTROL, 59 .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
60 }; 60 };
61 61
62 struct ept_queue_head *epts; 62 struct ept_queue_head *epts;
63 struct ept_queue_item *items[2 * NUM_ENDPOINTS]; 63 struct ept_queue_item *items[2 * NUM_ENDPOINTS];
64 static int mv_pullup(struct usb_gadget *gadget, int is_on); 64 static int mv_pullup(struct usb_gadget *gadget, int is_on);
65 static int mv_ep_enable(struct usb_ep *ep, 65 static int mv_ep_enable(struct usb_ep *ep,
66 const struct usb_endpoint_descriptor *desc); 66 const struct usb_endpoint_descriptor *desc);
67 static int mv_ep_disable(struct usb_ep *ep); 67 static int mv_ep_disable(struct usb_ep *ep);
68 static int mv_ep_queue(struct usb_ep *ep, 68 static int mv_ep_queue(struct usb_ep *ep,
69 struct usb_request *req, gfp_t gfp_flags); 69 struct usb_request *req, gfp_t gfp_flags);
70 static struct usb_request * 70 static struct usb_request *
71 mv_ep_alloc_request(struct usb_ep *ep, unsigned int gfp_flags); 71 mv_ep_alloc_request(struct usb_ep *ep, unsigned int gfp_flags);
72 static void mv_ep_free_request(struct usb_ep *ep, struct usb_request *_req); 72 static void mv_ep_free_request(struct usb_ep *ep, struct usb_request *_req);
73 73
74 static struct usb_gadget_ops mv_udc_ops = { 74 static struct usb_gadget_ops mv_udc_ops = {
75 .pullup = mv_pullup, 75 .pullup = mv_pullup,
76 }; 76 };
77 77
78 static struct usb_ep_ops mv_ep_ops = { 78 static struct usb_ep_ops mv_ep_ops = {
79 .enable = mv_ep_enable, 79 .enable = mv_ep_enable,
80 .disable = mv_ep_disable, 80 .disable = mv_ep_disable,
81 .queue = mv_ep_queue, 81 .queue = mv_ep_queue,
82 .alloc_request = mv_ep_alloc_request, 82 .alloc_request = mv_ep_alloc_request,
83 .free_request = mv_ep_free_request, 83 .free_request = mv_ep_free_request,
84 }; 84 };
85 85
86 /* Init values for USB endpoints. */ 86 /* Init values for USB endpoints. */
87 static const struct usb_ep mv_ep_init[2] = { 87 static const struct usb_ep mv_ep_init[2] = {
88 [0] = { /* EP 0 */ 88 [0] = { /* EP 0 */
89 .maxpacket = 64, 89 .maxpacket = 64,
90 .name = "ep0", 90 .name = "ep0",
91 .ops = &mv_ep_ops, 91 .ops = &mv_ep_ops,
92 }, 92 },
93 [1] = { /* EP 1..n */ 93 [1] = { /* EP 1..n */
94 .maxpacket = 512, 94 .maxpacket = 512,
95 .name = "ep-", 95 .name = "ep-",
96 .ops = &mv_ep_ops, 96 .ops = &mv_ep_ops,
97 }, 97 },
98 }; 98 };
99 99
100 static struct mv_drv controller = { 100 static struct mv_drv controller = {
101 .gadget = { 101 .gadget = {
102 .name = "mv_udc", 102 .name = "mv_udc",
103 }, 103 },
104 }; 104 };
105 105
106 static struct usb_request * 106 static struct usb_request *
107 mv_ep_alloc_request(struct usb_ep *ep, unsigned int gfp_flags) 107 mv_ep_alloc_request(struct usb_ep *ep, unsigned int gfp_flags)
108 { 108 {
109 struct mv_ep *mv_ep = container_of(ep, struct mv_ep, ep); 109 struct mv_ep *mv_ep = container_of(ep, struct mv_ep, ep);
110 return &mv_ep->req; 110 return &mv_ep->req;
111 } 111 }
112 112
113 static void mv_ep_free_request(struct usb_ep *ep, struct usb_request *_req) 113 static void mv_ep_free_request(struct usb_ep *ep, struct usb_request *_req)
114 { 114 {
115 return; 115 return;
116 } 116 }
117 117
118 static void ep_enable(int num, int in) 118 static void ep_enable(int num, int in)
119 { 119 {
120 struct ept_queue_head *head; 120 struct ept_queue_head *head;
121 struct mv_udc *udc = controller.udc; 121 struct mv_udc *udc = (struct mv_udc *)controller.ctrl->hcor;
122 unsigned n; 122 unsigned n;
123 head = epts + 2*num + in; 123 head = epts + 2*num + in;
124 124
125 n = readl(&udc->epctrl[num]); 125 n = readl(&udc->epctrl[num]);
126 if (in) 126 if (in)
127 n |= (CTRL_TXE | CTRL_TXR | CTRL_TXT_BULK); 127 n |= (CTRL_TXE | CTRL_TXR | CTRL_TXT_BULK);
128 else 128 else
129 n |= (CTRL_RXE | CTRL_RXR | CTRL_RXT_BULK); 129 n |= (CTRL_RXE | CTRL_RXR | CTRL_RXT_BULK);
130 130
131 if (num != 0) 131 if (num != 0)
132 head->config = CONFIG_MAX_PKT(EP_MAX_PACKET_SIZE) | CONFIG_ZLT; 132 head->config = CONFIG_MAX_PKT(EP_MAX_PACKET_SIZE) | CONFIG_ZLT;
133 writel(n, &udc->epctrl[num]); 133 writel(n, &udc->epctrl[num]);
134 } 134 }
135 135
136 static int mv_ep_enable(struct usb_ep *ep, 136 static int mv_ep_enable(struct usb_ep *ep,
137 const struct usb_endpoint_descriptor *desc) 137 const struct usb_endpoint_descriptor *desc)
138 { 138 {
139 struct mv_ep *mv_ep = container_of(ep, struct mv_ep, ep); 139 struct mv_ep *mv_ep = container_of(ep, struct mv_ep, ep);
140 int num, in; 140 int num, in;
141 num = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; 141 num = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
142 in = (desc->bEndpointAddress & USB_DIR_IN) != 0; 142 in = (desc->bEndpointAddress & USB_DIR_IN) != 0;
143 ep_enable(num, in); 143 ep_enable(num, in);
144 mv_ep->desc = desc; 144 mv_ep->desc = desc;
145 return 0; 145 return 0;
146 } 146 }
147 147
148 static int mv_ep_disable(struct usb_ep *ep) 148 static int mv_ep_disable(struct usb_ep *ep)
149 { 149 {
150 return 0; 150 return 0;
151 } 151 }
152 152
153 static int mv_ep_queue(struct usb_ep *ep, 153 static int mv_ep_queue(struct usb_ep *ep,
154 struct usb_request *req, gfp_t gfp_flags) 154 struct usb_request *req, gfp_t gfp_flags)
155 { 155 {
156 struct mv_ep *mv_ep = container_of(ep, struct mv_ep, ep); 156 struct mv_ep *mv_ep = container_of(ep, struct mv_ep, ep);
157 struct mv_udc *udc = controller.udc; 157 struct mv_udc *udc = (struct mv_udc *)controller.ctrl->hcor;
158 struct ept_queue_item *item; 158 struct ept_queue_item *item;
159 struct ept_queue_head *head; 159 struct ept_queue_head *head;
160 unsigned phys; 160 unsigned phys;
161 int bit, num, len, in; 161 int bit, num, len, in;
162 num = mv_ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; 162 num = mv_ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
163 in = (mv_ep->desc->bEndpointAddress & USB_DIR_IN) != 0; 163 in = (mv_ep->desc->bEndpointAddress & USB_DIR_IN) != 0;
164 item = items[2 * num + in]; 164 item = items[2 * num + in];
165 head = epts + 2 * num + in; 165 head = epts + 2 * num + in;
166 phys = (unsigned)req->buf; 166 phys = (unsigned)req->buf;
167 len = req->length; 167 len = req->length;
168 168
169 item->next = TERMINATE; 169 item->next = TERMINATE;
170 item->info = INFO_BYTES(len) | INFO_IOC | INFO_ACTIVE; 170 item->info = INFO_BYTES(len) | INFO_IOC | INFO_ACTIVE;
171 item->page0 = phys; 171 item->page0 = phys;
172 item->page1 = (phys & 0xfffff000) + 0x1000; 172 item->page1 = (phys & 0xfffff000) + 0x1000;
173 173
174 head->next = (unsigned) item; 174 head->next = (unsigned) item;
175 head->info = 0; 175 head->info = 0;
176 176
177 DBG("ept%d %s queue len %x, buffer %x\n", 177 DBG("ept%d %s queue len %x, buffer %x\n",
178 num, in ? "in" : "out", len, phys); 178 num, in ? "in" : "out", len, phys);
179 179
180 if (in) 180 if (in)
181 bit = EPT_TX(num); 181 bit = EPT_TX(num);
182 else 182 else
183 bit = EPT_RX(num); 183 bit = EPT_RX(num);
184 184
185 flush_cache(phys, len); 185 flush_cache(phys, len);
186 flush_cache((unsigned long)item, sizeof(struct ept_queue_item)); 186 flush_cache((unsigned long)item, sizeof(struct ept_queue_item));
187 writel(bit, &udc->epprime); 187 writel(bit, &udc->epprime);
188 188
189 return 0; 189 return 0;
190 } 190 }
191 191
192 static void handle_ep_complete(struct mv_ep *ep) 192 static void handle_ep_complete(struct mv_ep *ep)
193 { 193 {
194 struct ept_queue_item *item; 194 struct ept_queue_item *item;
195 int num, in, len; 195 int num, in, len;
196 num = ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; 196 num = ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
197 in = (ep->desc->bEndpointAddress & USB_DIR_IN) != 0; 197 in = (ep->desc->bEndpointAddress & USB_DIR_IN) != 0;
198 if (num == 0) 198 if (num == 0)
199 ep->desc = &ep0_out_desc; 199 ep->desc = &ep0_out_desc;
200 item = items[2 * num + in]; 200 item = items[2 * num + in];
201 201
202 if (item->info & 0xff) 202 if (item->info & 0xff)
203 printf("EP%d/%s FAIL nfo=%x pg0=%x\n", 203 printf("EP%d/%s FAIL nfo=%x pg0=%x\n",
204 num, in ? "in" : "out", item->info, item->page0); 204 num, in ? "in" : "out", item->info, item->page0);
205 205
206 len = (item->info >> 16) & 0x7fff; 206 len = (item->info >> 16) & 0x7fff;
207 ep->req.length -= len; 207 ep->req.length -= len;
208 DBG("ept%d %s complete %x\n", 208 DBG("ept%d %s complete %x\n",
209 num, in ? "in" : "out", len); 209 num, in ? "in" : "out", len);
210 ep->req.complete(&ep->ep, &ep->req); 210 ep->req.complete(&ep->ep, &ep->req);
211 if (num == 0) { 211 if (num == 0) {
212 ep->req.length = 0; 212 ep->req.length = 0;
213 usb_ep_queue(&ep->ep, &ep->req, 0); 213 usb_ep_queue(&ep->ep, &ep->req, 0);
214 ep->desc = &ep0_in_desc; 214 ep->desc = &ep0_in_desc;
215 } 215 }
216 } 216 }
217 217
218 #define SETUP(type, request) (((type) << 8) | (request)) 218 #define SETUP(type, request) (((type) << 8) | (request))
219 219
220 static void handle_setup(void) 220 static void handle_setup(void)
221 { 221 {
222 struct usb_request *req = &controller.ep[0].req; 222 struct usb_request *req = &controller.ep[0].req;
223 struct mv_udc *udc = controller.udc; 223 struct mv_udc *udc = (struct mv_udc *)controller.ctrl->hcor;
224 struct ept_queue_head *head; 224 struct ept_queue_head *head;
225 struct usb_ctrlrequest r; 225 struct usb_ctrlrequest r;
226 int status = 0; 226 int status = 0;
227 int num, in, _num, _in, i; 227 int num, in, _num, _in, i;
228 char *buf; 228 char *buf;
229 head = epts; 229 head = epts;
230 230
231 flush_cache((unsigned long)head, sizeof(struct ept_queue_head)); 231 flush_cache((unsigned long)head, sizeof(struct ept_queue_head));
232 memcpy(&r, head->setup_data, sizeof(struct usb_ctrlrequest)); 232 memcpy(&r, head->setup_data, sizeof(struct usb_ctrlrequest));
233 writel(EPT_RX(0), &udc->epstat); 233 writel(EPT_RX(0), &udc->epstat);
234 DBG("handle setup %s, %x, %x index %x value %x\n", reqname(r.bRequest), 234 DBG("handle setup %s, %x, %x index %x value %x\n", reqname(r.bRequest),
235 r.bRequestType, r.bRequest, r.wIndex, r.wValue); 235 r.bRequestType, r.bRequest, r.wIndex, r.wValue);
236 236
237 switch (SETUP(r.bRequestType, r.bRequest)) { 237 switch (SETUP(r.bRequestType, r.bRequest)) {
238 case SETUP(USB_RECIP_ENDPOINT, USB_REQ_CLEAR_FEATURE): 238 case SETUP(USB_RECIP_ENDPOINT, USB_REQ_CLEAR_FEATURE):
239 _num = r.wIndex & 15; 239 _num = r.wIndex & 15;
240 _in = !!(r.wIndex & 0x80); 240 _in = !!(r.wIndex & 0x80);
241 241
242 if ((r.wValue == 0) && (r.wLength == 0)) { 242 if ((r.wValue == 0) && (r.wLength == 0)) {
243 req->length = 0; 243 req->length = 0;
244 for (i = 0; i < NUM_ENDPOINTS; i++) { 244 for (i = 0; i < NUM_ENDPOINTS; i++) {
245 if (!controller.ep[i].desc) 245 if (!controller.ep[i].desc)
246 continue; 246 continue;
247 num = controller.ep[i].desc->bEndpointAddress 247 num = controller.ep[i].desc->bEndpointAddress
248 & USB_ENDPOINT_NUMBER_MASK; 248 & USB_ENDPOINT_NUMBER_MASK;
249 in = (controller.ep[i].desc->bEndpointAddress 249 in = (controller.ep[i].desc->bEndpointAddress
250 & USB_DIR_IN) != 0; 250 & USB_DIR_IN) != 0;
251 if ((num == _num) && (in == _in)) { 251 if ((num == _num) && (in == _in)) {
252 ep_enable(num, in); 252 ep_enable(num, in);
253 usb_ep_queue(controller.gadget.ep0, 253 usb_ep_queue(controller.gadget.ep0,
254 req, 0); 254 req, 0);
255 break; 255 break;
256 } 256 }
257 } 257 }
258 } 258 }
259 return; 259 return;
260 260
261 case SETUP(USB_RECIP_DEVICE, USB_REQ_SET_ADDRESS): 261 case SETUP(USB_RECIP_DEVICE, USB_REQ_SET_ADDRESS):
262 /* 262 /*
263 * write address delayed (will take effect 263 * write address delayed (will take effect
264 * after the next IN txn) 264 * after the next IN txn)
265 */ 265 */
266 writel((r.wValue << 25) | (1 << 24), &udc->devaddr); 266 writel((r.wValue << 25) | (1 << 24), &udc->devaddr);
267 req->length = 0; 267 req->length = 0;
268 usb_ep_queue(controller.gadget.ep0, req, 0); 268 usb_ep_queue(controller.gadget.ep0, req, 0);
269 return; 269 return;
270 270
271 case SETUP(USB_DIR_IN | USB_RECIP_DEVICE, USB_REQ_GET_STATUS): 271 case SETUP(USB_DIR_IN | USB_RECIP_DEVICE, USB_REQ_GET_STATUS):
272 req->length = 2; 272 req->length = 2;
273 buf = (char *)req->buf; 273 buf = (char *)req->buf;
274 buf[0] = 1 << USB_DEVICE_SELF_POWERED; 274 buf[0] = 1 << USB_DEVICE_SELF_POWERED;
275 buf[1] = 0; 275 buf[1] = 0;
276 usb_ep_queue(controller.gadget.ep0, req, 0); 276 usb_ep_queue(controller.gadget.ep0, req, 0);
277 return; 277 return;
278 } 278 }
279 /* pass request up to the gadget driver */ 279 /* pass request up to the gadget driver */
280 if (controller.driver) 280 if (controller.driver)
281 status = controller.driver->setup(&controller.gadget, &r); 281 status = controller.driver->setup(&controller.gadget, &r);
282 else 282 else
283 status = -ENODEV; 283 status = -ENODEV;
284 284
285 if (!status) 285 if (!status)
286 return; 286 return;
287 DBG("STALL reqname %s type %x value %x, index %x\n", 287 DBG("STALL reqname %s type %x value %x, index %x\n",
288 reqname(r.bRequest), r.bRequestType, r.wValue, r.wIndex); 288 reqname(r.bRequest), r.bRequestType, r.wValue, r.wIndex);
289 writel((1<<16) | (1 << 0), &udc->epctrl[0]); 289 writel((1<<16) | (1 << 0), &udc->epctrl[0]);
290 } 290 }
291 291
292 static void stop_activity(void) 292 static void stop_activity(void)
293 { 293 {
294 int i, num, in; 294 int i, num, in;
295 struct ept_queue_head *head; 295 struct ept_queue_head *head;
296 struct mv_udc *udc = controller.udc; 296 struct mv_udc *udc = (struct mv_udc *)controller.ctrl->hcor;
297 writel(readl(&udc->epcomp), &udc->epcomp); 297 writel(readl(&udc->epcomp), &udc->epcomp);
298 writel(readl(&udc->epstat), &udc->epstat); 298 writel(readl(&udc->epstat), &udc->epstat);
299 writel(0xffffffff, &udc->epflush); 299 writel(0xffffffff, &udc->epflush);
300 300
301 /* error out any pending reqs */ 301 /* error out any pending reqs */
302 for (i = 0; i < NUM_ENDPOINTS; i++) { 302 for (i = 0; i < NUM_ENDPOINTS; i++) {
303 if (i != 0) 303 if (i != 0)
304 writel(0, &udc->epctrl[i]); 304 writel(0, &udc->epctrl[i]);
305 if (controller.ep[i].desc) { 305 if (controller.ep[i].desc) {
306 num = controller.ep[i].desc->bEndpointAddress 306 num = controller.ep[i].desc->bEndpointAddress
307 & USB_ENDPOINT_NUMBER_MASK; 307 & USB_ENDPOINT_NUMBER_MASK;
308 in = (controller.ep[i].desc->bEndpointAddress 308 in = (controller.ep[i].desc->bEndpointAddress
309 & USB_DIR_IN) != 0; 309 & USB_DIR_IN) != 0;
310 head = epts + (num * 2) + (in); 310 head = epts + (num * 2) + (in);
311 head->info = INFO_ACTIVE; 311 head->info = INFO_ACTIVE;
312 } 312 }
313 } 313 }
314 } 314 }
315 315
316 void udc_irq(void) 316 void udc_irq(void)
317 { 317 {
318 struct mv_udc *udc = controller.udc; 318 struct mv_udc *udc = (struct mv_udc *)controller.ctrl->hcor;
319 unsigned n = readl(&udc->usbsts); 319 unsigned n = readl(&udc->usbsts);
320 writel(n, &udc->usbsts); 320 writel(n, &udc->usbsts);
321 int bit, i, num, in; 321 int bit, i, num, in;
322 322
323 n &= (STS_SLI | STS_URI | STS_PCI | STS_UI | STS_UEI); 323 n &= (STS_SLI | STS_URI | STS_PCI | STS_UI | STS_UEI);
324 if (n == 0) 324 if (n == 0)
325 return; 325 return;
326 326
327 if (n & STS_URI) { 327 if (n & STS_URI) {
328 DBG("-- reset --\n"); 328 DBG("-- reset --\n");
329 stop_activity(); 329 stop_activity();
330 } 330 }
331 if (n & STS_SLI) 331 if (n & STS_SLI)
332 DBG("-- suspend --\n"); 332 DBG("-- suspend --\n");
333 333
334 if (n & STS_PCI) { 334 if (n & STS_PCI) {
335 DBG("-- portchange --\n"); 335 DBG("-- portchange --\n");
336 bit = (readl(&udc->portsc) >> 26) & 3; 336 bit = (readl(&udc->portsc) >> 26) & 3;
337 if (bit == 2) { 337 if (bit == 2) {
338 controller.gadget.speed = USB_SPEED_HIGH; 338 controller.gadget.speed = USB_SPEED_HIGH;
339 for (i = 1; i < NUM_ENDPOINTS && n; i++) 339 for (i = 1; i < NUM_ENDPOINTS && n; i++)
340 if (controller.ep[i].desc) 340 if (controller.ep[i].desc)
341 controller.ep[i].ep.maxpacket = 512; 341 controller.ep[i].ep.maxpacket = 512;
342 } else { 342 } else {
343 controller.gadget.speed = USB_SPEED_FULL; 343 controller.gadget.speed = USB_SPEED_FULL;
344 } 344 }
345 } 345 }
346 346
347 if (n & STS_UEI) 347 if (n & STS_UEI)
348 printf("<UEI %x>\n", readl(&udc->epcomp)); 348 printf("<UEI %x>\n", readl(&udc->epcomp));
349 349
350 if ((n & STS_UI) || (n & STS_UEI)) { 350 if ((n & STS_UI) || (n & STS_UEI)) {
351 n = readl(&udc->epstat); 351 n = readl(&udc->epstat);
352 if (n & EPT_RX(0)) 352 if (n & EPT_RX(0))
353 handle_setup(); 353 handle_setup();
354 354
355 n = readl(&udc->epcomp); 355 n = readl(&udc->epcomp);
356 if (n != 0) 356 if (n != 0)
357 writel(n, &udc->epcomp); 357 writel(n, &udc->epcomp);
358 358
359 for (i = 0; i < NUM_ENDPOINTS && n; i++) { 359 for (i = 0; i < NUM_ENDPOINTS && n; i++) {
360 if (controller.ep[i].desc) { 360 if (controller.ep[i].desc) {
361 num = controller.ep[i].desc->bEndpointAddress 361 num = controller.ep[i].desc->bEndpointAddress
362 & USB_ENDPOINT_NUMBER_MASK; 362 & USB_ENDPOINT_NUMBER_MASK;
363 in = (controller.ep[i].desc->bEndpointAddress 363 in = (controller.ep[i].desc->bEndpointAddress
364 & USB_DIR_IN) != 0; 364 & USB_DIR_IN) != 0;
365 bit = (in) ? EPT_TX(num) : EPT_RX(num); 365 bit = (in) ? EPT_TX(num) : EPT_RX(num);
366 if (n & bit) 366 if (n & bit)
367 handle_ep_complete(&controller.ep[i]); 367 handle_ep_complete(&controller.ep[i]);
368 } 368 }
369 } 369 }
370 } 370 }
371 } 371 }
372 372
373 int usb_gadget_handle_interrupts(void) 373 int usb_gadget_handle_interrupts(void)
374 { 374 {
375 u32 value; 375 u32 value;
376 struct mv_udc *udc = controller.udc; 376 struct mv_udc *udc = (struct mv_udc *)controller.ctrl->hcor;
377 377
378 value = readl(&udc->usbsts); 378 value = readl(&udc->usbsts);
379 if (value) 379 if (value)
380 udc_irq(); 380 udc_irq();
381 381
382 return value; 382 return value;
383 } 383 }
384 384
385 static int mv_pullup(struct usb_gadget *gadget, int is_on) 385 static int mv_pullup(struct usb_gadget *gadget, int is_on)
386 { 386 {
387 struct mv_udc *udc = controller.udc; 387 struct mv_udc *udc = (struct mv_udc *)controller.ctrl->hcor;
388 if (is_on) { 388 if (is_on) {
389 /* RESET */ 389 /* RESET */
390 writel(USBCMD_ITC(MICRO_8FRAME) | USBCMD_RST, &udc->usbcmd); 390 writel(USBCMD_ITC(MICRO_8FRAME) | USBCMD_RST, &udc->usbcmd);
391 udelay(200); 391 udelay(200);
392 392
393 writel((unsigned) epts, &udc->epinitaddr); 393 writel((unsigned) epts, &udc->epinitaddr);
394 394
395 /* select DEVICE mode */ 395 /* select DEVICE mode */
396 writel(USBMODE_DEVICE, &udc->usbmode); 396 writel(USBMODE_DEVICE, &udc->usbmode);
397 397
398 writel(0xffffffff, &udc->epflush); 398 writel(0xffffffff, &udc->epflush);
399 399
400 /* Turn on the USB connection by enabling the pullup resistor */ 400 /* Turn on the USB connection by enabling the pullup resistor */
401 writel(USBCMD_ITC(MICRO_8FRAME) | USBCMD_RUN, &udc->usbcmd); 401 writel(USBCMD_ITC(MICRO_8FRAME) | USBCMD_RUN, &udc->usbcmd);
402 } else { 402 } else {
403 stop_activity(); 403 stop_activity();
404 writel(USBCMD_FS2, &udc->usbcmd); 404 writel(USBCMD_FS2, &udc->usbcmd);
405 udelay(800); 405 udelay(800);
406 if (controller.driver) 406 if (controller.driver)
407 controller.driver->disconnect(gadget); 407 controller.driver->disconnect(gadget);
408 } 408 }
409 409
410 return 0; 410 return 0;
411 } 411 }
412 412
413 void udc_disconnect(void) 413 void udc_disconnect(void)
414 { 414 {
415 struct mv_udc *udc = controller.udc; 415 struct mv_udc *udc = (struct mv_udc *)controller.ctrl->hcor;
416 /* disable pullup */ 416 /* disable pullup */
417 stop_activity(); 417 stop_activity();
418 writel(USBCMD_FS2, &udc->usbcmd); 418 writel(USBCMD_FS2, &udc->usbcmd);
419 udelay(800); 419 udelay(800);
420 if (controller.driver) 420 if (controller.driver)
421 controller.driver->disconnect(&controller.gadget); 421 controller.driver->disconnect(&controller.gadget);
422 } 422 }
423 423
424 static int mvudc_probe(void) 424 static int mvudc_probe(void)
425 { 425 {
426 struct ept_queue_head *head; 426 struct ept_queue_head *head;
427 int i; 427 int i;
428 428
429 controller.gadget.ops = &mv_udc_ops; 429 controller.gadget.ops = &mv_udc_ops;
430 controller.udc = (struct mv_udc *)CONFIG_USB_REG_BASE;
431 epts = memalign(PAGE_SIZE, QH_MAXNUM * sizeof(struct ept_queue_head)); 430 epts = memalign(PAGE_SIZE, QH_MAXNUM * sizeof(struct ept_queue_head));
432 memset(epts, 0, QH_MAXNUM * sizeof(struct ept_queue_head)); 431 memset(epts, 0, QH_MAXNUM * sizeof(struct ept_queue_head));
433 for (i = 0; i < 2 * NUM_ENDPOINTS; i++) { 432 for (i = 0; i < 2 * NUM_ENDPOINTS; i++) {
434 /* 433 /*
435 * For item0 and item1, they are served as ep0 434 * For item0 and item1, they are served as ep0
436 * out&in seperately 435 * out&in seperately
437 */ 436 */
438 head = epts + i; 437 head = epts + i;
439 if (i < 2) 438 if (i < 2)
440 head->config = CONFIG_MAX_PKT(EP0_MAX_PACKET_SIZE) 439 head->config = CONFIG_MAX_PKT(EP0_MAX_PACKET_SIZE)
441 | CONFIG_ZLT | CONFIG_IOS; 440 | CONFIG_ZLT | CONFIG_IOS;
442 else 441 else
443 head->config = CONFIG_MAX_PKT(EP_MAX_PACKET_SIZE) 442 head->config = CONFIG_MAX_PKT(EP_MAX_PACKET_SIZE)
444 | CONFIG_ZLT; 443 | CONFIG_ZLT;
445 head->next = TERMINATE; 444 head->next = TERMINATE;
446 head->info = 0; 445 head->info = 0;
447 446
448 items[i] = memalign(PAGE_SIZE, sizeof(struct ept_queue_item)); 447 items[i] = memalign(PAGE_SIZE, sizeof(struct ept_queue_item));
449 } 448 }
450 449
451 INIT_LIST_HEAD(&controller.gadget.ep_list); 450 INIT_LIST_HEAD(&controller.gadget.ep_list);
452 451
453 /* Init EP 0 */ 452 /* Init EP 0 */
454 memcpy(&controller.ep[0].ep, &mv_ep_init[0], sizeof(*mv_ep_init)); 453 memcpy(&controller.ep[0].ep, &mv_ep_init[0], sizeof(*mv_ep_init));
455 controller.ep[0].desc = &ep0_in_desc; 454 controller.ep[0].desc = &ep0_in_desc;
456 controller.gadget.ep0 = &controller.ep[0].ep; 455 controller.gadget.ep0 = &controller.ep[0].ep;
457 INIT_LIST_HEAD(&controller.gadget.ep0->ep_list); 456 INIT_LIST_HEAD(&controller.gadget.ep0->ep_list);
458 457
459 /* Init EP 1..n */ 458 /* Init EP 1..n */
460 for (i = 1; i < NUM_ENDPOINTS; i++) { 459 for (i = 1; i < NUM_ENDPOINTS; i++) {
461 memcpy(&controller.ep[i].ep, &mv_ep_init[1], 460 memcpy(&controller.ep[i].ep, &mv_ep_init[1],
462 sizeof(*mv_ep_init)); 461 sizeof(*mv_ep_init));
463 list_add_tail(&controller.ep[i].ep.ep_list, 462 list_add_tail(&controller.ep[i].ep.ep_list,
464 &controller.gadget.ep_list); 463 &controller.gadget.ep_list);
465 } 464 }
466 465
467 return 0; 466 return 0;
468 } 467 }
469 468
470 int usb_gadget_register_driver(struct usb_gadget_driver *driver) 469 int usb_gadget_register_driver(struct usb_gadget_driver *driver)
471 { 470 {
472 struct mv_udc *udc = controller.udc; 471 struct mv_udc *udc;
473 int retval; 472 int ret;
474 void *ctrl;
475 473
476 if (!driver 474 if (!driver
477 || driver->speed < USB_SPEED_FULL 475 || driver->speed < USB_SPEED_FULL
478 || !driver->bind 476 || !driver->bind
479 || !driver->setup) { 477 || !driver->setup) {
480 DBG("bad parameter.\n"); 478 DBG("bad parameter.\n");
481 return -EINVAL; 479 return -EINVAL;
482 } 480 }
483 481
484 if (!mvudc_probe()) { 482 ret = usb_lowlevel_init(0, (void **)&controller.ctrl);
485 usb_lowlevel_init(0, &ctrl); 483 if (ret)
484 return ret;
485
486 ret = mvudc_probe();
487 if (!ret) {
488 udc = (struct mv_udc *)controller.ctrl->hcor;
489
486 /* select ULPI phy */ 490 /* select ULPI phy */
487 writel(PTS(PTS_ENABLE) | PFSC, &udc->portsc); 491 writel(PTS(PTS_ENABLE) | PFSC, &udc->portsc);
488 } 492 }
489 retval = driver->bind(&controller.gadget); 493
490 if (retval) { 494 ret = driver->bind(&controller.gadget);
491 DBG("driver->bind() returned %d\n", retval); 495 if (ret) {
492 return retval; 496 DBG("driver->bind() returned %d\n", ret);
497 return ret;
493 } 498 }
494 controller.driver = driver; 499 controller.driver = driver;
495 500
496 return 0; 501 return 0;
497 } 502 }
498 503
499 int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) 504 int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
500 { 505 {
501 return 0; 506 return 0;
include/usb/mv_udc.h
1 /* 1 /*
2 * Copyright 2011, Marvell Semiconductor Inc. 2 * Copyright 2011, Marvell Semiconductor Inc.
3 * Lei Wen <leiwen@marvell.com> 3 * Lei Wen <leiwen@marvell.com>
4 * 4 *
5 * SPDX-License-Identifier: GPL-2.0+ 5 * SPDX-License-Identifier: GPL-2.0+
6 */ 6 */
7 7
8 8
9 #ifndef __MV_UDC_H__ 9 #ifndef __MV_UDC_H__
10 #define __MV_UDC_H__ 10 #define __MV_UDC_H__
11 11
12 #include <asm/byteorder.h> 12 #include <asm/byteorder.h>
13 #include <asm/errno.h> 13 #include <asm/errno.h>
14 #include <linux/usb/ch9.h> 14 #include <linux/usb/ch9.h>
15 #include <linux/usb/gadget.h> 15 #include <linux/usb/gadget.h>
16 16
17 #include "../../drivers/usb/host/ehci.h"
18
17 #define NUM_ENDPOINTS 6 19 #define NUM_ENDPOINTS 6
18 20
19 /* Endpoint parameters */ 21 /* Endpoint parameters */
20 #define MAX_ENDPOINTS 4 22 #define MAX_ENDPOINTS 4
21 23
22 #define EP_MAX_PACKET_SIZE 0x200 24 #define EP_MAX_PACKET_SIZE 0x200
23 #define EP0_MAX_PACKET_SIZE 64 25 #define EP0_MAX_PACKET_SIZE 64
24 26
25 struct mv_udc { 27 struct mv_udc {
26 u32 pad0[80];
27 #define MICRO_8FRAME 0x8 28 #define MICRO_8FRAME 0x8
28 #define USBCMD_ITC(x) ((((x) > 0xff) ? 0xff : x) << 16) 29 #define USBCMD_ITC(x) ((((x) > 0xff) ? 0xff : x) << 16)
29 #define USBCMD_FS2 (1 << 15) 30 #define USBCMD_FS2 (1 << 15)
30 #define USBCMD_RST (1 << 1) 31 #define USBCMD_RST (1 << 1)
31 #define USBCMD_RUN (1) 32 #define USBCMD_RUN (1)
32 u32 usbcmd; /* 0x140 */ 33 u32 usbcmd; /* 0x140 */
33 #define STS_SLI (1 << 8) 34 #define STS_SLI (1 << 8)
34 #define STS_URI (1 << 6) 35 #define STS_URI (1 << 6)
35 #define STS_PCI (1 << 2) 36 #define STS_PCI (1 << 2)
36 #define STS_UEI (1 << 1) 37 #define STS_UEI (1 << 1)
37 #define STS_UI (1 << 0) 38 #define STS_UI (1 << 0)
38 u32 usbsts; /* 0x144 */ 39 u32 usbsts; /* 0x144 */
39 u32 pad1[3]; 40 u32 pad1[3];
40 u32 devaddr; /* 0x154 */ 41 u32 devaddr; /* 0x154 */
41 u32 epinitaddr; /* 0x158 */ 42 u32 epinitaddr; /* 0x158 */
42 u32 pad2[10]; 43 u32 pad2[10];
43 #define PTS_ENABLE 2 44 #define PTS_ENABLE 2
44 #define PTS(x) (((x) & 0x3) << 30) 45 #define PTS(x) (((x) & 0x3) << 30)
45 #define PFSC (1 << 24) 46 #define PFSC (1 << 24)
46 u32 portsc; /* 0x184 */ 47 u32 portsc; /* 0x184 */
47 u32 pad3[8]; 48 u32 pad3[8];
48 #define USBMODE_DEVICE 2 49 #define USBMODE_DEVICE 2
49 u32 usbmode; /* 0x1a8 */ 50 u32 usbmode; /* 0x1a8 */
50 u32 epstat; /* 0x1ac */ 51 u32 epstat; /* 0x1ac */
51 #define EPT_TX(x) (1 << (((x) & 0xffff) + 16)) 52 #define EPT_TX(x) (1 << (((x) & 0xffff) + 16))
52 #define EPT_RX(x) (1 << ((x) & 0xffff)) 53 #define EPT_RX(x) (1 << ((x) & 0xffff))
53 u32 epprime; /* 0x1b0 */ 54 u32 epprime; /* 0x1b0 */
54 u32 epflush; /* 0x1b4 */ 55 u32 epflush; /* 0x1b4 */
55 u32 pad4; 56 u32 pad4;
56 u32 epcomp; /* 0x1bc */ 57 u32 epcomp; /* 0x1bc */
57 #define CTRL_TXE (1 << 23) 58 #define CTRL_TXE (1 << 23)
58 #define CTRL_TXR (1 << 22) 59 #define CTRL_TXR (1 << 22)
59 #define CTRL_RXE (1 << 7) 60 #define CTRL_RXE (1 << 7)
60 #define CTRL_RXR (1 << 6) 61 #define CTRL_RXR (1 << 6)
61 #define CTRL_TXT_BULK (2 << 18) 62 #define CTRL_TXT_BULK (2 << 18)
62 #define CTRL_RXT_BULK (2 << 2) 63 #define CTRL_RXT_BULK (2 << 2)
63 u32 epctrl[16]; /* 0x1c0 */ 64 u32 epctrl[16]; /* 0x1c0 */
64 }; 65 };
65 66
66 struct mv_ep { 67 struct mv_ep {
67 struct usb_ep ep; 68 struct usb_ep ep;
68 struct usb_request req; 69 struct usb_request req;
69 struct list_head queue; 70 struct list_head queue;
70 const struct usb_endpoint_descriptor *desc; 71 const struct usb_endpoint_descriptor *desc;
71 }; 72 };
72 73
73 struct mv_drv { 74 struct mv_drv {
74 struct usb_gadget gadget; 75 struct usb_gadget gadget;
75 struct usb_gadget_driver *driver; 76 struct usb_gadget_driver *driver;
76 struct mv_udc *udc; 77 struct ehci_ctrl *ctrl;
77 struct mv_ep ep[NUM_ENDPOINTS]; 78 struct mv_ep ep[NUM_ENDPOINTS];
78 }; 79 };
79 80
80 struct ept_queue_head { 81 struct ept_queue_head {
81 unsigned config; 82 unsigned config;
82 unsigned current; /* read-only */ 83 unsigned current; /* read-only */
83 84
84 unsigned next; 85 unsigned next;
85 unsigned info; 86 unsigned info;
86 unsigned page0; 87 unsigned page0;
87 unsigned page1; 88 unsigned page1;
88 unsigned page2; 89 unsigned page2;
89 unsigned page3; 90 unsigned page3;
90 unsigned page4; 91 unsigned page4;
91 unsigned reserved_0; 92 unsigned reserved_0;
92 93
93 unsigned char setup_data[8]; 94 unsigned char setup_data[8];
94 95
95 unsigned reserved_1; 96 unsigned reserved_1;
96 unsigned reserved_2; 97 unsigned reserved_2;
97 unsigned reserved_3; 98 unsigned reserved_3;
98 unsigned reserved_4; 99 unsigned reserved_4;
99 }; 100 };
100 101
101 #define CONFIG_MAX_PKT(n) ((n) << 16) 102 #define CONFIG_MAX_PKT(n) ((n) << 16)
102 #define CONFIG_ZLT (1 << 29) /* stop on zero-len xfer */ 103 #define CONFIG_ZLT (1 << 29) /* stop on zero-len xfer */
103 #define CONFIG_IOS (1 << 15) /* IRQ on setup */ 104 #define CONFIG_IOS (1 << 15) /* IRQ on setup */
104 105
105 struct ept_queue_item { 106 struct ept_queue_item {
106 unsigned next; 107 unsigned next;
107 unsigned info; 108 unsigned info;
108 unsigned page0; 109 unsigned page0;
109 unsigned page1; 110 unsigned page1;
110 unsigned page2; 111 unsigned page2;
111 unsigned page3; 112 unsigned page3;
112 unsigned page4; 113 unsigned page4;
113 unsigned reserved; 114 unsigned reserved;
114 }; 115 };
115 116
116 #define TERMINATE 1 117 #define TERMINATE 1
117 #define INFO_BYTES(n) ((n) << 16) 118 #define INFO_BYTES(n) ((n) << 16)
118 #define INFO_IOC (1 << 15) 119 #define INFO_IOC (1 << 15)
119 #define INFO_ACTIVE (1 << 7) 120 #define INFO_ACTIVE (1 << 7)
120 #define INFO_HALTED (1 << 6) 121 #define INFO_HALTED (1 << 6)
121 #define INFO_BUFFER_ERROR (1 << 5) 122 #define INFO_BUFFER_ERROR (1 << 5)
122 #define INFO_TX_ERROR (1 << 3) 123 #define INFO_TX_ERROR (1 << 3)
123 124
124 extern int usb_lowlevel_init(int index, void **controller);