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