1 /* 2 * Copyright 2006-2011, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Michael Lotz <mmlr@mlotz.ch> 7 * Jérôme Duval <korli@users.berlios.de> 8 */ 9 10 11 #include <stdio.h> 12 13 #include <driver_settings.h> 14 #include <bus/PCI.h> 15 #include <USB3.h> 16 #include <KernelExport.h> 17 18 #include "ehci.h" 19 20 21 #define CALLED(x...) TRACE_MODULE("CALLED %s\n", __PRETTY_FUNCTION__) 22 23 #define USB_MODULE_NAME "ehci" 24 25 26 device_manager_info* gDeviceManager; 27 static usb_for_controller_interface* gUSB; 28 29 30 #define EHCI_PCI_DEVICE_MODULE_NAME "busses/usb/ehci/pci/driver_v1" 31 #define EHCI_PCI_USB_BUS_MODULE_NAME "busses/usb/ehci/device_v1" 32 33 34 typedef struct { 35 EHCI* ehci; 36 pci_device_module_info* pci; 37 pci_device* device; 38 39 pci_info pciinfo; 40 41 device_node* node; 42 device_node* driver_node; 43 } ehci_pci_sim_info; 44 45 46 // #pragma mark - 47 48 49 static status_t 50 init_bus(device_node* node, void** bus_cookie) 51 { 52 CALLED(); 53 54 driver_module_info* driver; 55 ehci_pci_sim_info* bus; 56 device_node* parent = gDeviceManager->get_parent_node(node); 57 gDeviceManager->get_driver(parent, &driver, (void**)&bus); 58 gDeviceManager->put_node(parent); 59 60 Stack *stack; 61 if (gUSB->get_stack((void**)&stack) != B_OK) 62 return B_ERROR; 63 64 EHCI *ehci = new(std::nothrow) EHCI(&bus->pciinfo, bus->pci, bus->device, stack, node); 65 if (ehci == NULL) { 66 return B_NO_MEMORY; 67 } 68 69 if (ehci->InitCheck() < B_OK) { 70 TRACE_MODULE_ERROR("bus failed init check\n"); 71 delete ehci; 72 return B_ERROR; 73 } 74 75 if (ehci->Start() != B_OK) { 76 delete ehci; 77 return B_ERROR; 78 } 79 80 *bus_cookie = ehci; 81 82 return B_OK; 83 } 84 85 86 static void 87 uninit_bus(void* bus_cookie) 88 { 89 CALLED(); 90 EHCI* ehci = (EHCI*)bus_cookie; 91 delete ehci; 92 } 93 94 95 static status_t 96 register_child_devices(void* cookie) 97 { 98 CALLED(); 99 ehci_pci_sim_info* bus = (ehci_pci_sim_info*)cookie; 100 device_node* node = bus->driver_node; 101 102 char prettyName[25]; 103 sprintf(prettyName, "EHCI Controller %" B_PRIu16, 0); 104 105 device_attr attrs[] = { 106 // properties of this controller for the usb bus manager 107 { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, 108 { .string = prettyName }}, 109 { B_DEVICE_FIXED_CHILD, B_STRING_TYPE, 110 { .string = USB_FOR_CONTROLLER_MODULE_NAME }}, 111 112 // private data to identify the device 113 { NULL } 114 }; 115 116 return gDeviceManager->register_node(node, EHCI_PCI_USB_BUS_MODULE_NAME, 117 attrs, NULL, NULL); 118 } 119 120 121 static status_t 122 init_device(device_node* node, void** device_cookie) 123 { 124 CALLED(); 125 ehci_pci_sim_info* bus = (ehci_pci_sim_info*)calloc(1, 126 sizeof(ehci_pci_sim_info)); 127 if (bus == NULL) 128 return B_NO_MEMORY; 129 130 pci_device_module_info* pci; 131 pci_device* device; 132 { 133 device_node* pciParent = gDeviceManager->get_parent_node(node); 134 gDeviceManager->get_driver(pciParent, (driver_module_info**)&pci, 135 (void**)&device); 136 gDeviceManager->put_node(pciParent); 137 } 138 139 bus->pci = pci; 140 bus->device = device; 141 bus->driver_node = node; 142 143 pci_info *pciInfo = &bus->pciinfo; 144 pci->get_pci_info(device, pciInfo); 145 146 *device_cookie = bus; 147 return B_OK; 148 } 149 150 151 static void 152 uninit_device(void* device_cookie) 153 { 154 CALLED(); 155 ehci_pci_sim_info* bus = (ehci_pci_sim_info*)device_cookie; 156 free(bus); 157 158 } 159 160 161 static status_t 162 register_device(device_node* parent) 163 { 164 CALLED(); 165 device_attr attrs[] = { 166 {B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {.string = "EHCI PCI"}}, 167 {} 168 }; 169 170 return gDeviceManager->register_node(parent, 171 EHCI_PCI_DEVICE_MODULE_NAME, attrs, NULL, NULL); 172 } 173 174 175 static float 176 supports_device(device_node* parent) 177 { 178 CALLED(); 179 const char* bus; 180 uint16 type, subType, api; 181 182 // make sure parent is a EHCI PCI device node 183 if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false) 184 < B_OK) { 185 return -1; 186 } 187 188 if (strcmp(bus, "pci") != 0) 189 return 0.0f; 190 191 if (gDeviceManager->get_attr_uint16(parent, B_DEVICE_SUB_TYPE, &subType, 192 false) < B_OK 193 || gDeviceManager->get_attr_uint16(parent, B_DEVICE_TYPE, &type, 194 false) < B_OK 195 || gDeviceManager->get_attr_uint16(parent, B_DEVICE_INTERFACE, &api, 196 false) < B_OK) { 197 TRACE_MODULE("Could not find type/subtype/interface attributes\n"); 198 return -1; 199 } 200 201 if (type == PCI_serial_bus && subType == PCI_usb && api == PCI_usb_ehci) { 202 pci_device_module_info* pci; 203 pci_device* device; 204 gDeviceManager->get_driver(parent, (driver_module_info**)&pci, 205 (void**)&device); 206 TRACE_MODULE("EHCI Device found!\n"); 207 208 return 0.8f; 209 } 210 211 return 0.0f; 212 } 213 214 215 module_dependency module_dependencies[] = { 216 { USB_FOR_CONTROLLER_MODULE_NAME, (module_info**)&gUSB }, 217 { B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&gDeviceManager }, 218 {} 219 }; 220 221 222 static usb_bus_interface gEHCIPCIDeviceModule = { 223 { 224 { 225 EHCI_PCI_USB_BUS_MODULE_NAME, 226 0, 227 NULL 228 }, 229 NULL, // supports device 230 NULL, // register device 231 init_bus, 232 uninit_bus, 233 NULL, // register child devices 234 NULL, // rescan 235 NULL, // device removed 236 }, 237 }; 238 239 // Root device that binds to the PCI bus. It will register an usb_bus_interface 240 // node for each device. 241 static driver_module_info sEHCIDevice = { 242 { 243 EHCI_PCI_DEVICE_MODULE_NAME, 244 0, 245 NULL 246 }, 247 supports_device, 248 register_device, 249 init_device, 250 uninit_device, 251 register_child_devices, 252 NULL, // rescan 253 NULL, // device removed 254 }; 255 256 module_info* modules[] = { 257 (module_info* )&sEHCIDevice, 258 (module_info* )&gEHCIPCIDeviceModule, 259 NULL 260 }; 261 262 263 // 264 // #pragma mark - 265 // 266 267 268 #ifdef TRACE_USB 269 270 void 271 print_descriptor_chain(ehci_qtd *descriptor) 272 { 273 while (descriptor) { 274 dprintf(" %08" B_PRIx32 " n%08" B_PRIx32 " a%08" B_PRIx32 " t%08" 275 B_PRIx32 " %08" B_PRIx32 " %08" B_PRIx32 " %08" B_PRIx32 " %08" 276 B_PRIx32 " %08" B_PRIx32 " s%" B_PRIuSIZE "\n", 277 descriptor->this_phy, descriptor->next_phy, 278 descriptor->alt_next_phy, descriptor->token, 279 descriptor->buffer_phy[0], descriptor->buffer_phy[1], 280 descriptor->buffer_phy[2], descriptor->buffer_phy[3], 281 descriptor->buffer_phy[4], descriptor->buffer_size); 282 283 if (descriptor->next_phy & EHCI_ITEM_TERMINATE) 284 break; 285 286 descriptor = descriptor->next_log; 287 } 288 } 289 290 291 void 292 print_queue(ehci_qh *queueHead) 293 { 294 dprintf("queue: t%08" B_PRIx32 " n%08" B_PRIx32 " ch%08" B_PRIx32 295 " ca%08" B_PRIx32 " cu%08" B_PRIx32 "\n", 296 queueHead->this_phy, queueHead->next_phy, queueHead->endpoint_chars, 297 queueHead->endpoint_caps, queueHead->current_qtd_phy); 298 dprintf("overlay: n%08" B_PRIx32 " a%08" B_PRIx32 " t%08" B_PRIx32 299 " %08" B_PRIx32 " %08" B_PRIx32 " %08" B_PRIx32 " %08" B_PRIx32 300 " %08" B_PRIx32 "\n", queueHead->overlay.next_phy, 301 queueHead->overlay.alt_next_phy, queueHead->overlay.token, 302 queueHead->overlay.buffer_phy[0], queueHead->overlay.buffer_phy[1], 303 queueHead->overlay.buffer_phy[2], queueHead->overlay.buffer_phy[3], 304 queueHead->overlay.buffer_phy[4]); 305 print_descriptor_chain(queueHead->element_log); 306 } 307 308 309 #endif // TRACE_USB 310 311 312 // 313 // #pragma mark - 314 // 315 316 317 EHCI::EHCI(pci_info *info, pci_device_module_info* pci, pci_device* device, Stack *stack, 318 device_node* node) 319 : BusManager(stack, node), 320 fCapabilityRegisters(NULL), 321 fOperationalRegisters(NULL), 322 fRegisterArea(-1), 323 fPCIInfo(info), 324 fPci(pci), 325 fDevice(device), 326 fStack(stack), 327 fEnabledInterrupts(0), 328 fThreshold(0), 329 fPeriodicFrameListArea(-1), 330 fPeriodicFrameList(NULL), 331 fInterruptEntries(NULL), 332 fItdEntries(NULL), 333 fSitdEntries(NULL), 334 fAsyncQueueHead(NULL), 335 fAsyncAdvanceSem(-1), 336 fFirstTransfer(NULL), 337 fLastTransfer(NULL), 338 fFinishTransfersSem(-1), 339 fFinishThread(-1), 340 fProcessingPipe(NULL), 341 fFreeListHead(NULL), 342 fCleanupSem(-1), 343 fCleanupThread(-1), 344 fStopThreads(false), 345 fNextStartingFrame(-1), 346 fFrameBandwidth(NULL), 347 fFirstIsochronousTransfer(NULL), 348 fLastIsochronousTransfer(NULL), 349 fFinishIsochronousTransfersSem(-1), 350 fFinishIsochronousThread(-1), 351 fRootHub(NULL), 352 fRootHubAddress(0), 353 fPortCount(0), 354 fPortResetChange(0), 355 fPortSuspendChange(0), 356 fInterruptPollThread(-1), 357 fIRQ(0), 358 fUseMSI(false) 359 { 360 // Create a lock for the isochronous transfer list 361 mutex_init(&fIsochronousLock, "EHCI isochronous lock"); 362 363 if (BusManager::InitCheck() != B_OK) { 364 TRACE_ERROR("bus manager failed to init\n"); 365 return; 366 } 367 368 TRACE("constructing new EHCI host controller driver\n"); 369 fInitOK = false; 370 371 // ATI/AMD SB600/SB700 periodic list cache workaround 372 // Logic kindly borrowed from NetBSD PR 40056 373 if (fPCIInfo->vendor_id == AMD_SBX00_VENDOR) { 374 bool applyWorkaround = false; 375 376 if (fPCIInfo->device_id == AMD_SB600_EHCI_CONTROLLER) { 377 // always apply on SB600 378 applyWorkaround = true; 379 } else if (fPCIInfo->device_id == AMD_SB700_SB800_EHCI_CONTROLLER) { 380 // only apply on certain chipsets, determined by SMBus revision 381 device_node *pciNode = NULL; 382 device_node* deviceRoot = gDeviceManager->get_root_node(); 383 device_attr acpiAttrs[] = { 384 { B_DEVICE_BUS, B_STRING_TYPE, { .string = "pci" }}, 385 { B_DEVICE_VENDOR_ID, B_UINT16_TYPE, { .ui16 = AMD_SBX00_VENDOR }}, 386 { B_DEVICE_ID, B_UINT16_TYPE, { .ui16 = AMD_SBX00_SMBUS_CONTROLLER }}, 387 { NULL } 388 }; 389 if (gDeviceManager->find_child_node(deviceRoot, acpiAttrs, 390 &pciNode) == B_OK) { 391 pci_device_module_info *pci; 392 pci_device *pciDevice; 393 if (gDeviceManager->get_driver(pciNode, (driver_module_info **)&pci, 394 (void **)&pciDevice) == B_OK) { 395 396 pci_info smbus; 397 pci->get_pci_info(pciDevice, &smbus); 398 // Only applies to chipsets < SB710 (rev A14) 399 if (smbus.revision == 0x3a || smbus.revision == 0x3b) 400 applyWorkaround = true; 401 } 402 } 403 } 404 405 if (applyWorkaround) { 406 // According to AMD errata of SB700 and SB600 register documentation 407 // this disables the Periodic List Cache on SB600 and the Advanced 408 // Periodic List Cache on early SB700. Both the BSDs and Linux use 409 // this workaround. 410 411 TRACE_ALWAYS("disabling SB600/SB700 periodic list cache\n"); 412 uint32 workaround = fPci->read_pci_config(fDevice, 413 AMD_SBX00_EHCI_MISC_REGISTER, 4); 414 415 fPci->write_pci_config(fDevice, AMD_SBX00_EHCI_MISC_REGISTER, 4, 416 workaround | AMD_SBX00_EHCI_MISC_DISABLE_PERIODIC_LIST_CACHE); 417 } 418 } 419 420 // enable busmaster and memory mapped access 421 uint16 command = fPci->read_pci_config(fDevice, PCI_command, 2); 422 command &= ~PCI_command_io; 423 command |= PCI_command_master | PCI_command_memory; 424 425 fPci->write_pci_config(fDevice, PCI_command, 2, command); 426 427 // map the registers 428 uint32 offset = fPCIInfo->u.h0.base_registers[0] & (B_PAGE_SIZE - 1); 429 phys_addr_t physicalAddress = fPCIInfo->u.h0.base_registers[0] - offset; 430 size_t mapSize = (fPCIInfo->u.h0.base_register_sizes[0] + offset 431 + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); 432 433 TRACE("map physical memory 0x%08" B_PRIx32 " (base: 0x%08" B_PRIxPHYSADDR 434 "; offset: %" B_PRIx32 "); size: %" B_PRIu32 "\n", 435 fPCIInfo->u.h0.base_registers[0], physicalAddress, offset, 436 fPCIInfo->u.h0.base_register_sizes[0]); 437 438 fRegisterArea = map_physical_memory("EHCI memory mapped registers", 439 physicalAddress, mapSize, B_ANY_KERNEL_BLOCK_ADDRESS, 440 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, 441 (void **)&fCapabilityRegisters); 442 if (fRegisterArea < 0) { 443 TRACE_ERROR("failed to map register memory\n"); 444 return; 445 } 446 447 fCapabilityRegisters += offset; 448 fOperationalRegisters = fCapabilityRegisters + ReadCapReg8(EHCI_CAPLENGTH); 449 TRACE("mapped capability registers: 0x%p\n", fCapabilityRegisters); 450 TRACE("mapped operational registers: 0x%p\n", fOperationalRegisters); 451 452 TRACE("structural parameters: 0x%08" B_PRIx32 "\n", 453 ReadCapReg32(EHCI_HCSPARAMS)); 454 TRACE("capability parameters: 0x%08" B_PRIx32 "\n", 455 ReadCapReg32(EHCI_HCCPARAMS)); 456 457 if (EHCI_HCCPARAMS_FRAME_CACHE(ReadCapReg32(EHCI_HCCPARAMS))) 458 fThreshold = 2 + 8; 459 else 460 fThreshold = 2 + EHCI_HCCPARAMS_IPT(ReadCapReg32(EHCI_HCCPARAMS)); 461 462 // read port count from capability register 463 fPortCount = ReadCapReg32(EHCI_HCSPARAMS) & 0x0f; 464 465 uint32 extendedCapPointer = ReadCapReg32(EHCI_HCCPARAMS) >> EHCI_ECP_SHIFT; 466 extendedCapPointer &= EHCI_ECP_MASK; 467 if (extendedCapPointer > 0) { 468 TRACE("extended capabilities register at %" B_PRIu32 "\n", 469 extendedCapPointer); 470 471 uint32 legacySupport = fPci->read_pci_config(fDevice, extendedCapPointer, 4); 472 if ((legacySupport & EHCI_LEGSUP_CAPID_MASK) == EHCI_LEGSUP_CAPID) { 473 if ((legacySupport & EHCI_LEGSUP_BIOSOWNED) != 0) { 474 TRACE_ALWAYS("the host controller is bios owned, claiming" 475 " ownership\n"); 476 477 fPci->write_pci_config(fDevice, extendedCapPointer + 3, 1, 1); 478 479 for (int32 i = 0; i < 20; i++) { 480 legacySupport = fPci->read_pci_config(fDevice, 481 extendedCapPointer, 4); 482 483 if ((legacySupport & EHCI_LEGSUP_BIOSOWNED) == 0) 484 break; 485 486 TRACE_ALWAYS("controller is still bios owned, waiting\n"); 487 snooze(50000); 488 } 489 } 490 491 if (legacySupport & EHCI_LEGSUP_BIOSOWNED) { 492 TRACE_ERROR("bios won't give up control over the host " 493 "controller (ignoring)\n"); 494 } else if (legacySupport & EHCI_LEGSUP_OSOWNED) { 495 TRACE_ALWAYS( 496 "successfully took ownership of the host controller\n"); 497 } 498 499 // Force off the BIOS owned flag, and clear all SMIs. Some BIOSes 500 // do indicate a successful handover but do not remove their SMIs 501 // and then freeze the system when interrupts are generated. 502 fPci->write_pci_config(fDevice, extendedCapPointer + 2, 1, 0); 503 fPci->write_pci_config(fDevice, extendedCapPointer + 4, 4, 0); 504 } else { 505 TRACE_ALWAYS( 506 "extended capability is not a legacy support register\n"); 507 } 508 } else { 509 TRACE_ALWAYS("no extended capabilities register\n"); 510 } 511 512 // disable interrupts 513 WriteOpReg(EHCI_USBINTR, 0); 514 515 // reset the host controller 516 if (ControllerReset() != B_OK) { 517 TRACE_ERROR("host controller failed to reset\n"); 518 return; 519 } 520 521 // reset the segment register 522 WriteOpReg(EHCI_CTRDSSEGMENT, 0); 523 524 // create semaphores the finisher thread will wait for 525 fAsyncAdvanceSem = create_sem(0, "EHCI Async Advance"); 526 fFinishTransfersSem = create_sem(0, "EHCI Finish Transfers"); 527 fCleanupSem = create_sem(0, "EHCI Cleanup"); 528 if (fFinishTransfersSem < 0 || fAsyncAdvanceSem < 0 || fCleanupSem < 0) { 529 TRACE_ERROR("failed to create semaphores\n"); 530 return; 531 } 532 533 // create finisher service thread 534 fFinishThread = spawn_kernel_thread(FinishThread, "ehci finish thread", 535 B_NORMAL_PRIORITY, (void *)this); 536 resume_thread(fFinishThread); 537 538 // Create semaphore the isochronous finisher thread will wait for 539 fFinishIsochronousTransfersSem = create_sem(0, 540 "EHCI Isochronous Finish Transfers"); 541 if (fFinishIsochronousTransfersSem < 0) { 542 TRACE_ERROR("failed to create isochronous finisher semaphore\n"); 543 return; 544 } 545 546 // Create the isochronous finisher service thread 547 fFinishIsochronousThread = spawn_kernel_thread(FinishIsochronousThread, 548 "ehci isochronous finish thread", B_URGENT_DISPLAY_PRIORITY, 549 (void *)this); 550 resume_thread(fFinishIsochronousThread); 551 552 // create cleanup service thread 553 fCleanupThread = spawn_kernel_thread(CleanupThread, "ehci cleanup thread", 554 B_NORMAL_PRIORITY, (void *)this); 555 resume_thread(fCleanupThread); 556 557 // set up interrupts or interrupt polling now that the controller is ready 558 bool polling = false; 559 void *settings = load_driver_settings(B_SAFEMODE_DRIVER_SETTINGS); 560 if (settings != NULL) { 561 polling = get_driver_boolean_parameter(settings, "ehci_polling", false, 562 false); 563 unload_driver_settings(settings); 564 } 565 566 if (polling) { 567 // create and run the polling thread 568 TRACE_ALWAYS("enabling ehci polling\n"); 569 fInterruptPollThread = spawn_kernel_thread(InterruptPollThread, 570 "ehci interrupt poll thread", B_NORMAL_PRIORITY, (void *)this); 571 resume_thread(fInterruptPollThread); 572 } else { 573 // Find the right interrupt vector, using MSIs if available. 574 fIRQ = fPCIInfo->u.h0.interrupt_line; 575 if (fIRQ == 0xFF) 576 fIRQ = 0; 577 578 if (fPci->get_msi_count(fDevice) >= 1) { 579 uint32 msiVector = 0; 580 if (fPci->configure_msi(fDevice, 1, &msiVector) == B_OK 581 && fPci->enable_msi(fDevice) == B_OK) { 582 TRACE_ALWAYS("using message signaled interrupts\n"); 583 fIRQ = msiVector; 584 fUseMSI = true; 585 } 586 } 587 588 if (fIRQ == 0) { 589 TRACE_MODULE_ERROR("device PCI:%d:%d:%d was assigned an invalid IRQ\n", 590 fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function); 591 return; 592 } 593 594 // install the interrupt handler and enable interrupts 595 install_io_interrupt_handler(fIRQ, InterruptHandler, 596 (void *)this, 0); 597 } 598 599 // ensure that interrupts are en-/disabled on the PCI device 600 command = fPci->read_pci_config(fDevice, PCI_command, 2); 601 if ((polling || fUseMSI) == ((command & PCI_command_int_disable) == 0)) { 602 if (polling || fUseMSI) 603 command &= ~PCI_command_int_disable; 604 else 605 command |= PCI_command_int_disable; 606 607 fPci->write_pci_config(fDevice, PCI_command, 2, command); 608 } 609 610 fEnabledInterrupts = EHCI_USBINTR_HOSTSYSERR | EHCI_USBINTR_USBERRINT 611 | EHCI_USBINTR_USBINT | EHCI_USBINTR_INTONAA; 612 WriteOpReg(EHCI_USBINTR, fEnabledInterrupts); 613 614 // structures don't span page boundaries 615 size_t itdListSize = EHCI_VFRAMELIST_ENTRIES_COUNT 616 / (B_PAGE_SIZE / sizeof(itd_entry)) * B_PAGE_SIZE; 617 size_t sitdListSize = EHCI_VFRAMELIST_ENTRIES_COUNT 618 / (B_PAGE_SIZE / sizeof(sitd_entry)) * B_PAGE_SIZE; 619 size_t frameListSize = B_PAGE_SIZE + B_PAGE_SIZE + itdListSize 620 + sitdListSize; 621 622 // allocate the periodic frame list 623 fPeriodicFrameListArea = fStack->AllocateArea((void **)&fPeriodicFrameList, 624 &physicalAddress, frameListSize, "USB EHCI Periodic Framelist"); 625 if (fPeriodicFrameListArea < 0) { 626 TRACE_ERROR("unable to allocate periodic framelist\n"); 627 return; 628 } 629 630 if ((physicalAddress & 0xfff) != 0) { 631 panic("EHCI_PERIODICLISTBASE not aligned on 4k: 0x%" B_PRIxPHYSADDR 632 "\n", physicalAddress); 633 } 634 635 // set the periodic frame list base on the controller 636 WriteOpReg(EHCI_PERIODICLISTBASE, (uint32)physicalAddress); 637 638 // create the interrupt entries to support different polling intervals 639 TRACE("creating interrupt entries\n"); 640 uint32_t physicalBase = physicalAddress + B_PAGE_SIZE; 641 uint8 *logicalBase = (uint8 *)fPeriodicFrameList + B_PAGE_SIZE; 642 memset(logicalBase, 0, B_PAGE_SIZE); 643 644 fInterruptEntries = (interrupt_entry *)logicalBase; 645 for (int32 i = 0; i < EHCI_INTERRUPT_ENTRIES_COUNT; i++) { 646 ehci_qh *queueHead = &fInterruptEntries[i].queue_head; 647 queueHead->this_phy = physicalBase | EHCI_ITEM_TYPE_QH; 648 queueHead->current_qtd_phy = 0; 649 queueHead->overlay.next_phy = EHCI_ITEM_TERMINATE; 650 queueHead->overlay.alt_next_phy = EHCI_ITEM_TERMINATE; 651 queueHead->overlay.token = EHCI_QTD_STATUS_HALTED; 652 653 // set dummy endpoint information 654 queueHead->endpoint_chars = EHCI_QH_CHARS_EPS_HIGH 655 | (3 << EHCI_QH_CHARS_RL_SHIFT) | (64 << EHCI_QH_CHARS_MPL_SHIFT) 656 | EHCI_QH_CHARS_TOGGLE; 657 queueHead->endpoint_caps = (1 << EHCI_QH_CAPS_MULT_SHIFT) 658 | (0xff << EHCI_QH_CAPS_ISM_SHIFT); 659 660 physicalBase += sizeof(interrupt_entry); 661 if ((physicalBase & 0x1f) != 0) { 662 panic("physical base for interrupt entry %" B_PRId32 663 " not aligned on 32, interrupt entry structure size %lu\n", 664 i, sizeof(interrupt_entry)); 665 } 666 } 667 668 // create the itd and sitd entries 669 TRACE("build up iso entries\n"); 670 uint32_t itdPhysicalBase = physicalAddress + B_PAGE_SIZE + B_PAGE_SIZE; 671 itd_entry* itds = (itd_entry *)((uint8 *)fPeriodicFrameList + B_PAGE_SIZE 672 + B_PAGE_SIZE); 673 memset(itds, 0, itdListSize); 674 675 uint32_t sitdPhysicalBase = itdPhysicalBase + itdListSize; 676 sitd_entry* sitds = (sitd_entry *)((uint8 *)fPeriodicFrameList + B_PAGE_SIZE 677 + B_PAGE_SIZE + itdListSize); 678 memset(sitds, 0, sitdListSize); 679 680 fItdEntries = new(std::nothrow) ehci_itd *[EHCI_VFRAMELIST_ENTRIES_COUNT]; 681 fSitdEntries = new(std::nothrow) ehci_sitd *[EHCI_VFRAMELIST_ENTRIES_COUNT]; 682 683 dprintf("sitd entry size %lu, itd entry size %lu\n", sizeof(sitd_entry), 684 sizeof(itd_entry)); 685 for (int32 i = 0; i < EHCI_VFRAMELIST_ENTRIES_COUNT; i++) { 686 ehci_sitd *sitd = &sitds[i].sitd; 687 sitd->this_phy = sitdPhysicalBase | EHCI_ITEM_TYPE_SITD; 688 sitd->back_phy = EHCI_ITEM_TERMINATE; 689 fSitdEntries[i] = sitd; 690 TRACE("sitd entry %" B_PRId32 " %p 0x%" B_PRIx32 "\n", i, sitd, 691 sitd->this_phy); 692 693 ehci_itd *itd = &itds[i].itd; 694 itd->this_phy = itdPhysicalBase | EHCI_ITEM_TYPE_ITD; 695 itd->next_phy = sitd->this_phy; 696 fItdEntries[i] = itd; 697 TRACE("itd entry %" B_PRId32 " %p 0x%" B_PRIx32 "\n", i, itd, 698 itd->this_phy); 699 700 sitdPhysicalBase += sizeof(sitd_entry); 701 itdPhysicalBase += sizeof(itd_entry); 702 if ((sitdPhysicalBase & 0x10) != 0 || (itdPhysicalBase & 0x10) != 0) 703 panic("physical base for entry %" B_PRId32 " not aligned on 32\n", 704 i); 705 } 706 707 // build flat interrupt tree 708 TRACE("build up interrupt links\n"); 709 uint32 interval = EHCI_VFRAMELIST_ENTRIES_COUNT; 710 uint32 intervalIndex = EHCI_INTERRUPT_ENTRIES_COUNT - 1; 711 while (interval > 1) { 712 for (uint32 insertIndex = interval / 2; 713 insertIndex < EHCI_VFRAMELIST_ENTRIES_COUNT; 714 insertIndex += interval) { 715 fSitdEntries[insertIndex]->next_phy 716 = fInterruptEntries[intervalIndex].queue_head.this_phy; 717 } 718 719 intervalIndex--; 720 interval /= 2; 721 } 722 723 // setup the empty slot in the list and linking of all -> first 724 ehci_qh *firstLogical = &fInterruptEntries[0].queue_head; 725 fSitdEntries[0]->next_phy = firstLogical->this_phy; 726 for (int32 i = 1; i < EHCI_INTERRUPT_ENTRIES_COUNT; i++) { 727 fInterruptEntries[i].queue_head.next_phy = firstLogical->this_phy; 728 fInterruptEntries[i].queue_head.next_log = firstLogical; 729 fInterruptEntries[i].queue_head.prev_log = NULL; 730 } 731 732 // terminate the first entry 733 firstLogical->next_phy = EHCI_ITEM_TERMINATE; 734 firstLogical->next_log = NULL; 735 firstLogical->prev_log = NULL; 736 737 for (int32 i = 0; i < EHCI_FRAMELIST_ENTRIES_COUNT; i++) { 738 fPeriodicFrameList[i] 739 = fItdEntries[i & (EHCI_VFRAMELIST_ENTRIES_COUNT - 1)]->this_phy; 740 TRACE("periodic entry %" B_PRId32 " linked to 0x%" B_PRIx32 "\n", i, 741 fPeriodicFrameList[i]); 742 } 743 744 // Create the array that will keep bandwidth information 745 fFrameBandwidth = new(std::nothrow) uint16[EHCI_VFRAMELIST_ENTRIES_COUNT]; 746 for (int32 i = 0; i < EHCI_VFRAMELIST_ENTRIES_COUNT; i++) { 747 fFrameBandwidth[i] = MAX_AVAILABLE_BANDWIDTH; 748 } 749 750 // allocate a queue head that will always stay in the async frame list 751 fAsyncQueueHead = CreateQueueHead(); 752 if (!fAsyncQueueHead) { 753 TRACE_ERROR("unable to allocate stray async queue head\n"); 754 return; 755 } 756 757 fAsyncQueueHead->next_phy = fAsyncQueueHead->this_phy; 758 fAsyncQueueHead->next_log = fAsyncQueueHead; 759 fAsyncQueueHead->prev_log = fAsyncQueueHead; 760 fAsyncQueueHead->endpoint_chars = EHCI_QH_CHARS_EPS_HIGH 761 | EHCI_QH_CHARS_RECHEAD; 762 fAsyncQueueHead->endpoint_caps = 1 << EHCI_QH_CAPS_MULT_SHIFT; 763 fAsyncQueueHead->overlay.next_phy = EHCI_ITEM_TERMINATE; 764 765 WriteOpReg(EHCI_ASYNCLISTADDR, (uint32)fAsyncQueueHead->this_phy); 766 TRACE("set the async list addr to 0x%08" B_PRIx32 "\n", 767 ReadOpReg(EHCI_ASYNCLISTADDR)); 768 769 fInitOK = true; 770 TRACE("EHCI host controller driver constructed\n"); 771 } 772 773 774 EHCI::~EHCI() 775 { 776 TRACE("tear down EHCI host controller driver\n"); 777 778 WriteOpReg(EHCI_USBCMD, 0); 779 WriteOpReg(EHCI_CONFIGFLAG, 0); 780 CancelAllPendingTransfers(); 781 782 int32 result = 0; 783 fStopThreads = true; 784 delete_sem(fAsyncAdvanceSem); 785 delete_sem(fFinishTransfersSem); 786 delete_sem(fFinishIsochronousTransfersSem); 787 delete_sem(fCleanupSem); 788 wait_for_thread(fFinishThread, &result); 789 wait_for_thread(fCleanupThread, &result); 790 wait_for_thread(fFinishIsochronousThread, &result); 791 792 if (fInterruptPollThread >= 0) 793 wait_for_thread(fInterruptPollThread, &result); 794 else 795 remove_io_interrupt_handler(fIRQ, InterruptHandler, (void *)this); 796 797 LockIsochronous(); 798 isochronous_transfer_data *isoTransfer = fFirstIsochronousTransfer; 799 while (isoTransfer) { 800 isochronous_transfer_data *next = isoTransfer->link; 801 delete isoTransfer; 802 isoTransfer = next; 803 } 804 mutex_destroy(&fIsochronousLock); 805 806 delete fRootHub; 807 delete [] fFrameBandwidth; 808 delete [] fItdEntries; 809 delete [] fSitdEntries; 810 delete_area(fPeriodicFrameListArea); 811 delete_area(fRegisterArea); 812 813 if (fUseMSI) { 814 fPci->disable_msi(fDevice); 815 fPci->unconfigure_msi(fDevice); 816 } 817 818 } 819 820 821 status_t 822 EHCI::Start() 823 { 824 TRACE("starting EHCI host controller\n"); 825 TRACE("usbcmd: 0x%08" B_PRIx32 "; usbsts: 0x%08" B_PRIx32 "\n", 826 ReadOpReg(EHCI_USBCMD), ReadOpReg(EHCI_USBSTS)); 827 828 bool hasPerPortChangeEvent = (ReadCapReg32(EHCI_HCCPARAMS) 829 & EHCI_HCCPARAMS_PPCEC) != 0; 830 831 uint32 config = ReadOpReg(EHCI_USBCMD); 832 config &= ~((EHCI_USBCMD_ITC_MASK << EHCI_USBCMD_ITC_SHIFT) 833 | EHCI_USBCMD_PPCEE); 834 uint32 frameListSize = (config >> EHCI_USBCMD_FLS_SHIFT) 835 & EHCI_USBCMD_FLS_MASK; 836 837 WriteOpReg(EHCI_USBCMD, config | EHCI_USBCMD_RUNSTOP 838 | (hasPerPortChangeEvent ? EHCI_USBCMD_PPCEE : 0) 839 | EHCI_USBCMD_ASENABLE | EHCI_USBCMD_PSENABLE 840 | (frameListSize << EHCI_USBCMD_FLS_SHIFT) 841 | (1 << EHCI_USBCMD_ITC_SHIFT)); 842 843 switch (frameListSize) { 844 case 0: 845 TRACE("frame list size 1024\n"); 846 break; 847 case 1: 848 TRACE("frame list size 512\n"); 849 break; 850 case 2: 851 TRACE("frame list size 256\n"); 852 break; 853 default: 854 TRACE_ALWAYS("unknown frame list size\n"); 855 } 856 857 bool running = false; 858 for (int32 i = 0; i < 10; i++) { 859 uint32 status = ReadOpReg(EHCI_USBSTS); 860 TRACE("try %" B_PRId32 ": status 0x%08" B_PRIx32 "\n", i, status); 861 862 if (status & EHCI_USBSTS_HCHALTED) { 863 snooze(10000); 864 } else { 865 running = true; 866 break; 867 } 868 } 869 870 if (!running) { 871 TRACE_ERROR("host controller didn't start\n"); 872 return B_ERROR; 873 } 874 875 // route all ports to us 876 WriteOpReg(EHCI_CONFIGFLAG, EHCI_CONFIGFLAG_FLAG); 877 snooze(10000); 878 879 fRootHubAddress = AllocateAddress(); 880 fRootHub = new(std::nothrow) EHCIRootHub(RootObject(), fRootHubAddress); 881 if (!fRootHub) { 882 TRACE_ERROR("no memory to allocate root hub\n"); 883 return B_NO_MEMORY; 884 } 885 886 if (fRootHub->InitCheck() != B_OK) { 887 TRACE_ERROR("root hub failed init check\n"); 888 return fRootHub->InitCheck(); 889 } 890 891 SetRootHub(fRootHub); 892 893 fRootHub->RegisterNode(Node()); 894 895 TRACE_ALWAYS("successfully started the controller\n"); 896 return BusManager::Start(); 897 } 898 899 900 status_t 901 EHCI::StartDebugTransfer(Transfer *transfer) 902 { 903 static transfer_data transferData; 904 905 transferData.queue_head = CreateQueueHead(); 906 if (transferData.queue_head == NULL) 907 return B_NO_MEMORY; 908 909 Pipe *pipe = transfer->TransferPipe(); 910 status_t result = InitQueueHead(transferData.queue_head, pipe); 911 if (result != B_OK) { 912 FreeQueueHead(transferData.queue_head); 913 return result; 914 } 915 916 if ((pipe->Type() & USB_OBJECT_CONTROL_PIPE) != 0) { 917 result = FillQueueWithRequest(transfer, transferData.queue_head, 918 &transferData.data_descriptor, &transferData.incoming, false); 919 } else { 920 result = FillQueueWithData(transfer, transferData.queue_head, 921 &transferData.data_descriptor, &transferData.incoming, false); 922 } 923 924 if (result != B_OK) { 925 FreeQueueHead(transferData.queue_head); 926 return result; 927 } 928 929 if ((pipe->Type() & USB_OBJECT_INTERRUPT_PIPE) != 0) 930 LinkPeriodicDebugQueueHead(transferData.queue_head, pipe); 931 else 932 LinkAsyncDebugQueueHead(transferData.queue_head); 933 934 // we abuse the callback cookie to hold our transfer data 935 transfer->SetCallback(NULL, &transferData); 936 return B_OK; 937 } 938 939 940 void 941 EHCI::LinkAsyncDebugQueueHead(ehci_qh *queueHead) 942 { 943 ehci_qh *prevHead = fAsyncQueueHead->prev_log; 944 queueHead->next_phy = fAsyncQueueHead->this_phy; 945 queueHead->next_log = fAsyncQueueHead; 946 queueHead->prev_log = prevHead; 947 fAsyncQueueHead->prev_log = queueHead; 948 prevHead->next_log = queueHead; 949 prevHead->next_phy = queueHead->this_phy; 950 } 951 952 953 void 954 EHCI::LinkPeriodicDebugQueueHead(ehci_qh *queueHead, Pipe *pipe) 955 { 956 if (pipe->Speed() == USB_SPEED_HIGHSPEED) 957 queueHead->endpoint_caps |= (0xff << EHCI_QH_CAPS_ISM_SHIFT); 958 else { 959 queueHead->endpoint_caps |= (0x01 << EHCI_QH_CAPS_ISM_SHIFT); 960 queueHead->endpoint_caps |= (0x1c << EHCI_QH_CAPS_SCM_SHIFT); 961 } 962 963 ehci_qh *interruptQueue = &fInterruptEntries[0].queue_head; 964 queueHead->next_phy = interruptQueue->next_phy; 965 queueHead->next_log = interruptQueue->next_log; 966 queueHead->prev_log = interruptQueue; 967 if (interruptQueue->next_log) 968 interruptQueue->next_log->prev_log = queueHead; 969 interruptQueue->next_log = queueHead; 970 interruptQueue->next_phy = queueHead->this_phy; 971 } 972 973 974 status_t 975 EHCI::CheckDebugTransfer(Transfer *transfer) 976 { 977 bool transferOK = false; 978 bool transferError = false; 979 transfer_data *transferData = (transfer_data *)transfer->CallbackCookie(); 980 ehci_qtd *descriptor = transferData->queue_head->element_log; 981 982 while (descriptor) { 983 uint32 status = descriptor->token; 984 if ((status & EHCI_QTD_STATUS_ACTIVE) != 0) { 985 // still in progress 986 break; 987 } 988 989 if ((status & EHCI_QTD_STATUS_ERRMASK) != 0) { 990 transferError = true; 991 break; 992 } 993 994 if ((descriptor->next_phy & EHCI_ITEM_TERMINATE) != 0) { 995 // we arrived at the last (stray) descriptor, we're done 996 transferOK = true; 997 break; 998 } 999 1000 if (((status >> EHCI_QTD_PID_SHIFT) & EHCI_QTD_PID_MASK) 1001 == EHCI_QTD_PID_IN 1002 && ((status >> EHCI_QTD_BYTES_SHIFT) & EHCI_QTD_BYTES_MASK) != 0) { 1003 // a short packet condition existed on this descriptor 1004 if (descriptor->alt_next_log != NULL) { 1005 descriptor = descriptor->alt_next_log; 1006 continue; 1007 } 1008 1009 transferOK = true; 1010 break; 1011 } 1012 1013 descriptor = descriptor->next_log; 1014 } 1015 1016 if (!transferOK && !transferError) { 1017 spin(75); 1018 return B_DEV_PENDING; 1019 } 1020 1021 if (transferOK) { 1022 bool nextDataToggle = false; 1023 if (transferData->data_descriptor != NULL && transferData->incoming) { 1024 // data to read out 1025 generic_io_vec *vector = transfer->Vector(); 1026 size_t vectorCount = transfer->VectorCount(); 1027 1028 ReadDescriptorChain(transferData->data_descriptor, 1029 vector, vectorCount, transfer->IsPhysical(), &nextDataToggle); 1030 } else if (transferData->data_descriptor != NULL) 1031 ReadActualLength(transferData->data_descriptor, &nextDataToggle); 1032 1033 transfer->TransferPipe()->SetDataToggle(nextDataToggle); 1034 } 1035 1036 CleanupDebugTransfer(transfer); 1037 return transferOK ? B_OK : B_IO_ERROR; 1038 } 1039 1040 1041 void 1042 EHCI::CancelDebugTransfer(Transfer *transfer) 1043 { 1044 transfer_data *transferData = (transfer_data *)transfer->CallbackCookie(); 1045 1046 // clear the active bit so the descriptors are canceled 1047 ehci_qtd *descriptor = transferData->queue_head->element_log; 1048 while (descriptor != NULL) { 1049 descriptor->token &= ~EHCI_QTD_STATUS_ACTIVE; 1050 descriptor = descriptor->next_log; 1051 } 1052 1053 transfer->Finished(B_CANCELED, 0); 1054 CleanupDebugTransfer(transfer); 1055 } 1056 1057 1058 void 1059 EHCI::CleanupDebugTransfer(Transfer *transfer) 1060 { 1061 transfer_data *transferData = (transfer_data *)transfer->CallbackCookie(); 1062 ehci_qh *queueHead = transferData->queue_head; 1063 ehci_qh *prevHead = queueHead->prev_log; 1064 if (prevHead != NULL) { 1065 prevHead->next_phy = queueHead->next_phy; 1066 prevHead->next_log = queueHead->next_log; 1067 } 1068 1069 ehci_qh *nextHead = queueHead->next_log; 1070 if (nextHead != NULL) 1071 nextHead->prev_log = queueHead->prev_log; 1072 1073 queueHead->next_phy = fAsyncQueueHead->this_phy; 1074 queueHead->prev_log = NULL; 1075 queueHead->next_log = NULL; 1076 1077 // wait for async advance to ensure the controller does not access this 1078 // queue head anymore. 1079 spin(125); 1080 1081 FreeQueueHead(queueHead); 1082 } 1083 1084 1085 status_t 1086 EHCI::SubmitTransfer(Transfer *transfer) 1087 { 1088 // short circuit the root hub 1089 if (transfer->TransferPipe()->DeviceAddress() == fRootHubAddress) 1090 return fRootHub->ProcessTransfer(this, transfer); 1091 1092 Pipe *pipe = transfer->TransferPipe(); 1093 if ((pipe->Type() & USB_OBJECT_ISO_PIPE) != 0) 1094 return SubmitIsochronous(transfer); 1095 1096 status_t result = transfer->InitKernelAccess(); 1097 if (result != B_OK) 1098 return result; 1099 1100 ehci_qh *queueHead = CreateQueueHead(); 1101 if (!queueHead) { 1102 TRACE_ERROR("failed to allocate queue head\n"); 1103 return B_NO_MEMORY; 1104 } 1105 1106 result = InitQueueHead(queueHead, pipe); 1107 if (result != B_OK) { 1108 TRACE_ERROR("failed to init queue head\n"); 1109 FreeQueueHead(queueHead); 1110 return result; 1111 } 1112 1113 bool directionIn; 1114 ehci_qtd *dataDescriptor; 1115 if ((pipe->Type() & USB_OBJECT_CONTROL_PIPE) != 0) { 1116 result = FillQueueWithRequest(transfer, queueHead, &dataDescriptor, 1117 &directionIn, true); 1118 } else { 1119 result = FillQueueWithData(transfer, queueHead, &dataDescriptor, 1120 &directionIn, true); 1121 } 1122 1123 if (result != B_OK) { 1124 TRACE_ERROR("failed to fill transfer queue with data\n"); 1125 FreeQueueHead(queueHead); 1126 return result; 1127 } 1128 1129 result = AddPendingTransfer(transfer, queueHead, dataDescriptor, 1130 directionIn); 1131 if (result != B_OK) { 1132 TRACE_ERROR("failed to add pending transfer\n"); 1133 FreeQueueHead(queueHead); 1134 return result; 1135 } 1136 1137 #ifdef TRACE_USB 1138 TRACE("linking queue\n"); 1139 print_queue(queueHead); 1140 #endif 1141 1142 if ((pipe->Type() & USB_OBJECT_INTERRUPT_PIPE) != 0) 1143 result = LinkInterruptQueueHead(queueHead, pipe); 1144 else 1145 result = LinkQueueHead(queueHead); 1146 1147 if (result != B_OK) { 1148 TRACE_ERROR("failed to link queue head\n"); 1149 FreeQueueHead(queueHead); 1150 return result; 1151 } 1152 1153 return B_OK; 1154 } 1155 1156 1157 status_t 1158 EHCI::SubmitIsochronous(Transfer *transfer) 1159 { 1160 Pipe *pipe = transfer->TransferPipe(); 1161 bool directionIn = (pipe->Direction() == Pipe::In); 1162 usb_isochronous_data *isochronousData = transfer->IsochronousData(); 1163 size_t packetSize = transfer->DataLength(); 1164 #ifdef TRACE_USB 1165 size_t restSize = packetSize % isochronousData->packet_count; 1166 #endif 1167 packetSize /= isochronousData->packet_count; 1168 uint16 currentFrame; 1169 1170 if (packetSize > pipe->MaxPacketSize()) { 1171 TRACE_ERROR( 1172 "isochronous packetSize is bigger than pipe MaxPacketSize\n"); 1173 return B_BAD_VALUE; 1174 } 1175 1176 status_t result = transfer->InitKernelAccess(); 1177 if (result != B_OK) 1178 return result; 1179 1180 // Ignore the fact that the last descriptor might need less bandwidth. 1181 // The overhead is not worthy. 1182 uint16 bandwidth = transfer->Bandwidth() / isochronousData->packet_count; 1183 1184 TRACE("isochronous transfer descriptor bandwidth %d\n", bandwidth); 1185 1186 // The following holds the list of transfer descriptor of the 1187 // isochronous request. It is used to quickly remove all the isochronous 1188 // descriptors from the frame list, as descriptors are not link to each 1189 // other in a queue like for every other transfer. 1190 ehci_itd **isoRequest 1191 = new(std::nothrow) ehci_itd *[isochronousData->packet_count]; 1192 if (isoRequest == NULL) { 1193 TRACE("failed to create isoRequest array!\n"); 1194 return B_NO_MEMORY; 1195 } 1196 1197 TRACE("isochronous submitted size=%" B_PRIuSIZE " bytes, TDs=%" B_PRIu32 1198 ", maxPacketSize=%" B_PRIuSIZE ", packetSize=%" B_PRIuSIZE 1199 ", restSize=%" B_PRIuSIZE "\n", transfer->DataLength(), 1200 isochronousData->packet_count, pipe->MaxPacketSize(), packetSize, 1201 restSize); 1202 1203 // Find the entry where to start inserting the first Isochronous descriptor 1204 if ((isochronousData->flags & USB_ISO_ASAP) != 0 || 1205 isochronousData->starting_frame_number == NULL) { 1206 1207 if (fFirstIsochronousTransfer != NULL && fNextStartingFrame != -1) 1208 currentFrame = fNextStartingFrame; 1209 else { 1210 uint32 threshold = fThreshold; 1211 TRACE("threshold: %" B_PRIu32 "\n", threshold); 1212 1213 // find the first available frame with enough bandwidth. 1214 // This should always be the case, as defining the starting frame 1215 // number in the driver makes no sense for many reason, one of which 1216 // is that frame numbers value are host controller specific, and the 1217 // driver does not know which host controller is running. 1218 currentFrame = ((ReadOpReg(EHCI_FRINDEX) + threshold) / 8) 1219 & (EHCI_FRAMELIST_ENTRIES_COUNT - 1); 1220 } 1221 1222 // Make sure that: 1223 // 1. We are at least 5ms ahead the controller 1224 // 2. We stay in the range 0-127 1225 // 3. There is enough bandwidth in the first entry 1226 currentFrame &= EHCI_VFRAMELIST_ENTRIES_COUNT - 1; 1227 } else { 1228 // Find out if the frame number specified has enough bandwidth, 1229 // otherwise find the first next available frame with enough bandwidth 1230 currentFrame = *isochronousData->starting_frame_number; 1231 } 1232 1233 TRACE("isochronous starting frame=%d\n", currentFrame); 1234 1235 uint16 itdIndex = 0; 1236 size_t dataLength = transfer->DataLength(); 1237 void* bufferLog; 1238 phys_addr_t bufferPhy; 1239 if (fStack->AllocateChunk(&bufferLog, &bufferPhy, dataLength) != B_OK) { 1240 TRACE_ERROR("unable to allocate itd buffer\n"); 1241 delete[] isoRequest; 1242 return B_NO_MEMORY; 1243 } 1244 1245 memset(bufferLog, 0, dataLength); 1246 1247 phys_addr_t currentPhy = bufferPhy; 1248 uint32 frameCount = 0; 1249 while (dataLength > 0) { 1250 ehci_itd* itd = CreateItdDescriptor(); 1251 isoRequest[itdIndex++] = itd; 1252 uint16 pg = 0; 1253 itd->buffer_phy[pg] = currentPhy & 0xfffff000; 1254 uint32 offset = currentPhy & 0xfff; 1255 TRACE("isochronous created itd, filling it with phy %" B_PRIxPHYSADDR 1256 "\n", currentPhy); 1257 for (int32 i = 0; i < 8 && dataLength > 0; i++) { 1258 size_t length = min_c(dataLength, packetSize); 1259 itd->token[i] = (EHCI_ITD_STATUS_ACTIVE << EHCI_ITD_STATUS_SHIFT) 1260 | (length << EHCI_ITD_TLENGTH_SHIFT) | (pg << EHCI_ITD_PG_SHIFT) 1261 | (offset << EHCI_ITD_TOFFSET_SHIFT); 1262 itd->last_token = i; 1263 TRACE("isochronous filled slot %" B_PRId32 " 0x%" B_PRIx32 "\n", i, 1264 itd->token[i]); 1265 dataLength -= length; 1266 offset += length; 1267 if (dataLength > 0 && offset > 0xfff) { 1268 offset -= B_PAGE_SIZE; 1269 currentPhy += B_PAGE_SIZE; 1270 itd->buffer_phy[pg + 1] = currentPhy & 0xfffff000; 1271 pg++; 1272 } 1273 if (dataLength <= 0) 1274 itd->token[i] |= EHCI_ITD_IOC; 1275 } 1276 1277 currentPhy += (offset & 0xfff) - (currentPhy & 0xfff); 1278 1279 itd->buffer_phy[0] 1280 |= (pipe->EndpointAddress() << EHCI_ITD_ENDPOINT_SHIFT) 1281 | (pipe->DeviceAddress() << EHCI_ITD_ADDRESS_SHIFT); 1282 itd->buffer_phy[1] 1283 |= (pipe->MaxPacketSize() & EHCI_ITD_MAXPACKETSIZE_MASK) 1284 | (directionIn << EHCI_ITD_DIR_SHIFT); 1285 itd->buffer_phy[2] 1286 |= ((((pipe->MaxPacketSize() >> EHCI_ITD_MAXPACKETSIZE_LENGTH) + 1) 1287 & EHCI_ITD_MUL_MASK) << EHCI_ITD_MUL_SHIFT); 1288 1289 TRACE("isochronous filled itd buffer_phy[0,1,2] 0x%" B_PRIx32 ", 0x%" 1290 B_PRIx32 " 0x%" B_PRIx32 "\n", 1291 itd->buffer_phy[0], itd->buffer_phy[1], itd->buffer_phy[2]); 1292 1293 if (!LockIsochronous()) 1294 continue; 1295 LinkITDescriptors(itd, &fItdEntries[currentFrame]); 1296 UnlockIsochronous(); 1297 fFrameBandwidth[currentFrame] -= bandwidth; 1298 currentFrame = (currentFrame + 1) & (EHCI_VFRAMELIST_ENTRIES_COUNT - 1); 1299 frameCount++; 1300 } 1301 1302 TRACE("isochronous filled itds count %d\n", itdIndex); 1303 1304 // Add transfer to the list 1305 result = AddPendingIsochronousTransfer(transfer, isoRequest, 1306 itdIndex - 1, directionIn, bufferPhy, bufferLog, 1307 transfer->DataLength()); 1308 if (result != B_OK) { 1309 TRACE_ERROR("failed to add pending isochronous transfer\n"); 1310 for (uint32 i = 0; i < itdIndex; i++) 1311 FreeDescriptor(isoRequest[i]); 1312 delete[] isoRequest; 1313 return result; 1314 } 1315 1316 TRACE("appended isochronous transfer by starting at frame number %d\n", 1317 currentFrame); 1318 fNextStartingFrame = currentFrame + 1; 1319 1320 // Wake up the isochronous finisher thread 1321 release_sem_etc(fFinishIsochronousTransfersSem, 1 /*frameCount*/, 1322 B_DO_NOT_RESCHEDULE); 1323 1324 return B_OK; 1325 } 1326 1327 1328 isochronous_transfer_data * 1329 EHCI::FindIsochronousTransfer(ehci_itd *itd) 1330 { 1331 // Simply check every last descriptor of the isochronous transfer list 1332 isochronous_transfer_data *transfer = fFirstIsochronousTransfer; 1333 if (transfer) { 1334 while (transfer->descriptors[transfer->last_to_process] 1335 != itd) { 1336 transfer = transfer->link; 1337 if (!transfer) 1338 break; 1339 } 1340 } 1341 return transfer; 1342 } 1343 1344 1345 status_t 1346 EHCI::NotifyPipeChange(Pipe *pipe, usb_change change) 1347 { 1348 TRACE("pipe change %d for pipe %p\n", change, pipe); 1349 switch (change) { 1350 case USB_CHANGE_CREATED: 1351 case USB_CHANGE_DESTROYED: { 1352 // ToDo: we should create and keep a single queue head 1353 // for all transfers to/from this pipe 1354 break; 1355 } 1356 1357 case USB_CHANGE_PIPE_POLICY_CHANGED: { 1358 // ToDo: for isochronous pipes we might need to adapt to new 1359 // pipe policy settings here 1360 break; 1361 } 1362 } 1363 1364 return B_OK; 1365 } 1366 1367 1368 status_t 1369 EHCI::GetPortStatus(uint8 index, usb_port_status *status) 1370 { 1371 if (index >= fPortCount) 1372 return B_BAD_INDEX; 1373 1374 status->status = status->change = 0; 1375 uint32 portStatus = ReadOpReg(EHCI_PORTSC + index * sizeof(uint32)); 1376 1377 // build the status 1378 if (portStatus & EHCI_PORTSC_CONNSTATUS) 1379 status->status |= PORT_STATUS_CONNECTION; 1380 if (portStatus & EHCI_PORTSC_ENABLE) 1381 status->status |= PORT_STATUS_ENABLE; 1382 if (portStatus & EHCI_PORTSC_ENABLE) 1383 status->status |= PORT_STATUS_HIGH_SPEED; 1384 if (portStatus & EHCI_PORTSC_OCACTIVE) 1385 status->status |= PORT_STATUS_OVER_CURRENT; 1386 if (portStatus & EHCI_PORTSC_PORTRESET) 1387 status->status |= PORT_STATUS_RESET; 1388 if (portStatus & EHCI_PORTSC_PORTPOWER) 1389 status->status |= PORT_STATUS_POWER; 1390 if (portStatus & EHCI_PORTSC_SUSPEND) 1391 status->status |= PORT_STATUS_SUSPEND; 1392 if (portStatus & EHCI_PORTSC_DMINUS) 1393 status->status |= PORT_STATUS_LOW_SPEED; 1394 1395 // build the change 1396 if (portStatus & EHCI_PORTSC_CONNCHANGE) 1397 status->change |= PORT_STATUS_CONNECTION; 1398 if (portStatus & EHCI_PORTSC_ENABLECHANGE) 1399 status->change |= PORT_STATUS_ENABLE; 1400 if (portStatus & EHCI_PORTSC_OCCHANGE) 1401 status->change |= PORT_STATUS_OVER_CURRENT; 1402 1403 // there are no bits to indicate suspend and reset change 1404 if (fPortResetChange & (1 << index)) 1405 status->change |= PORT_STATUS_RESET; 1406 if (fPortSuspendChange & (1 << index)) 1407 status->change |= PORT_STATUS_SUSPEND; 1408 1409 return B_OK; 1410 } 1411 1412 1413 status_t 1414 EHCI::SetPortFeature(uint8 index, uint16 feature) 1415 { 1416 if (index >= fPortCount) 1417 return B_BAD_INDEX; 1418 1419 uint32 portRegister = EHCI_PORTSC + index * sizeof(uint32); 1420 uint32 portStatus = ReadOpReg(portRegister) & EHCI_PORTSC_DATAMASK; 1421 1422 switch (feature) { 1423 case PORT_SUSPEND: 1424 return SuspendPort(index); 1425 1426 case PORT_RESET: 1427 return ResetPort(index); 1428 1429 case PORT_POWER: 1430 WriteOpReg(portRegister, portStatus | EHCI_PORTSC_PORTPOWER); 1431 return B_OK; 1432 } 1433 1434 return B_BAD_VALUE; 1435 } 1436 1437 1438 status_t 1439 EHCI::ClearPortFeature(uint8 index, uint16 feature) 1440 { 1441 if (index >= fPortCount) 1442 return B_BAD_INDEX; 1443 1444 uint32 portRegister = EHCI_PORTSC + index * sizeof(uint32); 1445 uint32 portStatus = ReadOpReg(portRegister) & EHCI_PORTSC_DATAMASK; 1446 1447 switch (feature) { 1448 case PORT_ENABLE: 1449 WriteOpReg(portRegister, portStatus & ~EHCI_PORTSC_ENABLE); 1450 return B_OK; 1451 1452 case PORT_POWER: 1453 WriteOpReg(portRegister, portStatus & ~EHCI_PORTSC_PORTPOWER); 1454 return B_OK; 1455 1456 case C_PORT_CONNECTION: 1457 WriteOpReg(portRegister, portStatus | EHCI_PORTSC_CONNCHANGE); 1458 return B_OK; 1459 1460 case C_PORT_ENABLE: 1461 WriteOpReg(portRegister, portStatus | EHCI_PORTSC_ENABLECHANGE); 1462 return B_OK; 1463 1464 case C_PORT_OVER_CURRENT: 1465 WriteOpReg(portRegister, portStatus | EHCI_PORTSC_OCCHANGE); 1466 return B_OK; 1467 1468 case C_PORT_RESET: 1469 fPortResetChange &= ~(1 << index); 1470 return B_OK; 1471 1472 case C_PORT_SUSPEND: 1473 fPortSuspendChange &= ~(1 << index); 1474 return B_OK; 1475 } 1476 1477 return B_BAD_VALUE; 1478 } 1479 1480 1481 status_t 1482 EHCI::ResetPort(uint8 index) 1483 { 1484 TRACE("reset port %d\n", index); 1485 uint32 portRegister = EHCI_PORTSC + index * sizeof(uint32); 1486 uint32 portStatus = ReadOpReg(portRegister) & EHCI_PORTSC_DATAMASK; 1487 1488 if (portStatus & EHCI_PORTSC_DMINUS) { 1489 TRACE_ALWAYS("lowspeed device connected, giving up port ownership\n"); 1490 // there is a lowspeed device connected. 1491 // we give the ownership to a companion controller. 1492 WriteOpReg(portRegister, portStatus | EHCI_PORTSC_PORTOWNER); 1493 fPortResetChange |= (1 << index); 1494 return B_OK; 1495 } 1496 1497 // enable reset signaling 1498 WriteOpReg(portRegister, (portStatus & ~EHCI_PORTSC_ENABLE) 1499 | EHCI_PORTSC_PORTRESET); 1500 snooze(50000); 1501 1502 // disable reset signaling 1503 portStatus = ReadOpReg(portRegister) & EHCI_PORTSC_DATAMASK; 1504 WriteOpReg(portRegister, portStatus & ~EHCI_PORTSC_PORTRESET); 1505 snooze(2000); 1506 1507 portStatus = ReadOpReg(portRegister) & EHCI_PORTSC_DATAMASK; 1508 if (portStatus & EHCI_PORTSC_PORTRESET) { 1509 TRACE_ERROR("port reset won't complete\n"); 1510 return B_ERROR; 1511 } 1512 1513 if ((portStatus & EHCI_PORTSC_ENABLE) == 0) { 1514 TRACE_ALWAYS("fullspeed device connected, giving up port ownership\n"); 1515 // the port was not enabled, this means that no high speed device is 1516 // attached to this port. we give up ownership to a companion controler 1517 WriteOpReg(portRegister, portStatus | EHCI_PORTSC_PORTOWNER); 1518 } 1519 1520 fPortResetChange |= (1 << index); 1521 return B_OK; 1522 } 1523 1524 1525 status_t 1526 EHCI::SuspendPort(uint8 index) 1527 { 1528 uint32 portRegister = EHCI_PORTSC + index * sizeof(uint32); 1529 uint32 portStatus = ReadOpReg(portRegister) & EHCI_PORTSC_DATAMASK; 1530 WriteOpReg(portRegister, portStatus | EHCI_PORTSC_SUSPEND); 1531 fPortSuspendChange |= (1 << index); 1532 return B_OK; 1533 } 1534 1535 1536 status_t 1537 EHCI::ControllerReset() 1538 { 1539 // halt the controller first 1540 WriteOpReg(EHCI_USBCMD, 0); 1541 snooze(10000); 1542 1543 // then reset it 1544 WriteOpReg(EHCI_USBCMD, EHCI_USBCMD_HCRESET); 1545 1546 int32 tries = 5; 1547 while (ReadOpReg(EHCI_USBCMD) & EHCI_USBCMD_HCRESET) { 1548 snooze(10000); 1549 if (tries-- < 0) 1550 return B_ERROR; 1551 } 1552 1553 return B_OK; 1554 } 1555 1556 1557 status_t 1558 EHCI::LightReset() 1559 { 1560 return B_ERROR; 1561 } 1562 1563 1564 int32 1565 EHCI::InterruptHandler(void *data) 1566 { 1567 return ((EHCI *)data)->Interrupt(); 1568 } 1569 1570 1571 int32 1572 EHCI::Interrupt() 1573 { 1574 static spinlock lock = B_SPINLOCK_INITIALIZER; 1575 acquire_spinlock(&lock); 1576 1577 // check if any interrupt was generated 1578 uint32 status = ReadOpReg(EHCI_USBSTS) & EHCI_USBSTS_INTMASK; 1579 if ((status & fEnabledInterrupts) == 0) { 1580 if (status != 0) { 1581 TRACE("discarding not enabled interrupts 0x%08" B_PRIx32 "\n", 1582 status); 1583 WriteOpReg(EHCI_USBSTS, status); 1584 } 1585 1586 release_spinlock(&lock); 1587 return B_UNHANDLED_INTERRUPT; 1588 } 1589 1590 bool asyncAdvance = false; 1591 bool finishTransfers = false; 1592 int32 result = B_HANDLED_INTERRUPT; 1593 1594 if (status & EHCI_USBSTS_USBINT) { 1595 TRACE("transfer finished\n"); 1596 result = B_INVOKE_SCHEDULER; 1597 finishTransfers = true; 1598 } 1599 1600 if (status & EHCI_USBSTS_USBERRINT) { 1601 TRACE("transfer error\n"); 1602 result = B_INVOKE_SCHEDULER; 1603 finishTransfers = true; 1604 } 1605 1606 if (status & EHCI_USBSTS_FLROLLOVER) 1607 TRACE("frame list rollover\n"); 1608 1609 if (status & EHCI_USBSTS_PORTCHANGE) 1610 TRACE("port change detected\n"); 1611 1612 if (status & EHCI_USBSTS_INTONAA) { 1613 TRACE("interrupt on async advance\n"); 1614 asyncAdvance = true; 1615 result = B_INVOKE_SCHEDULER; 1616 } 1617 1618 if (status & EHCI_USBSTS_HOSTSYSERR) 1619 TRACE_ERROR("host system error!\n"); 1620 1621 WriteOpReg(EHCI_USBSTS, status); 1622 release_spinlock(&lock); 1623 1624 if (asyncAdvance) 1625 release_sem_etc(fAsyncAdvanceSem, 1, B_DO_NOT_RESCHEDULE); 1626 if (finishTransfers) 1627 release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE); 1628 1629 return result; 1630 } 1631 1632 1633 int32 1634 EHCI::InterruptPollThread(void *data) 1635 { 1636 EHCI *ehci = (EHCI *)data; 1637 1638 while (!ehci->fStopThreads) { 1639 // TODO: this could be handled much better by only polling when there 1640 // are actual transfers going on... 1641 snooze(1000); 1642 1643 cpu_status status = disable_interrupts(); 1644 ehci->Interrupt(); 1645 restore_interrupts(status); 1646 } 1647 1648 return 0; 1649 } 1650 1651 1652 status_t 1653 EHCI::AddPendingTransfer(Transfer *transfer, ehci_qh *queueHead, 1654 ehci_qtd *dataDescriptor, bool directionIn) 1655 { 1656 transfer_data *data = new(std::nothrow) transfer_data; 1657 if (!data) 1658 return B_NO_MEMORY; 1659 1660 data->transfer = transfer; 1661 data->queue_head = queueHead; 1662 data->data_descriptor = dataDescriptor; 1663 data->incoming = directionIn; 1664 data->canceled = false; 1665 data->link = NULL; 1666 1667 if (!Lock()) { 1668 delete data; 1669 return B_ERROR; 1670 } 1671 1672 // We do not support queuing other transfers in tandem with a fragmented one. 1673 transfer_data *it = fFirstTransfer; 1674 while (it) { 1675 if (it->transfer && it->transfer->TransferPipe() == transfer->TransferPipe() 1676 && it->transfer->IsFragmented()) { 1677 TRACE_ERROR("cannot submit transfer: a fragmented transfer is queued\n"); 1678 1679 Unlock(); 1680 delete data; 1681 return B_DEV_RESOURCE_CONFLICT; 1682 } 1683 1684 it = it->link; 1685 } 1686 1687 if (fLastTransfer) 1688 fLastTransfer->link = data; 1689 else 1690 fFirstTransfer = data; 1691 1692 fLastTransfer = data; 1693 Unlock(); 1694 1695 return B_OK; 1696 } 1697 1698 1699 status_t 1700 EHCI::AddPendingIsochronousTransfer(Transfer *transfer, ehci_itd **isoRequest, 1701 uint32 lastIndex, bool directionIn, addr_t bufferPhy, void* bufferLog, 1702 size_t bufferSize) 1703 { 1704 if (!transfer || !isoRequest) 1705 return B_BAD_VALUE; 1706 1707 isochronous_transfer_data *data 1708 = new(std::nothrow) isochronous_transfer_data; 1709 if (!data) 1710 return B_NO_MEMORY; 1711 1712 data->transfer = transfer; 1713 data->descriptors = isoRequest; 1714 data->last_to_process = lastIndex; 1715 data->incoming = directionIn; 1716 data->is_active = true; 1717 data->link = NULL; 1718 data->buffer_phy = bufferPhy; 1719 data->buffer_log = bufferLog; 1720 data->buffer_size = bufferSize; 1721 1722 // Put in the isochronous transfer list 1723 if (!LockIsochronous()) { 1724 delete data; 1725 return B_ERROR; 1726 } 1727 1728 if (fLastIsochronousTransfer) 1729 fLastIsochronousTransfer->link = data; 1730 else if (!fFirstIsochronousTransfer) 1731 fFirstIsochronousTransfer = data; 1732 1733 fLastIsochronousTransfer = data; 1734 UnlockIsochronous(); 1735 return B_OK; 1736 } 1737 1738 1739 status_t 1740 EHCI::CancelQueuedTransfers(Pipe *pipe, bool force) 1741 { 1742 if ((pipe->Type() & USB_OBJECT_ISO_PIPE) != 0) 1743 return CancelQueuedIsochronousTransfers(pipe, force); 1744 1745 if (!Lock()) 1746 return B_ERROR; 1747 1748 struct transfer_entry { 1749 Transfer * transfer; 1750 transfer_entry * next; 1751 }; 1752 1753 transfer_entry *list = NULL; 1754 transfer_data *current = fFirstTransfer; 1755 while (current) { 1756 if (current->transfer && current->transfer->TransferPipe() == pipe) { 1757 // clear the active bit so the descriptors are canceled 1758 ehci_qtd *descriptor = current->queue_head->element_log; 1759 while (descriptor) { 1760 descriptor->token &= ~EHCI_QTD_STATUS_ACTIVE; 1761 descriptor = descriptor->next_log; 1762 } 1763 1764 if (!force) { 1765 // if the transfer is canceled by force, the one causing the 1766 // cancel is probably not the one who initiated the transfer 1767 // and the callback is likely not safe anymore 1768 transfer_entry *entry 1769 = (transfer_entry *)malloc(sizeof(transfer_entry)); 1770 if (entry != NULL) { 1771 entry->transfer = current->transfer; 1772 current->transfer = NULL; 1773 entry->next = list; 1774 list = entry; 1775 } 1776 } 1777 1778 current->canceled = true; 1779 } 1780 1781 current = current->link; 1782 } 1783 1784 Unlock(); 1785 1786 while (list != NULL) { 1787 transfer_entry *next = list->next; 1788 list->transfer->Finished(B_CANCELED, 0); 1789 delete list->transfer; 1790 free(list); 1791 list = next; 1792 } 1793 1794 // wait for any transfers that might have made it before canceling 1795 while (fProcessingPipe == pipe) 1796 snooze(1000); 1797 1798 // notify the finisher so it can clean up the canceled transfers 1799 release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE); 1800 return B_OK; 1801 } 1802 1803 1804 status_t 1805 EHCI::CancelQueuedIsochronousTransfers(Pipe *pipe, bool force) 1806 { 1807 isochronous_transfer_data *current = fFirstIsochronousTransfer; 1808 1809 while (current) { 1810 if (current->transfer->TransferPipe() == pipe) { 1811 // TODO implement 1812 1813 // TODO: Use the force paramater in order to avoid calling 1814 // invalid callbacks 1815 current->is_active = false; 1816 } 1817 1818 current = current->link; 1819 } 1820 1821 TRACE_ERROR("no isochronous transfer found!\n"); 1822 return B_ERROR; 1823 } 1824 1825 1826 status_t 1827 EHCI::CancelAllPendingTransfers() 1828 { 1829 if (!Lock()) 1830 return B_ERROR; 1831 1832 transfer_data *transfer = fFirstTransfer; 1833 while (transfer) { 1834 transfer->transfer->Finished(B_CANCELED, 0); 1835 delete transfer->transfer; 1836 1837 transfer_data *next = transfer->link; 1838 delete transfer; 1839 transfer = next; 1840 } 1841 1842 fFirstTransfer = NULL; 1843 fLastTransfer = NULL; 1844 Unlock(); 1845 return B_OK; 1846 } 1847 1848 1849 int32 1850 EHCI::FinishThread(void *data) 1851 { 1852 ((EHCI *)data)->FinishTransfers(); 1853 return B_OK; 1854 } 1855 1856 1857 void 1858 EHCI::FinishTransfers() 1859 { 1860 while (!fStopThreads) { 1861 if (acquire_sem(fFinishTransfersSem) != B_OK) 1862 continue; 1863 1864 // eat up sems that have been released by multiple interrupts 1865 int32 semCount = 0; 1866 get_sem_count(fFinishTransfersSem, &semCount); 1867 if (semCount > 0) { 1868 acquire_sem_etc(fFinishTransfersSem, semCount, B_RELATIVE_TIMEOUT, 1869 0); 1870 } 1871 1872 if (!Lock()) 1873 continue; 1874 1875 TRACE("finishing transfers\n"); 1876 transfer_data *lastTransfer = NULL; 1877 transfer_data *transfer = fFirstTransfer; 1878 Unlock(); 1879 1880 while (transfer) { 1881 bool transferDone = false; 1882 ehci_qtd *descriptor = transfer->queue_head->element_log; 1883 status_t callbackStatus = B_OK; 1884 1885 while (descriptor) { 1886 uint32 status = descriptor->token; 1887 if (status & EHCI_QTD_STATUS_ACTIVE) { 1888 // still in progress 1889 TRACE("qtd (0x%08" B_PRIx32 ") still active\n", 1890 descriptor->this_phy); 1891 break; 1892 } 1893 1894 if (status & EHCI_QTD_STATUS_ERRMASK) { 1895 // a transfer error occured 1896 TRACE_ERROR("qtd (0x%" B_PRIx32 ") error: 0x%08" B_PRIx32 1897 "\n", descriptor->this_phy, status); 1898 1899 uint8 errorCount = status >> EHCI_QTD_ERRCOUNT_SHIFT; 1900 errorCount &= EHCI_QTD_ERRCOUNT_MASK; 1901 if (errorCount == 0) { 1902 // the error counter counted down to zero, report why 1903 int32 reasons = 0; 1904 if (status & EHCI_QTD_STATUS_BUFFER) { 1905 callbackStatus = transfer->incoming 1906 ? B_DEV_WRITE_ERROR : B_DEV_READ_ERROR; 1907 reasons++; 1908 } 1909 if (status & EHCI_QTD_STATUS_TERROR) { 1910 callbackStatus = B_DEV_CRC_ERROR; 1911 reasons++; 1912 } 1913 if ((transfer->queue_head->endpoint_chars 1914 & EHCI_QH_CHARS_EPS_HIGH) == 0) { 1915 // For full-/lowspeed endpoints the unused ping 1916 // state bit is used as another error bit, it is 1917 // unspecific however. 1918 if ((status & EHCI_QTD_STATUS_LS_ERR) != 0) { 1919 callbackStatus = B_DEV_STALLED; 1920 reasons++; 1921 } 1922 } 1923 1924 if (reasons > 1) 1925 callbackStatus = B_DEV_MULTIPLE_ERRORS; 1926 else if (reasons == 0) { 1927 TRACE_ERROR("error counter counted down to zero " 1928 "but none of the error bits are set\n"); 1929 callbackStatus = B_DEV_STALLED; 1930 } 1931 } else if (status & EHCI_QTD_STATUS_BABBLE) { 1932 // there is a babble condition 1933 callbackStatus = transfer->incoming 1934 ? B_DEV_DATA_OVERRUN : B_DEV_DATA_UNDERRUN; 1935 } else { 1936 // if the error counter didn't count down to zero 1937 // and there was no babble, then this halt was caused 1938 // by a stall handshake 1939 callbackStatus = B_DEV_STALLED; 1940 } 1941 1942 transferDone = true; 1943 break; 1944 } 1945 1946 if (descriptor->next_phy & EHCI_ITEM_TERMINATE) { 1947 // we arrived at the last (stray) descriptor, we're done 1948 TRACE("qtd (0x%08" B_PRIx32 ") done\n", 1949 descriptor->this_phy); 1950 callbackStatus = B_OK; 1951 transferDone = true; 1952 break; 1953 } 1954 1955 if (((status >> EHCI_QTD_PID_SHIFT) & EHCI_QTD_PID_MASK) 1956 == EHCI_QTD_PID_IN 1957 && ((status >> EHCI_QTD_BYTES_SHIFT) & EHCI_QTD_BYTES_MASK) 1958 != 0) { 1959 // a short packet condition existed on this descriptor, 1960 // follow the alternate next pointer if set 1961 if (descriptor->alt_next_log != NULL) { 1962 descriptor = descriptor->alt_next_log; 1963 continue; 1964 } 1965 1966 // no alternate next, transfer is done 1967 callbackStatus = B_OK; 1968 transferDone = true; 1969 break; 1970 } 1971 1972 descriptor = descriptor->next_log; 1973 } 1974 1975 if (!transferDone) { 1976 lastTransfer = transfer; 1977 transfer = transfer->link; 1978 continue; 1979 } 1980 1981 // remove the transfer from the list first so we are sure 1982 // it doesn't get canceled while we still process it 1983 transfer_data *next = transfer->link; 1984 if (Lock()) { 1985 if (lastTransfer) 1986 lastTransfer->link = transfer->link; 1987 1988 if (transfer == fFirstTransfer) 1989 fFirstTransfer = transfer->link; 1990 if (transfer == fLastTransfer) 1991 fLastTransfer = lastTransfer; 1992 1993 // store the currently processing pipe here so we can wait 1994 // in cancel if we are processing something on the target pipe 1995 if (!transfer->canceled) 1996 fProcessingPipe = transfer->transfer->TransferPipe(); 1997 1998 transfer->link = NULL; 1999 Unlock(); 2000 } 2001 2002 // if canceled the callback has already been called 2003 if (!transfer->canceled) { 2004 size_t actualLength = 0; 2005 2006 if (callbackStatus == B_OK) { 2007 bool nextDataToggle = false; 2008 if (transfer->data_descriptor && transfer->incoming) { 2009 // data to read out 2010 generic_io_vec *vector = transfer->transfer->Vector(); 2011 size_t vectorCount = transfer->transfer->VectorCount(); 2012 callbackStatus = transfer->transfer->PrepareKernelAccess(); 2013 if (callbackStatus == B_OK) { 2014 actualLength = ReadDescriptorChain( 2015 transfer->data_descriptor, 2016 vector, vectorCount, transfer->transfer->IsPhysical(), 2017 &nextDataToggle); 2018 } 2019 } else if (transfer->data_descriptor) { 2020 // calculate transfered length 2021 actualLength = ReadActualLength( 2022 transfer->data_descriptor, &nextDataToggle); 2023 } 2024 2025 transfer->transfer->TransferPipe()->SetDataToggle( 2026 nextDataToggle); 2027 } 2028 2029 if (callbackStatus == B_OK && transfer->transfer->IsFragmented()) { 2030 // this transfer may still have data left 2031 transfer->transfer->AdvanceByFragment(actualLength); 2032 if (transfer->transfer->FragmentLength() > 0) { 2033 FreeDescriptorChain(transfer->data_descriptor); 2034 status_t result = FillQueueWithData( 2035 transfer->transfer, 2036 transfer->queue_head, 2037 &transfer->data_descriptor, NULL, true); 2038 2039 if (result == B_OK && Lock()) { 2040 // reappend the transfer 2041 if (fLastTransfer) 2042 fLastTransfer->link = transfer; 2043 if (!fFirstTransfer) 2044 fFirstTransfer = transfer; 2045 2046 fLastTransfer = transfer; 2047 Unlock(); 2048 2049 transfer = next; 2050 continue; 2051 } 2052 } 2053 2054 // the transfer is done, but we already set the 2055 // actualLength with AdvanceByFragment() 2056 actualLength = 0; 2057 } 2058 2059 transfer->transfer->Finished(callbackStatus, actualLength); 2060 fProcessingPipe = NULL; 2061 } 2062 2063 // unlink hardware queue and delete the transfer 2064 UnlinkQueueHead(transfer->queue_head, &fFreeListHead); 2065 delete transfer->transfer; 2066 delete transfer; 2067 transfer = next; 2068 release_sem(fCleanupSem); 2069 } 2070 } 2071 } 2072 2073 2074 int32 2075 EHCI::CleanupThread(void *data) 2076 { 2077 ((EHCI *)data)->Cleanup(); 2078 return B_OK; 2079 } 2080 2081 2082 void 2083 EHCI::Cleanup() 2084 { 2085 ehci_qh *lastFreeListHead = NULL; 2086 2087 while (!fStopThreads) { 2088 if (acquire_sem(fCleanupSem) != B_OK) 2089 continue; 2090 2091 ehci_qh *freeListHead = fFreeListHead; 2092 if (freeListHead == lastFreeListHead) 2093 continue; 2094 2095 // set the doorbell and wait for the host controller to notify us 2096 WriteOpReg(EHCI_USBCMD, ReadOpReg(EHCI_USBCMD) | EHCI_USBCMD_INTONAAD); 2097 if (acquire_sem(fAsyncAdvanceSem) != B_OK) 2098 continue; 2099 2100 ehci_qh *current = freeListHead; 2101 while (current != lastFreeListHead) { 2102 ehci_qh *next = current->next_log; 2103 FreeQueueHead(current); 2104 current = next; 2105 } 2106 2107 lastFreeListHead = freeListHead; 2108 } 2109 } 2110 2111 2112 int32 2113 EHCI::FinishIsochronousThread(void *data) 2114 { 2115 ((EHCI *)data)->FinishIsochronousTransfers(); 2116 return B_OK; 2117 } 2118 2119 2120 void 2121 EHCI::FinishIsochronousTransfers() 2122 { 2123 /* This thread stays one position behind the controller and processes every 2124 * isochronous descriptor. Once it finds the last isochronous descriptor 2125 * of a transfer, it processes the entire transfer. 2126 */ 2127 while (!fStopThreads) { 2128 // Go to sleep if there are no isochronous transfers to process 2129 if (acquire_sem(fFinishIsochronousTransfersSem) != B_OK) 2130 return; 2131 2132 bool transferDone = false; 2133 2134 uint32 frame = (ReadOpReg(EHCI_FRINDEX) / 8 ) 2135 & (EHCI_FRAMELIST_ENTRIES_COUNT - 1); 2136 uint32 currentFrame = (frame + EHCI_VFRAMELIST_ENTRIES_COUNT - 5) 2137 & (EHCI_VFRAMELIST_ENTRIES_COUNT - 1); 2138 uint32 loop = 0; 2139 2140 // Process the frame list until one transfer is processed 2141 while (!transferDone && loop++ < EHCI_VFRAMELIST_ENTRIES_COUNT) { 2142 // wait 1ms in order to be sure to be one position behind 2143 // the controller 2144 while (currentFrame == (((ReadOpReg(EHCI_FRINDEX) / 8) 2145 & (EHCI_VFRAMELIST_ENTRIES_COUNT - 1)))) { 2146 snooze(1000); 2147 } 2148 2149 ehci_itd *itd = fItdEntries[currentFrame]; 2150 2151 TRACE("FinishIsochronousTransfers itd %p phy 0x%" B_PRIx32 2152 " prev (%p/0x%" B_PRIx32 ") at frame %" B_PRId32 "\n", itd, 2153 itd->this_phy, itd->prev, itd->prev != NULL 2154 ? itd->prev->this_phy : 0, currentFrame); 2155 2156 if (!LockIsochronous()) 2157 continue; 2158 2159 // Process the frame till it has isochronous descriptors in it. 2160 while (!(itd->next_phy & EHCI_ITEM_TERMINATE) && itd->prev != NULL) { 2161 TRACE("FinishIsochronousTransfers checking itd %p last_token" 2162 " %" B_PRId32 "\n", itd, itd->last_token); 2163 TRACE("FinishIsochronousTransfers tokens 0x%" B_PRIx32 " 0x%" 2164 B_PRIx32 " 0x%" B_PRIx32 " 0x%" B_PRIx32 " 0x%" B_PRIx32 2165 " 0x%" B_PRIx32 " 0x%" B_PRIx32 " 0x%" B_PRIx32 "\n", 2166 itd->token[0], itd->token[1], itd->token[2], itd->token[3], 2167 itd->token[4], itd->token[5], itd->token[6], itd->token[7]); 2168 if (((itd->token[itd->last_token] >> EHCI_ITD_STATUS_SHIFT) 2169 & EHCI_ITD_STATUS_ACTIVE) == EHCI_ITD_STATUS_ACTIVE) { 2170 TRACE("FinishIsochronousTransfers unprocessed active itd\n"); 2171 } 2172 UnlinkITDescriptors(itd, &fItdEntries[currentFrame]); 2173 2174 // Process the transfer if we found the last descriptor 2175 isochronous_transfer_data *transfer 2176 = FindIsochronousTransfer(itd); 2177 // Process the descriptors only if it is still active and 2178 // belongs to an inbound transfer. If the transfer is not 2179 // active, it means the request has been removed, so simply 2180 // remove the descriptors. 2181 if (transfer && transfer->is_active) { 2182 TRACE("FinishIsochronousTransfers active transfer\n"); 2183 size_t actualLength = 0; 2184 status_t status = B_OK; 2185 if (((itd->buffer_phy[1] >> EHCI_ITD_DIR_SHIFT) & 1) != 0) { 2186 status = transfer->transfer->PrepareKernelAccess(); 2187 if (status == B_OK) 2188 actualLength = ReadIsochronousDescriptorChain(transfer); 2189 } 2190 2191 // Remove the transfer 2192 if (transfer == fFirstIsochronousTransfer) { 2193 fFirstIsochronousTransfer = transfer->link; 2194 if (transfer == fLastIsochronousTransfer) 2195 fLastIsochronousTransfer = NULL; 2196 } else { 2197 isochronous_transfer_data *temp 2198 = fFirstIsochronousTransfer; 2199 while (temp != NULL && transfer != temp->link) 2200 temp = temp->link; 2201 2202 if (transfer == fLastIsochronousTransfer) 2203 fLastIsochronousTransfer = temp; 2204 if (temp != NULL && temp->link != NULL) 2205 temp->link = temp->link->link; 2206 } 2207 transfer->link = NULL; 2208 2209 transfer->transfer->Finished(status, actualLength); 2210 2211 itd = itd->prev; 2212 2213 for (uint32 i = 0; i <= transfer->last_to_process; i++) 2214 FreeDescriptor(transfer->descriptors[i]); 2215 2216 TRACE("FinishIsochronousTransfers descriptors freed\n"); 2217 2218 delete [] transfer->descriptors; 2219 delete transfer->transfer; 2220 fStack->FreeChunk(transfer->buffer_log, 2221 (phys_addr_t)transfer->buffer_phy, 2222 transfer->buffer_size); 2223 delete transfer; 2224 transferDone = true; 2225 } else { 2226 TRACE("FinishIsochronousTransfers not end of transfer\n"); 2227 itd = itd->prev; 2228 } 2229 } 2230 2231 UnlockIsochronous(); 2232 2233 TRACE("FinishIsochronousTransfers next frame\n"); 2234 2235 // Make sure to reset the frame bandwidth 2236 fFrameBandwidth[currentFrame] = MAX_AVAILABLE_BANDWIDTH; 2237 currentFrame = (currentFrame + 1) % EHCI_VFRAMELIST_ENTRIES_COUNT; 2238 } 2239 } 2240 } 2241 2242 2243 ehci_qh * 2244 EHCI::CreateQueueHead() 2245 { 2246 ehci_qh *result; 2247 phys_addr_t physicalAddress; 2248 if (fStack->AllocateChunk((void **)&result, &physicalAddress, 2249 sizeof(ehci_qh)) != B_OK) { 2250 TRACE_ERROR("failed to allocate queue head\n"); 2251 return NULL; 2252 } 2253 2254 result->this_phy = (addr_t)physicalAddress | EHCI_ITEM_TYPE_QH; 2255 result->next_phy = EHCI_ITEM_TERMINATE; 2256 result->next_log = NULL; 2257 result->prev_log = NULL; 2258 2259 ehci_qtd *descriptor = CreateDescriptor(0, 0); 2260 if (!descriptor) { 2261 TRACE_ERROR("failed to allocate initial qtd for queue head\n"); 2262 fStack->FreeChunk(result, physicalAddress, sizeof(ehci_qh)); 2263 return NULL; 2264 } 2265 2266 descriptor->token &= ~EHCI_QTD_STATUS_ACTIVE; 2267 result->stray_log = descriptor; 2268 result->element_log = descriptor; 2269 result->current_qtd_phy = 0; 2270 result->overlay.next_phy = descriptor->this_phy; 2271 result->overlay.alt_next_phy = EHCI_ITEM_TERMINATE; 2272 result->overlay.token = 0; 2273 for (int32 i = 0; i < 5; i++) { 2274 result->overlay.buffer_phy[i] = 0; 2275 result->overlay.ext_buffer_phy[i] = 0; 2276 } 2277 2278 return result; 2279 } 2280 2281 2282 status_t 2283 EHCI::InitQueueHead(ehci_qh *queueHead, Pipe *pipe) 2284 { 2285 switch (pipe->Speed()) { 2286 case USB_SPEED_LOWSPEED: 2287 queueHead->endpoint_chars = EHCI_QH_CHARS_EPS_LOW; 2288 break; 2289 case USB_SPEED_FULLSPEED: 2290 queueHead->endpoint_chars = EHCI_QH_CHARS_EPS_FULL; 2291 break; 2292 case USB_SPEED_HIGHSPEED: 2293 queueHead->endpoint_chars = EHCI_QH_CHARS_EPS_HIGH; 2294 break; 2295 default: 2296 TRACE_ERROR("unknown pipe speed\n"); 2297 return B_ERROR; 2298 } 2299 2300 queueHead->endpoint_chars |= (3 << EHCI_QH_CHARS_RL_SHIFT) 2301 | (pipe->MaxPacketSize() << EHCI_QH_CHARS_MPL_SHIFT) 2302 | (pipe->EndpointAddress() << EHCI_QH_CHARS_EPT_SHIFT) 2303 | (pipe->DeviceAddress() << EHCI_QH_CHARS_DEV_SHIFT) 2304 | EHCI_QH_CHARS_TOGGLE; 2305 2306 queueHead->endpoint_caps = (1 << EHCI_QH_CAPS_MULT_SHIFT); 2307 if (pipe->Speed() != USB_SPEED_HIGHSPEED) { 2308 if ((pipe->Type() & USB_OBJECT_CONTROL_PIPE) != 0) 2309 queueHead->endpoint_chars |= EHCI_QH_CHARS_CONTROL; 2310 2311 queueHead->endpoint_caps |= (pipe->HubPort() << EHCI_QH_CAPS_PORT_SHIFT) 2312 | (pipe->HubAddress() << EHCI_QH_CAPS_HUB_SHIFT); 2313 } 2314 2315 return B_OK; 2316 } 2317 2318 2319 void 2320 EHCI::FreeQueueHead(ehci_qh *queueHead) 2321 { 2322 if (!queueHead) 2323 return; 2324 2325 FreeDescriptorChain(queueHead->element_log); 2326 FreeDescriptor(queueHead->stray_log); 2327 fStack->FreeChunk(queueHead, (phys_addr_t)queueHead->this_phy, 2328 sizeof(ehci_qh)); 2329 } 2330 2331 2332 status_t 2333 EHCI::LinkQueueHead(ehci_qh *queueHead) 2334 { 2335 if (!Lock()) 2336 return B_ERROR; 2337 2338 ehci_qh *prevHead = fAsyncQueueHead->prev_log; 2339 queueHead->next_phy = fAsyncQueueHead->this_phy; 2340 queueHead->next_log = fAsyncQueueHead; 2341 queueHead->prev_log = prevHead; 2342 fAsyncQueueHead->prev_log = queueHead; 2343 prevHead->next_log = queueHead; 2344 prevHead->next_phy = queueHead->this_phy; 2345 2346 Unlock(); 2347 return B_OK; 2348 } 2349 2350 2351 status_t 2352 EHCI::LinkInterruptQueueHead(ehci_qh *queueHead, Pipe *pipe) 2353 { 2354 uint8 interval = pipe->Interval(); 2355 if (pipe->Speed() == USB_SPEED_HIGHSPEED) { 2356 // Allow interrupts to be scheduled on each possible micro frame. 2357 queueHead->endpoint_caps |= (0xff << EHCI_QH_CAPS_ISM_SHIFT); 2358 } else { 2359 // As we do not yet support FSTNs to correctly reference low/full 2360 // speed interrupt transfers, we simply put them into the 1 or 8 interval 2361 // queue. This way we ensure that we reach them on every micro frame 2362 // and can do the corresponding start/complete split transactions. 2363 // ToDo: use FSTNs to correctly link non high speed interrupt transfers 2364 if (pipe->Speed() == USB_SPEED_LOWSPEED) { 2365 // Low speed devices can't be polled faster than 8ms, so just use 2366 // that. 2367 interval = 4; 2368 } else 2369 interval = 1; 2370 2371 // For now we also force start splits to be in micro frame 0 and 2372 // complete splits to be in micro frame 2, 3 and 4. 2373 queueHead->endpoint_caps |= (0x01 << EHCI_QH_CAPS_ISM_SHIFT); 2374 queueHead->endpoint_caps |= (0x1c << EHCI_QH_CAPS_SCM_SHIFT); 2375 } 2376 2377 // this should not happen 2378 if (interval < 1) 2379 interval = 1; 2380 2381 // this may happen as intervals can go up to 16; we limit the value to 2382 // EHCI_INTERRUPT_ENTRIES_COUNT as you cannot support intervals above 2383 // that with a frame list of just EHCI_VFRAMELIST_ENTRIES_COUNT entries... 2384 if (interval > EHCI_INTERRUPT_ENTRIES_COUNT) 2385 interval = EHCI_INTERRUPT_ENTRIES_COUNT; 2386 2387 if (!Lock()) 2388 return B_ERROR; 2389 2390 ehci_qh *interruptQueue = &fInterruptEntries[interval - 1].queue_head; 2391 queueHead->next_phy = interruptQueue->next_phy; 2392 queueHead->next_log = interruptQueue->next_log; 2393 queueHead->prev_log = interruptQueue; 2394 if (interruptQueue->next_log) 2395 interruptQueue->next_log->prev_log = queueHead; 2396 interruptQueue->next_log = queueHead; 2397 interruptQueue->next_phy = queueHead->this_phy; 2398 2399 Unlock(); 2400 return B_OK; 2401 } 2402 2403 2404 status_t 2405 EHCI::UnlinkQueueHead(ehci_qh *queueHead, ehci_qh **freeListHead) 2406 { 2407 if (!Lock()) 2408 return B_ERROR; 2409 2410 ehci_qh *prevHead = queueHead->prev_log; 2411 ehci_qh *nextHead = queueHead->next_log; 2412 if (prevHead) { 2413 prevHead->next_phy = queueHead->next_phy; 2414 prevHead->next_log = queueHead->next_log; 2415 } 2416 2417 if (nextHead) 2418 nextHead->prev_log = queueHead->prev_log; 2419 2420 queueHead->next_phy = fAsyncQueueHead->this_phy; 2421 queueHead->prev_log = NULL; 2422 2423 queueHead->next_log = *freeListHead; 2424 *freeListHead = queueHead; 2425 2426 Unlock(); 2427 return B_OK; 2428 } 2429 2430 2431 status_t 2432 EHCI::FillQueueWithRequest(Transfer *transfer, ehci_qh *queueHead, 2433 ehci_qtd **_dataDescriptor, bool *_directionIn, bool prepareKernelAccess) 2434 { 2435 Pipe *pipe = transfer->TransferPipe(); 2436 usb_request_data *requestData = transfer->RequestData(); 2437 bool directionIn = (requestData->RequestType & USB_REQTYPE_DEVICE_IN) > 0; 2438 2439 ehci_qtd *setupDescriptor = CreateDescriptor(sizeof(usb_request_data), 2440 EHCI_QTD_PID_SETUP); 2441 ehci_qtd *statusDescriptor = CreateDescriptor(0, 2442 directionIn ? EHCI_QTD_PID_OUT : EHCI_QTD_PID_IN); 2443 2444 if (!setupDescriptor || !statusDescriptor) { 2445 TRACE_ERROR("failed to allocate descriptors\n"); 2446 FreeDescriptor(setupDescriptor); 2447 FreeDescriptor(statusDescriptor); 2448 return B_NO_MEMORY; 2449 } 2450 2451 generic_io_vec vector; 2452 vector.base = (generic_addr_t)requestData; 2453 vector.length = sizeof(usb_request_data); 2454 WriteDescriptorChain(setupDescriptor, &vector, 1, false); 2455 2456 ehci_qtd *strayDescriptor = queueHead->stray_log; 2457 statusDescriptor->token |= EHCI_QTD_IOC | EHCI_QTD_DATA_TOGGLE; 2458 2459 ehci_qtd *dataDescriptor = NULL; 2460 if (transfer->VectorCount() > 0) { 2461 ehci_qtd *lastDescriptor = NULL; 2462 status_t result = CreateDescriptorChain(pipe, &dataDescriptor, 2463 &lastDescriptor, statusDescriptor, transfer->FragmentLength(), 2464 directionIn ? EHCI_QTD_PID_IN : EHCI_QTD_PID_OUT); 2465 2466 if (result != B_OK) { 2467 FreeDescriptor(setupDescriptor); 2468 FreeDescriptor(statusDescriptor); 2469 return result; 2470 } 2471 2472 if (!directionIn) { 2473 if (prepareKernelAccess) { 2474 result = transfer->PrepareKernelAccess(); 2475 if (result != B_OK) { 2476 FreeDescriptor(setupDescriptor); 2477 FreeDescriptor(statusDescriptor); 2478 return result; 2479 } 2480 } 2481 WriteDescriptorChain(dataDescriptor, transfer->Vector(), 2482 transfer->VectorCount(), transfer->IsPhysical()); 2483 } 2484 2485 LinkDescriptors(setupDescriptor, dataDescriptor, strayDescriptor); 2486 LinkDescriptors(lastDescriptor, statusDescriptor, statusDescriptor); 2487 } else { 2488 // no data: link setup and status descriptors directly 2489 LinkDescriptors(setupDescriptor, statusDescriptor, strayDescriptor); 2490 } 2491 2492 queueHead->element_log = setupDescriptor; 2493 queueHead->overlay.next_phy = setupDescriptor->this_phy; 2494 queueHead->overlay.alt_next_phy = EHCI_ITEM_TERMINATE; 2495 2496 *_dataDescriptor = dataDescriptor; 2497 *_directionIn = directionIn; 2498 return B_OK; 2499 } 2500 2501 2502 status_t 2503 EHCI::FillQueueWithData(Transfer *transfer, ehci_qh *queueHead, 2504 ehci_qtd **_dataDescriptor, bool *_directionIn, bool prepareKernelAccess) 2505 { 2506 Pipe *pipe = transfer->TransferPipe(); 2507 bool directionIn = (pipe->Direction() == Pipe::In); 2508 2509 ehci_qtd *firstDescriptor = NULL; 2510 ehci_qtd *lastDescriptor = NULL; 2511 ehci_qtd *strayDescriptor = queueHead->stray_log; 2512 status_t result = CreateDescriptorChain(pipe, &firstDescriptor, 2513 &lastDescriptor, strayDescriptor, transfer->FragmentLength(), 2514 directionIn ? EHCI_QTD_PID_IN : EHCI_QTD_PID_OUT); 2515 2516 if (result != B_OK) 2517 return result; 2518 2519 lastDescriptor->token |= EHCI_QTD_IOC; 2520 if (!directionIn) { 2521 if (prepareKernelAccess) { 2522 result = transfer->PrepareKernelAccess(); 2523 if (result != B_OK) { 2524 FreeDescriptorChain(firstDescriptor); 2525 return result; 2526 } 2527 } 2528 WriteDescriptorChain(firstDescriptor, transfer->Vector(), 2529 transfer->VectorCount(), transfer->IsPhysical()); 2530 } 2531 2532 queueHead->element_log = firstDescriptor; 2533 queueHead->overlay.next_phy = firstDescriptor->this_phy; 2534 queueHead->overlay.alt_next_phy = EHCI_ITEM_TERMINATE; 2535 2536 *_dataDescriptor = firstDescriptor; 2537 if (_directionIn) 2538 *_directionIn = directionIn; 2539 return B_OK; 2540 } 2541 2542 2543 ehci_qtd * 2544 EHCI::CreateDescriptor(size_t bufferSize, uint8 pid) 2545 { 2546 ehci_qtd *result; 2547 phys_addr_t physicalAddress; 2548 if (fStack->AllocateChunk((void **)&result, &physicalAddress, 2549 sizeof(ehci_qtd)) != B_OK) { 2550 TRACE_ERROR("failed to allocate a qtd\n"); 2551 return NULL; 2552 } 2553 2554 result->this_phy = (addr_t)physicalAddress; 2555 result->next_phy = EHCI_ITEM_TERMINATE; 2556 result->next_log = NULL; 2557 result->alt_next_phy = EHCI_ITEM_TERMINATE; 2558 result->alt_next_log = NULL; 2559 result->buffer_size = bufferSize; 2560 result->token = bufferSize << EHCI_QTD_BYTES_SHIFT; 2561 result->token |= 3 << EHCI_QTD_ERRCOUNT_SHIFT; 2562 result->token |= pid << EHCI_QTD_PID_SHIFT; 2563 result->token |= EHCI_QTD_STATUS_ACTIVE; 2564 if (bufferSize == 0) { 2565 result->buffer_log = NULL; 2566 for (int32 i = 0; i < 5; i++) { 2567 result->buffer_phy[i] = 0; 2568 result->ext_buffer_phy[i] = 0; 2569 } 2570 2571 return result; 2572 } 2573 2574 if (fStack->AllocateChunk(&result->buffer_log, &physicalAddress, 2575 bufferSize) != B_OK) { 2576 TRACE_ERROR("unable to allocate qtd buffer\n"); 2577 fStack->FreeChunk(result, (phys_addr_t)result->this_phy, 2578 sizeof(ehci_qtd)); 2579 return NULL; 2580 } 2581 2582 addr_t physicalBase = (addr_t)physicalAddress; 2583 result->buffer_phy[0] = physicalBase; 2584 result->ext_buffer_phy[0] = 0; 2585 for (int32 i = 1; i < 5; i++) { 2586 physicalBase += B_PAGE_SIZE; 2587 result->buffer_phy[i] = physicalBase & EHCI_QTD_PAGE_MASK; 2588 result->ext_buffer_phy[i] = 0; 2589 } 2590 2591 return result; 2592 } 2593 2594 2595 status_t 2596 EHCI::CreateDescriptorChain(Pipe *pipe, ehci_qtd **_firstDescriptor, 2597 ehci_qtd **_lastDescriptor, ehci_qtd *strayDescriptor, size_t bufferSize, 2598 uint8 pid) 2599 { 2600 size_t packetSize = B_PAGE_SIZE * 4; 2601 int32 descriptorCount = (bufferSize + packetSize - 1) / packetSize; 2602 2603 bool dataToggle = pipe->DataToggle(); 2604 ehci_qtd *firstDescriptor = NULL; 2605 ehci_qtd *lastDescriptor = *_firstDescriptor; 2606 for (int32 i = 0; i < descriptorCount; i++) { 2607 ehci_qtd *descriptor = CreateDescriptor(min_c(packetSize, bufferSize), 2608 pid); 2609 2610 if (!descriptor) { 2611 FreeDescriptorChain(firstDescriptor); 2612 return B_NO_MEMORY; 2613 } 2614 2615 if (dataToggle) 2616 descriptor->token |= EHCI_QTD_DATA_TOGGLE; 2617 2618 if (lastDescriptor) 2619 LinkDescriptors(lastDescriptor, descriptor, strayDescriptor); 2620 2621 bufferSize -= packetSize; 2622 lastDescriptor = descriptor; 2623 if (!firstDescriptor) 2624 firstDescriptor = descriptor; 2625 } 2626 2627 *_firstDescriptor = firstDescriptor; 2628 *_lastDescriptor = lastDescriptor; 2629 return B_OK; 2630 } 2631 2632 2633 void 2634 EHCI::FreeDescriptor(ehci_qtd *descriptor) 2635 { 2636 if (!descriptor) 2637 return; 2638 2639 if (descriptor->buffer_log) { 2640 fStack->FreeChunk(descriptor->buffer_log, 2641 (phys_addr_t)descriptor->buffer_phy[0], descriptor->buffer_size); 2642 } 2643 2644 fStack->FreeChunk(descriptor, (phys_addr_t)descriptor->this_phy, 2645 sizeof(ehci_qtd)); 2646 } 2647 2648 2649 void 2650 EHCI::FreeDescriptorChain(ehci_qtd *topDescriptor) 2651 { 2652 ehci_qtd *current = topDescriptor; 2653 ehci_qtd *next = NULL; 2654 2655 while (current) { 2656 next = current->next_log; 2657 FreeDescriptor(current); 2658 current = next; 2659 } 2660 } 2661 2662 2663 ehci_itd * 2664 EHCI::CreateItdDescriptor() 2665 { 2666 ehci_itd *result; 2667 phys_addr_t physicalAddress; 2668 if (fStack->AllocateChunk((void **)&result, &physicalAddress, 2669 sizeof(ehci_itd)) != B_OK) { 2670 TRACE_ERROR("failed to allocate a itd\n"); 2671 return NULL; 2672 } 2673 2674 memset(result, 0, sizeof(ehci_itd)); 2675 result->this_phy = (addr_t)physicalAddress; 2676 result->next_phy = EHCI_ITEM_TERMINATE; 2677 2678 return result; 2679 } 2680 2681 2682 ehci_sitd * 2683 EHCI::CreateSitdDescriptor() 2684 { 2685 ehci_sitd *result; 2686 phys_addr_t physicalAddress; 2687 if (fStack->AllocateChunk((void **)&result, &physicalAddress, 2688 sizeof(ehci_sitd)) != B_OK) { 2689 TRACE_ERROR("failed to allocate a sitd\n"); 2690 return NULL; 2691 } 2692 2693 memset(result, 0, sizeof(ehci_sitd)); 2694 result->this_phy = (addr_t)physicalAddress | EHCI_ITEM_TYPE_SITD; 2695 result->next_phy = EHCI_ITEM_TERMINATE; 2696 2697 return result; 2698 } 2699 2700 2701 void 2702 EHCI::FreeDescriptor(ehci_itd *descriptor) 2703 { 2704 if (!descriptor) 2705 return; 2706 2707 fStack->FreeChunk(descriptor, (phys_addr_t)descriptor->this_phy, 2708 sizeof(ehci_itd)); 2709 } 2710 2711 2712 void 2713 EHCI::FreeDescriptor(ehci_sitd *descriptor) 2714 { 2715 if (!descriptor) 2716 return; 2717 2718 fStack->FreeChunk(descriptor, (phys_addr_t)descriptor->this_phy, 2719 sizeof(ehci_sitd)); 2720 } 2721 2722 2723 void 2724 EHCI::LinkDescriptors(ehci_qtd *first, ehci_qtd *last, ehci_qtd *alt) 2725 { 2726 first->next_phy = last->this_phy; 2727 first->next_log = last; 2728 2729 if (alt) { 2730 first->alt_next_phy = alt->this_phy; 2731 first->alt_next_log = alt; 2732 } else { 2733 first->alt_next_phy = EHCI_ITEM_TERMINATE; 2734 first->alt_next_log = NULL; 2735 } 2736 } 2737 2738 2739 void 2740 EHCI::LinkITDescriptors(ehci_itd *itd, ehci_itd **_last) 2741 { 2742 ehci_itd *last = *_last; 2743 itd->next_phy = last->next_phy; 2744 itd->next = NULL; 2745 itd->prev = last; 2746 last->next = itd; 2747 last->next_phy = itd->this_phy; 2748 *_last = itd; 2749 } 2750 2751 2752 void 2753 EHCI::LinkSITDescriptors(ehci_sitd *sitd, ehci_sitd **_last) 2754 { 2755 ehci_sitd *last = *_last; 2756 sitd->next_phy = last->next_phy; 2757 sitd->next = NULL; 2758 sitd->prev = last; 2759 last->next = sitd; 2760 last->next_phy = sitd->this_phy; 2761 *_last = sitd; 2762 } 2763 2764 2765 void 2766 EHCI::UnlinkITDescriptors(ehci_itd *itd, ehci_itd **last) 2767 { 2768 itd->prev->next_phy = itd->next_phy; 2769 itd->prev->next = itd->next; 2770 if (itd->next != NULL) 2771 itd->next->prev = itd->prev; 2772 if (itd == *last) 2773 *last = itd->prev; 2774 } 2775 2776 2777 void 2778 EHCI::UnlinkSITDescriptors(ehci_sitd *sitd, ehci_sitd **last) 2779 { 2780 sitd->prev->next_phy = sitd->next_phy; 2781 sitd->prev->next = sitd->next; 2782 if (sitd->next != NULL) 2783 sitd->next->prev = sitd->prev; 2784 if (sitd == *last) 2785 *last = sitd->prev; 2786 } 2787 2788 2789 size_t 2790 EHCI::WriteDescriptorChain(ehci_qtd *topDescriptor, generic_io_vec *vector, 2791 size_t vectorCount, bool physical) 2792 { 2793 ehci_qtd *current = topDescriptor; 2794 size_t actualLength = 0; 2795 size_t vectorIndex = 0; 2796 size_t vectorOffset = 0; 2797 size_t bufferOffset = 0; 2798 2799 while (current) { 2800 if (!current->buffer_log) 2801 break; 2802 2803 while (true) { 2804 size_t length = min_c(current->buffer_size - bufferOffset, 2805 vector[vectorIndex].length - vectorOffset); 2806 2807 status_t status = generic_memcpy( 2808 (generic_addr_t)current->buffer_log + bufferOffset, false, 2809 vector[vectorIndex].base + vectorOffset, physical, length); 2810 ASSERT(status == B_OK); 2811 2812 actualLength += length; 2813 vectorOffset += length; 2814 bufferOffset += length; 2815 2816 if (vectorOffset >= vector[vectorIndex].length) { 2817 if (++vectorIndex >= vectorCount) { 2818 TRACE("wrote descriptor chain (%ld bytes, no more vectors)" 2819 "\n", actualLength); 2820 return actualLength; 2821 } 2822 2823 vectorOffset = 0; 2824 } 2825 2826 if (bufferOffset >= current->buffer_size) { 2827 bufferOffset = 0; 2828 break; 2829 } 2830 } 2831 2832 if (current->next_phy & EHCI_ITEM_TERMINATE) 2833 break; 2834 2835 current = current->next_log; 2836 } 2837 2838 TRACE("wrote descriptor chain (%ld bytes)\n", actualLength); 2839 return actualLength; 2840 } 2841 2842 2843 size_t 2844 EHCI::ReadDescriptorChain(ehci_qtd *topDescriptor, generic_io_vec *vector, 2845 size_t vectorCount, bool physical, bool *nextDataToggle) 2846 { 2847 uint32 dataToggle = 0; 2848 ehci_qtd *current = topDescriptor; 2849 size_t actualLength = 0; 2850 size_t vectorIndex = 0; 2851 size_t vectorOffset = 0; 2852 size_t bufferOffset = 0; 2853 2854 while (current && (current->token & EHCI_QTD_STATUS_ACTIVE) == 0) { 2855 if (!current->buffer_log) 2856 break; 2857 2858 dataToggle = current->token & EHCI_QTD_DATA_TOGGLE; 2859 size_t bufferSize = current->buffer_size; 2860 bufferSize -= (current->token >> EHCI_QTD_BYTES_SHIFT) 2861 & EHCI_QTD_BYTES_MASK; 2862 2863 while (true) { 2864 size_t length = min_c(bufferSize - bufferOffset, 2865 vector[vectorIndex].length - vectorOffset); 2866 2867 status_t status = generic_memcpy( 2868 vector[vectorIndex].base + vectorOffset, physical, 2869 (generic_addr_t)current->buffer_log + bufferOffset, false, length); 2870 ASSERT(status == B_OK); 2871 2872 actualLength += length; 2873 vectorOffset += length; 2874 bufferOffset += length; 2875 2876 if (vectorOffset >= vector[vectorIndex].length) { 2877 if (++vectorIndex >= vectorCount) { 2878 TRACE("read descriptor chain (%ld bytes, no more vectors)" 2879 "\n", actualLength); 2880 *nextDataToggle = dataToggle > 0 ? true : false; 2881 return actualLength; 2882 } 2883 2884 vectorOffset = 0; 2885 } 2886 2887 if (bufferOffset >= bufferSize) { 2888 bufferOffset = 0; 2889 break; 2890 } 2891 } 2892 2893 if (current->next_phy & EHCI_ITEM_TERMINATE) 2894 break; 2895 2896 current = current->next_log; 2897 } 2898 2899 TRACE("read descriptor chain (%ld bytes)\n", actualLength); 2900 *nextDataToggle = dataToggle > 0 ? true : false; 2901 return actualLength; 2902 } 2903 2904 2905 size_t 2906 EHCI::ReadActualLength(ehci_qtd *topDescriptor, bool *nextDataToggle) 2907 { 2908 size_t actualLength = 0; 2909 ehci_qtd *current = topDescriptor; 2910 uint32 dataToggle = 0; 2911 2912 while (current && (current->token & EHCI_QTD_STATUS_ACTIVE) == 0) { 2913 dataToggle = current->token & EHCI_QTD_DATA_TOGGLE; 2914 size_t length = current->buffer_size; 2915 length -= (current->token >> EHCI_QTD_BYTES_SHIFT) 2916 & EHCI_QTD_BYTES_MASK; 2917 actualLength += length; 2918 2919 if (current->next_phy & EHCI_ITEM_TERMINATE) 2920 break; 2921 2922 current = current->next_log; 2923 } 2924 2925 TRACE("read actual length (%ld bytes)\n", actualLength); 2926 *nextDataToggle = dataToggle > 0 ? true : false; 2927 return actualLength; 2928 } 2929 2930 2931 size_t 2932 EHCI::WriteIsochronousDescriptorChain(isochronous_transfer_data *transfer) 2933 { 2934 // TODO implement 2935 return 0; 2936 } 2937 2938 2939 size_t 2940 EHCI::ReadIsochronousDescriptorChain(isochronous_transfer_data *transfer) 2941 { 2942 generic_io_vec *vector = transfer->transfer->Vector(); 2943 size_t vectorCount = transfer->transfer->VectorCount(); 2944 const bool physical = transfer->transfer->IsPhysical(); 2945 size_t vectorOffset = 0; 2946 size_t vectorIndex = 0; 2947 usb_isochronous_data *isochronousData 2948 = transfer->transfer->IsochronousData(); 2949 uint32 packet = 0; 2950 size_t totalLength = 0; 2951 size_t bufferOffset = 0; 2952 2953 size_t packetSize = transfer->transfer->DataLength(); 2954 packetSize /= isochronousData->packet_count; 2955 2956 for (uint32 i = 0; i <= transfer->last_to_process; i++) { 2957 ehci_itd *itd = transfer->descriptors[i]; 2958 for (uint32 j = 0; j <= itd->last_token 2959 && packet < isochronousData->packet_count; j++) { 2960 2961 size_t bufferSize = (itd->token[j] >> EHCI_ITD_TLENGTH_SHIFT) 2962 & EHCI_ITD_TLENGTH_MASK; 2963 if (((itd->token[j] >> EHCI_ITD_STATUS_SHIFT) 2964 & EHCI_ITD_STATUS_MASK) != 0) { 2965 bufferSize = 0; 2966 } 2967 isochronousData->packet_descriptors[packet].actual_length 2968 = bufferSize; 2969 2970 if (bufferSize > 0) 2971 isochronousData->packet_descriptors[packet].status = B_OK; 2972 else 2973 isochronousData->packet_descriptors[packet].status = B_ERROR; 2974 2975 totalLength += bufferSize; 2976 2977 size_t offset = bufferOffset; 2978 size_t skipSize = packetSize - bufferSize; 2979 while (bufferSize > 0) { 2980 size_t length = min_c(bufferSize, 2981 vector[vectorIndex].length - vectorOffset); 2982 status_t status = generic_memcpy( 2983 vector[vectorIndex].base + vectorOffset, physical, 2984 (generic_addr_t)transfer->buffer_log + bufferOffset, false, length); 2985 ASSERT(status == B_OK); 2986 2987 offset += length; 2988 vectorOffset += length; 2989 bufferSize -= length; 2990 2991 if (vectorOffset >= vector[vectorIndex].length) { 2992 if (++vectorIndex >= vectorCount) { 2993 TRACE("read isodescriptor chain (%ld bytes, no more " 2994 "vectors)\n", totalLength); 2995 return totalLength; 2996 } 2997 2998 vectorOffset = 0; 2999 } 3000 } 3001 3002 // skip to next packet offset 3003 while (skipSize > 0) { 3004 size_t length = min_c(skipSize, 3005 vector[vectorIndex].length - vectorOffset); 3006 vectorOffset += length; 3007 skipSize -= length; 3008 if (vectorOffset >= vector[vectorIndex].length) { 3009 if (++vectorIndex >= vectorCount) { 3010 TRACE("read isodescriptor chain (%ld bytes, no more " 3011 "vectors)\n", totalLength); 3012 return totalLength; 3013 } 3014 3015 vectorOffset = 0; 3016 } 3017 } 3018 3019 bufferOffset += packetSize; 3020 if (bufferOffset >= transfer->buffer_size) 3021 return totalLength; 3022 3023 packet++; 3024 } 3025 } 3026 3027 TRACE("ReadIsochronousDescriptorChain packet count %" B_PRId32 "\n", 3028 packet); 3029 3030 return totalLength; 3031 } 3032 3033 3034 bool 3035 EHCI::LockIsochronous() 3036 { 3037 return (mutex_lock(&fIsochronousLock) == B_OK); 3038 } 3039 3040 3041 void 3042 EHCI::UnlockIsochronous() 3043 { 3044 mutex_unlock(&fIsochronousLock); 3045 } 3046 3047 3048 inline void 3049 EHCI::WriteOpReg(uint32 reg, uint32 value) 3050 { 3051 *(volatile uint32 *)(fOperationalRegisters + reg) = value; 3052 } 3053 3054 3055 inline uint32 3056 EHCI::ReadOpReg(uint32 reg) 3057 { 3058 return *(volatile uint32 *)(fOperationalRegisters + reg); 3059 } 3060 3061 3062 inline uint8 3063 EHCI::ReadCapReg8(uint32 reg) 3064 { 3065 return *(volatile uint8 *)(fCapabilityRegisters + reg); 3066 } 3067 3068 3069 inline uint16 3070 EHCI::ReadCapReg16(uint32 reg) 3071 { 3072 return *(volatile uint16 *)(fCapabilityRegisters + reg); 3073 } 3074 3075 3076 inline uint32 3077 EHCI::ReadCapReg32(uint32 reg) 3078 { 3079 return *(volatile uint32 *)(fCapabilityRegisters + reg); 3080 } 3081