1 /* 2 * Copyright 2006-2008, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Michael Lotz <mmlr@mlotz.ch> 7 */ 8 9 #include <module.h> 10 #include <PCI.h> 11 #include <USB3.h> 12 #include <KernelExport.h> 13 14 #include "ehci.h" 15 16 #define USB_MODULE_NAME "ehci" 17 18 pci_module_info *EHCI::sPCIModule = NULL; 19 20 21 static int32 22 ehci_std_ops(int32 op, ...) 23 { 24 switch (op) { 25 case B_MODULE_INIT: 26 TRACE_MODULE("ehci init module\n"); 27 return B_OK; 28 case B_MODULE_UNINIT: 29 TRACE_MODULE("ehci uninit module\n"); 30 return B_OK; 31 } 32 33 return EINVAL; 34 } 35 36 37 usb_host_controller_info ehci_module = { 38 { 39 "busses/usb/ehci", 40 0, 41 ehci_std_ops 42 }, 43 NULL, 44 EHCI::AddTo 45 }; 46 47 48 module_info *modules[] = { 49 (module_info *)&ehci_module, 50 NULL 51 }; 52 53 54 // 55 // #pragma mark - 56 // 57 58 59 #ifdef TRACE_USB 60 61 void 62 print_descriptor_chain(ehci_qtd *descriptor) 63 { 64 while (descriptor) { 65 dprintf(" %08lx n%08lx a%08lx t%08lx %08lx %08lx %08lx %08lx %08lx s%ld\n", 66 descriptor->this_phy, descriptor->next_phy, 67 descriptor->alt_next_phy, descriptor->token, 68 descriptor->buffer_phy[0], descriptor->buffer_phy[1], 69 descriptor->buffer_phy[2], descriptor->buffer_phy[3], 70 descriptor->buffer_phy[4], descriptor->buffer_size); 71 72 if (descriptor->next_phy & EHCI_QTD_TERMINATE) 73 break; 74 75 descriptor = (ehci_qtd *)descriptor->next_log; 76 } 77 } 78 79 void 80 print_queue(ehci_qh *queueHead) 81 { 82 dprintf("queue: t%08lx n%08lx ch%08lx ca%08lx cu%08lx\n", 83 queueHead->this_phy, queueHead->next_phy, queueHead->endpoint_chars, 84 queueHead->endpoint_caps, queueHead->current_qtd_phy); 85 dprintf("overlay: n%08lx a%08lx t%08lx %08lx %08lx %08lx %08lx %08lx\n", 86 queueHead->overlay.next_phy, queueHead->overlay.alt_next_phy, 87 queueHead->overlay.token, queueHead->overlay.buffer_phy[0], 88 queueHead->overlay.buffer_phy[1], queueHead->overlay.buffer_phy[2], 89 queueHead->overlay.buffer_phy[3], queueHead->overlay.buffer_phy[4]); 90 print_descriptor_chain((ehci_qtd *)queueHead->element_log); 91 } 92 93 #endif // TRACE_USB 94 95 96 // 97 // #pragma mark - 98 // 99 100 101 EHCI::EHCI(pci_info *info, Stack *stack) 102 : BusManager(stack), 103 fCapabilityRegisters(NULL), 104 fOperationalRegisters(NULL), 105 fRegisterArea(-1), 106 fPCIInfo(info), 107 fStack(stack), 108 fEnabledInterrupts(0), 109 fPeriodicFrameListArea(-1), 110 fPeriodicFrameList(NULL), 111 fInterruptEntries(NULL), 112 fAsyncQueueHead(NULL), 113 fAsyncAdvanceSem(-1), 114 fFirstTransfer(NULL), 115 fLastTransfer(NULL), 116 fFinishTransfersSem(-1), 117 fFinishThread(-1), 118 fCleanupSem(-1), 119 fCleanupThread(-1), 120 fStopThreads(false), 121 fFreeListHead(NULL), 122 fProcessingPipe(NULL), 123 fRootHub(NULL), 124 fRootHubAddress(0), 125 fPortCount(0), 126 fPortResetChange(0), 127 fPortSuspendChange(0) 128 { 129 if (BusManager::InitCheck() < B_OK) { 130 TRACE_ERROR("bus manager failed to init\n"); 131 return; 132 } 133 134 TRACE("constructing new EHCI host controller driver\n"); 135 fInitOK = false; 136 137 // enable busmaster and memory mapped access 138 uint16 command = sPCIModule->read_pci_config(fPCIInfo->bus, 139 fPCIInfo->device, fPCIInfo->function, PCI_command, 2); 140 command &= ~PCI_command_io; 141 command |= PCI_command_master | PCI_command_memory; 142 143 sPCIModule->write_pci_config(fPCIInfo->bus, fPCIInfo->device, 144 fPCIInfo->function, PCI_command, 2, command); 145 146 // map the registers 147 uint32 offset = fPCIInfo->u.h0.base_registers[0] & (B_PAGE_SIZE - 1); 148 addr_t physicalAddress = fPCIInfo->u.h0.base_registers[0] - offset; 149 size_t mapSize = (fPCIInfo->u.h0.base_register_sizes[0] + offset 150 + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); 151 152 TRACE("map physical memory 0x%08lx (base: 0x%08lx; offset: %lx); size: %ld\n", 153 fPCIInfo->u.h0.base_registers[0], physicalAddress, offset, 154 fPCIInfo->u.h0.base_register_sizes[0]); 155 156 fRegisterArea = map_physical_memory("EHCI memory mapped registers", 157 (void *)physicalAddress, mapSize, B_ANY_KERNEL_BLOCK_ADDRESS, 158 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_READ_AREA | B_WRITE_AREA, 159 (void **)&fCapabilityRegisters); 160 if (fRegisterArea < B_OK) { 161 TRACE("failed to map register memory\n"); 162 return; 163 } 164 165 fCapabilityRegisters += offset; 166 fOperationalRegisters = fCapabilityRegisters + ReadCapReg8(EHCI_CAPLENGTH); 167 TRACE("mapped capability registers: 0x%08lx\n", (uint32)fCapabilityRegisters); 168 TRACE("mapped operational registers: 0x%08lx\n", (uint32)fOperationalRegisters); 169 170 TRACE("structural parameters: 0x%08lx\n", ReadCapReg32(EHCI_HCSPARAMS)); 171 TRACE("capability parameters: 0x%08lx\n", ReadCapReg32(EHCI_HCCPARAMS)); 172 173 // read port count from capability register 174 fPortCount = ReadCapReg32(EHCI_HCSPARAMS) & 0x0f; 175 176 uint32 extendedCapPointer = ReadCapReg32(EHCI_HCCPARAMS) >> EHCI_ECP_SHIFT; 177 extendedCapPointer &= EHCI_ECP_MASK; 178 if (extendedCapPointer > 0) { 179 TRACE("extended capabilities register at %ld\n", extendedCapPointer); 180 181 uint32 legacySupport = sPCIModule->read_pci_config(fPCIInfo->bus, 182 fPCIInfo->device, fPCIInfo->function, extendedCapPointer, 4); 183 if ((legacySupport & EHCI_LEGSUP_CAPID_MASK) == EHCI_LEGSUP_CAPID) { 184 if (legacySupport & EHCI_LEGSUP_BIOSOWNED) 185 TRACE_ALWAYS("the host controller is bios owned\n"); 186 187 TRACE_ALWAYS("claiming ownership of the host controller\n"); 188 sPCIModule->write_pci_config(fPCIInfo->bus, fPCIInfo->device, 189 fPCIInfo->function, extendedCapPointer + 3, 1, 1); 190 191 for (int32 i = 0; i < 20; i++) { 192 legacySupport = sPCIModule->read_pci_config(fPCIInfo->bus, 193 fPCIInfo->device, fPCIInfo->function, extendedCapPointer, 4); 194 195 if (legacySupport & EHCI_LEGSUP_BIOSOWNED) { 196 TRACE_ALWAYS("controller is still bios owned, waiting\n"); 197 snooze(50000); 198 } else 199 break; 200 } 201 202 if (legacySupport & EHCI_LEGSUP_BIOSOWNED) { 203 TRACE_ERROR("bios won't give up control over the host controller (ignoring)\n"); 204 } else if (legacySupport & EHCI_LEGSUP_OSOWNED) { 205 TRACE_ALWAYS("successfully took ownership of the host controller\n"); 206 } 207 208 // Force off the BIOS owned flag, and clear all SMIs. Some BIOSes 209 // do indicate a successful handover but do not remove their SMIs 210 // and then freeze the system when interrupts are generated. 211 sPCIModule->write_pci_config(fPCIInfo->bus, fPCIInfo->device, 212 fPCIInfo->function, extendedCapPointer + 2, 1, 0); 213 sPCIModule->write_pci_config(fPCIInfo->bus, fPCIInfo->device, 214 fPCIInfo->function, extendedCapPointer + 4, 4, 0); 215 } else { 216 TRACE("extended capability is not a legacy support register\n"); 217 } 218 } else { 219 TRACE("no extended capabilities register\n"); 220 } 221 222 // disable interrupts 223 WriteOpReg(EHCI_USBINTR, 0); 224 225 // reset the host controller 226 if (ControllerReset() < B_OK) { 227 TRACE_ERROR("host controller failed to reset\n"); 228 return; 229 } 230 231 // reset the segment register 232 WriteOpReg(EHCI_CTRDSSEGMENT, 0); 233 234 // create semaphores the finisher thread will wait for 235 fAsyncAdvanceSem = create_sem(0, "EHCI Async Advance"); 236 fFinishTransfersSem = create_sem(0, "EHCI Finish Transfers"); 237 fCleanupSem = create_sem(0, "EHCI Cleanup"); 238 if (fFinishTransfersSem < B_OK || fAsyncAdvanceSem < B_OK 239 || fCleanupSem < B_OK) { 240 TRACE_ERROR("failed to create semaphores\n"); 241 return; 242 } 243 244 // create finisher service thread 245 fFinishThread = spawn_kernel_thread(FinishThread, "ehci finish thread", 246 B_NORMAL_PRIORITY, (void *)this); 247 resume_thread(fFinishThread); 248 249 // create cleanup service thread 250 fCleanupThread = spawn_kernel_thread(CleanupThread, "ehci cleanup thread", 251 B_NORMAL_PRIORITY, (void *)this); 252 resume_thread(fCleanupThread); 253 254 // install the interrupt handler and enable interrupts 255 install_io_interrupt_handler(fPCIInfo->u.h0.interrupt_line, 256 InterruptHandler, (void *)this, 0); 257 fEnabledInterrupts = EHCI_USBINTR_HOSTSYSERR | EHCI_USBINTR_USBERRINT 258 | EHCI_USBINTR_USBINT | EHCI_USBINTR_INTONAA; 259 WriteOpReg(EHCI_USBINTR, fEnabledInterrupts); 260 261 // allocate the periodic frame list 262 fPeriodicFrameListArea = fStack->AllocateArea((void **)&fPeriodicFrameList, 263 (void **)&physicalAddress, B_PAGE_SIZE * 2, "USB EHCI Periodic Framelist"); 264 if (fPeriodicFrameListArea < B_OK) { 265 TRACE_ERROR("unable to allocate periodic framelist\n"); 266 return; 267 } 268 269 // set the periodic frame list base on the controller 270 WriteOpReg(EHCI_PERIODICLISTBASE, (uint32)physicalAddress); 271 272 // create the interrupt entries to support different polling intervals 273 TRACE("creating interrupt entries\n"); 274 addr_t physicalBase = physicalAddress + B_PAGE_SIZE; 275 uint8 *logicalBase = (uint8 *)fPeriodicFrameList + B_PAGE_SIZE; 276 memset(logicalBase, 0, B_PAGE_SIZE); 277 278 fInterruptEntries = (interrupt_entry *)logicalBase; 279 for (int32 i = 0; i < 11; i++) { 280 ehci_qh *queueHead = &fInterruptEntries[i].queue_head; 281 queueHead->this_phy = physicalBase; 282 queueHead->current_qtd_phy = EHCI_QTD_TERMINATE; 283 queueHead->overlay.next_phy = EHCI_QTD_TERMINATE; 284 queueHead->overlay.alt_next_phy = EHCI_QTD_TERMINATE; 285 queueHead->overlay.token = EHCI_QTD_STATUS_HALTED; 286 287 // set dummy endpoint information 288 queueHead->endpoint_chars = EHCI_QH_CHARS_EPS_HIGH 289 | (3 << EHCI_QH_CHARS_RL_SHIFT) | (64 << EHCI_QH_CHARS_MPL_SHIFT) 290 | EHCI_QH_CHARS_TOGGLE; 291 queueHead->endpoint_caps = (1 << EHCI_QH_CAPS_MULT_SHIFT) 292 | (0xff << EHCI_QH_CAPS_ISM_SHIFT); 293 294 physicalBase += sizeof(interrupt_entry); 295 } 296 297 // build flat interrupt tree 298 TRACE("build up interrupt links\n"); 299 uint32 interval = 1024; 300 uint32 intervalIndex = 10; 301 while (interval > 1) { 302 uint32 insertIndex = interval / 2; 303 while (insertIndex < 1024) { 304 uint32 entry = fInterruptEntries[intervalIndex].queue_head.this_phy; 305 fPeriodicFrameList[insertIndex] = entry | EHCI_PFRAMELIST_QH; 306 insertIndex += interval; 307 } 308 309 intervalIndex--; 310 interval /= 2; 311 } 312 313 // setup the empty slot in the list and linking of all -> first 314 ehci_qh *firstLogical = &fInterruptEntries[0].queue_head; 315 uint32 firstPhysical = firstLogical->this_phy | EHCI_QH_TYPE_QH; 316 fPeriodicFrameList[0] = firstPhysical; 317 for (int32 i = 1; i < 11; i++) { 318 fInterruptEntries[i].queue_head.next_phy = firstPhysical; 319 fInterruptEntries[i].queue_head.next_log = firstLogical; 320 fInterruptEntries[i].queue_head.prev_log = NULL; 321 } 322 323 // terminate the first entry 324 firstLogical->next_phy = EHCI_QH_TERMINATE; 325 firstLogical->next_log = NULL; 326 firstLogical->prev_log = NULL; 327 328 // allocate a queue head that will always stay in the async frame list 329 fAsyncQueueHead = CreateQueueHead(); 330 if (!fAsyncQueueHead) { 331 TRACE_ERROR("unable to allocate stray async queue head\n"); 332 return; 333 } 334 335 fAsyncQueueHead->next_phy = fAsyncQueueHead->this_phy | EHCI_QH_TYPE_QH; 336 fAsyncQueueHead->next_log = fAsyncQueueHead; 337 fAsyncQueueHead->prev_log = fAsyncQueueHead; 338 fAsyncQueueHead->endpoint_chars = EHCI_QH_CHARS_EPS_HIGH | EHCI_QH_CHARS_RECHEAD; 339 fAsyncQueueHead->endpoint_caps = 1 << EHCI_QH_CAPS_MULT_SHIFT; 340 fAsyncQueueHead->current_qtd_phy = EHCI_QTD_TERMINATE; 341 fAsyncQueueHead->overlay.next_phy = EHCI_QTD_TERMINATE; 342 343 WriteOpReg(EHCI_ASYNCLISTADDR, (uint32)fAsyncQueueHead->this_phy 344 | EHCI_QH_TYPE_QH); 345 TRACE("set the async list addr to 0x%08lx\n", ReadOpReg(EHCI_ASYNCLISTADDR)); 346 347 fInitOK = true; 348 TRACE("EHCI host controller driver constructed\n"); 349 } 350 351 352 EHCI::~EHCI() 353 { 354 TRACE("tear down EHCI host controller driver\n"); 355 356 WriteOpReg(EHCI_USBCMD, 0); 357 WriteOpReg(EHCI_CONFIGFLAG, 0); 358 CancelAllPendingTransfers(); 359 360 int32 result = 0; 361 fStopThreads = true; 362 delete_sem(fAsyncAdvanceSem); 363 delete_sem(fFinishTransfersSem); 364 wait_for_thread(fFinishThread, &result); 365 wait_for_thread(fCleanupThread, &result); 366 367 delete fRootHub; 368 delete_area(fPeriodicFrameListArea); 369 delete_area(fRegisterArea); 370 put_module(B_PCI_MODULE_NAME); 371 } 372 373 374 status_t 375 EHCI::Start() 376 { 377 TRACE("starting EHCI host controller\n"); 378 TRACE("usbcmd: 0x%08lx; usbsts: 0x%08lx\n", ReadOpReg(EHCI_USBCMD), ReadOpReg(EHCI_USBSTS)); 379 380 uint32 frameListSize = (ReadOpReg(EHCI_USBCMD) >> EHCI_USBCMD_FLS_SHIFT) 381 & EHCI_USBCMD_FLS_MASK; 382 WriteOpReg(EHCI_USBCMD, ReadOpReg(EHCI_USBCMD) | EHCI_USBCMD_RUNSTOP 383 | EHCI_USBCMD_ASENABLE | EHCI_USBCMD_PSENABLE 384 | (frameListSize << EHCI_USBCMD_FLS_SHIFT) 385 | (1 << EHCI_USBCMD_ITC_SHIFT)); 386 387 bool running = false; 388 for (int32 i = 0; i < 10; i++) { 389 uint32 status = ReadOpReg(EHCI_USBSTS); 390 TRACE("try %ld: status 0x%08lx\n", i, status); 391 392 if (status & EHCI_USBSTS_HCHALTED) { 393 snooze(10000); 394 } else { 395 running = true; 396 break; 397 } 398 } 399 400 if (!running) { 401 TRACE("host controller didn't start\n"); 402 return B_ERROR; 403 } 404 405 // route all ports to us 406 WriteOpReg(EHCI_CONFIGFLAG, EHCI_CONFIGFLAG_FLAG); 407 snooze(10000); 408 409 fRootHubAddress = AllocateAddress(); 410 fRootHub = new(std::nothrow) EHCIRootHub(RootObject(), fRootHubAddress); 411 if (!fRootHub) { 412 TRACE_ERROR("no memory to allocate root hub\n"); 413 return B_NO_MEMORY; 414 } 415 416 if (fRootHub->InitCheck() < B_OK) { 417 TRACE_ERROR("root hub failed init check\n"); 418 return fRootHub->InitCheck(); 419 } 420 421 SetRootHub(fRootHub); 422 TRACE_ALWAYS("successfully started the controller\n"); 423 return BusManager::Start(); 424 } 425 426 427 status_t 428 EHCI::SubmitTransfer(Transfer *transfer) 429 { 430 // short circuit the root hub 431 if (transfer->TransferPipe()->DeviceAddress() == fRootHubAddress) 432 return fRootHub->ProcessTransfer(this, transfer); 433 434 Pipe *pipe = transfer->TransferPipe(); 435 if (pipe->Type() & USB_OBJECT_ISO_PIPE) { 436 // ToDo: implement isochronous transfers... 437 return B_ERROR; 438 } 439 440 ehci_qh *queueHead = CreateQueueHead(); 441 if (!queueHead) { 442 TRACE_ERROR("failed to allocate queue head\n"); 443 return B_NO_MEMORY; 444 } 445 446 status_t result = InitQueueHead(queueHead, pipe); 447 if (result < B_OK) { 448 TRACE_ERROR("failed to init queue head\n"); 449 FreeQueueHead(queueHead); 450 return result; 451 } 452 453 bool directionIn; 454 ehci_qtd *dataDescriptor; 455 if (pipe->Type() & USB_OBJECT_CONTROL_PIPE) { 456 result = FillQueueWithRequest(transfer, queueHead, &dataDescriptor, 457 &directionIn); 458 } else { 459 result = FillQueueWithData(transfer, queueHead, &dataDescriptor, 460 &directionIn); 461 } 462 463 if (result < B_OK) { 464 TRACE_ERROR("failed to fill transfer queue with data\n"); 465 FreeQueueHead(queueHead); 466 return result; 467 } 468 469 result = AddPendingTransfer(transfer, queueHead, dataDescriptor, directionIn); 470 if (result < B_OK) { 471 TRACE_ERROR("failed to add pending transfer\n"); 472 FreeQueueHead(queueHead); 473 return result; 474 } 475 476 #ifdef TRACE_USB 477 TRACE("linking queue\n"); 478 print_queue(queueHead); 479 #endif 480 481 if (pipe->Type() & USB_OBJECT_INTERRUPT_PIPE) 482 result = LinkInterruptQueueHead(queueHead, pipe); 483 else 484 result = LinkQueueHead(queueHead); 485 486 if (result < B_OK) { 487 TRACE_ERROR("failed to link queue head\n"); 488 FreeQueueHead(queueHead); 489 return result; 490 } 491 492 return B_OK; 493 } 494 495 496 status_t 497 EHCI::NotifyPipeChange(Pipe *pipe, usb_change change) 498 { 499 TRACE("pipe change %d for pipe %p\n", change, pipe); 500 switch (change) { 501 case USB_CHANGE_CREATED: 502 case USB_CHANGE_DESTROYED: { 503 // ToDo: we should create and keep a single queue head 504 // for all transfers to/from this pipe 505 break; 506 } 507 508 case USB_CHANGE_PIPE_POLICY_CHANGED: { 509 // ToDo: for isochronous pipes we might need to adapt to new 510 // pipe policy settings here 511 break; 512 } 513 } 514 515 return B_OK; 516 } 517 518 519 status_t 520 EHCI::AddTo(Stack *stack) 521 { 522 #ifdef TRACE_USB 523 set_dprintf_enabled(true); 524 #ifndef HAIKU_TARGET_PLATFORM_HAIKU 525 load_driver_symbols("ehci"); 526 #endif 527 #endif 528 529 if (!sPCIModule) { 530 status_t status = get_module(B_PCI_MODULE_NAME, (module_info **)&sPCIModule); 531 if (status < B_OK) { 532 TRACE_MODULE_ERROR("getting pci module failed! 0x%08lx\n", status); 533 return status; 534 } 535 } 536 537 TRACE_MODULE("searching devices\n"); 538 bool found = false; 539 pci_info *item = new(std::nothrow) pci_info; 540 if (!item) { 541 sPCIModule = NULL; 542 put_module(B_PCI_MODULE_NAME); 543 return B_NO_MEMORY; 544 } 545 546 for (int32 i = 0; sPCIModule->get_nth_pci_info(i, item) >= B_OK; i++) { 547 if (item->class_base == PCI_serial_bus && item->class_sub == PCI_usb 548 && item->class_api == PCI_usb_ehci) { 549 if (item->u.h0.interrupt_line == 0 550 || item->u.h0.interrupt_line == 0xFF) { 551 TRACE_MODULE_ERROR("found device with invalid IRQ - check IRQ assignement\n"); 552 continue; 553 } 554 555 TRACE_MODULE("found device at IRQ %u\n", item->u.h0.interrupt_line); 556 EHCI *bus = new(std::nothrow) EHCI(item, stack); 557 if (!bus) { 558 delete item; 559 sPCIModule = NULL; 560 put_module(B_PCI_MODULE_NAME); 561 return B_NO_MEMORY; 562 } 563 564 if (bus->InitCheck() < B_OK) { 565 TRACE_MODULE_ERROR("bus failed init check\n"); 566 delete bus; 567 continue; 568 } 569 570 // the bus took it away 571 item = new(std::nothrow) pci_info; 572 573 bus->Start(); 574 stack->AddBusManager(bus); 575 found = true; 576 } 577 } 578 579 if (!found) { 580 TRACE_MODULE_ERROR("no devices found\n"); 581 delete item; 582 sPCIModule = NULL; 583 put_module(B_PCI_MODULE_NAME); 584 return ENODEV; 585 } 586 587 delete item; 588 return B_OK; 589 } 590 591 592 status_t 593 EHCI::GetPortStatus(uint8 index, usb_port_status *status) 594 { 595 if (index >= fPortCount) 596 return B_BAD_INDEX; 597 598 status->status = status->change = 0; 599 uint32 portStatus = ReadOpReg(EHCI_PORTSC + index * sizeof(uint32)); 600 601 // build the status 602 if (portStatus & EHCI_PORTSC_CONNSTATUS) 603 status->status |= PORT_STATUS_CONNECTION; 604 if (portStatus & EHCI_PORTSC_ENABLE) 605 status->status |= PORT_STATUS_ENABLE; 606 if (portStatus & EHCI_PORTSC_ENABLE) 607 status->status |= PORT_STATUS_HIGH_SPEED; 608 if (portStatus & EHCI_PORTSC_OCACTIVE) 609 status->status |= PORT_STATUS_OVER_CURRENT; 610 if (portStatus & EHCI_PORTSC_PORTRESET) 611 status->status |= PORT_STATUS_RESET; 612 if (portStatus & EHCI_PORTSC_PORTPOWER) 613 status->status |= PORT_STATUS_POWER; 614 if (portStatus & EHCI_PORTSC_SUSPEND) 615 status->status |= PORT_STATUS_SUSPEND; 616 if (portStatus & EHCI_PORTSC_DMINUS) 617 status->status |= PORT_STATUS_LOW_SPEED; 618 619 // build the change 620 if (portStatus & EHCI_PORTSC_CONNCHANGE) 621 status->change |= PORT_STATUS_CONNECTION; 622 if (portStatus & EHCI_PORTSC_ENABLECHANGE) 623 status->change |= PORT_STATUS_ENABLE; 624 if (portStatus & EHCI_PORTSC_OCCHANGE) 625 status->change |= PORT_STATUS_OVER_CURRENT; 626 627 // there are no bits to indicate suspend and reset change 628 if (fPortResetChange & (1 << index)) 629 status->change |= PORT_STATUS_RESET; 630 if (fPortSuspendChange & (1 << index)) 631 status->change |= PORT_STATUS_SUSPEND; 632 633 return B_OK; 634 } 635 636 637 status_t 638 EHCI::SetPortFeature(uint8 index, uint16 feature) 639 { 640 if (index >= fPortCount) 641 return B_BAD_INDEX; 642 643 uint32 portRegister = EHCI_PORTSC + index * sizeof(uint32); 644 uint32 portStatus = ReadOpReg(portRegister) & EHCI_PORTSC_DATAMASK; 645 646 switch (feature) { 647 case PORT_SUSPEND: 648 return SuspendPort(index); 649 650 case PORT_RESET: 651 return ResetPort(index); 652 653 case PORT_POWER: 654 WriteOpReg(portRegister, portStatus | EHCI_PORTSC_PORTPOWER); 655 return B_OK; 656 } 657 658 return B_BAD_VALUE; 659 } 660 661 662 status_t 663 EHCI::ClearPortFeature(uint8 index, uint16 feature) 664 { 665 if (index >= fPortCount) 666 return B_BAD_INDEX; 667 668 uint32 portRegister = EHCI_PORTSC + index * sizeof(uint32); 669 uint32 portStatus = ReadOpReg(portRegister) & EHCI_PORTSC_DATAMASK; 670 671 switch (feature) { 672 case PORT_ENABLE: 673 WriteOpReg(portRegister, portStatus & ~EHCI_PORTSC_ENABLE); 674 return B_OK; 675 676 case PORT_POWER: 677 WriteOpReg(portRegister, portStatus & ~EHCI_PORTSC_PORTPOWER); 678 return B_OK; 679 680 case C_PORT_CONNECTION: 681 WriteOpReg(portRegister, portStatus | EHCI_PORTSC_CONNCHANGE); 682 return B_OK; 683 684 case C_PORT_ENABLE: 685 WriteOpReg(portRegister, portStatus | EHCI_PORTSC_ENABLECHANGE); 686 return B_OK; 687 688 case C_PORT_OVER_CURRENT: 689 WriteOpReg(portRegister, portStatus | EHCI_PORTSC_OCCHANGE); 690 return B_OK; 691 692 case C_PORT_RESET: 693 fPortResetChange &= ~(1 << index); 694 return B_OK; 695 696 case C_PORT_SUSPEND: 697 fPortSuspendChange &= ~(1 << index); 698 return B_OK; 699 } 700 701 return B_BAD_VALUE; 702 } 703 704 705 status_t 706 EHCI::ResetPort(uint8 index) 707 { 708 TRACE("reset port %d\n", index); 709 uint32 portRegister = EHCI_PORTSC + index * sizeof(uint32); 710 uint32 portStatus = ReadOpReg(portRegister) & EHCI_PORTSC_DATAMASK; 711 712 if (portStatus & EHCI_PORTSC_DMINUS) { 713 TRACE_ALWAYS("lowspeed device connected, giving up port ownership\n"); 714 // there is a lowspeed device connected. 715 // we give the ownership to a companion controller. 716 WriteOpReg(portRegister, portStatus | EHCI_PORTSC_PORTOWNER); 717 fPortResetChange |= (1 << index); 718 return B_OK; 719 } 720 721 // enable reset signaling 722 WriteOpReg(portRegister, portStatus | EHCI_PORTSC_PORTRESET); 723 snooze(250000); 724 725 // disable reset signaling 726 portStatus = ReadOpReg(portRegister) & EHCI_PORTSC_DATAMASK; 727 WriteOpReg(portRegister, portStatus & ~EHCI_PORTSC_PORTRESET); 728 snooze(2000); 729 730 portStatus = ReadOpReg(portRegister) & EHCI_PORTSC_DATAMASK; 731 if (portStatus & EHCI_PORTSC_PORTRESET) { 732 TRACE_ERROR("port reset won't complete\n"); 733 return B_ERROR; 734 } 735 736 if ((portStatus & EHCI_PORTSC_ENABLE) == 0) { 737 TRACE_ALWAYS("fullspeed device connected, giving up port ownership\n"); 738 // the port was not enabled, this means that no high speed device is 739 // attached to this port. we give up ownership to a companion controler 740 WriteOpReg(portRegister, portStatus | EHCI_PORTSC_PORTOWNER); 741 } 742 743 fPortResetChange |= (1 << index); 744 return B_OK; 745 } 746 747 748 status_t 749 EHCI::SuspendPort(uint8 index) 750 { 751 uint32 portRegister = EHCI_PORTSC + index * sizeof(uint32); 752 uint32 portStatus = ReadOpReg(portRegister) & EHCI_PORTSC_DATAMASK; 753 WriteOpReg(portRegister, portStatus | EHCI_PORTSC_SUSPEND); 754 fPortSuspendChange |= (1 << index); 755 return B_OK; 756 } 757 758 759 status_t 760 EHCI::ControllerReset() 761 { 762 // halt the controller first 763 WriteOpReg(EHCI_USBCMD, 0); 764 snooze(10000); 765 766 // then reset it 767 WriteOpReg(EHCI_USBCMD, EHCI_USBCMD_HCRESET); 768 769 int32 tries = 5; 770 while (ReadOpReg(EHCI_USBCMD) & EHCI_USBCMD_HCRESET) { 771 snooze(10000); 772 if (tries-- < 0) 773 return B_ERROR; 774 } 775 776 return B_OK; 777 } 778 779 780 status_t 781 EHCI::LightReset() 782 { 783 return B_ERROR; 784 } 785 786 787 int32 788 EHCI::InterruptHandler(void *data) 789 { 790 return ((EHCI *)data)->Interrupt(); 791 } 792 793 794 int32 795 EHCI::Interrupt() 796 { 797 static spinlock lock = B_SPINLOCK_INITIALIZER; 798 acquire_spinlock(&lock); 799 800 // check if any interrupt was generated 801 uint32 status = ReadOpReg(EHCI_USBSTS) & EHCI_USBSTS_INTMASK; 802 if ((status & fEnabledInterrupts) == 0) { 803 if (status != 0) { 804 TRACE("discarding not enabled interrupts 0x%08lx\n", status); 805 WriteOpReg(EHCI_USBSTS, status); 806 } 807 808 release_spinlock(&lock); 809 return B_UNHANDLED_INTERRUPT; 810 } 811 812 bool asyncAdvance = false; 813 bool finishTransfers = false; 814 int32 result = B_HANDLED_INTERRUPT; 815 816 if (status & EHCI_USBSTS_USBINT) { 817 TRACE("transfer finished\n"); 818 result = B_INVOKE_SCHEDULER; 819 finishTransfers = true; 820 } 821 822 if (status & EHCI_USBSTS_USBERRINT) { 823 TRACE("transfer error\n"); 824 result = B_INVOKE_SCHEDULER; 825 finishTransfers = true; 826 } 827 828 if (status & EHCI_USBSTS_FLROLLOVER) 829 TRACE("frame list rollover\n"); 830 831 if (status & EHCI_USBSTS_PORTCHANGE) 832 TRACE("port change detected\n"); 833 834 if (status & EHCI_USBSTS_INTONAA) { 835 TRACE("interrupt on async advance\n"); 836 asyncAdvance = true; 837 result = B_INVOKE_SCHEDULER; 838 } 839 840 if (status & EHCI_USBSTS_HOSTSYSERR) 841 TRACE_ERROR("host system error!\n"); 842 843 WriteOpReg(EHCI_USBSTS, status); 844 release_spinlock(&lock); 845 846 if (asyncAdvance) 847 release_sem_etc(fAsyncAdvanceSem, 1, B_DO_NOT_RESCHEDULE); 848 if (finishTransfers) 849 release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE); 850 851 return result; 852 } 853 854 855 status_t 856 EHCI::AddPendingTransfer(Transfer *transfer, ehci_qh *queueHead, 857 ehci_qtd *dataDescriptor, bool directionIn) 858 { 859 transfer_data *data = new(std::nothrow) transfer_data; 860 if (!data) 861 return B_NO_MEMORY; 862 863 status_t result = transfer->InitKernelAccess(); 864 if (result < B_OK) { 865 delete data; 866 return result; 867 } 868 869 data->transfer = transfer; 870 data->queue_head = queueHead; 871 data->data_descriptor = dataDescriptor; 872 data->incoming = directionIn; 873 data->canceled = false; 874 data->link = NULL; 875 876 if (!Lock()) { 877 delete data; 878 return B_ERROR; 879 } 880 881 if (fLastTransfer) 882 fLastTransfer->link = data; 883 else 884 fFirstTransfer = data; 885 886 fLastTransfer = data; 887 Unlock(); 888 889 return B_OK; 890 } 891 892 893 status_t 894 EHCI::CancelQueuedTransfers(Pipe *pipe, bool force) 895 { 896 if (!Lock()) 897 return B_ERROR; 898 899 struct transfer_entry { 900 Transfer * transfer; 901 transfer_entry * next; 902 }; 903 904 transfer_entry *list = NULL; 905 transfer_data *current = fFirstTransfer; 906 while (current) { 907 if (current->transfer && current->transfer->TransferPipe() == pipe) { 908 // clear the active bit so the descriptors are canceled 909 ehci_qtd *descriptor = (ehci_qtd *)current->queue_head->element_log; 910 while (descriptor) { 911 descriptor->token &= ~EHCI_QTD_STATUS_ACTIVE; 912 descriptor = (ehci_qtd *)descriptor->next_log; 913 } 914 915 if (!force) { 916 // if the transfer is canceled by force, the one causing the 917 // cancel is probably not the one who initiated the transfer 918 // and the callback is likely not safe anymore 919 transfer_entry *entry 920 = (transfer_entry *)malloc(sizeof(transfer_entry)); 921 if (entry != NULL) { 922 entry->transfer = current->transfer; 923 current->transfer = NULL; 924 entry->next = list; 925 list = entry; 926 } 927 } 928 929 current->canceled = true; 930 } 931 932 current = current->link; 933 } 934 935 Unlock(); 936 937 while (list != NULL) { 938 transfer_entry *next = list->next; 939 list->transfer->Finished(B_CANCELED, 0); 940 delete list->transfer; 941 free(list); 942 list = next; 943 } 944 945 // wait for any transfers that might have made it before canceling 946 while (fProcessingPipe == pipe) 947 snooze(1000); 948 949 // notify the finisher so it can clean up the canceled transfers 950 release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE); 951 return B_OK; 952 } 953 954 955 status_t 956 EHCI::CancelAllPendingTransfers() 957 { 958 if (!Lock()) 959 return B_ERROR; 960 961 transfer_data *transfer = fFirstTransfer; 962 while (transfer) { 963 transfer->transfer->Finished(B_CANCELED, 0); 964 delete transfer->transfer; 965 966 transfer_data *next = transfer->link; 967 delete transfer; 968 transfer = next; 969 } 970 971 fFirstTransfer = NULL; 972 fLastTransfer = NULL; 973 Unlock(); 974 return B_OK; 975 } 976 977 978 int32 979 EHCI::FinishThread(void *data) 980 { 981 ((EHCI *)data)->FinishTransfers(); 982 return B_OK; 983 } 984 985 986 void 987 EHCI::FinishTransfers() 988 { 989 while (!fStopThreads) { 990 if (acquire_sem(fFinishTransfersSem) < B_OK) 991 continue; 992 993 // eat up sems that have been released by multiple interrupts 994 int32 semCount = 0; 995 get_sem_count(fFinishTransfersSem, &semCount); 996 if (semCount > 0) 997 acquire_sem_etc(fFinishTransfersSem, semCount, B_RELATIVE_TIMEOUT, 0); 998 999 if (!Lock()) 1000 continue; 1001 1002 TRACE("finishing transfers\n"); 1003 transfer_data *lastTransfer = NULL; 1004 transfer_data *transfer = fFirstTransfer; 1005 Unlock(); 1006 1007 while (transfer) { 1008 bool transferDone = false; 1009 ehci_qtd *descriptor = (ehci_qtd *)transfer->queue_head->element_log; 1010 status_t callbackStatus = B_OK; 1011 1012 while (descriptor) { 1013 uint32 status = descriptor->token; 1014 if (status & EHCI_QTD_STATUS_ACTIVE) { 1015 // still in progress 1016 TRACE("qtd (0x%08lx) still active\n", descriptor->this_phy); 1017 break; 1018 } 1019 1020 if (status & EHCI_QTD_STATUS_ERRMASK) { 1021 // a transfer error occured 1022 TRACE_ERROR("qtd (0x%08lx) error: 0x%08lx\n", descriptor->this_phy, status); 1023 1024 uint8 errorCount = status >> EHCI_QTD_ERRCOUNT_SHIFT; 1025 errorCount &= EHCI_QTD_ERRCOUNT_MASK; 1026 if (errorCount == 0) { 1027 // the error counter counted down to zero, report why 1028 int32 reasons = 0; 1029 if (status & EHCI_QTD_STATUS_BUFFER) { 1030 callbackStatus = transfer->incoming ? B_DEV_DATA_OVERRUN : B_DEV_DATA_UNDERRUN; 1031 reasons++; 1032 } 1033 if (status & EHCI_QTD_STATUS_TERROR) { 1034 callbackStatus = B_DEV_CRC_ERROR; 1035 reasons++; 1036 } 1037 1038 if (reasons > 1) 1039 callbackStatus = B_DEV_MULTIPLE_ERRORS; 1040 } else if (status & EHCI_QTD_STATUS_BABBLE) { 1041 // there is a babble condition 1042 callbackStatus = transfer->incoming ? B_DEV_FIFO_OVERRUN : B_DEV_FIFO_UNDERRUN; 1043 } else { 1044 // if the error counter didn't count down to zero 1045 // and there was no babble, then this halt was caused 1046 // by a stall handshake 1047 callbackStatus = B_DEV_STALLED; 1048 } 1049 1050 transferDone = true; 1051 break; 1052 } 1053 1054 if (descriptor->next_phy & EHCI_QTD_TERMINATE) { 1055 // we arrived at the last (stray) descriptor, we're done 1056 TRACE("qtd (0x%08lx) done\n", descriptor->this_phy); 1057 callbackStatus = B_OK; 1058 transferDone = true; 1059 break; 1060 } 1061 1062 descriptor = (ehci_qtd *)descriptor->next_log; 1063 } 1064 1065 if (!transferDone) { 1066 lastTransfer = transfer; 1067 transfer = transfer->link; 1068 continue; 1069 } 1070 1071 // remove the transfer from the list first so we are sure 1072 // it doesn't get canceled while we still process it 1073 transfer_data *next = transfer->link; 1074 if (Lock()) { 1075 if (lastTransfer) 1076 lastTransfer->link = transfer->link; 1077 1078 if (transfer == fFirstTransfer) 1079 fFirstTransfer = transfer->link; 1080 if (transfer == fLastTransfer) 1081 fLastTransfer = lastTransfer; 1082 1083 // store the currently processing pipe here so we can wait 1084 // in cancel if we are processing something on the target pipe 1085 if (!transfer->canceled) 1086 fProcessingPipe = transfer->transfer->TransferPipe(); 1087 1088 transfer->link = NULL; 1089 Unlock(); 1090 } 1091 1092 // if canceled the callback has already been called 1093 if (!transfer->canceled) { 1094 size_t actualLength = 0; 1095 1096 if (callbackStatus == B_OK) { 1097 bool nextDataToggle = false; 1098 if (transfer->data_descriptor && transfer->incoming) { 1099 // data to read out 1100 iovec *vector = transfer->transfer->Vector(); 1101 size_t vectorCount = transfer->transfer->VectorCount(); 1102 transfer->transfer->PrepareKernelAccess(); 1103 actualLength = ReadDescriptorChain( 1104 transfer->data_descriptor, 1105 vector, vectorCount, 1106 &nextDataToggle); 1107 } else if (transfer->data_descriptor) { 1108 // calculate transfered length 1109 actualLength = ReadActualLength( 1110 transfer->data_descriptor, &nextDataToggle); 1111 } 1112 1113 transfer->transfer->TransferPipe()->SetDataToggle(nextDataToggle); 1114 1115 if (transfer->transfer->IsFragmented()) { 1116 // this transfer may still have data left 1117 transfer->transfer->AdvanceByFragment(actualLength); 1118 if (transfer->transfer->VectorLength() > 0) { 1119 FreeDescriptorChain(transfer->data_descriptor); 1120 transfer->transfer->PrepareKernelAccess(); 1121 status_t result = FillQueueWithData( 1122 transfer->transfer, 1123 transfer->queue_head, 1124 &transfer->data_descriptor, NULL); 1125 1126 if (result == B_OK && Lock()) { 1127 // reappend the transfer 1128 if (fLastTransfer) 1129 fLastTransfer->link = transfer; 1130 if (!fFirstTransfer) 1131 fFirstTransfer = transfer; 1132 1133 fLastTransfer = transfer; 1134 Unlock(); 1135 1136 transfer = next; 1137 continue; 1138 } 1139 } 1140 1141 // the transfer is done, but we already set the 1142 // actualLength with AdvanceByFragment() 1143 actualLength = 0; 1144 } 1145 } 1146 1147 transfer->transfer->Finished(callbackStatus, actualLength); 1148 fProcessingPipe = NULL; 1149 } 1150 1151 // unlink hardware queue and delete the transfer 1152 UnlinkQueueHead(transfer->queue_head, &fFreeListHead); 1153 delete transfer->transfer; 1154 delete transfer; 1155 transfer = next; 1156 release_sem(fCleanupSem); 1157 } 1158 } 1159 } 1160 1161 1162 int32 1163 EHCI::CleanupThread(void *data) 1164 { 1165 ((EHCI *)data)->Cleanup(); 1166 return B_OK; 1167 } 1168 1169 1170 void 1171 EHCI::Cleanup() 1172 { 1173 ehci_qh *lastFreeListHead = NULL; 1174 1175 while (!fStopThreads) { 1176 if (acquire_sem(fCleanupSem) < B_OK) 1177 continue; 1178 1179 ehci_qh *freeListHead = fFreeListHead; 1180 if (freeListHead == lastFreeListHead) 1181 continue; 1182 1183 // set the doorbell and wait for the host controller to notify us 1184 WriteOpReg(EHCI_USBCMD, ReadOpReg(EHCI_USBCMD) | EHCI_USBCMD_INTONAAD); 1185 if (acquire_sem(fAsyncAdvanceSem) < B_OK) 1186 continue; 1187 1188 ehci_qh *current = freeListHead; 1189 while (current != lastFreeListHead) { 1190 ehci_qh *next = (ehci_qh *)current->next_log; 1191 FreeQueueHead(current); 1192 current = next; 1193 } 1194 1195 lastFreeListHead = freeListHead; 1196 } 1197 } 1198 1199 1200 ehci_qh * 1201 EHCI::CreateQueueHead() 1202 { 1203 ehci_qh *result; 1204 void *physicalAddress; 1205 if (fStack->AllocateChunk((void **)&result, &physicalAddress, 1206 sizeof(ehci_qh)) < B_OK) { 1207 TRACE_ERROR("failed to allocate queue head\n"); 1208 return NULL; 1209 } 1210 1211 result->this_phy = (addr_t)physicalAddress; 1212 result->next_phy = EHCI_QH_TERMINATE; 1213 result->next_log = NULL; 1214 result->prev_log = NULL; 1215 1216 ehci_qtd *descriptor = CreateDescriptor(0, 0); 1217 if (!descriptor) { 1218 TRACE_ERROR("failed to allocate initial qtd for queue head\n"); 1219 fStack->FreeChunk(result, (void *)result->this_phy, sizeof(ehci_qh)); 1220 return NULL; 1221 } 1222 1223 descriptor->token &= ~EHCI_QTD_STATUS_ACTIVE; 1224 result->stray_log = descriptor; 1225 result->element_log = descriptor; 1226 result->current_qtd_phy = EHCI_QTD_TERMINATE; 1227 result->overlay.next_phy = descriptor->this_phy; 1228 result->overlay.alt_next_phy = EHCI_QTD_TERMINATE; 1229 result->overlay.token = 0; 1230 for (int32 i = 0; i < 5; i++) { 1231 result->overlay.buffer_phy[i] = 0; 1232 result->overlay.ext_buffer_phy[i] = 0; 1233 } 1234 1235 return result; 1236 } 1237 1238 1239 status_t 1240 EHCI::InitQueueHead(ehci_qh *queueHead, Pipe *pipe) 1241 { 1242 switch (pipe->Speed()) { 1243 case USB_SPEED_LOWSPEED: 1244 queueHead->endpoint_chars = EHCI_QH_CHARS_EPS_LOW; 1245 break; 1246 case USB_SPEED_FULLSPEED: 1247 queueHead->endpoint_chars = EHCI_QH_CHARS_EPS_FULL; 1248 break; 1249 case USB_SPEED_HIGHSPEED: 1250 queueHead->endpoint_chars = EHCI_QH_CHARS_EPS_HIGH; 1251 break; 1252 default: 1253 TRACE_ERROR("unknown pipe speed\n"); 1254 return B_ERROR; 1255 } 1256 1257 queueHead->endpoint_chars |= (3 << EHCI_QH_CHARS_RL_SHIFT) 1258 | (pipe->MaxPacketSize() << EHCI_QH_CHARS_MPL_SHIFT) 1259 | (pipe->EndpointAddress() << EHCI_QH_CHARS_EPT_SHIFT) 1260 | (pipe->DeviceAddress() << EHCI_QH_CHARS_DEV_SHIFT) 1261 | EHCI_QH_CHARS_TOGGLE; 1262 1263 queueHead->endpoint_caps = (1 << EHCI_QH_CAPS_MULT_SHIFT); 1264 if (pipe->Speed() != USB_SPEED_HIGHSPEED) { 1265 if (pipe->Type() & USB_OBJECT_CONTROL_PIPE) 1266 queueHead->endpoint_chars |= EHCI_QH_CHARS_CONTROL; 1267 1268 queueHead->endpoint_caps |= (pipe->HubPort() << EHCI_QH_CAPS_PORT_SHIFT) 1269 | (pipe->HubAddress() << EHCI_QH_CAPS_HUB_SHIFT); 1270 } 1271 1272 return B_OK; 1273 } 1274 1275 1276 void 1277 EHCI::FreeQueueHead(ehci_qh *queueHead) 1278 { 1279 if (!queueHead) 1280 return; 1281 1282 FreeDescriptorChain((ehci_qtd *)queueHead->element_log); 1283 FreeDescriptor((ehci_qtd *)queueHead->stray_log); 1284 fStack->FreeChunk(queueHead, (void *)queueHead->this_phy, sizeof(ehci_qh)); 1285 } 1286 1287 1288 status_t 1289 EHCI::LinkQueueHead(ehci_qh *queueHead) 1290 { 1291 if (!Lock()) 1292 return B_ERROR; 1293 1294 ehci_qh *prevHead = (ehci_qh *)fAsyncQueueHead->prev_log; 1295 queueHead->next_phy = fAsyncQueueHead->this_phy | EHCI_QH_TYPE_QH; 1296 queueHead->next_log = fAsyncQueueHead; 1297 queueHead->prev_log = prevHead; 1298 fAsyncQueueHead->prev_log = queueHead; 1299 prevHead->next_log = queueHead; 1300 prevHead->next_phy = queueHead->this_phy | EHCI_QH_TYPE_QH; 1301 1302 Unlock(); 1303 return B_OK; 1304 } 1305 1306 1307 status_t 1308 EHCI::LinkInterruptQueueHead(ehci_qh *queueHead, Pipe *pipe) 1309 { 1310 if (!Lock()) 1311 return B_ERROR; 1312 1313 uint8 interval = pipe->Interval(); 1314 if (pipe->Speed() == USB_SPEED_HIGHSPEED) { 1315 // Allow interrupts to be scheduled on each possible micro frame. 1316 queueHead->endpoint_caps |= (0xff << EHCI_QH_CAPS_ISM_SHIFT); 1317 } else { 1318 // As we do not yet support FSTNs to correctly reference low/full 1319 // speed interrupt transfers, we simply put them into the 1 interval 1320 // queue. This way we ensure that we reach them on every micro frame 1321 // and can do the corresponding start/complete split transactions. 1322 // ToDo: use FSTNs to correctly link non high speed interrupt transfers 1323 interval = 1; 1324 1325 // For now we also force start splits to be in micro frame 0 and 1326 // complete splits to be in micro frame 2, 3 and 4. 1327 queueHead->endpoint_caps |= (0x01 << EHCI_QH_CAPS_ISM_SHIFT); 1328 queueHead->endpoint_caps |= (0x1c << EHCI_QH_CAPS_SCM_SHIFT); 1329 } 1330 1331 // this should not happen 1332 if (interval < 1) 1333 interval = 1; 1334 1335 // this may happen as intervals can go up to 16; we limit the value to 1336 // 11 as you cannot support intervals above that with a frame list of 1337 // just 1024 entries... 1338 if (interval > 11) 1339 interval = 11; 1340 1341 ehci_qh *interruptQueue = &fInterruptEntries[interval - 1].queue_head; 1342 queueHead->next_phy = interruptQueue->next_phy; 1343 queueHead->next_log = interruptQueue->next_log; 1344 queueHead->prev_log = interruptQueue; 1345 if (interruptQueue->next_log) 1346 ((ehci_qh *)interruptQueue->next_log)->prev_log = queueHead; 1347 interruptQueue->next_log = queueHead; 1348 interruptQueue->next_phy = queueHead->this_phy | EHCI_QH_TYPE_QH; 1349 1350 Unlock(); 1351 return B_OK; 1352 } 1353 1354 1355 status_t 1356 EHCI::UnlinkQueueHead(ehci_qh *queueHead, ehci_qh **freeListHead) 1357 { 1358 if (!Lock()) 1359 return B_ERROR; 1360 1361 ehci_qh *prevHead = (ehci_qh *)queueHead->prev_log; 1362 ehci_qh *nextHead = (ehci_qh *)queueHead->next_log; 1363 if (prevHead) { 1364 prevHead->next_phy = queueHead->next_phy | EHCI_QH_TYPE_QH; 1365 prevHead->next_log = queueHead->next_log; 1366 } 1367 1368 if (nextHead) 1369 nextHead->prev_log = queueHead->prev_log; 1370 1371 queueHead->next_phy = fAsyncQueueHead->this_phy | EHCI_QH_TYPE_QH; 1372 queueHead->prev_log = NULL; 1373 1374 queueHead->next_log = *freeListHead; 1375 *freeListHead = queueHead; 1376 1377 Unlock(); 1378 return B_OK; 1379 } 1380 1381 1382 status_t 1383 EHCI::FillQueueWithRequest(Transfer *transfer, ehci_qh *queueHead, 1384 ehci_qtd **_dataDescriptor, bool *_directionIn) 1385 { 1386 Pipe *pipe = transfer->TransferPipe(); 1387 usb_request_data *requestData = transfer->RequestData(); 1388 bool directionIn = (requestData->RequestType & USB_REQTYPE_DEVICE_IN) > 0; 1389 1390 ehci_qtd *setupDescriptor = CreateDescriptor(sizeof(usb_request_data), 1391 EHCI_QTD_PID_SETUP); 1392 ehci_qtd *statusDescriptor = CreateDescriptor(0, 1393 directionIn ? EHCI_QTD_PID_OUT : EHCI_QTD_PID_IN); 1394 1395 if (!setupDescriptor || !statusDescriptor) { 1396 TRACE_ERROR("failed to allocate descriptors\n"); 1397 FreeDescriptor(setupDescriptor); 1398 FreeDescriptor(statusDescriptor); 1399 return B_NO_MEMORY; 1400 } 1401 1402 iovec vector; 1403 vector.iov_base = requestData; 1404 vector.iov_len = sizeof(usb_request_data); 1405 WriteDescriptorChain(setupDescriptor, &vector, 1); 1406 1407 ehci_qtd *strayDescriptor = (ehci_qtd *)queueHead->stray_log; 1408 statusDescriptor->token |= EHCI_QTD_IOC | EHCI_QTD_DATA_TOGGLE; 1409 1410 ehci_qtd *dataDescriptor = NULL; 1411 if (transfer->VectorCount() > 0) { 1412 ehci_qtd *lastDescriptor = NULL; 1413 status_t result = CreateDescriptorChain(pipe, &dataDescriptor, 1414 &lastDescriptor, strayDescriptor, transfer->VectorLength(), 1415 directionIn ? EHCI_QTD_PID_IN : EHCI_QTD_PID_OUT); 1416 1417 if (result < B_OK) { 1418 FreeDescriptor(setupDescriptor); 1419 FreeDescriptor(statusDescriptor); 1420 return result; 1421 } 1422 1423 if (!directionIn) { 1424 WriteDescriptorChain(dataDescriptor, transfer->Vector(), 1425 transfer->VectorCount()); 1426 } 1427 1428 LinkDescriptors(setupDescriptor, dataDescriptor, strayDescriptor); 1429 LinkDescriptors(lastDescriptor, statusDescriptor, strayDescriptor); 1430 } else { 1431 // no data: link setup and status descriptors directly 1432 LinkDescriptors(setupDescriptor, statusDescriptor, strayDescriptor); 1433 } 1434 1435 queueHead->element_log = setupDescriptor; 1436 queueHead->overlay.next_phy = setupDescriptor->this_phy; 1437 queueHead->overlay.alt_next_phy = EHCI_QTD_TERMINATE; 1438 1439 *_dataDescriptor = dataDescriptor; 1440 *_directionIn = directionIn; 1441 return B_OK; 1442 } 1443 1444 1445 status_t 1446 EHCI::FillQueueWithData(Transfer *transfer, ehci_qh *queueHead, 1447 ehci_qtd **_dataDescriptor, bool *_directionIn) 1448 { 1449 Pipe *pipe = transfer->TransferPipe(); 1450 bool directionIn = (pipe->Direction() == Pipe::In); 1451 1452 ehci_qtd *firstDescriptor = NULL; 1453 ehci_qtd *lastDescriptor = NULL; 1454 ehci_qtd *strayDescriptor = (ehci_qtd *)queueHead->stray_log; 1455 status_t result = CreateDescriptorChain(pipe, &firstDescriptor, 1456 &lastDescriptor, strayDescriptor, transfer->VectorLength(), 1457 directionIn ? EHCI_QTD_PID_IN : EHCI_QTD_PID_OUT); 1458 1459 if (result < B_OK) 1460 return result; 1461 1462 lastDescriptor->token |= EHCI_QTD_IOC; 1463 if (!directionIn) { 1464 WriteDescriptorChain(firstDescriptor, transfer->Vector(), 1465 transfer->VectorCount()); 1466 } 1467 1468 queueHead->element_log = firstDescriptor; 1469 queueHead->overlay.next_phy = firstDescriptor->this_phy; 1470 queueHead->overlay.alt_next_phy = EHCI_QTD_TERMINATE; 1471 1472 *_dataDescriptor = firstDescriptor; 1473 if (_directionIn) 1474 *_directionIn = directionIn; 1475 return B_OK; 1476 } 1477 1478 1479 ehci_qtd * 1480 EHCI::CreateDescriptor(size_t bufferSize, uint8 pid) 1481 { 1482 ehci_qtd *result; 1483 void *physicalAddress; 1484 if (fStack->AllocateChunk((void **)&result, &physicalAddress, 1485 sizeof(ehci_qtd)) < B_OK) { 1486 TRACE_ERROR("failed to allocate a qtd\n"); 1487 return NULL; 1488 } 1489 1490 result->this_phy = (addr_t)physicalAddress; 1491 result->next_phy = EHCI_QTD_TERMINATE; 1492 result->next_log = NULL; 1493 result->alt_next_phy = EHCI_QTD_TERMINATE; 1494 result->alt_next_log = NULL; 1495 result->buffer_size = bufferSize; 1496 result->token = bufferSize << EHCI_QTD_BYTES_SHIFT; 1497 result->token |= 3 << EHCI_QTD_ERRCOUNT_SHIFT; 1498 result->token |= pid << EHCI_QTD_PID_SHIFT; 1499 result->token |= EHCI_QTD_STATUS_ACTIVE; 1500 if (bufferSize == 0) { 1501 result->buffer_log = NULL; 1502 for (int32 i = 0; i < 5; i++) { 1503 result->buffer_phy[i] = 0; 1504 result->ext_buffer_phy[i] = 0; 1505 } 1506 1507 return result; 1508 } 1509 1510 if (fStack->AllocateChunk(&result->buffer_log, &physicalAddress, 1511 bufferSize) < B_OK) { 1512 TRACE_ERROR("unable to allocate qtd buffer\n"); 1513 fStack->FreeChunk(result, (void *)result->this_phy, sizeof(ehci_qtd)); 1514 return NULL; 1515 } 1516 1517 addr_t physicalBase = (addr_t)physicalAddress; 1518 result->buffer_phy[0] = physicalBase; 1519 result->ext_buffer_phy[0] = 0; 1520 for (int32 i = 1; i < 5; i++) { 1521 physicalBase += B_PAGE_SIZE; 1522 result->buffer_phy[i] = physicalBase & EHCI_QTD_PAGE_MASK; 1523 result->ext_buffer_phy[i] = 0; 1524 } 1525 1526 return result; 1527 } 1528 1529 1530 status_t 1531 EHCI::CreateDescriptorChain(Pipe *pipe, ehci_qtd **_firstDescriptor, 1532 ehci_qtd **_lastDescriptor, ehci_qtd *strayDescriptor, size_t bufferSize, 1533 uint8 pid) 1534 { 1535 size_t packetSize = B_PAGE_SIZE * 4; 1536 int32 descriptorCount = (bufferSize + packetSize - 1) / packetSize; 1537 1538 bool dataToggle = pipe->DataToggle(); 1539 ehci_qtd *firstDescriptor = NULL; 1540 ehci_qtd *lastDescriptor = *_firstDescriptor; 1541 for (int32 i = 0; i < descriptorCount; i++) { 1542 ehci_qtd *descriptor = CreateDescriptor(min_c(packetSize, bufferSize), 1543 pid); 1544 1545 if (!descriptor) { 1546 FreeDescriptorChain(firstDescriptor); 1547 return B_NO_MEMORY; 1548 } 1549 1550 if (dataToggle) 1551 descriptor->token |= EHCI_QTD_DATA_TOGGLE; 1552 1553 if (lastDescriptor) 1554 LinkDescriptors(lastDescriptor, descriptor, strayDescriptor); 1555 1556 bufferSize -= packetSize; 1557 lastDescriptor = descriptor; 1558 if (!firstDescriptor) 1559 firstDescriptor = descriptor; 1560 } 1561 1562 *_firstDescriptor = firstDescriptor; 1563 *_lastDescriptor = lastDescriptor; 1564 return B_OK; 1565 } 1566 1567 1568 void 1569 EHCI::FreeDescriptor(ehci_qtd *descriptor) 1570 { 1571 if (!descriptor) 1572 return; 1573 1574 if (descriptor->buffer_log) { 1575 fStack->FreeChunk(descriptor->buffer_log, 1576 (void *)descriptor->buffer_phy[0], descriptor->buffer_size); 1577 } 1578 1579 fStack->FreeChunk(descriptor, (void *)descriptor->this_phy, sizeof(ehci_qtd)); 1580 } 1581 1582 1583 void 1584 EHCI::FreeDescriptorChain(ehci_qtd *topDescriptor) 1585 { 1586 ehci_qtd *current = topDescriptor; 1587 ehci_qtd *next = NULL; 1588 1589 while (current) { 1590 next = (ehci_qtd *)current->next_log; 1591 FreeDescriptor(current); 1592 current = next; 1593 } 1594 } 1595 1596 1597 void 1598 EHCI::LinkDescriptors(ehci_qtd *first, ehci_qtd *last, ehci_qtd *alt) 1599 { 1600 first->next_phy = last->this_phy; 1601 first->next_log = last; 1602 1603 if (alt) { 1604 first->alt_next_phy = alt->this_phy; 1605 first->alt_next_log = alt; 1606 } else { 1607 first->alt_next_phy = EHCI_QTD_TERMINATE; 1608 first->alt_next_log = NULL; 1609 } 1610 } 1611 1612 1613 size_t 1614 EHCI::WriteDescriptorChain(ehci_qtd *topDescriptor, iovec *vector, 1615 size_t vectorCount) 1616 { 1617 ehci_qtd *current = topDescriptor; 1618 size_t actualLength = 0; 1619 size_t vectorIndex = 0; 1620 size_t vectorOffset = 0; 1621 size_t bufferOffset = 0; 1622 1623 while (current) { 1624 if (!current->buffer_log) 1625 break; 1626 1627 while (true) { 1628 size_t length = min_c(current->buffer_size - bufferOffset, 1629 vector[vectorIndex].iov_len - vectorOffset); 1630 1631 memcpy((uint8 *)current->buffer_log + bufferOffset, 1632 (uint8 *)vector[vectorIndex].iov_base + vectorOffset, length); 1633 1634 actualLength += length; 1635 vectorOffset += length; 1636 bufferOffset += length; 1637 1638 if (vectorOffset >= vector[vectorIndex].iov_len) { 1639 if (++vectorIndex >= vectorCount) { 1640 TRACE("wrote descriptor chain (%ld bytes, no more vectors)\n", actualLength); 1641 return actualLength; 1642 } 1643 1644 vectorOffset = 0; 1645 } 1646 1647 if (bufferOffset >= current->buffer_size) { 1648 bufferOffset = 0; 1649 break; 1650 } 1651 } 1652 1653 if (current->next_phy & EHCI_QTD_TERMINATE) 1654 break; 1655 1656 current = (ehci_qtd *)current->next_log; 1657 } 1658 1659 TRACE("wrote descriptor chain (%ld bytes)\n", actualLength); 1660 return actualLength; 1661 } 1662 1663 1664 size_t 1665 EHCI::ReadDescriptorChain(ehci_qtd *topDescriptor, iovec *vector, 1666 size_t vectorCount, bool *nextDataToggle) 1667 { 1668 uint32 dataToggle = 0; 1669 ehci_qtd *current = topDescriptor; 1670 size_t actualLength = 0; 1671 size_t vectorIndex = 0; 1672 size_t vectorOffset = 0; 1673 size_t bufferOffset = 0; 1674 1675 while (current && (current->token & EHCI_QTD_STATUS_ACTIVE) == 0) { 1676 if (!current->buffer_log) 1677 break; 1678 1679 dataToggle = current->token & EHCI_QTD_DATA_TOGGLE; 1680 size_t bufferSize = current->buffer_size; 1681 bufferSize -= (current->token >> EHCI_QTD_BYTES_SHIFT) & EHCI_QTD_BYTES_MASK; 1682 1683 while (true) { 1684 size_t length = min_c(bufferSize - bufferOffset, 1685 vector[vectorIndex].iov_len - vectorOffset); 1686 1687 memcpy((uint8 *)vector[vectorIndex].iov_base + vectorOffset, 1688 (uint8 *)current->buffer_log + bufferOffset, length); 1689 1690 actualLength += length; 1691 vectorOffset += length; 1692 bufferOffset += length; 1693 1694 if (vectorOffset >= vector[vectorIndex].iov_len) { 1695 if (++vectorIndex >= vectorCount) { 1696 TRACE("read descriptor chain (%ld bytes, no more vectors)\n", actualLength); 1697 *nextDataToggle = dataToggle > 0 ? true : false; 1698 return actualLength; 1699 } 1700 1701 vectorOffset = 0; 1702 } 1703 1704 if (bufferOffset >= bufferSize) { 1705 bufferOffset = 0; 1706 break; 1707 } 1708 } 1709 1710 if (current->next_phy & EHCI_QTD_TERMINATE) 1711 break; 1712 1713 current = (ehci_qtd *)current->next_log; 1714 } 1715 1716 TRACE("read descriptor chain (%ld bytes)\n", actualLength); 1717 *nextDataToggle = dataToggle > 0 ? true : false; 1718 return actualLength; 1719 } 1720 1721 1722 size_t 1723 EHCI::ReadActualLength(ehci_qtd *topDescriptor, bool *nextDataToggle) 1724 { 1725 size_t actualLength = 0; 1726 ehci_qtd *current = topDescriptor; 1727 uint32 dataToggle = 0; 1728 1729 while (current && (current->token & EHCI_QTD_STATUS_ACTIVE) == 0) { 1730 dataToggle = current->token & EHCI_QTD_DATA_TOGGLE; 1731 size_t length = current->buffer_size; 1732 length -= (current->token >> EHCI_QTD_BYTES_SHIFT) & EHCI_QTD_BYTES_MASK; 1733 actualLength += length; 1734 1735 if (current->next_phy & EHCI_QTD_TERMINATE) 1736 break; 1737 1738 current = (ehci_qtd *)current->next_log; 1739 } 1740 1741 TRACE("read actual length (%ld bytes)\n", actualLength); 1742 *nextDataToggle = dataToggle > 0 ? true : false; 1743 return actualLength; 1744 } 1745 1746 1747 inline void 1748 EHCI::WriteOpReg(uint32 reg, uint32 value) 1749 { 1750 *(volatile uint32 *)(fOperationalRegisters + reg) = value; 1751 } 1752 1753 1754 inline uint32 1755 EHCI::ReadOpReg(uint32 reg) 1756 { 1757 return *(volatile uint32 *)(fOperationalRegisters + reg); 1758 } 1759 1760 1761 inline uint8 1762 EHCI::ReadCapReg8(uint32 reg) 1763 { 1764 return *(volatile uint8 *)(fCapabilityRegisters + reg); 1765 } 1766 1767 1768 inline uint16 1769 EHCI::ReadCapReg16(uint32 reg) 1770 { 1771 return *(volatile uint16 *)(fCapabilityRegisters + reg); 1772 } 1773 1774 1775 inline uint32 1776 EHCI::ReadCapReg32(uint32 reg) 1777 { 1778 return *(volatile uint32 *)(fCapabilityRegisters + reg); 1779 } 1780