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