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