1 /* $NetBSD: uhci.c,v 1.62 1999/10/23 00:21:01 augustss Exp $ */ 2 3 /* 4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Lennart Augustsson (augustss@carlstedt.se) at 9 * Carlstedt Research & Technology. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 /* 41 * USB Universal Host Controller driver. 42 * Handles e.g. PIIX3 and PIIX4. 43 * 44 * Data sheets: ftp://download.intel.com/design/intarch/datashts/29055002.pdf 45 * ftp://download.intel.com/design/intarch/datashts/29056201.pdf 46 * UHCI spec: http://www.intel.com/design/usb/uhci11d.pdf 47 * USB spec: http://www.usb.org/developers/data/usb11.pdf 48 */ 49 50 #include <sys/param.h> 51 #include <sys/systm.h> 52 #include <sys/kernel.h> 53 #include <sys/malloc.h> 54 #if defined(__NetBSD__) || defined(__OpenBSD__) 55 #include <sys/device.h> 56 #elif defined(__FreeBSD__) 57 #include <sys/module.h> 58 #include <sys/bus.h> 59 #endif 60 #include <sys/proc.h> 61 #include <sys/queue.h> 62 #include <sys/select.h> 63 64 #if defined(__FreeBSD__) 65 #include <machine/bus_pio.h> 66 #endif 67 #include <machine/bus.h> 68 #include <machine/endian.h> 69 70 #include <dev/usb/usb.h> 71 #include <dev/usb/usbdi.h> 72 #include <dev/usb/usbdivar.h> 73 #include <dev/usb/usb_mem.h> 74 #include <dev/usb/usb_quirks.h> 75 76 #include <dev/usb/uhcireg.h> 77 #include <dev/usb/uhcivar.h> 78 79 #if defined(__FreeBSD__) 80 #include <machine/clock.h> 81 82 #define delay(d) DELAY(d) 83 #endif 84 85 #define MS_TO_TICKS(ms) ((ms) * hz / 1000) 86 87 #if defined(__OpenBSD__) 88 struct cfdriver uhci_cd = { 89 NULL, "uhci", DV_DULL 90 }; 91 #endif 92 93 #ifdef USB_DEBUG 94 #define DPRINTF(x) if (uhcidebug) printf x 95 #define DPRINTFN(n,x) if (uhcidebug>(n)) printf x 96 extern int uhcidebug; 97 #else 98 #define DPRINTF(x) 99 #define DPRINTFN(n,x) 100 #endif 101 102 /* 103 * The UHCI controller is little endian, so on big endian machines 104 * the data strored in memory needs to be swapped. 105 */ 106 #if BYTE_ORDER == BIG_ENDIAN 107 #define LE(x) (bswap32(x)) 108 #else 109 #define LE(x) (x) 110 #endif 111 112 struct uhci_pipe { 113 struct usbd_pipe pipe; 114 uhci_intr_info_t *iinfo; 115 int nexttoggle; 116 /* Info needed for different pipe kinds. */ 117 union { 118 /* Control pipe */ 119 struct { 120 uhci_soft_qh_t *sqh; 121 usb_dma_t reqdma; 122 uhci_soft_td_t *setup, *stat; 123 u_int length; 124 } ctl; 125 /* Interrupt pipe */ 126 struct { 127 int npoll; 128 uhci_soft_qh_t **qhs; 129 } intr; 130 /* Bulk pipe */ 131 struct { 132 uhci_soft_qh_t *sqh; 133 u_int length; 134 int isread; 135 } bulk; 136 /* Iso pipe */ 137 struct iso { 138 uhci_soft_td_t **stds; 139 int next, inuse; 140 } iso; 141 } u; 142 }; 143 144 /* 145 * The uhci_intr_info free list can be global since they contain 146 * no dma specific data. The other free lists do. 147 */ 148 LIST_HEAD(, uhci_intr_info) uhci_ii_free; 149 150 void uhci_busreset __P((uhci_softc_t *)); 151 void uhci_power __P((int, void *)); 152 usbd_status uhci_run __P((uhci_softc_t *, int run)); 153 uhci_soft_td_t *uhci_alloc_std __P((uhci_softc_t *)); 154 void uhci_free_std __P((uhci_softc_t *, uhci_soft_td_t *)); 155 uhci_soft_qh_t *uhci_alloc_sqh __P((uhci_softc_t *)); 156 void uhci_free_sqh __P((uhci_softc_t *, uhci_soft_qh_t *)); 157 uhci_intr_info_t *uhci_alloc_intr_info __P((uhci_softc_t *)); 158 void uhci_free_intr_info __P((uhci_intr_info_t *ii)); 159 #if 0 160 void uhci_enter_ctl_q __P((uhci_softc_t *, uhci_soft_qh_t *, 161 uhci_intr_info_t *)); 162 void uhci_exit_ctl_q __P((uhci_softc_t *, uhci_soft_qh_t *)); 163 #endif 164 165 void uhci_free_std_chain __P((uhci_softc_t *, 166 uhci_soft_td_t *, uhci_soft_td_t *)); 167 usbd_status uhci_alloc_std_chain __P((struct uhci_pipe *, uhci_softc_t *, 168 int, int, int, usb_dma_t *, 169 uhci_soft_td_t **, 170 uhci_soft_td_t **)); 171 void uhci_timo __P((void *)); 172 void uhci_waitintr __P((uhci_softc_t *, usbd_request_handle)); 173 void uhci_check_intr __P((uhci_softc_t *, uhci_intr_info_t *)); 174 void uhci_idone __P((uhci_intr_info_t *)); 175 void uhci_abort_req __P((usbd_request_handle, usbd_status status)); 176 void uhci_abort_req_end __P((void *v)); 177 void uhci_timeout __P((void *)); 178 void uhci_wakeup_ctrl __P((void *, int, int, void *, int)); 179 void uhci_lock_frames __P((uhci_softc_t *)); 180 void uhci_unlock_frames __P((uhci_softc_t *)); 181 void uhci_add_ctrl __P((uhci_softc_t *, uhci_soft_qh_t *)); 182 void uhci_add_bulk __P((uhci_softc_t *, uhci_soft_qh_t *)); 183 void uhci_remove_ctrl __P((uhci_softc_t *, uhci_soft_qh_t *)); 184 void uhci_remove_bulk __P((uhci_softc_t *, uhci_soft_qh_t *)); 185 int uhci_str __P((usb_string_descriptor_t *, int, char *)); 186 usbd_status uhci_setup_isoc __P((usbd_pipe_handle pipe)); 187 void uhci_device_isoc_enter __P((usbd_request_handle)); 188 189 void uhci_wakeup_cb __P((usbd_request_handle reqh)); 190 191 usbd_status uhci_allocm __P((struct usbd_bus *, usb_dma_t *, u_int32_t)); 192 void uhci_freem __P((struct usbd_bus *, usb_dma_t *)); 193 194 usbd_status uhci_device_ctrl_transfer __P((usbd_request_handle)); 195 usbd_status uhci_device_ctrl_start __P((usbd_request_handle)); 196 void uhci_device_ctrl_abort __P((usbd_request_handle)); 197 void uhci_device_ctrl_close __P((usbd_pipe_handle)); 198 void uhci_device_ctrl_done __P((usbd_request_handle)); 199 200 usbd_status uhci_device_intr_transfer __P((usbd_request_handle)); 201 usbd_status uhci_device_intr_start __P((usbd_request_handle)); 202 void uhci_device_intr_abort __P((usbd_request_handle)); 203 void uhci_device_intr_close __P((usbd_pipe_handle)); 204 void uhci_device_intr_done __P((usbd_request_handle)); 205 206 usbd_status uhci_device_bulk_transfer __P((usbd_request_handle)); 207 usbd_status uhci_device_bulk_start __P((usbd_request_handle)); 208 void uhci_device_bulk_abort __P((usbd_request_handle)); 209 void uhci_device_bulk_close __P((usbd_pipe_handle)); 210 void uhci_device_bulk_done __P((usbd_request_handle)); 211 212 usbd_status uhci_device_isoc_transfer __P((usbd_request_handle)); 213 usbd_status uhci_device_isoc_start __P((usbd_request_handle)); 214 void uhci_device_isoc_abort __P((usbd_request_handle)); 215 void uhci_device_isoc_close __P((usbd_pipe_handle)); 216 void uhci_device_isoc_done __P((usbd_request_handle)); 217 218 usbd_status uhci_root_ctrl_transfer __P((usbd_request_handle)); 219 usbd_status uhci_root_ctrl_start __P((usbd_request_handle)); 220 void uhci_root_ctrl_abort __P((usbd_request_handle)); 221 void uhci_root_ctrl_close __P((usbd_pipe_handle)); 222 223 usbd_status uhci_root_intr_transfer __P((usbd_request_handle)); 224 usbd_status uhci_root_intr_start __P((usbd_request_handle)); 225 void uhci_root_intr_abort __P((usbd_request_handle)); 226 void uhci_root_intr_close __P((usbd_pipe_handle)); 227 void uhci_root_intr_done __P((usbd_request_handle)); 228 229 usbd_status uhci_open __P((usbd_pipe_handle)); 230 void uhci_poll __P((struct usbd_bus *)); 231 232 usbd_status uhci_device_request __P((usbd_request_handle reqh)); 233 234 void uhci_add_intr __P((uhci_softc_t *, int, uhci_soft_qh_t *)); 235 void uhci_remove_intr __P((uhci_softc_t *, int, uhci_soft_qh_t *)); 236 usbd_status uhci_device_setintr __P((uhci_softc_t *sc, 237 struct uhci_pipe *pipe, int ival)); 238 239 void uhci_device_clear_toggle __P((usbd_pipe_handle pipe)); 240 void uhci_noop __P((usbd_pipe_handle pipe)); 241 242 #ifdef UHCI_DEBUG 243 static void uhci_dumpregs __P((uhci_softc_t *)); 244 void uhci_dump_tds __P((uhci_soft_td_t *)); 245 void uhci_dump_qh __P((uhci_soft_qh_t *)); 246 void uhci_dump __P((void)); 247 void uhci_dump_td __P((uhci_soft_td_t *)); 248 #endif 249 250 #define UWRITE2(sc, r, x) bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x)) 251 #define UWRITE4(sc, r, x) bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x)) 252 #define UREAD1(sc, r) bus_space_read_1((sc)->iot, (sc)->ioh, (r)) 253 #define UREAD2(sc, r) bus_space_read_2((sc)->iot, (sc)->ioh, (r)) 254 #define UREAD4(sc, r) bus_space_read_4((sc)->iot, (sc)->ioh, (r)) 255 256 #define UHCICMD(sc, cmd) UWRITE2(sc, UHCI_CMD, cmd) 257 #define UHCISTS(sc) UREAD2(sc, UHCI_STS) 258 259 #define UHCI_RESET_TIMEOUT 100 /* reset timeout */ 260 261 #define UHCI_CURFRAME(sc) (UREAD2(sc, UHCI_FRNUM) & UHCI_FRNUM_MASK) 262 263 #define UHCI_INTR_ENDPT 1 264 265 struct usbd_bus_methods uhci_bus_methods = { 266 uhci_open, 267 uhci_poll, 268 uhci_allocm, 269 uhci_freem, 270 }; 271 272 struct usbd_pipe_methods uhci_root_ctrl_methods = { 273 uhci_root_ctrl_transfer, 274 uhci_root_ctrl_start, 275 uhci_root_ctrl_abort, 276 uhci_root_ctrl_close, 277 uhci_noop, 278 0, 279 }; 280 281 struct usbd_pipe_methods uhci_root_intr_methods = { 282 uhci_root_intr_transfer, 283 uhci_root_intr_start, 284 uhci_root_intr_abort, 285 uhci_root_intr_close, 286 uhci_noop, 287 uhci_root_intr_done, 288 }; 289 290 struct usbd_pipe_methods uhci_device_ctrl_methods = { 291 uhci_device_ctrl_transfer, 292 uhci_device_ctrl_start, 293 uhci_device_ctrl_abort, 294 uhci_device_ctrl_close, 295 uhci_noop, 296 uhci_device_ctrl_done, 297 }; 298 299 struct usbd_pipe_methods uhci_device_intr_methods = { 300 uhci_device_intr_transfer, 301 uhci_device_intr_start, 302 uhci_device_intr_abort, 303 uhci_device_intr_close, 304 uhci_device_clear_toggle, 305 uhci_device_intr_done, 306 }; 307 308 struct usbd_pipe_methods uhci_device_bulk_methods = { 309 uhci_device_bulk_transfer, 310 uhci_device_bulk_start, 311 uhci_device_bulk_abort, 312 uhci_device_bulk_close, 313 uhci_device_clear_toggle, 314 uhci_device_bulk_done, 315 }; 316 317 struct usbd_pipe_methods uhci_device_isoc_methods = { 318 uhci_device_isoc_transfer, 319 uhci_device_isoc_start, 320 uhci_device_isoc_abort, 321 uhci_device_isoc_close, 322 uhci_noop, 323 uhci_device_isoc_done, 324 }; 325 326 void 327 uhci_busreset(sc) 328 uhci_softc_t *sc; 329 { 330 UHCICMD(sc, UHCI_CMD_GRESET); /* global reset */ 331 usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY); /* wait a little */ 332 UHCICMD(sc, 0); /* do nothing */ 333 } 334 335 usbd_status 336 uhci_init(sc) 337 uhci_softc_t *sc; 338 { 339 usbd_status r; 340 int i, j; 341 uhci_soft_qh_t *csqh, *bsqh, *sqh; 342 uhci_soft_td_t *std; 343 344 DPRINTFN(1,("uhci_init: start\n")); 345 346 #if defined(UHCI_DEBUG) 347 if (uhcidebug > 2) 348 uhci_dumpregs(sc); 349 #endif 350 351 uhci_run(sc, 0); /* stop the controller */ 352 UWRITE2(sc, UHCI_INTR, 0); /* disable interrupts */ 353 354 uhci_busreset(sc); 355 356 /* Allocate and initialize real frame array. */ 357 r = usb_allocmem(&sc->sc_bus, 358 UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t), 359 UHCI_FRAMELIST_ALIGN, &sc->sc_dma); 360 if (r != USBD_NORMAL_COMPLETION) 361 return (r); 362 sc->sc_pframes = KERNADDR(&sc->sc_dma); 363 UWRITE2(sc, UHCI_FRNUM, 0); /* set frame number to 0 */ 364 UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&sc->sc_dma)); /* set frame list*/ 365 366 /* Allocate the dummy QH where bulk traffic will be queued. */ 367 bsqh = uhci_alloc_sqh(sc); 368 if (!bsqh) 369 return (USBD_NOMEM); 370 bsqh->qh.qh_hlink = LE(UHCI_PTR_T); /* end of QH chain */ 371 bsqh->qh.qh_elink = LE(UHCI_PTR_T); 372 sc->sc_bulk_start = sc->sc_bulk_end = bsqh; 373 374 /* Allocate the dummy QH where control traffic will be queued. */ 375 csqh = uhci_alloc_sqh(sc); 376 if (!csqh) 377 return (USBD_NOMEM); 378 csqh->hlink = bsqh; 379 csqh->qh.qh_hlink = LE(bsqh->physaddr | UHCI_PTR_Q); 380 csqh->qh.qh_elink = LE(UHCI_PTR_T); 381 sc->sc_ctl_start = sc->sc_ctl_end = csqh; 382 383 /* 384 * Make all (virtual) frame list pointers point to the interrupt 385 * queue heads and the interrupt queue heads at the control 386 * queue head and point the physical frame list to the virtual. 387 */ 388 for(i = 0; i < UHCI_VFRAMELIST_COUNT; i++) { 389 std = uhci_alloc_std(sc); 390 sqh = uhci_alloc_sqh(sc); 391 if (!std || !sqh) 392 return (USBD_NOMEM); 393 std->link.sqh = sqh; 394 std->td.td_link = LE(sqh->physaddr | UHCI_PTR_Q); 395 std->td.td_status = LE(UHCI_TD_IOS); /* iso, inactive */ 396 std->td.td_token = LE(0); 397 std->td.td_buffer = LE(0); 398 sqh->hlink = csqh; 399 sqh->qh.qh_hlink = LE(csqh->physaddr | UHCI_PTR_Q); 400 sqh->elink = 0; 401 sqh->qh.qh_elink = LE(UHCI_PTR_T); 402 sc->sc_vframes[i].htd = std; 403 sc->sc_vframes[i].etd = std; 404 sc->sc_vframes[i].hqh = sqh; 405 sc->sc_vframes[i].eqh = sqh; 406 for (j = i; 407 j < UHCI_FRAMELIST_COUNT; 408 j += UHCI_VFRAMELIST_COUNT) 409 sc->sc_pframes[j] = LE(std->physaddr); 410 } 411 412 LIST_INIT(&sc->sc_intrhead); 413 414 /* Set up the bus struct. */ 415 sc->sc_bus.methods = &uhci_bus_methods; 416 sc->sc_bus.pipe_size = sizeof(struct uhci_pipe); 417 418 sc->sc_suspend = PWR_RESUME; 419 sc->sc_powerhook = powerhook_establish(uhci_power, sc); 420 421 DPRINTFN(1,("uhci_init: enabling\n")); 422 UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE | 423 UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* enable interrupts */ 424 425 return (uhci_run(sc, 1)); /* and here we go... */ 426 } 427 428 int 429 uhci_activate(self, act) 430 device_ptr_t self; 431 enum devact act; 432 { 433 struct uhci_softc *sc = (struct uhci_softc *)self; 434 int rv = 0; 435 436 switch (act) { 437 case DVACT_ACTIVATE: 438 return (EOPNOTSUPP); 439 break; 440 441 case DVACT_DEACTIVATE: 442 if (sc->sc_child != NULL) 443 rv = config_deactivate(sc->sc_child); 444 break; 445 } 446 return (rv); 447 } 448 449 int 450 uhci_detach(sc, flags) 451 struct uhci_softc *sc; 452 int flags; 453 { 454 int rv = 0; 455 456 if (sc->sc_child != NULL) 457 rv = config_detach(sc->sc_child, flags); 458 459 if (rv != 0) 460 return (rv); 461 462 powerhook_disestablish(sc->sc_powerhook); 463 /* free data structures XXX */ 464 465 return (rv); 466 } 467 468 usbd_status 469 uhci_allocm(bus, dma, size) 470 struct usbd_bus *bus; 471 usb_dma_t *dma; 472 u_int32_t size; 473 { 474 #if defined(__NetBSD__) || defined(__OpenBSD__) 475 struct uhci_softc *sc = (struct uhci_softc *)bus; 476 #endif 477 478 return (usb_allocmem(&sc->sc_bus, size, 0, dma)); 479 } 480 481 void 482 uhci_freem(bus, dma) 483 struct usbd_bus *bus; 484 usb_dma_t *dma; 485 { 486 #if defined(__NetBSD__) || defined(__OpenBSD__) 487 struct uhci_softc *sc = (struct uhci_softc *)bus; 488 #endif 489 490 usb_freemem(&sc->sc_bus, dma); 491 } 492 493 #if defined(__NetBSD__) 494 /* 495 * Handle suspend/resume. 496 * 497 * We need to switch to polling mode here, because this routine is 498 * called from an intterupt context. This is all right since we 499 * are almost suspended anyway. 500 */ 501 void 502 uhci_power(why, v) 503 int why; 504 void *v; 505 { 506 uhci_softc_t *sc = v; 507 int cmd; 508 int s; 509 510 s = splusb(); 511 cmd = UREAD2(sc, UHCI_CMD); 512 513 DPRINTF(("uhci_power: sc=%p, why=%d (was %d), cmd=0x%x\n", 514 sc, why, sc->sc_suspend, cmd)); 515 516 if (why != PWR_RESUME) { 517 #if defined(UHCI_DEBUG) 518 if (uhcidebug > 2) 519 uhci_dumpregs(sc); 520 #endif 521 if (sc->sc_has_timo) 522 usb_untimeout(uhci_timo, sc->sc_has_timo, 523 sc->sc_has_timo->timo_handle); 524 sc->sc_bus.use_polling++; 525 uhci_run(sc, 0); /* stop the controller */ 526 UHCICMD(sc, cmd | UHCI_CMD_EGSM); /* enter global suspend */ 527 usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT); 528 sc->sc_suspend = why; 529 sc->sc_bus.use_polling--; 530 DPRINTF(("uhci_power: cmd=0x%x\n", UREAD2(sc, UHCI_CMD))); 531 } else { 532 /* 533 * XXX We should really do much more here in case the 534 * controller registers have been lost and BIOS has 535 * not restored them. 536 */ 537 #ifdef DIAGNOSTIC 538 if (sc->sc_suspend == PWR_RESUME) 539 printf("uhci_power: weird, resume without suspend.\n"); 540 #endif 541 sc->sc_bus.use_polling++; 542 sc->sc_suspend = why; 543 if (cmd & UHCI_CMD_RS) 544 uhci_run(sc, 0); /* in case BIOS has started it */ 545 UHCICMD(sc, cmd | UHCI_CMD_FGR); /* force global resume */ 546 usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY); 547 UHCICMD(sc, cmd & ~UHCI_CMD_EGSM); /* back to normal */ 548 UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE | 549 UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* re-enable intrs */ 550 uhci_run(sc, 1); /* and start traffic again */ 551 usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY); 552 sc->sc_bus.use_polling--; 553 if (sc->sc_has_timo) 554 usb_timeout(uhci_timo, sc->sc_has_timo, 555 sc->sc_ival, sc->sc_has_timo->timo_handle); 556 #if defined(UHCI_DEBUG) 557 if (uhcidebug > 2) 558 uhci_dumpregs(sc); 559 #endif 560 } 561 splx(s); 562 } 563 #endif /* defined(__NetBSD__) */ 564 565 #ifdef UHCI_DEBUG 566 static void 567 uhci_dumpregs(sc) 568 uhci_softc_t *sc; 569 { 570 DPRINTFN(-1,("%s regs: cmd=%04x, sts=%04x, intr=%04x, frnum=%04x, " 571 "flbase=%08x, sof=%04x, portsc1=%04x, portsc2=%04x\n", 572 USBDEVNAME(sc->sc_bus.bdev), 573 UREAD2(sc, UHCI_CMD), 574 UREAD2(sc, UHCI_STS), 575 UREAD2(sc, UHCI_INTR), 576 UREAD2(sc, UHCI_FRNUM), 577 UREAD4(sc, UHCI_FLBASEADDR), 578 UREAD1(sc, UHCI_SOF), 579 UREAD2(sc, UHCI_PORTSC1), 580 UREAD2(sc, UHCI_PORTSC2))); 581 } 582 583 void 584 uhci_dump_td(p) 585 uhci_soft_td_t *p; 586 { 587 DPRINTFN(-1,("TD(%p) at %08lx = link=0x%08lx status=0x%08lx " 588 "token=0x%08lx buffer=0x%08lx\n", 589 p, (long)p->physaddr, 590 (long)LE(p->td.td_link), 591 (long)LE(p->td.td_status), 592 (long)LE(p->td.td_token), 593 (long)LE(p->td.td_buffer))); 594 DPRINTFN(-1,(" %b %b,errcnt=%d,actlen=%d pid=%02x,addr=%d,endpt=%d," 595 "D=%d,maxlen=%d\n", 596 (int)LE(p->td.td_link), 597 "\20\1T\2Q\3VF", 598 (int)LE(p->td.td_status), 599 "\20\22BITSTUFF\23CRCTO\24NAK\25BABBLE\26DBUFFER\27" 600 "STALLED\30ACTIVE\31IOC\32ISO\33LS\36SPD", 601 UHCI_TD_GET_ERRCNT(LE(p->td.td_status)), 602 UHCI_TD_GET_ACTLEN(LE(p->td.td_status)), 603 UHCI_TD_GET_PID(LE(p->td.td_token)), 604 UHCI_TD_GET_DEVADDR(LE(p->td.td_token)), 605 UHCI_TD_GET_ENDPT(LE(p->td.td_token)), 606 UHCI_TD_GET_DT(LE(p->td.td_token)), 607 UHCI_TD_GET_MAXLEN(LE(p->td.td_token)))); 608 } 609 610 void 611 uhci_dump_qh(p) 612 uhci_soft_qh_t *p; 613 { 614 DPRINTFN(-1,("QH(%p) at %08x: hlink=%08x elink=%08x\n", p, 615 (int)p->physaddr, LE(p->qh.qh_hlink), LE(p->qh.qh_elink))); 616 } 617 618 619 #if 0 620 void 621 uhci_dump() 622 { 623 uhci_softc_t *sc = uhci; 624 625 uhci_dumpregs(sc); 626 printf("intrs=%d\n", sc->sc_bus.no_intrs); 627 printf("framelist[i].link = %08x\n", sc->sc_framelist[0].link); 628 uhci_dump_qh(sc->sc_ctl_start->qh.hlink); 629 } 630 #endif 631 632 void 633 uhci_dump_tds(std) 634 uhci_soft_td_t *std; 635 { 636 uhci_soft_td_t *p; 637 638 for(p = std; p; p = p->link.std) 639 uhci_dump_td(p); 640 } 641 #endif 642 643 /* 644 * This routine is executed periodically and simulates interrupts 645 * from the root controller interrupt pipe for port status change. 646 */ 647 void 648 uhci_timo(addr) 649 void *addr; 650 { 651 usbd_request_handle reqh = addr; 652 usbd_pipe_handle pipe = reqh->pipe; 653 uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus; 654 int s; 655 u_char *p; 656 657 DPRINTFN(15, ("uhci_timo\n")); 658 659 usb_timeout(uhci_timo, reqh, sc->sc_ival, reqh->timo_handle); 660 661 p = KERNADDR(&reqh->dmabuf); 662 p[0] = 0; 663 if (UREAD2(sc, UHCI_PORTSC1) & (UHCI_PORTSC_CSC|UHCI_PORTSC_OCIC)) 664 p[0] |= 1<<1; 665 if (UREAD2(sc, UHCI_PORTSC2) & (UHCI_PORTSC_CSC|UHCI_PORTSC_OCIC)) 666 p[0] |= 1<<2; 667 if (p[0] == 0) 668 /* No change, try again in a while */ 669 return; 670 671 reqh->actlen = 1; 672 reqh->status = USBD_NORMAL_COMPLETION; 673 s = splusb(); 674 reqh->hcpriv = 0; 675 reqh->device->bus->intr_context++; 676 usb_transfer_complete(reqh); 677 reqh->device->bus->intr_context--; 678 splx(s); 679 } 680 681 void 682 uhci_root_intr_done(reqh) 683 usbd_request_handle reqh; 684 { 685 } 686 687 688 void 689 uhci_lock_frames(sc) 690 uhci_softc_t *sc; 691 { 692 int s = splusb(); 693 while (sc->sc_vflock) { 694 sc->sc_vflock |= UHCI_WANT_LOCK; 695 tsleep(&sc->sc_vflock, PRIBIO, "uhcqhl", 0); 696 } 697 sc->sc_vflock = UHCI_HAS_LOCK; 698 splx(s); 699 } 700 701 void 702 uhci_unlock_frames(sc) 703 uhci_softc_t *sc; 704 { 705 int s = splusb(); 706 sc->sc_vflock &= ~UHCI_HAS_LOCK; 707 if (sc->sc_vflock & UHCI_WANT_LOCK) 708 wakeup(&sc->sc_vflock); 709 splx(s); 710 } 711 712 /* 713 * Allocate an interrupt information struct. A free list is kept 714 * for fast allocation. 715 */ 716 uhci_intr_info_t * 717 uhci_alloc_intr_info(sc) 718 uhci_softc_t *sc; 719 { 720 uhci_intr_info_t *ii; 721 722 ii = LIST_FIRST(&uhci_ii_free); 723 if (ii) 724 LIST_REMOVE(ii, list); 725 else { 726 ii = malloc(sizeof(uhci_intr_info_t), M_USBHC, M_NOWAIT); 727 } 728 ii->sc = sc; 729 #if defined(__FreeBSD__) 730 callout_handle_init(&ii->timeout_handle); 731 #endif 732 733 return ii; 734 } 735 736 void 737 uhci_free_intr_info(ii) 738 uhci_intr_info_t *ii; 739 { 740 LIST_INSERT_HEAD(&uhci_ii_free, ii, list); /* and put on free list */ 741 } 742 743 /* Add control QH, called at splusb(). */ 744 void 745 uhci_add_ctrl(sc, sqh) 746 uhci_softc_t *sc; 747 uhci_soft_qh_t *sqh; 748 { 749 uhci_soft_qh_t *eqh; 750 751 SPLUSBCHECK; 752 753 DPRINTFN(10, ("uhci_add_ctrl: sqh=%p\n", sqh)); 754 eqh = sc->sc_ctl_end; 755 sqh->hlink = eqh->hlink; 756 sqh->qh.qh_hlink = eqh->qh.qh_hlink; 757 eqh->hlink = sqh; 758 eqh->qh.qh_hlink = LE(sqh->physaddr | UHCI_PTR_Q); 759 sc->sc_ctl_end = sqh; 760 } 761 762 /* Remove control QH, called at splusb(). */ 763 void 764 uhci_remove_ctrl(sc, sqh) 765 uhci_softc_t *sc; 766 uhci_soft_qh_t *sqh; 767 { 768 uhci_soft_qh_t *pqh; 769 770 SPLUSBCHECK; 771 772 DPRINTFN(10, ("uhci_remove_ctrl: sqh=%p\n", sqh)); 773 for (pqh = sc->sc_ctl_start; pqh->hlink != sqh; pqh=pqh->hlink) 774 #if defined(DIAGNOSTIC) || defined(UHCI_DEBUG) 775 if (LE(pqh->qh.qh_hlink) & UHCI_PTR_T) { 776 printf("uhci_remove_ctrl: QH not found\n"); 777 return; 778 } 779 #else 780 ; 781 #endif 782 pqh->hlink = sqh->hlink; 783 pqh->qh.qh_hlink = sqh->qh.qh_hlink; 784 if (sc->sc_ctl_end == sqh) 785 sc->sc_ctl_end = pqh; 786 } 787 788 /* Add bulk QH, called at splusb(). */ 789 void 790 uhci_add_bulk(sc, sqh) 791 uhci_softc_t *sc; 792 uhci_soft_qh_t *sqh; 793 { 794 uhci_soft_qh_t *eqh; 795 796 SPLUSBCHECK; 797 798 DPRINTFN(10, ("uhci_add_bulk: sqh=%p\n", sqh)); 799 eqh = sc->sc_bulk_end; 800 sqh->hlink = eqh->hlink; 801 sqh->qh.qh_hlink = eqh->qh.qh_hlink; 802 eqh->hlink = sqh; 803 eqh->qh.qh_hlink = LE(sqh->physaddr | UHCI_PTR_Q); 804 sc->sc_bulk_end = sqh; 805 } 806 807 /* Remove bulk QH, called at splusb(). */ 808 void 809 uhci_remove_bulk(sc, sqh) 810 uhci_softc_t *sc; 811 uhci_soft_qh_t *sqh; 812 { 813 uhci_soft_qh_t *pqh; 814 815 SPLUSBCHECK; 816 817 DPRINTFN(10, ("uhci_remove_bulk: sqh=%p\n", sqh)); 818 for (pqh = sc->sc_bulk_start; pqh->hlink != sqh; pqh = pqh->hlink) 819 #if defined(DIAGNOSTIC) || defined(UHCI_DEBUG) 820 if (LE(pqh->qh.qh_hlink) & UHCI_PTR_T) { 821 printf("uhci_remove_bulk: QH not found\n"); 822 return; 823 } 824 #else 825 ; 826 #endif 827 pqh->hlink = sqh->hlink; 828 pqh->qh.qh_hlink = sqh->qh.qh_hlink; 829 if (sc->sc_bulk_end == sqh) 830 sc->sc_bulk_end = pqh; 831 } 832 833 int 834 uhci_intr(arg) 835 void *arg; 836 { 837 uhci_softc_t *sc = arg; 838 int status; 839 int ack; 840 uhci_intr_info_t *ii; 841 842 #if defined(UHCI_DEBUG) 843 if (uhcidebug > 15) { 844 DPRINTF(("%s: uhci_intr\n", USBDEVNAME(sc->sc_bus.bdev))); 845 uhci_dumpregs(sc); 846 } 847 #endif 848 849 status = UREAD2(sc, UHCI_STS); 850 if (status == 0) /* The interrupt was not for us. */ 851 return (0); 852 853 #if defined(DIAGNOSTIC) && defined(__NetBSD__) 854 if (sc->sc_suspend != PWR_RESUME) 855 printf("uhci_intr: suspended sts=0x%x\n", status); 856 #endif 857 858 ack = 0; 859 if (status & UHCI_STS_USBINT) 860 ack |= UHCI_STS_USBINT; 861 if (status & UHCI_STS_USBEI) 862 ack |= UHCI_STS_USBEI; 863 if (status & UHCI_STS_RD) { 864 ack |= UHCI_STS_RD; 865 printf("%s: resume detect\n", USBDEVNAME(sc->sc_bus.bdev)); 866 } 867 if (status & UHCI_STS_HSE) { 868 ack |= UHCI_STS_HSE; 869 printf("%s: host controller process error\n", 870 USBDEVNAME(sc->sc_bus.bdev)); 871 } 872 if (status & UHCI_STS_HCPE) { 873 ack |= UHCI_STS_HCPE; 874 printf("%s: host system error\n", USBDEVNAME(sc->sc_bus.bdev)); 875 } 876 if (status & UHCI_STS_HCH) { 877 /* no acknowledge needed */ 878 printf("%s: host controller halted\n", 879 USBDEVNAME(sc->sc_bus.bdev)); 880 } 881 882 if (ack) /* acknowledge the ints */ 883 UWRITE2(sc, UHCI_STS, ack); 884 else /* nothing to acknowledge */ 885 return (0); 886 887 sc->sc_bus.intr_context++; 888 sc->sc_bus.no_intrs++; 889 890 /* 891 * Interrupts on UHCI really suck. When the host controller 892 * interrupts because a transfer is completed there is no 893 * way of knowing which transfer it was. You can scan down 894 * the TDs and QHs of the previous frame to limit the search, 895 * but that assumes that the interrupt was not delayed by more 896 * than 1 ms, which may not always be true (e.g. after debug 897 * output on a slow console). 898 * We scan all interrupt descriptors to see if any have 899 * completed. 900 */ 901 for (ii = LIST_FIRST(&sc->sc_intrhead); ii; ii = LIST_NEXT(ii, list)) 902 uhci_check_intr(sc, ii); 903 904 DPRINTFN(10, ("uhci_intr: exit\n")); 905 906 sc->sc_bus.intr_context--; 907 908 return (1); 909 } 910 911 /* Check for an interrupt. */ 912 void 913 uhci_check_intr(sc, ii) 914 uhci_softc_t *sc; 915 uhci_intr_info_t *ii; 916 { 917 uhci_soft_td_t *std, *lstd; 918 u_int32_t status; 919 920 DPRINTFN(15, ("uhci_check_intr: ii=%p\n", ii)); 921 #ifdef DIAGNOSTIC 922 if (!ii) { 923 printf("uhci_check_intr: no ii? %p\n", ii); 924 return; 925 } 926 #endif 927 if (!ii->stdstart) 928 return; 929 lstd = ii->stdend; 930 #ifdef DIAGNOSTIC 931 if (!lstd) { 932 printf("uhci_check_intr: std==0\n"); 933 return; 934 } 935 #endif 936 /* 937 * If the last TD is still active we need to check whether there 938 * is a an error somewhere in the middle, or whether there was a 939 * short packet (SPD and not ACTIVE). 940 */ 941 if (LE(lstd->td.td_status) & UHCI_TD_ACTIVE) { 942 DPRINTFN(15, ("uhci_check_intr: active ii=%p\n", ii)); 943 for (std = ii->stdstart; std != lstd; std = std->link.std) { 944 status = LE(std->td.td_status); 945 if ((status & UHCI_TD_STALLED) || 946 (status & (UHCI_TD_SPD | UHCI_TD_ACTIVE)) == 947 UHCI_TD_SPD) 948 goto done; 949 } 950 DPRINTFN(15, ("uhci_check_intr: ii=%p std=%p still active\n", 951 ii, ii->stdstart)); 952 return; 953 } 954 done: 955 usb_untimeout(uhci_timeout, ii, ii->timeout_handle); 956 uhci_idone(ii); 957 } 958 959 /* Called at splusb() */ 960 void 961 uhci_idone(ii) 962 uhci_intr_info_t *ii; 963 { 964 usbd_request_handle reqh = ii->reqh; 965 struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe; 966 uhci_soft_td_t *std; 967 u_int32_t status; 968 int actlen; 969 970 #ifdef DIAGNOSTIC 971 { 972 int s = splhigh(); 973 if (ii->isdone) { 974 splx(s); 975 printf("uhci_idone: ii=%p is done!\n", ii); 976 return; 977 } 978 ii->isdone = 1; 979 splx(s); 980 } 981 #endif 982 983 if (reqh->status == USBD_CANCELLED || 984 reqh->status == USBD_TIMEOUT) { 985 DPRINTF(("uhci_idone: aborted reqh=%p\n", reqh)); 986 return; 987 } 988 989 if (reqh->nframes) { 990 /* Isoc transfer, do things differently. */ 991 uhci_soft_td_t **stds = upipe->u.iso.stds; 992 int i, n, nframes; 993 994 DPRINTFN(5,("uhci_idone: ii=%p isoc ready\n", ii)); 995 996 nframes = reqh->nframes; 997 actlen = 0; 998 n = reqh->hcprivint; 999 for (i = 0; i < nframes; i++) { 1000 std = stds[n]; 1001 #ifdef UHCI_DEBUG 1002 if (uhcidebug > 5) { 1003 DPRINTFN(-1,("uhci_idone: isoc TD %d\n", i)); 1004 uhci_dump_td(std); 1005 } 1006 #endif 1007 if (++n >= UHCI_VFRAMELIST_COUNT) 1008 n = 0; 1009 status = LE(std->td.td_status); 1010 actlen += UHCI_TD_GET_ACTLEN(status); 1011 } 1012 upipe->u.iso.inuse -= nframes; 1013 reqh->actlen = actlen; 1014 reqh->status = USBD_NORMAL_COMPLETION; 1015 reqh->hcpriv = ii; 1016 usb_transfer_complete(reqh); 1017 return; 1018 } 1019 1020 #ifdef UHCI_DEBUG 1021 DPRINTFN(10, ("uhci_idone: ii=%p ready\n", ii)); 1022 if (uhcidebug > 10) 1023 uhci_dump_tds(ii->stdstart); 1024 #endif 1025 1026 /* The transfer is done, compute actual length and status. */ 1027 /* XXX Is this correct for control xfers? */ 1028 actlen = 0; 1029 for (std = ii->stdstart; std; std = std->link.std) { 1030 status = LE(std->td.td_status); 1031 if (status & UHCI_TD_ACTIVE) 1032 break; 1033 if (UHCI_TD_GET_PID(LE(std->td.td_token)) != 1034 UHCI_TD_PID_SETUP) 1035 actlen += UHCI_TD_GET_ACTLEN(status); 1036 } 1037 /* If there are left over TDs we need to update the toggle. */ 1038 if (std) 1039 upipe->nexttoggle = UHCI_TD_GET_DT(LE(std->td.td_token)); 1040 1041 status &= UHCI_TD_ERROR; 1042 DPRINTFN(10, ("uhci_check_intr: actlen=%d, status=0x%x\n", 1043 actlen, status)); 1044 reqh->actlen = actlen; 1045 if (status != 0) { 1046 DPRINTFN(-1+((status&UHCI_TD_STALLED)!=0), 1047 ("uhci_idone: error, addr=%d, endpt=0x%02x, " 1048 "status 0x%b\n", 1049 reqh->pipe->device->address, 1050 reqh->pipe->endpoint->edesc->bEndpointAddress, 1051 (int)status, 1052 "\20\22BITSTUFF\23CRCTO\24NAK\25BABBLE\26DBUFFER\27" 1053 "STALLED\30ACTIVE")); 1054 if (status == UHCI_TD_STALLED) 1055 reqh->status = USBD_STALLED; 1056 else 1057 reqh->status = USBD_IOERROR; /* more info XXX */ 1058 } else { 1059 reqh->status = USBD_NORMAL_COMPLETION; 1060 } 1061 reqh->hcpriv = ii; 1062 usb_transfer_complete(reqh); 1063 } 1064 1065 /* 1066 * Called when a request does not complete. 1067 */ 1068 void 1069 uhci_timeout(addr) 1070 void *addr; 1071 { 1072 uhci_intr_info_t *ii = addr; 1073 1074 DPRINTF(("uhci_timeout: ii=%p\n", ii)); 1075 1076 ii->reqh->device->bus->intr_context++; 1077 uhci_abort_req(ii->reqh, USBD_TIMEOUT); 1078 ii->reqh->device->bus->intr_context--; 1079 } 1080 1081 /* 1082 * Wait here until controller claims to have an interrupt. 1083 * Then call uhci_intr and return. Use timeout to avoid waiting 1084 * too long. 1085 * Only used during boot when interrupts are not enabled yet. 1086 */ 1087 void 1088 uhci_waitintr(sc, reqh) 1089 uhci_softc_t *sc; 1090 usbd_request_handle reqh; 1091 { 1092 int timo = reqh->timeout; 1093 uhci_intr_info_t *ii; 1094 1095 DPRINTFN(10,("uhci_waitintr: timeout = %dms\n", timo)); 1096 1097 reqh->status = USBD_IN_PROGRESS; 1098 for (; timo >= 0; timo--) { 1099 usb_delay_ms(&sc->sc_bus, 1); 1100 DPRINTFN(20,("uhci_waitintr: 0x%04x\n", UREAD2(sc, UHCI_STS))); 1101 if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT) { 1102 uhci_intr(sc); 1103 if (reqh->status != USBD_IN_PROGRESS) 1104 return; 1105 } 1106 } 1107 1108 /* Timeout */ 1109 DPRINTF(("uhci_waitintr: timeout\n")); 1110 for (ii = LIST_FIRST(&sc->sc_intrhead); 1111 ii && ii->reqh != reqh; 1112 ii = LIST_NEXT(ii, list)) 1113 ; 1114 #ifdef DIAGNOSTIC 1115 if (!ii) 1116 panic("uhci_waitintr: lost intr_info\n"); 1117 #endif 1118 uhci_idone(ii); 1119 } 1120 1121 void 1122 uhci_poll(bus) 1123 struct usbd_bus *bus; 1124 { 1125 uhci_softc_t *sc = (uhci_softc_t *)bus; 1126 1127 if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT) 1128 uhci_intr(sc); 1129 } 1130 1131 #if 0 1132 void 1133 uhci_reset(p) 1134 void *p; 1135 { 1136 uhci_softc_t *sc = p; 1137 int n; 1138 1139 UHCICMD(sc, UHCI_CMD_HCRESET); 1140 /* The reset bit goes low when the controller is done. */ 1141 for (n = 0; n < UHCI_RESET_TIMEOUT && 1142 (UREAD2(sc, UHCI_CMD) & UHCI_CMD_HCRESET); n++) 1143 delay(100); 1144 if (n >= UHCI_RESET_TIMEOUT) 1145 printf("%s: controller did not reset\n", 1146 USBDEVNAME(sc->sc_bus.bdev)); 1147 } 1148 #endif 1149 1150 usbd_status 1151 uhci_run(sc, run) 1152 uhci_softc_t *sc; 1153 int run; 1154 { 1155 int s, n, running; 1156 1157 run = run != 0; 1158 s = splusb(); 1159 DPRINTF(("uhci_run: setting run=%d\n", run)); 1160 UHCICMD(sc, run ? UHCI_CMD_RS : 0); 1161 for(n = 0; n < 10; n++) { 1162 running = !(UREAD2(sc, UHCI_STS) & UHCI_STS_HCH); 1163 /* return when we've entered the state we want */ 1164 if (run == running) { 1165 splx(s); 1166 DPRINTF(("uhci_run: done cmd=0x%x sts=0x%x\n", 1167 UREAD2(sc, UHCI_CMD), UREAD2(sc, UHCI_STS))); 1168 return (USBD_NORMAL_COMPLETION); 1169 } 1170 usb_delay_ms(&sc->sc_bus, 1); 1171 } 1172 splx(s); 1173 printf("%s: cannot %s\n", USBDEVNAME(sc->sc_bus.bdev), 1174 run ? "start" : "stop"); 1175 return (USBD_IOERROR); 1176 } 1177 1178 /* 1179 * Memory management routines. 1180 * uhci_alloc_std allocates TDs 1181 * uhci_alloc_sqh allocates QHs 1182 * These two routines do their own free list management, 1183 * partly for speed, partly because allocating DMAable memory 1184 * has page size granularaity so much memory would be wasted if 1185 * only one TD/QH (32 bytes) was placed in each allocated chunk. 1186 */ 1187 1188 uhci_soft_td_t * 1189 uhci_alloc_std(sc) 1190 uhci_softc_t *sc; 1191 { 1192 uhci_soft_td_t *std; 1193 usbd_status r; 1194 int i, offs; 1195 usb_dma_t dma; 1196 1197 if (!sc->sc_freetds) { 1198 DPRINTFN(2,("uhci_alloc_std: allocating chunk\n")); 1199 r = usb_allocmem(&sc->sc_bus, UHCI_STD_SIZE * UHCI_STD_CHUNK, 1200 UHCI_TD_ALIGN, &dma); 1201 if (r != USBD_NORMAL_COMPLETION) 1202 return (0); 1203 for(i = 0; i < UHCI_STD_CHUNK; i++) { 1204 offs = i * UHCI_STD_SIZE; 1205 std = (uhci_soft_td_t *)((char *)KERNADDR(&dma) +offs); 1206 std->physaddr = DMAADDR(&dma) + offs; 1207 std->link.std = sc->sc_freetds; 1208 sc->sc_freetds = std; 1209 } 1210 } 1211 std = sc->sc_freetds; 1212 sc->sc_freetds = std->link.std; 1213 memset(&std->td, 0, sizeof(uhci_td_t)); 1214 return std; 1215 } 1216 1217 void 1218 uhci_free_std(sc, std) 1219 uhci_softc_t *sc; 1220 uhci_soft_td_t *std; 1221 { 1222 #ifdef DIAGNOSTIC 1223 #define TD_IS_FREE 0x12345678 1224 if (LE(std->td.td_token) == TD_IS_FREE) { 1225 printf("uhci_free_std: freeing free TD %p\n", std); 1226 return; 1227 } 1228 std->td.td_token = LE(TD_IS_FREE); 1229 #endif 1230 std->link.std = sc->sc_freetds; 1231 sc->sc_freetds = std; 1232 } 1233 1234 uhci_soft_qh_t * 1235 uhci_alloc_sqh(sc) 1236 uhci_softc_t *sc; 1237 { 1238 uhci_soft_qh_t *sqh; 1239 usbd_status r; 1240 int i, offs; 1241 usb_dma_t dma; 1242 1243 if (!sc->sc_freeqhs) { 1244 DPRINTFN(2, ("uhci_alloc_sqh: allocating chunk\n")); 1245 r = usb_allocmem(&sc->sc_bus, UHCI_SQH_SIZE * UHCI_SQH_CHUNK, 1246 UHCI_QH_ALIGN, &dma); 1247 if (r != USBD_NORMAL_COMPLETION) 1248 return 0; 1249 for(i = 0; i < UHCI_SQH_CHUNK; i++) { 1250 offs = i * UHCI_SQH_SIZE; 1251 sqh = (uhci_soft_qh_t *)((char *)KERNADDR(&dma) +offs); 1252 sqh->physaddr = DMAADDR(&dma) + offs; 1253 sqh->hlink = sc->sc_freeqhs; 1254 sc->sc_freeqhs = sqh; 1255 } 1256 } 1257 sqh = sc->sc_freeqhs; 1258 sc->sc_freeqhs = sqh->hlink; 1259 memset(&sqh->qh, 0, sizeof(uhci_qh_t)); 1260 return (sqh); 1261 } 1262 1263 void 1264 uhci_free_sqh(sc, sqh) 1265 uhci_softc_t *sc; 1266 uhci_soft_qh_t *sqh; 1267 { 1268 sqh->hlink = sc->sc_freeqhs; 1269 sc->sc_freeqhs = sqh; 1270 } 1271 1272 #if 0 1273 /* 1274 * Enter a list of transfers onto a control queue. 1275 * Called at splusb() 1276 */ 1277 void 1278 uhci_enter_ctl_q(sc, sqh, ii) 1279 uhci_softc_t *sc; 1280 uhci_soft_qh_t *sqh; 1281 uhci_intr_info_t *ii; 1282 { 1283 DPRINTFN(5, ("uhci_enter_ctl_q: sqh=%p\n", sqh)); 1284 1285 } 1286 #endif 1287 1288 void 1289 uhci_free_std_chain(sc, std, stdend) 1290 uhci_softc_t *sc; 1291 uhci_soft_td_t *std; 1292 uhci_soft_td_t *stdend; 1293 { 1294 uhci_soft_td_t *p; 1295 1296 for (; std != stdend; std = p) { 1297 p = std->link.std; 1298 uhci_free_std(sc, std); 1299 } 1300 } 1301 1302 usbd_status 1303 uhci_alloc_std_chain(upipe, sc, len, rd, shortok, dma, sp, ep) 1304 struct uhci_pipe *upipe; 1305 uhci_softc_t *sc; 1306 int len, rd, shortok; 1307 usb_dma_t *dma; 1308 uhci_soft_td_t **sp, **ep; 1309 { 1310 uhci_soft_td_t *p, *lastp; 1311 uhci_physaddr_t lastlink; 1312 int i, ntd, l, tog, maxp; 1313 u_int32_t status; 1314 int addr = upipe->pipe.device->address; 1315 int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress; 1316 1317 DPRINTFN(8, ("uhci_alloc_std_chain: addr=%d endpt=%d len=%d ls=%d " 1318 "shortok=%d\n", addr, UE_GET_ADDR(endpt), len, 1319 upipe->pipe.device->lowspeed, shortok)); 1320 if (len == 0) { 1321 *sp = *ep = 0; 1322 DPRINTFN(-1,("uhci_alloc_std_chain: len=0\n")); 1323 return (USBD_NORMAL_COMPLETION); 1324 } 1325 maxp = UGETW(upipe->pipe.endpoint->edesc->wMaxPacketSize); 1326 if (maxp == 0) { 1327 printf("uhci_alloc_std_chain: maxp=0\n"); 1328 return (USBD_INVAL); 1329 } 1330 ntd = (len + maxp - 1) / maxp; 1331 DPRINTFN(10, ("uhci_alloc_std_chain: maxp=%d ntd=%d\n", maxp, ntd)); 1332 tog = upipe->nexttoggle; 1333 if (ntd % 2 == 0) 1334 tog ^= 1; 1335 upipe->nexttoggle = tog ^ 1; 1336 lastp = 0; 1337 lastlink = UHCI_PTR_T; 1338 ntd--; 1339 status = UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(3) | UHCI_TD_ACTIVE); 1340 if (upipe->pipe.device->lowspeed) 1341 status |= UHCI_TD_LS; 1342 if (shortok) 1343 status |= UHCI_TD_SPD; 1344 for (i = ntd; i >= 0; i--) { 1345 p = uhci_alloc_std(sc); 1346 if (!p) { 1347 uhci_free_std_chain(sc, lastp, 0); 1348 return (USBD_NOMEM); 1349 } 1350 p->link.std = lastp; 1351 p->td.td_link = LE(lastlink); 1352 lastp = p; 1353 lastlink = p->physaddr; 1354 p->td.td_status = LE(status); 1355 if (i == ntd) { 1356 /* last TD */ 1357 l = len % maxp; 1358 if (l == 0) l = maxp; 1359 *ep = p; 1360 } else 1361 l = maxp; 1362 p->td.td_token = 1363 LE(rd ? UHCI_TD_IN (l, endpt, addr, tog) : 1364 UHCI_TD_OUT(l, endpt, addr, tog)); 1365 p->td.td_buffer = LE(DMAADDR(dma) + i * maxp); 1366 tog ^= 1; 1367 } 1368 *sp = lastp; 1369 DPRINTFN(10, ("uhci_alloc_std_chain: nexttog=%d\n", 1370 upipe->nexttoggle)); 1371 return (USBD_NORMAL_COMPLETION); 1372 } 1373 1374 void 1375 uhci_device_clear_toggle(pipe) 1376 usbd_pipe_handle pipe; 1377 { 1378 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe; 1379 upipe->nexttoggle = 0; 1380 } 1381 1382 void 1383 uhci_noop(pipe) 1384 usbd_pipe_handle pipe; 1385 { 1386 } 1387 1388 usbd_status 1389 uhci_device_bulk_transfer(reqh) 1390 usbd_request_handle reqh; 1391 { 1392 usbd_status r; 1393 1394 /* Insert last in queue. */ 1395 r = usb_insert_transfer(reqh); 1396 if (r != USBD_NORMAL_COMPLETION) 1397 return (r); 1398 1399 /* Pipe isn't running, start first */ 1400 return (uhci_device_bulk_start(SIMPLEQ_FIRST(&reqh->pipe->queue))); 1401 } 1402 1403 usbd_status 1404 uhci_device_bulk_start(reqh) 1405 usbd_request_handle reqh; 1406 { 1407 struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe; 1408 usbd_device_handle dev = upipe->pipe.device; 1409 uhci_softc_t *sc = (uhci_softc_t *)dev->bus; 1410 uhci_intr_info_t *ii = upipe->iinfo; 1411 uhci_soft_td_t *data, *dataend; 1412 uhci_soft_qh_t *sqh; 1413 usbd_status r; 1414 int len, isread, endpt; 1415 int s; 1416 1417 DPRINTFN(3, ("uhci_device_bulk_transfer: reqh=%p len=%d flags=%d\n", 1418 reqh, reqh->length, reqh->flags)); 1419 1420 #ifdef DIAGNOSTIC 1421 if (reqh->rqflags & URQ_REQUEST) 1422 panic("uhci_device_bulk_transfer: a request\n"); 1423 #endif 1424 1425 len = reqh->length; 1426 endpt = reqh->pipe->endpoint->edesc->bEndpointAddress; 1427 isread = UE_GET_DIR(endpt) == UE_DIR_IN; 1428 sqh = upipe->u.bulk.sqh; 1429 1430 upipe->u.bulk.isread = isread; 1431 upipe->u.bulk.length = len; 1432 1433 r = uhci_alloc_std_chain(upipe, sc, len, isread, 1434 reqh->flags & USBD_SHORT_XFER_OK, 1435 &reqh->dmabuf, &data, &dataend); 1436 if (r != USBD_NORMAL_COMPLETION) 1437 return (r); 1438 dataend->td.td_status |= LE(UHCI_TD_IOC); 1439 1440 #ifdef UHCI_DEBUG 1441 if (uhcidebug > 8) { 1442 DPRINTF(("uhci_device_bulk_transfer: data(1)\n")); 1443 uhci_dump_tds(data); 1444 } 1445 #endif 1446 1447 /* Set up interrupt info. */ 1448 ii->reqh = reqh; 1449 ii->stdstart = data; 1450 ii->stdend = dataend; 1451 #if defined(__FreeBSD__) 1452 callout_handle_init(&ii->timeout_handle); 1453 #endif 1454 #ifdef DIAGNOSTIC 1455 ii->isdone = 0; 1456 #endif 1457 1458 sqh->elink = data; 1459 sqh->qh.qh_elink = LE(data->physaddr); 1460 sqh->intr_info = ii; 1461 1462 s = splusb(); 1463 uhci_add_bulk(sc, sqh); 1464 LIST_INSERT_HEAD(&sc->sc_intrhead, ii, list); 1465 1466 if (reqh->timeout && !sc->sc_bus.use_polling) { 1467 usb_timeout(uhci_timeout, ii, MS_TO_TICKS(reqh->timeout), 1468 ii->timeout_handle); 1469 } 1470 splx(s); 1471 1472 #ifdef UHCI_DEBUG 1473 if (uhcidebug > 10) { 1474 DPRINTF(("uhci_device_bulk_transfer: data(2)\n")); 1475 uhci_dump_tds(data); 1476 } 1477 #endif 1478 1479 if (sc->sc_bus.use_polling) 1480 uhci_waitintr(sc, reqh); 1481 1482 return (USBD_IN_PROGRESS); 1483 } 1484 1485 /* Abort a device bulk request. */ 1486 void 1487 uhci_device_bulk_abort(reqh) 1488 usbd_request_handle reqh; 1489 { 1490 DPRINTF(("uhci_device_bulk_abort:\n")); 1491 uhci_abort_req(reqh, USBD_CANCELLED); 1492 } 1493 1494 void 1495 uhci_abort_req(reqh, status) 1496 usbd_request_handle reqh; 1497 usbd_status status; 1498 { 1499 struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe; 1500 uhci_intr_info_t *ii = upipe->iinfo; 1501 uhci_soft_td_t *std; 1502 1503 /* Make interrupt routine ignore it, */ 1504 reqh->status = status; 1505 1506 /* don't timeout, */ 1507 usb_untimeout(uhci_timeout, ii, ii->timeout_handle); 1508 1509 /* make hardware ignore it, */ 1510 for (std = ii->stdstart; std != 0; std = std->link.std) 1511 std->td.td_status &= LE(~(UHCI_TD_ACTIVE | UHCI_TD_IOC)); 1512 1513 reqh->hcpriv = ii; 1514 1515 /* make sure hardware has completed, */ 1516 if (reqh->device->bus->intr_context) { 1517 /* We have no process context, so we can't use tsleep(). */ 1518 timeout(uhci_abort_req_end, reqh, hz / USB_FRAMES_PER_SECOND); 1519 } else { 1520 usb_delay_ms(reqh->pipe->device->bus, 1); 1521 /* and call final part of interrupt handler. */ 1522 uhci_abort_req_end(reqh); 1523 } 1524 } 1525 1526 void 1527 uhci_abort_req_end(v) 1528 void *v; 1529 { 1530 usbd_request_handle reqh = v; 1531 int s; 1532 1533 s = splusb(); 1534 usb_transfer_complete(reqh); 1535 splx(s); 1536 } 1537 1538 /* Close a device bulk pipe. */ 1539 void 1540 uhci_device_bulk_close(pipe) 1541 usbd_pipe_handle pipe; 1542 { 1543 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe; 1544 usbd_device_handle dev = upipe->pipe.device; 1545 uhci_softc_t *sc = (uhci_softc_t *)dev->bus; 1546 1547 uhci_free_sqh(sc, upipe->u.bulk.sqh); 1548 uhci_free_intr_info(upipe->iinfo); 1549 /* XXX free other resources */ 1550 } 1551 1552 usbd_status 1553 uhci_device_ctrl_transfer(reqh) 1554 usbd_request_handle reqh; 1555 { 1556 usbd_status r; 1557 1558 /* Insert last in queue. */ 1559 r = usb_insert_transfer(reqh); 1560 if (r != USBD_NORMAL_COMPLETION) 1561 return (r); 1562 1563 /* Pipe isn't running, start first */ 1564 return (uhci_device_ctrl_start(SIMPLEQ_FIRST(&reqh->pipe->queue))); 1565 } 1566 1567 usbd_status 1568 uhci_device_ctrl_start(reqh) 1569 usbd_request_handle reqh; 1570 { 1571 uhci_softc_t *sc = (uhci_softc_t *)reqh->pipe->device->bus; 1572 usbd_status r; 1573 1574 #ifdef DIAGNOSTIC 1575 if (!(reqh->rqflags & URQ_REQUEST)) 1576 panic("uhci_device_ctrl_transfer: not a request\n"); 1577 #endif 1578 1579 r = uhci_device_request(reqh); 1580 if (r != USBD_NORMAL_COMPLETION) 1581 return (r); 1582 1583 if (sc->sc_bus.use_polling) 1584 uhci_waitintr(sc, reqh); 1585 return (USBD_IN_PROGRESS); 1586 } 1587 1588 usbd_status 1589 uhci_device_intr_transfer(reqh) 1590 usbd_request_handle reqh; 1591 { 1592 usbd_status r; 1593 1594 /* Insert last in queue. */ 1595 r = usb_insert_transfer(reqh); 1596 if (r != USBD_NORMAL_COMPLETION) 1597 return (r); 1598 1599 /* Pipe isn't running, start first */ 1600 return (uhci_device_intr_start(SIMPLEQ_FIRST(&reqh->pipe->queue))); 1601 } 1602 1603 usbd_status 1604 uhci_device_intr_start(reqh) 1605 usbd_request_handle reqh; 1606 { 1607 struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe; 1608 usbd_device_handle dev = upipe->pipe.device; 1609 uhci_softc_t *sc = (uhci_softc_t *)dev->bus; 1610 uhci_intr_info_t *ii = upipe->iinfo; 1611 uhci_soft_td_t *data, *dataend; 1612 uhci_soft_qh_t *sqh; 1613 usbd_status r; 1614 int i, s; 1615 1616 DPRINTFN(3,("uhci_device_intr_transfer: reqh=%p len=%d flags=%d\n", 1617 reqh, reqh->length, reqh->flags)); 1618 1619 #ifdef DIAGNOSTIC 1620 if (reqh->rqflags & URQ_REQUEST) 1621 panic("uhci_device_intr_transfer: a request\n"); 1622 #endif 1623 1624 r = uhci_alloc_std_chain(upipe, sc, reqh->length, 1, 1625 reqh->flags & USBD_SHORT_XFER_OK, 1626 &reqh->dmabuf, &data, &dataend); 1627 if (r != USBD_NORMAL_COMPLETION) 1628 return (r); 1629 dataend->td.td_status |= LE(UHCI_TD_IOC); 1630 1631 #ifdef UHCI_DEBUG 1632 if (uhcidebug > 10) { 1633 DPRINTF(("uhci_device_intr_transfer: data(1)\n")); 1634 uhci_dump_tds(data); 1635 uhci_dump_qh(upipe->u.intr.qhs[0]); 1636 } 1637 #endif 1638 1639 s = splusb(); 1640 /* Set up interrupt info. */ 1641 ii->reqh = reqh; 1642 ii->stdstart = data; 1643 ii->stdend = dataend; 1644 #if defined(__FreeBSD__) 1645 callout_handle_init(&ii->timeout_handle); 1646 #endif 1647 #ifdef DIAGNOSTIC 1648 ii->isdone = 0; 1649 #endif 1650 1651 DPRINTFN(10,("uhci_device_intr_transfer: qhs[0]=%p\n", 1652 upipe->u.intr.qhs[0])); 1653 for (i = 0; i < upipe->u.intr.npoll; i++) { 1654 sqh = upipe->u.intr.qhs[i]; 1655 sqh->elink = data; 1656 sqh->qh.qh_elink = LE(data->physaddr); 1657 } 1658 splx(s); 1659 1660 #ifdef UHCI_DEBUG 1661 if (uhcidebug > 10) { 1662 DPRINTF(("uhci_device_intr_transfer: data(2)\n")); 1663 uhci_dump_tds(data); 1664 uhci_dump_qh(upipe->u.intr.qhs[0]); 1665 } 1666 #endif 1667 1668 return (USBD_IN_PROGRESS); 1669 } 1670 1671 /* Abort a device control request. */ 1672 void 1673 uhci_device_ctrl_abort(reqh) 1674 usbd_request_handle reqh; 1675 { 1676 DPRINTF(("uhci_device_ctrl_abort:\n")); 1677 uhci_abort_req(reqh, USBD_CANCELLED); 1678 } 1679 1680 /* Close a device control pipe. */ 1681 void 1682 uhci_device_ctrl_close(pipe) 1683 usbd_pipe_handle pipe; 1684 { 1685 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe; 1686 1687 uhci_free_intr_info(upipe->iinfo); 1688 /* XXX free other resources */ 1689 } 1690 1691 /* Abort a device interrupt request. */ 1692 void 1693 uhci_device_intr_abort(reqh) 1694 usbd_request_handle reqh; 1695 { 1696 DPRINTFN(1,("uhci_device_intr_abort: reqh=%p\n", reqh)); 1697 if (reqh->pipe->intrreqh == reqh) { 1698 DPRINTFN(1,("uhci_device_intr_abort: remove\n")); 1699 reqh->pipe->intrreqh = 0; 1700 } 1701 uhci_abort_req(reqh, USBD_CANCELLED); 1702 } 1703 1704 /* Close a device interrupt pipe. */ 1705 void 1706 uhci_device_intr_close(pipe) 1707 usbd_pipe_handle pipe; 1708 { 1709 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe; 1710 uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus; 1711 int i, s, npoll; 1712 1713 upipe->iinfo->stdstart = 0; /* inactive */ 1714 1715 /* Unlink descriptors from controller data structures. */ 1716 npoll = upipe->u.intr.npoll; 1717 uhci_lock_frames(sc); 1718 for (i = 0; i < npoll; i++) 1719 uhci_remove_intr(sc, upipe->u.intr.qhs[i]->pos, 1720 upipe->u.intr.qhs[i]); 1721 uhci_unlock_frames(sc); 1722 1723 /* 1724 * We now have to wait for any activity on the physical 1725 * descriptors to stop. 1726 */ 1727 usb_delay_ms(&sc->sc_bus, 2); 1728 1729 for(i = 0; i < npoll; i++) 1730 uhci_free_sqh(sc, upipe->u.intr.qhs[i]); 1731 free(upipe->u.intr.qhs, M_USBHC); 1732 1733 s = splusb(); 1734 LIST_REMOVE(upipe->iinfo, list); /* remove from active list */ 1735 splx(s); 1736 uhci_free_intr_info(upipe->iinfo); 1737 1738 /* XXX free other resources */ 1739 } 1740 1741 usbd_status 1742 uhci_device_request(reqh) 1743 usbd_request_handle reqh; 1744 { 1745 struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe; 1746 usb_device_request_t *req = &reqh->request; 1747 usbd_device_handle dev = upipe->pipe.device; 1748 uhci_softc_t *sc = (uhci_softc_t *)dev->bus; 1749 int addr = dev->address; 1750 int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress; 1751 uhci_intr_info_t *ii = upipe->iinfo; 1752 uhci_soft_td_t *setup, *data, *stat, *next, *dataend; 1753 uhci_soft_qh_t *sqh; 1754 int len; 1755 u_int32_t ls; 1756 usbd_status r; 1757 int isread; 1758 int s; 1759 1760 DPRINTFN(3,("uhci_device_control type=0x%02x, request=0x%02x, " 1761 "wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n", 1762 req->bmRequestType, req->bRequest, UGETW(req->wValue), 1763 UGETW(req->wIndex), UGETW(req->wLength), 1764 addr, endpt)); 1765 1766 ls = dev->lowspeed ? UHCI_TD_LS : 0; 1767 isread = req->bmRequestType & UT_READ; 1768 len = UGETW(req->wLength); 1769 1770 setup = upipe->u.ctl.setup; 1771 stat = upipe->u.ctl.stat; 1772 sqh = upipe->u.ctl.sqh; 1773 1774 /* Set up data transaction */ 1775 if (len != 0) { 1776 upipe->nexttoggle = 1; 1777 r = uhci_alloc_std_chain(upipe, sc, len, isread, 1778 reqh->flags & USBD_SHORT_XFER_OK, 1779 &reqh->dmabuf, &data, &dataend); 1780 if (r != USBD_NORMAL_COMPLETION) 1781 return (r); 1782 next = data; 1783 dataend->link.std = stat; 1784 dataend->td.td_link = LE(stat->physaddr); 1785 } else { 1786 next = stat; 1787 } 1788 upipe->u.ctl.length = len; 1789 1790 memcpy(KERNADDR(&upipe->u.ctl.reqdma), req, sizeof *req); 1791 1792 setup->link.std = next; 1793 setup->td.td_link = LE(next->physaddr); 1794 setup->td.td_status = LE(UHCI_TD_SET_ERRCNT(3) | ls | UHCI_TD_ACTIVE); 1795 setup->td.td_token = LE(UHCI_TD_SETUP(sizeof *req, endpt, addr)); 1796 setup->td.td_buffer = LE(DMAADDR(&upipe->u.ctl.reqdma)); 1797 1798 stat->link.std = 0; 1799 stat->td.td_link = LE(UHCI_PTR_T); 1800 stat->td.td_status = LE(UHCI_TD_SET_ERRCNT(3) | ls | 1801 UHCI_TD_ACTIVE | UHCI_TD_IOC); 1802 stat->td.td_token = 1803 LE(isread ? UHCI_TD_OUT(0, endpt, addr, 1) : 1804 UHCI_TD_IN (0, endpt, addr, 1)); 1805 stat->td.td_buffer = LE(0); 1806 1807 #ifdef UHCI_DEBUG 1808 if (uhcidebug > 20) { 1809 DPRINTF(("uhci_device_request: before transfer\n")); 1810 uhci_dump_tds(setup); 1811 } 1812 #endif 1813 1814 /* Set up interrupt info. */ 1815 ii->reqh = reqh; 1816 ii->stdstart = setup; 1817 ii->stdend = stat; 1818 #if defined(__FreeBSD__) 1819 callout_handle_init(&ii->timeout_handle); 1820 #endif 1821 #ifdef DIAGNOSTIC 1822 ii->isdone = 0; 1823 #endif 1824 1825 sqh->elink = setup; 1826 sqh->qh.qh_elink = LE(setup->physaddr); 1827 sqh->intr_info = ii; 1828 1829 s = splusb(); 1830 uhci_add_ctrl(sc, sqh); 1831 LIST_INSERT_HEAD(&sc->sc_intrhead, ii, list); 1832 #ifdef UHCI_DEBUG 1833 if (uhcidebug > 12) { 1834 uhci_soft_td_t *std; 1835 uhci_soft_qh_t *xqh; 1836 uhci_soft_qh_t *sxqh; 1837 int maxqh = 0; 1838 uhci_physaddr_t link; 1839 DPRINTF(("uhci_enter_ctl_q: follow from [0]\n")); 1840 for (std = sc->sc_vframes[0].htd, link = 0; 1841 (link & UHCI_PTR_Q) == 0; 1842 std = std->link.std) { 1843 link = LE(std->td.td_link); 1844 uhci_dump_td(std); 1845 } 1846 for (sxqh = xqh = (uhci_soft_qh_t *)std; 1847 xqh; 1848 xqh = (maxqh++ == 5 || xqh->hlink==sxqh || 1849 xqh->hlink==xqh ? NULL : xqh->hlink)) { 1850 uhci_dump_qh(xqh); 1851 uhci_dump_qh(sxqh); 1852 } 1853 DPRINTF(("Enqueued QH:\n")); 1854 uhci_dump_qh(sqh); 1855 uhci_dump_tds(sqh->elink); 1856 } 1857 #endif 1858 if (reqh->timeout && !sc->sc_bus.use_polling) { 1859 usb_timeout(uhci_timeout, ii, 1860 MS_TO_TICKS(reqh->timeout), ii->timeout_handle); 1861 } 1862 splx(s); 1863 1864 return (USBD_NORMAL_COMPLETION); 1865 } 1866 1867 usbd_status 1868 uhci_device_isoc_transfer(reqh) 1869 usbd_request_handle reqh; 1870 { 1871 usbd_status r; 1872 1873 DPRINTFN(5,("uhci_device_isoc_transfer: reqh=%p\n", reqh)); 1874 1875 /* Put it on our queue, */ 1876 r = usb_insert_transfer(reqh); 1877 1878 /* bail out on error, */ 1879 if (r != USBD_NORMAL_COMPLETION && r != USBD_IN_PROGRESS) 1880 return (r); 1881 1882 /* XXX should check inuse here */ 1883 1884 /* insert into schedule, */ 1885 uhci_device_isoc_enter(reqh); 1886 1887 /* and put on interrupt list if the pipe wasn't running */ 1888 if (r == USBD_NORMAL_COMPLETION) 1889 uhci_device_isoc_start(SIMPLEQ_FIRST(&reqh->pipe->queue)); 1890 1891 return (r); 1892 } 1893 1894 void 1895 uhci_device_isoc_enter(reqh) 1896 usbd_request_handle reqh; 1897 { 1898 struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe; 1899 usbd_device_handle dev = upipe->pipe.device; 1900 uhci_softc_t *sc = (uhci_softc_t *)dev->bus; 1901 struct iso *iso = &upipe->u.iso; 1902 uhci_soft_td_t *std; 1903 u_int32_t buf, len, status; 1904 int s, i, next, nframes; 1905 1906 DPRINTFN(5,("uhci_device_isoc_enter: used=%d next=%d reqh=%p " 1907 "nframes=%d\n", 1908 iso->inuse, iso->next, reqh, reqh->nframes)); 1909 1910 if (reqh->status == USBD_IN_PROGRESS) { 1911 /* This request has already been entered into the frame list */ 1912 } 1913 1914 #ifdef DIAGNOSTIC 1915 if (iso->inuse >= UHCI_VFRAMELIST_COUNT) 1916 printf("uhci_device_isoc_enter: overflow!\n"); 1917 #endif 1918 1919 next = iso->next; 1920 if (next == -1) { 1921 /* Not in use yet, schedule it a few frames ahead. */ 1922 next = (UREAD2(sc, UHCI_FRNUM) + 3) % UHCI_VFRAMELIST_COUNT; 1923 DPRINTFN(2,("uhci_device_isoc_enter: start next=%d\n", next)); 1924 } 1925 1926 reqh->status = USBD_IN_PROGRESS; 1927 reqh->hcprivint = next; 1928 1929 buf = DMAADDR(&reqh->dmabuf); 1930 status = LE(UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(0) | 1931 UHCI_TD_ACTIVE | 1932 UHCI_TD_IOS)); 1933 nframes = reqh->nframes; 1934 s = splusb(); 1935 for (i = 0; i < nframes; i++) { 1936 std = iso->stds[next]; 1937 if (++next >= UHCI_VFRAMELIST_COUNT) 1938 next = 0; 1939 len = reqh->frlengths[i]; 1940 std->td.td_buffer = LE(buf); 1941 if (i == nframes - 1) 1942 status |= LE(UHCI_TD_IOC); 1943 std->td.td_status = status; 1944 std->td.td_token &= LE(~UHCI_TD_MAXLEN_MASK); 1945 std->td.td_token |= LE(UHCI_TD_SET_MAXLEN(len)); 1946 #ifdef UHCI_DEBUG 1947 if (uhcidebug > 5) { 1948 DPRINTFN(5,("uhci_device_isoc_enter: TD %d\n", i)); 1949 uhci_dump_td(std); 1950 } 1951 #endif 1952 buf += len; 1953 } 1954 iso->next = next; 1955 iso->inuse += reqh->nframes; 1956 1957 splx(s); 1958 } 1959 1960 usbd_status 1961 uhci_device_isoc_start(reqh) 1962 usbd_request_handle reqh; 1963 { 1964 struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe; 1965 uhci_softc_t *sc = (uhci_softc_t *)upipe->pipe.device->bus; 1966 uhci_intr_info_t *ii = upipe->iinfo; 1967 uhci_soft_td_t *end; 1968 int s, i; 1969 1970 #ifdef DIAGNOSTIC 1971 if (reqh->status != USBD_IN_PROGRESS) 1972 printf("uhci_device_isoc_start: not in progress %p\n", reqh); 1973 #endif 1974 1975 /* Find the last TD */ 1976 i = reqh->hcprivint + reqh->nframes; 1977 if (i >= UHCI_VFRAMELIST_COUNT) 1978 i -= UHCI_VFRAMELIST_COUNT; 1979 end = upipe->u.iso.stds[i]; 1980 1981 s = splusb(); 1982 1983 /* Set up interrupt info. */ 1984 ii->reqh = reqh; 1985 ii->stdstart = end; 1986 ii->stdend = end; 1987 #if defined(__FreeBSD__) 1988 callout_handle_init(&ii->timeout_handle); 1989 #endif 1990 #ifdef DIAGNOSTIC 1991 ii->isdone = 0; 1992 #endif 1993 LIST_INSERT_HEAD(&sc->sc_intrhead, ii, list); 1994 1995 splx(s); 1996 1997 return (USBD_IN_PROGRESS); 1998 } 1999 2000 void 2001 uhci_device_isoc_abort(reqh) 2002 usbd_request_handle reqh; 2003 { 2004 struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe; 2005 uhci_intr_info_t *ii = upipe->iinfo; 2006 uhci_soft_td_t **stds = upipe->u.iso.stds; 2007 uhci_soft_td_t *std; 2008 int i, n, nframes; 2009 2010 /* Make interrupt routine ignore it, */ 2011 reqh->status = USBD_CANCELLED; 2012 2013 /* make hardware ignore it, */ 2014 nframes = reqh->nframes; 2015 n = reqh->hcprivint; 2016 for (i = 0; i < nframes; i++) { 2017 std = stds[n]; 2018 std->td.td_status &= LE(~(UHCI_TD_ACTIVE | UHCI_TD_IOC)); 2019 if (++n >= UHCI_VFRAMELIST_COUNT) 2020 n = 0; 2021 } 2022 2023 reqh->hcpriv = ii; 2024 2025 /* make sure hardware has completed, */ 2026 if (reqh->device->bus->intr_context) { 2027 /* We have no process context, so we can't use tsleep(). */ 2028 timeout(uhci_abort_req_end, reqh, hz / USB_FRAMES_PER_SECOND); 2029 } else { 2030 usb_delay_ms(reqh->pipe->device->bus, 1); 2031 /* and call final part of interrupt handler. */ 2032 uhci_abort_req_end(reqh); 2033 } 2034 } 2035 2036 void 2037 uhci_device_isoc_close(pipe) 2038 usbd_pipe_handle pipe; 2039 { 2040 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe; 2041 usbd_device_handle dev = upipe->pipe.device; 2042 uhci_softc_t *sc = (uhci_softc_t *)dev->bus; 2043 uhci_soft_td_t *std, *vstd; 2044 struct iso *iso; 2045 int i; 2046 2047 /* 2048 * Make sure all TDs are marked as inactive. 2049 * Wait for completion. 2050 * Unschedule. 2051 * Deallocate. 2052 */ 2053 iso = &upipe->u.iso; 2054 2055 for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) 2056 iso->stds[i]->td.td_status &= LE(~UHCI_TD_ACTIVE); 2057 usb_delay_ms(&sc->sc_bus, 2); /* wait for completion */ 2058 2059 uhci_lock_frames(sc); 2060 for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) { 2061 std = iso->stds[i]; 2062 for (vstd = sc->sc_vframes[i].htd; 2063 vstd && vstd->link.std != std; 2064 vstd = vstd->link.std) 2065 ; 2066 if (!vstd) { 2067 /*panic*/ 2068 printf("uhci_device_isoc_close: %p not found\n", std); 2069 uhci_unlock_frames(sc); 2070 return; 2071 } 2072 vstd->link = std->link; 2073 vstd->td.td_link = std->td.td_link; 2074 uhci_free_std(sc, std); 2075 } 2076 uhci_unlock_frames(sc); 2077 2078 free(iso->stds, M_USBHC); 2079 } 2080 2081 usbd_status 2082 uhci_setup_isoc(pipe) 2083 usbd_pipe_handle pipe; 2084 { 2085 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe; 2086 usbd_device_handle dev = upipe->pipe.device; 2087 uhci_softc_t *sc = (uhci_softc_t *)dev->bus; 2088 int addr = upipe->pipe.device->address; 2089 int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress; 2090 int rd = UE_GET_DIR(endpt) == UE_DIR_IN; 2091 uhci_soft_td_t *std, *vstd; 2092 u_int32_t token; 2093 struct iso *iso; 2094 int i; 2095 2096 iso = &upipe->u.iso; 2097 iso->stds = malloc(UHCI_VFRAMELIST_COUNT * sizeof (uhci_soft_td_t *), 2098 M_USBHC, M_WAITOK); 2099 2100 token = LE(rd ? UHCI_TD_IN (0, endpt, addr, 0) : 2101 UHCI_TD_OUT(0, endpt, addr, 0)); 2102 2103 /* Allocate the TDs and mark as inactive; */ 2104 for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) { 2105 std = uhci_alloc_std(sc); 2106 if (std == 0) 2107 goto bad; 2108 std->td.td_status = LE(UHCI_TD_IOS); /* iso, inactive */ 2109 std->td.td_token = token; 2110 iso->stds[i] = std; 2111 } 2112 2113 /* Insert TDs into schedule. */ 2114 uhci_lock_frames(sc); 2115 for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) { 2116 std = iso->stds[i]; 2117 vstd = sc->sc_vframes[i].htd; 2118 std->link = vstd->link; 2119 std->td.td_link = vstd->td.td_link; 2120 vstd->link.std = std; 2121 vstd->td.td_link = LE(std->physaddr); 2122 } 2123 uhci_unlock_frames(sc); 2124 2125 iso->next = -1; 2126 iso->inuse = 0; 2127 2128 return (USBD_NORMAL_COMPLETION); 2129 2130 bad: 2131 while (--i >= 0) 2132 uhci_free_std(sc, iso->stds[i]); 2133 free(iso->stds, M_USBHC); 2134 return (USBD_NOMEM); 2135 } 2136 2137 void 2138 uhci_device_isoc_done(reqh) 2139 usbd_request_handle reqh; 2140 { 2141 uhci_intr_info_t *ii = reqh->hcpriv; 2142 2143 DPRINTFN(4, ("uhci_isoc_done: length=%d\n", reqh->actlen)); 2144 2145 /* Turn off the interrupt since it is active even if the TD is not. */ 2146 ii->stdend->td.td_status &= LE(~UHCI_TD_IOC); 2147 2148 LIST_REMOVE(ii, list); /* remove from active list */ 2149 } 2150 2151 void 2152 uhci_device_intr_done(reqh) 2153 usbd_request_handle reqh; 2154 { 2155 uhci_intr_info_t *ii = reqh->hcpriv; 2156 uhci_softc_t *sc = ii->sc; 2157 struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe; 2158 uhci_soft_qh_t *sqh; 2159 int i, npoll; 2160 2161 DPRINTFN(5, ("uhci_intr_done: length=%d\n", reqh->actlen)); 2162 2163 npoll = upipe->u.intr.npoll; 2164 for(i = 0; i < npoll; i++) { 2165 sqh = upipe->u.intr.qhs[i]; 2166 sqh->elink = 0; 2167 sqh->qh.qh_elink = LE(UHCI_PTR_T); 2168 } 2169 uhci_free_std_chain(sc, ii->stdstart, 0); 2170 2171 /* XXX Wasteful. */ 2172 if (reqh->pipe->repeat) { 2173 uhci_soft_td_t *data, *dataend; 2174 2175 /* This alloc cannot fail since we freed the chain above. */ 2176 uhci_alloc_std_chain(upipe, sc, reqh->length, 1, 2177 reqh->flags & USBD_SHORT_XFER_OK, 2178 &reqh->dmabuf, &data, &dataend); 2179 dataend->td.td_status |= LE(UHCI_TD_IOC); 2180 2181 #ifdef UHCI_DEBUG 2182 if (uhcidebug > 10) { 2183 DPRINTF(("uhci_device_intr_done: data(1)\n")); 2184 uhci_dump_tds(data); 2185 uhci_dump_qh(upipe->u.intr.qhs[0]); 2186 } 2187 #endif 2188 2189 ii->stdstart = data; 2190 ii->stdend = dataend; 2191 #if defined(__FreeBSD__) 2192 callout_handle_init(&ii->timeout_handle); 2193 #endif 2194 #ifdef DIAGNOSTIC 2195 ii->isdone = 0; 2196 #endif 2197 for (i = 0; i < npoll; i++) { 2198 sqh = upipe->u.intr.qhs[i]; 2199 sqh->elink = data; 2200 sqh->qh.qh_elink = LE(data->physaddr); 2201 } 2202 } else { 2203 ii->stdstart = 0; /* mark as inactive */ 2204 } 2205 } 2206 2207 /* Deallocate request data structures */ 2208 void 2209 uhci_device_ctrl_done(reqh) 2210 usbd_request_handle reqh; 2211 { 2212 uhci_intr_info_t *ii = reqh->hcpriv; 2213 uhci_softc_t *sc = ii->sc; 2214 struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe; 2215 2216 #ifdef DIAGNOSTIC 2217 if (!(reqh->rqflags & URQ_REQUEST)) 2218 panic("uhci_ctrl_done: not a request\n"); 2219 #endif 2220 2221 LIST_REMOVE(ii, list); /* remove from active list */ 2222 2223 uhci_remove_ctrl(sc, upipe->u.ctl.sqh); 2224 2225 if (upipe->u.ctl.length != 0) 2226 uhci_free_std_chain(sc, ii->stdstart->link.std, ii->stdend); 2227 2228 DPRINTFN(5, ("uhci_ctrl_done: length=%d\n", reqh->actlen)); 2229 } 2230 2231 /* Deallocate request data structures */ 2232 void 2233 uhci_device_bulk_done(reqh) 2234 usbd_request_handle reqh; 2235 { 2236 uhci_intr_info_t *ii = reqh->hcpriv; 2237 uhci_softc_t *sc = ii->sc; 2238 struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe; 2239 2240 LIST_REMOVE(ii, list); /* remove from active list */ 2241 2242 uhci_remove_bulk(sc, upipe->u.bulk.sqh); 2243 2244 uhci_free_std_chain(sc, ii->stdstart, 0); 2245 2246 DPRINTFN(5, ("uhci_bulk_done: length=%d\n", reqh->actlen)); 2247 } 2248 2249 /* Add interrupt QH, called with vflock. */ 2250 void 2251 uhci_add_intr(sc, n, sqh) 2252 uhci_softc_t *sc; 2253 int n; 2254 uhci_soft_qh_t *sqh; 2255 { 2256 struct uhci_vframe *vf = &sc->sc_vframes[n]; 2257 uhci_soft_qh_t *eqh; 2258 2259 DPRINTFN(4, ("uhci_add_intr: n=%d sqh=%p\n", n, sqh)); 2260 eqh = vf->eqh; 2261 sqh->hlink = eqh->hlink; 2262 sqh->qh.qh_hlink = eqh->qh.qh_hlink; 2263 eqh->hlink = sqh; 2264 eqh->qh.qh_hlink = LE(sqh->physaddr | UHCI_PTR_Q); 2265 vf->eqh = sqh; 2266 vf->bandwidth++; 2267 } 2268 2269 /* Remove interrupt QH, called with vflock. */ 2270 void 2271 uhci_remove_intr(sc, n, sqh) 2272 uhci_softc_t *sc; 2273 int n; 2274 uhci_soft_qh_t *sqh; 2275 { 2276 struct uhci_vframe *vf = &sc->sc_vframes[n]; 2277 uhci_soft_qh_t *pqh; 2278 2279 DPRINTFN(4, ("uhci_remove_intr: n=%d sqh=%p\n", n, sqh)); 2280 2281 for (pqh = vf->hqh; pqh->hlink != sqh; pqh = pqh->hlink) 2282 #if defined(DIAGNOSTIC) || defined(UHCI_DEBUG) 2283 if (LE(pqh->qh.qh_hlink) & UHCI_PTR_T) { 2284 DPRINTF(("uhci_remove_intr: QH not found\n")); 2285 return; 2286 } 2287 #else 2288 ; 2289 #endif 2290 pqh->hlink = sqh->hlink; 2291 pqh->qh.qh_hlink = sqh->qh.qh_hlink; 2292 if (vf->eqh == sqh) 2293 vf->eqh = pqh; 2294 vf->bandwidth--; 2295 } 2296 2297 usbd_status 2298 uhci_device_setintr(sc, upipe, ival) 2299 uhci_softc_t *sc; 2300 struct uhci_pipe *upipe; 2301 int ival; 2302 { 2303 uhci_soft_qh_t *sqh; 2304 int i, npoll, s; 2305 u_int bestbw, bw, bestoffs, offs; 2306 2307 DPRINTFN(2, ("uhci_setintr: pipe=%p\n", upipe)); 2308 if (ival == 0) { 2309 printf("uhci_setintr: 0 interval\n"); 2310 return (USBD_INVAL); 2311 } 2312 2313 if (ival > UHCI_VFRAMELIST_COUNT) 2314 ival = UHCI_VFRAMELIST_COUNT; 2315 npoll = (UHCI_VFRAMELIST_COUNT + ival - 1) / ival; 2316 DPRINTFN(2, ("uhci_setintr: ival=%d npoll=%d\n", ival, npoll)); 2317 2318 upipe->u.intr.npoll = npoll; 2319 upipe->u.intr.qhs = 2320 malloc(npoll * sizeof(uhci_soft_qh_t *), M_USBHC, M_WAITOK); 2321 2322 /* 2323 * Figure out which offset in the schedule that has most 2324 * bandwidth left over. 2325 */ 2326 #define MOD(i) ((i) & (UHCI_VFRAMELIST_COUNT-1)) 2327 for (bestoffs = offs = 0, bestbw = ~0; offs < ival; offs++) { 2328 for (bw = i = 0; i < npoll; i++) 2329 bw += sc->sc_vframes[MOD(i * ival + offs)].bandwidth; 2330 if (bw < bestbw) { 2331 bestbw = bw; 2332 bestoffs = offs; 2333 } 2334 } 2335 DPRINTFN(1, ("uhci_setintr: bw=%d offs=%d\n", bestbw, bestoffs)); 2336 2337 upipe->iinfo->stdstart = 0; 2338 for(i = 0; i < npoll; i++) { 2339 upipe->u.intr.qhs[i] = sqh = uhci_alloc_sqh(sc); 2340 sqh->elink = 0; 2341 sqh->qh.qh_elink = LE(UHCI_PTR_T); 2342 sqh->pos = MOD(i * ival + bestoffs); 2343 sqh->intr_info = upipe->iinfo; 2344 } 2345 #undef MOD 2346 2347 s = splusb(); 2348 LIST_INSERT_HEAD(&sc->sc_intrhead, upipe->iinfo, list); 2349 splx(s); 2350 2351 uhci_lock_frames(sc); 2352 /* Enter QHs into the controller data structures. */ 2353 for(i = 0; i < npoll; i++) 2354 uhci_add_intr(sc, upipe->u.intr.qhs[i]->pos, 2355 upipe->u.intr.qhs[i]); 2356 uhci_unlock_frames(sc); 2357 2358 DPRINTFN(5, ("uhci_setintr: returns %p\n", upipe)); 2359 return (USBD_NORMAL_COMPLETION); 2360 } 2361 2362 /* Open a new pipe. */ 2363 usbd_status 2364 uhci_open(pipe) 2365 usbd_pipe_handle pipe; 2366 { 2367 uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus; 2368 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe; 2369 usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc; 2370 usbd_status r; 2371 2372 DPRINTFN(1, ("uhci_open: pipe=%p, addr=%d, endpt=%d (%d)\n", 2373 pipe, pipe->device->address, 2374 ed->bEndpointAddress, sc->sc_addr)); 2375 if (pipe->device->address == sc->sc_addr) { 2376 switch (ed->bEndpointAddress) { 2377 case USB_CONTROL_ENDPOINT: 2378 pipe->methods = &uhci_root_ctrl_methods; 2379 break; 2380 case UE_DIR_IN | UHCI_INTR_ENDPT: 2381 pipe->methods = &uhci_root_intr_methods; 2382 break; 2383 default: 2384 return (USBD_INVAL); 2385 } 2386 } else { 2387 upipe->iinfo = uhci_alloc_intr_info(sc); 2388 if (upipe->iinfo == 0) 2389 return (USBD_NOMEM); 2390 switch (ed->bmAttributes & UE_XFERTYPE) { 2391 case UE_CONTROL: 2392 pipe->methods = &uhci_device_ctrl_methods; 2393 upipe->u.ctl.sqh = uhci_alloc_sqh(sc); 2394 if (upipe->u.ctl.sqh == 0) 2395 goto bad; 2396 upipe->u.ctl.setup = uhci_alloc_std(sc); 2397 if (upipe->u.ctl.setup == 0) { 2398 uhci_free_sqh(sc, upipe->u.ctl.sqh); 2399 goto bad; 2400 } 2401 upipe->u.ctl.stat = uhci_alloc_std(sc); 2402 if (upipe->u.ctl.stat == 0) { 2403 uhci_free_sqh(sc, upipe->u.ctl.sqh); 2404 uhci_free_std(sc, upipe->u.ctl.setup); 2405 goto bad; 2406 } 2407 r = usb_allocmem(&sc->sc_bus, 2408 sizeof(usb_device_request_t), 2409 0, &upipe->u.ctl.reqdma); 2410 if (r != USBD_NORMAL_COMPLETION) { 2411 uhci_free_sqh(sc, upipe->u.ctl.sqh); 2412 uhci_free_std(sc, upipe->u.ctl.setup); 2413 uhci_free_std(sc, upipe->u.ctl.stat); 2414 goto bad; 2415 } 2416 break; 2417 case UE_INTERRUPT: 2418 pipe->methods = &uhci_device_intr_methods; 2419 return (uhci_device_setintr(sc, upipe, ed->bInterval)); 2420 case UE_ISOCHRONOUS: 2421 pipe->methods = &uhci_device_isoc_methods; 2422 return (uhci_setup_isoc(pipe)); 2423 case UE_BULK: 2424 pipe->methods = &uhci_device_bulk_methods; 2425 upipe->u.bulk.sqh = uhci_alloc_sqh(sc); 2426 if (upipe->u.bulk.sqh == 0) 2427 goto bad; 2428 break; 2429 } 2430 } 2431 return (USBD_NORMAL_COMPLETION); 2432 2433 bad: 2434 uhci_free_intr_info(upipe->iinfo); 2435 return (USBD_NOMEM); 2436 } 2437 2438 /* 2439 * Data structures and routines to emulate the root hub. 2440 */ 2441 usb_device_descriptor_t uhci_devd = { 2442 USB_DEVICE_DESCRIPTOR_SIZE, 2443 UDESC_DEVICE, /* type */ 2444 {0x00, 0x01}, /* USB version */ 2445 UCLASS_HUB, /* class */ 2446 USUBCLASS_HUB, /* subclass */ 2447 0, /* protocol */ 2448 64, /* max packet */ 2449 {0},{0},{0x00,0x01}, /* device id */ 2450 1,2,0, /* string indicies */ 2451 1 /* # of configurations */ 2452 }; 2453 2454 usb_config_descriptor_t uhci_confd = { 2455 USB_CONFIG_DESCRIPTOR_SIZE, 2456 UDESC_CONFIG, 2457 {USB_CONFIG_DESCRIPTOR_SIZE + 2458 USB_INTERFACE_DESCRIPTOR_SIZE + 2459 USB_ENDPOINT_DESCRIPTOR_SIZE}, 2460 1, 2461 1, 2462 0, 2463 UC_SELF_POWERED, 2464 0 /* max power */ 2465 }; 2466 2467 usb_interface_descriptor_t uhci_ifcd = { 2468 USB_INTERFACE_DESCRIPTOR_SIZE, 2469 UDESC_INTERFACE, 2470 0, 2471 0, 2472 1, 2473 UCLASS_HUB, 2474 USUBCLASS_HUB, 2475 0, 2476 0 2477 }; 2478 2479 usb_endpoint_descriptor_t uhci_endpd = { 2480 USB_ENDPOINT_DESCRIPTOR_SIZE, 2481 UDESC_ENDPOINT, 2482 UE_DIR_IN | UHCI_INTR_ENDPT, 2483 UE_INTERRUPT, 2484 {8}, 2485 255 2486 }; 2487 2488 usb_hub_descriptor_t uhci_hubd_piix = { 2489 USB_HUB_DESCRIPTOR_SIZE, 2490 UDESC_HUB, 2491 2, 2492 { UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL, 0 }, 2493 50, /* power on to power good */ 2494 0, 2495 { 0x00 }, /* both ports are removable */ 2496 }; 2497 2498 int 2499 uhci_str(p, l, s) 2500 usb_string_descriptor_t *p; 2501 int l; 2502 char *s; 2503 { 2504 int i; 2505 2506 if (l == 0) 2507 return (0); 2508 p->bLength = 2 * strlen(s) + 2; 2509 if (l == 1) 2510 return (1); 2511 p->bDescriptorType = UDESC_STRING; 2512 l -= 2; 2513 for (i = 0; s[i] && l > 1; i++, l -= 2) 2514 USETW2(p->bString[i], 0, s[i]); 2515 return (2*i+2); 2516 } 2517 2518 /* 2519 * Simulate a hardware hub by handling all the necessary requests. 2520 */ 2521 usbd_status 2522 uhci_root_ctrl_transfer(reqh) 2523 usbd_request_handle reqh; 2524 { 2525 usbd_status r; 2526 2527 /* Insert last in queue. */ 2528 r = usb_insert_transfer(reqh); 2529 if (r != USBD_NORMAL_COMPLETION) 2530 return (r); 2531 2532 /* Pipe isn't running, start first */ 2533 return (uhci_root_ctrl_start(SIMPLEQ_FIRST(&reqh->pipe->queue))); 2534 } 2535 2536 usbd_status 2537 uhci_root_ctrl_start(reqh) 2538 usbd_request_handle reqh; 2539 { 2540 uhci_softc_t *sc = (uhci_softc_t *)reqh->pipe->device->bus; 2541 usb_device_request_t *req; 2542 void *buf = NULL; 2543 int port, x; 2544 int s, len, value, index, status, change, l, totlen = 0; 2545 usb_port_status_t ps; 2546 usbd_status r; 2547 2548 #ifdef DIAGNOSTIC 2549 if (!(reqh->rqflags & URQ_REQUEST)) 2550 panic("uhci_root_ctrl_transfer: not a request\n"); 2551 #endif 2552 req = &reqh->request; 2553 2554 DPRINTFN(2,("uhci_root_ctrl_control type=0x%02x request=%02x\n", 2555 req->bmRequestType, req->bRequest)); 2556 2557 len = UGETW(req->wLength); 2558 value = UGETW(req->wValue); 2559 index = UGETW(req->wIndex); 2560 2561 if (len != 0) 2562 buf = KERNADDR(&reqh->dmabuf); 2563 2564 #define C(x,y) ((x) | ((y) << 8)) 2565 switch(C(req->bRequest, req->bmRequestType)) { 2566 case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE): 2567 case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE): 2568 case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT): 2569 /* 2570 * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops 2571 * for the integrated root hub. 2572 */ 2573 break; 2574 case C(UR_GET_CONFIG, UT_READ_DEVICE): 2575 if (len > 0) { 2576 *(u_int8_t *)buf = sc->sc_conf; 2577 totlen = 1; 2578 } 2579 break; 2580 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE): 2581 DPRINTFN(2,("uhci_root_ctrl_control wValue=0x%04x\n", value)); 2582 switch(value >> 8) { 2583 case UDESC_DEVICE: 2584 if ((value & 0xff) != 0) { 2585 r = USBD_IOERROR; 2586 goto ret; 2587 } 2588 totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE); 2589 USETW(uhci_devd.idVendor, sc->sc_id_vendor); 2590 memcpy(buf, &uhci_devd, l); 2591 break; 2592 case UDESC_CONFIG: 2593 if ((value & 0xff) != 0) { 2594 r = USBD_IOERROR; 2595 goto ret; 2596 } 2597 totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE); 2598 memcpy(buf, &uhci_confd, l); 2599 buf = (char *)buf + l; 2600 len -= l; 2601 l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE); 2602 totlen += l; 2603 memcpy(buf, &uhci_ifcd, l); 2604 buf = (char *)buf + l; 2605 len -= l; 2606 l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE); 2607 totlen += l; 2608 memcpy(buf, &uhci_endpd, l); 2609 break; 2610 case UDESC_STRING: 2611 if (len == 0) 2612 break; 2613 *(u_int8_t *)buf = 0; 2614 totlen = 1; 2615 switch (value & 0xff) { 2616 case 1: /* Vendor */ 2617 totlen = uhci_str(buf, len, sc->sc_vendor); 2618 break; 2619 case 2: /* Product */ 2620 totlen = uhci_str(buf, len, "UHCI root hub"); 2621 break; 2622 } 2623 break; 2624 default: 2625 r = USBD_IOERROR; 2626 goto ret; 2627 } 2628 break; 2629 case C(UR_GET_INTERFACE, UT_READ_INTERFACE): 2630 if (len > 0) { 2631 *(u_int8_t *)buf = 0; 2632 totlen = 1; 2633 } 2634 break; 2635 case C(UR_GET_STATUS, UT_READ_DEVICE): 2636 if (len > 1) { 2637 USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED); 2638 totlen = 2; 2639 } 2640 break; 2641 case C(UR_GET_STATUS, UT_READ_INTERFACE): 2642 case C(UR_GET_STATUS, UT_READ_ENDPOINT): 2643 if (len > 1) { 2644 USETW(((usb_status_t *)buf)->wStatus, 0); 2645 totlen = 2; 2646 } 2647 break; 2648 case C(UR_SET_ADDRESS, UT_WRITE_DEVICE): 2649 if (value >= USB_MAX_DEVICES) { 2650 r = USBD_IOERROR; 2651 goto ret; 2652 } 2653 sc->sc_addr = value; 2654 break; 2655 case C(UR_SET_CONFIG, UT_WRITE_DEVICE): 2656 if (value != 0 && value != 1) { 2657 r = USBD_IOERROR; 2658 goto ret; 2659 } 2660 sc->sc_conf = value; 2661 break; 2662 case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE): 2663 break; 2664 case C(UR_SET_FEATURE, UT_WRITE_DEVICE): 2665 case C(UR_SET_FEATURE, UT_WRITE_INTERFACE): 2666 case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT): 2667 r = USBD_IOERROR; 2668 goto ret; 2669 case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE): 2670 break; 2671 case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT): 2672 break; 2673 /* Hub requests */ 2674 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE): 2675 break; 2676 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER): 2677 DPRINTFN(3, ("uhci_root_ctrl_control: UR_CLEAR_PORT_FEATURE " 2678 "port=%d feature=%d\n", 2679 index, value)); 2680 if (index == 1) 2681 port = UHCI_PORTSC1; 2682 else if (index == 2) 2683 port = UHCI_PORTSC2; 2684 else { 2685 r = USBD_IOERROR; 2686 goto ret; 2687 } 2688 switch(value) { 2689 case UHF_PORT_ENABLE: 2690 x = UREAD2(sc, port); 2691 UWRITE2(sc, port, x & ~UHCI_PORTSC_PE); 2692 break; 2693 case UHF_PORT_SUSPEND: 2694 x = UREAD2(sc, port); 2695 UWRITE2(sc, port, x & ~UHCI_PORTSC_SUSP); 2696 break; 2697 case UHF_PORT_RESET: 2698 x = UREAD2(sc, port); 2699 UWRITE2(sc, port, x & ~UHCI_PORTSC_PR); 2700 break; 2701 case UHF_C_PORT_CONNECTION: 2702 x = UREAD2(sc, port); 2703 UWRITE2(sc, port, x | UHCI_PORTSC_CSC); 2704 break; 2705 case UHF_C_PORT_ENABLE: 2706 x = UREAD2(sc, port); 2707 UWRITE2(sc, port, x | UHCI_PORTSC_POEDC); 2708 break; 2709 case UHF_C_PORT_OVER_CURRENT: 2710 x = UREAD2(sc, port); 2711 UWRITE2(sc, port, x | UHCI_PORTSC_OCIC); 2712 break; 2713 case UHF_C_PORT_RESET: 2714 sc->sc_isreset = 0; 2715 r = USBD_NORMAL_COMPLETION; 2716 goto ret; 2717 case UHF_PORT_CONNECTION: 2718 case UHF_PORT_OVER_CURRENT: 2719 case UHF_PORT_POWER: 2720 case UHF_PORT_LOW_SPEED: 2721 case UHF_C_PORT_SUSPEND: 2722 default: 2723 r = USBD_IOERROR; 2724 goto ret; 2725 } 2726 break; 2727 case C(UR_GET_BUS_STATE, UT_READ_CLASS_OTHER): 2728 if (index == 1) 2729 port = UHCI_PORTSC1; 2730 else if (index == 2) 2731 port = UHCI_PORTSC2; 2732 else { 2733 r = USBD_IOERROR; 2734 goto ret; 2735 } 2736 if (len > 0) { 2737 *(u_int8_t *)buf = 2738 (UREAD2(sc, port) & UHCI_PORTSC_LS) >> 2739 UHCI_PORTSC_LS_SHIFT; 2740 totlen = 1; 2741 } 2742 break; 2743 case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE): 2744 if (value != 0) { 2745 r = USBD_IOERROR; 2746 goto ret; 2747 } 2748 l = min(len, USB_HUB_DESCRIPTOR_SIZE); 2749 totlen = l; 2750 memcpy(buf, &uhci_hubd_piix, l); 2751 break; 2752 case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE): 2753 if (len != 4) { 2754 r = USBD_IOERROR; 2755 goto ret; 2756 } 2757 memset(buf, 0, len); 2758 totlen = len; 2759 break; 2760 case C(UR_GET_STATUS, UT_READ_CLASS_OTHER): 2761 if (index == 1) 2762 port = UHCI_PORTSC1; 2763 else if (index == 2) 2764 port = UHCI_PORTSC2; 2765 else { 2766 r = USBD_IOERROR; 2767 goto ret; 2768 } 2769 if (len != 4) { 2770 r = USBD_IOERROR; 2771 goto ret; 2772 } 2773 x = UREAD2(sc, port); 2774 status = change = 0; 2775 if (x & UHCI_PORTSC_CCS ) 2776 status |= UPS_CURRENT_CONNECT_STATUS; 2777 if (x & UHCI_PORTSC_CSC ) 2778 change |= UPS_C_CONNECT_STATUS; 2779 if (x & UHCI_PORTSC_PE ) 2780 status |= UPS_PORT_ENABLED; 2781 if (x & UHCI_PORTSC_POEDC) 2782 change |= UPS_C_PORT_ENABLED; 2783 if (x & UHCI_PORTSC_OCI ) 2784 status |= UPS_OVERCURRENT_INDICATOR; 2785 if (x & UHCI_PORTSC_OCIC ) 2786 change |= UPS_C_OVERCURRENT_INDICATOR; 2787 if (x & UHCI_PORTSC_SUSP ) 2788 status |= UPS_SUSPEND; 2789 if (x & UHCI_PORTSC_LSDA ) 2790 status |= UPS_LOW_SPEED; 2791 status |= UPS_PORT_POWER; 2792 if (sc->sc_isreset) 2793 change |= UPS_C_PORT_RESET; 2794 USETW(ps.wPortStatus, status); 2795 USETW(ps.wPortChange, change); 2796 l = min(len, sizeof ps); 2797 memcpy(buf, &ps, l); 2798 totlen = l; 2799 break; 2800 case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE): 2801 r = USBD_IOERROR; 2802 goto ret; 2803 case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE): 2804 break; 2805 case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER): 2806 if (index == 1) 2807 port = UHCI_PORTSC1; 2808 else if (index == 2) 2809 port = UHCI_PORTSC2; 2810 else { 2811 r = USBD_IOERROR; 2812 goto ret; 2813 } 2814 switch(value) { 2815 case UHF_PORT_ENABLE: 2816 x = UREAD2(sc, port); 2817 UWRITE2(sc, port, x | UHCI_PORTSC_PE); 2818 break; 2819 case UHF_PORT_SUSPEND: 2820 x = UREAD2(sc, port); 2821 UWRITE2(sc, port, x | UHCI_PORTSC_SUSP); 2822 break; 2823 case UHF_PORT_RESET: 2824 x = UREAD2(sc, port); 2825 UWRITE2(sc, port, x | UHCI_PORTSC_PR); 2826 usb_delay_ms(&sc->sc_bus, 10); 2827 UWRITE2(sc, port, x & ~UHCI_PORTSC_PR); 2828 delay(100); 2829 x = UREAD2(sc, port); 2830 UWRITE2(sc, port, x | UHCI_PORTSC_PE); 2831 delay(100); 2832 DPRINTFN(3,("uhci port %d reset, status = 0x%04x\n", 2833 index, UREAD2(sc, port))); 2834 sc->sc_isreset = 1; 2835 break; 2836 case UHF_C_PORT_CONNECTION: 2837 case UHF_C_PORT_ENABLE: 2838 case UHF_C_PORT_OVER_CURRENT: 2839 case UHF_PORT_CONNECTION: 2840 case UHF_PORT_OVER_CURRENT: 2841 case UHF_PORT_POWER: 2842 case UHF_PORT_LOW_SPEED: 2843 case UHF_C_PORT_SUSPEND: 2844 case UHF_C_PORT_RESET: 2845 default: 2846 r = USBD_IOERROR; 2847 goto ret; 2848 } 2849 break; 2850 default: 2851 r = USBD_IOERROR; 2852 goto ret; 2853 } 2854 reqh->actlen = totlen; 2855 r = USBD_NORMAL_COMPLETION; 2856 ret: 2857 reqh->status = r; 2858 reqh->hcpriv = 0; 2859 s = splusb(); 2860 usb_transfer_complete(reqh); 2861 splx(s); 2862 return (USBD_IN_PROGRESS); 2863 } 2864 2865 /* Abort a root control request. */ 2866 void 2867 uhci_root_ctrl_abort(reqh) 2868 usbd_request_handle reqh; 2869 { 2870 /* Nothing to do, all transfers are syncronous. */ 2871 } 2872 2873 /* Close the root pipe. */ 2874 void 2875 uhci_root_ctrl_close(pipe) 2876 usbd_pipe_handle pipe; 2877 { 2878 uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus; 2879 2880 sc->sc_has_timo = 0; 2881 DPRINTF(("uhci_root_ctrl_close\n")); 2882 } 2883 2884 /* Abort a root interrupt request. */ 2885 void 2886 uhci_root_intr_abort(reqh) 2887 usbd_request_handle reqh; 2888 { 2889 uhci_softc_t *sc = (uhci_softc_t *)reqh->pipe->device->bus; 2890 2891 usb_untimeout(uhci_timo, reqh, reqh->timo_handle); 2892 sc->sc_has_timo = 0; 2893 2894 if (reqh->pipe->intrreqh == reqh) { 2895 DPRINTF(("uhci_root_intr_abort: remove\n")); 2896 reqh->pipe->intrreqh = 0; 2897 } 2898 reqh->status = USBD_CANCELLED; 2899 usb_transfer_complete(reqh); 2900 } 2901 2902 usbd_status 2903 uhci_root_intr_transfer(reqh) 2904 usbd_request_handle reqh; 2905 { 2906 usbd_status r; 2907 2908 /* Insert last in queue. */ 2909 r = usb_insert_transfer(reqh); 2910 if (r != USBD_NORMAL_COMPLETION) 2911 return (r); 2912 2913 /* Pipe isn't running, start first */ 2914 return (uhci_root_intr_start(SIMPLEQ_FIRST(&reqh->pipe->queue))); 2915 } 2916 2917 /* Start a transfer on the root interrupt pipe */ 2918 usbd_status 2919 uhci_root_intr_start(reqh) 2920 usbd_request_handle reqh; 2921 { 2922 usbd_pipe_handle pipe = reqh->pipe; 2923 uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus; 2924 2925 DPRINTFN(3, ("uhci_root_intr_transfer: reqh=%p len=%d flags=%d\n", 2926 reqh, reqh->length, reqh->flags)); 2927 2928 sc->sc_ival = MS_TO_TICKS(reqh->pipe->endpoint->edesc->bInterval); 2929 usb_timeout(uhci_timo, reqh, sc->sc_ival, reqh->timo_handle); 2930 sc->sc_has_timo = reqh; 2931 return (USBD_IN_PROGRESS); 2932 } 2933 2934 /* Close the root interrupt pipe. */ 2935 void 2936 uhci_root_intr_close(pipe) 2937 usbd_pipe_handle pipe; 2938 { 2939 uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus; 2940 2941 usb_untimeout(uhci_timo, pipe->intrreqh, pipe->intrreqh->timo_handle); 2942 sc->sc_has_timo = 0; 2943 DPRINTF(("uhci_root_intr_close\n")); 2944 } 2945 2946