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