blob: 4e2c2babad20f2588877a70f2db3593d5e5d8c49 [file] [log] [blame]
Chunfeng Yundf2069a2016-10-19 10:28:23 +08001/*
2 * mtu3_gadget_ep0.c - MediaTek USB3 DRD peripheral driver ep0 handling
3 *
4 * Copyright (c) 2016 MediaTek Inc.
5 *
6 * Author: Chunfeng.Yun <chunfeng.yun@mediatek.com>
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include "mtu3.h"
20
21/* ep0 is always mtu3->in_eps[0] */
22#define next_ep0_request(mtu) next_request((mtu)->ep0)
23
24/* for high speed test mode; see USB 2.0 spec 7.1.20 */
25static const u8 mtu3_test_packet[53] = {
26 /* implicit SYNC then DATA0 to start */
27
28 /* JKJKJKJK x9 */
29 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
30 /* JJKKJJKK x8 */
31 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
32 /* JJJJKKKK x8 */
33 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
34 /* JJJJJJJKKKKKKK x8 */
35 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
36 /* JJJJJJJK x8 */
37 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd,
38 /* JKKKKKKK x10, JK */
39 0xfc, 0x7e, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0x7e,
40 /* implicit CRC16 then EOP to end */
41};
42
43static char *decode_ep0_state(struct mtu3 *mtu)
44{
45 switch (mtu->ep0_state) {
46 case MU3D_EP0_STATE_SETUP:
47 return "SETUP";
48 case MU3D_EP0_STATE_TX:
49 return "IN";
50 case MU3D_EP0_STATE_RX:
51 return "OUT";
52 case MU3D_EP0_STATE_TX_END:
53 return "TX-END";
54 case MU3D_EP0_STATE_STALL:
55 return "STALL";
56 default:
57 return "??";
58 }
59}
60
61static void ep0_req_giveback(struct mtu3 *mtu, struct usb_request *req)
62{
63 mtu3_req_complete(mtu->ep0, req, 0);
64}
65
66static int
67forward_to_driver(struct mtu3 *mtu, const struct usb_ctrlrequest *setup)
68__releases(mtu->lock)
69__acquires(mtu->lock)
70{
71 int ret;
72
73 if (!mtu->gadget_driver)
74 return -EOPNOTSUPP;
75
76 spin_unlock(&mtu->lock);
77 ret = mtu->gadget_driver->setup(&mtu->g, setup);
78 spin_lock(&mtu->lock);
79
80 dev_dbg(mtu->dev, "%s ret %d\n", __func__, ret);
81 return ret;
82}
83
84static void ep0_write_fifo(struct mtu3_ep *mep, const u8 *src, u16 len)
85{
86 void __iomem *fifo = mep->mtu->mac_base + U3D_FIFO0;
87 u16 index = 0;
88
89 dev_dbg(mep->mtu->dev, "%s: ep%din, len=%d, buf=%p\n",
90 __func__, mep->epnum, len, src);
91
92 if (len >= 4) {
93 iowrite32_rep(fifo, src, len >> 2);
94 index = len & ~0x03;
95 }
96 if (len & 0x02) {
97 writew(*(u16 *)&src[index], fifo);
98 index += 2;
99 }
100 if (len & 0x01)
101 writeb(src[index], fifo);
102}
103
104static void ep0_read_fifo(struct mtu3_ep *mep, u8 *dst, u16 len)
105{
106 void __iomem *fifo = mep->mtu->mac_base + U3D_FIFO0;
107 u32 value;
108 u16 index = 0;
109
110 dev_dbg(mep->mtu->dev, "%s: ep%dout len=%d buf=%p\n",
111 __func__, mep->epnum, len, dst);
112
113 if (len >= 4) {
114 ioread32_rep(fifo, dst, len >> 2);
115 index = len & ~0x03;
116 }
117 if (len & 0x3) {
118 value = readl(fifo);
119 memcpy(&dst[index], &value, len & 0x3);
120 }
121
122}
123
124static void ep0_load_test_packet(struct mtu3 *mtu)
125{
126 /*
127 * because the length of test packet is less than max packet of HS ep0,
128 * write it into fifo directly.
129 */
130 ep0_write_fifo(mtu->ep0, mtu3_test_packet, sizeof(mtu3_test_packet));
131}
132
133/*
134 * A. send STALL for setup transfer without data stage:
135 * set SENDSTALL and SETUPPKTRDY at the same time;
136 * B. send STALL for other cases:
137 * set SENDSTALL only.
138 */
139static void ep0_stall_set(struct mtu3_ep *mep0, bool set, u32 pktrdy)
140{
141 struct mtu3 *mtu = mep0->mtu;
142 void __iomem *mbase = mtu->mac_base;
143 u32 csr;
144
145 /* EP0_SENTSTALL is W1C */
146 csr = mtu3_readl(mbase, U3D_EP0CSR) & EP0_W1C_BITS;
147 if (set)
148 csr |= EP0_SENDSTALL | pktrdy;
149 else
150 csr = (csr & ~EP0_SENDSTALL) | EP0_SENTSTALL;
151 mtu3_writel(mtu->mac_base, U3D_EP0CSR, csr);
152
153 mtu->ep0_state = MU3D_EP0_STATE_SETUP;
154
155 dev_dbg(mtu->dev, "ep0: %s STALL, ep0_state: %s\n",
156 set ? "SEND" : "CLEAR", decode_ep0_state(mtu));
157}
158
159static int ep0_queue(struct mtu3_ep *mep0, struct mtu3_request *mreq);
160
161static void ep0_dummy_complete(struct usb_ep *ep, struct usb_request *req)
162{}
163
164static int
165ep0_get_status(struct mtu3 *mtu, const struct usb_ctrlrequest *setup)
166{
167 struct mtu3_ep *mep = NULL;
168 int handled = 1;
169 u8 result[2] = {0, 0};
170 u8 epnum = 0;
171 int is_in;
172
173 switch (setup->bRequestType & USB_RECIP_MASK) {
174 case USB_RECIP_DEVICE:
175 result[0] = mtu->is_self_powered << USB_DEVICE_SELF_POWERED;
176 result[0] |= mtu->may_wakeup << USB_DEVICE_REMOTE_WAKEUP;
177 break;
178 case USB_RECIP_INTERFACE:
179 break;
180 case USB_RECIP_ENDPOINT:
181 epnum = (u8) le16_to_cpu(setup->wIndex);
182 is_in = epnum & USB_DIR_IN;
183 epnum &= USB_ENDPOINT_NUMBER_MASK;
184
185 if (epnum >= mtu->num_eps) {
186 handled = -EINVAL;
187 break;
188 }
189 if (!epnum)
190 break;
191
192 mep = (is_in ? mtu->in_eps : mtu->out_eps) + epnum;
193 if (!mep->desc) {
194 handled = -EINVAL;
195 break;
196 }
197 if (mep->flags & MTU3_EP_STALL)
198 result[0] |= 1 << USB_ENDPOINT_HALT;
199
200 break;
201 default:
202 /* class, vendor, etc ... delegate */
203 handled = 0;
204 break;
205 }
206
207 if (handled > 0) {
208 int ret;
209
210 /* prepare a data stage for GET_STATUS */
211 dev_dbg(mtu->dev, "get_status=%x\n", *(u16 *)result);
212 memcpy(mtu->setup_buf, result, sizeof(result));
213 mtu->ep0_req.mep = mtu->ep0;
214 mtu->ep0_req.request.length = 2;
215 mtu->ep0_req.request.buf = &mtu->setup_buf;
216 mtu->ep0_req.request.complete = ep0_dummy_complete;
217 ret = ep0_queue(mtu->ep0, &mtu->ep0_req);
218 if (ret < 0)
219 handled = ret;
220 }
221 return handled;
222}
223
224static int handle_test_mode(struct mtu3 *mtu, struct usb_ctrlrequest *setup)
225{
226 void __iomem *mbase = mtu->mac_base;
227 int handled = 1;
228
229 switch (le16_to_cpu(setup->wIndex) >> 8) {
230 case TEST_J:
231 dev_dbg(mtu->dev, "TEST_J\n");
232 mtu->test_mode_nr = TEST_J_MODE;
233 break;
234 case TEST_K:
235 dev_dbg(mtu->dev, "TEST_K\n");
236 mtu->test_mode_nr = TEST_K_MODE;
237 break;
238 case TEST_SE0_NAK:
239 dev_dbg(mtu->dev, "TEST_SE0_NAK\n");
240 mtu->test_mode_nr = TEST_SE0_NAK_MODE;
241 break;
242 case TEST_PACKET:
243 dev_dbg(mtu->dev, "TEST_PACKET\n");
244 mtu->test_mode_nr = TEST_PACKET_MODE;
245 break;
246 default:
247 handled = -EINVAL;
248 goto out;
249 }
250
251 mtu->test_mode = true;
252
253 /* no TX completion interrupt, and need restart platform after test */
254 if (mtu->test_mode_nr == TEST_PACKET_MODE)
255 ep0_load_test_packet(mtu);
256
257 mtu3_writel(mbase, U3D_USB2_TEST_MODE, mtu->test_mode_nr);
258
259 mtu->ep0_state = MU3D_EP0_STATE_SETUP;
260
261out:
262 return handled;
263}
264
265static int ep0_handle_feature_dev(struct mtu3 *mtu,
266 struct usb_ctrlrequest *setup, bool set)
267{
268 int handled = -EINVAL;
269
270 switch (le16_to_cpu(setup->wValue)) {
271 case USB_DEVICE_REMOTE_WAKEUP:
272 mtu->may_wakeup = !!set;
273 handled = 1;
274 break;
275 case USB_DEVICE_TEST_MODE:
276 if (!set || (mtu->g.speed != USB_SPEED_HIGH) ||
277 (le16_to_cpu(setup->wIndex) & 0xff))
278 break;
279
280 handled = handle_test_mode(mtu, setup);
281 break;
282 default:
283 handled = -EINVAL;
284 break;
285 }
286 return handled;
287}
288
289static int ep0_handle_feature(struct mtu3 *mtu,
290 struct usb_ctrlrequest *setup, bool set)
291{
292 struct mtu3_ep *mep;
293 int handled = -EINVAL;
294 int is_in;
295 u16 value;
296 u16 index;
297 u8 epnum;
298
299 value = le16_to_cpu(setup->wValue);
300 index = le16_to_cpu(setup->wIndex);
301
302 switch (setup->bRequestType & USB_RECIP_MASK) {
303 case USB_RECIP_DEVICE:
304 handled = ep0_handle_feature_dev(mtu, setup, set);
305 break;
306 case USB_RECIP_ENDPOINT:
307 epnum = index & USB_ENDPOINT_NUMBER_MASK;
308 if (epnum == 0 || epnum >= mtu->num_eps ||
309 value != USB_ENDPOINT_HALT)
310 break;
311
312 is_in = index & USB_DIR_IN;
313 mep = (is_in ? mtu->in_eps : mtu->out_eps) + epnum;
314 if (!mep->desc)
315 break;
316
317 handled = 1;
318 /* ignore request if endpoint is wedged */
319 if (mep->wedged)
320 break;
321
322 mtu3_ep_stall_set(mep, set);
323 break;
324 default:
325 /* class, vendor, etc ... delegate */
326 handled = 0;
327 break;
328 }
329 return handled;
330}
331
332/*
333 * handle all control requests can be handled
334 * returns:
335 * negative errno - error happened
336 * zero - need delegate SETUP to gadget driver
337 * positive - already handled
338 */
339static int handle_standard_request(struct mtu3 *mtu,
340 struct usb_ctrlrequest *setup)
341{
342 void __iomem *mbase = mtu->mac_base;
343 enum usb_device_state state = mtu->g.state;
344 int handled = -EINVAL;
345 u32 dev_conf;
346 u16 value;
347
348 value = le16_to_cpu(setup->wValue);
349
350 /* the gadget driver handles everything except what we must handle */
351 switch (setup->bRequest) {
352 case USB_REQ_SET_ADDRESS:
353 /* change it after the status stage */
354 mtu->address = (u8) (value & 0x7f);
355 dev_dbg(mtu->dev, "set address to 0x%x\n", mtu->address);
356
357 dev_conf = mtu3_readl(mbase, U3D_DEVICE_CONF);
358 dev_conf &= ~DEV_ADDR_MSK;
359 dev_conf |= DEV_ADDR(mtu->address);
360 mtu3_writel(mbase, U3D_DEVICE_CONF, dev_conf);
361
362 if (mtu->address)
363 usb_gadget_set_state(&mtu->g, USB_STATE_ADDRESS);
364 else
365 usb_gadget_set_state(&mtu->g, USB_STATE_DEFAULT);
366
367 handled = 1;
368 break;
369 case USB_REQ_SET_CONFIGURATION:
370 if (state == USB_STATE_ADDRESS) {
371 usb_gadget_set_state(&mtu->g,
372 USB_STATE_CONFIGURED);
373 } else if (state == USB_STATE_CONFIGURED) {
374 /*
375 * USB2 spec sec 9.4.7, if wValue is 0 then dev
376 * is moved to addressed state
377 */
378 if (!value)
379 usb_gadget_set_state(&mtu->g,
380 USB_STATE_ADDRESS);
381 }
382 handled = 0;
383 break;
384 case USB_REQ_CLEAR_FEATURE:
385 handled = ep0_handle_feature(mtu, setup, 0);
386 break;
387 case USB_REQ_SET_FEATURE:
388 handled = ep0_handle_feature(mtu, setup, 1);
389 break;
390 case USB_REQ_GET_STATUS:
391 handled = ep0_get_status(mtu, setup);
392 break;
393 case USB_REQ_SET_ISOCH_DELAY:
394 handled = 1;
395 break;
396 default:
397 /* delegate SET_CONFIGURATION, etc */
398 handled = 0;
399 }
400
401 return handled;
402}
403
404/* receive an data packet (OUT) */
405static void ep0_rx_state(struct mtu3 *mtu)
406{
407 struct mtu3_request *mreq;
408 struct usb_request *req;
409 void __iomem *mbase = mtu->mac_base;
410 u32 maxp;
411 u32 csr;
412 u16 count = 0;
413
414 dev_dbg(mtu->dev, "%s\n", __func__);
415
416 csr = mtu3_readl(mbase, U3D_EP0CSR) & EP0_W1C_BITS;
417 mreq = next_ep0_request(mtu);
418 req = &mreq->request;
419
420 /* read packet and ack; or stall because of gadget driver bug */
421 if (req) {
422 void *buf = req->buf + req->actual;
423 unsigned int len = req->length - req->actual;
424
425 /* read the buffer */
426 count = mtu3_readl(mbase, U3D_RXCOUNT0);
427 if (count > len) {
428 req->status = -EOVERFLOW;
429 count = len;
430 }
431 ep0_read_fifo(mtu->ep0, buf, count);
432 req->actual += count;
433 csr |= EP0_RXPKTRDY;
434
435 maxp = mtu->g.ep0->maxpacket;
436 if (count < maxp || req->actual == req->length) {
437 mtu->ep0_state = MU3D_EP0_STATE_SETUP;
438 dev_dbg(mtu->dev, "ep0 state: %s\n",
439 decode_ep0_state(mtu));
440
441 csr |= EP0_DATAEND;
442 } else {
443 req = NULL;
444 }
445 } else {
446 csr |= EP0_RXPKTRDY | EP0_SENDSTALL;
447 dev_dbg(mtu->dev, "%s: SENDSTALL\n", __func__);
448 }
449
450 mtu3_writel(mbase, U3D_EP0CSR, csr);
451
452 /* give back the request if have received all data */
453 if (req)
454 ep0_req_giveback(mtu, req);
455
456}
457
458/* transmitting to the host (IN) */
459static void ep0_tx_state(struct mtu3 *mtu)
460{
461 struct mtu3_request *mreq = next_ep0_request(mtu);
462 struct usb_request *req;
463 u32 csr;
464 u8 *src;
465 u8 count;
466 u32 maxp;
467
468 dev_dbg(mtu->dev, "%s\n", __func__);
469
470 if (!mreq)
471 return;
472
473 maxp = mtu->g.ep0->maxpacket;
474 req = &mreq->request;
475
476 /* load the data */
477 src = (u8 *)req->buf + req->actual;
478 count = min(maxp, req->length - req->actual);
479 if (count)
480 ep0_write_fifo(mtu->ep0, src, count);
481
482 dev_dbg(mtu->dev, "%s act=%d, len=%d, cnt=%d, maxp=%d zero=%d\n",
483 __func__, req->actual, req->length, count, maxp, req->zero);
484
485 req->actual += count;
486
487 if ((count < maxp)
488 || ((req->actual == req->length) && !req->zero))
489 mtu->ep0_state = MU3D_EP0_STATE_TX_END;
490
491 /* send it out, triggering a "txpktrdy cleared" irq */
492 csr = mtu3_readl(mtu->mac_base, U3D_EP0CSR) & EP0_W1C_BITS;
493 mtu3_writel(mtu->mac_base, U3D_EP0CSR, csr | EP0_TXPKTRDY);
494
495 dev_dbg(mtu->dev, "%s ep0csr=0x%x\n", __func__,
496 mtu3_readl(mtu->mac_base, U3D_EP0CSR));
497}
498
499static void ep0_read_setup(struct mtu3 *mtu, struct usb_ctrlrequest *setup)
500{
501 struct mtu3_request *mreq;
502 u32 count;
503 u32 csr;
504
505 csr = mtu3_readl(mtu->mac_base, U3D_EP0CSR) & EP0_W1C_BITS;
506 count = mtu3_readl(mtu->mac_base, U3D_RXCOUNT0);
507
508 ep0_read_fifo(mtu->ep0, (u8 *)setup, count);
509
510 dev_dbg(mtu->dev, "SETUP req%02x.%02x v%04x i%04x l%04x\n",
511 setup->bRequestType, setup->bRequest,
512 le16_to_cpu(setup->wValue), le16_to_cpu(setup->wIndex),
513 le16_to_cpu(setup->wLength));
514
515 /* clean up any leftover transfers */
516 mreq = next_ep0_request(mtu);
517 if (mreq)
518 ep0_req_giveback(mtu, &mreq->request);
519
520 if (le16_to_cpu(setup->wLength) == 0) {
521 ; /* no data stage, nothing to do */
522 } else if (setup->bRequestType & USB_DIR_IN) {
523 mtu3_writel(mtu->mac_base, U3D_EP0CSR,
524 csr | EP0_SETUPPKTRDY | EP0_DPHTX);
525 mtu->ep0_state = MU3D_EP0_STATE_TX;
526 } else {
527 mtu3_writel(mtu->mac_base, U3D_EP0CSR,
528 (csr | EP0_SETUPPKTRDY) & (~EP0_DPHTX));
529 mtu->ep0_state = MU3D_EP0_STATE_RX;
530 }
531}
532
533static int ep0_handle_setup(struct mtu3 *mtu)
534__releases(mtu->lock)
535__acquires(mtu->lock)
536{
537 struct usb_ctrlrequest setup;
538 struct mtu3_request *mreq;
539 void __iomem *mbase = mtu->mac_base;
540 int handled = 0;
541
542 ep0_read_setup(mtu, &setup);
543
544 if ((setup.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
545 handled = handle_standard_request(mtu, &setup);
546
547 dev_dbg(mtu->dev, "handled %d, ep0_state: %s\n",
548 handled, decode_ep0_state(mtu));
549
550 if (handled < 0)
551 goto stall;
552 else if (handled > 0)
553 goto finish;
554
555 handled = forward_to_driver(mtu, &setup);
556 if (handled < 0) {
557stall:
558 dev_dbg(mtu->dev, "%s stall (%d)\n", __func__, handled);
559
560 ep0_stall_set(mtu->ep0, true,
561 le16_to_cpu(setup.wLength) ? 0 : EP0_SETUPPKTRDY);
562
563 return 0;
564 }
565
566finish:
567 if (mtu->test_mode) {
568 ; /* nothing to do */
569 } else if (le16_to_cpu(setup.wLength) == 0) { /* no data stage */
570
571 mtu3_writel(mbase, U3D_EP0CSR,
572 (mtu3_readl(mbase, U3D_EP0CSR) & EP0_W1C_BITS)
573 | EP0_SETUPPKTRDY | EP0_DATAEND);
574
575 /* complete zlp request directly */
576 mreq = next_ep0_request(mtu);
577 if (mreq && !mreq->request.length)
578 ep0_req_giveback(mtu, &mreq->request);
579 }
580
581 return 0;
582}
583
584irqreturn_t mtu3_ep0_isr(struct mtu3 *mtu)
585{
586 void __iomem *mbase = mtu->mac_base;
587 struct mtu3_request *mreq;
588 u32 int_status;
589 irqreturn_t ret = IRQ_NONE;
590 u32 csr;
591 u32 len;
592
593 int_status = mtu3_readl(mbase, U3D_EPISR);
594 int_status &= mtu3_readl(mbase, U3D_EPIER);
595 mtu3_writel(mbase, U3D_EPISR, int_status); /* W1C */
596
597 /* only handle ep0's */
598 if (!(int_status & EP0ISR))
599 return IRQ_NONE;
600
601 csr = mtu3_readl(mbase, U3D_EP0CSR);
602
603 dev_dbg(mtu->dev, "%s csr=0x%x\n", __func__, csr);
604
605 /* we sent a stall.. need to clear it now.. */
606 if (csr & EP0_SENTSTALL) {
607 ep0_stall_set(mtu->ep0, false, 0);
608 csr = mtu3_readl(mbase, U3D_EP0CSR);
609 ret = IRQ_HANDLED;
610 }
611 dev_dbg(mtu->dev, "ep0_state: %s\n", decode_ep0_state(mtu));
612
613 switch (mtu->ep0_state) {
614 case MU3D_EP0_STATE_TX:
615 /* irq on clearing txpktrdy */
616 if ((csr & EP0_FIFOFULL) == 0) {
617 ep0_tx_state(mtu);
618 ret = IRQ_HANDLED;
619 }
620 break;
621 case MU3D_EP0_STATE_RX:
622 /* irq on set rxpktrdy */
623 if (csr & EP0_RXPKTRDY) {
624 ep0_rx_state(mtu);
625 ret = IRQ_HANDLED;
626 }
627 break;
628 case MU3D_EP0_STATE_TX_END:
629 mtu3_writel(mbase, U3D_EP0CSR,
630 (csr & EP0_W1C_BITS) | EP0_DATAEND);
631
632 mreq = next_ep0_request(mtu);
633 if (mreq)
634 ep0_req_giveback(mtu, &mreq->request);
635
636 mtu->ep0_state = MU3D_EP0_STATE_SETUP;
637 ret = IRQ_HANDLED;
638 dev_dbg(mtu->dev, "ep0_state: %s\n", decode_ep0_state(mtu));
639 break;
640 case MU3D_EP0_STATE_SETUP:
641 if (!(csr & EP0_SETUPPKTRDY))
642 break;
643
644 len = mtu3_readl(mbase, U3D_RXCOUNT0);
645 if (len != 8) {
646 dev_err(mtu->dev, "SETUP packet len %d != 8 ?\n", len);
647 break;
648 }
649
650 ep0_handle_setup(mtu);
651 ret = IRQ_HANDLED;
652 break;
653 default:
654 /* can't happen */
655 ep0_stall_set(mtu->ep0, true, 0);
656 WARN_ON(1);
657 break;
658 }
659
660 return ret;
661}
662
663
664static int mtu3_ep0_enable(struct usb_ep *ep,
665 const struct usb_endpoint_descriptor *desc)
666{
667 /* always enabled */
668 return -EINVAL;
669}
670
671static int mtu3_ep0_disable(struct usb_ep *ep)
672{
673 /* always enabled */
674 return -EINVAL;
675}
676
677static int ep0_queue(struct mtu3_ep *mep, struct mtu3_request *mreq)
678{
679 struct mtu3 *mtu = mep->mtu;
680
681 mreq->mtu = mtu;
682 mreq->request.actual = 0;
683 mreq->request.status = -EINPROGRESS;
684
685 dev_dbg(mtu->dev, "%s %s (ep0_state: %s), len#%d\n", __func__,
686 mep->name, decode_ep0_state(mtu), mreq->request.length);
687
688 if (!list_empty(&mep->req_list))
689 return -EBUSY;
690
691 switch (mtu->ep0_state) {
692 case MU3D_EP0_STATE_SETUP:
693 case MU3D_EP0_STATE_RX: /* control-OUT data */
694 case MU3D_EP0_STATE_TX: /* control-IN data */
695 break;
696 default:
697 dev_err(mtu->dev, "%s, error in ep0 state %s\n", __func__,
698 decode_ep0_state(mtu));
699 return -EINVAL;
700 }
701
702 list_add_tail(&mreq->list, &mep->req_list);
703
704 /* sequence #1, IN ... start writing the data */
705 if (mtu->ep0_state == MU3D_EP0_STATE_TX)
706 ep0_tx_state(mtu);
707
708 return 0;
709}
710
711static int mtu3_ep0_queue(struct usb_ep *ep,
712 struct usb_request *req, gfp_t gfp)
713{
714 struct mtu3_ep *mep;
715 struct mtu3_request *mreq;
716 struct mtu3 *mtu;
717 unsigned long flags;
718 int ret = 0;
719
720 if (!ep || !req)
721 return -EINVAL;
722
723 mep = to_mtu3_ep(ep);
724 mtu = mep->mtu;
725 mreq = to_mtu3_request(req);
726
727 spin_lock_irqsave(&mtu->lock, flags);
728 ret = ep0_queue(mep, mreq);
729 spin_unlock_irqrestore(&mtu->lock, flags);
730 return ret;
731}
732
733static int mtu3_ep0_dequeue(struct usb_ep *ep, struct usb_request *req)
734{
735 /* we just won't support this */
736 return -EINVAL;
737}
738
739static int mtu3_ep0_halt(struct usb_ep *ep, int value)
740{
741 struct mtu3_ep *mep;
742 struct mtu3 *mtu;
743 unsigned long flags;
744 int ret = 0;
745
746 if (!ep || !value)
747 return -EINVAL;
748
749 mep = to_mtu3_ep(ep);
750 mtu = mep->mtu;
751
752 dev_dbg(mtu->dev, "%s\n", __func__);
753
754 spin_lock_irqsave(&mtu->lock, flags);
755
756 if (!list_empty(&mep->req_list)) {
757 ret = -EBUSY;
758 goto cleanup;
759 }
760
761 switch (mtu->ep0_state) {
762 /*
763 * stalls are usually issued after parsing SETUP packet, either
764 * directly in irq context from setup() or else later.
765 */
766 case MU3D_EP0_STATE_TX:
767 case MU3D_EP0_STATE_TX_END:
768 case MU3D_EP0_STATE_RX:
769 case MU3D_EP0_STATE_SETUP:
770 ep0_stall_set(mtu->ep0, true, 0);
771 break;
772 default:
773 dev_dbg(mtu->dev, "ep0 can't halt in state %s\n",
774 decode_ep0_state(mtu));
775 ret = -EINVAL;
776 }
777
778cleanup:
779 spin_unlock_irqrestore(&mtu->lock, flags);
780 return ret;
781}
782
783const struct usb_ep_ops mtu3_ep0_ops = {
784 .enable = mtu3_ep0_enable,
785 .disable = mtu3_ep0_disable,
786 .alloc_request = mtu3_alloc_request,
787 .free_request = mtu3_free_request,
788 .queue = mtu3_ep0_queue,
789 .dequeue = mtu3_ep0_dequeue,
790 .set_halt = mtu3_ep0_halt,
791};