1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#include <common.h>
24#include <errno.h>
25#include <asm/byteorder.h>
26#include <asm/unaligned.h>
27#include <usb.h>
28#include <asm/io.h>
29#include <malloc.h>
30#include <watchdog.h>
31#include <linux/compiler.h>
32
33#include "ehci.h"
34
35#ifndef CONFIG_USB_MAX_CONTROLLER_COUNT
36#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
37#endif
38
39
40
41
42
43#define HCHALT_TIMEOUT (8 * 1000)
44
45static struct ehci_ctrl ehcic[CONFIG_USB_MAX_CONTROLLER_COUNT];
46
47#define ALIGN_END_ADDR(type, ptr, size) \
48 ((uint32_t)(ptr) + roundup((size) * sizeof(type), USB_DMA_MINALIGN))
49
50static struct descriptor {
51 struct usb_hub_descriptor hub;
52 struct usb_device_descriptor device;
53 struct usb_linux_config_descriptor config;
54 struct usb_linux_interface_descriptor interface;
55 struct usb_endpoint_descriptor endpoint;
56} __attribute__ ((packed)) descriptor = {
57 {
58 0x8,
59 0x29,
60 2,
61 0,
62 10,
63 0,
64 {},
65 {}
66 },
67 {
68 0x12,
69 1,
70 cpu_to_le16(0x0200),
71 9,
72 0,
73 1,
74 64,
75 0x0000,
76 0x0000,
77 cpu_to_le16(0x0100),
78 1,
79 2,
80 0,
81 1
82 },
83 {
84 0x9,
85 2,
86 cpu_to_le16(0x19),
87 1,
88 1,
89 0,
90 0x40,
91 0
92 },
93 {
94 0x9,
95 4,
96 0,
97 0,
98 1,
99 9,
100 0,
101 0,
102 0
103 },
104 {
105 0x7,
106 5,
107 0x81,
108
109
110 3,
111 8,
112 255
113 },
114};
115
116#if defined(CONFIG_EHCI_IS_TDI)
117#define ehci_is_TDI() (1)
118#else
119#define ehci_is_TDI() (0)
120#endif
121
122__weak int ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg)
123{
124 return PORTSC_PSPD(reg);
125}
126
127__weak void ehci_set_usbmode(int index)
128{
129 uint32_t tmp;
130 uint32_t *reg_ptr;
131
132 reg_ptr = (uint32_t *)((u8 *)&ehcic[index].hcor->or_usbcmd + USBMODE);
133 tmp = ehci_readl(reg_ptr);
134 tmp |= USBMODE_CM_HC;
135#if defined(CONFIG_EHCI_MMIO_BIG_ENDIAN)
136 tmp |= USBMODE_BE;
137#endif
138 ehci_writel(reg_ptr, tmp);
139}
140
141__weak void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
142{
143 mdelay(50);
144}
145
146static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec)
147{
148 uint32_t result;
149 do {
150 result = ehci_readl(ptr);
151 udelay(5);
152 if (result == ~(uint32_t)0)
153 return -1;
154 result &= mask;
155 if (result == done)
156 return 0;
157 usec--;
158 } while (usec > 0);
159 return -1;
160}
161
162static int ehci_reset(int index)
163{
164 uint32_t cmd;
165 int ret = 0;
166
167 cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
168 cmd = (cmd & ~CMD_RUN) | CMD_RESET;
169 ehci_writel(&ehcic[index].hcor->or_usbcmd, cmd);
170 ret = handshake((uint32_t *)&ehcic[index].hcor->or_usbcmd,
171 CMD_RESET, 0, 250 * 1000);
172 if (ret < 0) {
173 printf("EHCI fail to reset\n");
174 goto out;
175 }
176
177 if (ehci_is_TDI())
178 ehci_set_usbmode(index);
179
180#ifdef CONFIG_USB_EHCI_TXFIFO_THRESH
181 cmd = ehci_readl(&ehcic[index].hcor->or_txfilltuning);
182 cmd &= ~TXFIFO_THRESH_MASK;
183 cmd |= TXFIFO_THRESH(CONFIG_USB_EHCI_TXFIFO_THRESH);
184 ehci_writel(&ehcic[index].hcor->or_txfilltuning, cmd);
185#endif
186out:
187 return ret;
188}
189
190static int ehci_shutdown(struct ehci_ctrl *ctrl)
191{
192 int i, ret = 0;
193 uint32_t cmd, reg;
194
195 if (!ctrl || !ctrl->hcor)
196 return -EINVAL;
197
198 cmd = ehci_readl(&ctrl->hcor->or_usbcmd);
199 cmd &= ~(CMD_PSE | CMD_ASE);
200 ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
201 ret = handshake(&ctrl->hcor->or_usbsts, STS_ASS | STS_PSS, 0,
202 100 * 1000);
203
204 if (!ret) {
205 for (i = 0; i < CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS; i++) {
206 reg = ehci_readl(&ctrl->hcor->or_portsc[i]);
207 reg |= EHCI_PS_SUSP;
208 ehci_writel(&ctrl->hcor->or_portsc[i], reg);
209 }
210
211 cmd &= ~CMD_RUN;
212 ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
213 ret = handshake(&ctrl->hcor->or_usbsts, STS_HALT, STS_HALT,
214 HCHALT_TIMEOUT);
215 }
216
217 if (ret)
218 puts("EHCI failed to shut down host controller.\n");
219
220 return ret;
221}
222
223static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz)
224{
225 uint32_t delta, next;
226 uint32_t addr = (uint32_t)buf;
227 int idx;
228
229 if (addr != ALIGN(addr, ARCH_DMA_MINALIGN))
230 debug("EHCI-HCD: Misaligned buffer address (%p)\n", buf);
231
232 flush_dcache_range(addr, ALIGN(addr + sz, ARCH_DMA_MINALIGN));
233
234 idx = 0;
235 while (idx < QT_BUFFER_CNT) {
236 td->qt_buffer[idx] = cpu_to_hc32(addr);
237 td->qt_buffer_hi[idx] = 0;
238 next = (addr + EHCI_PAGE_SIZE) & ~(EHCI_PAGE_SIZE - 1);
239 delta = next - addr;
240 if (delta >= sz)
241 break;
242 sz -= delta;
243 addr = next;
244 idx++;
245 }
246
247 if (idx == QT_BUFFER_CNT) {
248 printf("out of buffer pointers (%u bytes left)\n", sz);
249 return -1;
250 }
251
252 return 0;
253}
254
255static inline u8 ehci_encode_speed(enum usb_device_speed speed)
256{
257 #define QH_HIGH_SPEED 2
258 #define QH_FULL_SPEED 0
259 #define QH_LOW_SPEED 1
260 if (speed == USB_SPEED_HIGH)
261 return QH_HIGH_SPEED;
262 if (speed == USB_SPEED_LOW)
263 return QH_LOW_SPEED;
264 return QH_FULL_SPEED;
265}
266
267static void ehci_update_endpt2_dev_n_port(struct usb_device *dev,
268 struct QH *qh)
269{
270 struct usb_device *ttdev;
271
272 if (dev->speed != USB_SPEED_LOW && dev->speed != USB_SPEED_FULL)
273 return;
274
275
276
277
278
279
280 ttdev = dev;
281 while (ttdev->parent && ttdev->parent->speed != USB_SPEED_HIGH)
282 ttdev = ttdev->parent;
283 if (!ttdev->parent)
284 return;
285
286 qh->qh_endpt2 |= cpu_to_hc32(QH_ENDPT2_PORTNUM(ttdev->portnr) |
287 QH_ENDPT2_HUBADDR(ttdev->parent->devnum));
288}
289
290static int
291ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
292 int length, struct devrequest *req)
293{
294 ALLOC_ALIGN_BUFFER(struct QH, qh, 1, USB_DMA_MINALIGN);
295 struct qTD *qtd;
296 int qtd_count = 0;
297 int qtd_counter = 0;
298 volatile struct qTD *vtd;
299 unsigned long ts;
300 uint32_t *tdp;
301 uint32_t endpt, maxpacket, token, usbsts;
302 uint32_t c, toggle;
303 uint32_t cmd;
304 int timeout;
305 int ret = 0;
306 struct ehci_ctrl *ctrl = dev->controller;
307
308 debug("dev=%p, pipe=%lx, buffer=%p, length=%d, req=%p\n", dev, pipe,
309 buffer, length, req);
310 if (req != NULL)
311 debug("req=%u (%#x), type=%u (%#x), value=%u (%#x), index=%u\n",
312 req->request, req->request,
313 req->requesttype, req->requesttype,
314 le16_to_cpu(req->value), le16_to_cpu(req->value),
315 le16_to_cpu(req->index));
316
317#define PKT_ALIGN 512
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333 if (req != NULL)
334
335 qtd_count += 1 + 1;
336 if (length > 0 || req == NULL) {
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351 int xfr_sz = QT_BUFFER_CNT;
352
353
354
355
356
357 if ((uint32_t)buffer & (PKT_ALIGN - 1))
358 xfr_sz--;
359
360 xfr_sz *= EHCI_PAGE_SIZE;
361
362
363
364
365
366
367 qtd_count += 2 + length / xfr_sz;
368 }
369
370
371
372
373#if CONFIG_SYS_MALLOC_LEN <= 64 + 128 * 1024
374#warning CONFIG_SYS_MALLOC_LEN may be too small for EHCI
375#endif
376 qtd = memalign(USB_DMA_MINALIGN, qtd_count * sizeof(struct qTD));
377 if (qtd == NULL) {
378 printf("unable to allocate TDs\n");
379 return -1;
380 }
381
382 memset(qh, 0, sizeof(struct QH));
383 memset(qtd, 0, qtd_count * sizeof(*qtd));
384
385 toggle = usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
386
387
388
389
390
391
392
393
394
395
396
397 qh->qh_link = cpu_to_hc32((uint32_t)&ctrl->qh_list | QH_LINK_TYPE_QH);
398 c = (dev->speed != USB_SPEED_HIGH) && !usb_pipeendpoint(pipe);
399 maxpacket = usb_maxpacket(dev, pipe);
400 endpt = QH_ENDPT1_RL(8) | QH_ENDPT1_C(c) |
401 QH_ENDPT1_MAXPKTLEN(maxpacket) | QH_ENDPT1_H(0) |
402 QH_ENDPT1_DTC(QH_ENDPT1_DTC_DT_FROM_QTD) |
403 QH_ENDPT1_EPS(ehci_encode_speed(dev->speed)) |
404 QH_ENDPT1_ENDPT(usb_pipeendpoint(pipe)) | QH_ENDPT1_I(0) |
405 QH_ENDPT1_DEVADDR(usb_pipedevice(pipe));
406 qh->qh_endpt1 = cpu_to_hc32(endpt);
407 endpt = QH_ENDPT2_MULT(1) | QH_ENDPT2_UFCMASK(0) | QH_ENDPT2_UFSMASK(0);
408 qh->qh_endpt2 = cpu_to_hc32(endpt);
409 ehci_update_endpt2_dev_n_port(dev, qh);
410 qh->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
411 qh->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
412
413 tdp = &qh->qh_overlay.qt_next;
414
415 if (req != NULL) {
416
417
418
419
420
421
422
423
424
425 qtd[qtd_counter].qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
426 qtd[qtd_counter].qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
427 token = QT_TOKEN_DT(0) | QT_TOKEN_TOTALBYTES(sizeof(*req)) |
428 QT_TOKEN_IOC(0) | QT_TOKEN_CPAGE(0) | QT_TOKEN_CERR(3) |
429 QT_TOKEN_PID(QT_TOKEN_PID_SETUP) |
430 QT_TOKEN_STATUS(QT_TOKEN_STATUS_ACTIVE);
431 qtd[qtd_counter].qt_token = cpu_to_hc32(token);
432 if (ehci_td_buffer(&qtd[qtd_counter], req, sizeof(*req))) {
433 printf("unable to construct SETUP TD\n");
434 goto fail;
435 }
436
437 *tdp = cpu_to_hc32((uint32_t)&qtd[qtd_counter]);
438 tdp = &qtd[qtd_counter++].qt_next;
439 toggle = 1;
440 }
441
442 if (length > 0 || req == NULL) {
443 uint8_t *buf_ptr = buffer;
444 int left_length = length;
445
446 do {
447
448
449
450
451 int xfr_bytes = QT_BUFFER_CNT * EHCI_PAGE_SIZE;
452
453
454
455
456
457 xfr_bytes -= (uint32_t)buf_ptr & (EHCI_PAGE_SIZE - 1);
458
459
460
461
462 xfr_bytes &= ~(PKT_ALIGN - 1);
463
464
465
466
467 xfr_bytes = min(xfr_bytes, left_length);
468
469
470
471
472
473
474
475
476
477
478 qtd[qtd_counter].qt_next =
479 cpu_to_hc32(QT_NEXT_TERMINATE);
480 qtd[qtd_counter].qt_altnext =
481 cpu_to_hc32(QT_NEXT_TERMINATE);
482 token = QT_TOKEN_DT(toggle) |
483 QT_TOKEN_TOTALBYTES(xfr_bytes) |
484 QT_TOKEN_IOC(req == NULL) | QT_TOKEN_CPAGE(0) |
485 QT_TOKEN_CERR(3) |
486 QT_TOKEN_PID(usb_pipein(pipe) ?
487 QT_TOKEN_PID_IN : QT_TOKEN_PID_OUT) |
488 QT_TOKEN_STATUS(QT_TOKEN_STATUS_ACTIVE);
489 qtd[qtd_counter].qt_token = cpu_to_hc32(token);
490 if (ehci_td_buffer(&qtd[qtd_counter], buf_ptr,
491 xfr_bytes)) {
492 printf("unable to construct DATA TD\n");
493 goto fail;
494 }
495
496 *tdp = cpu_to_hc32((uint32_t)&qtd[qtd_counter]);
497 tdp = &qtd[qtd_counter++].qt_next;
498
499
500
501
502
503 if ((xfr_bytes / maxpacket) & 1)
504 toggle ^= 1;
505 buf_ptr += xfr_bytes;
506 left_length -= xfr_bytes;
507 } while (left_length > 0);
508 }
509
510 if (req != NULL) {
511
512
513
514
515
516
517
518 qtd[qtd_counter].qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
519 qtd[qtd_counter].qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
520 token = QT_TOKEN_DT(1) | QT_TOKEN_TOTALBYTES(0) |
521 QT_TOKEN_IOC(1) | QT_TOKEN_CPAGE(0) | QT_TOKEN_CERR(3) |
522 QT_TOKEN_PID(usb_pipein(pipe) ?
523 QT_TOKEN_PID_OUT : QT_TOKEN_PID_IN) |
524 QT_TOKEN_STATUS(QT_TOKEN_STATUS_ACTIVE);
525 qtd[qtd_counter].qt_token = cpu_to_hc32(token);
526
527 *tdp = cpu_to_hc32((uint32_t)&qtd[qtd_counter]);
528 tdp = &qtd[qtd_counter++].qt_next;
529 }
530
531 ctrl->qh_list.qh_link = cpu_to_hc32((uint32_t)qh | QH_LINK_TYPE_QH);
532
533
534 flush_dcache_range((uint32_t)&ctrl->qh_list,
535 ALIGN_END_ADDR(struct QH, &ctrl->qh_list, 1));
536 flush_dcache_range((uint32_t)qh, ALIGN_END_ADDR(struct QH, qh, 1));
537 flush_dcache_range((uint32_t)qtd,
538 ALIGN_END_ADDR(struct qTD, qtd, qtd_count));
539
540
541 ehci_writel(&ctrl->hcor->or_asynclistaddr, (uint32_t)&ctrl->qh_list);
542
543 usbsts = ehci_readl(&ctrl->hcor->or_usbsts);
544 ehci_writel(&ctrl->hcor->or_usbsts, (usbsts & 0x3f));
545
546
547 cmd = ehci_readl(&ctrl->hcor->or_usbcmd);
548 cmd |= CMD_ASE;
549 ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
550
551 ret = handshake((uint32_t *)&ctrl->hcor->or_usbsts, STS_ASS, STS_ASS,
552 100 * 1000);
553 if (ret < 0) {
554 printf("EHCI fail timeout STS_ASS set\n");
555 goto fail;
556 }
557
558
559 ts = get_timer(0);
560 vtd = &qtd[qtd_counter - 1];
561 timeout = USB_TIMEOUT_MS(pipe);
562 do {
563
564 invalidate_dcache_range((uint32_t)&ctrl->qh_list,
565 ALIGN_END_ADDR(struct QH, &ctrl->qh_list, 1));
566 invalidate_dcache_range((uint32_t)qh,
567 ALIGN_END_ADDR(struct QH, qh, 1));
568 invalidate_dcache_range((uint32_t)qtd,
569 ALIGN_END_ADDR(struct qTD, qtd, qtd_count));
570
571 token = hc32_to_cpu(vtd->qt_token);
572 if (!(QT_TOKEN_GET_STATUS(token) & QT_TOKEN_STATUS_ACTIVE))
573 break;
574 WATCHDOG_RESET();
575 } while (get_timer(ts) < timeout);
576
577
578
579
580
581
582
583
584
585
586 invalidate_dcache_range((uint32_t)buffer,
587 ALIGN((uint32_t)buffer + length, ARCH_DMA_MINALIGN));
588
589
590 if (QT_TOKEN_GET_STATUS(token) & QT_TOKEN_STATUS_ACTIVE)
591 printf("EHCI timed out on TD - token=%#x\n", token);
592
593
594 cmd = ehci_readl(&ctrl->hcor->or_usbcmd);
595 cmd &= ~CMD_ASE;
596 ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
597
598 ret = handshake((uint32_t *)&ctrl->hcor->or_usbsts, STS_ASS, 0,
599 100 * 1000);
600 if (ret < 0) {
601 printf("EHCI fail timeout STS_ASS reset\n");
602 goto fail;
603 }
604
605 token = hc32_to_cpu(qh->qh_overlay.qt_token);
606 if (!(QT_TOKEN_GET_STATUS(token) & QT_TOKEN_STATUS_ACTIVE)) {
607 debug("TOKEN=%#x\n", token);
608 switch (QT_TOKEN_GET_STATUS(token) &
609 ~(QT_TOKEN_STATUS_SPLITXSTATE | QT_TOKEN_STATUS_PERR)) {
610 case 0:
611 toggle = QT_TOKEN_GET_DT(token);
612 usb_settoggle(dev, usb_pipeendpoint(pipe),
613 usb_pipeout(pipe), toggle);
614 dev->status = 0;
615 break;
616 case QT_TOKEN_STATUS_HALTED:
617 dev->status = USB_ST_STALLED;
618 break;
619 case QT_TOKEN_STATUS_ACTIVE | QT_TOKEN_STATUS_DATBUFERR:
620 case QT_TOKEN_STATUS_DATBUFERR:
621 dev->status = USB_ST_BUF_ERR;
622 break;
623 case QT_TOKEN_STATUS_HALTED | QT_TOKEN_STATUS_BABBLEDET:
624 case QT_TOKEN_STATUS_BABBLEDET:
625 dev->status = USB_ST_BABBLE_DET;
626 break;
627 default:
628 dev->status = USB_ST_CRC_ERR;
629 if (QT_TOKEN_GET_STATUS(token) & QT_TOKEN_STATUS_HALTED)
630 dev->status |= USB_ST_STALLED;
631 break;
632 }
633 dev->act_len = length - QT_TOKEN_GET_TOTALBYTES(token);
634 } else {
635 dev->act_len = 0;
636#ifndef CONFIG_USB_EHCI_FARADAY
637 debug("dev=%u, usbsts=%#x, p[1]=%#x, p[2]=%#x\n",
638 dev->devnum, ehci_readl(&ctrl->hcor->or_usbsts),
639 ehci_readl(&ctrl->hcor->or_portsc[0]),
640 ehci_readl(&ctrl->hcor->or_portsc[1]));
641#endif
642 }
643
644 free(qtd);
645 return (dev->status != USB_ST_NOT_PROC) ? 0 : -1;
646
647fail:
648 free(qtd);
649 return -1;
650}
651
652__weak uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port)
653{
654 if (port < 0 || port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
655
656 debug("The request port(%u) is not configured\n", port);
657 return NULL;
658 }
659
660 return (uint32_t *)&hcor->or_portsc[port];
661}
662
663int
664ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
665 int length, struct devrequest *req)
666{
667 uint8_t tmpbuf[4];
668 u16 typeReq;
669 void *srcptr = NULL;
670 int len, srclen;
671 uint32_t reg;
672 uint32_t *status_reg;
673 int port = le16_to_cpu(req->index) & 0xff;
674 struct ehci_ctrl *ctrl = dev->controller;
675
676 srclen = 0;
677
678 debug("req=%u (%#x), type=%u (%#x), value=%u, index=%u\n",
679 req->request, req->request,
680 req->requesttype, req->requesttype,
681 le16_to_cpu(req->value), le16_to_cpu(req->index));
682
683 typeReq = req->request | req->requesttype << 8;
684
685 switch (typeReq) {
686 case USB_REQ_GET_STATUS | ((USB_RT_PORT | USB_DIR_IN) << 8):
687 case USB_REQ_SET_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
688 case USB_REQ_CLEAR_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
689 status_reg = ehci_get_portsc_register(ctrl->hcor, port - 1);
690 if (!status_reg)
691 return -1;
692 break;
693 default:
694 status_reg = NULL;
695 break;
696 }
697
698 switch (typeReq) {
699 case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
700 switch (le16_to_cpu(req->value) >> 8) {
701 case USB_DT_DEVICE:
702 debug("USB_DT_DEVICE request\n");
703 srcptr = &descriptor.device;
704 srclen = descriptor.device.bLength;
705 break;
706 case USB_DT_CONFIG:
707 debug("USB_DT_CONFIG config\n");
708 srcptr = &descriptor.config;
709 srclen = descriptor.config.bLength +
710 descriptor.interface.bLength +
711 descriptor.endpoint.bLength;
712 break;
713 case USB_DT_STRING:
714 debug("USB_DT_STRING config\n");
715 switch (le16_to_cpu(req->value) & 0xff) {
716 case 0:
717 srcptr = "\4\3\1\0";
718 srclen = 4;
719 break;
720 case 1:
721 srcptr = "\16\3u\0-\0b\0o\0o\0t\0";
722 srclen = 14;
723 break;
724 case 2:
725 srcptr = "\52\3E\0H\0C\0I\0 "
726 "\0H\0o\0s\0t\0 "
727 "\0C\0o\0n\0t\0r\0o\0l\0l\0e\0r\0";
728 srclen = 42;
729 break;
730 default:
731 debug("unknown value DT_STRING %x\n",
732 le16_to_cpu(req->value));
733 goto unknown;
734 }
735 break;
736 default:
737 debug("unknown value %x\n", le16_to_cpu(req->value));
738 goto unknown;
739 }
740 break;
741 case USB_REQ_GET_DESCRIPTOR | ((USB_DIR_IN | USB_RT_HUB) << 8):
742 switch (le16_to_cpu(req->value) >> 8) {
743 case USB_DT_HUB:
744 debug("USB_DT_HUB config\n");
745 srcptr = &descriptor.hub;
746 srclen = descriptor.hub.bLength;
747 break;
748 default:
749 debug("unknown value %x\n", le16_to_cpu(req->value));
750 goto unknown;
751 }
752 break;
753 case USB_REQ_SET_ADDRESS | (USB_RECIP_DEVICE << 8):
754 debug("USB_REQ_SET_ADDRESS\n");
755 ctrl->rootdev = le16_to_cpu(req->value);
756 break;
757 case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
758 debug("USB_REQ_SET_CONFIGURATION\n");
759
760 break;
761 case USB_REQ_GET_STATUS | ((USB_DIR_IN | USB_RT_HUB) << 8):
762 tmpbuf[0] = 1;
763 tmpbuf[1] = 0;
764 srcptr = tmpbuf;
765 srclen = 2;
766 break;
767 case USB_REQ_GET_STATUS | ((USB_RT_PORT | USB_DIR_IN) << 8):
768 memset(tmpbuf, 0, 4);
769 reg = ehci_readl(status_reg);
770 if (reg & EHCI_PS_CS)
771 tmpbuf[0] |= USB_PORT_STAT_CONNECTION;
772 if (reg & EHCI_PS_PE)
773 tmpbuf[0] |= USB_PORT_STAT_ENABLE;
774 if (reg & EHCI_PS_SUSP)
775 tmpbuf[0] |= USB_PORT_STAT_SUSPEND;
776 if (reg & EHCI_PS_OCA)
777 tmpbuf[0] |= USB_PORT_STAT_OVERCURRENT;
778 if (reg & EHCI_PS_PR)
779 tmpbuf[0] |= USB_PORT_STAT_RESET;
780 if (reg & EHCI_PS_PP)
781 tmpbuf[1] |= USB_PORT_STAT_POWER >> 8;
782
783 if (ehci_is_TDI()) {
784 switch (ehci_get_port_speed(ctrl->hcor, reg)) {
785 case PORTSC_PSPD_FS:
786 break;
787 case PORTSC_PSPD_LS:
788 tmpbuf[1] |= USB_PORT_STAT_LOW_SPEED >> 8;
789 break;
790 case PORTSC_PSPD_HS:
791 default:
792 tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8;
793 break;
794 }
795 } else {
796 tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8;
797 }
798
799 if (reg & EHCI_PS_CSC)
800 tmpbuf[2] |= USB_PORT_STAT_C_CONNECTION;
801 if (reg & EHCI_PS_PEC)
802 tmpbuf[2] |= USB_PORT_STAT_C_ENABLE;
803 if (reg & EHCI_PS_OCC)
804 tmpbuf[2] |= USB_PORT_STAT_C_OVERCURRENT;
805 if (ctrl->portreset & (1 << port))
806 tmpbuf[2] |= USB_PORT_STAT_C_RESET;
807
808 srcptr = tmpbuf;
809 srclen = 4;
810 break;
811 case USB_REQ_SET_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
812 reg = ehci_readl(status_reg);
813 reg &= ~EHCI_PS_CLEAR;
814 switch (le16_to_cpu(req->value)) {
815 case USB_PORT_FEAT_ENABLE:
816 reg |= EHCI_PS_PE;
817 ehci_writel(status_reg, reg);
818 break;
819 case USB_PORT_FEAT_POWER:
820 if (HCS_PPC(ehci_readl(&ctrl->hccr->cr_hcsparams))) {
821 reg |= EHCI_PS_PP;
822 ehci_writel(status_reg, reg);
823 }
824 break;
825 case USB_PORT_FEAT_RESET:
826 if ((reg & (EHCI_PS_PE | EHCI_PS_CS)) == EHCI_PS_CS &&
827 !ehci_is_TDI() &&
828 EHCI_PS_IS_LOWSPEED(reg)) {
829
830 debug("port %d low speed --> companion\n",
831 port - 1);
832 reg |= EHCI_PS_PO;
833 ehci_writel(status_reg, reg);
834 break;
835 } else {
836 int ret;
837
838 reg |= EHCI_PS_PR;
839 reg &= ~EHCI_PS_PE;
840 ehci_writel(status_reg, reg);
841
842
843
844
845
846 ehci_powerup_fixup(status_reg, ®);
847
848 ehci_writel(status_reg, reg & ~EHCI_PS_PR);
849
850
851
852
853
854 ret = handshake(status_reg, EHCI_PS_PR, 0,
855 2 * 1000);
856 if (!ret)
857 ctrl->portreset |= 1 << port;
858 else
859 printf("port(%d) reset error\n",
860 port - 1);
861 }
862 break;
863 case USB_PORT_FEAT_TEST:
864 ehci_shutdown(ctrl);
865 reg &= ~(0xf << 16);
866 reg |= ((le16_to_cpu(req->index) >> 8) & 0xf) << 16;
867 ehci_writel(status_reg, reg);
868 break;
869 default:
870 debug("unknown feature %x\n", le16_to_cpu(req->value));
871 goto unknown;
872 }
873
874 (void) ehci_readl(&ctrl->hcor->or_usbcmd);
875 break;
876 case USB_REQ_CLEAR_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
877 reg = ehci_readl(status_reg);
878 reg &= ~EHCI_PS_CLEAR;
879 switch (le16_to_cpu(req->value)) {
880 case USB_PORT_FEAT_ENABLE:
881 reg &= ~EHCI_PS_PE;
882 break;
883 case USB_PORT_FEAT_C_ENABLE:
884 reg |= EHCI_PS_PE;
885 break;
886 case USB_PORT_FEAT_POWER:
887 if (HCS_PPC(ehci_readl(&ctrl->hccr->cr_hcsparams)))
888 reg &= ~EHCI_PS_PP;
889 break;
890 case USB_PORT_FEAT_C_CONNECTION:
891 reg |= EHCI_PS_CSC;
892 break;
893 case USB_PORT_FEAT_OVER_CURRENT:
894 reg |= EHCI_PS_OCC;
895 break;
896 case USB_PORT_FEAT_C_RESET:
897 ctrl->portreset &= ~(1 << port);
898 break;
899 default:
900 debug("unknown feature %x\n", le16_to_cpu(req->value));
901 goto unknown;
902 }
903 ehci_writel(status_reg, reg);
904
905 (void) ehci_readl(&ctrl->hcor->or_usbcmd);
906 break;
907 default:
908 debug("Unknown request\n");
909 goto unknown;
910 }
911
912 mdelay(1);
913 len = min3(srclen, (int)le16_to_cpu(req->length), length);
914 if (srcptr != NULL && len > 0)
915 memcpy(buffer, srcptr, len);
916 else
917 debug("Len is 0\n");
918
919 dev->act_len = len;
920 dev->status = 0;
921 return 0;
922
923unknown:
924 debug("requesttype=%x, request=%x, value=%x, index=%x, length=%x\n",
925 req->requesttype, req->request, le16_to_cpu(req->value),
926 le16_to_cpu(req->index), le16_to_cpu(req->length));
927
928 dev->act_len = 0;
929 dev->status = USB_ST_STALLED;
930 return -1;
931}
932
933int usb_lowlevel_stop(int index)
934{
935 ehci_shutdown(&ehcic[index]);
936 return ehci_hcd_stop(index);
937}
938
939int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
940{
941 uint32_t reg;
942 uint32_t cmd;
943 struct QH *qh_list;
944 struct QH *periodic;
945 int i;
946 int rc;
947
948 rc = ehci_hcd_init(index, init, &ehcic[index].hccr, &ehcic[index].hcor);
949 if (rc)
950 return rc;
951 if (init == USB_INIT_DEVICE)
952 goto done;
953
954
955 if (ehci_reset(index))
956 return -1;
957
958#if defined(CONFIG_EHCI_HCD_INIT_AFTER_RESET)
959 rc = ehci_hcd_init(index, init, &ehcic[index].hccr, &ehcic[index].hcor);
960 if (rc)
961 return rc;
962#endif
963
964 if (ehci_readl(&ehcic[index].hccr->cr_hccparams) & 1)
965 ehci_writel(&ehcic[index].hcor->or_ctrldssegment, 0);
966
967 qh_list = &ehcic[index].qh_list;
968
969
970 memset(qh_list, 0, sizeof(*qh_list));
971 qh_list->qh_link = cpu_to_hc32((uint32_t)qh_list | QH_LINK_TYPE_QH);
972 qh_list->qh_endpt1 = cpu_to_hc32(QH_ENDPT1_H(1) |
973 QH_ENDPT1_EPS(USB_SPEED_HIGH));
974 qh_list->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
975 qh_list->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
976 qh_list->qh_overlay.qt_token =
977 cpu_to_hc32(QT_TOKEN_STATUS(QT_TOKEN_STATUS_HALTED));
978
979 flush_dcache_range((uint32_t)qh_list,
980 ALIGN_END_ADDR(struct QH, qh_list, 1));
981
982
983 ehci_writel(&ehcic[index].hcor->or_asynclistaddr, (uint32_t)qh_list);
984
985
986
987
988
989 ehcic[index].periodic_schedules = 0;
990 periodic = &ehcic[index].periodic_queue;
991 memset(periodic, 0, sizeof(*periodic));
992 periodic->qh_link = cpu_to_hc32(QH_LINK_TERMINATE);
993 periodic->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
994 periodic->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
995
996 flush_dcache_range((uint32_t)periodic,
997 ALIGN_END_ADDR(struct QH, periodic, 1));
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008 if (ehcic[index].periodic_list == NULL)
1009 ehcic[index].periodic_list = memalign(4096, 1024 * 4);
1010
1011 if (!ehcic[index].periodic_list)
1012 return -ENOMEM;
1013 for (i = 0; i < 1024; i++) {
1014 ehcic[index].periodic_list[i] = cpu_to_hc32((uint32_t)periodic
1015 | QH_LINK_TYPE_QH);
1016 }
1017
1018 flush_dcache_range((uint32_t)ehcic[index].periodic_list,
1019 ALIGN_END_ADDR(uint32_t, ehcic[index].periodic_list,
1020 1024));
1021
1022
1023 ehci_writel(&ehcic[index].hcor->or_periodiclistbase,
1024 (uint32_t)ehcic[index].periodic_list);
1025
1026 reg = ehci_readl(&ehcic[index].hccr->cr_hcsparams);
1027 descriptor.hub.bNbrPorts = HCS_N_PORTS(reg);
1028 debug("Register %x NbrPorts %d\n", reg, descriptor.hub.bNbrPorts);
1029
1030 if (HCS_INDICATOR(reg))
1031 put_unaligned(get_unaligned(&descriptor.hub.wHubCharacteristics)
1032 | 0x80, &descriptor.hub.wHubCharacteristics);
1033
1034 if (HCS_PPC(reg))
1035 put_unaligned(get_unaligned(&descriptor.hub.wHubCharacteristics)
1036 | 0x01, &descriptor.hub.wHubCharacteristics);
1037
1038
1039 cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
1040
1041
1042
1043
1044 cmd &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET);
1045 cmd |= CMD_RUN;
1046 ehci_writel(&ehcic[index].hcor->or_usbcmd, cmd);
1047
1048#ifndef CONFIG_USB_EHCI_FARADAY
1049
1050 cmd = ehci_readl(&ehcic[index].hcor->or_configflag);
1051 cmd |= FLAG_CF;
1052 ehci_writel(&ehcic[index].hcor->or_configflag, cmd);
1053#endif
1054
1055
1056 cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
1057 mdelay(5);
1058 reg = HC_VERSION(ehci_readl(&ehcic[index].hccr->cr_capbase));
1059 printf("USB EHCI %x.%02x\n", reg >> 8, reg & 0xff);
1060
1061 ehcic[index].rootdev = 0;
1062done:
1063 *controller = &ehcic[index];
1064 return 0;
1065}
1066
1067int
1068submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
1069 int length)
1070{
1071
1072 if (usb_pipetype(pipe) != PIPE_BULK) {
1073 debug("non-bulk pipe (type=%lu)", usb_pipetype(pipe));
1074 return -1;
1075 }
1076 return ehci_submit_async(dev, pipe, buffer, length, NULL);
1077}
1078
1079int
1080submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
1081 int length, struct devrequest *setup)
1082{
1083 struct ehci_ctrl *ctrl = dev->controller;
1084
1085 if (usb_pipetype(pipe) != PIPE_CONTROL) {
1086 debug("non-control pipe (type=%lu)", usb_pipetype(pipe));
1087 return -1;
1088 }
1089
1090 if (usb_pipedevice(pipe) == ctrl->rootdev) {
1091 if (!ctrl->rootdev)
1092 dev->speed = USB_SPEED_HIGH;
1093 return ehci_submit_root(dev, pipe, buffer, length, setup);
1094 }
1095 return ehci_submit_async(dev, pipe, buffer, length, setup);
1096}
1097
1098struct int_queue {
1099 int elementsize;
1100 struct QH *first;
1101 struct QH *current;
1102 struct QH *last;
1103 struct qTD *tds;
1104};
1105
1106#define NEXT_QH(qh) (struct QH *)(hc32_to_cpu((qh)->qh_link) & ~0x1f)
1107
1108static int
1109enable_periodic(struct ehci_ctrl *ctrl)
1110{
1111 uint32_t cmd;
1112 struct ehci_hcor *hcor = ctrl->hcor;
1113 int ret;
1114
1115 cmd = ehci_readl(&hcor->or_usbcmd);
1116 cmd |= CMD_PSE;
1117 ehci_writel(&hcor->or_usbcmd, cmd);
1118
1119 ret = handshake((uint32_t *)&hcor->or_usbsts,
1120 STS_PSS, STS_PSS, 100 * 1000);
1121 if (ret < 0) {
1122 printf("EHCI failed: timeout when enabling periodic list\n");
1123 return -ETIMEDOUT;
1124 }
1125 udelay(1000);
1126 return 0;
1127}
1128
1129static int
1130disable_periodic(struct ehci_ctrl *ctrl)
1131{
1132 uint32_t cmd;
1133 struct ehci_hcor *hcor = ctrl->hcor;
1134 int ret;
1135
1136 cmd = ehci_readl(&hcor->or_usbcmd);
1137 cmd &= ~CMD_PSE;
1138 ehci_writel(&hcor->or_usbcmd, cmd);
1139
1140 ret = handshake((uint32_t *)&hcor->or_usbsts,
1141 STS_PSS, 0, 100 * 1000);
1142 if (ret < 0) {
1143 printf("EHCI failed: timeout when disabling periodic list\n");
1144 return -ETIMEDOUT;
1145 }
1146 return 0;
1147}
1148
1149struct int_queue *
1150create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize,
1151 int elementsize, void *buffer)
1152{
1153 struct ehci_ctrl *ctrl = dev->controller;
1154 struct int_queue *result = NULL;
1155 int i;
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168 if (elementsize > usb_maxpacket(dev, pipe)) {
1169 printf("%s: xfers requiring several transactions are not supported.\n",
1170 __func__);
1171 return NULL;
1172 }
1173
1174 debug("Enter create_int_queue\n");
1175 if (usb_pipetype(pipe) != PIPE_INTERRUPT) {
1176 debug("non-interrupt pipe (type=%lu)", usb_pipetype(pipe));
1177 return NULL;
1178 }
1179
1180
1181
1182
1183
1184 if (elementsize >= 16384) {
1185 debug("too large elements for interrupt transfers\n");
1186 return NULL;
1187 }
1188
1189 result = malloc(sizeof(*result));
1190 if (!result) {
1191 debug("ehci intr queue: out of memory\n");
1192 goto fail1;
1193 }
1194 result->elementsize = elementsize;
1195 result->first = memalign(USB_DMA_MINALIGN,
1196 sizeof(struct QH) * queuesize);
1197 if (!result->first) {
1198 debug("ehci intr queue: out of memory\n");
1199 goto fail2;
1200 }
1201 result->current = result->first;
1202 result->last = result->first + queuesize - 1;
1203 result->tds = memalign(USB_DMA_MINALIGN,
1204 sizeof(struct qTD) * queuesize);
1205 if (!result->tds) {
1206 debug("ehci intr queue: out of memory\n");
1207 goto fail3;
1208 }
1209 memset(result->first, 0, sizeof(struct QH) * queuesize);
1210 memset(result->tds, 0, sizeof(struct qTD) * queuesize);
1211
1212 for (i = 0; i < queuesize; i++) {
1213 struct QH *qh = result->first + i;
1214 struct qTD *td = result->tds + i;
1215 void **buf = &qh->buffer;
1216
1217 qh->qh_link = cpu_to_hc32((uint32_t)(qh+1) | QH_LINK_TYPE_QH);
1218 if (i == queuesize - 1)
1219 qh->qh_link = cpu_to_hc32(QH_LINK_TERMINATE);
1220
1221 qh->qh_overlay.qt_next = cpu_to_hc32((uint32_t)td);
1222 qh->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
1223 qh->qh_endpt1 =
1224 cpu_to_hc32((0 << 28) |
1225 (usb_maxpacket(dev, pipe) << 16) |
1226 (1 << 14) |
1227 QH_ENDPT1_EPS(ehci_encode_speed(dev->speed)) |
1228 (usb_pipeendpoint(pipe) << 8) |
1229 (usb_pipedevice(pipe) << 0));
1230 qh->qh_endpt2 = cpu_to_hc32((1 << 30) |
1231 (1 << 0));
1232 if (dev->speed == USB_SPEED_LOW ||
1233 dev->speed == USB_SPEED_FULL) {
1234
1235 qh->qh_endpt2 |= cpu_to_hc32((0x1c << 8));
1236 }
1237 ehci_update_endpt2_dev_n_port(dev, qh);
1238
1239 td->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
1240 td->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
1241 debug("communication direction is '%s'\n",
1242 usb_pipein(pipe) ? "in" : "out");
1243 td->qt_token = cpu_to_hc32((elementsize << 16) |
1244 ((usb_pipein(pipe) ? 1 : 0) << 8) |
1245 0x80);
1246 td->qt_buffer[0] =
1247 cpu_to_hc32((uint32_t)buffer + i * elementsize);
1248 td->qt_buffer[1] =
1249 cpu_to_hc32((td->qt_buffer[0] + 0x1000) & ~0xfff);
1250 td->qt_buffer[2] =
1251 cpu_to_hc32((td->qt_buffer[0] + 0x2000) & ~0xfff);
1252 td->qt_buffer[3] =
1253 cpu_to_hc32((td->qt_buffer[0] + 0x3000) & ~0xfff);
1254 td->qt_buffer[4] =
1255 cpu_to_hc32((td->qt_buffer[0] + 0x4000) & ~0xfff);
1256
1257 *buf = buffer + i * elementsize;
1258 }
1259
1260 flush_dcache_range((uint32_t)buffer,
1261 ALIGN_END_ADDR(char, buffer,
1262 queuesize * elementsize));
1263 flush_dcache_range((uint32_t)result->first,
1264 ALIGN_END_ADDR(struct QH, result->first,
1265 queuesize));
1266 flush_dcache_range((uint32_t)result->tds,
1267 ALIGN_END_ADDR(struct qTD, result->tds,
1268 queuesize));
1269
1270 if (ctrl->periodic_schedules > 0) {
1271 if (disable_periodic(ctrl) < 0) {
1272 debug("FATAL: periodic should never fail, but did");
1273 goto fail3;
1274 }
1275 }
1276
1277
1278 struct QH *list = &ctrl->periodic_queue;
1279 result->last->qh_link = list->qh_link;
1280 list->qh_link = cpu_to_hc32((uint32_t)result->first | QH_LINK_TYPE_QH);
1281
1282 flush_dcache_range((uint32_t)result->last,
1283 ALIGN_END_ADDR(struct QH, result->last, 1));
1284 flush_dcache_range((uint32_t)list,
1285 ALIGN_END_ADDR(struct QH, list, 1));
1286
1287 if (enable_periodic(ctrl) < 0) {
1288 debug("FATAL: periodic should never fail, but did");
1289 goto fail3;
1290 }
1291 ctrl->periodic_schedules++;
1292
1293 debug("Exit create_int_queue\n");
1294 return result;
1295fail3:
1296 if (result->tds)
1297 free(result->tds);
1298fail2:
1299 if (result->first)
1300 free(result->first);
1301 if (result)
1302 free(result);
1303fail1:
1304 return NULL;
1305}
1306
1307void *poll_int_queue(struct usb_device *dev, struct int_queue *queue)
1308{
1309 struct QH *cur = queue->current;
1310 struct qTD *cur_td;
1311
1312
1313 if (cur == NULL) {
1314 debug("Exit poll_int_queue with completed queue\n");
1315 return NULL;
1316 }
1317
1318 cur_td = &queue->tds[queue->current - queue->first];
1319 invalidate_dcache_range((uint32_t)cur_td,
1320 ALIGN_END_ADDR(struct qTD, cur_td, 1));
1321 if (QT_TOKEN_GET_STATUS(hc32_to_cpu(cur_td->qt_token)) &
1322 QT_TOKEN_STATUS_ACTIVE) {
1323 debug("Exit poll_int_queue with no completed intr transfer. token is %x\n",
1324 hc32_to_cpu(cur_td->qt_token));
1325 return NULL;
1326 }
1327 if (!(cur->qh_link & QH_LINK_TERMINATE))
1328 queue->current++;
1329 else
1330 queue->current = NULL;
1331
1332 invalidate_dcache_range((uint32_t)cur->buffer,
1333 ALIGN_END_ADDR(char, cur->buffer,
1334 queue->elementsize));
1335
1336 debug("Exit poll_int_queue with completed intr transfer. token is %x at %p (first at %p)\n",
1337 hc32_to_cpu(cur_td->qt_token), cur, queue->first);
1338 return cur->buffer;
1339}
1340
1341
1342int
1343destroy_int_queue(struct usb_device *dev, struct int_queue *queue)
1344{
1345 struct ehci_ctrl *ctrl = dev->controller;
1346 int result = -1;
1347 unsigned long timeout;
1348
1349 if (disable_periodic(ctrl) < 0) {
1350 debug("FATAL: periodic should never fail, but did");
1351 goto out;
1352 }
1353 ctrl->periodic_schedules--;
1354
1355 struct QH *cur = &ctrl->periodic_queue;
1356 timeout = get_timer(0) + 500;
1357 while (!(cur->qh_link & cpu_to_hc32(QH_LINK_TERMINATE))) {
1358 debug("considering %p, with qh_link %x\n", cur, cur->qh_link);
1359 if (NEXT_QH(cur) == queue->first) {
1360 debug("found candidate. removing from chain\n");
1361 cur->qh_link = queue->last->qh_link;
1362 flush_dcache_range((uint32_t)cur,
1363 ALIGN_END_ADDR(struct QH, cur, 1));
1364 result = 0;
1365 break;
1366 }
1367 cur = NEXT_QH(cur);
1368 if (get_timer(0) > timeout) {
1369 printf("Timeout destroying interrupt endpoint queue\n");
1370 result = -1;
1371 goto out;
1372 }
1373 }
1374
1375 if (ctrl->periodic_schedules > 0) {
1376 result = enable_periodic(ctrl);
1377 if (result < 0)
1378 debug("FATAL: periodic should never fail, but did");
1379 }
1380
1381out:
1382 free(queue->tds);
1383 free(queue->first);
1384 free(queue);
1385
1386 return result;
1387}
1388
1389int
1390submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
1391 int length, int interval)
1392{
1393 void *backbuffer;
1394 struct int_queue *queue;
1395 unsigned long timeout;
1396 int result = 0, ret;
1397
1398 debug("dev=%p, pipe=%lu, buffer=%p, length=%d, interval=%d",
1399 dev, pipe, buffer, length, interval);
1400
1401 queue = create_int_queue(dev, pipe, 1, length, buffer);
1402 if (!queue)
1403 return -1;
1404
1405 timeout = get_timer(0) + USB_TIMEOUT_MS(pipe);
1406 while ((backbuffer = poll_int_queue(dev, queue)) == NULL)
1407 if (get_timer(0) > timeout) {
1408 printf("Timeout poll on interrupt endpoint\n");
1409 result = -ETIMEDOUT;
1410 break;
1411 }
1412
1413 if (backbuffer != buffer) {
1414 debug("got wrong buffer back (%x instead of %x)\n",
1415 (uint32_t)backbuffer, (uint32_t)buffer);
1416 return -EINVAL;
1417 }
1418
1419 ret = destroy_int_queue(dev, queue);
1420 if (ret < 0)
1421 return ret;
1422
1423
1424 return result;
1425}
1426