1 /* $NetBSD: ahci.c,v 1.13 2016/04/23 10:15:29 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.13 2016/04/23 10:15:29 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/kmem.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 #include <dev/usb/usbroothub.h> 85 86 #include <mips/adm5120/include/adm5120reg.h> 87 #include <mips/adm5120/include/adm5120var.h> 88 #include <mips/adm5120/include/adm5120_obiovar.h> 89 90 #include <mips/adm5120/dev/ahcireg.h> 91 #include <mips/adm5120/dev/ahcivar.h> 92 93 static usbd_status ahci_open(struct usbd_pipe *); 94 static void ahci_softintr(void *); 95 static void ahci_poll(struct usbd_bus *); 96 static void ahci_poll_hub(void *); 97 static void ahci_poll_device(void *arg); 98 static struct usbd_xfer * 99 ahci_allocx(struct usbd_bus *, unsigned int); 100 static void ahci_freex(struct usbd_bus *, struct usbd_xfer *); 101 102 static void ahci_get_lock(struct usbd_bus *, kmutex_t **); 103 static int ahci_roothub_ctrl(struct usbd_bus *, usb_device_request_t *, 104 void *, int); 105 106 static usbd_status ahci_root_intr_transfer(struct usbd_xfer *); 107 static usbd_status ahci_root_intr_start(struct usbd_xfer *); 108 static void ahci_root_intr_abort(struct usbd_xfer *); 109 static void ahci_root_intr_close(struct usbd_pipe *); 110 static void ahci_root_intr_done(struct usbd_xfer *); 111 112 static usbd_status ahci_device_ctrl_transfer(struct usbd_xfer *); 113 static usbd_status ahci_device_ctrl_start(struct usbd_xfer *); 114 static void ahci_device_ctrl_abort(struct usbd_xfer *); 115 static void ahci_device_ctrl_close(struct usbd_pipe *); 116 static void ahci_device_ctrl_done(struct usbd_xfer *); 117 118 static usbd_status ahci_device_intr_transfer(struct usbd_xfer *); 119 static usbd_status ahci_device_intr_start(struct usbd_xfer *); 120 static void ahci_device_intr_abort(struct usbd_xfer *); 121 static void ahci_device_intr_close(struct usbd_pipe *); 122 static void ahci_device_intr_done(struct usbd_xfer *); 123 124 static usbd_status ahci_device_isoc_transfer(struct usbd_xfer *); 125 static usbd_status ahci_device_isoc_start(struct usbd_xfer *); 126 static void ahci_device_isoc_abort(struct usbd_xfer *); 127 static void ahci_device_isoc_close(struct usbd_pipe *); 128 static void ahci_device_isoc_done(struct usbd_xfer *); 129 130 static usbd_status ahci_device_bulk_transfer(struct usbd_xfer *); 131 static usbd_status ahci_device_bulk_start(struct usbd_xfer *); 132 static void ahci_device_bulk_abort(struct usbd_xfer *); 133 static void ahci_device_bulk_close(struct usbd_pipe *); 134 static void ahci_device_bulk_done(struct usbd_xfer *); 135 136 static int ahci_transaction(struct ahci_softc *, 137 struct usbd_pipe *, uint8_t, int, u_char *, uint8_t); 138 static void ahci_noop(struct usbd_pipe *); 139 static void ahci_abort_xfer(struct usbd_xfer *, usbd_status); 140 static void ahci_device_clear_toggle(struct usbd_pipe *); 141 142 extern int usbdebug; 143 extern int uhubdebug; 144 extern int umassdebug; 145 int ahci_dummy; 146 147 #define AHCI_DEBUG 148 149 #ifdef AHCI_DEBUG 150 #define D_TRACE (0x0001) /* function trace */ 151 #define D_MSG (0x0002) /* debug messages */ 152 #define D_XFER (0x0004) /* transfer messages (noisy!) */ 153 #define D_MEM (0x0008) /* memory allocation */ 154 155 int ahci_debug = 0; 156 #define DPRINTF(z,x) if((ahci_debug&(z))!=0)printf x 157 void print_req(usb_device_request_t *); 158 void print_req_hub(usb_device_request_t *); 159 void print_dumpreg(struct ahci_softc *); 160 void print_xfer(struct usbd_xfer *); 161 #else 162 #define DPRINTF(z,x) 163 #endif 164 165 166 struct usbd_bus_methods ahci_bus_methods = { 167 .ubm_open = ahci_open, 168 .ubm_softint = ahci_softintr, 169 .ubm_dopoll = ahci_poll, 170 .ubm_allocx = ahci_allocx, 171 .ubm_freex = ahci_freex, 172 .ubm_getlock = ahci_get_lock, 173 .ubm_rhctrl = ahci_roothub_ctrl, 174 }; 175 176 struct usbd_pipe_methods ahci_root_intr_methods = { 177 .upm_transfer = ahci_root_intr_transfer, 178 .upm_start = ahci_root_intr_start, 179 .upm_abort = ahci_root_intr_abort, 180 .upm_close = ahci_root_intr_close, 181 .upm_cleartoggle = ahci_noop, 182 .upm_done = ahci_root_intr_done, 183 }; 184 185 struct usbd_pipe_methods ahci_device_ctrl_methods = { 186 .upm_transfer = ahci_device_ctrl_transfer, 187 .upm_start = ahci_device_ctrl_start, 188 .upm_abort = ahci_device_ctrl_abort, 189 .upm_close = ahci_device_ctrl_close, 190 .upm_cleartoggle = ahci_noop, 191 .upm_done = ahci_device_ctrl_done, 192 }; 193 194 struct usbd_pipe_methods ahci_device_intr_methods = { 195 .upm_transfer = ahci_device_intr_transfer, 196 .upm_start = ahci_device_intr_start, 197 .upm_abort = ahci_device_intr_abort, 198 .upm_close = ahci_device_intr_close, 199 .upm_cleartoggle = ahci_device_clear_toggle, 200 .upm_done = ahci_device_intr_done, 201 }; 202 203 struct usbd_pipe_methods ahci_device_isoc_methods = { 204 .upm_transfer = ahci_device_isoc_transfer, 205 .upm_start = ahci_device_isoc_start, 206 .upm_abort = ahci_device_isoc_abort, 207 .upm_close = ahci_device_isoc_close, 208 .upm_cleartoggle = ahci_noop, 209 .upm_done = ahci_device_isoc_done, 210 }; 211 212 struct usbd_pipe_methods ahci_device_bulk_methods = { 213 .upm_transfer = ahci_device_bulk_transfer, 214 .upm_start = ahci_device_bulk_start, 215 .upm_abort = ahci_device_bulk_abort, 216 .upm_close = ahci_device_bulk_close, 217 .upm_cleartoggle = ahci_device_clear_toggle, 218 .upm_done = ahci_device_bulk_done, 219 }; 220 221 struct ahci_pipe { 222 struct usbd_pipe pipe; 223 uint32_t toggle; 224 }; 225 226 static int ahci_match(device_t, cfdata_t, void *); 227 static void ahci_attach(device_t, device_t, void *); 228 229 CFATTACH_DECL_NEW(ahci, sizeof(struct ahci_softc), 230 ahci_match, ahci_attach, NULL, NULL); 231 232 static int 233 ahci_match(device_t parent, struct cfdata *cf, void *aux) 234 { 235 struct obio_attach_args *aa = aux; 236 237 if (strcmp(aa->oba_name, cf->cf_name) == 0) 238 return 1; 239 240 return 0; 241 } 242 243 #define REG_READ(o) bus_space_read_4(sc->sc_st, sc->sc_ioh, (o)) 244 #define REG_WRITE(o,v) bus_space_write_4(sc->sc_st, sc->sc_ioh, (o),(v)) 245 246 /* 247 * Attach SL11H/SL811HS. Return 0 if success. 248 */ 249 void 250 ahci_attach(device_t parent, device_t self, void *aux) 251 { 252 struct obio_attach_args *aa = aux; 253 struct ahci_softc *sc = device_private(self); 254 255 printf("\n"); 256 sc->sc_dmat = aa->oba_dt; 257 sc->sc_st = aa->oba_st; 258 259 /* Initialize sc */ 260 sc->sc_bus.ub_revision = USBREV_1_1; 261 sc->sc_bus.ub_methods = &ahci_bus_methods; 262 sc->sc_bus.ub_pipesize = sizeof(struct ahci_pipe); 263 sc->sc_bus.ub_dmatag = sc->sc_dmat; 264 sc->sc_bus.ub_usedma = true; 265 266 /* Map the device. */ 267 if (bus_space_map(sc->sc_st, aa->oba_addr, 268 512, 0, &sc->sc_ioh) != 0) { 269 aprint_error_dev(self, "unable to map device\n"); 270 return; 271 } 272 273 /* Hook up the interrupt handler. */ 274 sc->sc_ih = adm5120_intr_establish(aa->oba_irq, INTR_IRQ, ahci_intr, sc); 275 276 if (sc->sc_ih == NULL) { 277 aprint_error_dev(self, 278 "unable to register interrupt handler\n"); 279 return; 280 } 281 282 SIMPLEQ_INIT(&sc->sc_free_xfers); 283 284 callout_init(&sc->sc_poll_handle, 0); 285 286 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB); 287 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED /* XXXNH */); 288 289 REG_WRITE(ADMHCD_REG_INTENABLE, 0); /* disable interrupts */ 290 REG_WRITE(ADMHCD_REG_CONTROL, ADMHCD_SW_RESET); /* reset */ 291 delay_ms(10); 292 while (REG_READ(ADMHCD_REG_CONTROL) & ADMHCD_SW_RESET) 293 delay_ms(1); 294 295 REG_WRITE(ADMHCD_REG_CONTROL, ADMHCD_HOST_EN); 296 REG_WRITE(ADMHCD_REG_HOSTHEAD, 0x00000000); 297 REG_WRITE(ADMHCD_REG_FMINTERVAL, 0x20002edf); 298 REG_WRITE(ADMHCD_REG_LSTHRESH, 0x628); 299 REG_WRITE(ADMHCD_REG_RHDESCR, ADMHCD_NPS | ADMHCD_LPSC); 300 REG_WRITE(ADMHCD_REG_HOSTCONTROL, ADMHCD_STATE_OP); 301 302 REG_WRITE(ADMHCD_REG_INTENABLE, 0); /* XXX: enable interrupts */ 303 304 #ifdef USB_DEBUG 305 /* usbdebug = 0x7f; 306 uhubdebug = 0x7f; 307 umassdebug = 0xffffffff; */ 308 #endif 309 310 /* Attach USB devices */ 311 sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint); 312 313 } 314 315 int 316 ahci_intr(void *arg) 317 { 318 #if 0 319 struct ahci_softc *sc = arg; 320 uint8_t r; 321 #ifdef AHCI_DEBUG 322 char bitbuf[256]; 323 #endif 324 325 r = sl11read(sc, SL11_ISR); 326 327 sl11write(sc, SL11_ISR, SL11_ISR_DATA | SL11_ISR_SOFTIMER); 328 329 if ((r & SL11_ISR_RESET)) { 330 sc->sc_flags |= AHCDF_RESET; 331 sl11write(sc, SL11_ISR, SL11_ISR_RESET); 332 } 333 if ((r & SL11_ISR_INSERT)) { 334 sc->sc_flags |= AHCDF_INSERT; 335 sl11write(sc, SL11_ISR, SL11_ISR_INSERT); 336 } 337 338 #ifdef AHCI_DEBUG 339 snprintb(bitbuf, sizeof(bitbuf), 340 ((sl11read(sc, SL11_CTRL) & SL11_CTRL_SUSPEND) 341 ? "\20\x8""D+\7RESUME\6INSERT\5SOF\4res\3""BABBLE\2USBB\1USBA" 342 : "\20\x8""D+\7RESET\6INSERT\5SOF\4res\3""BABBLE\2USBB\1USBA"), 343 r); 344 345 DPRINTF(D_XFER, ("I=%s ", bitbuf)); 346 #endif /* AHCI_DEBUG */ 347 #endif 348 349 return 0; 350 } 351 352 usbd_status 353 ahci_open(struct usbd_pipe *pipe) 354 { 355 struct usbd_device *dev = pipe->up_dev; 356 struct ahci_pipe *apipe = (struct ahci_pipe *)pipe; 357 usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc; 358 uint8_t rhaddr = dev->ud_bus->ub_rhaddr; 359 360 DPRINTF(D_TRACE, ("ahci_open(addr=%d,ep=%d,scaddr=%d)", 361 dev->ud_addr, ed->bEndpointAddress, rhaddr)); 362 363 apipe->toggle=0; 364 365 if (dev->ud_addr == rhaddr) { 366 switch (ed->bEndpointAddress) { 367 case USB_CONTROL_ENDPOINT: 368 pipe->up_methods = &roothub_ctrl_methods; 369 break; 370 case UE_DIR_IN | USBROOTHUB_INTR_ENDPT: 371 pipe->up_methods = &ahci_root_intr_methods; 372 break; 373 default: 374 printf("open:endpointErr!\n"); 375 return USBD_INVAL; 376 } 377 } else { 378 switch (ed->bmAttributes & UE_XFERTYPE) { 379 case UE_CONTROL: 380 DPRINTF(D_MSG, ("control ")); 381 pipe->up_methods = &ahci_device_ctrl_methods; 382 break; 383 case UE_INTERRUPT: 384 DPRINTF(D_MSG, ("interrupt ")); 385 pipe->up_methods = &ahci_device_intr_methods; 386 break; 387 case UE_ISOCHRONOUS: 388 DPRINTF(D_MSG, ("isochronous ")); 389 pipe->up_methods = &ahci_device_isoc_methods; 390 break; 391 case UE_BULK: 392 DPRINTF(D_MSG, ("bluk ")); 393 pipe->up_methods = &ahci_device_bulk_methods; 394 break; 395 } 396 } 397 return USBD_NORMAL_COMPLETION; 398 } 399 400 void 401 ahci_softintr(void *arg) 402 { 403 DPRINTF(D_TRACE, ("%s()", __func__)); 404 } 405 406 void 407 ahci_poll(struct usbd_bus *bus) 408 { 409 DPRINTF(D_TRACE, ("%s()", __func__)); 410 } 411 412 #define AHCI_BUS2SC(bus) ((bus)->ub_hcpriv) 413 #define AHCI_PIPE2SC(pipe) AHCI_BUS2SC((pipe)->up_dev->ud_bus) 414 #define AHCI_XFER2SC(xfer) AHCI_BUS2SC((xfer)->ux_bus) 415 #define AHCI_APIPE2SC(ap) AHCI_BUS2SC((d)->pipe.up_dev->ud_bus) 416 417 /* 418 * Emulation of interrupt transfer for status change endpoint 419 * of root hub. 420 */ 421 void 422 ahci_poll_hub(void *arg) 423 { 424 struct usbd_xfer *xfer = arg; 425 struct ahci_softc *sc = AHCI_XFER2SC(xfer); 426 u_char *p; 427 static int p0_state=0; 428 static int p1_state=0; 429 430 callout_reset(&sc->sc_poll_handle, sc->sc_interval, ahci_poll_hub, xfer); 431 432 /* USB spec 11.13.3 (p.260) */ 433 p = KERNADDR(&xfer->ux_dmabuf, 0); 434 p[0] = 0; 435 if ((REG_READ(ADMHCD_REG_PORTSTATUS0) & ADMHCD_CCS) != p0_state) { 436 p[0] = 2; 437 DPRINTF(D_TRACE, ("!")); 438 p0_state=(REG_READ(ADMHCD_REG_PORTSTATUS0) & ADMHCD_CCS); 439 }; 440 if ((REG_READ(ADMHCD_REG_PORTSTATUS1) & ADMHCD_CCS) != p1_state) { 441 p[0] = 2; 442 DPRINTF(D_TRACE, ("@")); 443 p1_state=(REG_READ(ADMHCD_REG_PORTSTATUS1) & ADMHCD_CCS); 444 }; 445 446 /* no change, return NAK */ 447 if (p[0] == 0) 448 return; 449 450 xfer->ux_actlen = 1; 451 xfer->ux_status = USBD_NORMAL_COMPLETION; 452 mutex_enter(&sc->sc_lock); 453 usb_transfer_complete(xfer); 454 mutex_exit(&sc->sc_lock); 455 } 456 457 struct usbd_xfer * 458 ahci_allocx(struct usbd_bus *bus, unsigned int nframes) 459 { 460 struct ahci_softc *sc = AHCI_BUS2SC(bus); 461 struct usbd_xfer *xfer; 462 463 DPRINTF(D_MEM, ("SLallocx")); 464 465 xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers); 466 if (xfer) { 467 SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, ux_next); 468 #ifdef DIAGNOSTIC 469 if (xfer->ux_state != XFER_FREE) { 470 printf("ahci_allocx: xfer=%p not free, 0x%08x\n", 471 xfer, xfer->ux_state); 472 } 473 #endif 474 } else { 475 xfer = kmem_alloc(sizeof(*xfer), KM_SLEEP); 476 } 477 478 if (xfer) { 479 memset(xfer, 0, sizeof(*xfer)); 480 #ifdef DIAGNOSTIC 481 xfer->ux_state = XFER_BUSY; 482 #endif 483 } 484 485 return xfer; 486 } 487 488 void 489 ahci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer) 490 { 491 struct ahci_softc *sc = AHCI_BUS2SC(bus); 492 493 DPRINTF(D_MEM, ("SLfreex")); 494 495 #ifdef DIAGNOSTIC 496 if (xfer->ux_state != XFER_BUSY) { 497 printf("ahci_freex: xfer=%p not busy, 0x%08x\n", 498 xfer, xfer->ux_state); 499 return; 500 } 501 xfer->ux_state = XFER_FREE; 502 #endif 503 SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, ux_next); 504 } 505 506 static void 507 ahci_get_lock(struct usbd_bus *bus, kmutex_t **lock) 508 { 509 struct ahci_softc *sc = AHCI_BUS2SC(bus); 510 511 *lock = &sc->sc_lock; 512 } 513 514 void 515 ahci_noop(struct usbd_pipe *pipe) 516 { 517 DPRINTF(D_TRACE, ("%s()", __func__)); 518 } 519 520 /* 521 * Data structures and routines to emulate the root hub. 522 */ 523 524 static int 525 ahci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, 526 void *buf, int buflen) 527 { 528 struct ahci_softc *sc = AHCI_BUS2SC(bus); 529 uint16_t len, value, index; 530 usb_port_status_t ps; 531 int totlen = 0; 532 int status; 533 534 DPRINTF(D_TRACE, ("SLRCstart ")); 535 536 len = UGETW(req->wLength); 537 value = UGETW(req->wValue); 538 index = UGETW(req->wIndex); 539 540 #define C(x,y) ((x) | ((y) << 8)) 541 switch (C(req->bRequest, req->bmRequestType)) { 542 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE): 543 switch (value) { 544 case C(0, UDESC_DEVICE): { 545 usb_device_descriptor_t devd; 546 547 DPRINTF(D_MSG, ("UDESC_DEVICE ")); 548 totlen = min(buflen, sizeof(devd)); 549 memcpy(&devd, buf, totlen); 550 USETW(devd.idVendor, USB_VENDOR_SCANLOGIC); 551 memcpy(buf, &devd, totlen); 552 break; 553 } 554 #define sd ((usb_string_descriptor_t *)buf) 555 case C(1, UDESC_STRING): 556 /* Vendor */ 557 totlen = usb_makestrdesc(sd, len, "ADMTek"); 558 break; 559 case C(2, UDESC_STRING): 560 /* Product */ 561 totlen = usb_makestrdesc(sd, len, "ADM5120 root hub"); 562 break; 563 default: 564 printf("unknownGetDescriptor=%x", value); 565 /* default from usbroothub */ 566 return buflen; 567 } 568 break; 569 /* 570 * Hub specific requests 571 */ 572 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE): 573 /* Clear Hub Feature, 11.16.2.1, not supported */ 574 DPRINTF(D_MSG, ("ClearHubFeature not supported\n")); 575 break; 576 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER): 577 578 #define WPS(x) REG_WRITE(ADMHCD_REG_PORTSTATUS0+(index-1)*4, (x)) 579 /* Clear Port Feature, 11.16.2.2 */ 580 if (index != 1 && index != 2 ) { 581 return -1; 582 } 583 switch (value) { 584 case UHF_PORT_POWER: 585 DPRINTF(D_MSG, ("POWER_OFF ")); 586 WPS(ADMHCD_LSDA); 587 break; 588 case UHF_PORT_SUSPEND: 589 DPRINTF(D_MSG, ("SUSPEND ")); 590 WPS(ADMHCD_POCI); 591 break; 592 case UHF_PORT_ENABLE: 593 DPRINTF(D_MSG, ("ENABLE ")); 594 WPS(ADMHCD_CCS); 595 break; 596 case UHF_C_PORT_CONNECTION: 597 WPS(ADMHCD_CSC); 598 break; 599 case UHF_C_PORT_RESET: 600 WPS(ADMHCD_PRSC); 601 break; 602 case UHF_C_PORT_SUSPEND: 603 WPS(ADMHCD_PSSC); 604 break; 605 case UHF_C_PORT_ENABLE: 606 WPS(ADMHCD_PESC); 607 break; 608 case UHF_C_PORT_OVER_CURRENT: 609 WPS(ADMHCD_OCIC); 610 break; 611 default: 612 printf("ClrPortFeatERR:value=0x%x ", value); 613 return -1; 614 } 615 //DPRINTF(D_XFER, ("CH=%04x ", sc->sc_change)); 616 #undef WPS 617 break; 618 case C(UR_GET_BUS_STATE, UT_READ_CLASS_OTHER): 619 /* Get Bus State, 11.16.2.3, not supported */ 620 /* shall return a STALL... */ 621 break; 622 case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE): 623 /* Get Hub Descriptor, 11.16.2.4 */ 624 DPRINTF(D_MSG, ("UR_GET_DESCRIPTOR RCD")); 625 if ((value&0xff) != 0) { 626 return -1; 627 } 628 usb_hub_descriptor_t hubd; 629 630 totlen = min(buflen, sizeof(hubd)); 631 memcpy(&hubd, buf, totlen); 632 hubd.bNbrPorts = 2; 633 USETW(hubd.wHubCharacteristics, 0); 634 hubd.bPwrOn2PwrGood = 0; 635 memcpy(buf, &hubd, totlen); 636 break; 637 case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE): 638 /* Get Hub Status, 11.16.2.5 */ 639 DPRINTF(D_MSG, ("UR_GET_STATUS RCD")); 640 if (len != 4) { 641 return -1; 642 } 643 memset(buf, 0, len); 644 totlen = len; 645 break; 646 case C(UR_GET_STATUS, UT_READ_CLASS_OTHER): 647 /* Get Port Status, 11.16.2.6 */ 648 if ((index != 1 && index != 2) || len != 4) { 649 printf("index=%d,len=%d ", index, len); 650 return -1; 651 } 652 status = REG_READ(ADMHCD_REG_PORTSTATUS0+(index-1)*4); 653 DPRINTF(D_MSG, ("UR_GET_STATUS RCO=%x ", status)); 654 655 //DPRINTF(D_XFER, ("ST=%04x,CH=%04x ", status, sc->sc_change)); 656 USETW(ps.wPortStatus, status & (UPS_CURRENT_CONNECT_STATUS|UPS_PORT_ENABLED|UPS_SUSPEND|UPS_OVERCURRENT_INDICATOR|UPS_RESET|UPS_PORT_POWER|UPS_LOW_SPEED)); 657 USETW(ps.wPortChange, (status>>16) & (UPS_C_CONNECT_STATUS|UPS_C_PORT_ENABLED|UPS_C_SUSPEND|UPS_C_OVERCURRENT_INDICATOR|UPS_C_PORT_RESET)); 658 totlen = min(len, sizeof(ps)); 659 memcpy(buf, &ps, totlen); 660 break; 661 case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE): 662 /* Set Hub Descriptor, 11.16.2.7, not supported */ 663 /* STALL ? */ 664 return -1; 665 case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE): 666 /* Set Hub Feature, 11.16.2.8, not supported */ 667 break; 668 case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER): 669 #define WPS(x) REG_WRITE(ADMHCD_REG_PORTSTATUS0+(index-1)*4, (x)) 670 /* Set Port Feature, 11.16.2.9 */ 671 if ((index != 1) && (index !=2)) { 672 printf("index=%d ", index); 673 return -1; 674 } 675 switch (value) { 676 case UHF_PORT_RESET: 677 DPRINTF(D_MSG, ("PORT_RESET ")); 678 WPS(ADMHCD_PRS); 679 break; 680 case UHF_PORT_POWER: 681 DPRINTF(D_MSG, ("PORT_POWER ")); 682 WPS(ADMHCD_PPS); 683 break; 684 case UHF_PORT_ENABLE: 685 DPRINTF(D_MSG, ("PORT_ENABLE ")); 686 WPS(ADMHCD_PES); 687 break; 688 default: 689 printf("SetPortFeatERR=0x%x ", value); 690 return -1; 691 } 692 #undef WPS 693 break; 694 default: 695 DPRINTF(D_MSG, ("ioerr(UR=%02x,UT=%02x) ", 696 req->bRequest, req->bmRequestType)); 697 /* default from usbroothub */ 698 return buflen; 699 } 700 701 return totlen; 702 } 703 704 static usbd_status 705 ahci_root_intr_transfer(struct usbd_xfer *xfer) 706 { 707 struct ahci_softc *sc = AHCI_XFER2SC(xfer); 708 usbd_status error; 709 710 DPRINTF(D_TRACE, ("SLRItransfer ")); 711 712 /* Insert last in queue */ 713 mutex_enter(&sc->sc_lock); 714 error = usb_insert_transfer(xfer); 715 mutex_exit(&sc->sc_lock); 716 if (error) 717 return error; 718 719 /* 720 * Pipe isn't running (otherwise error would be USBD_INPROG), 721 * start first. 722 */ 723 return ahci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 724 } 725 726 static usbd_status 727 ahci_root_intr_start(struct usbd_xfer *xfer) 728 { 729 struct ahci_softc *sc = AHCI_XFER2SC(xfer); 730 731 DPRINTF(D_TRACE, ("SLRIstart ")); 732 733 sc->sc_interval = MS_TO_TICKS(xfer->ux_pipe->up_endpoint->ue_edesc->bInterval); 734 callout_reset(&sc->sc_poll_handle, sc->sc_interval, ahci_poll_hub, xfer); 735 sc->sc_intr_xfer = xfer; 736 return USBD_IN_PROGRESS; 737 } 738 739 static void 740 ahci_root_intr_abort(struct usbd_xfer *xfer) 741 { 742 DPRINTF(D_TRACE, ("SLRIabort ")); 743 } 744 745 static void 746 ahci_root_intr_close(struct usbd_pipe *pipe) 747 { 748 struct ahci_softc *sc = AHCI_PIPE2SC(pipe); 749 750 DPRINTF(D_TRACE, ("SLRIclose ")); 751 752 callout_stop(&sc->sc_poll_handle); 753 sc->sc_intr_xfer = NULL; 754 } 755 756 static void 757 ahci_root_intr_done(struct usbd_xfer *xfer) 758 { 759 //DPRINTF(D_XFER, ("RIdn ")); 760 } 761 762 static usbd_status 763 ahci_device_ctrl_transfer(struct usbd_xfer *xfer) 764 { 765 struct ahci_softc *sc = AHCI_XFER2SC(xfer); 766 usbd_status error; 767 768 DPRINTF(D_TRACE, ("C")); 769 770 mutex_enter(&sc->sc_lock); 771 error = usb_insert_transfer(xfer); 772 mutex_exit(&sc->sc_lock); 773 if (error) 774 return error; 775 776 return ahci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 777 } 778 779 static usbd_status 780 ahci_device_ctrl_start(struct usbd_xfer *xfer) 781 { 782 usbd_status status = USBD_NORMAL_COMPLETION; 783 int s, err; 784 static struct admhcd_ed ep_v __attribute__((aligned(16))), *ep; 785 static struct admhcd_td td_v[4] __attribute__((aligned(16))), *td, *td1, *td2, *td3; 786 static usb_dma_t reqdma; 787 struct usbd_pipe *pipe = xfer->ux_pipe; 788 usb_device_request_t *req = &xfer->ux_request; 789 struct ahci_softc *sc = AHCI_XFER2SC(xfer); 790 int len, isread; 791 792 793 #if 0 794 struct ahci_pipe *apipe = (struct ahci_pipe *)xfer->ux_pipe; 795 #endif 796 mutex_enter(&sc->sc_lock); 797 /* printf("ctrl_start>>>\n"); */ 798 799 #ifdef DIAGNOSTIC 800 if (!(xfer->ux_rqflags & URQ_REQUEST)) { 801 /* XXX panic */ 802 printf("ahci_device_ctrl_transfer: not a request\n"); 803 return USBD_INVAL; 804 } 805 #endif 806 807 #define KSEG1ADDR(x) (0xa0000000 | (((uint32_t)x) & 0x1fffffff)) 808 DPRINTF(D_TRACE, ("st ")); 809 if (!ep) { 810 ep = (struct admhcd_ed *)KSEG1ADDR(&ep_v); 811 td = (struct admhcd_td *)KSEG1ADDR(&td_v[0]); 812 td1 = (struct admhcd_td *)KSEG1ADDR(&td_v[1]); 813 td2 = (struct admhcd_td *)KSEG1ADDR(&td_v[2]); 814 td3 = (struct admhcd_td *)KSEG1ADDR(&td_v[3]); 815 err = usb_allocmem(&sc->sc_bus, 816 sizeof(usb_device_request_t), 817 0, &reqdma); 818 if (err) 819 return USBD_NOMEM; 820 821 /* printf("ep: %p\n",ep); */ 822 }; 823 824 ep->control = pipe->up_dev->ud_addr | \ 825 ((pipe->up_dev->ud_speed==USB_SPEED_FULL)?ADMHCD_ED_SPEED:0) | \ 826 ((UGETW(pipe->up_endpoint->ue_edesc->wMaxPacketSize))<<ADMHCD_ED_MAXSHIFT); 827 memcpy(KERNADDR(&reqdma, 0), req, sizeof *req); 828 /* printf("status: %x\n",REG_READ(ADMHCD_REG_PORTSTATUS0)); 829 printf("ep_control: %x\n",ep->control); 830 printf("speed: %x\n",pipe->up_dev->ud_speed); 831 printf("req: %p\n",req); 832 printf("dmabuf: %p\n",xfer->ux_dmabuf.block); */ 833 834 isread = req->bmRequestType & UT_READ; 835 len = UGETW(req->wLength); 836 837 ep->next = ep; 838 839 td->buffer = DMAADDR(&reqdma,0) | 0xa0000000; 840 td->buflen=sizeof(*req); 841 td->control=ADMHCD_TD_SETUP | ADMHCD_TD_DATA0 | ADMHCD_TD_OWN; 842 843 if (len) { 844 td->next = td1; 845 846 td1->buffer = DMAADDR(&xfer->ux_dmabuf,0) | 0xa0000000; 847 td1->buflen = len; 848 td1->next = td2; 849 td1->control= (isread?ADMHCD_TD_IN:ADMHCD_TD_OUT) | ADMHCD_TD_DATA1 | ADMHCD_TD_R | ADMHCD_TD_OWN; 850 } else { 851 td1->control = 0; 852 td->next = td2; 853 }; 854 855 td2->buffer = 0; 856 td2->buflen= 0; 857 td2->next = td3; 858 td2->control = (isread?ADMHCD_TD_OUT:ADMHCD_TD_IN) | ADMHCD_TD_DATA1 | ADMHCD_TD_OWN; 859 860 td3->buffer = 0; 861 td3->buflen= 0; 862 td3->next = 0; 863 td3->control = 0; 864 865 ep->head = td; 866 ep->tail = td3; 867 /* 868 printf("ep: %p\n",ep); 869 printf("ep->next: %p\n",ep->next); 870 printf("ep->head: %p\n",ep->head); 871 printf("ep->tail: %p\n",ep->tail); 872 printf("td: %p\n",td); 873 printf("td->next: %p\n",td->next); 874 printf("td->buffer: %x\n",td->buffer); 875 printf("td->buflen: %x\n",td->buflen); 876 printf("td1: %p\n",td1); 877 printf("td1->next: %p\n",td1->next); 878 printf("td2: %p\n",td2); 879 printf("td2->next: %p\n",td2->next); 880 printf("td3: %p\n",td3); 881 printf("td3->next: %p\n",td3->next); 882 */ 883 884 REG_WRITE(ADMHCD_REG_HOSTHEAD, (uint32_t)ep); 885 REG_WRITE(ADMHCD_REG_HOSTCONTROL, ADMHCD_STATE_OP | ADMHCD_DMA_EN); 886 /* printf("1: %x %x %x %x\n", ep->control, td->control, td1->control, td2->control); */ 887 s=100; 888 while (s--) { 889 delay_ms(10); 890 /* printf("%x %x %x %x\n", ep->control, td->control, td1->control, td2->control);*/ 891 status = USBD_TIMEOUT; 892 if (td->control & ADMHCD_TD_OWN) continue; 893 894 err = (td->control & ADMHCD_TD_ERRMASK)>>ADMHCD_TD_ERRSHIFT; 895 if (err) { 896 status = USBD_IOERROR; 897 break; 898 }; 899 900 status = USBD_TIMEOUT; 901 if (td1->control & ADMHCD_TD_OWN) continue; 902 err = (td1->control & ADMHCD_TD_ERRMASK)>>ADMHCD_TD_ERRSHIFT; 903 if (err) { 904 status = USBD_IOERROR; 905 break; 906 }; 907 908 status = USBD_TIMEOUT; 909 if (td2->control & ADMHCD_TD_OWN) continue; 910 err = (td2->control & ADMHCD_TD_ERRMASK)>>ADMHCD_TD_ERRSHIFT; 911 if (err) { 912 status = USBD_IOERROR; 913 }; 914 status = USBD_NORMAL_COMPLETION; 915 break; 916 917 }; 918 REG_WRITE(ADMHCD_REG_HOSTCONTROL, ADMHCD_STATE_OP); 919 920 xfer->ux_actlen = len; 921 xfer->ux_status = status; 922 923 /* printf("ctrl_start<<<\n"); */ 924 925 usb_transfer_complete(xfer); 926 mutex_exit(&sc->sc_lock); 927 return USBD_NORMAL_COMPLETION; 928 } 929 930 static void 931 ahci_device_ctrl_abort(struct usbd_xfer *xfer) 932 { 933 DPRINTF(D_TRACE, ("Cab ")); 934 ahci_abort_xfer(xfer, USBD_CANCELLED); 935 } 936 937 static void 938 ahci_device_ctrl_close(struct usbd_pipe *pipe) 939 { 940 DPRINTF(D_TRACE, ("Ccl ")); 941 } 942 943 static void 944 ahci_device_ctrl_done(struct usbd_xfer *xfer) 945 { 946 DPRINTF(D_TRACE, ("Cdn ")); 947 } 948 949 static usbd_status 950 ahci_device_intr_transfer(struct usbd_xfer *xfer) 951 { 952 struct ahci_softc *sc = AHCI_XFER2SC(xfer); 953 usbd_status error; 954 955 DPRINTF(D_TRACE, ("INTRtrans ")); 956 957 mutex_enter(&sc->sc_lock); 958 error = usb_insert_transfer(xfer); 959 mutex_exit(&sc->sc_lock); 960 if (error) 961 return error; 962 963 return ahci_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 964 } 965 966 static usbd_status 967 ahci_device_intr_start(struct usbd_xfer *xfer) 968 { 969 struct usbd_pipe *pipe = xfer->ux_pipe; 970 struct ahci_xfer *sx; 971 972 DPRINTF(D_TRACE, ("INTRstart ")); 973 974 sx = kmem_intr_alloc(sizeof(*sx), KM_NOSLEEP); 975 if (sx == NULL) 976 goto reterr; 977 memset(sx, 0, sizeof(*sx)); 978 sx->sx_xfer = xfer; 979 xfer->ux_hcpriv = sx; 980 981 /* initialize callout */ 982 callout_init(&sx->sx_callout_t, 0); 983 callout_reset(&sx->sx_callout_t, 984 MS_TO_TICKS(pipe->up_endpoint->ue_edesc->bInterval), 985 ahci_poll_device, sx); 986 987 /* ACK */ 988 return USBD_IN_PROGRESS; 989 990 reterr: 991 return USBD_IOERROR; 992 } 993 994 static void 995 ahci_poll_device(void *arg) 996 { 997 struct ahci_xfer *sx = (struct ahci_xfer *)arg; 998 struct usbd_xfer *xfer = sx->sx_xfer; 999 struct usbd_pipe *pipe = xfer->ux_pipe; 1000 struct ahci_softc *sc = AHCI_XFER2SC(xfer); 1001 void *buf; 1002 int pid; 1003 int r; 1004 1005 DPRINTF(D_TRACE, ("pldev")); 1006 1007 callout_reset(&sx->sx_callout_t, 1008 MS_TO_TICKS(pipe->up_endpoint->ue_edesc->bInterval), 1009 ahci_poll_device, sx); 1010 1011 /* interrupt transfer */ 1012 pid = (UE_GET_DIR(pipe->up_endpoint->ue_edesc->bEndpointAddress) == UE_DIR_IN) 1013 ? ADMHCD_TD_IN : ADMHCD_TD_OUT; 1014 buf = KERNADDR(&xfer->ux_dmabuf, 0); 1015 1016 r = ahci_transaction(sc, pipe, pid, xfer->ux_length, buf, 0/*toggle*/); 1017 if (r < 0) { 1018 DPRINTF(D_MSG, ("%s error", __func__)); 1019 return; 1020 } 1021 /* no change, return NAK */ 1022 if (r == 0) 1023 return; 1024 1025 xfer->ux_status = USBD_NORMAL_COMPLETION; 1026 mutex_enter(&sc->sc_lock); 1027 usb_transfer_complete(xfer); 1028 mutex_exit(&sc->sc_lock); 1029 } 1030 1031 static void 1032 ahci_device_intr_abort(struct usbd_xfer *xfer) 1033 { 1034 struct ahci_xfer *sx; 1035 1036 DPRINTF(D_TRACE, ("INTRabort ")); 1037 1038 sx = xfer->ux_hcpriv; 1039 if (sx) { 1040 callout_stop(&sx->sx_callout_t); 1041 kmem_intr_free(sx, sizeof(*sx)); 1042 xfer->ux_hcpriv = NULL; 1043 } else { 1044 printf("%s: sx == NULL!\n", __func__); 1045 } 1046 ahci_abort_xfer(xfer, USBD_CANCELLED); 1047 } 1048 1049 static void 1050 ahci_device_intr_close(struct usbd_pipe *pipe) 1051 { 1052 DPRINTF(D_TRACE, ("INTRclose ")); 1053 } 1054 1055 static void 1056 ahci_device_intr_done(struct usbd_xfer *xfer) 1057 { 1058 DPRINTF(D_TRACE, ("INTRdone ")); 1059 } 1060 1061 static usbd_status 1062 ahci_device_isoc_transfer(struct usbd_xfer *xfer) 1063 { 1064 DPRINTF(D_TRACE, ("S")); 1065 return USBD_NORMAL_COMPLETION; 1066 } 1067 1068 static usbd_status 1069 ahci_device_isoc_start(struct usbd_xfer *xfer) 1070 { 1071 DPRINTF(D_TRACE, ("st ")); 1072 return USBD_NORMAL_COMPLETION; 1073 } 1074 1075 static void 1076 ahci_device_isoc_abort(struct usbd_xfer *xfer) 1077 { 1078 DPRINTF(D_TRACE, ("Sab ")); 1079 } 1080 1081 static void 1082 ahci_device_isoc_close(struct usbd_pipe *pipe) 1083 { 1084 DPRINTF(D_TRACE, ("Scl ")); 1085 } 1086 1087 static void 1088 ahci_device_isoc_done(struct usbd_xfer *xfer) 1089 { 1090 DPRINTF(D_TRACE, ("Sdn ")); 1091 } 1092 1093 static usbd_status 1094 ahci_device_bulk_transfer(struct usbd_xfer *xfer) 1095 { 1096 struct ahci_softc *sc = AHCI_XFER2SC(xfer); 1097 usbd_status error; 1098 1099 DPRINTF(D_TRACE, ("B")); 1100 1101 mutex_enter(&sc->sc_lock); 1102 error = usb_insert_transfer(xfer); 1103 mutex_exit(&sc->sc_lock); 1104 if (error) 1105 return error; 1106 1107 return ahci_device_bulk_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 1108 } 1109 1110 static usbd_status 1111 ahci_device_bulk_start(struct usbd_xfer *xfer) 1112 { 1113 #define NBULK_TDS 32 1114 static volatile int level = 0; 1115 usbd_status status = USBD_NORMAL_COMPLETION; 1116 int s, err; 1117 static struct admhcd_ed ep_v __attribute__((aligned(16))), *ep; 1118 static struct admhcd_td td_v[NBULK_TDS] __attribute__((aligned(16))), *td[NBULK_TDS]; 1119 struct usbd_pipe *pipe = xfer->ux_pipe; 1120 struct ahci_softc *sc = AHCI_XFER2SC(xfer); 1121 int endpt, i, len, tlen, segs, offset, isread, toggle, short_ok; 1122 struct ahci_pipe *apipe = (struct ahci_pipe *)xfer->ux_pipe; 1123 1124 #define KSEG1ADDR(x) (0xa0000000 | (((uint32_t)x) & 0x1fffffff)) 1125 DPRINTF(D_TRACE, ("st ")); 1126 1127 #ifdef DIAGNOSTIC 1128 if (xfer->ux_rqflags & URQ_REQUEST) { 1129 /* XXX panic */ 1130 printf("ohci_device_bulk_start: a request\n"); 1131 return USBD_INVAL; 1132 } 1133 #endif 1134 1135 mutex_enter(&sc->sc_lock); 1136 level++; 1137 /* printf("bulk_start>>>\n"); */ 1138 1139 if (!ep) { 1140 ep = (struct admhcd_ed *)KSEG1ADDR(&ep_v); 1141 for (i=0; i<NBULK_TDS; i++) { 1142 td[i] = (struct admhcd_td *)KSEG1ADDR(&td_v[i]); 1143 }; 1144 /* printf("ep: %p\n",ep);*/ 1145 }; 1146 if (apipe->toggle == 0) { 1147 toggle = ADMHCD_TD_DATA0; 1148 } else { 1149 toggle = apipe->toggle; 1150 }; 1151 1152 endpt = pipe->up_endpoint->ue_edesc->bEndpointAddress; 1153 ep->control = pipe->up_dev->ud_addr | ((endpt & 0xf) << ADMHCD_ED_EPSHIFT)|\ 1154 ((pipe->up_dev->ud_speed==USB_SPEED_FULL)?ADMHCD_ED_SPEED:0) | \ 1155 ((UGETW(pipe->up_endpoint->ue_edesc->wMaxPacketSize))<<ADMHCD_ED_MAXSHIFT); 1156 1157 short_ok = xfer->ux_flags & USBD_SHORT_XFER_OK?ADMHCD_TD_R:0; 1158 /* printf("level: %d\n",level); 1159 printf("short_xfer: %x\n",short_ok); 1160 printf("ep_control: %x\n",ep->control); 1161 printf("speed: %x\n",pipe->up_dev->ud_speed); 1162 printf("dmabuf: %p\n",xfer->ux_dmabuf.block); */ 1163 1164 isread = UE_GET_DIR(endpt) == UE_DIR_IN; 1165 len = xfer->ux_length; 1166 1167 ep->next = ep; 1168 1169 i = 0; 1170 offset = 0; 1171 while ((len>0) || (i==0)) { 1172 tlen = min(len,4096); 1173 td[i]->buffer = DMAADDR(&xfer->ux_dmabuf,offset) | 0xa0000000; 1174 td[i]->buflen=tlen; 1175 td[i]->control=(isread?ADMHCD_TD_IN:ADMHCD_TD_OUT) | toggle | ADMHCD_TD_OWN | short_ok; 1176 td[i]->len=tlen; 1177 toggle = ADMHCD_TD_TOGGLE; 1178 len -= tlen; 1179 offset += tlen; 1180 td[i]->next = td[i+1]; 1181 i++; 1182 }; 1183 1184 td[i]->buffer = 0; 1185 td[i]->buflen = 0; 1186 td[i]->control = 0; 1187 td[i]->next = 0; 1188 1189 ep->head = td[0]; 1190 ep->tail = td[i]; 1191 segs = i; 1192 len = 0; 1193 1194 /* printf("segs: %d\n",segs); 1195 printf("ep: %p\n",ep); 1196 printf("ep->control: %x\n",ep->control); 1197 printf("ep->next: %p\n",ep->next); 1198 printf("ep->head: %p\n",ep->head); 1199 printf("ep->tail: %p\n",ep->tail); 1200 for (i=0; i<segs; i++) { 1201 printf("td[%d]: %p\n",i,td[i]); 1202 printf("td[%d]->control: %x\n",i,td[i]->control); 1203 printf("td[%d]->next: %p\n",i,td[i]->next); 1204 printf("td[%d]->buffer: %x\n",i,td[i]->buffer); 1205 printf("td[%d]->buflen: %x\n",i,td[i]->buflen); 1206 }; */ 1207 1208 REG_WRITE(ADMHCD_REG_HOSTHEAD, (uint32_t)ep); 1209 REG_WRITE(ADMHCD_REG_HOSTCONTROL, ADMHCD_STATE_OP | ADMHCD_DMA_EN); 1210 i = 0; 1211 /* printf("1: %x %d %x %x\n", ep->control, i, td[i]->control, td[i]->buflen); */ 1212 s=100; 1213 err = 0; 1214 while (s--) { 1215 /* printf("%x %d %x %x\n", ep->control, i, td[i]->control, td[i]->buflen); */ 1216 status = USBD_TIMEOUT; 1217 if (td[i]->control & ADMHCD_TD_OWN) { 1218 delay_ms(3); 1219 continue; 1220 }; 1221 1222 len += td[i]->len - td[i]->buflen; 1223 1224 err = (td[i]->control & ADMHCD_TD_ERRMASK)>>ADMHCD_TD_ERRSHIFT; 1225 if (err) { 1226 status = USBD_IOERROR; 1227 break; 1228 }; 1229 1230 i++; 1231 if (i==segs) { 1232 status = USBD_NORMAL_COMPLETION; 1233 break; 1234 }; 1235 1236 }; 1237 REG_WRITE(ADMHCD_REG_HOSTCONTROL, ADMHCD_STATE_OP); 1238 1239 apipe->toggle = ((uint32_t)ep->head & 2)?ADMHCD_TD_DATA1:ADMHCD_TD_DATA0; 1240 /* printf("bulk_transfer_done: status: %x, err: %x, len: %x, toggle: %x\n", status,err,len,apipe->toggle); */ 1241 1242 if (short_ok && (err == 0x9 || err == 0xd)) { 1243 /* printf("bulk_transfer_done: short_transfer fix\n"); */ 1244 status = USBD_NORMAL_COMPLETION; 1245 }; 1246 xfer->ux_actlen = len; 1247 xfer->ux_status = status; 1248 1249 level--; 1250 /* printf("bulk_start<<<\n"); */ 1251 1252 usb_transfer_complete(xfer); 1253 mutex_exit(&sc->sc_lock); 1254 1255 return USBD_NORMAL_COMPLETION; 1256 } 1257 1258 static void 1259 ahci_device_bulk_abort(struct usbd_xfer *xfer) 1260 { 1261 DPRINTF(D_TRACE, ("Bab ")); 1262 ahci_abort_xfer(xfer, USBD_CANCELLED); 1263 } 1264 1265 static void 1266 ahci_device_bulk_close(struct usbd_pipe *pipe) 1267 { 1268 DPRINTF(D_TRACE, ("Bcl ")); 1269 } 1270 1271 static void 1272 ahci_device_bulk_done(struct usbd_xfer *xfer) 1273 { 1274 DPRINTF(D_TRACE, ("Bdn ")); 1275 } 1276 1277 #define DATA0_RD (0x03) 1278 #define DATA0_WR (0x07) 1279 #define AHCI_TIMEOUT (5000) 1280 1281 /* 1282 * Do a transaction. 1283 * return 1 if ACK, 0 if NAK, -1 if error. 1284 */ 1285 static int 1286 ahci_transaction(struct ahci_softc *sc, struct usbd_pipe *pipe, 1287 uint8_t pid, int len, u_char *buf, uint8_t toggle) 1288 { 1289 return -1; 1290 #if 0 1291 #ifdef AHCI_DEBUG 1292 char str[64]; 1293 int i; 1294 #endif 1295 int timeout; 1296 int ls_via_hub = 0; 1297 int pl; 1298 uint8_t isr; 1299 uint8_t result = 0; 1300 uint8_t devaddr = pipe->up_dev->ud_addr; 1301 uint8_t endpointaddr = pipe->up_endpoint->ue_edesc->bEndpointAddress; 1302 uint8_t endpoint; 1303 uint8_t cmd = DATA0_RD; 1304 1305 endpoint = UE_GET_ADDR(endpointaddr); 1306 DPRINTF(D_XFER, ("\n(%x,%d%s%d,%d) ", 1307 pid, len, (pid == SL11_PID_IN) ? "<-" : "->", devaddr, endpoint)); 1308 1309 /* Set registers */ 1310 sl11write(sc, SL11_E0ADDR, 0x40); 1311 sl11write(sc, SL11_E0LEN, len); 1312 sl11write(sc, SL11_E0PID, (pid << 4) + endpoint); 1313 sl11write(sc, SL11_E0DEV, devaddr); 1314 1315 /* Set buffer unless PID_IN */ 1316 if (pid != SL11_PID_IN) { 1317 if (len > 0) 1318 sl11write_region(sc, 0x40, buf, len); 1319 cmd = DATA0_WR; 1320 } 1321 1322 /* timing ? */ 1323 pl = (len >> 3) + 3; 1324 1325 /* Low speed device via HUB */ 1326 /* XXX does not work... */ 1327 if ((sc->sc_fullspeed) && pipe->up_dev->ud_speed == USB_SPEED_LOW) { 1328 pl = len + 16; 1329 cmd |= SL11_EPCTRL_PREAMBLE; 1330 1331 /* 1332 * SL811HS/T rev 1.2 has a bug, when it got PID_IN 1333 * from LowSpeed device via HUB. 1334 */ 1335 if (sc->sc_sltype == SLTYPE_SL811HS_R12 && pid == SL11_PID_IN) { 1336 ls_via_hub = 1; 1337 DPRINTF(D_MSG, ("LSvH ")); 1338 } 1339 } 1340 1341 /* timing ? */ 1342 if (sl11read(sc, SL811_CSOF) <= (uint8_t)pl) 1343 cmd |= SL11_EPCTRL_SOF; 1344 1345 /* Transfer */ 1346 sl11write(sc, SL11_ISR, 0xff); 1347 sl11write(sc, SL11_E0CTRL, cmd | toggle); 1348 1349 /* Polling */ 1350 for (timeout = AHCI_TIMEOUT; timeout; timeout--) { 1351 isr = sl11read(sc, SL11_ISR); 1352 if ((isr & SL11_ISR_USBA)) 1353 break; 1354 } 1355 1356 /* Check result status */ 1357 result = sl11read(sc, SL11_E0STAT); 1358 if (!(result & SL11_EPSTAT_NAK) && ls_via_hub) { 1359 /* Resend PID_IN within 20usec */ 1360 sl11write(sc, SL11_ISR, 0xff); 1361 sl11write(sc, SL11_E0CTRL, SL11_EPCTRL_ARM); 1362 } 1363 1364 sl11write(sc, SL11_ISR, 0xff); 1365 1366 DPRINTF(D_XFER, ("t=%d i=%x ", AHCI_TIMEOUT - timeout, isr)); 1367 #if AHCI_DEBUG 1368 snprintb(str, sizeof(str), 1369 "\20\x8STALL\7NAK\6OV\5SETUP\4DATA1\3TIMEOUT\2ERR\1ACK", result); 1370 DPRINTF(D_XFER, ("STAT=%s ", str)); 1371 #endif 1372 1373 if ((result & SL11_EPSTAT_ERROR)) 1374 return -1; 1375 1376 if ((result & SL11_EPSTAT_NAK)) 1377 return 0; 1378 1379 /* Read buffer if PID_IN */ 1380 if (pid == SL11_PID_IN && len > 0) { 1381 sl11read_region(sc, buf, 0x40, len); 1382 #if AHCI_DEBUG 1383 for (i = 0; i < len; i++) 1384 DPRINTF(D_XFER, ("%02X ", buf[i])); 1385 #endif 1386 } 1387 1388 return 1; 1389 #endif 1390 } 1391 1392 void 1393 ahci_abort_xfer(struct usbd_xfer *xfer, usbd_status status) 1394 { 1395 xfer->ux_status = status; 1396 usb_transfer_complete(xfer); 1397 } 1398 1399 void 1400 ahci_device_clear_toggle(struct usbd_pipe *pipe) 1401 { 1402 struct ahci_pipe *apipe = (struct ahci_pipe *)pipe; 1403 apipe->toggle = 0; 1404 } 1405 1406 #ifdef AHCI_DEBUG 1407 void 1408 print_req(usb_device_request_t *r) 1409 { 1410 const char *xmes[]={ 1411 "GETSTAT", 1412 "CLRFEAT", 1413 "res", 1414 "SETFEAT", 1415 "res", 1416 "SETADDR", 1417 "GETDESC", 1418 "SETDESC", 1419 "GETCONF", 1420 "SETCONF", 1421 "GETIN/F", 1422 "SETIN/F", 1423 "SYNC_FR" 1424 }; 1425 int req, type, value, index, len; 1426 1427 req = r->bRequest; 1428 type = r->bmRequestType; 1429 value = UGETW(r->wValue); 1430 index = UGETW(r->wIndex); 1431 len = UGETW(r->wLength); 1432 1433 printf("%x,%s,v=%d,i=%d,l=%d ", 1434 type, xmes[req], value, index, len); 1435 } 1436 1437 void 1438 print_req_hub(usb_device_request_t *r) 1439 { 1440 struct { 1441 int req; 1442 int type; 1443 const char *str; 1444 } conf[] = { 1445 { 1, 0x20, "ClrHubFeat" }, 1446 { 1, 0x23, "ClrPortFeat" }, 1447 { 2, 0xa3, "GetBusState" }, 1448 { 6, 0xa0, "GetHubDesc" }, 1449 { 0, 0xa0, "GetHubStat" }, 1450 { 0, 0xa3, "GetPortStat" }, 1451 { 7, 0x20, "SetHubDesc" }, 1452 { 3, 0x20, "SetHubFeat" }, 1453 { 3, 0x23, "SetPortFeat" }, 1454 {-1, 0, NULL}, 1455 }; 1456 int i; 1457 int value, index, len; 1458 1459 value = UGETW(r->wValue); 1460 index = UGETW(r->wIndex); 1461 len = UGETW(r->wLength); 1462 for (i = 0; ; i++) { 1463 if (conf[i].req == -1 ) 1464 return print_req(r); 1465 if (r->bmRequestType == conf[i].type && r->bRequest == conf[i].req) { 1466 printf("%s", conf[i].str); 1467 break; 1468 } 1469 } 1470 printf(",v=%d,i=%d,l=%d ", value, index, len); 1471 } 1472 1473 void 1474 print_dumpreg(struct ahci_softc *sc) 1475 { 1476 #if 0 1477 printf("00=%02x,01=%02x,02=%02x,03=%02x,04=%02x," 1478 "08=%02x,09=%02x,0A=%02x,0B=%02x,0C=%02x,", 1479 sl11read(sc, 0), sl11read(sc, 1), 1480 sl11read(sc, 2), sl11read(sc, 3), 1481 sl11read(sc, 4), sl11read(sc, 8), 1482 sl11read(sc, 9), sl11read(sc, 10), 1483 sl11read(sc, 11), sl11read(sc, 12) 1484 ); 1485 printf("CR1=%02x,IER=%02x,0D=%02x,0E=%02x,0F=%02x ", 1486 sl11read(sc, 5), sl11read(sc, 6), 1487 sl11read(sc, 13), sl11read(sc, 14), sl11read(sc, 15) 1488 ); 1489 #endif 1490 } 1491 1492 void 1493 print_xfer(struct usbd_xfer *xfer) 1494 { 1495 printf("xfer: length=%d, actlen=%d, flags=%x, timeout=%d,", 1496 xfer->ux_length, xfer->ux_actlen, xfer->ux_flags, xfer->ux_timeout); 1497 printf("request{ "); 1498 print_req_hub(&xfer->ux_request); 1499 printf("} "); 1500 } 1501 #endif /* AHCI_DEBUG */ 1502