1 /* $NetBSD: ahci.c,v 1.5 2008/12/16 22:35:24 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 2007 Ruslan Ermilov and Vsevolod Lobko. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or 8 * without modification, are permitted provided that the following 9 * conditions are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above 13 * copyright notice, this list of conditions and the following 14 * disclaimer in the documentation and/or other materials provided 15 * with the distribution. 16 * 3. The names of the authors may not be used to endorse or promote 17 * products derived from this software without specific prior 18 * written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY 21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 23 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 25 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 27 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 29 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 30 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 31 * OF SUCH DAMAGE. 32 */ 33 /* 34 * Copyright (c) 2001 The NetBSD Foundation, Inc. 35 * All rights reserved. 36 * 37 * This code is derived from software contributed to The NetBSD Foundation 38 * by Tetsuya Isaki. 39 * 40 * Redistribution and use in source and binary forms, with or without 41 * modification, are permitted provided that the following conditions 42 * are met: 43 * 1. Redistributions of source code must retain the above copyright 44 * notice, this list of conditions and the following disclaimer. 45 * 2. Redistributions in binary form must reproduce the above copyright 46 * notice, this list of conditions and the following disclaimer in the 47 * documentation and/or other materials provided with the distribution. 48 * 49 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 50 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 51 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 52 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 53 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 54 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 55 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 56 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 57 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 58 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 59 * POSSIBILITY OF SUCH DAMAGE. 60 */ 61 62 /* 63 * !! HIGHLY EXPERIMENTAL CODE !! 64 */ 65 66 #include <sys/cdefs.h> 67 __KERNEL_RCSID(0, "$NetBSD: ahci.c,v 1.5 2008/12/16 22:35:24 christos Exp $"); 68 69 #include <sys/param.h> 70 #include <sys/systm.h> 71 #include <sys/kernel.h> 72 #include <sys/proc.h> 73 #include <sys/device.h> 74 #include <sys/malloc.h> 75 76 #include <machine/bus.h> 77 #include <machine/cpu.h> 78 79 #include <dev/usb/usb.h> 80 #include <dev/usb/usbdi.h> 81 #include <dev/usb/usbdivar.h> 82 #include <dev/usb/usb_mem.h> 83 #include <dev/usb/usbdevs.h> 84 85 #include <mips/adm5120/include/adm5120reg.h> 86 #include <mips/adm5120/include/adm5120var.h> 87 #include <mips/adm5120/include/adm5120_obiovar.h> 88 89 #include <mips/adm5120/dev/ahcireg.h> 90 #include <mips/adm5120/dev/ahcivar.h> 91 92 static usbd_status ahci_open(usbd_pipe_handle); 93 static void ahci_softintr(void *); 94 static void ahci_poll(struct usbd_bus *); 95 static void ahci_poll_hub(void *); 96 static void ahci_poll_device(void *arg); 97 static usbd_status ahci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t); 98 static void ahci_freem(struct usbd_bus *, usb_dma_t *); 99 static usbd_xfer_handle ahci_allocx(struct usbd_bus *); 100 static void ahci_freex(struct usbd_bus *, usbd_xfer_handle); 101 102 static int ahci_str(usb_string_descriptor_t *, int, const char *); 103 104 static usbd_status ahci_root_ctrl_transfer(usbd_xfer_handle); 105 static usbd_status ahci_root_ctrl_start(usbd_xfer_handle); 106 static void ahci_root_ctrl_abort(usbd_xfer_handle); 107 static void ahci_root_ctrl_close(usbd_pipe_handle); 108 static void ahci_root_ctrl_done(usbd_xfer_handle); 109 110 static usbd_status ahci_root_intr_transfer(usbd_xfer_handle); 111 static usbd_status ahci_root_intr_start(usbd_xfer_handle); 112 static void ahci_root_intr_abort(usbd_xfer_handle); 113 static void ahci_root_intr_close(usbd_pipe_handle); 114 static void ahci_root_intr_done(usbd_xfer_handle); 115 116 static usbd_status ahci_device_ctrl_transfer(usbd_xfer_handle); 117 static usbd_status ahci_device_ctrl_start(usbd_xfer_handle); 118 static void ahci_device_ctrl_abort(usbd_xfer_handle); 119 static void ahci_device_ctrl_close(usbd_pipe_handle); 120 static void ahci_device_ctrl_done(usbd_xfer_handle); 121 122 static usbd_status ahci_device_intr_transfer(usbd_xfer_handle); 123 static usbd_status ahci_device_intr_start(usbd_xfer_handle); 124 static void ahci_device_intr_abort(usbd_xfer_handle); 125 static void ahci_device_intr_close(usbd_pipe_handle); 126 static void ahci_device_intr_done(usbd_xfer_handle); 127 128 static usbd_status ahci_device_isoc_transfer(usbd_xfer_handle); 129 static usbd_status ahci_device_isoc_start(usbd_xfer_handle); 130 static void ahci_device_isoc_abort(usbd_xfer_handle); 131 static void ahci_device_isoc_close(usbd_pipe_handle); 132 static void ahci_device_isoc_done(usbd_xfer_handle); 133 134 static usbd_status ahci_device_bulk_transfer(usbd_xfer_handle); 135 static usbd_status ahci_device_bulk_start(usbd_xfer_handle); 136 static void ahci_device_bulk_abort(usbd_xfer_handle); 137 static void ahci_device_bulk_close(usbd_pipe_handle); 138 static void ahci_device_bulk_done(usbd_xfer_handle); 139 140 static int ahci_transaction(struct ahci_softc *, 141 usbd_pipe_handle, u_int8_t, int, u_char *, u_int8_t); 142 static void ahci_noop(usbd_pipe_handle); 143 static void ahci_abort_xfer(usbd_xfer_handle, usbd_status); 144 static void ahci_device_clear_toggle(usbd_pipe_handle); 145 146 extern int usbdebug; 147 extern int uhubdebug; 148 extern int umassdebug; 149 int ahci_dummy; 150 151 #define AHCI_DEBUG 152 153 /* For root hub */ 154 #define AHCI_INTR_ENDPT (1) 155 156 #ifdef AHCI_DEBUG 157 #define D_TRACE (0x0001) /* function trace */ 158 #define D_MSG (0x0002) /* debug messages */ 159 #define D_XFER (0x0004) /* transfer messages (noisy!) */ 160 #define D_MEM (0x0008) /* memory allocation */ 161 162 int ahci_debug = 0; 163 #define DPRINTF(z,x) if((ahci_debug&(z))!=0)printf x 164 void print_req(usb_device_request_t *); 165 void print_req_hub(usb_device_request_t *); 166 void print_dumpreg(struct ahci_softc *); 167 void print_xfer(usbd_xfer_handle); 168 #else 169 #define DPRINTF(z,x) 170 #endif 171 172 173 struct usbd_bus_methods ahci_bus_methods = { 174 ahci_open, 175 ahci_softintr, 176 ahci_poll, 177 ahci_allocm, 178 ahci_freem, 179 ahci_allocx, 180 ahci_freex, 181 }; 182 183 struct usbd_pipe_methods ahci_root_ctrl_methods = { 184 ahci_root_ctrl_transfer, 185 ahci_root_ctrl_start, 186 ahci_root_ctrl_abort, 187 ahci_root_ctrl_close, 188 ahci_noop, 189 ahci_root_ctrl_done, 190 }; 191 192 struct usbd_pipe_methods ahci_root_intr_methods = { 193 ahci_root_intr_transfer, 194 ahci_root_intr_start, 195 ahci_root_intr_abort, 196 ahci_root_intr_close, 197 ahci_noop, 198 ahci_root_intr_done, 199 }; 200 201 struct usbd_pipe_methods ahci_device_ctrl_methods = { 202 ahci_device_ctrl_transfer, 203 ahci_device_ctrl_start, 204 ahci_device_ctrl_abort, 205 ahci_device_ctrl_close, 206 ahci_noop, 207 ahci_device_ctrl_done, 208 }; 209 210 struct usbd_pipe_methods ahci_device_intr_methods = { 211 ahci_device_intr_transfer, 212 ahci_device_intr_start, 213 ahci_device_intr_abort, 214 ahci_device_intr_close, 215 ahci_device_clear_toggle, 216 ahci_device_intr_done, 217 }; 218 219 struct usbd_pipe_methods ahci_device_isoc_methods = { 220 ahci_device_isoc_transfer, 221 ahci_device_isoc_start, 222 ahci_device_isoc_abort, 223 ahci_device_isoc_close, 224 ahci_noop, 225 ahci_device_isoc_done, 226 }; 227 228 struct usbd_pipe_methods ahci_device_bulk_methods = { 229 ahci_device_bulk_transfer, 230 ahci_device_bulk_start, 231 ahci_device_bulk_abort, 232 ahci_device_bulk_close, 233 ahci_device_clear_toggle, 234 ahci_device_bulk_done, 235 }; 236 237 struct ahci_pipe { 238 struct usbd_pipe pipe; 239 u_int32_t toggle; 240 }; 241 242 static int ahci_match(device_t, struct cfdata *, void *); 243 static void ahci_attach(device_t, device_t, void *); 244 245 CFATTACH_DECL(ahci, sizeof(struct ahci_softc), 246 ahci_match, ahci_attach, NULL, NULL); 247 248 static int 249 ahci_match(device_t parent, struct cfdata *cf, void *aux) 250 { 251 struct obio_attach_args *aa = aux; 252 253 if (strcmp(aa->oba_name, cf->cf_name) == 0) 254 return (1); 255 256 return (0); 257 } 258 259 #define REG_READ(o) bus_space_read_4(sc->sc_st, sc->sc_ioh, (o)) 260 #define REG_WRITE(o,v) bus_space_write_4(sc->sc_st, sc->sc_ioh, (o),(v)) 261 262 /* 263 * Attach SL11H/SL811HS. Return 0 if success. 264 */ 265 void 266 ahci_attach(device_t parent, device_t self, void *aux) 267 { 268 struct obio_attach_args *aa = aux; 269 struct ahci_softc *sc = device_private(self); 270 271 printf("\n"); 272 sc->sc_dmat = aa->oba_dt; 273 sc->sc_st = aa->oba_st; 274 275 /* Initialize sc */ 276 sc->sc_bus.usbrev = USBREV_1_1; 277 sc->sc_bus.methods = &ahci_bus_methods; 278 sc->sc_bus.pipe_size = sizeof(struct ahci_pipe); 279 sc->sc_bus.dmatag = sc->sc_dmat; 280 sc->busy = 0; 281 282 /* Map the device. */ 283 if (bus_space_map(sc->sc_st, aa->oba_addr, 284 512, 0, &sc->sc_ioh) != 0) { 285 aprint_error_dev(self, "unable to map device\n"); 286 return; 287 } 288 289 /* Hook up the interrupt handler. */ 290 sc->sc_ih = adm5120_intr_establish(aa->oba_irq, INTR_IRQ, ahci_intr, sc); 291 292 if (sc->sc_ih == NULL) { 293 aprint_error_dev(self, 294 "unable to register interrupt handler\n"); 295 return; 296 } 297 298 SIMPLEQ_INIT(&sc->sc_free_xfers); 299 300 usb_callout_init(sc->sc_poll_handle); 301 302 REG_WRITE(ADMHCD_REG_INTENABLE, 0); /* disable interrupts */ 303 REG_WRITE(ADMHCD_REG_CONTROL, ADMHCD_SW_RESET); /* reset */ 304 delay_ms(10); 305 while (REG_READ(ADMHCD_REG_CONTROL) & ADMHCD_SW_RESET) 306 delay_ms(1); 307 308 REG_WRITE(ADMHCD_REG_CONTROL, ADMHCD_HOST_EN); 309 REG_WRITE(ADMHCD_REG_HOSTHEAD, 0x00000000); 310 REG_WRITE(ADMHCD_REG_FMINTERVAL, 0x20002edf); 311 REG_WRITE(ADMHCD_REG_LSTHRESH, 0x628); 312 REG_WRITE(ADMHCD_REG_RHDESCR, ADMHCD_NPS | ADMHCD_LPSC); 313 REG_WRITE(ADMHCD_REG_HOSTCONTROL, ADMHCD_STATE_OP); 314 315 REG_WRITE(ADMHCD_REG_INTENABLE, 0); /* XXX: enable interrupts */ 316 317 #ifdef USB_DEBUG 318 /* usbdebug = 0x7f; 319 uhubdebug = 0x7f; 320 umassdebug = 0xffffffff; */ 321 #endif 322 323 /* Attach USB devices */ 324 sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint); 325 326 } 327 328 int 329 ahci_intr(void *arg) 330 { 331 #if 0 332 struct ahci_softc *sc = arg; 333 u_int8_t r; 334 #ifdef AHCI_DEBUG 335 char bitbuf[256]; 336 #endif 337 338 r = sl11read(sc, SL11_ISR); 339 340 sl11write(sc, SL11_ISR, SL11_ISR_DATA | SL11_ISR_SOFTIMER); 341 342 if ((r & SL11_ISR_RESET)) { 343 sc->sc_flags |= AHCDF_RESET; 344 sl11write(sc, SL11_ISR, SL11_ISR_RESET); 345 } 346 if ((r & SL11_ISR_INSERT)) { 347 sc->sc_flags |= AHCDF_INSERT; 348 sl11write(sc, SL11_ISR, SL11_ISR_INSERT); 349 } 350 351 #ifdef AHCI_DEBUG 352 snprintb(bitbuf, sizeof(bitbuf), 353 ((sl11read(sc, SL11_CTRL) & SL11_CTRL_SUSPEND) 354 ? "\20\x8""D+\7RESUME\6INSERT\5SOF\4res\3""BABBLE\2USBB\1USBA" 355 : "\20\x8""D+\7RESET\6INSERT\5SOF\4res\3""BABBLE\2USBB\1USBA"), 356 r); 357 358 DPRINTF(D_XFER, ("I=%s ", bitbuf)); 359 #endif /* AHCI_DEBUG */ 360 #endif 361 362 return 0; 363 } 364 365 usbd_status 366 ahci_open(usbd_pipe_handle pipe) 367 { 368 usbd_device_handle dev = pipe->device; 369 struct ahci_softc *sc = (struct ahci_softc *)dev->bus; 370 struct ahci_pipe *apipe = (struct ahci_pipe *)pipe; 371 usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc; 372 373 DPRINTF(D_TRACE, ("ahci_open(addr=%d,ep=%d,scaddr=%d)", 374 dev->address, ed->bEndpointAddress, sc->sc_addr)); 375 376 apipe->toggle=0; 377 378 if (dev->address == sc->sc_addr) { 379 switch (ed->bEndpointAddress) { 380 case USB_CONTROL_ENDPOINT: 381 pipe->methods = &ahci_root_ctrl_methods; 382 break; 383 case UE_DIR_IN | AHCI_INTR_ENDPT: 384 pipe->methods = &ahci_root_intr_methods; 385 break; 386 default: 387 printf("open:endpointErr!\n"); 388 return USBD_INVAL; 389 } 390 } else { 391 switch (ed->bmAttributes & UE_XFERTYPE) { 392 case UE_CONTROL: 393 DPRINTF(D_MSG, ("control ")); 394 pipe->methods = &ahci_device_ctrl_methods; 395 break; 396 case UE_INTERRUPT: 397 DPRINTF(D_MSG, ("interrupt ")); 398 pipe->methods = &ahci_device_intr_methods; 399 break; 400 case UE_ISOCHRONOUS: 401 DPRINTF(D_MSG, ("isochronous ")); 402 pipe->methods = &ahci_device_isoc_methods; 403 break; 404 case UE_BULK: 405 DPRINTF(D_MSG, ("bluk ")); 406 pipe->methods = &ahci_device_bulk_methods; 407 break; 408 } 409 } 410 return USBD_NORMAL_COMPLETION; 411 } 412 413 void 414 ahci_softintr(void *arg) 415 { 416 DPRINTF(D_TRACE, ("%s()", __func__)); 417 } 418 419 void 420 ahci_poll(struct usbd_bus *bus) 421 { 422 DPRINTF(D_TRACE, ("%s()", __func__)); 423 } 424 425 /* 426 * Emulation of interrupt transfer for status change endpoint 427 * of root hub. 428 */ 429 void 430 ahci_poll_hub(void *arg) 431 { 432 usbd_xfer_handle xfer = arg; 433 usbd_pipe_handle pipe = xfer->pipe; 434 struct ahci_softc *sc = (struct ahci_softc *)pipe->device->bus; 435 int s; 436 u_char *p; 437 static int p0_state=0; 438 static int p1_state=0; 439 440 usb_callout(sc->sc_poll_handle, sc->sc_interval, ahci_poll_hub, xfer); 441 442 /* USB spec 11.13.3 (p.260) */ 443 p = KERNADDR(&xfer->dmabuf, 0); 444 p[0] = 0; 445 if ((REG_READ(ADMHCD_REG_PORTSTATUS0) & ADMHCD_CCS) != p0_state) { 446 p[0] = 2; 447 DPRINTF(D_TRACE, ("!")); 448 p0_state=(REG_READ(ADMHCD_REG_PORTSTATUS0) & ADMHCD_CCS); 449 }; 450 if ((REG_READ(ADMHCD_REG_PORTSTATUS1) & ADMHCD_CCS) != p1_state) { 451 p[0] = 2; 452 DPRINTF(D_TRACE, ("@")); 453 p1_state=(REG_READ(ADMHCD_REG_PORTSTATUS1) & ADMHCD_CCS); 454 }; 455 456 /* no change, return NAK */ 457 if (p[0] == 0) 458 return; 459 460 xfer->actlen = 1; 461 xfer->status = USBD_NORMAL_COMPLETION; 462 s = splusb(); 463 xfer->device->bus->intr_context++; 464 usb_transfer_complete(xfer); 465 xfer->device->bus->intr_context--; 466 splx(s); 467 } 468 469 usbd_status 470 ahci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size) 471 { 472 struct ahci_softc *sc = (struct ahci_softc *)bus; 473 474 DPRINTF(D_MEM, ("SLallocm")); 475 return usb_allocmem(&sc->sc_bus, size, 0, dma); 476 } 477 478 void 479 ahci_freem(struct usbd_bus *bus, usb_dma_t *dma) 480 { 481 struct ahci_softc *sc = (struct ahci_softc *)bus; 482 483 DPRINTF(D_MEM, ("SLfreem")); 484 usb_freemem(&sc->sc_bus, dma); 485 } 486 487 usbd_xfer_handle 488 ahci_allocx(struct usbd_bus *bus) 489 { 490 struct ahci_softc *sc = (struct ahci_softc *)bus; 491 usbd_xfer_handle xfer; 492 493 DPRINTF(D_MEM, ("SLallocx")); 494 495 xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers); 496 if (xfer) { 497 SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next); 498 #ifdef DIAGNOSTIC 499 if (xfer->busy_free != XFER_FREE) { 500 printf("ahci_allocx: xfer=%p not free, 0x%08x\n", 501 xfer, xfer->busy_free); 502 } 503 #endif 504 } else { 505 xfer = malloc(sizeof(*xfer), M_USB, M_NOWAIT); 506 } 507 508 if (xfer) { 509 memset(xfer, 0, sizeof(*xfer)); 510 #ifdef DIAGNOSTIC 511 xfer->busy_free = XFER_BUSY; 512 #endif 513 } 514 515 return xfer; 516 } 517 518 void 519 ahci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer) 520 { 521 struct ahci_softc *sc = (struct ahci_softc *)bus; 522 523 DPRINTF(D_MEM, ("SLfreex")); 524 525 #ifdef DIAGNOSTIC 526 if (xfer->busy_free != XFER_BUSY) { 527 printf("ahci_freex: xfer=%p not busy, 0x%08x\n", 528 xfer, xfer->busy_free); 529 return; 530 } 531 xfer->busy_free = XFER_FREE; 532 #endif 533 SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next); 534 } 535 536 void 537 ahci_noop(usbd_pipe_handle pipe) 538 { 539 DPRINTF(D_TRACE, ("%s()", __func__)); 540 } 541 542 /* 543 * Data structures and routines to emulate the root hub. 544 */ 545 usb_device_descriptor_t ahci_devd = { 546 USB_DEVICE_DESCRIPTOR_SIZE, 547 UDESC_DEVICE, /* type */ 548 {0x01, 0x01}, /* USB version */ 549 UDCLASS_HUB, /* class */ 550 UDSUBCLASS_HUB, /* subclass */ 551 0, /* protocol */ 552 64, /* max packet */ 553 {USB_VENDOR_SCANLOGIC & 0xff, /* vendor ID (low) */ 554 USB_VENDOR_SCANLOGIC >> 8 }, /* vendor ID (high) */ 555 {0} /* ? */, /* product ID */ 556 {0}, /* device */ 557 1, /* index to manufacturer */ 558 2, /* index to product */ 559 0, /* index to serial number */ 560 1 /* number of configurations */ 561 }; 562 563 usb_config_descriptor_t ahci_confd = { 564 USB_CONFIG_DESCRIPTOR_SIZE, 565 UDESC_CONFIG, 566 {USB_CONFIG_DESCRIPTOR_SIZE + 567 USB_INTERFACE_DESCRIPTOR_SIZE + 568 USB_ENDPOINT_DESCRIPTOR_SIZE}, 569 1, /* number of interfaces */ 570 1, /* configuration value */ 571 0, /* index to configuration */ 572 UC_SELF_POWERED, /* attributes */ 573 250 /* max current is 500mA... */ 574 }; 575 576 usb_interface_descriptor_t ahci_ifcd = { 577 USB_INTERFACE_DESCRIPTOR_SIZE, 578 UDESC_INTERFACE, 579 0, /* interface number */ 580 0, /* alternate setting */ 581 1, /* number of endpoint */ 582 UICLASS_HUB, /* class */ 583 UISUBCLASS_HUB, /* subclass */ 584 0, /* protocol */ 585 0 /* index to interface */ 586 }; 587 588 usb_endpoint_descriptor_t ahci_endpd = { 589 USB_ENDPOINT_DESCRIPTOR_SIZE, 590 UDESC_ENDPOINT, 591 UE_DIR_IN | AHCI_INTR_ENDPT, /* endpoint address */ 592 UE_INTERRUPT, /* attributes */ 593 {8}, /* max packet size */ 594 255 /* interval */ 595 }; 596 597 usb_hub_descriptor_t ahci_hubd = { 598 USB_HUB_DESCRIPTOR_SIZE, 599 UDESC_HUB, 600 2, /* number of ports */ 601 { 0, 0}, /* hub characteristics */ 602 0, /* 5:power on to power good */ 603 0, /* 6:maximum current */ 604 { 0x00 }, /* both ports are removable */ 605 { 0x00 } /* port power control mask */ 606 }; 607 608 static int 609 ahci_str(usb_string_descriptor_t *p, int l, const char *s) 610 { 611 int i; 612 613 if (l == 0) 614 return 0; 615 p->bLength = 2 * strlen(s) + 2; 616 if (l == 1) 617 return 1; 618 p->bDescriptorType = UDESC_STRING; 619 l -= 2; 620 for (i = 0; s[i] && l > 1; i++, l -= 2) 621 USETW2(p->bString[i], 0, s[i]); 622 return 2 * i + 2; 623 } 624 625 usbd_status 626 ahci_root_ctrl_transfer(usbd_xfer_handle xfer) 627 { 628 usbd_status error; 629 630 DPRINTF(D_TRACE, ("SLRCtrans ")); 631 632 /* Insert last in queue */ 633 error = usb_insert_transfer(xfer); 634 if (error) { 635 DPRINTF(D_MSG, ("usb_insert_transfer returns err! ")); 636 return error; 637 } 638 639 /* 640 * Pipe isn't running (otherwise error would be USBD_INPROG), 641 * so start it first. 642 */ 643 return ahci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)); 644 } 645 646 usbd_status 647 ahci_root_ctrl_start(usbd_xfer_handle xfer) 648 { 649 struct ahci_softc *sc = (struct ahci_softc *)xfer->pipe->device->bus; 650 usb_device_request_t *req; 651 int len, value, index, l, s, status; 652 int totlen = 0; 653 void *buf = NULL; 654 usb_port_status_t ps; 655 usbd_status error; 656 657 658 DPRINTF(D_TRACE, ("SLRCstart ")); 659 660 req = &xfer->request; 661 662 len = UGETW(req->wLength); 663 value = UGETW(req->wValue); 664 index = UGETW(req->wIndex); 665 666 if (len) 667 buf = KERNADDR(&xfer->dmabuf, 0); 668 669 #ifdef AHCI_DEBUG 670 if ((ahci_debug & D_TRACE)) 671 print_req_hub(req); 672 #endif 673 674 #define C(x,y) ((x) | ((y) << 8)) 675 switch (C(req->bRequest, req->bmRequestType)) { 676 case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE): 677 DPRINTF(D_MSG, ("UR_CLEAR_FEATURE(DEVICE)XXX ")); 678 break; 679 case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE): 680 DPRINTF(D_MSG, ("UR_CLEAR_FEATURE(INTERFACE)XXX ")); 681 break; 682 case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT): 683 DPRINTF(D_MSG, ("UR_CLEAR_FEATURE(ENDPOINT)XXX ")); 684 break; 685 case C(UR_GET_CONFIG, UT_READ_DEVICE): 686 DPRINTF(D_MSG, ("UR_GET_CONFIG ")); 687 if (len > 0) { 688 *(u_int8_t *)buf = sc->sc_conf; 689 totlen = 1; 690 } 691 break; 692 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE): 693 switch (value >> 8) { 694 case UDESC_DEVICE: 695 DPRINTF(D_MSG, ("UDESC_DEVICE ")); 696 if ((value & 0xff) != 0) { 697 error = USBD_IOERROR; 698 goto ret; 699 } 700 totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE); 701 memcpy(buf, &ahci_devd, l); 702 break; 703 case UDESC_CONFIG: 704 DPRINTF(D_MSG, ("UDESC_CONFIG ")); 705 if ((value & 0xff) != 0) { 706 error = USBD_IOERROR; 707 goto ret; 708 } 709 totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE); 710 memcpy(buf, &ahci_confd, l); 711 buf = (char *)buf + l; 712 len -= l; 713 714 l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE); 715 totlen += l; 716 memcpy(buf, &ahci_ifcd, l); 717 buf = (char *)buf + l; 718 len -= l; 719 720 l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE); 721 totlen += l; 722 memcpy(buf, &ahci_endpd, l); 723 break; 724 case UDESC_STRING: 725 DPRINTF(D_MSG, ("UDESC_STR ")); 726 if (len == 0) 727 break; 728 *(u_int8_t *)buf = 0; 729 totlen = 1; 730 switch (value & 0xff) { 731 case 0: 732 break; 733 case 1: /* Vendor */ 734 totlen = ahci_str(buf, len, "ADMTek"); 735 break; 736 case 2: /* Product */ 737 totlen = ahci_str(buf, len, "ADM5120 root hub"); 738 break; 739 default: 740 printf("strerr%d ", value & 0xff); 741 break; 742 } 743 break; 744 default: 745 printf("unknownGetDescriptor=%x", value); 746 error = USBD_IOERROR; 747 break; 748 } 749 break; 750 case C(UR_GET_INTERFACE, UT_READ_INTERFACE): 751 /* Get Interface, 9.4.4 */ 752 if (len > 0) { 753 *(u_int8_t *)buf = 0; 754 totlen = 1; 755 } 756 break; 757 case C(UR_GET_STATUS, UT_READ_DEVICE): 758 /* Get Status from device, 9.4.5 */ 759 if (len > 1) { 760 USETW(((usb_status_t *)buf)->wStatus, UDS_SELF_POWERED); 761 totlen = 2; 762 } 763 break; 764 case C(UR_GET_STATUS, UT_READ_INTERFACE): 765 case C(UR_GET_STATUS, UT_READ_ENDPOINT): 766 /* Get Status from interface, endpoint, 9.4.5 */ 767 if (len > 1) { 768 USETW(((usb_status_t *)buf)->wStatus, 0); 769 totlen = 2; 770 } 771 break; 772 case C(UR_SET_ADDRESS, UT_WRITE_DEVICE): 773 /* Set Address, 9.4.6 */ 774 DPRINTF(D_MSG, ("UR_SET_ADDRESS ")); 775 if (value >= USB_MAX_DEVICES) { 776 error = USBD_IOERROR; 777 goto ret; 778 } 779 sc->sc_addr = value; 780 break; 781 case C(UR_SET_CONFIG, UT_WRITE_DEVICE): 782 /* Set Configuration, 9.4.7 */ 783 DPRINTF(D_MSG, ("UR_SET_CONFIG ")); 784 if (value != 0 && value != 1) { 785 error = USBD_IOERROR; 786 goto ret; 787 } 788 sc->sc_conf = value; 789 break; 790 case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE): 791 /* Set Descriptor, 9.4.8, not supported */ 792 DPRINTF(D_MSG, ("UR_SET_DESCRIPTOR,WRITE_DEVICE not supported\n")); 793 break; 794 case C(UR_SET_FEATURE, UT_WRITE_DEVICE): 795 case C(UR_SET_FEATURE, UT_WRITE_INTERFACE): 796 case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT): 797 /* Set Feature, 9.4.9, not supported */ 798 DPRINTF(D_MSG, ("UR_SET_FEATURE not supported\n")); 799 error = USBD_IOERROR; 800 break; 801 case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE): 802 /* Set Interface, 9.4.10, not supported */ 803 break; 804 case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT): 805 /* Synch Frame, 9.4.11, not supported */ 806 break; 807 808 /* 809 * Hub specific requests 810 */ 811 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE): 812 /* Clear Hub Feature, 11.16.2.1, not supported */ 813 DPRINTF(D_MSG, ("ClearHubFeature not supported\n")); 814 break; 815 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER): 816 817 #define WPS(x) REG_WRITE(ADMHCD_REG_PORTSTATUS0+(index-1)*4, (x)) 818 /* Clear Port Feature, 11.16.2.2 */ 819 if (index != 1 && index != 2 ) { 820 error = USBD_IOERROR; 821 goto ret; 822 } 823 switch (value) { 824 case UHF_PORT_POWER: 825 DPRINTF(D_MSG, ("POWER_OFF ")); 826 WPS(ADMHCD_LSDA); 827 break; 828 case UHF_PORT_SUSPEND: 829 DPRINTF(D_MSG, ("SUSPEND ")); 830 WPS(ADMHCD_POCI); 831 break; 832 case UHF_PORT_ENABLE: 833 DPRINTF(D_MSG, ("ENABLE ")); 834 WPS(ADMHCD_CCS); 835 break; 836 case UHF_C_PORT_CONNECTION: 837 WPS(ADMHCD_CSC); 838 break; 839 case UHF_C_PORT_RESET: 840 WPS(ADMHCD_PRSC); 841 break; 842 case UHF_C_PORT_SUSPEND: 843 WPS(ADMHCD_PSSC); 844 break; 845 case UHF_C_PORT_ENABLE: 846 WPS(ADMHCD_PESC); 847 break; 848 case UHF_C_PORT_OVER_CURRENT: 849 WPS(ADMHCD_OCIC); 850 break; 851 default: 852 printf("ClrPortFeatERR:value=0x%x ", value); 853 error = USBD_IOERROR; 854 break; 855 } 856 //DPRINTF(D_XFER, ("CH=%04x ", sc->sc_change)); 857 #undef WPS 858 break; 859 case C(UR_GET_BUS_STATE, UT_READ_CLASS_OTHER): 860 /* Get Bus State, 11.16.2.3, not supported */ 861 /* shall return a STALL... */ 862 break; 863 case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE): 864 /* Get Hub Descriptor, 11.16.2.4 */ 865 DPRINTF(D_MSG, ("UR_GET_DESCRIPTOR RCD")); 866 if ((value&0xff) != 0) { 867 error = USBD_IOERROR; 868 goto ret; 869 } 870 l = min(len, USB_HUB_DESCRIPTOR_SIZE); 871 totlen = l; 872 memcpy(buf, &ahci_hubd, l); 873 break; 874 case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE): 875 /* Get Hub Status, 11.16.2.5 */ 876 DPRINTF(D_MSG, ("UR_GET_STATUS RCD")); 877 if (len != 4) { 878 error = USBD_IOERROR; 879 goto ret; 880 } 881 memset(buf, 0, len); 882 totlen = len; 883 break; 884 case C(UR_GET_STATUS, UT_READ_CLASS_OTHER): 885 /* Get Port Status, 11.16.2.6 */ 886 if ((index != 1 && index != 2) || len != 4) { 887 printf("index=%d,len=%d ", index, len); 888 error = USBD_IOERROR; 889 goto ret; 890 } 891 status = REG_READ(ADMHCD_REG_PORTSTATUS0+(index-1)*4); 892 DPRINTF(D_MSG, ("UR_GET_STATUS RCO=%x ", status)); 893 894 //DPRINTF(D_XFER, ("ST=%04x,CH=%04x ", status, sc->sc_change)); 895 USETW(ps.wPortStatus, status & (UPS_CURRENT_CONNECT_STATUS|UPS_PORT_ENABLED|UPS_SUSPEND|UPS_OVERCURRENT_INDICATOR|UPS_RESET|UPS_PORT_POWER|UPS_LOW_SPEED)); 896 USETW(ps.wPortChange, (status>>16) & (UPS_C_CONNECT_STATUS|UPS_C_PORT_ENABLED|UPS_C_SUSPEND|UPS_C_OVERCURRENT_INDICATOR|UPS_C_PORT_RESET)); 897 l = min(len, sizeof(ps)); 898 memcpy(buf, &ps, l); 899 totlen = l; 900 break; 901 case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE): 902 /* Set Hub Descriptor, 11.16.2.7, not supported */ 903 /* STALL ? */ 904 error = USBD_IOERROR; 905 break; 906 case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE): 907 /* Set Hub Feature, 11.16.2.8, not supported */ 908 break; 909 case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER): 910 #define WPS(x) REG_WRITE(ADMHCD_REG_PORTSTATUS0+(index-1)*4, (x)) 911 /* Set Port Feature, 11.16.2.9 */ 912 if ((index != 1) && (index !=2)) { 913 printf("index=%d ", index); 914 error = USBD_IOERROR; 915 goto ret; 916 } 917 switch (value) { 918 case UHF_PORT_RESET: 919 DPRINTF(D_MSG, ("PORT_RESET ")); 920 WPS(ADMHCD_PRS); 921 break; 922 case UHF_PORT_POWER: 923 DPRINTF(D_MSG, ("PORT_POWER ")); 924 WPS(ADMHCD_PPS); 925 break; 926 case UHF_PORT_ENABLE: 927 DPRINTF(D_MSG, ("PORT_ENABLE ")); 928 WPS(ADMHCD_PES); 929 break; 930 default: 931 printf("SetPortFeatERR=0x%x ", value); 932 error = USBD_IOERROR; 933 break; 934 } 935 #undef WPS 936 break; 937 default: 938 DPRINTF(D_MSG, ("ioerr(UR=%02x,UT=%02x) ", 939 req->bRequest, req->bmRequestType)); 940 error = USBD_IOERROR; 941 goto ret; 942 } 943 xfer->actlen = totlen; 944 error = USBD_NORMAL_COMPLETION; 945 ret: 946 xfer->status = error; 947 s = splusb(); 948 usb_transfer_complete(xfer); 949 splx(s); 950 return USBD_IN_PROGRESS; 951 } 952 953 void 954 ahci_root_ctrl_abort(usbd_xfer_handle xfer) 955 { 956 DPRINTF(D_TRACE, ("SLRCabort ")); 957 } 958 959 void 960 ahci_root_ctrl_close(usbd_pipe_handle pipe) 961 { 962 DPRINTF(D_TRACE, ("SLRCclose ")); 963 } 964 965 void 966 ahci_root_ctrl_done(usbd_xfer_handle xfer) 967 { 968 DPRINTF(D_TRACE, ("SLRCdone\n")); 969 } 970 971 static usbd_status 972 ahci_root_intr_transfer(usbd_xfer_handle xfer) 973 { 974 usbd_status error; 975 976 DPRINTF(D_TRACE, ("SLRItransfer ")); 977 978 /* Insert last in queue */ 979 error = usb_insert_transfer(xfer); 980 if (error) 981 return error; 982 983 /* 984 * Pipe isn't running (otherwise error would be USBD_INPROG), 985 * start first. 986 */ 987 return ahci_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)); 988 } 989 990 static usbd_status 991 ahci_root_intr_start(usbd_xfer_handle xfer) 992 { 993 usbd_pipe_handle pipe = xfer->pipe; 994 struct ahci_softc *sc = (struct ahci_softc *)pipe->device->bus; 995 996 DPRINTF(D_TRACE, ("SLRIstart ")); 997 998 sc->sc_interval = MS_TO_TICKS(xfer->pipe->endpoint->edesc->bInterval); 999 usb_callout(sc->sc_poll_handle, sc->sc_interval, ahci_poll_hub, xfer); 1000 sc->sc_intr_xfer = xfer; 1001 return USBD_IN_PROGRESS; 1002 } 1003 1004 static void 1005 ahci_root_intr_abort(usbd_xfer_handle xfer) 1006 { 1007 DPRINTF(D_TRACE, ("SLRIabort ")); 1008 } 1009 1010 static void 1011 ahci_root_intr_close(usbd_pipe_handle pipe) 1012 { 1013 struct ahci_softc *sc = (struct ahci_softc *)pipe->device->bus; 1014 1015 DPRINTF(D_TRACE, ("SLRIclose ")); 1016 1017 usb_uncallout(sc->sc_poll_handle, ahci_poll_hub, sc->sc_intr_xfer); 1018 sc->sc_intr_xfer = NULL; 1019 } 1020 1021 static void 1022 ahci_root_intr_done(usbd_xfer_handle xfer) 1023 { 1024 //DPRINTF(D_XFER, ("RIdn ")); 1025 } 1026 1027 static usbd_status 1028 ahci_device_ctrl_transfer(usbd_xfer_handle xfer) 1029 { 1030 usbd_status error; 1031 1032 DPRINTF(D_TRACE, ("C")); 1033 1034 error = usb_insert_transfer(xfer); 1035 if (error) 1036 return error; 1037 1038 return ahci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)); 1039 } 1040 1041 static usbd_status 1042 ahci_device_ctrl_start(usbd_xfer_handle xfer) 1043 { 1044 usbd_status status = USBD_NORMAL_COMPLETION; 1045 int s, err; 1046 static struct admhcd_ed ep_v __attribute__((aligned(16))), *ep; 1047 static struct admhcd_td td_v[4] __attribute__((aligned(16))), *td, *td1, *td2, *td3; 1048 static usb_dma_t reqdma; 1049 usbd_pipe_handle pipe = xfer->pipe; 1050 usb_device_request_t *req = &xfer->request; 1051 struct ahci_softc *sc = (struct ahci_softc *)pipe->device->bus; 1052 int len, isread; 1053 1054 1055 #if 0 1056 struct ahci_pipe *apipe = (struct ahci_pipe *)xfer->pipe; 1057 #endif 1058 while (sc->busy) { 1059 delay_ms(10); 1060 }; 1061 sc->busy++; 1062 /* printf("ctrl_start>>>\n"); */ 1063 1064 #ifdef DIAGNOSTIC 1065 if (!(xfer->rqflags & URQ_REQUEST)) { 1066 /* XXX panic */ 1067 printf("ahci_device_ctrl_transfer: not a request\n"); 1068 return (USBD_INVAL); 1069 } 1070 #endif 1071 1072 #define KSEG1ADDR(x) (0xa0000000 | (((u_int32_t)x) & 0x1fffffff)) 1073 DPRINTF(D_TRACE, ("st ")); 1074 if (!ep) { 1075 ep = (struct admhcd_ed *)KSEG1ADDR(&ep_v); 1076 td = (struct admhcd_td *)KSEG1ADDR(&td_v[0]); 1077 td1 = (struct admhcd_td *)KSEG1ADDR(&td_v[1]); 1078 td2 = (struct admhcd_td *)KSEG1ADDR(&td_v[2]); 1079 td3 = (struct admhcd_td *)KSEG1ADDR(&td_v[3]); 1080 err = usb_allocmem(&sc->sc_bus, 1081 sizeof(usb_device_request_t), 1082 0, &reqdma); 1083 if (err) 1084 return (USBD_NOMEM); 1085 1086 /* printf("ep: %p\n",ep); */ 1087 }; 1088 1089 ep->control = pipe->device->address | \ 1090 ((pipe->device->speed==USB_SPEED_FULL)?ADMHCD_ED_SPEED:0) | \ 1091 ((UGETW(pipe->endpoint->edesc->wMaxPacketSize))<<ADMHCD_ED_MAXSHIFT); 1092 memcpy(KERNADDR(&reqdma, 0), req, sizeof *req); 1093 /* printf("status: %x\n",REG_READ(ADMHCD_REG_PORTSTATUS0)); 1094 printf("ep_control: %x\n",ep->control); 1095 printf("speed: %x\n",pipe->device->speed); 1096 printf("req: %p\n",req); 1097 printf("dmabuf: %p\n",xfer->dmabuf.block); */ 1098 1099 isread = req->bmRequestType & UT_READ; 1100 len = UGETW(req->wLength); 1101 1102 ep->next = ep; 1103 1104 td->buffer = DMAADDR(&reqdma,0) | 0xa0000000; 1105 td->buflen=sizeof(*req); 1106 td->control=ADMHCD_TD_SETUP | ADMHCD_TD_DATA0 | ADMHCD_TD_OWN; 1107 1108 if (len) { 1109 td->next = td1; 1110 1111 td1->buffer = DMAADDR(&xfer->dmabuf,0) | 0xa0000000; 1112 td1->buflen = len; 1113 td1->next = td2; 1114 td1->control= (isread?ADMHCD_TD_IN:ADMHCD_TD_OUT) | ADMHCD_TD_DATA1 | ADMHCD_TD_R | ADMHCD_TD_OWN; 1115 } else { 1116 td1->control = 0; 1117 td->next = td2; 1118 }; 1119 1120 td2->buffer = 0; 1121 td2->buflen= 0; 1122 td2->next = td3; 1123 td2->control = (isread?ADMHCD_TD_OUT:ADMHCD_TD_IN) | ADMHCD_TD_DATA1 | ADMHCD_TD_OWN; 1124 1125 td3->buffer = 0; 1126 td3->buflen= 0; 1127 td3->next = 0; 1128 td3->control = 0; 1129 1130 ep->head = td; 1131 ep->tail = td3; 1132 /* 1133 printf("ep: %p\n",ep); 1134 printf("ep->next: %p\n",ep->next); 1135 printf("ep->head: %p\n",ep->head); 1136 printf("ep->tail: %p\n",ep->tail); 1137 printf("td: %p\n",td); 1138 printf("td->next: %p\n",td->next); 1139 printf("td->buffer: %x\n",td->buffer); 1140 printf("td->buflen: %x\n",td->buflen); 1141 printf("td1: %p\n",td1); 1142 printf("td1->next: %p\n",td1->next); 1143 printf("td2: %p\n",td2); 1144 printf("td2->next: %p\n",td2->next); 1145 printf("td3: %p\n",td3); 1146 printf("td3->next: %p\n",td3->next); 1147 */ 1148 1149 REG_WRITE(ADMHCD_REG_HOSTHEAD, (u_int32_t)ep); 1150 REG_WRITE(ADMHCD_REG_HOSTCONTROL, ADMHCD_STATE_OP | ADMHCD_DMA_EN); 1151 /* printf("1: %x %x %x %x\n", ep->control, td->control, td1->control, td2->control); */ 1152 s=100; 1153 while (s--) { 1154 delay_ms(10); 1155 /* printf("%x %x %x %x\n", ep->control, td->control, td1->control, td2->control);*/ 1156 status = USBD_TIMEOUT; 1157 if (td->control & ADMHCD_TD_OWN) continue; 1158 1159 err = (td->control & ADMHCD_TD_ERRMASK)>>ADMHCD_TD_ERRSHIFT; 1160 if (err) { 1161 status = USBD_IOERROR; 1162 break; 1163 }; 1164 1165 status = USBD_TIMEOUT; 1166 if (td1->control & ADMHCD_TD_OWN) continue; 1167 err = (td1->control & ADMHCD_TD_ERRMASK)>>ADMHCD_TD_ERRSHIFT; 1168 if (err) { 1169 status = USBD_IOERROR; 1170 break; 1171 }; 1172 1173 status = USBD_TIMEOUT; 1174 if (td2->control & ADMHCD_TD_OWN) continue; 1175 err = (td2->control & ADMHCD_TD_ERRMASK)>>ADMHCD_TD_ERRSHIFT; 1176 if (err) { 1177 status = USBD_IOERROR; 1178 }; 1179 status = USBD_NORMAL_COMPLETION; 1180 break; 1181 1182 }; 1183 REG_WRITE(ADMHCD_REG_HOSTCONTROL, ADMHCD_STATE_OP); 1184 1185 xfer->actlen = len; 1186 xfer->status = status; 1187 1188 sc->busy--; 1189 /* printf("ctrl_start<<<\n"); */ 1190 1191 s = splusb(); 1192 usb_transfer_complete(xfer); 1193 splx(s); 1194 return USBD_IN_PROGRESS; 1195 } 1196 1197 static void 1198 ahci_device_ctrl_abort(usbd_xfer_handle xfer) 1199 { 1200 DPRINTF(D_TRACE, ("Cab ")); 1201 ahci_abort_xfer(xfer, USBD_CANCELLED); 1202 } 1203 1204 static void 1205 ahci_device_ctrl_close(usbd_pipe_handle pipe) 1206 { 1207 DPRINTF(D_TRACE, ("Ccl ")); 1208 } 1209 1210 static void 1211 ahci_device_ctrl_done(usbd_xfer_handle xfer) 1212 { 1213 DPRINTF(D_TRACE, ("Cdn ")); 1214 } 1215 1216 static usbd_status 1217 ahci_device_intr_transfer(usbd_xfer_handle xfer) 1218 { 1219 usbd_status error; 1220 1221 DPRINTF(D_TRACE, ("INTRtrans ")); 1222 1223 error = usb_insert_transfer(xfer); 1224 if (error) 1225 return error; 1226 1227 return ahci_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)); 1228 } 1229 1230 static usbd_status 1231 ahci_device_intr_start(usbd_xfer_handle xfer) 1232 { 1233 usbd_pipe_handle pipe = xfer->pipe; 1234 struct ahci_xfer *sx; 1235 1236 DPRINTF(D_TRACE, ("INTRstart ")); 1237 1238 sx = malloc(sizeof(*sx), M_USB, M_NOWAIT); 1239 if (sx == NULL) 1240 goto reterr; 1241 memset(sx, 0, sizeof(*sx)); 1242 sx->sx_xfer = xfer; 1243 xfer->hcpriv = sx; 1244 1245 /* initialize callout */ 1246 usb_callout_init(sx->sx_callout_t); 1247 usb_callout(sx->sx_callout_t, 1248 MS_TO_TICKS(pipe->endpoint->edesc->bInterval), 1249 ahci_poll_device, sx); 1250 1251 /* ACK */ 1252 return USBD_IN_PROGRESS; 1253 1254 reterr: 1255 return USBD_IOERROR; 1256 } 1257 1258 static void 1259 ahci_poll_device(void *arg) 1260 { 1261 struct ahci_xfer *sx = (struct ahci_xfer *)arg; 1262 usbd_xfer_handle xfer = sx->sx_xfer; 1263 usbd_pipe_handle pipe = xfer->pipe; 1264 struct ahci_softc *sc = (struct ahci_softc *)pipe->device->bus; 1265 void *buf; 1266 int pid; 1267 int r; 1268 int s; 1269 1270 DPRINTF(D_TRACE, ("pldev")); 1271 1272 usb_callout(sx->sx_callout_t, 1273 MS_TO_TICKS(pipe->endpoint->edesc->bInterval), 1274 ahci_poll_device, sx); 1275 1276 /* interrupt transfer */ 1277 pid = (UE_GET_DIR(pipe->endpoint->edesc->bEndpointAddress) == UE_DIR_IN) 1278 ? ADMHCD_TD_IN : ADMHCD_TD_OUT; 1279 buf = KERNADDR(&xfer->dmabuf, 0); 1280 1281 r = ahci_transaction(sc, pipe, pid, xfer->length, buf, 0/*toggle*/); 1282 if (r < 0) { 1283 DPRINTF(D_MSG, ("%s error", __func__)); 1284 return; 1285 } 1286 /* no change, return NAK */ 1287 if (r == 0) 1288 return; 1289 1290 xfer->status = USBD_NORMAL_COMPLETION; 1291 s = splusb(); 1292 xfer->device->bus->intr_context++; 1293 usb_transfer_complete(xfer); 1294 xfer->device->bus->intr_context--; 1295 splx(s); 1296 } 1297 1298 static void 1299 ahci_device_intr_abort(usbd_xfer_handle xfer) 1300 { 1301 struct ahci_xfer *sx; 1302 1303 DPRINTF(D_TRACE, ("INTRabort ")); 1304 1305 sx = xfer->hcpriv; 1306 if (sx) { 1307 usb_uncallout(sx->sx_callout_t, ahci_poll_device, sx); 1308 free(sx, M_USB); 1309 xfer->hcpriv = NULL; 1310 } else { 1311 printf("%s: sx == NULL!\n", __func__); 1312 } 1313 ahci_abort_xfer(xfer, USBD_CANCELLED); 1314 } 1315 1316 static void 1317 ahci_device_intr_close(usbd_pipe_handle pipe) 1318 { 1319 DPRINTF(D_TRACE, ("INTRclose ")); 1320 } 1321 1322 static void 1323 ahci_device_intr_done(usbd_xfer_handle xfer) 1324 { 1325 DPRINTF(D_TRACE, ("INTRdone ")); 1326 } 1327 1328 static usbd_status 1329 ahci_device_isoc_transfer(usbd_xfer_handle xfer) 1330 { 1331 DPRINTF(D_TRACE, ("S")); 1332 return USBD_NORMAL_COMPLETION; 1333 } 1334 1335 static usbd_status 1336 ahci_device_isoc_start(usbd_xfer_handle xfer) 1337 { 1338 DPRINTF(D_TRACE, ("st ")); 1339 return USBD_NORMAL_COMPLETION; 1340 } 1341 1342 static void 1343 ahci_device_isoc_abort(usbd_xfer_handle xfer) 1344 { 1345 DPRINTF(D_TRACE, ("Sab ")); 1346 } 1347 1348 static void 1349 ahci_device_isoc_close(usbd_pipe_handle pipe) 1350 { 1351 DPRINTF(D_TRACE, ("Scl ")); 1352 } 1353 1354 static void 1355 ahci_device_isoc_done(usbd_xfer_handle xfer) 1356 { 1357 DPRINTF(D_TRACE, ("Sdn ")); 1358 } 1359 1360 static usbd_status 1361 ahci_device_bulk_transfer(usbd_xfer_handle xfer) 1362 { 1363 usbd_status error; 1364 1365 DPRINTF(D_TRACE, ("B")); 1366 1367 error = usb_insert_transfer(xfer); 1368 if (error) 1369 return error; 1370 1371 return ahci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue)); 1372 } 1373 1374 static usbd_status 1375 ahci_device_bulk_start(usbd_xfer_handle xfer) 1376 { 1377 #define NBULK_TDS 32 1378 static volatile int level = 0; 1379 usbd_status status = USBD_NORMAL_COMPLETION; 1380 int s, err; 1381 static struct admhcd_ed ep_v __attribute__((aligned(16))), *ep; 1382 static struct admhcd_td td_v[NBULK_TDS] __attribute__((aligned(16))), *td[NBULK_TDS]; 1383 usbd_pipe_handle pipe = xfer->pipe; 1384 struct ahci_softc *sc = (struct ahci_softc *)pipe->device->bus; 1385 int endpt, i, len, tlen, segs, offset, isread, toggle, short_ok; 1386 struct ahci_pipe *apipe = (struct ahci_pipe *)xfer->pipe; 1387 1388 #define KSEG1ADDR(x) (0xa0000000 | (((u_int32_t)x) & 0x1fffffff)) 1389 DPRINTF(D_TRACE, ("st ")); 1390 1391 #ifdef DIAGNOSTIC 1392 if (xfer->rqflags & URQ_REQUEST) { 1393 /* XXX panic */ 1394 printf("ohci_device_bulk_start: a request\n"); 1395 return (USBD_INVAL); 1396 } 1397 #endif 1398 1399 while (sc->busy) { 1400 delay_ms(10); 1401 }; 1402 sc->busy++; 1403 level++; 1404 /* printf("bulk_start>>>\n"); */ 1405 1406 if (!ep) { 1407 ep = (struct admhcd_ed *)KSEG1ADDR(&ep_v); 1408 for (i=0; i<NBULK_TDS; i++) { 1409 td[i] = (struct admhcd_td *)KSEG1ADDR(&td_v[i]); 1410 }; 1411 /* printf("ep: %p\n",ep);*/ 1412 }; 1413 if (apipe->toggle == 0) { 1414 toggle = ADMHCD_TD_DATA0; 1415 } else { 1416 toggle = apipe->toggle; 1417 }; 1418 1419 endpt = pipe->endpoint->edesc->bEndpointAddress; 1420 ep->control = pipe->device->address | ((endpt & 0xf) << ADMHCD_ED_EPSHIFT)|\ 1421 ((pipe->device->speed==USB_SPEED_FULL)?ADMHCD_ED_SPEED:0) | \ 1422 ((UGETW(pipe->endpoint->edesc->wMaxPacketSize))<<ADMHCD_ED_MAXSHIFT); 1423 1424 short_ok = xfer->flags & USBD_SHORT_XFER_OK?ADMHCD_TD_R:0; 1425 /* printf("level: %d\n",level); 1426 printf("short_xfer: %x\n",short_ok); 1427 printf("ep_control: %x\n",ep->control); 1428 printf("speed: %x\n",pipe->device->speed); 1429 printf("dmabuf: %p\n",xfer->dmabuf.block); */ 1430 1431 isread = UE_GET_DIR(endpt) == UE_DIR_IN; 1432 len = xfer->length; 1433 1434 ep->next = ep; 1435 1436 i = 0; 1437 offset = 0; 1438 while ((len>0) || (i==0)) { 1439 tlen = min(len,4096); 1440 td[i]->buffer = DMAADDR(&xfer->dmabuf,offset) | 0xa0000000; 1441 td[i]->buflen=tlen; 1442 td[i]->control=(isread?ADMHCD_TD_IN:ADMHCD_TD_OUT) | toggle | ADMHCD_TD_OWN | short_ok; 1443 td[i]->len=tlen; 1444 toggle = ADMHCD_TD_TOGGLE; 1445 len -= tlen; 1446 offset += tlen; 1447 td[i]->next = td[i+1]; 1448 i++; 1449 }; 1450 1451 td[i]->buffer = 0; 1452 td[i]->buflen = 0; 1453 td[i]->control = 0; 1454 td[i]->next = 0; 1455 1456 ep->head = td[0]; 1457 ep->tail = td[i]; 1458 segs = i; 1459 len = 0; 1460 1461 /* printf("segs: %d\n",segs); 1462 printf("ep: %p\n",ep); 1463 printf("ep->control: %x\n",ep->control); 1464 printf("ep->next: %p\n",ep->next); 1465 printf("ep->head: %p\n",ep->head); 1466 printf("ep->tail: %p\n",ep->tail); 1467 for (i=0; i<segs; i++) { 1468 printf("td[%d]: %p\n",i,td[i]); 1469 printf("td[%d]->control: %x\n",i,td[i]->control); 1470 printf("td[%d]->next: %p\n",i,td[i]->next); 1471 printf("td[%d]->buffer: %x\n",i,td[i]->buffer); 1472 printf("td[%d]->buflen: %x\n",i,td[i]->buflen); 1473 }; */ 1474 1475 REG_WRITE(ADMHCD_REG_HOSTHEAD, (u_int32_t)ep); 1476 REG_WRITE(ADMHCD_REG_HOSTCONTROL, ADMHCD_STATE_OP | ADMHCD_DMA_EN); 1477 i = 0; 1478 /* printf("1: %x %d %x %x\n", ep->control, i, td[i]->control, td[i]->buflen); */ 1479 s=100; 1480 err = 0; 1481 while (s--) { 1482 /* printf("%x %d %x %x\n", ep->control, i, td[i]->control, td[i]->buflen); */ 1483 status = USBD_TIMEOUT; 1484 if (td[i]->control & ADMHCD_TD_OWN) { 1485 delay_ms(3); 1486 continue; 1487 }; 1488 1489 len += td[i]->len - td[i]->buflen; 1490 1491 err = (td[i]->control & ADMHCD_TD_ERRMASK)>>ADMHCD_TD_ERRSHIFT; 1492 if (err) { 1493 status = USBD_IOERROR; 1494 break; 1495 }; 1496 1497 i++; 1498 if (i==segs) { 1499 status = USBD_NORMAL_COMPLETION; 1500 break; 1501 }; 1502 1503 }; 1504 REG_WRITE(ADMHCD_REG_HOSTCONTROL, ADMHCD_STATE_OP); 1505 1506 apipe->toggle = ((u_int32_t)ep->head & 2)?ADMHCD_TD_DATA1:ADMHCD_TD_DATA0; 1507 /* printf("bulk_transfer_done: status: %x, err: %x, len: %x, toggle: %x\n", status,err,len,apipe->toggle); */ 1508 1509 if (short_ok && (err == 0x9 || err == 0xd)) { 1510 /* printf("bulk_transfer_done: short_transfer fix\n"); */ 1511 status = USBD_NORMAL_COMPLETION; 1512 }; 1513 xfer->actlen = len; 1514 xfer->status = status; 1515 1516 level--; 1517 sc->busy--; 1518 /* printf("bulk_start<<<\n"); */ 1519 1520 s = splusb(); 1521 usb_transfer_complete(xfer); 1522 splx(s); 1523 return USBD_IN_PROGRESS; 1524 } 1525 1526 static void 1527 ahci_device_bulk_abort(usbd_xfer_handle xfer) 1528 { 1529 DPRINTF(D_TRACE, ("Bab ")); 1530 ahci_abort_xfer(xfer, USBD_CANCELLED); 1531 } 1532 1533 static void 1534 ahci_device_bulk_close(usbd_pipe_handle pipe) 1535 { 1536 DPRINTF(D_TRACE, ("Bcl ")); 1537 } 1538 1539 static void 1540 ahci_device_bulk_done(usbd_xfer_handle xfer) 1541 { 1542 DPRINTF(D_TRACE, ("Bdn ")); 1543 } 1544 1545 #define DATA0_RD (0x03) 1546 #define DATA0_WR (0x07) 1547 #define AHCI_TIMEOUT (5000) 1548 1549 /* 1550 * Do a transaction. 1551 * return 1 if ACK, 0 if NAK, -1 if error. 1552 */ 1553 static int 1554 ahci_transaction(struct ahci_softc *sc, usbd_pipe_handle pipe, 1555 u_int8_t pid, int len, u_char *buf, u_int8_t toggle) 1556 { 1557 return -1; 1558 #if 0 1559 #ifdef AHCI_DEBUG 1560 char str[64]; 1561 int i; 1562 #endif 1563 int timeout; 1564 int ls_via_hub = 0; 1565 int pl; 1566 u_int8_t isr; 1567 u_int8_t result = 0; 1568 u_int8_t devaddr = pipe->device->address; 1569 u_int8_t endpointaddr = pipe->endpoint->edesc->bEndpointAddress; 1570 u_int8_t endpoint; 1571 u_int8_t cmd = DATA0_RD; 1572 1573 endpoint = UE_GET_ADDR(endpointaddr); 1574 DPRINTF(D_XFER, ("\n(%x,%d%s%d,%d) ", 1575 pid, len, (pid == SL11_PID_IN) ? "<-" : "->", devaddr, endpoint)); 1576 1577 /* Set registers */ 1578 sl11write(sc, SL11_E0ADDR, 0x40); 1579 sl11write(sc, SL11_E0LEN, len); 1580 sl11write(sc, SL11_E0PID, (pid << 4) + endpoint); 1581 sl11write(sc, SL11_E0DEV, devaddr); 1582 1583 /* Set buffer unless PID_IN */ 1584 if (pid != SL11_PID_IN) { 1585 if (len > 0) 1586 sl11write_region(sc, 0x40, buf, len); 1587 cmd = DATA0_WR; 1588 } 1589 1590 /* timing ? */ 1591 pl = (len >> 3) + 3; 1592 1593 /* Low speed device via HUB */ 1594 /* XXX does not work... */ 1595 if ((sc->sc_fullspeed) && pipe->device->speed == USB_SPEED_LOW) { 1596 pl = len + 16; 1597 cmd |= SL11_EPCTRL_PREAMBLE; 1598 1599 /* 1600 * SL811HS/T rev 1.2 has a bug, when it got PID_IN 1601 * from LowSpeed device via HUB. 1602 */ 1603 if (sc->sc_sltype == SLTYPE_SL811HS_R12 && pid == SL11_PID_IN) { 1604 ls_via_hub = 1; 1605 DPRINTF(D_MSG, ("LSvH ")); 1606 } 1607 } 1608 1609 /* timing ? */ 1610 if (sl11read(sc, SL811_CSOF) <= (u_int8_t)pl) 1611 cmd |= SL11_EPCTRL_SOF; 1612 1613 /* Transfer */ 1614 sl11write(sc, SL11_ISR, 0xff); 1615 sl11write(sc, SL11_E0CTRL, cmd | toggle); 1616 1617 /* Polling */ 1618 for (timeout = AHCI_TIMEOUT; timeout; timeout--) { 1619 isr = sl11read(sc, SL11_ISR); 1620 if ((isr & SL11_ISR_USBA)) 1621 break; 1622 } 1623 1624 /* Check result status */ 1625 result = sl11read(sc, SL11_E0STAT); 1626 if (!(result & SL11_EPSTAT_NAK) && ls_via_hub) { 1627 /* Resend PID_IN within 20usec */ 1628 sl11write(sc, SL11_ISR, 0xff); 1629 sl11write(sc, SL11_E0CTRL, SL11_EPCTRL_ARM); 1630 } 1631 1632 sl11write(sc, SL11_ISR, 0xff); 1633 1634 DPRINTF(D_XFER, ("t=%d i=%x ", AHCI_TIMEOUT - timeout, isr)); 1635 #if AHCI_DEBUG 1636 snprintb(str, sizeof(str), 1637 "\20\x8STALL\7NAK\6OV\5SETUP\4DATA1\3TIMEOUT\2ERR\1ACK", result); 1638 DPRINTF(D_XFER, ("STAT=%s ", str)); 1639 #endif 1640 1641 if ((result & SL11_EPSTAT_ERROR)) 1642 return -1; 1643 1644 if ((result & SL11_EPSTAT_NAK)) 1645 return 0; 1646 1647 /* Read buffer if PID_IN */ 1648 if (pid == SL11_PID_IN && len > 0) { 1649 sl11read_region(sc, buf, 0x40, len); 1650 #if AHCI_DEBUG 1651 for (i = 0; i < len; i++) 1652 DPRINTF(D_XFER, ("%02X ", buf[i])); 1653 #endif 1654 } 1655 1656 return 1; 1657 #endif 1658 } 1659 1660 void 1661 ahci_abort_xfer(usbd_xfer_handle xfer, usbd_status status) 1662 { 1663 xfer->status = status; 1664 usb_transfer_complete(xfer); 1665 } 1666 1667 void 1668 ahci_device_clear_toggle(usbd_pipe_handle pipe) 1669 { 1670 struct ahci_pipe *apipe = (struct ahci_pipe *)pipe; 1671 apipe->toggle = 0; 1672 } 1673 1674 #ifdef AHCI_DEBUG 1675 void 1676 print_req(usb_device_request_t *r) 1677 { 1678 const char *xmes[]={ 1679 "GETSTAT", 1680 "CLRFEAT", 1681 "res", 1682 "SETFEAT", 1683 "res", 1684 "SETADDR", 1685 "GETDESC", 1686 "SETDESC", 1687 "GETCONF", 1688 "SETCONF", 1689 "GETIN/F", 1690 "SETIN/F", 1691 "SYNC_FR" 1692 }; 1693 int req, type, value, index, len; 1694 1695 req = r->bRequest; 1696 type = r->bmRequestType; 1697 value = UGETW(r->wValue); 1698 index = UGETW(r->wIndex); 1699 len = UGETW(r->wLength); 1700 1701 printf("%x,%s,v=%d,i=%d,l=%d ", 1702 type, xmes[req], value, index, len); 1703 } 1704 1705 void 1706 print_req_hub(usb_device_request_t *r) 1707 { 1708 struct { 1709 int req; 1710 int type; 1711 const char *str; 1712 } conf[] = { 1713 { 1, 0x20, "ClrHubFeat" }, 1714 { 1, 0x23, "ClrPortFeat" }, 1715 { 2, 0xa3, "GetBusState" }, 1716 { 6, 0xa0, "GetHubDesc" }, 1717 { 0, 0xa0, "GetHubStat" }, 1718 { 0, 0xa3, "GetPortStat" }, 1719 { 7, 0x20, "SetHubDesc" }, 1720 { 3, 0x20, "SetHubFeat" }, 1721 { 3, 0x23, "SetPortFeat" }, 1722 {-1, 0, NULL}, 1723 }; 1724 int i; 1725 int value, index, len; 1726 1727 value = UGETW(r->wValue); 1728 index = UGETW(r->wIndex); 1729 len = UGETW(r->wLength); 1730 for (i = 0; ; i++) { 1731 if (conf[i].req == -1 ) 1732 return print_req(r); 1733 if (r->bmRequestType == conf[i].type && r->bRequest == conf[i].req) { 1734 printf("%s", conf[i].str); 1735 break; 1736 } 1737 } 1738 printf(",v=%d,i=%d,l=%d ", value, index, len); 1739 } 1740 1741 void 1742 print_dumpreg(struct ahci_softc *sc) 1743 { 1744 #if 0 1745 printf("00=%02x,01=%02x,02=%02x,03=%02x,04=%02x," 1746 "08=%02x,09=%02x,0A=%02x,0B=%02x,0C=%02x,", 1747 sl11read(sc, 0), sl11read(sc, 1), 1748 sl11read(sc, 2), sl11read(sc, 3), 1749 sl11read(sc, 4), sl11read(sc, 8), 1750 sl11read(sc, 9), sl11read(sc, 10), 1751 sl11read(sc, 11), sl11read(sc, 12) 1752 ); 1753 printf("CR1=%02x,IER=%02x,0D=%02x,0E=%02x,0F=%02x ", 1754 sl11read(sc, 5), sl11read(sc, 6), 1755 sl11read(sc, 13), sl11read(sc, 14), sl11read(sc, 15) 1756 ); 1757 #endif 1758 } 1759 1760 void 1761 print_xfer(usbd_xfer_handle xfer) 1762 { 1763 printf("xfer: length=%d, actlen=%d, flags=%x, timeout=%d,", 1764 xfer->length, xfer->actlen, xfer->flags, xfer->timeout); 1765 printf("request{ "); 1766 print_req_hub(&xfer->request); 1767 printf("} "); 1768 } 1769 #endif /* AHCI_DEBUG */ 1770