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