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