This source file includes following definitions.
- ast_vhub_reply
- __ast_vhub_simple_reply
- ast_vhub_ep0_handle_setup
- ast_vhub_ep0_do_send
- ast_vhub_ep0_rx_prime
- ast_vhub_ep0_do_receive
- ast_vhub_ep0_handle_ack
- ast_vhub_ep0_queue
- ast_vhub_ep0_dequeue
- ast_vhub_reset_ep0
- ast_vhub_init_ep0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/platform_device.h>
18 #include <linux/delay.h>
19 #include <linux/ioport.h>
20 #include <linux/slab.h>
21 #include <linux/errno.h>
22 #include <linux/list.h>
23 #include <linux/interrupt.h>
24 #include <linux/proc_fs.h>
25 #include <linux/prefetch.h>
26 #include <linux/clk.h>
27 #include <linux/usb/gadget.h>
28 #include <linux/of.h>
29 #include <linux/of_gpio.h>
30 #include <linux/regmap.h>
31 #include <linux/dma-mapping.h>
32
33 #include "vhub.h"
34
35 int ast_vhub_reply(struct ast_vhub_ep *ep, char *ptr, int len)
36 {
37 struct usb_request *req = &ep->ep0.req.req;
38 int rc;
39
40 if (WARN_ON(ep->d_idx != 0))
41 return std_req_stall;
42 if (WARN_ON(!ep->ep0.dir_in))
43 return std_req_stall;
44 if (WARN_ON(len > AST_VHUB_EP0_MAX_PACKET))
45 return std_req_stall;
46 if (WARN_ON(req->status == -EINPROGRESS))
47 return std_req_stall;
48
49 req->buf = ptr;
50 req->length = len;
51 req->complete = NULL;
52 req->zero = true;
53
54
55
56
57
58
59 spin_unlock(&ep->vhub->lock);
60 if (ep->ep.ops->queue(&ep->ep, req, GFP_ATOMIC))
61 rc = std_req_stall;
62 else
63 rc = std_req_data;
64 spin_lock(&ep->vhub->lock);
65 return rc;
66 }
67
68 int __ast_vhub_simple_reply(struct ast_vhub_ep *ep, int len, ...)
69 {
70 u8 *buffer = ep->buf;
71 unsigned int i;
72 va_list args;
73
74 va_start(args, len);
75
76
77 for (i = 0; i < len; i++)
78 buffer[i] = va_arg(args, int);
79 va_end(args);
80
81
82 return ast_vhub_reply(ep, NULL, len);
83 }
84
85 void ast_vhub_ep0_handle_setup(struct ast_vhub_ep *ep)
86 {
87 struct usb_ctrlrequest crq;
88 enum std_req_rc std_req_rc;
89 int rc = -ENODEV;
90
91 if (WARN_ON(ep->d_idx != 0))
92 return;
93
94
95
96
97
98 memcpy_fromio(&crq, ep->ep0.setup, sizeof(crq));
99
100 EPDBG(ep, "SETUP packet %02x/%02x/%04x/%04x/%04x [%s] st=%d\n",
101 crq.bRequestType, crq.bRequest,
102 le16_to_cpu(crq.wValue),
103 le16_to_cpu(crq.wIndex),
104 le16_to_cpu(crq.wLength),
105 (crq.bRequestType & USB_DIR_IN) ? "in" : "out",
106 ep->ep0.state);
107
108
109
110
111
112
113
114
115
116
117
118 if (ep->ep0.state != ep0_state_token &&
119 ep->ep0.state != ep0_state_stall) {
120 EPDBG(ep, "wrong state\n");
121 ast_vhub_nuke(ep, -EIO);
122 }
123
124
125 ep->ep0.state = ep0_state_data;
126 ep->ep0.dir_in = !!(crq.bRequestType & USB_DIR_IN);
127
128
129 std_req_rc = std_req_driver;
130 if (ep->dev == NULL) {
131 if ((crq.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
132 std_req_rc = ast_vhub_std_hub_request(ep, &crq);
133 else if ((crq.bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS)
134 std_req_rc = ast_vhub_class_hub_request(ep, &crq);
135 else
136 std_req_rc = std_req_stall;
137 } else if ((crq.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
138 std_req_rc = ast_vhub_std_dev_request(ep, &crq);
139
140
141 switch(std_req_rc) {
142 case std_req_complete:
143 goto complete;
144 case std_req_stall:
145 goto stall;
146 case std_req_driver:
147 break;
148 case std_req_data:
149 return;
150 }
151
152
153 if (WARN_ON(!ep->dev))
154 goto stall;
155 if (ep->dev->driver) {
156 EPDBG(ep, "forwarding to gadget...\n");
157 spin_unlock(&ep->vhub->lock);
158 rc = ep->dev->driver->setup(&ep->dev->gadget, &crq);
159 spin_lock(&ep->vhub->lock);
160 EPDBG(ep, "driver returned %d\n", rc);
161 } else {
162 EPDBG(ep, "no gadget for request !\n");
163 }
164 if (rc >= 0)
165 return;
166
167 stall:
168 EPDBG(ep, "stalling\n");
169 writel(VHUB_EP0_CTRL_STALL, ep->ep0.ctlstat);
170 ep->ep0.state = ep0_state_stall;
171 ep->ep0.dir_in = false;
172 return;
173
174 complete:
175 EPVDBG(ep, "sending [in] status with no data\n");
176 writel(VHUB_EP0_TX_BUFF_RDY, ep->ep0.ctlstat);
177 ep->ep0.state = ep0_state_status;
178 ep->ep0.dir_in = false;
179 }
180
181
182 static void ast_vhub_ep0_do_send(struct ast_vhub_ep *ep,
183 struct ast_vhub_req *req)
184 {
185 unsigned int chunk;
186 u32 reg;
187
188
189
190
191 if (req->req.length == 0)
192 req->last_desc = 1;
193
194
195 if (req->last_desc >= 0) {
196 EPVDBG(ep, "complete send %d/%d\n",
197 req->req.actual, req->req.length);
198 ep->ep0.state = ep0_state_status;
199 writel(VHUB_EP0_RX_BUFF_RDY, ep->ep0.ctlstat);
200 ast_vhub_done(ep, req, 0);
201 return;
202 }
203
204
205
206
207
208 chunk = req->req.length - req->req.actual;
209 if (chunk > ep->ep.maxpacket)
210 chunk = ep->ep.maxpacket;
211 else if ((chunk < ep->ep.maxpacket) || !req->req.zero)
212 req->last_desc = 1;
213
214 EPVDBG(ep, "send chunk=%d last=%d, req->act=%d mp=%d\n",
215 chunk, req->last_desc, req->req.actual, ep->ep.maxpacket);
216
217
218
219
220
221 if (chunk && req->req.buf)
222 memcpy(ep->buf, req->req.buf + req->req.actual, chunk);
223
224 vhub_dma_workaround(ep->buf);
225
226
227 reg = VHUB_EP0_SET_TX_LEN(chunk);
228 writel(reg, ep->ep0.ctlstat);
229 writel(reg | VHUB_EP0_TX_BUFF_RDY, ep->ep0.ctlstat);
230 req->req.actual += chunk;
231 }
232
233 static void ast_vhub_ep0_rx_prime(struct ast_vhub_ep *ep)
234 {
235 EPVDBG(ep, "rx prime\n");
236
237
238 writel(VHUB_EP0_RX_BUFF_RDY, ep->ep0.ctlstat);
239 }
240
241 static void ast_vhub_ep0_do_receive(struct ast_vhub_ep *ep, struct ast_vhub_req *req,
242 unsigned int len)
243 {
244 unsigned int remain;
245 int rc = 0;
246
247
248 remain = req->req.length - req->req.actual;
249
250 EPVDBG(ep, "receive got=%d remain=%d\n", len, remain);
251
252
253 if (len > remain) {
254 EPDBG(ep, "receiving too much (ovf: %d) !\n",
255 len - remain);
256 len = remain;
257 rc = -EOVERFLOW;
258 }
259 if (len && req->req.buf)
260 memcpy(req->req.buf + req->req.actual, ep->buf, len);
261 req->req.actual += len;
262
263
264 if (len < ep->ep.maxpacket || len == remain) {
265 ep->ep0.state = ep0_state_status;
266 writel(VHUB_EP0_TX_BUFF_RDY, ep->ep0.ctlstat);
267 ast_vhub_done(ep, req, rc);
268 } else
269 ast_vhub_ep0_rx_prime(ep);
270 }
271
272 void ast_vhub_ep0_handle_ack(struct ast_vhub_ep *ep, bool in_ack)
273 {
274 struct ast_vhub_req *req;
275 struct ast_vhub *vhub = ep->vhub;
276 struct device *dev = &vhub->pdev->dev;
277 bool stall = false;
278 u32 stat;
279
280
281 stat = readl(ep->ep0.ctlstat);
282
283
284 req = list_first_entry_or_null(&ep->queue, struct ast_vhub_req, queue);
285
286 EPVDBG(ep, "ACK status=%08x,state=%d is_in=%d in_ack=%d req=%p\n",
287 stat, ep->ep0.state, ep->ep0.dir_in, in_ack, req);
288
289 switch(ep->ep0.state) {
290 case ep0_state_token:
291
292 if (req) {
293 dev_warn(dev, "request present while in TOKEN state\n");
294 ast_vhub_nuke(ep, -EINVAL);
295 }
296 dev_warn(dev, "ack while in TOKEN state\n");
297 stall = true;
298 break;
299 case ep0_state_data:
300
301 if ((ep->ep0.dir_in && (stat & VHUB_EP0_TX_BUFF_RDY)) ||
302 (!ep->ep0.dir_in && (stat & VHUB_EP0_RX_BUFF_RDY)) ||
303 (ep->ep0.dir_in != in_ack)) {
304
305 dev_warn(dev, "irq state mismatch");
306 break;
307 }
308
309
310
311
312 if (!req) {
313 dev_warn(dev, "data phase, no request\n");
314 stall = true;
315 break;
316 }
317
318
319 if (ep->ep0.dir_in)
320 ast_vhub_ep0_do_send(ep, req);
321 else
322 ast_vhub_ep0_do_receive(ep, req, VHUB_EP0_RX_LEN(stat));
323 return;
324 case ep0_state_status:
325
326 if (req) {
327 dev_warn(dev, "request present while in STATUS state\n");
328 ast_vhub_nuke(ep, -EINVAL);
329 }
330
331
332
333
334
335
336 if (ep->ep0.dir_in == in_ack) {
337 dev_warn(dev, "status direction mismatch\n");
338 stall = true;
339 }
340 break;
341 case ep0_state_stall:
342
343
344
345
346 ast_vhub_nuke(ep, -EIO);
347 break;
348 }
349
350
351 if (stall) {
352 writel(VHUB_EP0_CTRL_STALL, ep->ep0.ctlstat);
353 ep->ep0.state = ep0_state_stall;
354 } else
355 ep->ep0.state = ep0_state_token;
356 }
357
358 static int ast_vhub_ep0_queue(struct usb_ep* u_ep, struct usb_request *u_req,
359 gfp_t gfp_flags)
360 {
361 struct ast_vhub_req *req = to_ast_req(u_req);
362 struct ast_vhub_ep *ep = to_ast_ep(u_ep);
363 struct ast_vhub *vhub = ep->vhub;
364 struct device *dev = &vhub->pdev->dev;
365 unsigned long flags;
366
367
368 if (!u_req || (!u_req->complete && !req->internal)) {
369 dev_warn(dev, "Bogus EP0 request ! u_req=%p\n", u_req);
370 if (u_req) {
371 dev_warn(dev, "complete=%p internal=%d\n",
372 u_req->complete, req->internal);
373 }
374 return -EINVAL;
375 }
376
377
378 if (WARN_ON(ep->d_idx != 0))
379 return -EINVAL;
380
381
382 if (ep->dev && !ep->dev->enabled)
383 return -ESHUTDOWN;
384
385
386 if (u_req->length && !u_req->buf && !req->internal) {
387 dev_warn(dev, "Request with no buffer !\n");
388 return -EINVAL;
389 }
390
391 EPVDBG(ep, "enqueue req @%p\n", req);
392 EPVDBG(ep, " l=%d zero=%d noshort=%d is_in=%d\n",
393 u_req->length, u_req->zero,
394 u_req->short_not_ok, ep->ep0.dir_in);
395
396
397 u_req->status = -EINPROGRESS;
398 u_req->actual = 0;
399 req->last_desc = -1;
400 req->active = false;
401
402 spin_lock_irqsave(&vhub->lock, flags);
403
404
405 if (!list_empty(&ep->queue) ||
406 ep->ep0.state == ep0_state_token ||
407 ep->ep0.state == ep0_state_stall) {
408 dev_warn(dev, "EP0: Request in wrong state\n");
409 EPVDBG(ep, "EP0: list_empty=%d state=%d\n",
410 list_empty(&ep->queue), ep->ep0.state);
411 spin_unlock_irqrestore(&vhub->lock, flags);
412 return -EBUSY;
413 }
414
415
416 list_add_tail(&req->queue, &ep->queue);
417
418 if (ep->ep0.dir_in) {
419
420 ast_vhub_ep0_do_send(ep, req);
421 } else if (u_req->length == 0) {
422
423 EPVDBG(ep, "0-length rx completion\n");
424 ep->ep0.state = ep0_state_status;
425 writel(VHUB_EP0_TX_BUFF_RDY, ep->ep0.ctlstat);
426 ast_vhub_done(ep, req, 0);
427 } else {
428
429 ast_vhub_ep0_rx_prime(ep);
430 }
431
432 spin_unlock_irqrestore(&vhub->lock, flags);
433
434 return 0;
435 }
436
437 static int ast_vhub_ep0_dequeue(struct usb_ep* u_ep, struct usb_request *u_req)
438 {
439 struct ast_vhub_ep *ep = to_ast_ep(u_ep);
440 struct ast_vhub *vhub = ep->vhub;
441 struct ast_vhub_req *req;
442 unsigned long flags;
443 int rc = -EINVAL;
444
445 spin_lock_irqsave(&vhub->lock, flags);
446
447
448 req = list_first_entry_or_null(&ep->queue, struct ast_vhub_req, queue);
449
450
451 if (req && u_req == &req->req) {
452 EPVDBG(ep, "dequeue req @%p\n", req);
453
454
455
456
457
458 ast_vhub_done(ep, req, -ECONNRESET);
459
460
461 writel(VHUB_EP0_CTRL_STALL, ep->ep0.ctlstat);
462 ep->ep0.state = ep0_state_status;
463 ep->ep0.dir_in = false;
464 rc = 0;
465 }
466 spin_unlock_irqrestore(&vhub->lock, flags);
467 return rc;
468 }
469
470
471 static const struct usb_ep_ops ast_vhub_ep0_ops = {
472 .queue = ast_vhub_ep0_queue,
473 .dequeue = ast_vhub_ep0_dequeue,
474 .alloc_request = ast_vhub_alloc_request,
475 .free_request = ast_vhub_free_request,
476 };
477
478 void ast_vhub_reset_ep0(struct ast_vhub_dev *dev)
479 {
480 struct ast_vhub_ep *ep = &dev->ep0;
481
482 ast_vhub_nuke(ep, -EIO);
483 ep->ep0.state = ep0_state_token;
484 }
485
486
487 void ast_vhub_init_ep0(struct ast_vhub *vhub, struct ast_vhub_ep *ep,
488 struct ast_vhub_dev *dev)
489 {
490 memset(ep, 0, sizeof(*ep));
491
492 INIT_LIST_HEAD(&ep->ep.ep_list);
493 INIT_LIST_HEAD(&ep->queue);
494 ep->ep.ops = &ast_vhub_ep0_ops;
495 ep->ep.name = "ep0";
496 ep->ep.caps.type_control = true;
497 usb_ep_set_maxpacket_limit(&ep->ep, AST_VHUB_EP0_MAX_PACKET);
498 ep->d_idx = 0;
499 ep->dev = dev;
500 ep->vhub = vhub;
501 ep->ep0.state = ep0_state_token;
502 INIT_LIST_HEAD(&ep->ep0.req.queue);
503 ep->ep0.req.internal = true;
504
505
506 if (dev) {
507 ep->ep0.ctlstat = dev->regs + AST_VHUB_DEV_EP0_CTRL;
508 ep->ep0.setup = vhub->regs +
509 AST_VHUB_SETUP0 + 8 * (dev->index + 1);
510 ep->buf = vhub->ep0_bufs +
511 AST_VHUB_EP0_MAX_PACKET * (dev->index + 1);
512 ep->buf_dma = vhub->ep0_bufs_dma +
513 AST_VHUB_EP0_MAX_PACKET * (dev->index + 1);
514 } else {
515 ep->ep0.ctlstat = vhub->regs + AST_VHUB_EP0_CTRL;
516 ep->ep0.setup = vhub->regs + AST_VHUB_SETUP0;
517 ep->buf = vhub->ep0_bufs;
518 ep->buf_dma = vhub->ep0_bufs_dma;
519 }
520 }