blob: c95c6a4828126906f69ee49f520e5c091b22beeb [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Thomas Abraham38f424f2009-01-04 09:41:03 +05302/*
3 * Mentor USB OTG Core host controller driver.
4 *
5 * Copyright (c) 2008 Texas Instruments
6 *
Thomas Abraham38f424f2009-01-04 09:41:03 +05307 * Author: Thomas Abraham t-abraham@ti.com, Texas Instruments
8 */
9
Simon Glass0f2af882020-05-10 11:40:05 -060010#include <log.h>
Ilya Yanoka1cf10f2012-11-06 13:48:20 +000011#include <usb.h>
Simon Glassdbd79542020-05-10 11:40:11 -060012#include <linux/delay.h>
Thomas Abraham38f424f2009-01-04 09:41:03 +053013#include "musb_hcd.h"
14
15/* MSC control transfers */
Wolfgang Denk62fb2b42021-09-27 17:42:39 +020016#define USB_MSC_BBB_RESET 0xFF
Thomas Abraham38f424f2009-01-04 09:41:03 +053017#define USB_MSC_BBB_GET_MAX_LUN 0xFE
18
19/* Endpoint configuration information */
Mike Frysinger671bc3d2010-10-20 07:15:35 -040020static const struct musb_epinfo epinfo[3] = {
Thomas Abraham38f424f2009-01-04 09:41:03 +053021 {MUSB_BULK_EP, 1, 512}, /* EP1 - Bluk Out - 512 Bytes */
22 {MUSB_BULK_EP, 0, 512}, /* EP1 - Bluk In - 512 Bytes */
23 {MUSB_INTR_EP, 0, 64} /* EP2 - Interrupt IN - 64 Bytes */
24};
25
Bryan Wu73073cc2010-01-09 16:53:54 -050026/* --- Virtual Root Hub ---------------------------------------------------- */
27#ifdef MUSB_NO_MULTIPOINT
28static int rh_devnum;
29static u32 port_status;
30
Stephen Warren39c89682014-02-13 21:15:18 -070031#include <usbroothubdes.h>
Bryan Wu73073cc2010-01-09 16:53:54 -050032
Bryan Wu73073cc2010-01-09 16:53:54 -050033#endif
34
Thomas Abraham38f424f2009-01-04 09:41:03 +053035/*
36 * This function writes the data toggle value.
37 */
38static void write_toggle(struct usb_device *dev, u8 ep, u8 dir_out)
39{
40 u16 toggle = usb_gettoggle(dev, ep, dir_out);
41 u16 csr;
42
43 if (dir_out) {
Bryan Wufe439d22010-08-09 14:58:24 -040044 csr = readw(&musbr->txcsr);
45 if (!toggle) {
46 if (csr & MUSB_TXCSR_MODE)
47 csr = MUSB_TXCSR_CLRDATATOG;
48 else
49 csr = 0;
50 writew(csr, &musbr->txcsr);
51 } else {
Thomas Abraham38f424f2009-01-04 09:41:03 +053052 csr |= MUSB_TXCSR_H_WR_DATATOGGLE;
53 writew(csr, &musbr->txcsr);
54 csr |= (toggle << MUSB_TXCSR_H_DATATOGGLE_SHIFT);
55 writew(csr, &musbr->txcsr);
56 }
57 } else {
Bryan Wufe439d22010-08-09 14:58:24 -040058 if (!toggle) {
59 csr = readw(&musbr->txcsr);
60 if (csr & MUSB_TXCSR_MODE)
61 csr = MUSB_RXCSR_CLRDATATOG;
62 else
63 csr = 0;
64 writew(csr, &musbr->rxcsr);
65 } else {
Thomas Abraham38f424f2009-01-04 09:41:03 +053066 csr = readw(&musbr->rxcsr);
67 csr |= MUSB_RXCSR_H_WR_DATATOGGLE;
68 writew(csr, &musbr->rxcsr);
69 csr |= (toggle << MUSB_S_RXCSR_H_DATATOGGLE);
70 writew(csr, &musbr->rxcsr);
71 }
72 }
73}
74
75/*
Vagrant Cascadianedfdb992016-04-30 19:18:00 -070076 * This function checks if RxStall has occurred on the endpoint. If a RxStall
77 * has occurred, the RxStall is cleared and 1 is returned. If RxStall has
78 * not occurred, 0 is returned.
Thomas Abraham38f424f2009-01-04 09:41:03 +053079 */
80static u8 check_stall(u8 ep, u8 dir_out)
81{
82 u16 csr;
83
84 /* For endpoint 0 */
85 if (!ep) {
86 csr = readw(&musbr->txcsr);
87 if (csr & MUSB_CSR0_H_RXSTALL) {
88 csr &= ~MUSB_CSR0_H_RXSTALL;
89 writew(csr, &musbr->txcsr);
90 return 1;
91 }
92 } else { /* For non-ep0 */
93 if (dir_out) { /* is it tx ep */
94 csr = readw(&musbr->txcsr);
95 if (csr & MUSB_TXCSR_H_RXSTALL) {
96 csr &= ~MUSB_TXCSR_H_RXSTALL;
97 writew(csr, &musbr->txcsr);
98 return 1;
99 }
100 } else { /* is it rx ep */
101 csr = readw(&musbr->rxcsr);
102 if (csr & MUSB_RXCSR_H_RXSTALL) {
103 csr &= ~MUSB_RXCSR_H_RXSTALL;
104 writew(csr, &musbr->rxcsr);
105 return 1;
106 }
107 }
108 }
109 return 0;
110}
111
112/*
113 * waits until ep0 is ready. Returns 0 if ep is ready, -1 for timeout
114 * error and -2 for stall.
115 */
116static int wait_until_ep0_ready(struct usb_device *dev, u32 bit_mask)
117{
118 u16 csr;
119 int result = 1;
Tom Rinicb8630f2023-01-10 11:19:38 -0500120 int timeout = MUSB_TIMEOUT;
Thomas Abraham38f424f2009-01-04 09:41:03 +0530121
122 while (result > 0) {
123 csr = readw(&musbr->txcsr);
124 if (csr & MUSB_CSR0_H_ERROR) {
125 csr &= ~MUSB_CSR0_H_ERROR;
126 writew(csr, &musbr->txcsr);
127 dev->status = USB_ST_CRC_ERR;
128 result = -1;
129 break;
130 }
131
132 switch (bit_mask) {
133 case MUSB_CSR0_TXPKTRDY:
134 if (!(csr & MUSB_CSR0_TXPKTRDY)) {
135 if (check_stall(MUSB_CONTROL_EP, 0)) {
136 dev->status = USB_ST_STALLED;
137 result = -2;
138 } else
139 result = 0;
140 }
141 break;
142
143 case MUSB_CSR0_RXPKTRDY:
144 if (check_stall(MUSB_CONTROL_EP, 0)) {
145 dev->status = USB_ST_STALLED;
146 result = -2;
147 } else
148 if (csr & MUSB_CSR0_RXPKTRDY)
149 result = 0;
150 break;
151
152 case MUSB_CSR0_H_REQPKT:
153 if (!(csr & MUSB_CSR0_H_REQPKT)) {
154 if (check_stall(MUSB_CONTROL_EP, 0)) {
155 dev->status = USB_ST_STALLED;
156 result = -2;
157 } else
158 result = 0;
159 }
160 break;
161 }
Bryan Wu3169ce82009-06-16 05:26:27 -0400162
163 /* Check the timeout */
164 if (--timeout)
165 udelay(1);
166 else {
167 dev->status = USB_ST_CRC_ERR;
168 result = -1;
169 break;
170 }
Thomas Abraham38f424f2009-01-04 09:41:03 +0530171 }
Bryan Wu3169ce82009-06-16 05:26:27 -0400172
Thomas Abraham38f424f2009-01-04 09:41:03 +0530173 return result;
174}
175
176/*
177 * waits until tx ep is ready. Returns 1 when ep is ready and 0 on error.
178 */
Andrew Murrayca6dfde2013-10-01 15:58:56 +0100179static int wait_until_txep_ready(struct usb_device *dev, u8 ep)
Thomas Abraham38f424f2009-01-04 09:41:03 +0530180{
181 u16 csr;
Tom Rinicb8630f2023-01-10 11:19:38 -0500182 int timeout = MUSB_TIMEOUT;
Thomas Abraham38f424f2009-01-04 09:41:03 +0530183
184 do {
185 if (check_stall(ep, 1)) {
186 dev->status = USB_ST_STALLED;
187 return 0;
188 }
189
190 csr = readw(&musbr->txcsr);
191 if (csr & MUSB_TXCSR_H_ERROR) {
192 dev->status = USB_ST_CRC_ERR;
193 return 0;
194 }
Bryan Wu3169ce82009-06-16 05:26:27 -0400195
196 /* Check the timeout */
197 if (--timeout)
198 udelay(1);
199 else {
200 dev->status = USB_ST_CRC_ERR;
201 return -1;
202 }
203
Thomas Abraham38f424f2009-01-04 09:41:03 +0530204 } while (csr & MUSB_TXCSR_TXPKTRDY);
205 return 1;
206}
207
208/*
209 * waits until rx ep is ready. Returns 1 when ep is ready and 0 on error.
210 */
Andrew Murrayca6dfde2013-10-01 15:58:56 +0100211static int wait_until_rxep_ready(struct usb_device *dev, u8 ep)
Thomas Abraham38f424f2009-01-04 09:41:03 +0530212{
213 u16 csr;
Tom Rinicb8630f2023-01-10 11:19:38 -0500214 int timeout = MUSB_TIMEOUT;
Thomas Abraham38f424f2009-01-04 09:41:03 +0530215
216 do {
217 if (check_stall(ep, 0)) {
218 dev->status = USB_ST_STALLED;
219 return 0;
220 }
221
222 csr = readw(&musbr->rxcsr);
223 if (csr & MUSB_RXCSR_H_ERROR) {
224 dev->status = USB_ST_CRC_ERR;
225 return 0;
226 }
Bryan Wu3169ce82009-06-16 05:26:27 -0400227
228 /* Check the timeout */
229 if (--timeout)
230 udelay(1);
231 else {
232 dev->status = USB_ST_CRC_ERR;
233 return -1;
234 }
235
Thomas Abraham38f424f2009-01-04 09:41:03 +0530236 } while (!(csr & MUSB_RXCSR_RXPKTRDY));
237 return 1;
238}
239
240/*
241 * This function performs the setup phase of the control transfer
242 */
243static int ctrlreq_setup_phase(struct usb_device *dev, struct devrequest *setup)
244{
245 int result;
246 u16 csr;
247
248 /* write the control request to ep0 fifo */
249 write_fifo(MUSB_CONTROL_EP, sizeof(struct devrequest), (void *)setup);
250
251 /* enable transfer of setup packet */
252 csr = readw(&musbr->txcsr);
253 csr |= (MUSB_CSR0_TXPKTRDY|MUSB_CSR0_H_SETUPPKT);
254 writew(csr, &musbr->txcsr);
255
256 /* wait until the setup packet is transmitted */
257 result = wait_until_ep0_ready(dev, MUSB_CSR0_TXPKTRDY);
258 dev->act_len = 0;
259 return result;
260}
261
262/*
263 * This function handles the control transfer in data phase
264 */
265static int ctrlreq_in_data_phase(struct usb_device *dev, u32 len, void *buffer)
266{
267 u16 csr;
268 u32 rxlen = 0;
269 u32 nextlen = 0;
270 u8 maxpktsize = (1 << dev->maxpacketsize) * 8;
271 u8 *rxbuff = (u8 *)buffer;
272 u8 rxedlength;
273 int result;
274
275 while (rxlen < len) {
276 /* Determine the next read length */
277 nextlen = ((len-rxlen) > maxpktsize) ? maxpktsize : (len-rxlen);
278
279 /* Set the ReqPkt bit */
280 csr = readw(&musbr->txcsr);
281 writew(csr | MUSB_CSR0_H_REQPKT, &musbr->txcsr);
282 result = wait_until_ep0_ready(dev, MUSB_CSR0_RXPKTRDY);
283 if (result < 0)
284 return result;
285
286 /* Actual number of bytes received by usb */
287 rxedlength = readb(&musbr->rxcount);
288
289 /* Read the data from the RxFIFO */
290 read_fifo(MUSB_CONTROL_EP, rxedlength, &rxbuff[rxlen]);
291
292 /* Clear the RxPktRdy Bit */
293 csr = readw(&musbr->txcsr);
294 csr &= ~MUSB_CSR0_RXPKTRDY;
295 writew(csr, &musbr->txcsr);
296
297 /* short packet? */
298 if (rxedlength != nextlen) {
299 dev->act_len += rxedlength;
300 break;
301 }
302 rxlen += nextlen;
303 dev->act_len = rxlen;
304 }
305 return 0;
306}
307
308/*
309 * This function handles the control transfer out data phase
310 */
311static int ctrlreq_out_data_phase(struct usb_device *dev, u32 len, void *buffer)
312{
313 u16 csr;
314 u32 txlen = 0;
315 u32 nextlen = 0;
316 u8 maxpktsize = (1 << dev->maxpacketsize) * 8;
317 u8 *txbuff = (u8 *)buffer;
318 int result = 0;
319
320 while (txlen < len) {
321 /* Determine the next write length */
322 nextlen = ((len-txlen) > maxpktsize) ? maxpktsize : (len-txlen);
323
324 /* Load the data to send in FIFO */
325 write_fifo(MUSB_CONTROL_EP, txlen, &txbuff[txlen]);
326
327 /* Set TXPKTRDY bit */
328 csr = readw(&musbr->txcsr);
Wolfgang Denk9d328a62021-09-27 17:42:38 +0200329
Andrew Murray98529262013-09-29 18:02:22 +0100330 csr |= MUSB_CSR0_TXPKTRDY;
Andrew Murray98529262013-09-29 18:02:22 +0100331 csr |= MUSB_CSR0_H_DIS_PING;
Andrew Murray98529262013-09-29 18:02:22 +0100332 writew(csr, &musbr->txcsr);
Thomas Abraham38f424f2009-01-04 09:41:03 +0530333 result = wait_until_ep0_ready(dev, MUSB_CSR0_TXPKTRDY);
334 if (result < 0)
335 break;
336
337 txlen += nextlen;
338 dev->act_len = txlen;
339 }
340 return result;
341}
342
343/*
344 * This function handles the control transfer out status phase
345 */
346static int ctrlreq_out_status_phase(struct usb_device *dev)
347{
348 u16 csr;
349 int result;
350
351 /* Set the StatusPkt bit */
352 csr = readw(&musbr->txcsr);
Andrew Murray98529262013-09-29 18:02:22 +0100353 csr |= (MUSB_CSR0_TXPKTRDY | MUSB_CSR0_H_STATUSPKT);
Andrew Murray98529262013-09-29 18:02:22 +0100354 csr |= MUSB_CSR0_H_DIS_PING;
Thomas Abraham38f424f2009-01-04 09:41:03 +0530355 writew(csr, &musbr->txcsr);
356
357 /* Wait until TXPKTRDY bit is cleared */
358 result = wait_until_ep0_ready(dev, MUSB_CSR0_TXPKTRDY);
359 return result;
360}
361
362/*
363 * This function handles the control transfer in status phase
364 */
365static int ctrlreq_in_status_phase(struct usb_device *dev)
366{
367 u16 csr;
368 int result;
369
370 /* Set the StatusPkt bit and ReqPkt bit */
Andrew Murray98529262013-09-29 18:02:22 +0100371 csr = MUSB_CSR0_H_REQPKT | MUSB_CSR0_H_STATUSPKT;
Andrew Murray98529262013-09-29 18:02:22 +0100372 csr |= MUSB_CSR0_H_DIS_PING;
Thomas Abraham38f424f2009-01-04 09:41:03 +0530373 writew(csr, &musbr->txcsr);
374 result = wait_until_ep0_ready(dev, MUSB_CSR0_H_REQPKT);
375
376 /* clear StatusPkt bit and RxPktRdy bit */
377 csr = readw(&musbr->txcsr);
378 csr &= ~(MUSB_CSR0_RXPKTRDY | MUSB_CSR0_H_STATUSPKT);
379 writew(csr, &musbr->txcsr);
380 return result;
381}
382
383/*
384 * determines the speed of the device (High/Full/Slow)
385 */
386static u8 get_dev_speed(struct usb_device *dev)
387{
Ilya Yanoka1cf10f2012-11-06 13:48:20 +0000388 return (dev->speed == USB_SPEED_HIGH) ? MUSB_TYPE_SPEED_HIGH :
389 ((dev->speed == USB_SPEED_LOW) ? MUSB_TYPE_SPEED_LOW :
Thomas Abraham38f424f2009-01-04 09:41:03 +0530390 MUSB_TYPE_SPEED_FULL);
391}
392
393/*
394 * configure the hub address and the port address.
395 */
396static void config_hub_port(struct usb_device *dev, u8 ep)
397{
398 u8 chid;
399 u8 hub;
400
401 /* Find out the nearest parent which is high speed */
402 while (dev->parent->parent != NULL)
403 if (get_dev_speed(dev->parent) != MUSB_TYPE_SPEED_HIGH)
404 dev = dev->parent;
405 else
406 break;
407
408 /* determine the port address at that hub */
409 hub = dev->parent->devnum;
410 for (chid = 0; chid < USB_MAXCHILDREN; chid++)
411 if (dev->parent->children[chid] == dev)
412 break;
413
Bryan Wu784f1382009-12-16 22:04:00 -0500414#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +0530415 /* configure the hub address and the port address */
416 writeb(hub, &musbr->tar[ep].txhubaddr);
417 writeb((chid + 1), &musbr->tar[ep].txhubport);
418 writeb(hub, &musbr->tar[ep].rxhubaddr);
419 writeb((chid + 1), &musbr->tar[ep].rxhubport);
Bryan Wu784f1382009-12-16 22:04:00 -0500420#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +0530421}
422
Bryan Wu73073cc2010-01-09 16:53:54 -0500423#ifdef MUSB_NO_MULTIPOINT
424
425static void musb_port_reset(int do_reset)
426{
427 u8 power = readb(&musbr->power);
428
429 if (do_reset) {
430 power &= 0xf0;
431 writeb(power | MUSB_POWER_RESET, &musbr->power);
432 port_status |= USB_PORT_STAT_RESET;
433 port_status &= ~USB_PORT_STAT_ENABLE;
434 udelay(30000);
435 } else {
436 writeb(power & ~MUSB_POWER_RESET, &musbr->power);
437
438 power = readb(&musbr->power);
439 if (power & MUSB_POWER_HSMODE)
440 port_status |= USB_PORT_STAT_HIGH_SPEED;
441
442 port_status &= ~(USB_PORT_STAT_RESET | (USB_PORT_STAT_C_CONNECTION << 16));
443 port_status |= USB_PORT_STAT_ENABLE
444 | (USB_PORT_STAT_C_RESET << 16)
445 | (USB_PORT_STAT_C_ENABLE << 16);
446 }
447}
448
Thomas Abraham38f424f2009-01-04 09:41:03 +0530449/*
Bryan Wu73073cc2010-01-09 16:53:54 -0500450 * root hub control
451 */
452static int musb_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
453 void *buffer, int transfer_len,
454 struct devrequest *cmd)
455{
456 int leni = transfer_len;
457 int len = 0;
458 int stat = 0;
459 u32 datab[4];
Mike Frysinger671bc3d2010-10-20 07:15:35 -0400460 const u8 *data_buf = (u8 *) datab;
Bryan Wu73073cc2010-01-09 16:53:54 -0500461 u16 bmRType_bReq;
462 u16 wValue;
463 u16 wIndex;
464 u16 wLength;
465 u16 int_usb;
466
467 if ((pipe & PIPE_INTERRUPT) == PIPE_INTERRUPT) {
468 debug("Root-Hub submit IRQ: NOT implemented\n");
469 return 0;
470 }
471
472 bmRType_bReq = cmd->requesttype | (cmd->request << 8);
473 wValue = swap_16(cmd->value);
474 wIndex = swap_16(cmd->index);
475 wLength = swap_16(cmd->length);
476
477 debug("--- HUB ----------------------------------------\n");
478 debug("submit rh urb, req=%x val=%#x index=%#x len=%d\n",
479 bmRType_bReq, wValue, wIndex, wLength);
480 debug("------------------------------------------------\n");
481
482 switch (bmRType_bReq) {
483 case RH_GET_STATUS:
484 debug("RH_GET_STATUS\n");
485
486 *(__u16 *) data_buf = swap_16(1);
487 len = 2;
488 break;
489
490 case RH_GET_STATUS | RH_INTERFACE:
491 debug("RH_GET_STATUS | RH_INTERFACE\n");
492
493 *(__u16 *) data_buf = swap_16(0);
494 len = 2;
495 break;
496
497 case RH_GET_STATUS | RH_ENDPOINT:
498 debug("RH_GET_STATUS | RH_ENDPOINT\n");
499
500 *(__u16 *) data_buf = swap_16(0);
501 len = 2;
502 break;
503
504 case RH_GET_STATUS | RH_CLASS:
505 debug("RH_GET_STATUS | RH_CLASS\n");
506
507 *(__u32 *) data_buf = swap_32(0);
508 len = 4;
509 break;
510
511 case RH_GET_STATUS | RH_OTHER | RH_CLASS:
512 debug("RH_GET_STATUS | RH_OTHER | RH_CLASS\n");
513
514 int_usb = readw(&musbr->intrusb);
515 if (int_usb & MUSB_INTR_CONNECT) {
516 port_status |= USB_PORT_STAT_CONNECTION
517 | (USB_PORT_STAT_C_CONNECTION << 16);
518 port_status |= USB_PORT_STAT_HIGH_SPEED
519 | USB_PORT_STAT_ENABLE;
520 }
521
522 if (port_status & USB_PORT_STAT_RESET)
523 musb_port_reset(0);
524
525 *(__u32 *) data_buf = swap_32(port_status);
526 len = 4;
527 break;
528
529 case RH_CLEAR_FEATURE | RH_ENDPOINT:
530 debug("RH_CLEAR_FEATURE | RH_ENDPOINT\n");
531
532 switch (wValue) {
533 case RH_ENDPOINT_STALL:
534 debug("C_HUB_ENDPOINT_STALL\n");
535 len = 0;
536 break;
537 }
538 port_status &= ~(1 << wValue);
539 break;
540
541 case RH_CLEAR_FEATURE | RH_CLASS:
542 debug("RH_CLEAR_FEATURE | RH_CLASS\n");
543
544 switch (wValue) {
545 case RH_C_HUB_LOCAL_POWER:
546 debug("C_HUB_LOCAL_POWER\n");
547 len = 0;
548 break;
549
550 case RH_C_HUB_OVER_CURRENT:
551 debug("C_HUB_OVER_CURRENT\n");
552 len = 0;
553 break;
554 }
555 port_status &= ~(1 << wValue);
556 break;
557
558 case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
559 debug("RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS\n");
560
561 switch (wValue) {
562 case RH_PORT_ENABLE:
563 len = 0;
564 break;
565
566 case RH_PORT_SUSPEND:
567 len = 0;
568 break;
569
570 case RH_PORT_POWER:
571 len = 0;
572 break;
573
574 case RH_C_PORT_CONNECTION:
575 len = 0;
576 break;
577
578 case RH_C_PORT_ENABLE:
579 len = 0;
580 break;
581
582 case RH_C_PORT_SUSPEND:
583 len = 0;
584 break;
585
586 case RH_C_PORT_OVER_CURRENT:
587 len = 0;
588 break;
589
590 case RH_C_PORT_RESET:
591 len = 0;
592 break;
593
594 default:
595 debug("invalid wValue\n");
596 stat = USB_ST_STALLED;
597 }
598
599 port_status &= ~(1 << wValue);
600 break;
601
602 case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
603 debug("RH_SET_FEATURE | RH_OTHER | RH_CLASS\n");
604
605 switch (wValue) {
606 case RH_PORT_SUSPEND:
607 len = 0;
608 break;
609
610 case RH_PORT_RESET:
611 musb_port_reset(1);
612 len = 0;
613 break;
614
615 case RH_PORT_POWER:
616 len = 0;
617 break;
618
619 case RH_PORT_ENABLE:
620 len = 0;
621 break;
622
623 default:
624 debug("invalid wValue\n");
625 stat = USB_ST_STALLED;
626 }
627
628 port_status |= 1 << wValue;
629 break;
630
631 case RH_SET_ADDRESS:
632 debug("RH_SET_ADDRESS\n");
633
634 rh_devnum = wValue;
635 len = 0;
636 break;
637
638 case RH_GET_DESCRIPTOR:
639 debug("RH_GET_DESCRIPTOR: %x, %d\n", wValue, wLength);
640
641 switch (wValue) {
642 case (USB_DT_DEVICE << 8): /* device descriptor */
643 len = min_t(unsigned int,
644 leni, min_t(unsigned int,
645 sizeof(root_hub_dev_des),
646 wLength));
647 data_buf = root_hub_dev_des;
648 break;
649
650 case (USB_DT_CONFIG << 8): /* configuration descriptor */
651 len = min_t(unsigned int,
652 leni, min_t(unsigned int,
653 sizeof(root_hub_config_des),
654 wLength));
655 data_buf = root_hub_config_des;
656 break;
657
658 case ((USB_DT_STRING << 8) | 0x00): /* string 0 descriptors */
659 len = min_t(unsigned int,
660 leni, min_t(unsigned int,
661 sizeof(root_hub_str_index0),
662 wLength));
663 data_buf = root_hub_str_index0;
664 break;
665
666 case ((USB_DT_STRING << 8) | 0x01): /* string 1 descriptors */
667 len = min_t(unsigned int,
668 leni, min_t(unsigned int,
669 sizeof(root_hub_str_index1),
670 wLength));
671 data_buf = root_hub_str_index1;
672 break;
673
674 default:
675 debug("invalid wValue\n");
676 stat = USB_ST_STALLED;
677 }
678
679 break;
680
Mike Frysinger671bc3d2010-10-20 07:15:35 -0400681 case RH_GET_DESCRIPTOR | RH_CLASS: {
682 u8 *_data_buf = (u8 *) datab;
Bryan Wu73073cc2010-01-09 16:53:54 -0500683 debug("RH_GET_DESCRIPTOR | RH_CLASS\n");
684
Mike Frysinger671bc3d2010-10-20 07:15:35 -0400685 _data_buf[0] = 0x09; /* min length; */
686 _data_buf[1] = 0x29;
687 _data_buf[2] = 0x1; /* 1 port */
688 _data_buf[3] = 0x01; /* per-port power switching */
689 _data_buf[3] |= 0x10; /* no overcurrent reporting */
Bryan Wu73073cc2010-01-09 16:53:54 -0500690
691 /* Corresponds to data_buf[4-7] */
Mike Frysinger671bc3d2010-10-20 07:15:35 -0400692 _data_buf[4] = 0;
693 _data_buf[5] = 5;
694 _data_buf[6] = 0;
695 _data_buf[7] = 0x02;
696 _data_buf[8] = 0xff;
Bryan Wu73073cc2010-01-09 16:53:54 -0500697
698 len = min_t(unsigned int, leni,
699 min_t(unsigned int, data_buf[0], wLength));
700 break;
Mike Frysinger671bc3d2010-10-20 07:15:35 -0400701 }
Bryan Wu73073cc2010-01-09 16:53:54 -0500702
703 case RH_GET_CONFIGURATION:
704 debug("RH_GET_CONFIGURATION\n");
705
706 *(__u8 *) data_buf = 0x01;
707 len = 1;
708 break;
709
710 case RH_SET_CONFIGURATION:
711 debug("RH_SET_CONFIGURATION\n");
712
713 len = 0;
714 break;
715
716 default:
717 debug("*** *** *** unsupported root hub command *** *** ***\n");
718 stat = USB_ST_STALLED;
719 }
720
721 len = min_t(int, len, leni);
722 if (buffer != data_buf)
723 memcpy(buffer, data_buf, len);
724
725 dev->act_len = len;
726 dev->status = stat;
Mike Frysinger68896282012-02-03 03:03:04 +0000727 debug("dev act_len %d, status %lu\n", dev->act_len, dev->status);
Bryan Wu73073cc2010-01-09 16:53:54 -0500728
729 return stat;
730}
731
732static void musb_rh_init(void)
733{
734 rh_devnum = 0;
735 port_status = 0;
736}
737
738#else
739
740static void musb_rh_init(void) {}
741
742#endif
743
744/*
Thomas Abraham38f424f2009-01-04 09:41:03 +0530745 * do a control transfer
746 */
747int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
748 int len, struct devrequest *setup)
749{
750 int devnum = usb_pipedevice(pipe);
Thomas Abraham38f424f2009-01-04 09:41:03 +0530751 u8 devspeed;
752
Bryan Wu73073cc2010-01-09 16:53:54 -0500753#ifdef MUSB_NO_MULTIPOINT
754 /* Control message is for the HUB? */
Cliff Cai94cfe2a2011-04-21 12:42:10 -0400755 if (devnum == rh_devnum) {
756 int stat = musb_submit_rh_msg(dev, pipe, buffer, len, setup);
757 if (stat)
758 return stat;
759 }
Bryan Wu73073cc2010-01-09 16:53:54 -0500760#endif
761
Thomas Abraham38f424f2009-01-04 09:41:03 +0530762 /* select control endpoint */
763 writeb(MUSB_CONTROL_EP, &musbr->index);
Anatolij Gustschinb2aed5d2011-11-19 13:12:09 +0000764 readw(&musbr->txcsr);
Thomas Abraham38f424f2009-01-04 09:41:03 +0530765
Bryan Wu784f1382009-12-16 22:04:00 -0500766#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +0530767 /* target addr and (for multipoint) hub addr/port */
768 writeb(devnum, &musbr->tar[MUSB_CONTROL_EP].txfuncaddr);
769 writeb(devnum, &musbr->tar[MUSB_CONTROL_EP].rxfuncaddr);
Bryan Wu784f1382009-12-16 22:04:00 -0500770#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +0530771
772 /* configure the hub address and the port number as required */
773 devspeed = get_dev_speed(dev);
774 if ((musb_ishighspeed()) && (dev->parent != NULL) &&
775 (devspeed != MUSB_TYPE_SPEED_HIGH)) {
776 config_hub_port(dev, MUSB_CONTROL_EP);
777 writeb(devspeed << 6, &musbr->txtype);
778 } else {
779 writeb(musb_cfg.musb_speed << 6, &musbr->txtype);
Bryan Wu784f1382009-12-16 22:04:00 -0500780#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +0530781 writeb(0, &musbr->tar[MUSB_CONTROL_EP].txhubaddr);
782 writeb(0, &musbr->tar[MUSB_CONTROL_EP].txhubport);
783 writeb(0, &musbr->tar[MUSB_CONTROL_EP].rxhubaddr);
784 writeb(0, &musbr->tar[MUSB_CONTROL_EP].rxhubport);
Bryan Wu784f1382009-12-16 22:04:00 -0500785#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +0530786 }
787
788 /* Control transfer setup phase */
789 if (ctrlreq_setup_phase(dev, setup) < 0)
790 return 0;
791
792 switch (setup->request) {
793 case USB_REQ_GET_DESCRIPTOR:
794 case USB_REQ_GET_CONFIGURATION:
795 case USB_REQ_GET_INTERFACE:
796 case USB_REQ_GET_STATUS:
797 case USB_MSC_BBB_GET_MAX_LUN:
798 /* control transfer in-data-phase */
799 if (ctrlreq_in_data_phase(dev, len, buffer) < 0)
800 return 0;
801 /* control transfer out-status-phase */
802 if (ctrlreq_out_status_phase(dev) < 0)
803 return 0;
804 break;
805
806 case USB_REQ_SET_ADDRESS:
807 case USB_REQ_SET_CONFIGURATION:
808 case USB_REQ_SET_FEATURE:
809 case USB_REQ_SET_INTERFACE:
810 case USB_REQ_CLEAR_FEATURE:
811 case USB_MSC_BBB_RESET:
812 /* control transfer in status phase */
813 if (ctrlreq_in_status_phase(dev) < 0)
814 return 0;
815 break;
816
817 case USB_REQ_SET_DESCRIPTOR:
818 /* control transfer out data phase */
819 if (ctrlreq_out_data_phase(dev, len, buffer) < 0)
820 return 0;
821 /* control transfer in status phase */
822 if (ctrlreq_in_status_phase(dev) < 0)
823 return 0;
824 break;
825
826 default:
827 /* unhandled control transfer */
828 return -1;
829 }
830
831 dev->status = 0;
832 dev->act_len = len;
Bryan Wu953ee312010-08-09 18:41:12 -0400833
834#ifdef MUSB_NO_MULTIPOINT
835 /* Set device address to USB_FADDR register */
836 if (setup->request == USB_REQ_SET_ADDRESS)
837 writeb(dev->devnum, &musbr->faddr);
838#endif
839
Thomas Abraham38f424f2009-01-04 09:41:03 +0530840 return len;
841}
842
843/*
844 * do a bulk transfer
845 */
846int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
847 void *buffer, int len)
848{
849 int dir_out = usb_pipeout(pipe);
850 int ep = usb_pipeendpoint(pipe);
Bryan Wu784f1382009-12-16 22:04:00 -0500851#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +0530852 int devnum = usb_pipedevice(pipe);
Bryan Wu784f1382009-12-16 22:04:00 -0500853#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +0530854 u8 type;
855 u16 csr;
856 u32 txlen = 0;
857 u32 nextlen = 0;
858 u8 devspeed;
859
860 /* select bulk endpoint */
861 writeb(MUSB_BULK_EP, &musbr->index);
862
Bryan Wu784f1382009-12-16 22:04:00 -0500863#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +0530864 /* write the address of the device */
865 if (dir_out)
866 writeb(devnum, &musbr->tar[MUSB_BULK_EP].txfuncaddr);
867 else
868 writeb(devnum, &musbr->tar[MUSB_BULK_EP].rxfuncaddr);
Bryan Wu784f1382009-12-16 22:04:00 -0500869#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +0530870
871 /* configure the hub address and the port number as required */
872 devspeed = get_dev_speed(dev);
873 if ((musb_ishighspeed()) && (dev->parent != NULL) &&
874 (devspeed != MUSB_TYPE_SPEED_HIGH)) {
875 /*
876 * MUSB is in high speed and the destination device is full
877 * speed device. So configure the hub address and port
878 * address registers.
879 */
880 config_hub_port(dev, MUSB_BULK_EP);
881 } else {
Bryan Wu784f1382009-12-16 22:04:00 -0500882#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +0530883 if (dir_out) {
884 writeb(0, &musbr->tar[MUSB_BULK_EP].txhubaddr);
885 writeb(0, &musbr->tar[MUSB_BULK_EP].txhubport);
886 } else {
887 writeb(0, &musbr->tar[MUSB_BULK_EP].rxhubaddr);
888 writeb(0, &musbr->tar[MUSB_BULK_EP].rxhubport);
889 }
Bryan Wu784f1382009-12-16 22:04:00 -0500890#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +0530891 devspeed = musb_cfg.musb_speed;
892 }
893
894 /* Write the saved toggle bit value */
895 write_toggle(dev, ep, dir_out);
896
897 if (dir_out) { /* bulk-out transfer */
898 /* Program the TxType register */
899 type = (devspeed << MUSB_TYPE_SPEED_SHIFT) |
900 (MUSB_TYPE_PROTO_BULK << MUSB_TYPE_PROTO_SHIFT) |
901 (ep & MUSB_TYPE_REMOTE_END);
902 writeb(type, &musbr->txtype);
903
904 /* Write maximum packet size to the TxMaxp register */
905 writew(dev->epmaxpacketout[ep], &musbr->txmaxp);
906 while (txlen < len) {
907 nextlen = ((len-txlen) < dev->epmaxpacketout[ep]) ?
908 (len-txlen) : dev->epmaxpacketout[ep];
909
910 /* Write the data to the FIFO */
911 write_fifo(MUSB_BULK_EP, nextlen,
912 (void *)(((u8 *)buffer) + txlen));
913
914 /* Set the TxPktRdy bit */
915 csr = readw(&musbr->txcsr);
916 writew(csr | MUSB_TXCSR_TXPKTRDY, &musbr->txcsr);
917
918 /* Wait until the TxPktRdy bit is cleared */
Andrew Murrayca6dfde2013-10-01 15:58:56 +0100919 if (wait_until_txep_ready(dev, MUSB_BULK_EP) != 1) {
Thomas Abraham38f424f2009-01-04 09:41:03 +0530920 readw(&musbr->txcsr);
921 usb_settoggle(dev, ep, dir_out,
922 (csr >> MUSB_TXCSR_H_DATATOGGLE_SHIFT) & 1);
923 dev->act_len = txlen;
924 return 0;
925 }
926 txlen += nextlen;
927 }
928
929 /* Keep a copy of the data toggle bit */
930 csr = readw(&musbr->txcsr);
931 usb_settoggle(dev, ep, dir_out,
932 (csr >> MUSB_TXCSR_H_DATATOGGLE_SHIFT) & 1);
933 } else { /* bulk-in transfer */
934 /* Write the saved toggle bit value */
935 write_toggle(dev, ep, dir_out);
936
937 /* Program the RxType register */
938 type = (devspeed << MUSB_TYPE_SPEED_SHIFT) |
939 (MUSB_TYPE_PROTO_BULK << MUSB_TYPE_PROTO_SHIFT) |
940 (ep & MUSB_TYPE_REMOTE_END);
941 writeb(type, &musbr->rxtype);
942
943 /* Write the maximum packet size to the RxMaxp register */
944 writew(dev->epmaxpacketin[ep], &musbr->rxmaxp);
945 while (txlen < len) {
946 nextlen = ((len-txlen) < dev->epmaxpacketin[ep]) ?
947 (len-txlen) : dev->epmaxpacketin[ep];
948
949 /* Set the ReqPkt bit */
Bryan Wu65b99d32009-12-16 22:04:01 -0500950 csr = readw(&musbr->rxcsr);
951 writew(csr | MUSB_RXCSR_H_REQPKT, &musbr->rxcsr);
Thomas Abraham38f424f2009-01-04 09:41:03 +0530952
953 /* Wait until the RxPktRdy bit is set */
Andrew Murrayca6dfde2013-10-01 15:58:56 +0100954 if (wait_until_rxep_ready(dev, MUSB_BULK_EP) != 1) {
Thomas Abraham38f424f2009-01-04 09:41:03 +0530955 csr = readw(&musbr->rxcsr);
956 usb_settoggle(dev, ep, dir_out,
957 (csr >> MUSB_S_RXCSR_H_DATATOGGLE) & 1);
958 csr &= ~MUSB_RXCSR_RXPKTRDY;
959 writew(csr, &musbr->rxcsr);
960 dev->act_len = txlen;
961 return 0;
962 }
963
964 /* Read the data from the FIFO */
965 read_fifo(MUSB_BULK_EP, nextlen,
966 (void *)(((u8 *)buffer) + txlen));
967
968 /* Clear the RxPktRdy bit */
969 csr = readw(&musbr->rxcsr);
970 csr &= ~MUSB_RXCSR_RXPKTRDY;
971 writew(csr, &musbr->rxcsr);
972 txlen += nextlen;
973 }
974
975 /* Keep a copy of the data toggle bit */
976 csr = readw(&musbr->rxcsr);
977 usb_settoggle(dev, ep, dir_out,
978 (csr >> MUSB_S_RXCSR_H_DATATOGGLE) & 1);
979 }
980
981 /* bulk transfer is complete */
982 dev->status = 0;
983 dev->act_len = len;
984 return 0;
985}
986
987/*
988 * This function initializes the usb controller module.
989 */
Troy Kisky8f9c49d2013-10-10 15:27:56 -0700990int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
Thomas Abraham38f424f2009-01-04 09:41:03 +0530991{
992 u8 power;
993 u32 timeout;
994
Bryan Wu73073cc2010-01-09 16:53:54 -0500995 musb_rh_init();
996
Thomas Abraham38f424f2009-01-04 09:41:03 +0530997 if (musb_platform_init() == -1)
998 return -1;
999
1000 /* Configure all the endpoint FIFO's and start usb controller */
1001 musbr = musb_cfg.regs;
Axel Lind6272f22013-06-23 00:57:46 +08001002 musb_configure_ep(&epinfo[0], ARRAY_SIZE(epinfo));
Thomas Abraham38f424f2009-01-04 09:41:03 +05301003 musb_start();
1004
1005 /*
1006 * Wait until musb is enabled in host mode with a timeout. There
1007 * should be a usb device connected.
1008 */
1009 timeout = musb_cfg.timeout;
Matej Frančeškin36eccd22012-08-30 09:24:39 +02001010 while (--timeout)
Thomas Abraham38f424f2009-01-04 09:41:03 +05301011 if (readb(&musbr->devctl) & MUSB_DEVCTL_HM)
1012 break;
1013
1014 /* if musb core is not in host mode, then return */
1015 if (!timeout)
1016 return -1;
1017
1018 /* start usb bus reset */
1019 power = readb(&musbr->power);
1020 writeb(power | MUSB_POWER_RESET, &musbr->power);
1021
1022 /* After initiating a usb reset, wait for about 20ms to 30ms */
1023 udelay(30000);
1024
1025 /* stop usb bus reset */
1026 power = readb(&musbr->power);
1027 power &= ~MUSB_POWER_RESET;
1028 writeb(power, &musbr->power);
1029
1030 /* Determine if the connected device is a high/full/low speed device */
1031 musb_cfg.musb_speed = (readb(&musbr->power) & MUSB_POWER_HSMODE) ?
1032 MUSB_TYPE_SPEED_HIGH :
1033 ((readb(&musbr->devctl) & MUSB_DEVCTL_FSDEV) ?
1034 MUSB_TYPE_SPEED_FULL : MUSB_TYPE_SPEED_LOW);
1035 return 0;
1036}
1037
1038/*
1039 * This function stops the operation of the davinci usb module.
1040 */
Lucas Stacha3231282012-09-26 00:14:34 +02001041int usb_lowlevel_stop(int index)
Thomas Abraham38f424f2009-01-04 09:41:03 +05301042{
1043 /* Reset the USB module */
1044 musb_platform_deinit();
1045 writeb(0, &musbr->devctl);
1046 return 0;
1047}
1048
1049/*
1050 * This function supports usb interrupt transfers. Currently, usb interrupt
1051 * transfers are not supported.
1052 */
Jean-Jacques Hiblot4f34e362019-09-11 09:44:10 +02001053int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
1054 int len, int interval, bool nonblock)
Thomas Abraham38f424f2009-01-04 09:41:03 +05301055{
1056 int dir_out = usb_pipeout(pipe);
1057 int ep = usb_pipeendpoint(pipe);
Bryan Wu784f1382009-12-16 22:04:00 -05001058#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +05301059 int devnum = usb_pipedevice(pipe);
Bryan Wu784f1382009-12-16 22:04:00 -05001060#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +05301061 u8 type;
1062 u16 csr;
1063 u32 txlen = 0;
1064 u32 nextlen = 0;
1065 u8 devspeed;
1066
1067 /* select interrupt endpoint */
1068 writeb(MUSB_INTR_EP, &musbr->index);
1069
Bryan Wu784f1382009-12-16 22:04:00 -05001070#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +05301071 /* write the address of the device */
1072 if (dir_out)
1073 writeb(devnum, &musbr->tar[MUSB_INTR_EP].txfuncaddr);
1074 else
1075 writeb(devnum, &musbr->tar[MUSB_INTR_EP].rxfuncaddr);
Bryan Wu784f1382009-12-16 22:04:00 -05001076#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +05301077
1078 /* configure the hub address and the port number as required */
1079 devspeed = get_dev_speed(dev);
1080 if ((musb_ishighspeed()) && (dev->parent != NULL) &&
1081 (devspeed != MUSB_TYPE_SPEED_HIGH)) {
1082 /*
1083 * MUSB is in high speed and the destination device is full
1084 * speed device. So configure the hub address and port
1085 * address registers.
1086 */
1087 config_hub_port(dev, MUSB_INTR_EP);
1088 } else {
Bryan Wu784f1382009-12-16 22:04:00 -05001089#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +05301090 if (dir_out) {
1091 writeb(0, &musbr->tar[MUSB_INTR_EP].txhubaddr);
1092 writeb(0, &musbr->tar[MUSB_INTR_EP].txhubport);
1093 } else {
1094 writeb(0, &musbr->tar[MUSB_INTR_EP].rxhubaddr);
1095 writeb(0, &musbr->tar[MUSB_INTR_EP].rxhubport);
1096 }
Bryan Wu784f1382009-12-16 22:04:00 -05001097#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +05301098 devspeed = musb_cfg.musb_speed;
1099 }
1100
1101 /* Write the saved toggle bit value */
1102 write_toggle(dev, ep, dir_out);
1103
1104 if (!dir_out) { /* intrrupt-in transfer */
1105 /* Write the saved toggle bit value */
1106 write_toggle(dev, ep, dir_out);
1107 writeb(interval, &musbr->rxinterval);
1108
1109 /* Program the RxType register */
1110 type = (devspeed << MUSB_TYPE_SPEED_SHIFT) |
1111 (MUSB_TYPE_PROTO_INTR << MUSB_TYPE_PROTO_SHIFT) |
1112 (ep & MUSB_TYPE_REMOTE_END);
1113 writeb(type, &musbr->rxtype);
1114
1115 /* Write the maximum packet size to the RxMaxp register */
1116 writew(dev->epmaxpacketin[ep], &musbr->rxmaxp);
1117
1118 while (txlen < len) {
1119 nextlen = ((len-txlen) < dev->epmaxpacketin[ep]) ?
1120 (len-txlen) : dev->epmaxpacketin[ep];
1121
1122 /* Set the ReqPkt bit */
Bryan Wu65b99d32009-12-16 22:04:01 -05001123 csr = readw(&musbr->rxcsr);
1124 writew(csr | MUSB_RXCSR_H_REQPKT, &musbr->rxcsr);
Thomas Abraham38f424f2009-01-04 09:41:03 +05301125
1126 /* Wait until the RxPktRdy bit is set */
Andrew Murrayca6dfde2013-10-01 15:58:56 +01001127 if (wait_until_rxep_ready(dev, MUSB_INTR_EP) != 1) {
Thomas Abraham38f424f2009-01-04 09:41:03 +05301128 csr = readw(&musbr->rxcsr);
1129 usb_settoggle(dev, ep, dir_out,
1130 (csr >> MUSB_S_RXCSR_H_DATATOGGLE) & 1);
1131 csr &= ~MUSB_RXCSR_RXPKTRDY;
1132 writew(csr, &musbr->rxcsr);
1133 dev->act_len = txlen;
1134 return 0;
1135 }
1136
1137 /* Read the data from the FIFO */
1138 read_fifo(MUSB_INTR_EP, nextlen,
1139 (void *)(((u8 *)buffer) + txlen));
1140
1141 /* Clear the RxPktRdy bit */
1142 csr = readw(&musbr->rxcsr);
1143 csr &= ~MUSB_RXCSR_RXPKTRDY;
1144 writew(csr, &musbr->rxcsr);
1145 txlen += nextlen;
1146 }
1147
1148 /* Keep a copy of the data toggle bit */
1149 csr = readw(&musbr->rxcsr);
1150 usb_settoggle(dev, ep, dir_out,
1151 (csr >> MUSB_S_RXCSR_H_DATATOGGLE) & 1);
1152 }
1153
1154 /* interrupt transfer is complete */
1155 dev->irq_status = 0;
1156 dev->irq_act_len = len;
1157 dev->irq_handle(dev);
1158 dev->status = 0;
1159 dev->act_len = len;
1160 return 0;
1161}