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