1/*- 2 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. 3 * Copyright (c) 2004 The NetBSD Foundation, Inc. All rights reserved. 4 * Copyright (c) 2004 Lennart Augustsson. All rights reserved. 5 * Copyright (c) 2004 Charles M. Hannum. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 30 unchanged lines hidden (view full) --- 39 */ 40 41/* 42 * TODO: 43 * 1) command failures are not recovered correctly 44 */ 45 46#include <sys/cdefs.h> |
47__FBSDID("$FreeBSD: head/sys/dev/usb/controller/ehci.c 194228 2009-06-15 01:02:43Z thompsa $"); |
48 49#include <dev/usb/usb.h> 50#include <dev/usb/usb_mfunc.h> 51#include <dev/usb/usb_error.h> 52 53#define USB_DEBUG_VAR ehcidebug 54 55#include <dev/usb/usb_core.h> --- 92 unchanged lines hidden (view full) --- 148usb_error_t 149ehci_reset(ehci_softc_t *sc) 150{ 151 uint32_t hcr; 152 int i; 153 154 EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET); 155 for (i = 0; i < 100; i++) { |
156 usb_pause_mtx(NULL, hz / 1000); |
157 hcr = EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_HCRESET; 158 if (!hcr) { 159 if (sc->sc_flags & (EHCI_SCFLG_SETMODE | EHCI_SCFLG_BIGEMMIO)) { 160 /* 161 * Force USBMODE as requested. Controllers 162 * may have multiple operating modes. 163 */ 164 uint32_t usbmode = EOREAD4(sc, EHCI_USBMODE); --- 19 unchanged lines hidden (view full) --- 184static usb_error_t 185ehci_hcreset(ehci_softc_t *sc) 186{ 187 uint32_t hcr; 188 int i; 189 190 EOWRITE4(sc, EHCI_USBCMD, 0); /* Halt controller */ 191 for (i = 0; i < 100; i++) { |
192 usb_pause_mtx(NULL, hz / 1000); |
193 hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH; 194 if (hcr) 195 break; 196 } 197 if (!hcr) 198 /* 199 * Fall through and try reset anyway even though 200 * Table 2-9 in the EHCI spec says this will result --- 15 unchanged lines hidden (view full) --- 216 uint16_t i; 217 uint16_t x; 218 uint16_t y; 219 uint16_t bit; 220 usb_error_t err = 0; 221 222 DPRINTF("start\n"); 223 |
224 usb_callout_init_mtx(&sc->sc_tmo_pcd, &sc->sc_bus.bus_mtx, 0); |
225 226#if USB_DEBUG 227 if (ehcidebug > 2) { 228 ehci_dump_regs(sc); 229 } 230#endif 231 232 sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH); --- 36 unchanged lines hidden (view full) --- 269 /* set up the bus struct */ 270 sc->sc_bus.methods = &ehci_bus_methods; 271 272 sc->sc_eintrs = EHCI_NORMAL_INTRS; 273 274 for (i = 0; i < EHCI_VIRTUAL_FRAMELIST_COUNT; i++) { 275 ehci_qh_t *qh; 276 |
277 usbd_get_page(sc->sc_hw.intr_start_pc + i, 0, &buf_res); |
278 279 qh = buf_res.buffer; 280 281 /* initialize page cache pointer */ 282 283 qh->page_cache = sc->sc_hw.intr_start_pc + i; 284 285 /* store a pointer to queue head */ --- 51 unchanged lines hidden (view full) --- 337 338 /* the last (1ms) QH terminates */ 339 qh->qh_link = htohc32(sc, EHCI_LINK_TERMINATE); 340 } 341 for (i = 0; i < EHCI_VIRTUAL_FRAMELIST_COUNT; i++) { 342 ehci_sitd_t *sitd; 343 ehci_itd_t *itd; 344 |
345 usbd_get_page(sc->sc_hw.isoc_fs_start_pc + i, 0, &buf_res); |
346 347 sitd = buf_res.buffer; 348 349 /* initialize page cache pointer */ 350 351 sitd->page_cache = sc->sc_hw.isoc_fs_start_pc + i; 352 353 /* store a pointer to the transfer descriptor */ --- 8 unchanged lines hidden (view full) --- 362 363 sitd->sitd_back = 364 htohc32(sc, EHCI_LINK_TERMINATE); 365 366 sitd->sitd_next = 367 sc->sc_intr_p_last[i | (EHCI_VIRTUAL_FRAMELIST_COUNT / 2)]->qh_self; 368 369 |
370 usbd_get_page(sc->sc_hw.isoc_hs_start_pc + i, 0, &buf_res); |
371 372 itd = buf_res.buffer; 373 374 /* initialize page cache pointer */ 375 376 itd->page_cache = sc->sc_hw.isoc_hs_start_pc + i; 377 378 /* store a pointer to the transfer descriptor */ --- 5 unchanged lines hidden (view full) --- 384 itd->itd_self = 385 htohc32(sc, buf_res.physaddr) | 386 htohc32(sc, EHCI_LINK_ITD); 387 388 itd->itd_next = 389 sitd->sitd_self; 390 } 391 |
392 usbd_get_page(&sc->sc_hw.pframes_pc, 0, &buf_res); |
393 394 if (1) { 395 uint32_t *pframes; 396 397 pframes = buf_res.buffer; 398 399 /* 400 * execution order: 401 * pframes -> high speed isochronous -> 402 * full speed isochronous -> interrupt QH's 403 */ 404 for (i = 0; i < EHCI_FRAMELIST_COUNT; i++) { 405 pframes[i] = sc->sc_isoc_hs_p_last 406 [i & (EHCI_VIRTUAL_FRAMELIST_COUNT - 1)]->itd_self; 407 } 408 } 409 /* setup sync list pointer */ 410 EOWRITE4(sc, EHCI_PERIODICLISTBASE, buf_res.physaddr); 411 |
412 usbd_get_page(&sc->sc_hw.async_start_pc, 0, &buf_res); |
413 414 if (1) { 415 416 ehci_qh_t *qh; 417 418 qh = buf_res.buffer; 419 420 /* initialize page cache pointer */ --- 19 unchanged lines hidden (view full) --- 440 441 /* fill the overlay qTD */ 442 qh->qh_qtd.qtd_next = htohc32(sc, EHCI_LINK_TERMINATE); 443 qh->qh_qtd.qtd_altnext = htohc32(sc, EHCI_LINK_TERMINATE); 444 qh->qh_qtd.qtd_status = htohc32(sc, EHCI_QTD_HALTED); 445 } 446 /* flush all cache into memory */ 447 |
448 usb_bus_mem_flush_all(&sc->sc_bus, &ehci_iterate_hw_softc); |
449 450#if USB_DEBUG 451 if (ehcidebug) { 452 ehci_dump_sqh(sc, sc->sc_async_p_last); 453 } 454#endif 455 456 /* setup async list pointer */ --- 10 unchanged lines hidden (view full) --- 467 EHCI_CMD_ASE | 468 EHCI_CMD_PSE | 469 EHCI_CMD_RS); 470 471 /* Take over port ownership */ 472 EOWRITE4(sc, EHCI_CONFIGFLAG, EHCI_CONF_CF); 473 474 for (i = 0; i < 100; i++) { |
475 usb_pause_mtx(NULL, hz / 1000); |
476 hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH; 477 if (!hcr) { 478 break; 479 } 480 } 481 if (hcr) { 482 device_printf(sc->sc_bus.bdev, "run timeout\n"); 483 return (USB_ERR_IOERROR); --- 9 unchanged lines hidden (view full) --- 493/* 494 * shut down the controller when the system is going down 495 */ 496void 497ehci_detach(ehci_softc_t *sc) 498{ 499 USB_BUS_LOCK(&sc->sc_bus); 500 |
501 usb_callout_stop(&sc->sc_tmo_pcd); |
502 503 EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs); 504 USB_BUS_UNLOCK(&sc->sc_bus); 505 506 if (ehci_hcreset(sc)) { 507 DPRINTF("reset failed!\n"); 508 } 509 510 /* XXX let stray task complete */ |
511 usb_pause_mtx(NULL, hz / 20); |
512 |
513 usb_callout_drain(&sc->sc_tmo_pcd); |
514} 515 516void 517ehci_suspend(ehci_softc_t *sc) 518{ 519 uint32_t cmd; 520 uint32_t hcr; 521 uint8_t i; --- 16 unchanged lines hidden (view full) --- 538 539 for (i = 0; i < 100; i++) { 540 hcr = EOREAD4(sc, EHCI_USBSTS) & 541 (EHCI_STS_ASS | EHCI_STS_PSS); 542 543 if (hcr == 0) { 544 break; 545 } |
546 usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000); |
547 } 548 549 if (hcr != 0) { 550 device_printf(sc->sc_bus.bdev, "reset timeout\n"); 551 } 552 cmd &= ~EHCI_CMD_RS; 553 EOWRITE4(sc, EHCI_USBCMD, cmd); 554 555 for (i = 0; i < 100; i++) { 556 hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH; 557 if (hcr == EHCI_STS_HCH) { 558 break; 559 } |
560 usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000); |
561 } 562 563 if (hcr != EHCI_STS_HCH) { 564 device_printf(sc->sc_bus.bdev, 565 "config timeout\n"); 566 } 567 USB_BUS_UNLOCK(&sc->sc_bus); 568} --- 6 unchanged lines hidden (view full) --- 575 uint32_t hcr; 576 uint8_t i; 577 578 USB_BUS_LOCK(&sc->sc_bus); 579 580 /* restore things in case the bios doesn't */ 581 EOWRITE4(sc, EHCI_CTRLDSSEGMENT, 0); 582 |
583 usbd_get_page(&sc->sc_hw.pframes_pc, 0, &buf_res); |
584 EOWRITE4(sc, EHCI_PERIODICLISTBASE, buf_res.physaddr); 585 |
586 usbd_get_page(&sc->sc_hw.async_start_pc, 0, &buf_res); |
587 EOWRITE4(sc, EHCI_ASYNCLISTADDR, buf_res.physaddr | EHCI_LINK_QH); 588 589 EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs); 590 591 hcr = 0; 592 for (i = 1; i <= sc->sc_noport; i++) { 593 cmd = EOREAD4(sc, EHCI_PORTSC(i)); 594 if (((cmd & EHCI_PS_PO) == 0) && 595 ((cmd & EHCI_PS_SUSP) == EHCI_PS_SUSP)) { 596 EOWRITE4(sc, EHCI_PORTSC(i), 597 cmd | EHCI_PS_FPR); 598 hcr = 1; 599 } 600 } 601 602 if (hcr) { |
603 usb_pause_mtx(&sc->sc_bus.bus_mtx, |
604 USB_MS_TO_TICKS(USB_RESUME_WAIT)); 605 606 for (i = 1; i <= sc->sc_noport; i++) { 607 cmd = EOREAD4(sc, EHCI_PORTSC(i)); 608 if (((cmd & EHCI_PS_PO) == 0) && 609 ((cmd & EHCI_PS_SUSP) == EHCI_PS_SUSP)) { 610 EOWRITE4(sc, EHCI_PORTSC(i), 611 cmd & ~EHCI_PS_FPR); 612 } 613 } 614 } 615 EOWRITE4(sc, EHCI_USBCMD, sc->sc_cmd); 616 617 for (i = 0; i < 100; i++) { 618 hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH; 619 if (hcr != EHCI_STS_HCH) { 620 break; 621 } |
622 usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 1000); |
623 } 624 if (hcr == EHCI_STS_HCH) { 625 device_printf(sc->sc_bus.bdev, "config timeout\n"); 626 } 627 628 USB_BUS_UNLOCK(&sc->sc_bus); 629 |
630 usb_pause_mtx(NULL, |
631 USB_MS_TO_TICKS(USB_RESUME_WAIT)); 632 633 /* catch any lost interrupts */ 634 ehci_do_poll(&sc->sc_bus); 635} 636 637void 638ehci_shutdown(ehci_softc_t *sc) --- 149 unchanged lines hidden (view full) --- 788 } 789} 790 791static uint8_t 792ehci_dump_sqtd(ehci_softc_t *sc, ehci_qtd_t *sqtd) 793{ 794 uint8_t temp; 795 |
796 usb_pc_cpu_invalidate(sqtd->page_cache); |
797 printf("QTD(%p) at 0x%08x:\n", sqtd, hc32toh(sc, sqtd->qtd_self)); 798 ehci_dump_qtd(sc, sqtd); 799 temp = (sqtd->qtd_next & htohc32(sc, EHCI_LINK_TERMINATE)) ? 1 : 0; 800 return (temp); 801} 802 803static void 804ehci_dump_sqtds(ehci_softc_t *sc, ehci_qtd_t *sqtd) --- 11 unchanged lines hidden (view full) --- 816} 817 818static void 819ehci_dump_sqh(ehci_softc_t *sc, ehci_qh_t *qh) 820{ 821 uint32_t endp; 822 uint32_t endphub; 823 |
824 usb_pc_cpu_invalidate(qh->page_cache); |
825 printf("QH(%p) at 0x%08x:\n", qh, hc32toh(sc, qh->qh_self) & ~0x1F); 826 printf(" link="); 827 ehci_dump_link(sc, qh->qh_link, 1); 828 printf("\n"); 829 endp = hc32toh(sc, qh->qh_endp); 830 printf(" endp=0x%08x\n", endp); 831 printf(" addr=0x%02x inact=%d endpt=%d eps=%d dtc=%d hrecl=%d\n", 832 EHCI_QH_GET_ADDR(endp), EHCI_QH_GET_INACT(endp), --- 13 unchanged lines hidden (view full) --- 846 printf("\n"); 847 printf("Overlay qTD:\n"); 848 ehci_dump_qtd(sc, (void *)&qh->qh_qtd); 849} 850 851static void 852ehci_dump_sitd(ehci_softc_t *sc, ehci_sitd_t *sitd) 853{ |
854 usb_pc_cpu_invalidate(sitd->page_cache); |
855 printf("SITD(%p) at 0x%08x\n", sitd, hc32toh(sc, sitd->sitd_self) & ~0x1F); 856 printf(" next=0x%08x\n", hc32toh(sc, sitd->sitd_next)); 857 printf(" portaddr=0x%08x dir=%s addr=%d endpt=0x%x port=0x%x huba=0x%x\n", 858 hc32toh(sc, sitd->sitd_portaddr), 859 (sitd->sitd_portaddr & htohc32(sc, EHCI_SITD_SET_DIR_IN)) 860 ? "in" : "out", 861 EHCI_SITD_GET_ADDR(hc32toh(sc, sitd->sitd_portaddr)), 862 EHCI_SITD_GET_ENDPT(hc32toh(sc, sitd->sitd_portaddr)), --- 9 unchanged lines hidden (view full) --- 872 hc32toh(sc, sitd->sitd_bp[1]), 873 hc32toh(sc, sitd->sitd_bp_hi[0]), 874 hc32toh(sc, sitd->sitd_bp_hi[1])); 875} 876 877static void 878ehci_dump_itd(ehci_softc_t *sc, ehci_itd_t *itd) 879{ |
880 usb_pc_cpu_invalidate(itd->page_cache); |
881 printf("ITD(%p) at 0x%08x\n", itd, hc32toh(sc, itd->itd_self) & ~0x1F); 882 printf(" next=0x%08x\n", hc32toh(sc, itd->itd_next)); 883 printf(" status[0]=0x%08x; <%s>\n", hc32toh(sc, itd->itd_status[0]), 884 (itd->itd_status[0] & htohc32(sc, EHCI_ITD_ACTIVE)) ? "ACTIVE" : ""); 885 printf(" status[1]=0x%08x; <%s>\n", hc32toh(sc, itd->itd_status[1]), 886 (itd->itd_status[1] & htohc32(sc, EHCI_ITD_ACTIVE)) ? "ACTIVE" : ""); 887 printf(" status[2]=0x%08x; <%s>\n", hc32toh(sc, itd->itd_status[2]), 888 (itd->itd_status[2] & htohc32(sc, EHCI_ITD_ACTIVE)) ? "ACTIVE" : ""); --- 65 unchanged lines hidden (view full) --- 954static void 955ehci_transfer_intr_enqueue(struct usb_xfer *xfer) 956{ 957 /* check for early completion */ 958 if (ehci_check_transfer(xfer)) { 959 return; 960 } 961 /* put transfer on interrupt queue */ |
962 usbd_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer); |
963 964 /* start timeout, if any */ 965 if (xfer->timeout != 0) { |
966 usbd_transfer_timeout_ms(xfer, &ehci_timeout, xfer->timeout); |
967 } 968} 969 970#define EHCI_APPEND_FS_TD(std,last) (last) = _ehci_append_fs_td(std,last) 971static ehci_sitd_t * 972_ehci_append_fs_td(ehci_sitd_t *std, ehci_sitd_t *last) 973{ 974 DPRINTFN(11, "%p to %p\n", std, last); 975 976 /* (sc->sc_bus.mtx) must be locked */ 977 978 std->next = last->next; 979 std->sitd_next = last->sitd_next; 980 981 std->prev = last; 982 |
983 usb_pc_cpu_flush(std->page_cache); |
984 985 /* 986 * the last->next->prev is never followed: std->next->prev = std; 987 */ 988 last->next = std; 989 last->sitd_next = std->sitd_self; 990 |
991 usb_pc_cpu_flush(last->page_cache); |
992 993 return (std); 994} 995 996#define EHCI_APPEND_HS_TD(std,last) (last) = _ehci_append_hs_td(std,last) 997static ehci_itd_t * 998_ehci_append_hs_td(ehci_itd_t *std, ehci_itd_t *last) 999{ 1000 DPRINTFN(11, "%p to %p\n", std, last); 1001 1002 /* (sc->sc_bus.mtx) must be locked */ 1003 1004 std->next = last->next; 1005 std->itd_next = last->itd_next; 1006 1007 std->prev = last; 1008 |
1009 usb_pc_cpu_flush(std->page_cache); |
1010 1011 /* 1012 * the last->next->prev is never followed: std->next->prev = std; 1013 */ 1014 last->next = std; 1015 last->itd_next = std->itd_self; 1016 |
1017 usb_pc_cpu_flush(last->page_cache); |
1018 1019 return (std); 1020} 1021 1022#define EHCI_APPEND_QH(sqh,last) (last) = _ehci_append_qh(sqh,last) 1023static ehci_qh_t * 1024_ehci_append_qh(ehci_qh_t *sqh, ehci_qh_t *last) 1025{ --- 6 unchanged lines hidden (view full) --- 1032 } 1033 /* (sc->sc_bus.mtx) must be locked */ 1034 1035 sqh->next = last->next; 1036 sqh->qh_link = last->qh_link; 1037 1038 sqh->prev = last; 1039 |
1040 usb_pc_cpu_flush(sqh->page_cache); |
1041 1042 /* 1043 * the last->next->prev is never followed: sqh->next->prev = sqh; 1044 */ 1045 1046 last->next = sqh; 1047 last->qh_link = sqh->qh_self; 1048 |
1049 usb_pc_cpu_flush(last->page_cache); |
1050 1051 return (sqh); 1052} 1053 1054#define EHCI_REMOVE_FS_TD(std,last) (last) = _ehci_remove_fs_td(std,last) 1055static ehci_sitd_t * 1056_ehci_remove_fs_td(ehci_sitd_t *std, ehci_sitd_t *last) 1057{ 1058 DPRINTFN(11, "%p from %p\n", std, last); 1059 1060 /* (sc->sc_bus.mtx) must be locked */ 1061 1062 std->prev->next = std->next; 1063 std->prev->sitd_next = std->sitd_next; 1064 |
1065 usb_pc_cpu_flush(std->prev->page_cache); |
1066 1067 if (std->next) { 1068 std->next->prev = std->prev; |
1069 usb_pc_cpu_flush(std->next->page_cache); |
1070 } 1071 return ((last == std) ? std->prev : last); 1072} 1073 1074#define EHCI_REMOVE_HS_TD(std,last) (last) = _ehci_remove_hs_td(std,last) 1075static ehci_itd_t * 1076_ehci_remove_hs_td(ehci_itd_t *std, ehci_itd_t *last) 1077{ 1078 DPRINTFN(11, "%p from %p\n", std, last); 1079 1080 /* (sc->sc_bus.mtx) must be locked */ 1081 1082 std->prev->next = std->next; 1083 std->prev->itd_next = std->itd_next; 1084 |
1085 usb_pc_cpu_flush(std->prev->page_cache); |
1086 1087 if (std->next) { 1088 std->next->prev = std->prev; |
1089 usb_pc_cpu_flush(std->next->page_cache); |
1090 } 1091 return ((last == std) ? std->prev : last); 1092} 1093 1094#define EHCI_REMOVE_QH(sqh,last) (last) = _ehci_remove_qh(sqh,last) 1095static ehci_qh_t * 1096_ehci_remove_qh(ehci_qh_t *sqh, ehci_qh_t *last) 1097{ 1098 DPRINTFN(11, "%p from %p\n", sqh, last); 1099 1100 /* (sc->sc_bus.mtx) must be locked */ 1101 1102 /* only remove if not removed from a queue */ 1103 if (sqh->prev) { 1104 1105 sqh->prev->next = sqh->next; 1106 sqh->prev->qh_link = sqh->qh_link; 1107 |
1108 usb_pc_cpu_flush(sqh->prev->page_cache); |
1109 1110 if (sqh->next) { 1111 sqh->next->prev = sqh->prev; |
1112 usb_pc_cpu_flush(sqh->next->page_cache); |
1113 } 1114 last = ((last == sqh) ? sqh->prev : last); 1115 1116 sqh->prev = 0; 1117 |
1118 usb_pc_cpu_flush(sqh->page_cache); |
1119 } 1120 return (last); 1121} 1122 1123static usb_error_t 1124ehci_non_isoc_done_sub(struct usb_xfer *xfer) 1125{ 1126 ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus); --- 5 unchanged lines hidden (view full) --- 1132 td = xfer->td_transfer_cache; 1133 td_alt_next = td->alt_next; 1134 1135 if (xfer->aframes != xfer->nframes) { 1136 xfer->frlengths[xfer->aframes] = 0; 1137 } 1138 while (1) { 1139 |
1140 usb_pc_cpu_invalidate(td->page_cache); |
1141 status = hc32toh(sc, td->qtd_status); 1142 1143 len = EHCI_QTD_GET_BYTES(status); 1144 1145 /* 1146 * Verify the status length and 1147 * add the length to "frlengths[]": 1148 */ --- 133 unchanged lines hidden (view full) --- 1282 DPRINTFN(13, "xfer=%p checking transfer\n", xfer); 1283 1284 if (methods == &ehci_device_isoc_fs_methods) { 1285 ehci_sitd_t *td; 1286 1287 /* isochronous full speed transfer */ 1288 1289 td = xfer->td_transfer_last; |
1290 usb_pc_cpu_invalidate(td->page_cache); |
1291 status = hc32toh(sc, td->sitd_status); 1292 1293 /* also check if first is complete */ 1294 1295 td = xfer->td_transfer_first; |
1296 usb_pc_cpu_invalidate(td->page_cache); |
1297 status |= hc32toh(sc, td->sitd_status); 1298 1299 if (!(status & EHCI_SITD_ACTIVE)) { 1300 ehci_device_done(xfer, USB_ERR_NORMAL_COMPLETION); 1301 goto transferred; 1302 } 1303 } else if (methods == &ehci_device_isoc_hs_methods) { 1304 ehci_itd_t *td; 1305 1306 /* isochronous high speed transfer */ 1307 1308 td = xfer->td_transfer_last; |
1309 usb_pc_cpu_invalidate(td->page_cache); |
1310 status = 1311 td->itd_status[0] | td->itd_status[1] | 1312 td->itd_status[2] | td->itd_status[3] | 1313 td->itd_status[4] | td->itd_status[5] | 1314 td->itd_status[6] | td->itd_status[7]; 1315 1316 /* also check first transfer */ 1317 td = xfer->td_transfer_first; |
1318 usb_pc_cpu_invalidate(td->page_cache); |
1319 status |= 1320 td->itd_status[0] | td->itd_status[1] | 1321 td->itd_status[2] | td->itd_status[3] | 1322 td->itd_status[4] | td->itd_status[5] | 1323 td->itd_status[6] | td->itd_status[7]; 1324 1325 /* if no transactions are active we continue */ 1326 if (!(status & htohc32(sc, EHCI_ITD_ACTIVE))) { --- 7 unchanged lines hidden (view full) --- 1334 1335 /* 1336 * check whether there is an error somewhere in the middle, 1337 * or whether there was a short packet (SPD and not ACTIVE) 1338 */ 1339 td = xfer->td_transfer_cache; 1340 1341 while (1) { |
1342 usb_pc_cpu_invalidate(td->page_cache); |
1343 status = hc32toh(sc, td->qtd_status); 1344 1345 /* 1346 * if there is an active TD the transfer isn't done 1347 */ 1348 if (status & EHCI_QTD_ACTIVE) { 1349 /* update cache */ 1350 xfer->td_transfer_cache = td; --- 119 unchanged lines hidden (view full) --- 1470 * on until the port has been reset. 1471 */ 1472 sc->sc_eintrs &= ~EHCI_STS_PCD; 1473 EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs); 1474 1475 ehci_root_intr(sc); 1476 1477 /* do not allow RHSC interrupts > 1 per second */ |
1478 usb_callout_reset(&sc->sc_tmo_pcd, hz, |
1479 (void *)&ehci_pcd_enable, sc); 1480 } 1481 status &= ~(EHCI_STS_INT | EHCI_STS_ERRINT | EHCI_STS_PCD | EHCI_STS_IAA); 1482 1483 if (status != 0) { 1484 /* block unprocessed interrupts */ 1485 sc->sc_eintrs &= ~status; 1486 EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs); --- 142 unchanged lines hidden (view full) --- 1629 td->len = average; 1630 1631 /* update remaining length */ 1632 1633 temp->len -= average; 1634 1635 /* fill out buffer pointers */ 1636 |
1637 usbd_get_page(temp->pc, buf_offset, &buf_res); |
1638 td->qtd_buffer[0] = 1639 htohc32(temp->sc, buf_res.physaddr); 1640 td->qtd_buffer_hi[0] = 0; 1641 1642 x = 1; 1643 1644 while (average > EHCI_PAGE_SIZE) { 1645 average -= EHCI_PAGE_SIZE; 1646 buf_offset += EHCI_PAGE_SIZE; |
1647 usbd_get_page(temp->pc, buf_offset, &buf_res); |
1648 td->qtd_buffer[x] = 1649 htohc32(temp->sc, 1650 buf_res.physaddr & (~0xFFF)); 1651 td->qtd_buffer_hi[x] = 0; 1652 x++; 1653 } 1654 1655 /* 1656 * NOTE: The "average" variable is never zero after 1657 * exiting the loop above ! 1658 * 1659 * NOTE: We have to subtract one from the offset to 1660 * ensure that we are computing the physical address 1661 * of a valid page ! 1662 */ 1663 buf_offset += average; |
1664 usbd_get_page(temp->pc, buf_offset - 1, &buf_res); |
1665 td->qtd_buffer[x] = 1666 htohc32(temp->sc, 1667 buf_res.physaddr & (~0xFFF)); 1668 td->qtd_buffer_hi[x] = 0; 1669 } 1670 1671 if (td_next) { 1672 /* link the current TD with the next one */ 1673 td->qtd_next = td_next->qtd_self; 1674 } 1675 td->qtd_altnext = qtd_altnext; 1676 td->alt_next = td_alt_next; 1677 |
1678 usb_pc_cpu_flush(td->page_cache); |
1679 } 1680 1681 if (precompute) { 1682 precompute = 0; 1683 1684 /* setup alt next pointer, if any */ 1685 if (temp->last_frame) { 1686 td_alt_next = NULL; --- 25 unchanged lines hidden (view full) --- 1712 ehci_qh_t *qh; 1713 ehci_qtd_t *td; 1714 uint32_t qh_endp; 1715 uint32_t qh_endphub; 1716 uint32_t x; 1717 1718 DPRINTFN(9, "addr=%d endpt=%d sumlen=%d speed=%d\n", 1719 xfer->address, UE_GET_ADDR(xfer->endpointno), |
1720 xfer->sumlen, usbd_get_speed(xfer->xroot->udev)); |
1721 1722 temp.average = xfer->max_hc_frame_size; 1723 temp.max_frame_size = xfer->max_frame_size; 1724 temp.sc = EHCI_BUS2SC(xfer->xroot->bus); 1725 1726 /* toggle the DMA set we are using */ 1727 xfer->flags_int.curr_dma_set ^= 1; 1728 --- 15 unchanged lines hidden (view full) --- 1744 temp.qtd_status |= 1745 htohc32(temp.sc, EHCI_QTD_SET_TOGGLE(1)); 1746 } 1747 temp.auto_data_toggle = 0; 1748 } else { 1749 temp.auto_data_toggle = 1; 1750 } 1751 |
1752 if (usbd_get_speed(xfer->xroot->udev) != USB_SPEED_HIGH) { |
1753 /* max 3 retries */ 1754 temp.qtd_status |= 1755 htohc32(temp.sc, EHCI_QTD_SET_CERR(3)); 1756 } 1757 /* check if we should prepend a setup message */ 1758 1759 if (xfer->flags_int.control_xfr) { 1760 if (xfer->flags_int.control_hdr) { --- 106 unchanged lines hidden (view full) --- 1867 } 1868 td = temp.td; 1869 1870 /* the last TD terminates the transfer: */ 1871 td->qtd_next = htohc32(temp.sc, EHCI_LINK_TERMINATE); 1872 td->qtd_altnext = htohc32(temp.sc, EHCI_LINK_TERMINATE); 1873 td->qtd_status |= htohc32(temp.sc, EHCI_QTD_IOC); 1874 |
1875 usb_pc_cpu_flush(td->page_cache); |
1876 1877 /* must have at least one frame! */ 1878 1879 xfer->td_transfer_last = td; 1880 1881#if USB_DEBUG 1882 if (ehcidebug > 8) { 1883 DPRINTF("nexttog=%d; data before transfer:\n", --- 9 unchanged lines hidden (view full) --- 1893 1894 /* the "qh_link" field is filled when the QH is added */ 1895 1896 qh_endp = 1897 (EHCI_QH_SET_ADDR(xfer->address) | 1898 EHCI_QH_SET_ENDPT(UE_GET_ADDR(xfer->endpointno)) | 1899 EHCI_QH_SET_MPL(xfer->max_packet_size)); 1900 |
1901 if (usbd_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH) { |
1902 qh_endp |= (EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH) | 1903 EHCI_QH_DTC); 1904 if (methods != &ehci_device_intr_methods) 1905 qh_endp |= EHCI_QH_SET_NRL(8); 1906 } else { 1907 |
1908 if (usbd_get_speed(xfer->xroot->udev) == USB_SPEED_FULL) { |
1909 qh_endp |= (EHCI_QH_SET_EPS(EHCI_QH_SPEED_FULL) | 1910 EHCI_QH_DTC); 1911 } else { 1912 qh_endp |= (EHCI_QH_SET_EPS(EHCI_QH_SPEED_LOW) | 1913 EHCI_QH_DTC); 1914 } 1915 1916 if (methods == &ehci_device_ctrl_methods) { --- 4 unchanged lines hidden (view full) --- 1921 qh_endp |= EHCI_QH_SET_NRL(1); 1922 } 1923 } 1924 1925 qh->qh_endp = htohc32(temp.sc, qh_endp); 1926 1927 qh_endphub = 1928 (EHCI_QH_SET_MULT(xfer->max_packet_count & 3) | |
1929 EHCI_QH_SET_CMASK(xfer->usb_cmask) | 1930 EHCI_QH_SET_SMASK(xfer->usb_smask) | |
1931 EHCI_QH_SET_HUBA(xfer->xroot->udev->hs_hub_addr) | 1932 EHCI_QH_SET_PORT(xfer->xroot->udev->hs_port_no)); 1933 1934 qh->qh_endphub = htohc32(temp.sc, qh_endphub); 1935 qh->qh_curqtd = htohc32(temp.sc, 0); 1936 1937 /* fill the overlay qTD */ 1938 qh->qh_qtd.qtd_status = htohc32(temp.sc, 0); --- 11 unchanged lines hidden (view full) --- 1950 } 1951 } 1952 td = xfer->td_transfer_first; 1953 1954 qh->qh_qtd.qtd_next = td->qtd_self; 1955 qh->qh_qtd.qtd_altnext = 1956 htohc32(temp.sc, EHCI_LINK_TERMINATE); 1957 |
1958 usb_pc_cpu_flush(qh->page_cache); |
1959 1960 if (xfer->xroot->udev->flags.self_suspended == 0) { 1961 EHCI_APPEND_QH(qh, *qh_last); 1962 } 1963} 1964 1965static void 1966ehci_root_intr(ehci_softc_t *sc) --- 44 unchanged lines hidden (view full) --- 2011 pp_last = &sc->sc_isoc_fs_p_last[0]; 2012 } 2013#if USB_DEBUG 2014 if (ehcidebug > 15) { 2015 DPRINTF("isoc FS-TD\n"); 2016 ehci_dump_sitd(sc, td); 2017 } 2018#endif |
2019 usb_pc_cpu_invalidate(td->page_cache); |
2020 status = hc32toh(sc, td->sitd_status); 2021 2022 len = EHCI_SITD_GET_LEN(status); 2023 2024 DPRINTFN(2, "status=0x%08x, rem=%u\n", status, len); 2025 2026 if (*plen >= len) { 2027 len = *plen - len; --- 38 unchanged lines hidden (view full) --- 2066 } 2067#if USB_DEBUG 2068 if (ehcidebug > 15) { 2069 DPRINTF("isoc HS-TD\n"); 2070 ehci_dump_itd(sc, td); 2071 } 2072#endif 2073 |
2074 usb_pc_cpu_invalidate(td->page_cache); |
2075 status = hc32toh(sc, td->itd_status[td_no]); 2076 2077 len = EHCI_ITD_GET_LEN(status); 2078 2079 DPRINTFN(2, "status=0x%08x, len=%u\n", status, len); 2080 2081 if (*plen >= len) { 2082 /* --- 67 unchanged lines hidden (view full) --- 2150 } 2151 if (methods == &ehci_device_isoc_hs_methods) { 2152 ehci_isoc_hs_done(sc, xfer); 2153 } 2154 xfer->td_transfer_first = NULL; 2155 xfer->td_transfer_last = NULL; 2156 } 2157 /* dequeue transfer and start next transfer */ |
2158 usbd_transfer_done(xfer, error); |
2159} 2160 2161/*------------------------------------------------------------------------* 2162 * ehci bulk support 2163 *------------------------------------------------------------------------*/ 2164static void 2165ehci_device_bulk_open(struct usb_xfer *xfer) 2166{ --- 91 unchanged lines hidden (view full) --- 2258 ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus); 2259 uint16_t best; 2260 uint16_t bit; 2261 uint16_t x; 2262 uint8_t slot; 2263 2264 /* Allocate a microframe slot first: */ 2265 |
2266 slot = usb_intr_schedule_adjust |
2267 (xfer->xroot->udev, xfer->max_frame_size, USB_HS_MICRO_FRAMES_MAX); 2268 |
2269 if (usbd_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH) { 2270 xfer->usb_uframe = slot; 2271 xfer->usb_smask = (1 << slot) & 0xFF; 2272 xfer->usb_cmask = 0; |
2273 } else { |
2274 xfer->usb_uframe = slot; 2275 xfer->usb_smask = (1 << slot) & 0x3F; 2276 xfer->usb_cmask = (-(4 << slot)) & 0xFE; |
2277 } 2278 2279 /* 2280 * Find the best QH position corresponding to the given interval: 2281 */ 2282 2283 best = 0; 2284 bit = EHCI_VIRTUAL_FRAMELIST_COUNT / 2; --- 21 unchanged lines hidden (view full) --- 2306} 2307 2308static void 2309ehci_device_intr_close(struct usb_xfer *xfer) 2310{ 2311 ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus); 2312 uint8_t slot; 2313 |
2314 slot = usb_intr_schedule_adjust 2315 (xfer->xroot->udev, -(xfer->max_frame_size), xfer->usb_uframe); |
2316 2317 sc->sc_intr_stat[xfer->qh_pos]--; 2318 2319 ehci_device_done(xfer, USB_ERR_CANCELLED); 2320} 2321 2322static void 2323ehci_device_intr_enter(struct usb_xfer *xfer) --- 55 unchanged lines hidden (view full) --- 2379 * TODO: make some kind of automatic 2380 * SMASK/CMASK selection based on micro-frame 2381 * usage 2382 * 2383 * micro-frame usage (8 microframes per 1ms) 2384 */ 2385 td->sitd_back = htohc32(sc, EHCI_LINK_TERMINATE); 2386 |
2387 usb_pc_cpu_flush(td->page_cache); |
2388 } 2389 } 2390} 2391 2392static void 2393ehci_device_isoc_fs_close(struct usb_xfer *xfer) 2394{ 2395 ehci_device_done(xfer, USB_ERR_CANCELLED); --- 58 unchanged lines hidden (view full) --- 2454 */ 2455 buf_offset = (xfer->endpoint->isoc_next - nframes) & 2456 (EHCI_VIRTUAL_FRAMELIST_COUNT - 1); 2457 2458 /* 2459 * pre-compute when the isochronous transfer will be finished: 2460 */ 2461 xfer->isoc_time_complete = |
2462 usbd_fs_isoc_schedule_isoc_time_expand |
2463 (xfer->xroot->udev, &fss_start, &fss_end, nframes) + buf_offset + 2464 xfer->nframes; 2465 2466 /* get the real number of frames */ 2467 2468 nframes = xfer->nframes; 2469 2470 buf_offset = 0; --- 39 unchanged lines hidden (view full) --- 2510 } 2511#endif 2512 *plen = xfer->max_frame_size; 2513 } 2514 /* 2515 * We currently don't care if the ISOCHRONOUS schedule is 2516 * full! 2517 */ |
2518 error = usbd_fs_isoc_schedule_alloc(fss, &sa, *plen); |
2519 if (error) { 2520 /* 2521 * The FULL speed schedule is FULL! Set length 2522 * to zero. 2523 */ 2524 *plen = 0; 2525 } 2526 if (*plen) { 2527 /* |
2528 * only call "usbd_get_page()" when we have a |
2529 * non-zero length 2530 */ |
2531 usbd_get_page(xfer->frbuffers, buf_offset, &buf_res); |
2532 td->sitd_bp[0] = htohc32(sc, buf_res.physaddr); 2533 buf_offset += *plen; 2534 /* 2535 * NOTE: We need to subtract one from the offset so 2536 * that we are on a valid page! 2537 */ |
2538 usbd_get_page(xfer->frbuffers, buf_offset - 1, |
2539 &buf_res); 2540 temp = buf_res.physaddr & ~0xFFF; 2541 } else { 2542 td->sitd_bp[0] = 0; 2543 temp = 0; 2544 } 2545 2546 if (UE_GET_DIR(xfer->endpointno) == UE_DIR_OUT) { --- 36 unchanged lines hidden (view full) --- 2583 EHCI_SITD_IOC | 2584 EHCI_SITD_ACTIVE | 2585 EHCI_SITD_SET_LEN(*plen)); 2586 } else { 2587 td->sitd_status = htohc32(sc, 2588 EHCI_SITD_ACTIVE | 2589 EHCI_SITD_SET_LEN(*plen)); 2590 } |
2591 usb_pc_cpu_flush(td->page_cache); |
2592 2593#if USB_DEBUG 2594 if (ehcidebug > 15) { 2595 DPRINTF("FS-TD %d\n", nframes); 2596 ehci_dump_sitd(sc, td); 2597 } 2598#endif 2599 /* insert TD into schedule */ --- 68 unchanged lines hidden (view full) --- 2668 temp |= EHCI_ITD_SET_DIR_IN; 2669 } 2670 /* set maximum packet size */ 2671 td->itd_bp[1] = htohc32(sc, temp); 2672 2673 /* set transfer multiplier */ 2674 td->itd_bp[2] = htohc32(sc, xfer->max_packet_count & 3); 2675 |
2676 usb_pc_cpu_flush(td->page_cache); |
2677 } 2678 } 2679} 2680 2681static void 2682ehci_device_isoc_hs_close(struct usb_xfer *xfer) 2683{ 2684 ehci_device_done(xfer, USB_ERR_CANCELLED); --- 55 unchanged lines hidden (view full) --- 2740 */ 2741 buf_offset = (xfer->endpoint->isoc_next - nframes) & 2742 (EHCI_VIRTUAL_FRAMELIST_COUNT - 1); 2743 2744 /* 2745 * pre-compute when the isochronous transfer will be finished: 2746 */ 2747 xfer->isoc_time_complete = |
2748 usb_isoc_time_expand(&sc->sc_bus, nframes) + buf_offset + |
2749 ((xfer->nframes + 7) / 8); 2750 2751 /* get the real number of frames */ 2752 2753 nframes = xfer->nframes; 2754 2755 buf_offset = 0; 2756 td_no = 0; --- 50 unchanged lines hidden (view full) --- 2807 } 2808 2809 /* check if there is any data to be transferred */ 2810 if (itd_offset[0] != buf_offset) { 2811 page_no = 0; 2812 itd_offset[td_no] = buf_offset; 2813 2814 /* get first page offset */ |
2815 usbd_get_page(xfer->frbuffers, itd_offset[0], &buf_res); |
2816 /* get page address */ 2817 page_addr = buf_res.physaddr & ~0xFFF; 2818 /* update page address */ 2819 td->itd_bp[0] &= htohc32(sc, 0xFFF); 2820 td->itd_bp[0] |= htohc32(sc, page_addr); 2821 2822 for (x = 0; x != td_no; x++) { 2823 /* set page number and page offset */ 2824 status = (EHCI_ITD_SET_PG(page_no) | 2825 (buf_res.physaddr & 0xFFF)); 2826 td->itd_status[x] |= htohc32(sc, status); 2827 2828 /* get next page offset */ 2829 if (itd_offset[x + 1] == buf_offset) { 2830 /* 2831 * We subtract one so that 2832 * we don't go off the last 2833 * page! 2834 */ |
2835 usbd_get_page(xfer->frbuffers, buf_offset - 1, &buf_res); |
2836 } else { |
2837 usbd_get_page(xfer->frbuffers, itd_offset[x + 1], &buf_res); |
2838 } 2839 2840 /* check if we need a new page */ 2841 if ((buf_res.physaddr ^ page_addr) & ~0xFFF) { 2842 /* new page needed */ 2843 page_addr = buf_res.physaddr & ~0xFFF; 2844 if (page_no == 6) { 2845 panic("%s: too many pages\n", __FUNCTION__); --- 4 unchanged lines hidden (view full) --- 2850 td->itd_bp[page_no] |= htohc32(sc, page_addr); 2851 } 2852 } 2853 } 2854 /* set IOC bit if we are complete */ 2855 if (nframes == 0) { 2856 td->itd_status[7] |= htohc32(sc, EHCI_ITD_IOC); 2857 } |
2858 usb_pc_cpu_flush(td->page_cache); |
2859#if USB_DEBUG 2860 if (ehcidebug > 15) { 2861 DPRINTF("HS-TD %d\n", nframes); 2862 ehci_dump_itd(sc, td); 2863 } 2864#endif 2865 /* insert TD into schedule */ 2866 EHCI_APPEND_HS_TD(td, *pp_last); --- 209 unchanged lines hidden (view full) --- 3076 str_ptr = "EHCI root HUB"; 3077 break; 3078 3079 default: 3080 str_ptr = ""; 3081 break; 3082 } 3083 |
3084 len = usb_make_str_desc( |
3085 sc->sc_hub_desc.temp, 3086 sizeof(sc->sc_hub_desc.temp), 3087 str_ptr); 3088 break; 3089 default: 3090 err = USB_ERR_IOERROR; 3091 goto done; 3092 } --- 58 unchanged lines hidden (view full) --- 3151 3152 /* 3153 * waking up a High Speed device is rather 3154 * complicated if 3155 */ 3156 EOWRITE4(sc, port, v | EHCI_PS_FPR); 3157 } 3158 /* wait 20ms for resume sequence to complete */ |
3159 usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 50); |
3160 3161 EOWRITE4(sc, port, v & ~(EHCI_PS_SUSP | 3162 EHCI_PS_FPR | (3 << 10) /* High Speed */ )); 3163 3164 /* 4ms settle time */ |
3165 usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 250); |
3166 break; 3167 case UHF_PORT_POWER: 3168 EOWRITE4(sc, port, v & ~EHCI_PS_PP); 3169 break; 3170 case UHF_PORT_TEST: 3171 DPRINTFN(3, "clear port test " 3172 "%d\n", index); 3173 break; --- 134 unchanged lines hidden (view full) --- 3308 ehci_disown(sc, index, 1); 3309 break; 3310 } 3311 /* Start reset sequence. */ 3312 v &= ~(EHCI_PS_PE | EHCI_PS_PR); 3313 EOWRITE4(sc, port, v | EHCI_PS_PR); 3314 3315 /* Wait for reset to complete. */ |
3316 usb_pause_mtx(&sc->sc_bus.bus_mtx, |
3317 USB_MS_TO_TICKS(USB_PORT_ROOT_RESET_DELAY)); 3318 3319 /* Terminate reset sequence. */ 3320 if (!(sc->sc_flags & EHCI_SCFLG_NORESTERM)) 3321 EOWRITE4(sc, port, v); 3322 3323 /* Wait for HC to complete reset. */ |
3324 usb_pause_mtx(&sc->sc_bus.bus_mtx, |
3325 USB_MS_TO_TICKS(EHCI_PORT_RESET_COMPLETE)); 3326 3327 v = EOREAD4(sc, port); 3328 DPRINTF("ehci after reset, status=0x%08x\n", v); 3329 if (v & EHCI_PS_PR) { 3330 device_printf(sc->sc_bus.bdev, 3331 "port reset timeout\n"); 3332 err = USB_ERR_TIMEOUT; --- 100 unchanged lines hidden (view full) --- 3433 * transfer descriptors is given by the buffer size divided 3434 * by the maximum data payload. 3435 */ 3436 parm->hc_max_packet_size = 0x400; 3437 parm->hc_max_packet_count = 1; 3438 parm->hc_max_frame_size = EHCI_QTD_PAYLOAD_MAX; 3439 xfer->flags_int.bdma_enable = 1; 3440 |
3441 usbd_transfer_setup_sub(parm); |
3442 3443 nqh = 1; 3444 nqtd = ((2 * xfer->nframes) + 1 /* STATUS */ 3445 + (xfer->max_data_length / xfer->max_hc_frame_size)); 3446 3447 } else if (parm->methods == &ehci_device_bulk_methods) { 3448 3449 parm->hc_max_packet_size = 0x400; 3450 parm->hc_max_packet_count = 1; 3451 parm->hc_max_frame_size = EHCI_QTD_PAYLOAD_MAX; 3452 xfer->flags_int.bdma_enable = 1; 3453 |
3454 usbd_transfer_setup_sub(parm); |
3455 3456 nqh = 1; 3457 nqtd = ((2 * xfer->nframes) 3458 + (xfer->max_data_length / xfer->max_hc_frame_size)); 3459 3460 } else if (parm->methods == &ehci_device_intr_methods) { 3461 3462 if (parm->speed == USB_SPEED_HIGH) { --- 5 unchanged lines hidden (view full) --- 3468 } else { 3469 parm->hc_max_packet_size = USB_FS_BYTES_PER_HS_UFRAME / 8; 3470 parm->hc_max_packet_count = 1; 3471 } 3472 3473 parm->hc_max_frame_size = EHCI_QTD_PAYLOAD_MAX; 3474 xfer->flags_int.bdma_enable = 1; 3475 |
3476 usbd_transfer_setup_sub(parm); |
3477 3478 nqh = 1; 3479 nqtd = ((2 * xfer->nframes) 3480 + (xfer->max_data_length / xfer->max_hc_frame_size)); 3481 3482 } else if (parm->methods == &ehci_device_isoc_fs_methods) { 3483 3484 parm->hc_max_packet_size = 0x3FF; 3485 parm->hc_max_packet_count = 1; 3486 parm->hc_max_frame_size = 0x3FF; 3487 xfer->flags_int.bdma_enable = 1; 3488 |
3489 usbd_transfer_setup_sub(parm); |
3490 3491 nsitd = xfer->nframes; 3492 3493 } else if (parm->methods == &ehci_device_isoc_hs_methods) { 3494 3495 parm->hc_max_packet_size = 0x400; 3496 parm->hc_max_packet_count = 3; 3497 parm->hc_max_frame_size = 0xC00; 3498 xfer->flags_int.bdma_enable = 1; 3499 |
3500 usbd_transfer_setup_sub(parm); |
3501 3502 nitd = (xfer->nframes + 7) / 8; 3503 3504 } else { 3505 3506 parm->hc_max_packet_size = 0x400; 3507 parm->hc_max_packet_count = 1; 3508 parm->hc_max_frame_size = 0x400; 3509 |
3510 usbd_transfer_setup_sub(parm); |
3511 } 3512 3513alloc_dma_set: 3514 3515 if (parm->err) { 3516 return; 3517 } 3518 /* 3519 * Allocate queue heads and transfer descriptors 3520 */ 3521 last_obj = NULL; 3522 |
3523 if (usbd_transfer_setup_sub_malloc( |
3524 parm, &pc, sizeof(ehci_itd_t), 3525 EHCI_ITD_ALIGN, nitd)) { 3526 parm->err = USB_ERR_NOMEM; 3527 return; 3528 } 3529 if (parm->buf) { 3530 for (n = 0; n != nitd; n++) { 3531 ehci_itd_t *td; 3532 |
3533 usbd_get_page(pc + n, 0, &page_info); |
3534 3535 td = page_info.buffer; 3536 3537 /* init TD */ 3538 td->itd_self = htohc32(sc, page_info.physaddr | EHCI_LINK_ITD); 3539 td->obj_next = last_obj; 3540 td->page_cache = pc + n; 3541 3542 last_obj = td; 3543 |
3544 usb_pc_cpu_flush(pc + n); |
3545 } 3546 } |
3547 if (usbd_transfer_setup_sub_malloc( |
3548 parm, &pc, sizeof(ehci_sitd_t), 3549 EHCI_SITD_ALIGN, nsitd)) { 3550 parm->err = USB_ERR_NOMEM; 3551 return; 3552 } 3553 if (parm->buf) { 3554 for (n = 0; n != nsitd; n++) { 3555 ehci_sitd_t *td; 3556 |
3557 usbd_get_page(pc + n, 0, &page_info); |
3558 3559 td = page_info.buffer; 3560 3561 /* init TD */ 3562 td->sitd_self = htohc32(sc, page_info.physaddr | EHCI_LINK_SITD); 3563 td->obj_next = last_obj; 3564 td->page_cache = pc + n; 3565 3566 last_obj = td; 3567 |
3568 usb_pc_cpu_flush(pc + n); |
3569 } 3570 } |
3571 if (usbd_transfer_setup_sub_malloc( |
3572 parm, &pc, sizeof(ehci_qtd_t), 3573 EHCI_QTD_ALIGN, nqtd)) { 3574 parm->err = USB_ERR_NOMEM; 3575 return; 3576 } 3577 if (parm->buf) { 3578 for (n = 0; n != nqtd; n++) { 3579 ehci_qtd_t *qtd; 3580 |
3581 usbd_get_page(pc + n, 0, &page_info); |
3582 3583 qtd = page_info.buffer; 3584 3585 /* init TD */ 3586 qtd->qtd_self = htohc32(sc, page_info.physaddr); 3587 qtd->obj_next = last_obj; 3588 qtd->page_cache = pc + n; 3589 3590 last_obj = qtd; 3591 |
3592 usb_pc_cpu_flush(pc + n); |
3593 } 3594 } 3595 xfer->td_start[xfer->flags_int.curr_dma_set] = last_obj; 3596 3597 last_obj = NULL; 3598 |
3599 if (usbd_transfer_setup_sub_malloc( |
3600 parm, &pc, sizeof(ehci_qh_t), 3601 EHCI_QH_ALIGN, nqh)) { 3602 parm->err = USB_ERR_NOMEM; 3603 return; 3604 } 3605 if (parm->buf) { 3606 for (n = 0; n != nqh; n++) { 3607 ehci_qh_t *qh; 3608 |
3609 usbd_get_page(pc + n, 0, &page_info); |
3610 3611 qh = page_info.buffer; 3612 3613 /* init QH */ 3614 qh->qh_self = htohc32(sc, page_info.physaddr | EHCI_LINK_QH); 3615 qh->obj_next = last_obj; 3616 qh->page_cache = pc + n; 3617 3618 last_obj = qh; 3619 |
3620 usb_pc_cpu_flush(pc + n); |
3621 } 3622 } 3623 xfer->qh_start[xfer->flags_int.curr_dma_set] = last_obj; 3624 3625 if (!xfer->flags_int.curr_dma_set) { 3626 xfer->flags_int.curr_dma_set = 1; 3627 goto alloc_dma_set; 3628 } --- 184 unchanged lines hidden --- |