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