1 /* $NetBSD: ohci.c,v 1.218 2011/08/07 13:45:46 jmcneill Exp $ */ 2 /* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */ 3 4 /* 5 * Copyright (c) 1998, 2004, 2005 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 (lennart@augustsson.net) at 10 * Carlstedt Research & Technology. 11 * This code is derived from software contributed to The NetBSD Foundation 12 * by Charles M. Hannum. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 24 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 25 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 27 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 /* 37 * USB Open Host Controller driver. 38 * 39 * OHCI spec: http://www.compaq.com/productinfo/development/openhci.html 40 * USB spec: http://www.usb.org/developers/docs/ 41 */ 42 43 #include <sys/cdefs.h> 44 __KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.218 2011/08/07 13:45:46 jmcneill Exp $"); 45 46 #include "opt_usb.h" 47 48 #include <sys/param.h> 49 #include <sys/systm.h> 50 #include <sys/malloc.h> 51 #include <sys/kernel.h> 52 #include <sys/device.h> 53 #include <sys/select.h> 54 #include <sys/proc.h> 55 #include <sys/queue.h> 56 57 #include <sys/bus.h> 58 #include <machine/endian.h> 59 60 #include <dev/usb/usb.h> 61 #include <dev/usb/usbdi.h> 62 #include <dev/usb/usbdivar.h> 63 #include <dev/usb/usb_mem.h> 64 #include <dev/usb/usb_quirks.h> 65 66 #include <dev/usb/ohcireg.h> 67 #include <dev/usb/ohcivar.h> 68 #include <dev/usb/usbroothub_subr.h> 69 70 71 72 #ifdef OHCI_DEBUG 73 #define DPRINTF(x) if (ohcidebug) printf x 74 #define DPRINTFN(n,x) if (ohcidebug>(n)) printf x 75 int ohcidebug = 0; 76 #else 77 #define DPRINTF(x) 78 #define DPRINTFN(n,x) 79 #endif 80 81 #if BYTE_ORDER == BIG_ENDIAN 82 #define SWAP_ENDIAN OHCI_LITTLE_ENDIAN 83 #else 84 #define SWAP_ENDIAN OHCI_BIG_ENDIAN 85 #endif 86 87 #define O16TOH(val) (sc->sc_endian == SWAP_ENDIAN ? bswap16(val) : val) 88 #define O32TOH(val) (sc->sc_endian == SWAP_ENDIAN ? bswap32(val) : val) 89 #define HTOO16(val) O16TOH(val) 90 #define HTOO32(val) O32TOH(val) 91 92 struct ohci_pipe; 93 94 Static ohci_soft_ed_t *ohci_alloc_sed(ohci_softc_t *); 95 Static void ohci_free_sed(ohci_softc_t *, ohci_soft_ed_t *); 96 97 Static ohci_soft_td_t *ohci_alloc_std(ohci_softc_t *); 98 Static void ohci_free_std(ohci_softc_t *, ohci_soft_td_t *); 99 100 Static ohci_soft_itd_t *ohci_alloc_sitd(ohci_softc_t *); 101 Static void ohci_free_sitd(ohci_softc_t *,ohci_soft_itd_t *); 102 103 #if 0 104 Static void ohci_free_std_chain(ohci_softc_t *, ohci_soft_td_t *, 105 ohci_soft_td_t *); 106 #endif 107 Static usbd_status ohci_alloc_std_chain(struct ohci_pipe *, 108 ohci_softc_t *, int, int, usbd_xfer_handle, 109 ohci_soft_td_t *, ohci_soft_td_t **); 110 111 Static usbd_status ohci_open(usbd_pipe_handle); 112 Static void ohci_poll(struct usbd_bus *); 113 Static void ohci_softintr(void *); 114 Static void ohci_waitintr(ohci_softc_t *, usbd_xfer_handle); 115 Static void ohci_rhsc(ohci_softc_t *, usbd_xfer_handle); 116 117 Static usbd_status ohci_device_request(usbd_xfer_handle xfer); 118 Static void ohci_add_ed(ohci_softc_t *, ohci_soft_ed_t *, 119 ohci_soft_ed_t *); 120 121 Static void ohci_rem_ed(ohci_soft_ed_t *, ohci_soft_ed_t *); 122 Static void ohci_hash_add_td(ohci_softc_t *, ohci_soft_td_t *); 123 Static void ohci_hash_rem_td(ohci_softc_t *, ohci_soft_td_t *); 124 Static ohci_soft_td_t *ohci_hash_find_td(ohci_softc_t *, ohci_physaddr_t); 125 Static void ohci_hash_add_itd(ohci_softc_t *, ohci_soft_itd_t *); 126 Static void ohci_hash_rem_itd(ohci_softc_t *, ohci_soft_itd_t *); 127 Static ohci_soft_itd_t *ohci_hash_find_itd(ohci_softc_t *, ohci_physaddr_t); 128 129 Static usbd_status ohci_setup_isoc(usbd_pipe_handle pipe); 130 Static void ohci_device_isoc_enter(usbd_xfer_handle); 131 132 Static usbd_status ohci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t); 133 Static void ohci_freem(struct usbd_bus *, usb_dma_t *); 134 135 Static usbd_xfer_handle ohci_allocx(struct usbd_bus *); 136 Static void ohci_freex(struct usbd_bus *, usbd_xfer_handle); 137 138 Static usbd_status ohci_root_ctrl_transfer(usbd_xfer_handle); 139 Static usbd_status ohci_root_ctrl_start(usbd_xfer_handle); 140 Static void ohci_root_ctrl_abort(usbd_xfer_handle); 141 Static void ohci_root_ctrl_close(usbd_pipe_handle); 142 Static void ohci_root_ctrl_done(usbd_xfer_handle); 143 144 Static usbd_status ohci_root_intr_transfer(usbd_xfer_handle); 145 Static usbd_status ohci_root_intr_start(usbd_xfer_handle); 146 Static void ohci_root_intr_abort(usbd_xfer_handle); 147 Static void ohci_root_intr_close(usbd_pipe_handle); 148 Static void ohci_root_intr_done(usbd_xfer_handle); 149 150 Static usbd_status ohci_device_ctrl_transfer(usbd_xfer_handle); 151 Static usbd_status ohci_device_ctrl_start(usbd_xfer_handle); 152 Static void ohci_device_ctrl_abort(usbd_xfer_handle); 153 Static void ohci_device_ctrl_close(usbd_pipe_handle); 154 Static void ohci_device_ctrl_done(usbd_xfer_handle); 155 156 Static usbd_status ohci_device_bulk_transfer(usbd_xfer_handle); 157 Static usbd_status ohci_device_bulk_start(usbd_xfer_handle); 158 Static void ohci_device_bulk_abort(usbd_xfer_handle); 159 Static void ohci_device_bulk_close(usbd_pipe_handle); 160 Static void ohci_device_bulk_done(usbd_xfer_handle); 161 162 Static usbd_status ohci_device_intr_transfer(usbd_xfer_handle); 163 Static usbd_status ohci_device_intr_start(usbd_xfer_handle); 164 Static void ohci_device_intr_abort(usbd_xfer_handle); 165 Static void ohci_device_intr_close(usbd_pipe_handle); 166 Static void ohci_device_intr_done(usbd_xfer_handle); 167 168 Static usbd_status ohci_device_isoc_transfer(usbd_xfer_handle); 169 Static usbd_status ohci_device_isoc_start(usbd_xfer_handle); 170 Static void ohci_device_isoc_abort(usbd_xfer_handle); 171 Static void ohci_device_isoc_close(usbd_pipe_handle); 172 Static void ohci_device_isoc_done(usbd_xfer_handle); 173 174 Static usbd_status ohci_device_setintr(ohci_softc_t *sc, 175 struct ohci_pipe *pipe, int ival); 176 177 Static void ohci_timeout(void *); 178 Static void ohci_timeout_task(void *); 179 Static void ohci_rhsc_enable(void *); 180 181 Static void ohci_close_pipe(usbd_pipe_handle, ohci_soft_ed_t *); 182 Static void ohci_abort_xfer(usbd_xfer_handle, usbd_status); 183 184 Static void ohci_device_clear_toggle(usbd_pipe_handle pipe); 185 Static void ohci_noop(usbd_pipe_handle pipe); 186 187 #ifdef OHCI_DEBUG 188 Static void ohci_dumpregs(ohci_softc_t *); 189 Static void ohci_dump_tds(ohci_softc_t *, ohci_soft_td_t *); 190 Static void ohci_dump_td(ohci_softc_t *, ohci_soft_td_t *); 191 Static void ohci_dump_ed(ohci_softc_t *, ohci_soft_ed_t *); 192 Static void ohci_dump_itd(ohci_softc_t *, ohci_soft_itd_t *); 193 Static void ohci_dump_itds(ohci_softc_t *, ohci_soft_itd_t *); 194 #endif 195 196 #define OBARR(sc) bus_space_barrier((sc)->iot, (sc)->ioh, 0, (sc)->sc_size, \ 197 BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE) 198 #define OWRITE1(sc, r, x) \ 199 do { OBARR(sc); bus_space_write_1((sc)->iot, (sc)->ioh, (r), (x)); } while (0) 200 #define OWRITE2(sc, r, x) \ 201 do { OBARR(sc); bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x)); } while (0) 202 #define OWRITE4(sc, r, x) \ 203 do { OBARR(sc); bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x)); } while (0) 204 static __inline uint8_t 205 OREAD1(ohci_softc_t *sc, bus_size_t r) 206 { 207 208 OBARR(sc); 209 return bus_space_read_1(sc->iot, sc->ioh, r); 210 } 211 212 static __inline uint16_t 213 OREAD2(ohci_softc_t *sc, bus_size_t r) 214 { 215 216 OBARR(sc); 217 return bus_space_read_2(sc->iot, sc->ioh, r); 218 } 219 220 static __inline uint32_t 221 OREAD4(ohci_softc_t *sc, bus_size_t r) 222 { 223 224 OBARR(sc); 225 return bus_space_read_4(sc->iot, sc->ioh, r); 226 } 227 228 /* Reverse the bits in a value 0 .. 31 */ 229 Static u_int8_t revbits[OHCI_NO_INTRS] = 230 { 0x00, 0x10, 0x08, 0x18, 0x04, 0x14, 0x0c, 0x1c, 231 0x02, 0x12, 0x0a, 0x1a, 0x06, 0x16, 0x0e, 0x1e, 232 0x01, 0x11, 0x09, 0x19, 0x05, 0x15, 0x0d, 0x1d, 233 0x03, 0x13, 0x0b, 0x1b, 0x07, 0x17, 0x0f, 0x1f }; 234 235 struct ohci_pipe { 236 struct usbd_pipe pipe; 237 ohci_soft_ed_t *sed; 238 union { 239 ohci_soft_td_t *td; 240 ohci_soft_itd_t *itd; 241 } tail; 242 /* Info needed for different pipe kinds. */ 243 union { 244 /* Control pipe */ 245 struct { 246 usb_dma_t reqdma; 247 u_int length; 248 ohci_soft_td_t *setup, *data, *stat; 249 } ctl; 250 /* Interrupt pipe */ 251 struct { 252 int nslots; 253 int pos; 254 } intr; 255 /* Bulk pipe */ 256 struct { 257 u_int length; 258 int isread; 259 } bulk; 260 /* Iso pipe */ 261 struct iso { 262 int next, inuse; 263 } iso; 264 } u; 265 }; 266 267 #define OHCI_INTR_ENDPT 1 268 269 Static const struct usbd_bus_methods ohci_bus_methods = { 270 ohci_open, 271 ohci_softintr, 272 ohci_poll, 273 ohci_allocm, 274 ohci_freem, 275 ohci_allocx, 276 ohci_freex, 277 }; 278 279 Static const struct usbd_pipe_methods ohci_root_ctrl_methods = { 280 ohci_root_ctrl_transfer, 281 ohci_root_ctrl_start, 282 ohci_root_ctrl_abort, 283 ohci_root_ctrl_close, 284 ohci_noop, 285 ohci_root_ctrl_done, 286 }; 287 288 Static const struct usbd_pipe_methods ohci_root_intr_methods = { 289 ohci_root_intr_transfer, 290 ohci_root_intr_start, 291 ohci_root_intr_abort, 292 ohci_root_intr_close, 293 ohci_noop, 294 ohci_root_intr_done, 295 }; 296 297 Static const struct usbd_pipe_methods ohci_device_ctrl_methods = { 298 ohci_device_ctrl_transfer, 299 ohci_device_ctrl_start, 300 ohci_device_ctrl_abort, 301 ohci_device_ctrl_close, 302 ohci_noop, 303 ohci_device_ctrl_done, 304 }; 305 306 Static const struct usbd_pipe_methods ohci_device_intr_methods = { 307 ohci_device_intr_transfer, 308 ohci_device_intr_start, 309 ohci_device_intr_abort, 310 ohci_device_intr_close, 311 ohci_device_clear_toggle, 312 ohci_device_intr_done, 313 }; 314 315 Static const struct usbd_pipe_methods ohci_device_bulk_methods = { 316 ohci_device_bulk_transfer, 317 ohci_device_bulk_start, 318 ohci_device_bulk_abort, 319 ohci_device_bulk_close, 320 ohci_device_clear_toggle, 321 ohci_device_bulk_done, 322 }; 323 324 Static const struct usbd_pipe_methods ohci_device_isoc_methods = { 325 ohci_device_isoc_transfer, 326 ohci_device_isoc_start, 327 ohci_device_isoc_abort, 328 ohci_device_isoc_close, 329 ohci_noop, 330 ohci_device_isoc_done, 331 }; 332 333 int 334 ohci_activate(device_t self, enum devact act) 335 { 336 struct ohci_softc *sc = device_private(self); 337 338 switch (act) { 339 case DVACT_DEACTIVATE: 340 sc->sc_dying = 1; 341 return 0; 342 default: 343 return EOPNOTSUPP; 344 } 345 } 346 347 void 348 ohci_childdet(device_t self, device_t child) 349 { 350 struct ohci_softc *sc = device_private(self); 351 352 KASSERT(sc->sc_child == child); 353 sc->sc_child = NULL; 354 } 355 356 int 357 ohci_detach(struct ohci_softc *sc, int flags) 358 { 359 int rv = 0; 360 usbd_xfer_handle xfer; 361 362 if (sc->sc_child != NULL) 363 rv = config_detach(sc->sc_child, flags); 364 365 if (rv != 0) 366 return (rv); 367 368 callout_stop(&sc->sc_tmo_rhsc); 369 370 usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */ 371 callout_destroy(&sc->sc_tmo_rhsc); 372 373 if (sc->sc_hcca != NULL) 374 usb_freemem(&sc->sc_bus, &sc->sc_hccadma); 375 while((xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers)) != NULL) { 376 SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next); 377 free(xfer, M_USB); 378 } 379 380 return (rv); 381 } 382 383 ohci_soft_ed_t * 384 ohci_alloc_sed(ohci_softc_t *sc) 385 { 386 ohci_soft_ed_t *sed; 387 usbd_status err; 388 int i, offs; 389 usb_dma_t dma; 390 391 if (sc->sc_freeeds == NULL) { 392 DPRINTFN(2, ("ohci_alloc_sed: allocating chunk\n")); 393 err = usb_allocmem(&sc->sc_bus, OHCI_SED_SIZE * OHCI_SED_CHUNK, 394 OHCI_ED_ALIGN, &dma); 395 if (err) 396 return (0); 397 for(i = 0; i < OHCI_SED_CHUNK; i++) { 398 offs = i * OHCI_SED_SIZE; 399 sed = KERNADDR(&dma, offs); 400 sed->physaddr = DMAADDR(&dma, offs); 401 sed->dma = dma; 402 sed->offs = offs; 403 sed->next = sc->sc_freeeds; 404 sc->sc_freeeds = sed; 405 } 406 } 407 sed = sc->sc_freeeds; 408 sc->sc_freeeds = sed->next; 409 memset(&sed->ed, 0, sizeof(ohci_ed_t)); 410 sed->next = 0; 411 return (sed); 412 } 413 414 void 415 ohci_free_sed(ohci_softc_t *sc, ohci_soft_ed_t *sed) 416 { 417 sed->next = sc->sc_freeeds; 418 sc->sc_freeeds = sed; 419 } 420 421 ohci_soft_td_t * 422 ohci_alloc_std(ohci_softc_t *sc) 423 { 424 ohci_soft_td_t *std; 425 usbd_status err; 426 int i, offs; 427 usb_dma_t dma; 428 int s; 429 430 if (sc->sc_freetds == NULL) { 431 DPRINTFN(2, ("ohci_alloc_std: allocating chunk\n")); 432 err = usb_allocmem(&sc->sc_bus, OHCI_STD_SIZE * OHCI_STD_CHUNK, 433 OHCI_TD_ALIGN, &dma); 434 if (err) 435 return (NULL); 436 s = splusb(); 437 for(i = 0; i < OHCI_STD_CHUNK; i++) { 438 offs = i * OHCI_STD_SIZE; 439 std = KERNADDR(&dma, offs); 440 std->physaddr = DMAADDR(&dma, offs); 441 std->dma = dma; 442 std->offs = offs; 443 std->nexttd = sc->sc_freetds; 444 sc->sc_freetds = std; 445 } 446 splx(s); 447 } 448 449 s = splusb(); 450 std = sc->sc_freetds; 451 sc->sc_freetds = std->nexttd; 452 memset(&std->td, 0, sizeof(ohci_td_t)); 453 std->nexttd = NULL; 454 std->xfer = NULL; 455 ohci_hash_add_td(sc, std); 456 splx(s); 457 458 return (std); 459 } 460 461 void 462 ohci_free_std(ohci_softc_t *sc, ohci_soft_td_t *std) 463 { 464 int s; 465 466 s = splusb(); 467 ohci_hash_rem_td(sc, std); 468 std->nexttd = sc->sc_freetds; 469 sc->sc_freetds = std; 470 splx(s); 471 } 472 473 usbd_status 474 ohci_alloc_std_chain(struct ohci_pipe *opipe, ohci_softc_t *sc, 475 int alen, int rd, usbd_xfer_handle xfer, 476 ohci_soft_td_t *sp, ohci_soft_td_t **ep) 477 { 478 ohci_soft_td_t *next, *cur; 479 ohci_physaddr_t dataphys, dataphysend; 480 u_int32_t tdflags; 481 int len, curlen; 482 usb_dma_t *dma = &xfer->dmabuf; 483 u_int16_t flags = xfer->flags; 484 485 DPRINTFN(alen < 4096,("ohci_alloc_std_chain: start len=%d\n", alen)); 486 487 len = alen; 488 cur = sp; 489 dataphys = DMAADDR(dma, 0); 490 dataphysend = OHCI_PAGE(dataphys + len - 1); 491 usb_syncmem(dma, 0, len, 492 rd ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); 493 tdflags = HTOO32( 494 (rd ? OHCI_TD_IN : OHCI_TD_OUT) | 495 (flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0) | 496 OHCI_TD_NOCC | OHCI_TD_TOGGLE_CARRY | OHCI_TD_NOINTR); 497 498 for (;;) { 499 next = ohci_alloc_std(sc); 500 if (next == NULL) 501 goto nomem; 502 503 /* The OHCI hardware can handle at most one page crossing. */ 504 if (OHCI_PAGE(dataphys) == dataphysend || 505 OHCI_PAGE(dataphys) + OHCI_PAGE_SIZE == dataphysend) { 506 /* we can handle it in this TD */ 507 curlen = len; 508 } else { 509 /* must use multiple TDs, fill as much as possible. */ 510 curlen = 2 * OHCI_PAGE_SIZE - 511 (dataphys & (OHCI_PAGE_SIZE-1)); 512 /* the length must be a multiple of the max size */ 513 curlen -= curlen % UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize); 514 #ifdef DIAGNOSTIC 515 if (curlen == 0) 516 panic("ohci_alloc_std: curlen == 0"); 517 #endif 518 } 519 DPRINTFN(4,("ohci_alloc_std_chain: dataphys=0x%08x " 520 "dataphysend=0x%08x len=%d curlen=%d\n", 521 dataphys, dataphysend, 522 len, curlen)); 523 len -= curlen; 524 525 cur->td.td_flags = tdflags; 526 cur->td.td_cbp = HTOO32(dataphys); 527 cur->nexttd = next; 528 cur->td.td_nexttd = HTOO32(next->physaddr); 529 cur->td.td_be = HTOO32(dataphys + curlen - 1); 530 cur->len = curlen; 531 cur->flags = OHCI_ADD_LEN; 532 cur->xfer = xfer; 533 usb_syncmem(&cur->dma, cur->offs, sizeof(cur->td), 534 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 535 DPRINTFN(10,("ohci_alloc_std_chain: cbp=0x%08x be=0x%08x\n", 536 dataphys, dataphys + curlen - 1)); 537 if (len == 0) 538 break; 539 DPRINTFN(10,("ohci_alloc_std_chain: extend chain\n")); 540 dataphys += curlen; 541 cur = next; 542 } 543 if (!rd && (flags & USBD_FORCE_SHORT_XFER) && 544 alen % UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize) == 0) { 545 /* Force a 0 length transfer at the end. */ 546 547 cur = next; 548 next = ohci_alloc_std(sc); 549 if (next == NULL) 550 goto nomem; 551 552 cur->td.td_flags = tdflags; 553 cur->td.td_cbp = 0; /* indicate 0 length packet */ 554 cur->nexttd = next; 555 cur->td.td_nexttd = HTOO32(next->physaddr); 556 cur->td.td_be = ~0; 557 cur->len = 0; 558 cur->flags = 0; 559 cur->xfer = xfer; 560 usb_syncmem(&cur->dma, cur->offs, sizeof(cur->td), 561 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 562 DPRINTFN(2,("ohci_alloc_std_chain: add 0 xfer\n")); 563 } 564 *ep = cur; 565 566 return (USBD_NORMAL_COMPLETION); 567 568 nomem: 569 /* XXX free chain */ 570 return (USBD_NOMEM); 571 } 572 573 #if 0 574 Static void 575 ohci_free_std_chain(ohci_softc_t *sc, ohci_soft_td_t *std, 576 ohci_soft_td_t *stdend) 577 { 578 ohci_soft_td_t *p; 579 580 for (; std != stdend; std = p) { 581 p = std->nexttd; 582 ohci_free_std(sc, std); 583 } 584 } 585 #endif 586 587 ohci_soft_itd_t * 588 ohci_alloc_sitd(ohci_softc_t *sc) 589 { 590 ohci_soft_itd_t *sitd; 591 usbd_status err; 592 int i, s, offs; 593 usb_dma_t dma; 594 595 if (sc->sc_freeitds == NULL) { 596 DPRINTFN(2, ("ohci_alloc_sitd: allocating chunk\n")); 597 err = usb_allocmem(&sc->sc_bus, OHCI_SITD_SIZE * OHCI_SITD_CHUNK, 598 OHCI_ITD_ALIGN, &dma); 599 if (err) 600 return (NULL); 601 s = splusb(); 602 for(i = 0; i < OHCI_SITD_CHUNK; i++) { 603 offs = i * OHCI_SITD_SIZE; 604 sitd = KERNADDR(&dma, offs); 605 sitd->physaddr = DMAADDR(&dma, offs); 606 sitd->dma = dma; 607 sitd->offs = offs; 608 sitd->nextitd = sc->sc_freeitds; 609 sc->sc_freeitds = sitd; 610 } 611 splx(s); 612 } 613 614 s = splusb(); 615 sitd = sc->sc_freeitds; 616 sc->sc_freeitds = sitd->nextitd; 617 memset(&sitd->itd, 0, sizeof(ohci_itd_t)); 618 sitd->nextitd = NULL; 619 sitd->xfer = NULL; 620 ohci_hash_add_itd(sc, sitd); 621 splx(s); 622 623 #ifdef DIAGNOSTIC 624 sitd->isdone = 0; 625 #endif 626 627 return (sitd); 628 } 629 630 void 631 ohci_free_sitd(ohci_softc_t *sc, ohci_soft_itd_t *sitd) 632 { 633 int s; 634 635 DPRINTFN(10,("ohci_free_sitd: sitd=%p\n", sitd)); 636 637 #ifdef DIAGNOSTIC 638 if (!sitd->isdone) { 639 panic("ohci_free_sitd: sitd=%p not done", sitd); 640 return; 641 } 642 /* Warn double free */ 643 sitd->isdone = 0; 644 #endif 645 646 s = splusb(); 647 ohci_hash_rem_itd(sc, sitd); 648 sitd->nextitd = sc->sc_freeitds; 649 sc->sc_freeitds = sitd; 650 splx(s); 651 } 652 653 usbd_status 654 ohci_init(ohci_softc_t *sc) 655 { 656 ohci_soft_ed_t *sed, *psed; 657 usbd_status err; 658 int i; 659 u_int32_t s, ctl, rwc, ival, hcr, fm, per, rev, desca, descb; 660 661 DPRINTF(("ohci_init: start\n")); 662 aprint_normal_dev(sc->sc_dev, ""); 663 664 sc->sc_hcca = NULL; 665 callout_init(&sc->sc_tmo_rhsc, 0); 666 667 for (i = 0; i < OHCI_HASH_SIZE; i++) 668 LIST_INIT(&sc->sc_hash_tds[i]); 669 for (i = 0; i < OHCI_HASH_SIZE; i++) 670 LIST_INIT(&sc->sc_hash_itds[i]); 671 672 SIMPLEQ_INIT(&sc->sc_free_xfers); 673 674 rev = OREAD4(sc, OHCI_REVISION); 675 aprint_normal("OHCI version %d.%d%s\n", 676 OHCI_REV_HI(rev), OHCI_REV_LO(rev), 677 OHCI_REV_LEGACY(rev) ? ", legacy support" : ""); 678 679 if (OHCI_REV_HI(rev) != 1 || OHCI_REV_LO(rev) != 0) { 680 aprint_error_dev(sc->sc_dev, "unsupported OHCI revision\n"); 681 sc->sc_bus.usbrev = USBREV_UNKNOWN; 682 return (USBD_INVAL); 683 } 684 sc->sc_bus.usbrev = USBREV_1_0; 685 686 usb_setup_reserve(sc->sc_dev, &sc->sc_dma_reserve, sc->sc_bus.dmatag, 687 USB_MEM_RESERVE); 688 689 /* XXX determine alignment by R/W */ 690 /* Allocate the HCCA area. */ 691 err = usb_allocmem(&sc->sc_bus, OHCI_HCCA_SIZE, 692 OHCI_HCCA_ALIGN, &sc->sc_hccadma); 693 if (err) { 694 sc->sc_hcca = NULL; 695 return err; 696 } 697 sc->sc_hcca = KERNADDR(&sc->sc_hccadma, 0); 698 memset(sc->sc_hcca, 0, OHCI_HCCA_SIZE); 699 700 sc->sc_eintrs = OHCI_NORMAL_INTRS; 701 702 /* Allocate dummy ED that starts the control list. */ 703 sc->sc_ctrl_head = ohci_alloc_sed(sc); 704 if (sc->sc_ctrl_head == NULL) { 705 err = USBD_NOMEM; 706 goto bad1; 707 } 708 sc->sc_ctrl_head->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); 709 710 /* Allocate dummy ED that starts the bulk list. */ 711 sc->sc_bulk_head = ohci_alloc_sed(sc); 712 if (sc->sc_bulk_head == NULL) { 713 err = USBD_NOMEM; 714 goto bad2; 715 } 716 sc->sc_bulk_head->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); 717 usb_syncmem(&sc->sc_bulk_head->dma, sc->sc_bulk_head->offs, 718 sizeof(sc->sc_bulk_head->ed), 719 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 720 721 /* Allocate dummy ED that starts the isochronous list. */ 722 sc->sc_isoc_head = ohci_alloc_sed(sc); 723 if (sc->sc_isoc_head == NULL) { 724 err = USBD_NOMEM; 725 goto bad3; 726 } 727 sc->sc_isoc_head->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); 728 usb_syncmem(&sc->sc_isoc_head->dma, sc->sc_isoc_head->offs, 729 sizeof(sc->sc_isoc_head->ed), 730 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 731 732 /* Allocate all the dummy EDs that make up the interrupt tree. */ 733 for (i = 0; i < OHCI_NO_EDS; i++) { 734 sed = ohci_alloc_sed(sc); 735 if (sed == NULL) { 736 while (--i >= 0) 737 ohci_free_sed(sc, sc->sc_eds[i]); 738 err = USBD_NOMEM; 739 goto bad4; 740 } 741 /* All ED fields are set to 0. */ 742 sc->sc_eds[i] = sed; 743 sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); 744 if (i != 0) 745 psed = sc->sc_eds[(i-1) / 2]; 746 else 747 psed= sc->sc_isoc_head; 748 sed->next = psed; 749 sed->ed.ed_nexted = HTOO32(psed->physaddr); 750 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 751 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 752 } 753 /* 754 * Fill HCCA interrupt table. The bit reversal is to get 755 * the tree set up properly to spread the interrupts. 756 */ 757 for (i = 0; i < OHCI_NO_INTRS; i++) 758 sc->sc_hcca->hcca_interrupt_table[revbits[i]] = 759 HTOO32(sc->sc_eds[OHCI_NO_EDS-OHCI_NO_INTRS+i]->physaddr); 760 usb_syncmem(&sc->sc_hccadma, 0, OHCI_HCCA_SIZE, 761 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 762 763 #ifdef OHCI_DEBUG 764 if (ohcidebug > 15) { 765 for (i = 0; i < OHCI_NO_EDS; i++) { 766 printf("ed#%d ", i); 767 ohci_dump_ed(sc, sc->sc_eds[i]); 768 } 769 printf("iso "); 770 ohci_dump_ed(sc, sc->sc_isoc_head); 771 } 772 #endif 773 774 /* Preserve values programmed by SMM/BIOS but lost over reset. */ 775 ctl = OREAD4(sc, OHCI_CONTROL); 776 rwc = ctl & OHCI_RWC; 777 fm = OREAD4(sc, OHCI_FM_INTERVAL); 778 desca = OREAD4(sc, OHCI_RH_DESCRIPTOR_A); 779 descb = OREAD4(sc, OHCI_RH_DESCRIPTOR_B); 780 781 /* Determine in what context we are running. */ 782 if (ctl & OHCI_IR) { 783 /* SMM active, request change */ 784 DPRINTF(("ohci_init: SMM active, request owner change\n")); 785 if ((sc->sc_intre & (OHCI_OC | OHCI_MIE)) == 786 (OHCI_OC | OHCI_MIE)) 787 OWRITE4(sc, OHCI_INTERRUPT_ENABLE, OHCI_MIE); 788 s = OREAD4(sc, OHCI_COMMAND_STATUS); 789 OWRITE4(sc, OHCI_COMMAND_STATUS, s | OHCI_OCR); 790 for (i = 0; i < 100 && (ctl & OHCI_IR); i++) { 791 usb_delay_ms(&sc->sc_bus, 1); 792 ctl = OREAD4(sc, OHCI_CONTROL); 793 } 794 OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_MIE); 795 if ((ctl & OHCI_IR) == 0) { 796 aprint_error_dev(sc->sc_dev, 797 "SMM does not respond, resetting\n"); 798 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET | rwc); 799 goto reset; 800 } 801 #if 0 802 /* Don't bother trying to reuse the BIOS init, we'll reset it anyway. */ 803 } else if ((ctl & OHCI_HCFS_MASK) != OHCI_HCFS_RESET) { 804 /* BIOS started controller. */ 805 DPRINTF(("ohci_init: BIOS active\n")); 806 if ((ctl & OHCI_HCFS_MASK) != OHCI_HCFS_OPERATIONAL) { 807 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_OPERATIONAL | rwc); 808 usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY); 809 } 810 #endif 811 } else { 812 DPRINTF(("ohci_init: cold started\n")); 813 reset: 814 /* Controller was cold started. */ 815 usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY); 816 } 817 818 /* 819 * This reset should not be necessary according to the OHCI spec, but 820 * without it some controllers do not start. 821 */ 822 DPRINTF(("%s: resetting\n", device_xname(sc->sc_dev))); 823 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET | rwc); 824 usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY); 825 826 /* We now own the host controller and the bus has been reset. */ 827 828 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_HCR); /* Reset HC */ 829 /* Nominal time for a reset is 10 us. */ 830 for (i = 0; i < 10; i++) { 831 delay(10); 832 hcr = OREAD4(sc, OHCI_COMMAND_STATUS) & OHCI_HCR; 833 if (!hcr) 834 break; 835 } 836 if (hcr) { 837 aprint_error_dev(sc->sc_dev, "reset timeout\n"); 838 err = USBD_IOERROR; 839 goto bad5; 840 } 841 #ifdef OHCI_DEBUG 842 if (ohcidebug > 15) 843 ohci_dumpregs(sc); 844 #endif 845 846 /* The controller is now in SUSPEND state, we have 2ms to finish. */ 847 848 /* Set up HC registers. */ 849 OWRITE4(sc, OHCI_HCCA, DMAADDR(&sc->sc_hccadma, 0)); 850 OWRITE4(sc, OHCI_CONTROL_HEAD_ED, sc->sc_ctrl_head->physaddr); 851 OWRITE4(sc, OHCI_BULK_HEAD_ED, sc->sc_bulk_head->physaddr); 852 /* disable all interrupts and then switch on all desired interrupts */ 853 OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS); 854 /* switch on desired functional features */ 855 ctl = OREAD4(sc, OHCI_CONTROL); 856 ctl &= ~(OHCI_CBSR_MASK | OHCI_LES | OHCI_HCFS_MASK | OHCI_IR); 857 ctl |= OHCI_PLE | OHCI_IE | OHCI_CLE | OHCI_BLE | 858 OHCI_RATIO_1_4 | OHCI_HCFS_OPERATIONAL | rwc; 859 /* And finally start it! */ 860 OWRITE4(sc, OHCI_CONTROL, ctl); 861 862 /* 863 * The controller is now OPERATIONAL. Set a some final 864 * registers that should be set earlier, but that the 865 * controller ignores when in the SUSPEND state. 866 */ 867 ival = OHCI_GET_IVAL(fm); 868 fm = (OREAD4(sc, OHCI_FM_INTERVAL) & OHCI_FIT) ^ OHCI_FIT; 869 fm |= OHCI_FSMPS(ival) | ival; 870 OWRITE4(sc, OHCI_FM_INTERVAL, fm); 871 per = OHCI_PERIODIC(ival); /* 90% periodic */ 872 OWRITE4(sc, OHCI_PERIODIC_START, per); 873 874 /* Fiddle the No OverCurrent Protection bit to avoid chip bug. */ 875 OWRITE4(sc, OHCI_RH_DESCRIPTOR_A, desca | OHCI_NOCP); 876 OWRITE4(sc, OHCI_RH_STATUS, OHCI_LPSC); /* Enable port power */ 877 usb_delay_ms(&sc->sc_bus, OHCI_ENABLE_POWER_DELAY); 878 OWRITE4(sc, OHCI_RH_DESCRIPTOR_A, desca); 879 880 /* 881 * The AMD756 requires a delay before re-reading the register, 882 * otherwise it will occasionally report 0 ports. 883 */ 884 sc->sc_noport = 0; 885 for (i = 0; i < 10 && sc->sc_noport == 0; i++) { 886 usb_delay_ms(&sc->sc_bus, OHCI_READ_DESC_DELAY); 887 sc->sc_noport = OHCI_GET_NDP(OREAD4(sc, OHCI_RH_DESCRIPTOR_A)); 888 } 889 890 #ifdef OHCI_DEBUG 891 if (ohcidebug > 5) 892 ohci_dumpregs(sc); 893 #endif 894 895 /* Set up the bus struct. */ 896 sc->sc_bus.methods = &ohci_bus_methods; 897 sc->sc_bus.pipe_size = sizeof(struct ohci_pipe); 898 899 sc->sc_control = sc->sc_intre = 0; 900 901 /* Finally, turn on interrupts. */ 902 DPRINTFN(1,("ohci_init: enabling %#x\n", sc->sc_eintrs | OHCI_MIE)); 903 OWRITE4(sc, OHCI_INTERRUPT_ENABLE, sc->sc_eintrs | OHCI_MIE); 904 905 return (USBD_NORMAL_COMPLETION); 906 907 bad5: 908 for (i = 0; i < OHCI_NO_EDS; i++) 909 ohci_free_sed(sc, sc->sc_eds[i]); 910 bad4: 911 ohci_free_sed(sc, sc->sc_isoc_head); 912 bad3: 913 ohci_free_sed(sc, sc->sc_bulk_head); 914 bad2: 915 ohci_free_sed(sc, sc->sc_ctrl_head); 916 bad1: 917 usb_freemem(&sc->sc_bus, &sc->sc_hccadma); 918 sc->sc_hcca = NULL; 919 return (err); 920 } 921 922 usbd_status 923 ohci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size) 924 { 925 struct ohci_softc *sc = bus->hci_private; 926 usbd_status status; 927 928 status = usb_allocmem(&sc->sc_bus, size, 0, dma); 929 if (status == USBD_NOMEM) 930 status = usb_reserve_allocm(&sc->sc_dma_reserve, dma, size); 931 return status; 932 } 933 934 void 935 ohci_freem(struct usbd_bus *bus, usb_dma_t *dma) 936 { 937 struct ohci_softc *sc = bus->hci_private; 938 if (dma->block->flags & USB_DMA_RESERVE) { 939 usb_reserve_freem(&sc->sc_dma_reserve, dma); 940 return; 941 } 942 usb_freemem(&sc->sc_bus, dma); 943 } 944 945 usbd_xfer_handle 946 ohci_allocx(struct usbd_bus *bus) 947 { 948 struct ohci_softc *sc = bus->hci_private; 949 usbd_xfer_handle xfer; 950 951 xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers); 952 if (xfer != NULL) { 953 SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next); 954 #ifdef DIAGNOSTIC 955 if (xfer->busy_free != XFER_FREE) { 956 printf("ohci_allocx: xfer=%p not free, 0x%08x\n", xfer, 957 xfer->busy_free); 958 } 959 #endif 960 } else { 961 xfer = malloc(sizeof(struct ohci_xfer), M_USB, M_NOWAIT); 962 } 963 if (xfer != NULL) { 964 memset(xfer, 0, sizeof (struct ohci_xfer)); 965 #ifdef DIAGNOSTIC 966 xfer->busy_free = XFER_BUSY; 967 #endif 968 } 969 return (xfer); 970 } 971 972 void 973 ohci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer) 974 { 975 struct ohci_softc *sc = bus->hci_private; 976 977 #ifdef DIAGNOSTIC 978 if (xfer->busy_free != XFER_BUSY) { 979 printf("ohci_freex: xfer=%p not busy, 0x%08x\n", xfer, 980 xfer->busy_free); 981 } 982 xfer->busy_free = XFER_FREE; 983 #endif 984 SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next); 985 } 986 987 /* 988 * Shut down the controller when the system is going down. 989 */ 990 bool 991 ohci_shutdown(device_t self, int flags) 992 { 993 ohci_softc_t *sc = device_private(self); 994 995 DPRINTF(("ohci_shutdown: stopping the HC\n")); 996 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET); 997 return true; 998 } 999 1000 bool 1001 ohci_resume(device_t dv, const pmf_qual_t *qual) 1002 { 1003 ohci_softc_t *sc = device_private(dv); 1004 uint32_t ctl; 1005 int s; 1006 1007 s = splhardusb(); 1008 sc->sc_bus.use_polling++; 1009 /* Some broken BIOSes do not recover these values */ 1010 OWRITE4(sc, OHCI_HCCA, DMAADDR(&sc->sc_hccadma, 0)); 1011 OWRITE4(sc, OHCI_CONTROL_HEAD_ED, 1012 sc->sc_ctrl_head->physaddr); 1013 OWRITE4(sc, OHCI_BULK_HEAD_ED, 1014 sc->sc_bulk_head->physaddr); 1015 if (sc->sc_intre) 1016 OWRITE4(sc, OHCI_INTERRUPT_ENABLE, sc->sc_intre & 1017 (OHCI_ALL_INTRS | OHCI_MIE)); 1018 if (sc->sc_control) 1019 ctl = sc->sc_control; 1020 else 1021 ctl = OREAD4(sc, OHCI_CONTROL); 1022 ctl |= OHCI_HCFS_RESUME; 1023 OWRITE4(sc, OHCI_CONTROL, ctl); 1024 usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY); 1025 ctl = (ctl & ~OHCI_HCFS_MASK) | OHCI_HCFS_OPERATIONAL; 1026 OWRITE4(sc, OHCI_CONTROL, ctl); 1027 usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY); 1028 sc->sc_control = sc->sc_intre = 0; 1029 sc->sc_bus.use_polling--; 1030 splx(s); 1031 1032 return true; 1033 } 1034 1035 bool 1036 ohci_suspend(device_t dv, const pmf_qual_t *qual) 1037 { 1038 ohci_softc_t *sc = device_private(dv); 1039 uint32_t ctl; 1040 int s; 1041 1042 s = splhardusb(); 1043 sc->sc_bus.use_polling++; 1044 ctl = OREAD4(sc, OHCI_CONTROL) & ~OHCI_HCFS_MASK; 1045 if (sc->sc_control == 0) { 1046 /* 1047 * Preserve register values, in case that BIOS 1048 * does not recover them. 1049 */ 1050 sc->sc_control = ctl; 1051 sc->sc_intre = OREAD4(sc, 1052 OHCI_INTERRUPT_ENABLE); 1053 } 1054 ctl |= OHCI_HCFS_SUSPEND; 1055 OWRITE4(sc, OHCI_CONTROL, ctl); 1056 usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT); 1057 sc->sc_bus.use_polling--; 1058 splx(s); 1059 1060 return true; 1061 } 1062 1063 #ifdef OHCI_DEBUG 1064 void 1065 ohci_dumpregs(ohci_softc_t *sc) 1066 { 1067 DPRINTF(("ohci_dumpregs: rev=0x%08x control=0x%08x command=0x%08x\n", 1068 OREAD4(sc, OHCI_REVISION), 1069 OREAD4(sc, OHCI_CONTROL), 1070 OREAD4(sc, OHCI_COMMAND_STATUS))); 1071 DPRINTF((" intrstat=0x%08x intre=0x%08x intrd=0x%08x\n", 1072 OREAD4(sc, OHCI_INTERRUPT_STATUS), 1073 OREAD4(sc, OHCI_INTERRUPT_ENABLE), 1074 OREAD4(sc, OHCI_INTERRUPT_DISABLE))); 1075 DPRINTF((" hcca=0x%08x percur=0x%08x ctrlhd=0x%08x\n", 1076 OREAD4(sc, OHCI_HCCA), 1077 OREAD4(sc, OHCI_PERIOD_CURRENT_ED), 1078 OREAD4(sc, OHCI_CONTROL_HEAD_ED))); 1079 DPRINTF((" ctrlcur=0x%08x bulkhd=0x%08x bulkcur=0x%08x\n", 1080 OREAD4(sc, OHCI_CONTROL_CURRENT_ED), 1081 OREAD4(sc, OHCI_BULK_HEAD_ED), 1082 OREAD4(sc, OHCI_BULK_CURRENT_ED))); 1083 DPRINTF((" done=0x%08x fmival=0x%08x fmrem=0x%08x\n", 1084 OREAD4(sc, OHCI_DONE_HEAD), 1085 OREAD4(sc, OHCI_FM_INTERVAL), 1086 OREAD4(sc, OHCI_FM_REMAINING))); 1087 DPRINTF((" fmnum=0x%08x perst=0x%08x lsthrs=0x%08x\n", 1088 OREAD4(sc, OHCI_FM_NUMBER), 1089 OREAD4(sc, OHCI_PERIODIC_START), 1090 OREAD4(sc, OHCI_LS_THRESHOLD))); 1091 DPRINTF((" desca=0x%08x descb=0x%08x stat=0x%08x\n", 1092 OREAD4(sc, OHCI_RH_DESCRIPTOR_A), 1093 OREAD4(sc, OHCI_RH_DESCRIPTOR_B), 1094 OREAD4(sc, OHCI_RH_STATUS))); 1095 DPRINTF((" port1=0x%08x port2=0x%08x\n", 1096 OREAD4(sc, OHCI_RH_PORT_STATUS(1)), 1097 OREAD4(sc, OHCI_RH_PORT_STATUS(2)))); 1098 DPRINTF((" HCCA: frame_number=0x%04x done_head=0x%08x\n", 1099 O32TOH(sc->sc_hcca->hcca_frame_number), 1100 O32TOH(sc->sc_hcca->hcca_done_head))); 1101 } 1102 #endif 1103 1104 Static int ohci_intr1(ohci_softc_t *); 1105 1106 int 1107 ohci_intr(void *p) 1108 { 1109 ohci_softc_t *sc = p; 1110 1111 if (sc == NULL || sc->sc_dying || !device_has_power(sc->sc_dev)) 1112 return (0); 1113 1114 /* If we get an interrupt while polling, then just ignore it. */ 1115 if (sc->sc_bus.use_polling) { 1116 #ifdef DIAGNOSTIC 1117 DPRINTFN(16, ("ohci_intr: ignored interrupt while polling\n")); 1118 #endif 1119 /* for level triggered intrs, should do something to ack */ 1120 OWRITE4(sc, OHCI_INTERRUPT_STATUS, 1121 OREAD4(sc, OHCI_INTERRUPT_STATUS)); 1122 1123 return (0); 1124 } 1125 1126 return (ohci_intr1(sc)); 1127 } 1128 1129 Static int 1130 ohci_intr1(ohci_softc_t *sc) 1131 { 1132 u_int32_t intrs, eintrs; 1133 1134 DPRINTFN(14,("ohci_intr1: enter\n")); 1135 1136 /* In case the interrupt occurs before initialization has completed. */ 1137 if (sc == NULL || sc->sc_hcca == NULL) { 1138 #ifdef DIAGNOSTIC 1139 printf("ohci_intr: sc->sc_hcca == NULL\n"); 1140 #endif 1141 return (0); 1142 } 1143 1144 intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS); 1145 if (!intrs) 1146 return (0); 1147 1148 OWRITE4(sc, OHCI_INTERRUPT_STATUS, intrs & ~(OHCI_MIE|OHCI_WDH)); /* Acknowledge */ 1149 eintrs = intrs & sc->sc_eintrs; 1150 DPRINTFN(7, ("ohci_intr: sc=%p intrs=%#x(%#x) eintrs=%#x(%#x)\n", 1151 sc, (u_int)intrs, OREAD4(sc, OHCI_INTERRUPT_STATUS), 1152 (u_int)eintrs, sc->sc_eintrs)); 1153 1154 if (!eintrs) { 1155 return (0); 1156 } 1157 1158 sc->sc_bus.intr_context++; 1159 sc->sc_bus.no_intrs++; 1160 if (eintrs & OHCI_SO) { 1161 sc->sc_overrun_cnt++; 1162 if (usbd_ratecheck(&sc->sc_overrun_ntc)) { 1163 printf("%s: %u scheduling overruns\n", 1164 device_xname(sc->sc_dev), sc->sc_overrun_cnt); 1165 sc->sc_overrun_cnt = 0; 1166 } 1167 /* XXX do what */ 1168 eintrs &= ~OHCI_SO; 1169 } 1170 if (eintrs & OHCI_WDH) { 1171 /* 1172 * We block the interrupt below, and reenable it later from 1173 * ohci_softintr(). 1174 */ 1175 usb_schedsoftintr(&sc->sc_bus); 1176 } 1177 if (eintrs & OHCI_RD) { 1178 printf("%s: resume detect\n", device_xname(sc->sc_dev)); 1179 /* XXX process resume detect */ 1180 } 1181 if (eintrs & OHCI_UE) { 1182 printf("%s: unrecoverable error, controller halted\n", 1183 device_xname(sc->sc_dev)); 1184 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET); 1185 /* XXX what else */ 1186 } 1187 if (eintrs & OHCI_RHSC) { 1188 /* 1189 * We block the interrupt below, and reenable it later from 1190 * a timeout. 1191 */ 1192 ohci_rhsc(sc, sc->sc_intrxfer); 1193 /* Do not allow RHSC interrupts > 1 per second */ 1194 callout_reset(&sc->sc_tmo_rhsc, hz, ohci_rhsc_enable, sc); 1195 } 1196 1197 sc->sc_bus.intr_context--; 1198 1199 if (eintrs != 0) { 1200 /* Block unprocessed interrupts. */ 1201 OWRITE4(sc, OHCI_INTERRUPT_DISABLE, eintrs); 1202 sc->sc_eintrs &= ~eintrs; 1203 DPRINTFN(1, ("%s: blocking intrs 0x%x\n", 1204 device_xname(sc->sc_dev), eintrs)); 1205 } 1206 1207 return (1); 1208 } 1209 1210 void 1211 ohci_rhsc_enable(void *v_sc) 1212 { 1213 ohci_softc_t *sc = v_sc; 1214 int s; 1215 1216 s = splhardusb(); 1217 sc->sc_eintrs |= OHCI_RHSC; 1218 OWRITE4(sc, OHCI_INTERRUPT_ENABLE, OHCI_RHSC); 1219 splx(s); 1220 } 1221 1222 #ifdef OHCI_DEBUG 1223 const char *ohci_cc_strs[] = { 1224 "NO_ERROR", 1225 "CRC", 1226 "BIT_STUFFING", 1227 "DATA_TOGGLE_MISMATCH", 1228 "STALL", 1229 "DEVICE_NOT_RESPONDING", 1230 "PID_CHECK_FAILURE", 1231 "UNEXPECTED_PID", 1232 "DATA_OVERRUN", 1233 "DATA_UNDERRUN", 1234 "BUFFER_OVERRUN", 1235 "BUFFER_UNDERRUN", 1236 "reserved", 1237 "reserved", 1238 "NOT_ACCESSED", 1239 "NOT_ACCESSED", 1240 }; 1241 #endif 1242 1243 void 1244 ohci_softintr(void *v) 1245 { 1246 struct usbd_bus *bus = v; 1247 ohci_softc_t *sc = bus->hci_private; 1248 ohci_soft_itd_t *sitd, *sidone, *sitdnext; 1249 ohci_soft_td_t *std, *sdone, *stdnext; 1250 usbd_xfer_handle xfer; 1251 struct ohci_pipe *opipe; 1252 int len, cc, s; 1253 int i, j, actlen, iframes, uedir; 1254 ohci_physaddr_t done; 1255 1256 DPRINTFN(10,("ohci_softintr: enter\n")); 1257 1258 sc->sc_bus.intr_context++; 1259 1260 s = splhardusb(); 1261 usb_syncmem(&sc->sc_hccadma, offsetof(struct ohci_hcca, hcca_done_head), 1262 sizeof(sc->sc_hcca->hcca_done_head), 1263 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1264 done = O32TOH(sc->sc_hcca->hcca_done_head) & ~OHCI_DONE_INTRS; 1265 sc->sc_hcca->hcca_done_head = 0; 1266 usb_syncmem(&sc->sc_hccadma, offsetof(struct ohci_hcca, hcca_done_head), 1267 sizeof(sc->sc_hcca->hcca_done_head), 1268 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1269 OWRITE4(sc, OHCI_INTERRUPT_STATUS, OHCI_WDH); 1270 sc->sc_eintrs |= OHCI_WDH; 1271 OWRITE4(sc, OHCI_INTERRUPT_ENABLE, OHCI_WDH); 1272 splx(s); 1273 1274 /* Reverse the done list. */ 1275 for (sdone = NULL, sidone = NULL; done != 0; ) { 1276 std = ohci_hash_find_td(sc, done); 1277 if (std != NULL) { 1278 usb_syncmem(&std->dma, std->offs, sizeof(std->td), 1279 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1280 std->dnext = sdone; 1281 done = O32TOH(std->td.td_nexttd); 1282 sdone = std; 1283 DPRINTFN(10,("add TD %p\n", std)); 1284 continue; 1285 } 1286 sitd = ohci_hash_find_itd(sc, done); 1287 if (sitd != NULL) { 1288 usb_syncmem(&sitd->dma, sitd->offs, sizeof(sitd->itd), 1289 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1290 sitd->dnext = sidone; 1291 done = O32TOH(sitd->itd.itd_nextitd); 1292 sidone = sitd; 1293 DPRINTFN(5,("add ITD %p\n", sitd)); 1294 continue; 1295 } 1296 device_printf(sc->sc_dev, "WARNING: addr 0x%08lx not found\n", 1297 (u_long)done); 1298 break; 1299 } 1300 1301 DPRINTFN(10,("ohci_softintr: sdone=%p sidone=%p\n", sdone, sidone)); 1302 1303 #ifdef OHCI_DEBUG 1304 if (ohcidebug > 10) { 1305 DPRINTF(("ohci_process_done: TD done:\n")); 1306 ohci_dump_tds(sc, sdone); 1307 } 1308 #endif 1309 1310 for (std = sdone; std; std = stdnext) { 1311 xfer = std->xfer; 1312 stdnext = std->dnext; 1313 DPRINTFN(10, ("ohci_process_done: std=%p xfer=%p hcpriv=%p\n", 1314 std, xfer, xfer ? xfer->hcpriv : 0)); 1315 if (xfer == NULL) { 1316 /* 1317 * xfer == NULL: There seems to be no xfer associated 1318 * with this TD. It is tailp that happened to end up on 1319 * the done queue. 1320 * Shouldn't happen, but some chips are broken(?). 1321 */ 1322 continue; 1323 } 1324 if (xfer->status == USBD_CANCELLED || 1325 xfer->status == USBD_TIMEOUT) { 1326 DPRINTF(("ohci_process_done: cancel/timeout %p\n", 1327 xfer)); 1328 /* Handled by abort routine. */ 1329 continue; 1330 } 1331 callout_stop(&xfer->timeout_handle); 1332 1333 len = std->len; 1334 if (std->td.td_cbp != 0) 1335 len -= O32TOH(std->td.td_be) - 1336 O32TOH(std->td.td_cbp) + 1; 1337 DPRINTFN(10, ("ohci_process_done: len=%d, flags=0x%x\n", len, 1338 std->flags)); 1339 if (std->flags & OHCI_ADD_LEN) 1340 xfer->actlen += len; 1341 1342 cc = OHCI_TD_GET_CC(O32TOH(std->td.td_flags)); 1343 if (cc == OHCI_CC_NO_ERROR) { 1344 if (std->flags & OHCI_CALL_DONE) { 1345 xfer->status = USBD_NORMAL_COMPLETION; 1346 s = splusb(); 1347 usb_transfer_complete(xfer); 1348 splx(s); 1349 } 1350 ohci_free_std(sc, std); 1351 } else { 1352 /* 1353 * Endpoint is halted. First unlink all the TDs 1354 * belonging to the failed transfer, and then restart 1355 * the endpoint. 1356 */ 1357 ohci_soft_td_t *p, *n; 1358 opipe = (struct ohci_pipe *)xfer->pipe; 1359 1360 DPRINTFN(15,("ohci_process_done: error cc=%d (%s)\n", 1361 OHCI_TD_GET_CC(O32TOH(std->td.td_flags)), 1362 ohci_cc_strs[OHCI_TD_GET_CC(O32TOH(std->td.td_flags))])); 1363 1364 /* remove TDs */ 1365 for (p = std; p->xfer == xfer; p = n) { 1366 n = p->nexttd; 1367 ohci_free_std(sc, p); 1368 } 1369 1370 /* clear halt */ 1371 opipe->sed->ed.ed_headp = HTOO32(p->physaddr); 1372 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF); 1373 1374 if (cc == OHCI_CC_STALL) 1375 xfer->status = USBD_STALLED; 1376 else 1377 xfer->status = USBD_IOERROR; 1378 s = splusb(); 1379 usb_transfer_complete(xfer); 1380 splx(s); 1381 } 1382 } 1383 1384 #ifdef OHCI_DEBUG 1385 if (ohcidebug > 10) { 1386 DPRINTF(("ohci_softintr: ITD done:\n")); 1387 ohci_dump_itds(sc, sidone); 1388 } 1389 #endif 1390 1391 for (sitd = sidone; sitd != NULL; sitd = sitdnext) { 1392 xfer = sitd->xfer; 1393 sitdnext = sitd->dnext; 1394 DPRINTFN(1, ("ohci_process_done: sitd=%p xfer=%p hcpriv=%p\n", 1395 sitd, xfer, xfer ? xfer->hcpriv : 0)); 1396 if (xfer == NULL) 1397 continue; 1398 if (xfer->status == USBD_CANCELLED || 1399 xfer->status == USBD_TIMEOUT) { 1400 DPRINTF(("ohci_process_done: cancel/timeout %p\n", 1401 xfer)); 1402 /* Handled by abort routine. */ 1403 continue; 1404 } 1405 #ifdef DIAGNOSTIC 1406 if (sitd->isdone) 1407 printf("ohci_softintr: sitd=%p is done\n", sitd); 1408 sitd->isdone = 1; 1409 #endif 1410 if (sitd->flags & OHCI_CALL_DONE) { 1411 ohci_soft_itd_t *next; 1412 1413 opipe = (struct ohci_pipe *)xfer->pipe; 1414 opipe->u.iso.inuse -= xfer->nframes; 1415 uedir = UE_GET_DIR(xfer->pipe->endpoint->edesc-> 1416 bEndpointAddress); 1417 xfer->status = USBD_NORMAL_COMPLETION; 1418 actlen = 0; 1419 for (i = 0, sitd = xfer->hcpriv;; 1420 sitd = next) { 1421 next = sitd->nextitd; 1422 if (OHCI_ITD_GET_CC(O32TOH(sitd-> 1423 itd.itd_flags)) != OHCI_CC_NO_ERROR) 1424 xfer->status = USBD_IOERROR; 1425 /* For input, update frlengths with actual */ 1426 /* XXX anything necessary for output? */ 1427 if (uedir == UE_DIR_IN && 1428 xfer->status == USBD_NORMAL_COMPLETION) { 1429 iframes = OHCI_ITD_GET_FC(O32TOH( 1430 sitd->itd.itd_flags)); 1431 for (j = 0; j < iframes; i++, j++) { 1432 len = O16TOH(sitd-> 1433 itd.itd_offset[j]); 1434 if ((OHCI_ITD_PSW_GET_CC(len) & 1435 OHCI_CC_NOT_ACCESSED_MASK) 1436 == OHCI_CC_NOT_ACCESSED) 1437 len = 0; 1438 else 1439 len = OHCI_ITD_PSW_LENGTH(len); 1440 xfer->frlengths[i] = len; 1441 actlen += len; 1442 } 1443 } 1444 if (sitd->flags & OHCI_CALL_DONE) 1445 break; 1446 ohci_free_sitd(sc, sitd); 1447 } 1448 ohci_free_sitd(sc, sitd); 1449 if (uedir == UE_DIR_IN && 1450 xfer->status == USBD_NORMAL_COMPLETION) 1451 xfer->actlen = actlen; 1452 xfer->hcpriv = NULL; 1453 1454 s = splusb(); 1455 usb_transfer_complete(xfer); 1456 splx(s); 1457 } 1458 } 1459 1460 #ifdef USB_USE_SOFTINTR 1461 if (sc->sc_softwake) { 1462 sc->sc_softwake = 0; 1463 wakeup(&sc->sc_softwake); 1464 } 1465 #endif /* USB_USE_SOFTINTR */ 1466 1467 sc->sc_bus.intr_context--; 1468 DPRINTFN(10,("ohci_softintr: done:\n")); 1469 } 1470 1471 void 1472 ohci_device_ctrl_done(usbd_xfer_handle xfer) 1473 { 1474 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; 1475 int len = UGETW(xfer->request.wLength); 1476 int isread = (xfer->request.bmRequestType & UT_READ); 1477 1478 DPRINTFN(10,("ohci_device_ctrl_done: xfer=%p\n", xfer)); 1479 1480 #ifdef DIAGNOSTIC 1481 if (!(xfer->rqflags & URQ_REQUEST)) { 1482 panic("ohci_device_ctrl_done: not a request"); 1483 } 1484 #endif 1485 if (len) 1486 usb_syncmem(&xfer->dmabuf, 0, len, 1487 isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 1488 usb_syncmem(&opipe->u.ctl.reqdma, 0, 1489 sizeof(usb_device_request_t), BUS_DMASYNC_POSTWRITE); 1490 } 1491 1492 void 1493 ohci_device_intr_done(usbd_xfer_handle xfer) 1494 { 1495 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; 1496 ohci_softc_t *sc = opipe->pipe.device->bus->hci_private; 1497 ohci_soft_ed_t *sed = opipe->sed; 1498 ohci_soft_td_t *data, *tail; 1499 int isread = 1500 (UE_GET_DIR(xfer->pipe->endpoint->edesc->bEndpointAddress) == UE_DIR_IN); 1501 1502 1503 DPRINTFN(10,("ohci_device_intr_done: xfer=%p, actlen=%d\n", 1504 xfer, xfer->actlen)); 1505 1506 usb_syncmem(&xfer->dmabuf, 0, xfer->length, 1507 isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 1508 if (xfer->pipe->repeat) { 1509 data = opipe->tail.td; 1510 tail = ohci_alloc_std(sc); /* XXX should reuse TD */ 1511 if (tail == NULL) { 1512 xfer->status = USBD_NOMEM; 1513 return; 1514 } 1515 tail->xfer = NULL; 1516 1517 data->td.td_flags = HTOO32( 1518 OHCI_TD_IN | OHCI_TD_NOCC | 1519 OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY); 1520 if (xfer->flags & USBD_SHORT_XFER_OK) 1521 data->td.td_flags |= HTOO32(OHCI_TD_R); 1522 data->td.td_cbp = HTOO32(DMAADDR(&xfer->dmabuf, 0)); 1523 data->nexttd = tail; 1524 data->td.td_nexttd = HTOO32(tail->physaddr); 1525 data->td.td_be = HTOO32(O32TOH(data->td.td_cbp) + 1526 xfer->length - 1); 1527 data->len = xfer->length; 1528 data->xfer = xfer; 1529 data->flags = OHCI_CALL_DONE | OHCI_ADD_LEN; 1530 usb_syncmem(&data->dma, data->offs, sizeof(data->td), 1531 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1532 xfer->hcpriv = data; 1533 xfer->actlen = 0; 1534 1535 sed->ed.ed_tailp = HTOO32(tail->physaddr); 1536 usb_syncmem(&sed->dma, 1537 sed->offs + offsetof(ohci_ed_t, ed_tailp), 1538 sizeof(sed->ed.ed_tailp), 1539 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1540 opipe->tail.td = tail; 1541 } 1542 } 1543 1544 void 1545 ohci_device_bulk_done(usbd_xfer_handle xfer) 1546 { 1547 int isread = 1548 (UE_GET_DIR(xfer->pipe->endpoint->edesc->bEndpointAddress) == UE_DIR_IN); 1549 1550 DPRINTFN(10,("ohci_device_bulk_done: xfer=%p, actlen=%d\n", 1551 xfer, xfer->actlen)); 1552 usb_syncmem(&xfer->dmabuf, 0, xfer->length, 1553 isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 1554 } 1555 1556 void 1557 ohci_rhsc(ohci_softc_t *sc, usbd_xfer_handle xfer) 1558 { 1559 usbd_pipe_handle pipe; 1560 u_char *p; 1561 int i, m; 1562 int hstatus; 1563 1564 hstatus = OREAD4(sc, OHCI_RH_STATUS); 1565 DPRINTF(("ohci_rhsc: sc=%p xfer=%p hstatus=0x%08x\n", 1566 sc, xfer, hstatus)); 1567 1568 if (xfer == NULL) { 1569 /* Just ignore the change. */ 1570 return; 1571 } 1572 1573 pipe = xfer->pipe; 1574 1575 p = KERNADDR(&xfer->dmabuf, 0); 1576 m = min(sc->sc_noport, xfer->length * 8 - 1); 1577 memset(p, 0, xfer->length); 1578 for (i = 1; i <= m; i++) { 1579 /* Pick out CHANGE bits from the status reg. */ 1580 if (OREAD4(sc, OHCI_RH_PORT_STATUS(i)) >> 16) 1581 p[i/8] |= 1 << (i%8); 1582 } 1583 DPRINTF(("ohci_rhsc: change=0x%02x\n", *p)); 1584 xfer->actlen = xfer->length; 1585 xfer->status = USBD_NORMAL_COMPLETION; 1586 1587 usb_transfer_complete(xfer); 1588 } 1589 1590 void 1591 ohci_root_intr_done(usbd_xfer_handle xfer) 1592 { 1593 } 1594 1595 void 1596 ohci_root_ctrl_done(usbd_xfer_handle xfer) 1597 { 1598 } 1599 1600 /* 1601 * Wait here until controller claims to have an interrupt. 1602 * Then call ohci_intr and return. Use timeout to avoid waiting 1603 * too long. 1604 */ 1605 void 1606 ohci_waitintr(ohci_softc_t *sc, usbd_xfer_handle xfer) 1607 { 1608 int timo; 1609 u_int32_t intrs; 1610 1611 xfer->status = USBD_IN_PROGRESS; 1612 for (timo = xfer->timeout; timo >= 0; timo--) { 1613 usb_delay_ms(&sc->sc_bus, 1); 1614 if (sc->sc_dying) 1615 break; 1616 intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs; 1617 DPRINTFN(15,("ohci_waitintr: 0x%04x\n", intrs)); 1618 #ifdef OHCI_DEBUG 1619 if (ohcidebug > 15) 1620 ohci_dumpregs(sc); 1621 #endif 1622 if (intrs) { 1623 ohci_intr1(sc); 1624 if (xfer->status != USBD_IN_PROGRESS) 1625 return; 1626 } 1627 } 1628 1629 /* Timeout */ 1630 DPRINTF(("ohci_waitintr: timeout\n")); 1631 xfer->status = USBD_TIMEOUT; 1632 usb_transfer_complete(xfer); 1633 /* XXX should free TD */ 1634 } 1635 1636 void 1637 ohci_poll(struct usbd_bus *bus) 1638 { 1639 ohci_softc_t *sc = bus->hci_private; 1640 #ifdef OHCI_DEBUG 1641 static int last; 1642 int new; 1643 new = OREAD4(sc, OHCI_INTERRUPT_STATUS); 1644 if (new != last) { 1645 DPRINTFN(10,("ohci_poll: intrs=0x%04x\n", new)); 1646 last = new; 1647 } 1648 #endif 1649 1650 sc->sc_eintrs |= OHCI_WDH; 1651 if (OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs) 1652 ohci_intr1(sc); 1653 } 1654 1655 usbd_status 1656 ohci_device_request(usbd_xfer_handle xfer) 1657 { 1658 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; 1659 usb_device_request_t *req = &xfer->request; 1660 usbd_device_handle dev = opipe->pipe.device; 1661 ohci_softc_t *sc = dev->bus->hci_private; 1662 int addr = dev->address; 1663 ohci_soft_td_t *setup, *stat, *next, *tail; 1664 ohci_soft_ed_t *sed; 1665 int isread; 1666 int len; 1667 usbd_status err; 1668 int s; 1669 1670 isread = req->bmRequestType & UT_READ; 1671 len = UGETW(req->wLength); 1672 1673 DPRINTFN(3,("ohci_device_control type=0x%02x, request=0x%02x, " 1674 "wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n", 1675 req->bmRequestType, req->bRequest, UGETW(req->wValue), 1676 UGETW(req->wIndex), len, addr, 1677 opipe->pipe.endpoint->edesc->bEndpointAddress)); 1678 1679 setup = opipe->tail.td; 1680 stat = ohci_alloc_std(sc); 1681 if (stat == NULL) { 1682 err = USBD_NOMEM; 1683 goto bad1; 1684 } 1685 tail = ohci_alloc_std(sc); 1686 if (tail == NULL) { 1687 err = USBD_NOMEM; 1688 goto bad2; 1689 } 1690 tail->xfer = NULL; 1691 1692 sed = opipe->sed; 1693 opipe->u.ctl.length = len; 1694 1695 /* Update device address and length since they may have changed 1696 during the setup of the control pipe in usbd_new_device(). */ 1697 /* XXX This only needs to be done once, but it's too early in open. */ 1698 /* XXXX Should not touch ED here! */ 1699 1700 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), 1701 sizeof(sed->ed.ed_flags), 1702 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1703 sed->ed.ed_flags = HTOO32( 1704 (O32TOH(sed->ed.ed_flags) & ~(OHCI_ED_ADDRMASK | OHCI_ED_MAXPMASK)) | 1705 OHCI_ED_SET_FA(addr) | 1706 OHCI_ED_SET_MAXP(UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize))); 1707 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), 1708 sizeof(sed->ed.ed_flags), 1709 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1710 1711 next = stat; 1712 1713 /* Set up data transaction */ 1714 if (len != 0) { 1715 ohci_soft_td_t *std = stat; 1716 1717 err = ohci_alloc_std_chain(opipe, sc, len, isread, xfer, 1718 std, &stat); 1719 stat = stat->nexttd; /* point at free TD */ 1720 if (err) 1721 goto bad3; 1722 /* Start toggle at 1 and then use the carried toggle. */ 1723 std->td.td_flags &= HTOO32(~OHCI_TD_TOGGLE_MASK); 1724 std->td.td_flags |= HTOO32(OHCI_TD_TOGGLE_1); 1725 usb_syncmem(&std->dma, 1726 std->offs + offsetof(ohci_td_t, td_flags), 1727 sizeof(std->td.td_flags), 1728 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1729 } 1730 1731 memcpy(KERNADDR(&opipe->u.ctl.reqdma, 0), req, sizeof *req); 1732 usb_syncmem(&opipe->u.ctl.reqdma, 0, sizeof *req, BUS_DMASYNC_PREWRITE); 1733 1734 setup->td.td_flags = HTOO32(OHCI_TD_SETUP | OHCI_TD_NOCC | 1735 OHCI_TD_TOGGLE_0 | OHCI_TD_NOINTR); 1736 setup->td.td_cbp = HTOO32(DMAADDR(&opipe->u.ctl.reqdma, 0)); 1737 setup->nexttd = next; 1738 setup->td.td_nexttd = HTOO32(next->physaddr); 1739 setup->td.td_be = HTOO32(O32TOH(setup->td.td_cbp) + sizeof *req - 1); 1740 setup->len = 0; 1741 setup->xfer = xfer; 1742 setup->flags = 0; 1743 xfer->hcpriv = setup; 1744 usb_syncmem(&setup->dma, setup->offs, sizeof(setup->td), 1745 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1746 1747 stat->td.td_flags = HTOO32( 1748 (isread ? OHCI_TD_OUT : OHCI_TD_IN) | 1749 OHCI_TD_NOCC | OHCI_TD_TOGGLE_1 | OHCI_TD_SET_DI(1)); 1750 stat->td.td_cbp = 0; 1751 stat->nexttd = tail; 1752 stat->td.td_nexttd = HTOO32(tail->physaddr); 1753 stat->td.td_be = 0; 1754 stat->flags = OHCI_CALL_DONE; 1755 stat->len = 0; 1756 stat->xfer = xfer; 1757 usb_syncmem(&stat->dma, stat->offs, sizeof(stat->td), 1758 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1759 1760 #ifdef OHCI_DEBUG 1761 if (ohcidebug > 5) { 1762 DPRINTF(("ohci_device_request:\n")); 1763 ohci_dump_ed(sc, sed); 1764 ohci_dump_tds(sc, setup); 1765 } 1766 #endif 1767 1768 /* Insert ED in schedule */ 1769 s = splusb(); 1770 sed->ed.ed_tailp = HTOO32(tail->physaddr); 1771 usb_syncmem(&sed->dma, 1772 sed->offs + offsetof(ohci_ed_t, ed_tailp), 1773 sizeof(sed->ed.ed_tailp), 1774 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1775 opipe->tail.td = tail; 1776 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF); 1777 if (xfer->timeout && !sc->sc_bus.use_polling) { 1778 callout_reset(&xfer->timeout_handle, mstohz(xfer->timeout), 1779 ohci_timeout, xfer); 1780 } 1781 splx(s); 1782 1783 #ifdef OHCI_DEBUG 1784 if (ohcidebug > 20) { 1785 delay(10000); 1786 DPRINTF(("ohci_device_request: status=%x\n", 1787 OREAD4(sc, OHCI_COMMAND_STATUS))); 1788 ohci_dumpregs(sc); 1789 printf("ctrl head:\n"); 1790 ohci_dump_ed(sc, sc->sc_ctrl_head); 1791 printf("sed:\n"); 1792 ohci_dump_ed(sc, sed); 1793 ohci_dump_tds(sc, setup); 1794 } 1795 #endif 1796 1797 return (USBD_NORMAL_COMPLETION); 1798 1799 bad3: 1800 ohci_free_std(sc, tail); 1801 bad2: 1802 ohci_free_std(sc, stat); 1803 bad1: 1804 return (err); 1805 } 1806 1807 /* 1808 * Add an ED to the schedule. Called at splusb(). 1809 */ 1810 void 1811 ohci_add_ed(ohci_softc_t *sc, ohci_soft_ed_t *sed, ohci_soft_ed_t *head) 1812 { 1813 DPRINTFN(8,("ohci_add_ed: sed=%p head=%p\n", sed, head)); 1814 1815 SPLUSBCHECK; 1816 usb_syncmem(&head->dma, head->offs + offsetof(ohci_ed_t, ed_nexted), 1817 sizeof(head->ed.ed_nexted), 1818 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1819 sed->next = head->next; 1820 sed->ed.ed_nexted = head->ed.ed_nexted; 1821 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_nexted), 1822 sizeof(sed->ed.ed_nexted), 1823 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1824 head->next = sed; 1825 head->ed.ed_nexted = HTOO32(sed->physaddr); 1826 usb_syncmem(&head->dma, head->offs + offsetof(ohci_ed_t, ed_nexted), 1827 sizeof(head->ed.ed_nexted), 1828 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1829 } 1830 1831 /* 1832 * Remove an ED from the schedule. Called at splusb(). 1833 */ 1834 void 1835 ohci_rem_ed(ohci_soft_ed_t *sed, ohci_soft_ed_t *head) 1836 { 1837 ohci_soft_ed_t *p; 1838 1839 SPLUSBCHECK; 1840 1841 /* XXX */ 1842 for (p = head; p != NULL && p->next != sed; p = p->next) 1843 ; 1844 if (p == NULL) 1845 panic("ohci_rem_ed: ED not found"); 1846 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_nexted), 1847 sizeof(sed->ed.ed_nexted), 1848 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1849 p->next = sed->next; 1850 p->ed.ed_nexted = sed->ed.ed_nexted; 1851 usb_syncmem(&p->dma, p->offs + offsetof(ohci_ed_t, ed_nexted), 1852 sizeof(p->ed.ed_nexted), 1853 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1854 } 1855 1856 /* 1857 * When a transfer is completed the TD is added to the done queue by 1858 * the host controller. This queue is the processed by software. 1859 * Unfortunately the queue contains the physical address of the TD 1860 * and we have no simple way to translate this back to a kernel address. 1861 * To make the translation possible (and fast) we use a hash table of 1862 * TDs currently in the schedule. The physical address is used as the 1863 * hash value. 1864 */ 1865 1866 #define HASH(a) (((a) >> 4) % OHCI_HASH_SIZE) 1867 /* Called at splusb() */ 1868 void 1869 ohci_hash_add_td(ohci_softc_t *sc, ohci_soft_td_t *std) 1870 { 1871 int h = HASH(std->physaddr); 1872 1873 SPLUSBCHECK; 1874 1875 LIST_INSERT_HEAD(&sc->sc_hash_tds[h], std, hnext); 1876 } 1877 1878 /* Called at splusb() */ 1879 void 1880 ohci_hash_rem_td(ohci_softc_t *sc, ohci_soft_td_t *std) 1881 { 1882 SPLUSBCHECK; 1883 1884 LIST_REMOVE(std, hnext); 1885 } 1886 1887 ohci_soft_td_t * 1888 ohci_hash_find_td(ohci_softc_t *sc, ohci_physaddr_t a) 1889 { 1890 int h = HASH(a); 1891 ohci_soft_td_t *std; 1892 1893 for (std = LIST_FIRST(&sc->sc_hash_tds[h]); 1894 std != NULL; 1895 std = LIST_NEXT(std, hnext)) 1896 if (std->physaddr == a) 1897 return (std); 1898 return (NULL); 1899 } 1900 1901 /* Called at splusb() */ 1902 void 1903 ohci_hash_add_itd(ohci_softc_t *sc, ohci_soft_itd_t *sitd) 1904 { 1905 int h = HASH(sitd->physaddr); 1906 1907 SPLUSBCHECK; 1908 1909 DPRINTFN(10,("ohci_hash_add_itd: sitd=%p physaddr=0x%08lx\n", 1910 sitd, (u_long)sitd->physaddr)); 1911 1912 LIST_INSERT_HEAD(&sc->sc_hash_itds[h], sitd, hnext); 1913 } 1914 1915 /* Called at splusb() */ 1916 void 1917 ohci_hash_rem_itd(ohci_softc_t *sc, ohci_soft_itd_t *sitd) 1918 { 1919 SPLUSBCHECK; 1920 1921 DPRINTFN(10,("ohci_hash_rem_itd: sitd=%p physaddr=0x%08lx\n", 1922 sitd, (u_long)sitd->physaddr)); 1923 1924 LIST_REMOVE(sitd, hnext); 1925 } 1926 1927 ohci_soft_itd_t * 1928 ohci_hash_find_itd(ohci_softc_t *sc, ohci_physaddr_t a) 1929 { 1930 int h = HASH(a); 1931 ohci_soft_itd_t *sitd; 1932 1933 for (sitd = LIST_FIRST(&sc->sc_hash_itds[h]); 1934 sitd != NULL; 1935 sitd = LIST_NEXT(sitd, hnext)) 1936 if (sitd->physaddr == a) 1937 return (sitd); 1938 return (NULL); 1939 } 1940 1941 void 1942 ohci_timeout(void *addr) 1943 { 1944 struct ohci_xfer *oxfer = addr; 1945 struct ohci_pipe *opipe = (struct ohci_pipe *)oxfer->xfer.pipe; 1946 ohci_softc_t *sc = opipe->pipe.device->bus->hci_private; 1947 1948 DPRINTF(("ohci_timeout: oxfer=%p\n", oxfer)); 1949 1950 if (sc->sc_dying) { 1951 ohci_abort_xfer(&oxfer->xfer, USBD_TIMEOUT); 1952 return; 1953 } 1954 1955 /* Execute the abort in a process context. */ 1956 usb_init_task(&oxfer->abort_task, ohci_timeout_task, addr); 1957 usb_add_task(oxfer->xfer.pipe->device, &oxfer->abort_task, 1958 USB_TASKQ_HC); 1959 } 1960 1961 void 1962 ohci_timeout_task(void *addr) 1963 { 1964 usbd_xfer_handle xfer = addr; 1965 int s; 1966 1967 DPRINTF(("ohci_timeout_task: xfer=%p\n", xfer)); 1968 1969 s = splusb(); 1970 ohci_abort_xfer(xfer, USBD_TIMEOUT); 1971 splx(s); 1972 } 1973 1974 #ifdef OHCI_DEBUG 1975 void 1976 ohci_dump_tds(ohci_softc_t *sc, ohci_soft_td_t *std) 1977 { 1978 for (; std; std = std->nexttd) 1979 ohci_dump_td(sc, std); 1980 } 1981 1982 void 1983 ohci_dump_td(ohci_softc_t *sc, ohci_soft_td_t *std) 1984 { 1985 char sbuf[128]; 1986 1987 usb_syncmem(&std->dma, std->offs, sizeof(std->td), 1988 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1989 snprintb(sbuf, sizeof(sbuf), 1990 "\20\23R\24OUT\25IN\31TOG1\32SETTOGGLE", 1991 (u_int32_t)O32TOH(std->td.td_flags)); 1992 printf("TD(%p) at %08lx: %s delay=%d ec=%d cc=%d\ncbp=0x%08lx " 1993 "nexttd=0x%08lx be=0x%08lx\n", 1994 std, (u_long)std->physaddr, sbuf, 1995 OHCI_TD_GET_DI(O32TOH(std->td.td_flags)), 1996 OHCI_TD_GET_EC(O32TOH(std->td.td_flags)), 1997 OHCI_TD_GET_CC(O32TOH(std->td.td_flags)), 1998 (u_long)O32TOH(std->td.td_cbp), 1999 (u_long)O32TOH(std->td.td_nexttd), 2000 (u_long)O32TOH(std->td.td_be)); 2001 } 2002 2003 void 2004 ohci_dump_itd(ohci_softc_t *sc, ohci_soft_itd_t *sitd) 2005 { 2006 int i; 2007 2008 usb_syncmem(&sitd->dma, sitd->offs, sizeof(sitd->itd), 2009 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 2010 printf("ITD(%p) at %08lx: sf=%d di=%d fc=%d cc=%d\n" 2011 "bp0=0x%08lx next=0x%08lx be=0x%08lx\n", 2012 sitd, (u_long)sitd->physaddr, 2013 OHCI_ITD_GET_SF(O32TOH(sitd->itd.itd_flags)), 2014 OHCI_ITD_GET_DI(O32TOH(sitd->itd.itd_flags)), 2015 OHCI_ITD_GET_FC(O32TOH(sitd->itd.itd_flags)), 2016 OHCI_ITD_GET_CC(O32TOH(sitd->itd.itd_flags)), 2017 (u_long)O32TOH(sitd->itd.itd_bp0), 2018 (u_long)O32TOH(sitd->itd.itd_nextitd), 2019 (u_long)O32TOH(sitd->itd.itd_be)); 2020 for (i = 0; i < OHCI_ITD_NOFFSET; i++) 2021 printf("offs[%d]=0x%04x ", i, 2022 (u_int)O16TOH(sitd->itd.itd_offset[i])); 2023 printf("\n"); 2024 } 2025 2026 void 2027 ohci_dump_itds(ohci_softc_t *sc, ohci_soft_itd_t *sitd) 2028 { 2029 for (; sitd; sitd = sitd->nextitd) 2030 ohci_dump_itd(sc, sitd); 2031 } 2032 2033 void 2034 ohci_dump_ed(ohci_softc_t *sc, ohci_soft_ed_t *sed) 2035 { 2036 char sbuf[128], sbuf2[128]; 2037 2038 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 2039 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 2040 snprintb(sbuf, sizeof(sbuf), 2041 "\20\14OUT\15IN\16LOWSPEED\17SKIP\20ISO", 2042 (u_int32_t)O32TOH(sed->ed.ed_flags)); 2043 snprintb(sbuf2, sizeof(sbuf2), "\20\1HALT\2CARRY", 2044 (u_int32_t)O32TOH(sed->ed.ed_headp)); 2045 2046 printf("ED(%p) at 0x%08lx: addr=%d endpt=%d maxp=%d flags=%s\ntailp=0x%08lx " 2047 "headflags=%s headp=0x%08lx nexted=0x%08lx\n", 2048 sed, (u_long)sed->physaddr, 2049 OHCI_ED_GET_FA(O32TOH(sed->ed.ed_flags)), 2050 OHCI_ED_GET_EN(O32TOH(sed->ed.ed_flags)), 2051 OHCI_ED_GET_MAXP(O32TOH(sed->ed.ed_flags)), sbuf, 2052 (u_long)O32TOH(sed->ed.ed_tailp), sbuf2, 2053 (u_long)O32TOH(sed->ed.ed_headp), 2054 (u_long)O32TOH(sed->ed.ed_nexted)); 2055 } 2056 #endif 2057 2058 usbd_status 2059 ohci_open(usbd_pipe_handle pipe) 2060 { 2061 usbd_device_handle dev = pipe->device; 2062 ohci_softc_t *sc = dev->bus->hci_private; 2063 usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc; 2064 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; 2065 u_int8_t addr = dev->address; 2066 u_int8_t xfertype = ed->bmAttributes & UE_XFERTYPE; 2067 ohci_soft_ed_t *sed; 2068 ohci_soft_td_t *std; 2069 ohci_soft_itd_t *sitd; 2070 ohci_physaddr_t tdphys; 2071 u_int32_t fmt; 2072 usbd_status err; 2073 int s; 2074 int ival; 2075 2076 DPRINTFN(1, ("ohci_open: pipe=%p, addr=%d, endpt=%d (%d)\n", 2077 pipe, addr, ed->bEndpointAddress, sc->sc_addr)); 2078 2079 if (sc->sc_dying) 2080 return (USBD_IOERROR); 2081 2082 std = NULL; 2083 sed = NULL; 2084 2085 if (addr == sc->sc_addr) { 2086 switch (ed->bEndpointAddress) { 2087 case USB_CONTROL_ENDPOINT: 2088 pipe->methods = &ohci_root_ctrl_methods; 2089 break; 2090 case UE_DIR_IN | OHCI_INTR_ENDPT: 2091 pipe->methods = &ohci_root_intr_methods; 2092 break; 2093 default: 2094 return (USBD_INVAL); 2095 } 2096 } else { 2097 sed = ohci_alloc_sed(sc); 2098 if (sed == NULL) 2099 goto bad0; 2100 opipe->sed = sed; 2101 if (xfertype == UE_ISOCHRONOUS) { 2102 sitd = ohci_alloc_sitd(sc); 2103 if (sitd == NULL) 2104 goto bad1; 2105 opipe->tail.itd = sitd; 2106 tdphys = sitd->physaddr; 2107 fmt = OHCI_ED_FORMAT_ISO; 2108 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) 2109 fmt |= OHCI_ED_DIR_IN; 2110 else 2111 fmt |= OHCI_ED_DIR_OUT; 2112 } else { 2113 std = ohci_alloc_std(sc); 2114 if (std == NULL) 2115 goto bad1; 2116 opipe->tail.td = std; 2117 tdphys = std->physaddr; 2118 fmt = OHCI_ED_FORMAT_GEN | OHCI_ED_DIR_TD; 2119 } 2120 sed->ed.ed_flags = HTOO32( 2121 OHCI_ED_SET_FA(addr) | 2122 OHCI_ED_SET_EN(UE_GET_ADDR(ed->bEndpointAddress)) | 2123 (dev->speed == USB_SPEED_LOW ? OHCI_ED_SPEED : 0) | 2124 fmt | 2125 OHCI_ED_SET_MAXP(UGETW(ed->wMaxPacketSize))); 2126 sed->ed.ed_headp = HTOO32(tdphys | 2127 (pipe->endpoint->datatoggle ? OHCI_TOGGLECARRY : 0)); 2128 sed->ed.ed_tailp = HTOO32(tdphys); 2129 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 2130 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2131 2132 switch (xfertype) { 2133 case UE_CONTROL: 2134 pipe->methods = &ohci_device_ctrl_methods; 2135 err = usb_allocmem(&sc->sc_bus, 2136 sizeof(usb_device_request_t), 2137 0, &opipe->u.ctl.reqdma); 2138 if (err) 2139 goto bad; 2140 s = splusb(); 2141 ohci_add_ed(sc, sed, sc->sc_ctrl_head); 2142 splx(s); 2143 break; 2144 case UE_INTERRUPT: 2145 pipe->methods = &ohci_device_intr_methods; 2146 ival = pipe->interval; 2147 if (ival == USBD_DEFAULT_INTERVAL) 2148 ival = ed->bInterval; 2149 return (ohci_device_setintr(sc, opipe, ival)); 2150 case UE_ISOCHRONOUS: 2151 pipe->methods = &ohci_device_isoc_methods; 2152 return (ohci_setup_isoc(pipe)); 2153 case UE_BULK: 2154 pipe->methods = &ohci_device_bulk_methods; 2155 s = splusb(); 2156 ohci_add_ed(sc, sed, sc->sc_bulk_head); 2157 splx(s); 2158 break; 2159 } 2160 } 2161 return (USBD_NORMAL_COMPLETION); 2162 2163 bad: 2164 if (std != NULL) 2165 ohci_free_std(sc, std); 2166 bad1: 2167 if (sed != NULL) 2168 ohci_free_sed(sc, sed); 2169 bad0: 2170 return (USBD_NOMEM); 2171 2172 } 2173 2174 /* 2175 * Close a reqular pipe. 2176 * Assumes that there are no pending transactions. 2177 */ 2178 void 2179 ohci_close_pipe(usbd_pipe_handle pipe, ohci_soft_ed_t *head) 2180 { 2181 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; 2182 ohci_softc_t *sc = pipe->device->bus->hci_private; 2183 ohci_soft_ed_t *sed = opipe->sed; 2184 int s; 2185 2186 s = splusb(); 2187 #ifdef DIAGNOSTIC 2188 sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); 2189 if ((O32TOH(sed->ed.ed_tailp) & OHCI_HEADMASK) != 2190 (O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK)) { 2191 ohci_soft_td_t *std; 2192 std = ohci_hash_find_td(sc, O32TOH(sed->ed.ed_headp)); 2193 printf("ohci_close_pipe: pipe not empty sed=%p hd=0x%x " 2194 "tl=0x%x pipe=%p, std=%p\n", sed, 2195 (int)O32TOH(sed->ed.ed_headp), 2196 (int)O32TOH(sed->ed.ed_tailp), 2197 pipe, std); 2198 #ifdef USB_DEBUG 2199 usbd_dump_pipe(&opipe->pipe); 2200 #endif 2201 #ifdef OHCI_DEBUG 2202 ohci_dump_ed(sc, sed); 2203 if (std) 2204 ohci_dump_td(sc, std); 2205 #endif 2206 usb_delay_ms(&sc->sc_bus, 2); 2207 if ((O32TOH(sed->ed.ed_tailp) & OHCI_HEADMASK) != 2208 (O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK)) 2209 printf("ohci_close_pipe: pipe still not empty\n"); 2210 } 2211 #endif 2212 ohci_rem_ed(sed, head); 2213 /* Make sure the host controller is not touching this ED */ 2214 usb_delay_ms(&sc->sc_bus, 1); 2215 pipe->endpoint->datatoggle = 2216 (O32TOH(sed->ed.ed_headp) & OHCI_TOGGLECARRY) ? 1 : 0; 2217 splx(s); 2218 ohci_free_sed(sc, opipe->sed); 2219 } 2220 2221 /* 2222 * Abort a device request. 2223 * If this routine is called at splusb() it guarantees that the request 2224 * will be removed from the hardware scheduling and that the callback 2225 * for it will be called with USBD_CANCELLED status. 2226 * It's impossible to guarantee that the requested transfer will not 2227 * have happened since the hardware runs concurrently. 2228 * If the transaction has already happened we rely on the ordinary 2229 * interrupt processing to process it. 2230 */ 2231 void 2232 ohci_abort_xfer(usbd_xfer_handle xfer, usbd_status status) 2233 { 2234 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; 2235 ohci_softc_t *sc = opipe->pipe.device->bus->hci_private; 2236 ohci_soft_ed_t *sed = opipe->sed; 2237 ohci_soft_td_t *p, *n; 2238 ohci_physaddr_t headp; 2239 int s, hit; 2240 int wake; 2241 2242 DPRINTF(("ohci_abort_xfer: xfer=%p pipe=%p sed=%p\n", xfer, opipe,sed)); 2243 2244 if (sc->sc_dying) { 2245 /* If we're dying, just do the software part. */ 2246 s = splusb(); 2247 xfer->status = status; /* make software ignore it */ 2248 callout_stop(&xfer->timeout_handle); 2249 usb_transfer_complete(xfer); 2250 splx(s); 2251 return; 2252 } 2253 2254 if (xfer->device->bus->intr_context || !curproc) 2255 panic("ohci_abort_xfer: not in process context"); 2256 2257 /* 2258 * If an abort is already in progress then just wait for it to 2259 * complete and return. 2260 */ 2261 if (xfer->hcflags & UXFER_ABORTING) { 2262 DPRINTFN(2, ("ohci_abort_xfer: already aborting\n")); 2263 #ifdef DIAGNOSTIC 2264 if (status == USBD_TIMEOUT) 2265 printf("0hci_abort_xfer: TIMEOUT while aborting\n"); 2266 #endif 2267 /* Override the status which might be USBD_TIMEOUT. */ 2268 xfer->status = status; 2269 DPRINTFN(2, ("ohci_abort_xfer: waiting for abort to finish\n")); 2270 xfer->hcflags |= UXFER_ABORTWAIT; 2271 while (xfer->hcflags & UXFER_ABORTING) 2272 tsleep(&xfer->hcflags, PZERO, "ohciaw", 0); 2273 return; 2274 } 2275 xfer->hcflags |= UXFER_ABORTING; 2276 2277 /* 2278 * Step 1: Make interrupt routine and hardware ignore xfer. 2279 */ 2280 s = splusb(); 2281 xfer->status = status; /* make software ignore it */ 2282 callout_stop(&xfer->timeout_handle); 2283 splx(s); 2284 DPRINTFN(1,("ohci_abort_xfer: stop ed=%p\n", sed)); 2285 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), 2286 sizeof(sed->ed.ed_flags), 2287 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 2288 sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); /* force hardware skip */ 2289 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), 2290 sizeof(sed->ed.ed_flags), 2291 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2292 2293 /* 2294 * Step 2: Wait until we know hardware has finished any possible 2295 * use of the xfer. Also make sure the soft interrupt routine 2296 * has run. 2297 */ 2298 usb_delay_ms(opipe->pipe.device->bus, 20); /* Hardware finishes in 1ms */ 2299 s = splusb(); 2300 #ifdef USB_USE_SOFTINTR 2301 sc->sc_softwake = 1; 2302 #endif /* USB_USE_SOFTINTR */ 2303 usb_schedsoftintr(&sc->sc_bus); 2304 #ifdef USB_USE_SOFTINTR 2305 tsleep(&sc->sc_softwake, PZERO, "ohciab", 0); 2306 #endif /* USB_USE_SOFTINTR */ 2307 splx(s); 2308 2309 /* 2310 * Step 3: Remove any vestiges of the xfer from the hardware. 2311 * The complication here is that the hardware may have executed 2312 * beyond the xfer we're trying to abort. So as we're scanning 2313 * the TDs of this xfer we check if the hardware points to 2314 * any of them. 2315 */ 2316 s = splusb(); /* XXX why? */ 2317 p = xfer->hcpriv; 2318 #ifdef DIAGNOSTIC 2319 if (p == NULL) { 2320 xfer->hcflags &= ~UXFER_ABORTING; /* XXX */ 2321 splx(s); 2322 printf("ohci_abort_xfer: hcpriv is NULL\n"); 2323 return; 2324 } 2325 #endif 2326 #ifdef OHCI_DEBUG 2327 if (ohcidebug > 1) { 2328 DPRINTF(("ohci_abort_xfer: sed=\n")); 2329 ohci_dump_ed(sc, sed); 2330 ohci_dump_tds(sc, p); 2331 } 2332 #endif 2333 headp = O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK; 2334 hit = 0; 2335 for (; p->xfer == xfer; p = n) { 2336 hit |= headp == p->physaddr; 2337 n = p->nexttd; 2338 ohci_free_std(sc, p); 2339 } 2340 /* Zap headp register if hardware pointed inside the xfer. */ 2341 if (hit) { 2342 DPRINTFN(1,("ohci_abort_xfer: set hd=0x%08x, tl=0x%08x\n", 2343 (int)p->physaddr, (int)O32TOH(sed->ed.ed_tailp))); 2344 sed->ed.ed_headp = HTOO32(p->physaddr); /* unlink TDs */ 2345 usb_syncmem(&sed->dma, 2346 sed->offs + offsetof(ohci_ed_t, ed_headp), 2347 sizeof(sed->ed.ed_headp), 2348 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2349 } else { 2350 DPRINTFN(1,("ohci_abort_xfer: no hit\n")); 2351 } 2352 2353 /* 2354 * Step 4: Turn on hardware again. 2355 */ 2356 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), 2357 sizeof(sed->ed.ed_flags), 2358 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 2359 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); /* remove hardware skip */ 2360 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), 2361 sizeof(sed->ed.ed_flags), 2362 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2363 2364 /* 2365 * Step 5: Execute callback. 2366 */ 2367 wake = xfer->hcflags & UXFER_ABORTWAIT; 2368 xfer->hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT); 2369 usb_transfer_complete(xfer); 2370 if (wake) 2371 wakeup(&xfer->hcflags); 2372 2373 splx(s); 2374 } 2375 2376 /* 2377 * Data structures and routines to emulate the root hub. 2378 */ 2379 Static usb_device_descriptor_t ohci_devd = { 2380 USB_DEVICE_DESCRIPTOR_SIZE, 2381 UDESC_DEVICE, /* type */ 2382 {0x00, 0x01}, /* USB version */ 2383 UDCLASS_HUB, /* class */ 2384 UDSUBCLASS_HUB, /* subclass */ 2385 UDPROTO_FSHUB, /* protocol */ 2386 64, /* max packet */ 2387 {0},{0},{0x00,0x01}, /* device id */ 2388 1,2,0, /* string indicies */ 2389 1 /* # of configurations */ 2390 }; 2391 2392 Static const usb_config_descriptor_t ohci_confd = { 2393 USB_CONFIG_DESCRIPTOR_SIZE, 2394 UDESC_CONFIG, 2395 {USB_CONFIG_DESCRIPTOR_SIZE + 2396 USB_INTERFACE_DESCRIPTOR_SIZE + 2397 USB_ENDPOINT_DESCRIPTOR_SIZE}, 2398 1, 2399 1, 2400 0, 2401 UC_ATTR_MBO | UC_SELF_POWERED, 2402 0 /* max power */ 2403 }; 2404 2405 Static const usb_interface_descriptor_t ohci_ifcd = { 2406 USB_INTERFACE_DESCRIPTOR_SIZE, 2407 UDESC_INTERFACE, 2408 0, 2409 0, 2410 1, 2411 UICLASS_HUB, 2412 UISUBCLASS_HUB, 2413 UIPROTO_FSHUB, 2414 0 2415 }; 2416 2417 Static const usb_endpoint_descriptor_t ohci_endpd = { 2418 .bLength = USB_ENDPOINT_DESCRIPTOR_SIZE, 2419 .bDescriptorType = UDESC_ENDPOINT, 2420 .bEndpointAddress = UE_DIR_IN | OHCI_INTR_ENDPT, 2421 .bmAttributes = UE_INTERRUPT, 2422 .wMaxPacketSize = {8, 0}, /* max packet */ 2423 .bInterval = 255, 2424 }; 2425 2426 Static const usb_hub_descriptor_t ohci_hubd = { 2427 .bDescLength = USB_HUB_DESCRIPTOR_SIZE, 2428 .bDescriptorType = UDESC_HUB, 2429 }; 2430 2431 /* 2432 * Simulate a hardware hub by handling all the necessary requests. 2433 */ 2434 Static usbd_status 2435 ohci_root_ctrl_transfer(usbd_xfer_handle xfer) 2436 { 2437 usbd_status err; 2438 2439 /* Insert last in queue. */ 2440 err = usb_insert_transfer(xfer); 2441 if (err) 2442 return (err); 2443 2444 /* Pipe isn't running, start first */ 2445 return (ohci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); 2446 } 2447 2448 Static usbd_status 2449 ohci_root_ctrl_start(usbd_xfer_handle xfer) 2450 { 2451 ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; 2452 usb_device_request_t *req; 2453 void *buf = NULL; 2454 int port, i; 2455 int s, len, value, index, l, totlen = 0; 2456 usb_port_status_t ps; 2457 usb_hub_descriptor_t hubd; 2458 usbd_status err; 2459 u_int32_t v; 2460 2461 if (sc->sc_dying) 2462 return (USBD_IOERROR); 2463 2464 #ifdef DIAGNOSTIC 2465 if (!(xfer->rqflags & URQ_REQUEST)) 2466 /* XXX panic */ 2467 return (USBD_INVAL); 2468 #endif 2469 req = &xfer->request; 2470 2471 DPRINTFN(4,("ohci_root_ctrl_control type=0x%02x request=%02x\n", 2472 req->bmRequestType, req->bRequest)); 2473 2474 len = UGETW(req->wLength); 2475 value = UGETW(req->wValue); 2476 index = UGETW(req->wIndex); 2477 2478 if (len != 0) 2479 buf = KERNADDR(&xfer->dmabuf, 0); 2480 2481 #define C(x,y) ((x) | ((y) << 8)) 2482 switch(C(req->bRequest, req->bmRequestType)) { 2483 case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE): 2484 case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE): 2485 case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT): 2486 /* 2487 * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops 2488 * for the integrated root hub. 2489 */ 2490 break; 2491 case C(UR_GET_CONFIG, UT_READ_DEVICE): 2492 if (len > 0) { 2493 *(u_int8_t *)buf = sc->sc_conf; 2494 totlen = 1; 2495 } 2496 break; 2497 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE): 2498 DPRINTFN(8,("ohci_root_ctrl_control wValue=0x%04x\n", value)); 2499 if (len == 0) 2500 break; 2501 switch(value >> 8) { 2502 case UDESC_DEVICE: 2503 if ((value & 0xff) != 0) { 2504 err = USBD_IOERROR; 2505 goto ret; 2506 } 2507 totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE); 2508 USETW(ohci_devd.idVendor, sc->sc_id_vendor); 2509 memcpy(buf, &ohci_devd, l); 2510 break; 2511 case UDESC_CONFIG: 2512 if ((value & 0xff) != 0) { 2513 err = USBD_IOERROR; 2514 goto ret; 2515 } 2516 totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE); 2517 memcpy(buf, &ohci_confd, l); 2518 buf = (char *)buf + l; 2519 len -= l; 2520 l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE); 2521 totlen += l; 2522 memcpy(buf, &ohci_ifcd, l); 2523 buf = (char *)buf + l; 2524 len -= l; 2525 l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE); 2526 totlen += l; 2527 memcpy(buf, &ohci_endpd, l); 2528 break; 2529 case UDESC_STRING: 2530 #define sd ((usb_string_descriptor_t *)buf) 2531 switch (value & 0xff) { 2532 case 0: /* Language table */ 2533 totlen = usb_makelangtbl(sd, len); 2534 break; 2535 case 1: /* Vendor */ 2536 totlen = usb_makestrdesc(sd, len, 2537 sc->sc_vendor); 2538 break; 2539 case 2: /* Product */ 2540 totlen = usb_makestrdesc(sd, len, 2541 "OHCI root hub"); 2542 break; 2543 } 2544 #undef sd 2545 break; 2546 default: 2547 err = USBD_IOERROR; 2548 goto ret; 2549 } 2550 break; 2551 case C(UR_GET_INTERFACE, UT_READ_INTERFACE): 2552 if (len > 0) { 2553 *(u_int8_t *)buf = 0; 2554 totlen = 1; 2555 } 2556 break; 2557 case C(UR_GET_STATUS, UT_READ_DEVICE): 2558 if (len > 1) { 2559 USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED); 2560 totlen = 2; 2561 } 2562 break; 2563 case C(UR_GET_STATUS, UT_READ_INTERFACE): 2564 case C(UR_GET_STATUS, UT_READ_ENDPOINT): 2565 if (len > 1) { 2566 USETW(((usb_status_t *)buf)->wStatus, 0); 2567 totlen = 2; 2568 } 2569 break; 2570 case C(UR_SET_ADDRESS, UT_WRITE_DEVICE): 2571 if (value >= USB_MAX_DEVICES) { 2572 err = USBD_IOERROR; 2573 goto ret; 2574 } 2575 sc->sc_addr = value; 2576 break; 2577 case C(UR_SET_CONFIG, UT_WRITE_DEVICE): 2578 if (value != 0 && value != 1) { 2579 err = USBD_IOERROR; 2580 goto ret; 2581 } 2582 sc->sc_conf = value; 2583 break; 2584 case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE): 2585 break; 2586 case C(UR_SET_FEATURE, UT_WRITE_DEVICE): 2587 case C(UR_SET_FEATURE, UT_WRITE_INTERFACE): 2588 case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT): 2589 err = USBD_IOERROR; 2590 goto ret; 2591 case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE): 2592 break; 2593 case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT): 2594 break; 2595 /* Hub requests */ 2596 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE): 2597 break; 2598 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER): 2599 DPRINTFN(8, ("ohci_root_ctrl_control: UR_CLEAR_PORT_FEATURE " 2600 "port=%d feature=%d\n", 2601 index, value)); 2602 if (index < 1 || index > sc->sc_noport) { 2603 err = USBD_IOERROR; 2604 goto ret; 2605 } 2606 port = OHCI_RH_PORT_STATUS(index); 2607 switch(value) { 2608 case UHF_PORT_ENABLE: 2609 OWRITE4(sc, port, UPS_CURRENT_CONNECT_STATUS); 2610 break; 2611 case UHF_PORT_SUSPEND: 2612 OWRITE4(sc, port, UPS_OVERCURRENT_INDICATOR); 2613 break; 2614 case UHF_PORT_POWER: 2615 /* Yes, writing to the LOW_SPEED bit clears power. */ 2616 OWRITE4(sc, port, UPS_LOW_SPEED); 2617 break; 2618 case UHF_C_PORT_CONNECTION: 2619 OWRITE4(sc, port, UPS_C_CONNECT_STATUS << 16); 2620 break; 2621 case UHF_C_PORT_ENABLE: 2622 OWRITE4(sc, port, UPS_C_PORT_ENABLED << 16); 2623 break; 2624 case UHF_C_PORT_SUSPEND: 2625 OWRITE4(sc, port, UPS_C_SUSPEND << 16); 2626 break; 2627 case UHF_C_PORT_OVER_CURRENT: 2628 OWRITE4(sc, port, UPS_C_OVERCURRENT_INDICATOR << 16); 2629 break; 2630 case UHF_C_PORT_RESET: 2631 OWRITE4(sc, port, UPS_C_PORT_RESET << 16); 2632 break; 2633 default: 2634 err = USBD_IOERROR; 2635 goto ret; 2636 } 2637 switch(value) { 2638 case UHF_C_PORT_CONNECTION: 2639 case UHF_C_PORT_ENABLE: 2640 case UHF_C_PORT_SUSPEND: 2641 case UHF_C_PORT_OVER_CURRENT: 2642 case UHF_C_PORT_RESET: 2643 /* Enable RHSC interrupt if condition is cleared. */ 2644 if ((OREAD4(sc, port) >> 16) == 0) 2645 ohci_rhsc_enable(sc); 2646 break; 2647 default: 2648 break; 2649 } 2650 break; 2651 case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE): 2652 if (len == 0) 2653 break; 2654 if ((value & 0xff) != 0) { 2655 err = USBD_IOERROR; 2656 goto ret; 2657 } 2658 v = OREAD4(sc, OHCI_RH_DESCRIPTOR_A); 2659 hubd = ohci_hubd; 2660 hubd.bNbrPorts = sc->sc_noport; 2661 USETW(hubd.wHubCharacteristics, 2662 (v & OHCI_NPS ? UHD_PWR_NO_SWITCH : 2663 v & OHCI_PSM ? UHD_PWR_GANGED : UHD_PWR_INDIVIDUAL) 2664 /* XXX overcurrent */ 2665 ); 2666 hubd.bPwrOn2PwrGood = OHCI_GET_POTPGT(v); 2667 v = OREAD4(sc, OHCI_RH_DESCRIPTOR_B); 2668 for (i = 0, l = sc->sc_noport; l > 0; i++, l -= 8, v >>= 8) 2669 hubd.DeviceRemovable[i++] = (u_int8_t)v; 2670 hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE + i; 2671 l = min(len, hubd.bDescLength); 2672 totlen = l; 2673 memcpy(buf, &hubd, l); 2674 break; 2675 case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE): 2676 if (len != 4) { 2677 err = USBD_IOERROR; 2678 goto ret; 2679 } 2680 memset(buf, 0, len); /* ? XXX */ 2681 totlen = len; 2682 break; 2683 case C(UR_GET_STATUS, UT_READ_CLASS_OTHER): 2684 DPRINTFN(8,("ohci_root_ctrl_transfer: get port status i=%d\n", 2685 index)); 2686 if (index < 1 || index > sc->sc_noport) { 2687 err = USBD_IOERROR; 2688 goto ret; 2689 } 2690 if (len != 4) { 2691 err = USBD_IOERROR; 2692 goto ret; 2693 } 2694 v = OREAD4(sc, OHCI_RH_PORT_STATUS(index)); 2695 DPRINTFN(8,("ohci_root_ctrl_transfer: port status=0x%04x\n", 2696 v)); 2697 USETW(ps.wPortStatus, v); 2698 USETW(ps.wPortChange, v >> 16); 2699 l = min(len, sizeof ps); 2700 memcpy(buf, &ps, l); 2701 totlen = l; 2702 break; 2703 case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE): 2704 err = USBD_IOERROR; 2705 goto ret; 2706 case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE): 2707 break; 2708 case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER): 2709 if (index < 1 || index > sc->sc_noport) { 2710 err = USBD_IOERROR; 2711 goto ret; 2712 } 2713 port = OHCI_RH_PORT_STATUS(index); 2714 switch(value) { 2715 case UHF_PORT_ENABLE: 2716 OWRITE4(sc, port, UPS_PORT_ENABLED); 2717 break; 2718 case UHF_PORT_SUSPEND: 2719 OWRITE4(sc, port, UPS_SUSPEND); 2720 break; 2721 case UHF_PORT_RESET: 2722 DPRINTFN(5,("ohci_root_ctrl_transfer: reset port %d\n", 2723 index)); 2724 OWRITE4(sc, port, UPS_RESET); 2725 for (i = 0; i < 5; i++) { 2726 usb_delay_ms(&sc->sc_bus, 2727 USB_PORT_ROOT_RESET_DELAY); 2728 if (sc->sc_dying) { 2729 err = USBD_IOERROR; 2730 goto ret; 2731 } 2732 if ((OREAD4(sc, port) & UPS_RESET) == 0) 2733 break; 2734 } 2735 DPRINTFN(8,("ohci port %d reset, status = 0x%04x\n", 2736 index, OREAD4(sc, port))); 2737 break; 2738 case UHF_PORT_POWER: 2739 DPRINTFN(2,("ohci_root_ctrl_transfer: set port power " 2740 "%d\n", index)); 2741 OWRITE4(sc, port, UPS_PORT_POWER); 2742 break; 2743 default: 2744 err = USBD_IOERROR; 2745 goto ret; 2746 } 2747 break; 2748 default: 2749 err = USBD_IOERROR; 2750 goto ret; 2751 } 2752 xfer->actlen = totlen; 2753 err = USBD_NORMAL_COMPLETION; 2754 ret: 2755 xfer->status = err; 2756 s = splusb(); 2757 usb_transfer_complete(xfer); 2758 splx(s); 2759 return (USBD_IN_PROGRESS); 2760 } 2761 2762 /* Abort a root control request. */ 2763 Static void 2764 ohci_root_ctrl_abort(usbd_xfer_handle xfer) 2765 { 2766 /* Nothing to do, all transfers are synchronous. */ 2767 } 2768 2769 /* Close the root pipe. */ 2770 Static void 2771 ohci_root_ctrl_close(usbd_pipe_handle pipe) 2772 { 2773 DPRINTF(("ohci_root_ctrl_close\n")); 2774 /* Nothing to do. */ 2775 } 2776 2777 Static usbd_status 2778 ohci_root_intr_transfer(usbd_xfer_handle xfer) 2779 { 2780 usbd_status err; 2781 2782 /* Insert last in queue. */ 2783 err = usb_insert_transfer(xfer); 2784 if (err) 2785 return (err); 2786 2787 /* Pipe isn't running, start first */ 2788 return (ohci_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); 2789 } 2790 2791 Static usbd_status 2792 ohci_root_intr_start(usbd_xfer_handle xfer) 2793 { 2794 usbd_pipe_handle pipe = xfer->pipe; 2795 ohci_softc_t *sc = pipe->device->bus->hci_private; 2796 2797 if (sc->sc_dying) 2798 return (USBD_IOERROR); 2799 2800 sc->sc_intrxfer = xfer; 2801 2802 return (USBD_IN_PROGRESS); 2803 } 2804 2805 /* Abort a root interrupt request. */ 2806 Static void 2807 ohci_root_intr_abort(usbd_xfer_handle xfer) 2808 { 2809 int s; 2810 2811 if (xfer->pipe->intrxfer == xfer) { 2812 DPRINTF(("ohci_root_intr_abort: remove\n")); 2813 xfer->pipe->intrxfer = NULL; 2814 } 2815 xfer->status = USBD_CANCELLED; 2816 s = splusb(); 2817 usb_transfer_complete(xfer); 2818 splx(s); 2819 } 2820 2821 /* Close the root pipe. */ 2822 Static void 2823 ohci_root_intr_close(usbd_pipe_handle pipe) 2824 { 2825 ohci_softc_t *sc = pipe->device->bus->hci_private; 2826 2827 DPRINTF(("ohci_root_intr_close\n")); 2828 2829 sc->sc_intrxfer = NULL; 2830 } 2831 2832 /************************/ 2833 2834 Static usbd_status 2835 ohci_device_ctrl_transfer(usbd_xfer_handle xfer) 2836 { 2837 usbd_status err; 2838 2839 /* Insert last in queue. */ 2840 err = usb_insert_transfer(xfer); 2841 if (err) 2842 return (err); 2843 2844 /* Pipe isn't running, start first */ 2845 return (ohci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); 2846 } 2847 2848 Static usbd_status 2849 ohci_device_ctrl_start(usbd_xfer_handle xfer) 2850 { 2851 ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; 2852 usbd_status err; 2853 2854 if (sc->sc_dying) 2855 return (USBD_IOERROR); 2856 2857 #ifdef DIAGNOSTIC 2858 if (!(xfer->rqflags & URQ_REQUEST)) { 2859 /* XXX panic */ 2860 printf("ohci_device_ctrl_transfer: not a request\n"); 2861 return (USBD_INVAL); 2862 } 2863 #endif 2864 2865 err = ohci_device_request(xfer); 2866 if (err) 2867 return (err); 2868 2869 if (sc->sc_bus.use_polling) 2870 ohci_waitintr(sc, xfer); 2871 return (USBD_IN_PROGRESS); 2872 } 2873 2874 /* Abort a device control request. */ 2875 Static void 2876 ohci_device_ctrl_abort(usbd_xfer_handle xfer) 2877 { 2878 DPRINTF(("ohci_device_ctrl_abort: xfer=%p\n", xfer)); 2879 ohci_abort_xfer(xfer, USBD_CANCELLED); 2880 } 2881 2882 /* Close a device control pipe. */ 2883 Static void 2884 ohci_device_ctrl_close(usbd_pipe_handle pipe) 2885 { 2886 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; 2887 ohci_softc_t *sc = pipe->device->bus->hci_private; 2888 2889 DPRINTF(("ohci_device_ctrl_close: pipe=%p\n", pipe)); 2890 ohci_close_pipe(pipe, sc->sc_ctrl_head); 2891 ohci_free_std(sc, opipe->tail.td); 2892 } 2893 2894 /************************/ 2895 2896 Static void 2897 ohci_device_clear_toggle(usbd_pipe_handle pipe) 2898 { 2899 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; 2900 ohci_softc_t *sc = pipe->device->bus->hci_private; 2901 2902 opipe->sed->ed.ed_headp &= HTOO32(~OHCI_TOGGLECARRY); 2903 } 2904 2905 Static void 2906 ohci_noop(usbd_pipe_handle pipe) 2907 { 2908 } 2909 2910 Static usbd_status 2911 ohci_device_bulk_transfer(usbd_xfer_handle xfer) 2912 { 2913 usbd_status err; 2914 2915 /* Insert last in queue. */ 2916 err = usb_insert_transfer(xfer); 2917 if (err) 2918 return (err); 2919 2920 /* Pipe isn't running, start first */ 2921 return (ohci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); 2922 } 2923 2924 Static usbd_status 2925 ohci_device_bulk_start(usbd_xfer_handle xfer) 2926 { 2927 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; 2928 usbd_device_handle dev = opipe->pipe.device; 2929 ohci_softc_t *sc = dev->bus->hci_private; 2930 int addr = dev->address; 2931 ohci_soft_td_t *data, *tail, *tdp; 2932 ohci_soft_ed_t *sed; 2933 int s, len, isread, endpt; 2934 usbd_status err; 2935 2936 if (sc->sc_dying) 2937 return (USBD_IOERROR); 2938 2939 #ifdef DIAGNOSTIC 2940 if (xfer->rqflags & URQ_REQUEST) { 2941 /* XXX panic */ 2942 printf("ohci_device_bulk_start: a request\n"); 2943 return (USBD_INVAL); 2944 } 2945 #endif 2946 2947 len = xfer->length; 2948 endpt = xfer->pipe->endpoint->edesc->bEndpointAddress; 2949 isread = UE_GET_DIR(endpt) == UE_DIR_IN; 2950 sed = opipe->sed; 2951 2952 DPRINTFN(4,("ohci_device_bulk_start: xfer=%p len=%d isread=%d " 2953 "flags=%d endpt=%d\n", xfer, len, isread, xfer->flags, 2954 endpt)); 2955 2956 opipe->u.bulk.isread = isread; 2957 opipe->u.bulk.length = len; 2958 2959 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 2960 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 2961 /* Update device address */ 2962 sed->ed.ed_flags = HTOO32( 2963 (O32TOH(sed->ed.ed_flags) & ~OHCI_ED_ADDRMASK) | 2964 OHCI_ED_SET_FA(addr)); 2965 2966 /* Allocate a chain of new TDs (including a new tail). */ 2967 data = opipe->tail.td; 2968 err = ohci_alloc_std_chain(opipe, sc, len, isread, xfer, 2969 data, &tail); 2970 /* We want interrupt at the end of the transfer. */ 2971 tail->td.td_flags &= HTOO32(~OHCI_TD_INTR_MASK); 2972 tail->td.td_flags |= HTOO32(OHCI_TD_SET_DI(1)); 2973 tail->flags |= OHCI_CALL_DONE; 2974 tail = tail->nexttd; /* point at sentinel */ 2975 usb_syncmem(&tail->dma, tail->offs + offsetof(ohci_td_t, td_flags), 2976 sizeof(tail->td.td_flags), 2977 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2978 if (err) 2979 return (err); 2980 2981 tail->xfer = NULL; 2982 xfer->hcpriv = data; 2983 2984 DPRINTFN(4,("ohci_device_bulk_start: ed_flags=0x%08x td_flags=0x%08x " 2985 "td_cbp=0x%08x td_be=0x%08x\n", 2986 (int)O32TOH(sed->ed.ed_flags), 2987 (int)O32TOH(data->td.td_flags), 2988 (int)O32TOH(data->td.td_cbp), 2989 (int)O32TOH(data->td.td_be))); 2990 2991 #ifdef OHCI_DEBUG 2992 if (ohcidebug > 5) { 2993 ohci_dump_ed(sc, sed); 2994 ohci_dump_tds(sc, data); 2995 } 2996 #endif 2997 2998 /* Insert ED in schedule */ 2999 s = splusb(); 3000 for (tdp = data; tdp != tail; tdp = tdp->nexttd) { 3001 tdp->xfer = xfer; 3002 } 3003 sed->ed.ed_tailp = HTOO32(tail->physaddr); 3004 opipe->tail.td = tail; 3005 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); 3006 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 3007 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3008 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF); 3009 if (xfer->timeout && !sc->sc_bus.use_polling) { 3010 callout_reset(&xfer->timeout_handle, mstohz(xfer->timeout), 3011 ohci_timeout, xfer); 3012 } 3013 3014 #if 0 3015 /* This goes wrong if we are too slow. */ 3016 if (ohcidebug > 10) { 3017 delay(10000); 3018 DPRINTF(("ohci_device_intr_transfer: status=%x\n", 3019 OREAD4(sc, OHCI_COMMAND_STATUS))); 3020 ohci_dump_ed(sc, sed); 3021 ohci_dump_tds(sc, data); 3022 } 3023 #endif 3024 3025 splx(s); 3026 3027 return (USBD_IN_PROGRESS); 3028 } 3029 3030 Static void 3031 ohci_device_bulk_abort(usbd_xfer_handle xfer) 3032 { 3033 DPRINTF(("ohci_device_bulk_abort: xfer=%p\n", xfer)); 3034 ohci_abort_xfer(xfer, USBD_CANCELLED); 3035 } 3036 3037 /* 3038 * Close a device bulk pipe. 3039 */ 3040 Static void 3041 ohci_device_bulk_close(usbd_pipe_handle pipe) 3042 { 3043 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; 3044 ohci_softc_t *sc = pipe->device->bus->hci_private; 3045 3046 DPRINTF(("ohci_device_bulk_close: pipe=%p\n", pipe)); 3047 ohci_close_pipe(pipe, sc->sc_bulk_head); 3048 ohci_free_std(sc, opipe->tail.td); 3049 } 3050 3051 /************************/ 3052 3053 Static usbd_status 3054 ohci_device_intr_transfer(usbd_xfer_handle xfer) 3055 { 3056 usbd_status err; 3057 3058 /* Insert last in queue. */ 3059 err = usb_insert_transfer(xfer); 3060 if (err) 3061 return (err); 3062 3063 /* Pipe isn't running, start first */ 3064 return (ohci_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); 3065 } 3066 3067 Static usbd_status 3068 ohci_device_intr_start(usbd_xfer_handle xfer) 3069 { 3070 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; 3071 usbd_device_handle dev = opipe->pipe.device; 3072 ohci_softc_t *sc = dev->bus->hci_private; 3073 ohci_soft_ed_t *sed = opipe->sed; 3074 ohci_soft_td_t *data, *tail; 3075 int s, len, isread, endpt; 3076 3077 if (sc->sc_dying) 3078 return (USBD_IOERROR); 3079 3080 DPRINTFN(3, ("ohci_device_intr_transfer: xfer=%p len=%d " 3081 "flags=%d priv=%p\n", 3082 xfer, xfer->length, xfer->flags, xfer->priv)); 3083 3084 #ifdef DIAGNOSTIC 3085 if (xfer->rqflags & URQ_REQUEST) 3086 panic("ohci_device_intr_transfer: a request"); 3087 #endif 3088 3089 len = xfer->length; 3090 endpt = xfer->pipe->endpoint->edesc->bEndpointAddress; 3091 isread = UE_GET_DIR(endpt) == UE_DIR_IN; 3092 3093 data = opipe->tail.td; 3094 tail = ohci_alloc_std(sc); 3095 if (tail == NULL) 3096 return (USBD_NOMEM); 3097 tail->xfer = NULL; 3098 3099 data->td.td_flags = HTOO32( 3100 isread ? OHCI_TD_IN : OHCI_TD_OUT | 3101 OHCI_TD_NOCC | 3102 OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY); 3103 if (xfer->flags & USBD_SHORT_XFER_OK) 3104 data->td.td_flags |= HTOO32(OHCI_TD_R); 3105 data->td.td_cbp = HTOO32(DMAADDR(&xfer->dmabuf, 0)); 3106 data->nexttd = tail; 3107 data->td.td_nexttd = HTOO32(tail->physaddr); 3108 data->td.td_be = HTOO32(O32TOH(data->td.td_cbp) + len - 1); 3109 data->len = len; 3110 data->xfer = xfer; 3111 data->flags = OHCI_CALL_DONE | OHCI_ADD_LEN; 3112 usb_syncmem(&data->dma, data->offs, sizeof(data->td), 3113 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3114 xfer->hcpriv = data; 3115 3116 #ifdef OHCI_DEBUG 3117 if (ohcidebug > 5) { 3118 DPRINTF(("ohci_device_intr_transfer:\n")); 3119 ohci_dump_ed(sc, sed); 3120 ohci_dump_tds(sc, data); 3121 } 3122 #endif 3123 3124 /* Insert ED in schedule */ 3125 s = splusb(); 3126 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 3127 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 3128 sed->ed.ed_tailp = HTOO32(tail->physaddr); 3129 opipe->tail.td = tail; 3130 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); 3131 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 3132 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3133 3134 #if 0 3135 /* 3136 * This goes horribly wrong, printing thousands of descriptors, 3137 * because false references are followed due to the fact that the 3138 * TD is gone. 3139 */ 3140 if (ohcidebug > 5) { 3141 usb_delay_ms(&sc->sc_bus, 5); 3142 DPRINTF(("ohci_device_intr_transfer: status=%x\n", 3143 OREAD4(sc, OHCI_COMMAND_STATUS))); 3144 ohci_dump_ed(sc, sed); 3145 ohci_dump_tds(sc, data); 3146 } 3147 #endif 3148 splx(s); 3149 3150 return (USBD_IN_PROGRESS); 3151 } 3152 3153 /* Abort a device control request. */ 3154 Static void 3155 ohci_device_intr_abort(usbd_xfer_handle xfer) 3156 { 3157 if (xfer->pipe->intrxfer == xfer) { 3158 DPRINTF(("ohci_device_intr_abort: remove\n")); 3159 xfer->pipe->intrxfer = NULL; 3160 } 3161 ohci_abort_xfer(xfer, USBD_CANCELLED); 3162 } 3163 3164 /* Close a device interrupt pipe. */ 3165 Static void 3166 ohci_device_intr_close(usbd_pipe_handle pipe) 3167 { 3168 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; 3169 ohci_softc_t *sc = pipe->device->bus->hci_private; 3170 int nslots = opipe->u.intr.nslots; 3171 int pos = opipe->u.intr.pos; 3172 int j; 3173 ohci_soft_ed_t *p, *sed = opipe->sed; 3174 int s; 3175 3176 DPRINTFN(1,("ohci_device_intr_close: pipe=%p nslots=%d pos=%d\n", 3177 pipe, nslots, pos)); 3178 s = splusb(); 3179 usb_syncmem(&sed->dma, sed->offs, 3180 sizeof(sed->ed), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 3181 sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); 3182 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), 3183 sizeof(sed->ed.ed_flags), 3184 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3185 if ((O32TOH(sed->ed.ed_tailp) & OHCI_HEADMASK) != 3186 (O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK)) 3187 usb_delay_ms(&sc->sc_bus, 2); 3188 3189 for (p = sc->sc_eds[pos]; p && p->next != sed; p = p->next) 3190 continue; 3191 #ifdef DIAGNOSTIC 3192 if (p == NULL) 3193 panic("ohci_device_intr_close: ED not found"); 3194 #endif 3195 p->next = sed->next; 3196 p->ed.ed_nexted = sed->ed.ed_nexted; 3197 usb_syncmem(&p->dma, p->offs + offsetof(ohci_ed_t, ed_nexted), 3198 sizeof(p->ed.ed_nexted), 3199 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3200 splx(s); 3201 3202 for (j = 0; j < nslots; j++) 3203 --sc->sc_bws[(pos * nslots + j) % OHCI_NO_INTRS]; 3204 3205 ohci_free_std(sc, opipe->tail.td); 3206 ohci_free_sed(sc, opipe->sed); 3207 } 3208 3209 Static usbd_status 3210 ohci_device_setintr(ohci_softc_t *sc, struct ohci_pipe *opipe, int ival) 3211 { 3212 int i, j, s, best; 3213 u_int npoll, slow, shigh, nslots; 3214 u_int bestbw, bw; 3215 ohci_soft_ed_t *hsed, *sed = opipe->sed; 3216 3217 DPRINTFN(2, ("ohci_setintr: pipe=%p\n", opipe)); 3218 if (ival == 0) { 3219 printf("ohci_setintr: 0 interval\n"); 3220 return (USBD_INVAL); 3221 } 3222 3223 npoll = OHCI_NO_INTRS; 3224 while (npoll > ival) 3225 npoll /= 2; 3226 DPRINTFN(2, ("ohci_setintr: ival=%d npoll=%d\n", ival, npoll)); 3227 3228 /* 3229 * We now know which level in the tree the ED must go into. 3230 * Figure out which slot has most bandwidth left over. 3231 * Slots to examine: 3232 * npoll 3233 * 1 0 3234 * 2 1 2 3235 * 4 3 4 5 6 3236 * 8 7 8 9 10 11 12 13 14 3237 * N (N-1) .. (N-1+N-1) 3238 */ 3239 slow = npoll-1; 3240 shigh = slow + npoll; 3241 nslots = OHCI_NO_INTRS / npoll; 3242 for (best = i = slow, bestbw = ~0; i < shigh; i++) { 3243 bw = 0; 3244 for (j = 0; j < nslots; j++) 3245 bw += sc->sc_bws[(i * nslots + j) % OHCI_NO_INTRS]; 3246 if (bw < bestbw) { 3247 best = i; 3248 bestbw = bw; 3249 } 3250 } 3251 DPRINTFN(2, ("ohci_setintr: best=%d(%d..%d) bestbw=%d\n", 3252 best, slow, shigh, bestbw)); 3253 3254 s = splusb(); 3255 hsed = sc->sc_eds[best]; 3256 sed->next = hsed->next; 3257 usb_syncmem(&hsed->dma, hsed->offs + offsetof(ohci_ed_t, ed_flags), 3258 sizeof(hsed->ed.ed_flags), 3259 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 3260 sed->ed.ed_nexted = hsed->ed.ed_nexted; 3261 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), 3262 sizeof(sed->ed.ed_flags), 3263 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3264 hsed->next = sed; 3265 hsed->ed.ed_nexted = HTOO32(sed->physaddr); 3266 usb_syncmem(&hsed->dma, hsed->offs + offsetof(ohci_ed_t, ed_flags), 3267 sizeof(hsed->ed.ed_flags), 3268 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3269 splx(s); 3270 3271 for (j = 0; j < nslots; j++) 3272 ++sc->sc_bws[(best * nslots + j) % OHCI_NO_INTRS]; 3273 opipe->u.intr.nslots = nslots; 3274 opipe->u.intr.pos = best; 3275 3276 DPRINTFN(5, ("ohci_setintr: returns %p\n", opipe)); 3277 return (USBD_NORMAL_COMPLETION); 3278 } 3279 3280 /***********************/ 3281 3282 usbd_status 3283 ohci_device_isoc_transfer(usbd_xfer_handle xfer) 3284 { 3285 usbd_status err; 3286 3287 DPRINTFN(5,("ohci_device_isoc_transfer: xfer=%p\n", xfer)); 3288 3289 /* Put it on our queue, */ 3290 err = usb_insert_transfer(xfer); 3291 3292 /* bail out on error, */ 3293 if (err && err != USBD_IN_PROGRESS) 3294 return (err); 3295 3296 /* XXX should check inuse here */ 3297 3298 /* insert into schedule, */ 3299 ohci_device_isoc_enter(xfer); 3300 3301 /* and start if the pipe wasn't running */ 3302 if (!err) 3303 ohci_device_isoc_start(SIMPLEQ_FIRST(&xfer->pipe->queue)); 3304 3305 return (err); 3306 } 3307 3308 void 3309 ohci_device_isoc_enter(usbd_xfer_handle xfer) 3310 { 3311 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; 3312 usbd_device_handle dev = opipe->pipe.device; 3313 ohci_softc_t *sc = dev->bus->hci_private; 3314 ohci_soft_ed_t *sed = opipe->sed; 3315 struct iso *iso = &opipe->u.iso; 3316 ohci_soft_itd_t *sitd, *nsitd; 3317 ohci_physaddr_t buf, offs, noffs, bp0; 3318 int i, ncur, nframes; 3319 int s; 3320 3321 DPRINTFN(1,("ohci_device_isoc_enter: used=%d next=%d xfer=%p " 3322 "nframes=%d\n", 3323 iso->inuse, iso->next, xfer, xfer->nframes)); 3324 3325 if (sc->sc_dying) 3326 return; 3327 3328 if (iso->next == -1) { 3329 /* Not in use yet, schedule it a few frames ahead. */ 3330 iso->next = O32TOH(sc->sc_hcca->hcca_frame_number) + 5; 3331 DPRINTFN(2,("ohci_device_isoc_enter: start next=%d\n", 3332 iso->next)); 3333 } 3334 3335 sitd = opipe->tail.itd; 3336 buf = DMAADDR(&xfer->dmabuf, 0); 3337 bp0 = OHCI_PAGE(buf); 3338 offs = OHCI_PAGE_OFFSET(buf); 3339 nframes = xfer->nframes; 3340 xfer->hcpriv = sitd; 3341 for (i = ncur = 0; i < nframes; i++, ncur++) { 3342 noffs = offs + xfer->frlengths[i]; 3343 if (ncur == OHCI_ITD_NOFFSET || /* all offsets used */ 3344 OHCI_PAGE(buf + noffs) > bp0 + OHCI_PAGE_SIZE) { /* too many page crossings */ 3345 3346 /* Allocate next ITD */ 3347 nsitd = ohci_alloc_sitd(sc); 3348 if (nsitd == NULL) { 3349 /* XXX what now? */ 3350 printf("%s: isoc TD alloc failed\n", 3351 device_xname(sc->sc_dev)); 3352 return; 3353 } 3354 3355 /* Fill current ITD */ 3356 sitd->itd.itd_flags = HTOO32( 3357 OHCI_ITD_NOCC | 3358 OHCI_ITD_SET_SF(iso->next) | 3359 OHCI_ITD_SET_DI(6) | /* delay intr a little */ 3360 OHCI_ITD_SET_FC(ncur)); 3361 sitd->itd.itd_bp0 = HTOO32(bp0); 3362 sitd->nextitd = nsitd; 3363 sitd->itd.itd_nextitd = HTOO32(nsitd->physaddr); 3364 sitd->itd.itd_be = HTOO32(bp0 + offs - 1); 3365 sitd->xfer = xfer; 3366 sitd->flags = 0; 3367 usb_syncmem(&sitd->dma, sitd->offs, sizeof(sitd->itd), 3368 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3369 3370 sitd = nsitd; 3371 iso->next = iso->next + ncur; 3372 bp0 = OHCI_PAGE(buf + offs); 3373 ncur = 0; 3374 } 3375 sitd->itd.itd_offset[ncur] = HTOO16(OHCI_ITD_MK_OFFS(offs)); 3376 offs = noffs; 3377 } 3378 nsitd = ohci_alloc_sitd(sc); 3379 if (nsitd == NULL) { 3380 /* XXX what now? */ 3381 printf("%s: isoc TD alloc failed\n", 3382 device_xname(sc->sc_dev)); 3383 return; 3384 } 3385 /* Fixup last used ITD */ 3386 sitd->itd.itd_flags = HTOO32( 3387 OHCI_ITD_NOCC | 3388 OHCI_ITD_SET_SF(iso->next) | 3389 OHCI_ITD_SET_DI(0) | 3390 OHCI_ITD_SET_FC(ncur)); 3391 sitd->itd.itd_bp0 = HTOO32(bp0); 3392 sitd->nextitd = nsitd; 3393 sitd->itd.itd_nextitd = HTOO32(nsitd->physaddr); 3394 sitd->itd.itd_be = HTOO32(bp0 + offs - 1); 3395 sitd->xfer = xfer; 3396 sitd->flags = OHCI_CALL_DONE; 3397 usb_syncmem(&sitd->dma, sitd->offs, sizeof(sitd->itd), 3398 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3399 3400 iso->next = iso->next + ncur; 3401 iso->inuse += nframes; 3402 3403 xfer->actlen = offs; /* XXX pretend we did it all */ 3404 3405 xfer->status = USBD_IN_PROGRESS; 3406 3407 #ifdef OHCI_DEBUG 3408 if (ohcidebug > 5) { 3409 DPRINTF(("ohci_device_isoc_enter: frame=%d\n", 3410 O32TOH(sc->sc_hcca->hcca_frame_number))); 3411 ohci_dump_itds(sc, xfer->hcpriv); 3412 ohci_dump_ed(sc, sed); 3413 } 3414 #endif 3415 3416 s = splusb(); 3417 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 3418 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 3419 sed->ed.ed_tailp = HTOO32(nsitd->physaddr); 3420 opipe->tail.itd = nsitd; 3421 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); 3422 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), 3423 sizeof(sed->ed.ed_flags), 3424 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3425 splx(s); 3426 3427 #ifdef OHCI_DEBUG 3428 if (ohcidebug > 5) { 3429 delay(150000); 3430 DPRINTF(("ohci_device_isoc_enter: after frame=%d\n", 3431 O32TOH(sc->sc_hcca->hcca_frame_number))); 3432 ohci_dump_itds(sc, xfer->hcpriv); 3433 ohci_dump_ed(sc, sed); 3434 } 3435 #endif 3436 } 3437 3438 usbd_status 3439 ohci_device_isoc_start(usbd_xfer_handle xfer) 3440 { 3441 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; 3442 ohci_softc_t *sc = opipe->pipe.device->bus->hci_private; 3443 3444 DPRINTFN(5,("ohci_device_isoc_start: xfer=%p\n", xfer)); 3445 3446 if (sc->sc_dying) 3447 return (USBD_IOERROR); 3448 3449 #ifdef DIAGNOSTIC 3450 if (xfer->status != USBD_IN_PROGRESS) 3451 printf("ohci_device_isoc_start: not in progress %p\n", xfer); 3452 #endif 3453 3454 /* XXX anything to do? */ 3455 3456 return (USBD_IN_PROGRESS); 3457 } 3458 3459 void 3460 ohci_device_isoc_abort(usbd_xfer_handle xfer) 3461 { 3462 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; 3463 ohci_softc_t *sc = opipe->pipe.device->bus->hci_private; 3464 ohci_soft_ed_t *sed; 3465 ohci_soft_itd_t *sitd; 3466 int s; 3467 3468 s = splusb(); 3469 3470 DPRINTFN(1,("ohci_device_isoc_abort: xfer=%p\n", xfer)); 3471 3472 /* Transfer is already done. */ 3473 if (xfer->status != USBD_NOT_STARTED && 3474 xfer->status != USBD_IN_PROGRESS) { 3475 splx(s); 3476 printf("ohci_device_isoc_abort: early return\n"); 3477 return; 3478 } 3479 3480 /* Give xfer the requested abort code. */ 3481 xfer->status = USBD_CANCELLED; 3482 3483 sed = opipe->sed; 3484 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 3485 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 3486 sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); /* force hardware skip */ 3487 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), 3488 sizeof(sed->ed.ed_flags), 3489 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3490 3491 sitd = xfer->hcpriv; 3492 #ifdef DIAGNOSTIC 3493 if (sitd == NULL) { 3494 splx(s); 3495 printf("ohci_device_isoc_abort: hcpriv==0\n"); 3496 return; 3497 } 3498 #endif 3499 for (; sitd->xfer == xfer; sitd = sitd->nextitd) { 3500 #ifdef DIAGNOSTIC 3501 DPRINTFN(1,("abort sets done sitd=%p\n", sitd)); 3502 sitd->isdone = 1; 3503 #endif 3504 } 3505 3506 splx(s); 3507 3508 usb_delay_ms(&sc->sc_bus, OHCI_ITD_NOFFSET); 3509 3510 s = splusb(); 3511 3512 /* Run callback. */ 3513 usb_transfer_complete(xfer); 3514 3515 sed->ed.ed_headp = HTOO32(sitd->physaddr); /* unlink TDs */ 3516 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); /* remove hardware skip */ 3517 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 3518 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3519 3520 splx(s); 3521 } 3522 3523 void 3524 ohci_device_isoc_done(usbd_xfer_handle xfer) 3525 { 3526 DPRINTFN(1,("ohci_device_isoc_done: xfer=%p\n", xfer)); 3527 } 3528 3529 usbd_status 3530 ohci_setup_isoc(usbd_pipe_handle pipe) 3531 { 3532 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; 3533 ohci_softc_t *sc = pipe->device->bus->hci_private; 3534 struct iso *iso = &opipe->u.iso; 3535 int s; 3536 3537 iso->next = -1; 3538 iso->inuse = 0; 3539 3540 s = splusb(); 3541 ohci_add_ed(sc, opipe->sed, sc->sc_isoc_head); 3542 splx(s); 3543 3544 return (USBD_NORMAL_COMPLETION); 3545 } 3546 3547 void 3548 ohci_device_isoc_close(usbd_pipe_handle pipe) 3549 { 3550 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; 3551 ohci_softc_t *sc = pipe->device->bus->hci_private; 3552 3553 DPRINTF(("ohci_device_isoc_close: pipe=%p\n", pipe)); 3554 ohci_close_pipe(pipe, sc->sc_isoc_head); 3555 #ifdef DIAGNOSTIC 3556 opipe->tail.itd->isdone = 1; 3557 #endif 3558 ohci_free_sitd(sc, opipe->tail.itd); 3559 } 3560