1 /* 2 * Copyright 2006-2019, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Michael Lotz <mmlr@mlotz.ch> 7 * Jian Chiang <j.jian.chiang@gmail.com> 8 * Jérôme Duval <jerome.duval@gmail.com> 9 * Akshay Jaggi <akshay1994.leo@gmail.com> 10 */ 11 12 13 #include <module.h> 14 #include <PCI.h> 15 #include <PCI_x86.h> 16 #include <USB3.h> 17 #include <KernelExport.h> 18 19 #include <util/AutoLock.h> 20 21 #include "xhci.h" 22 23 #define USB_MODULE_NAME "xhci" 24 25 pci_module_info *XHCI::sPCIModule = NULL; 26 pci_x86_module_info *XHCI::sPCIx86Module = NULL; 27 28 29 static int32 30 xhci_std_ops(int32 op, ...) 31 { 32 switch (op) { 33 case B_MODULE_INIT: 34 TRACE_MODULE("xhci init module\n"); 35 return B_OK; 36 case B_MODULE_UNINIT: 37 TRACE_MODULE("xhci uninit module\n"); 38 return B_OK; 39 } 40 41 return EINVAL; 42 } 43 44 45 static const char* 46 xhci_error_string(uint32 error) 47 { 48 switch (error) { 49 case COMP_INVALID: return "Invalid"; 50 case COMP_SUCCESS: return "Success"; 51 case COMP_DATA_BUFFER: return "Data buffer"; 52 case COMP_BABBLE: return "Babble detected"; 53 case COMP_USB_TRANSACTION: return "USB transaction"; 54 case COMP_TRB: return "TRB"; 55 case COMP_STALL: return "Stall"; 56 case COMP_RESOURCE: return "Resource"; 57 case COMP_BANDWIDTH: return "Bandwidth"; 58 case COMP_NO_SLOTS: return "No slots"; 59 case COMP_INVALID_STREAM: return "Invalid stream"; 60 case COMP_SLOT_NOT_ENABLED: return "Slot not enabled"; 61 case COMP_ENDPOINT_NOT_ENABLED: return "Endpoint not enabled"; 62 case COMP_SHORT_PACKET: return "Short packet"; 63 case COMP_RING_UNDERRUN: return "Ring underrun"; 64 case COMP_RING_OVERRUN: return "Ring overrun"; 65 case COMP_VF_RING_FULL: return "VF Event Ring Full"; 66 case COMP_PARAMETER: return "Parameter"; 67 case COMP_BANDWIDTH_OVERRUN: return "Bandwidth overrun"; 68 case COMP_CONTEXT_STATE: return "Context state"; 69 case COMP_NO_PING_RESPONSE: return "No ping response"; 70 case COMP_EVENT_RING_FULL: return "Event ring full"; 71 case COMP_INCOMPATIBLE_DEVICE: return "Incompatible device"; 72 case COMP_MISSED_SERVICE: return "Missed service"; 73 case COMP_COMMAND_RING_STOPPED: return "Command ring stopped"; 74 case COMP_COMMAND_ABORTED: return "Command aborted"; 75 case COMP_STOPPED: return "Stopped"; 76 case COMP_LENGTH_INVALID: return "Length invalid"; 77 case COMP_MAX_EXIT_LATENCY: return "Max exit latency too large"; 78 case COMP_ISOC_OVERRUN: return "Isoch buffer overrun"; 79 case COMP_EVENT_LOST: return "Event lost"; 80 case COMP_UNDEFINED: return "Undefined"; 81 case COMP_INVALID_STREAM_ID: return "Invalid stream ID"; 82 case COMP_SECONDARY_BANDWIDTH: return "Secondary bandwidth"; 83 case COMP_SPLIT_TRANSACTION: return "Split transaction"; 84 85 default: return "Undefined"; 86 } 87 } 88 89 90 usb_host_controller_info xhci_module = { 91 { 92 "busses/usb/xhci", 93 0, 94 xhci_std_ops 95 }, 96 NULL, 97 XHCI::AddTo 98 }; 99 100 101 module_info *modules[] = { 102 (module_info *)&xhci_module, 103 NULL 104 }; 105 106 107 XHCI::XHCI(pci_info *info, Stack *stack) 108 : BusManager(stack), 109 fRegisterArea(-1), 110 fRegisters(NULL), 111 fPCIInfo(info), 112 fStack(stack), 113 fIRQ(0), 114 fUseMSI(false), 115 fErstArea(-1), 116 fDcbaArea(-1), 117 fCmdCompSem(-1), 118 fFinishTransfersSem(-1), 119 fFinishThread(-1), 120 fStopThreads(false), 121 fFinishedHead(NULL), 122 fRootHub(NULL), 123 fRootHubAddress(0), 124 fPortCount(0), 125 fSlotCount(0), 126 fScratchpadCount(0), 127 fContextSizeShift(0), 128 fEventSem(-1), 129 fEventThread(-1), 130 fEventIdx(0), 131 fCmdIdx(0), 132 fEventCcs(1), 133 fCmdCcs(1) 134 { 135 B_INITIALIZE_SPINLOCK(&fSpinlock); 136 137 if (BusManager::InitCheck() < B_OK) { 138 TRACE_ERROR("bus manager failed to init\n"); 139 return; 140 } 141 142 TRACE("constructing new XHCI host controller driver\n"); 143 fInitOK = false; 144 145 // enable busmaster and memory mapped access 146 uint16 command = sPCIModule->read_pci_config(fPCIInfo->bus, 147 fPCIInfo->device, fPCIInfo->function, PCI_command, 2); 148 command &= ~(PCI_command_io | PCI_command_int_disable); 149 command |= PCI_command_master | PCI_command_memory; 150 151 sPCIModule->write_pci_config(fPCIInfo->bus, fPCIInfo->device, 152 fPCIInfo->function, PCI_command, 2, command); 153 154 // map the registers (low + high for 64-bit when requested) 155 phys_addr_t physicalAddress = fPCIInfo->u.h0.base_registers[0]; 156 physicalAddress &= PCI_address_memory_32_mask; 157 if ((fPCIInfo->u.h0.base_register_flags[0] & 0xC) == PCI_address_type_64) 158 physicalAddress += (phys_addr_t)fPCIInfo->u.h0.base_registers[1] << 32; 159 160 size_t mapSize = fPCIInfo->u.h0.base_register_sizes[0]; 161 162 TRACE("map physical memory %08" B_PRIx32 " : %08" B_PRIx32 " " 163 "(base: %08" B_PRIxPHYSADDR "; offset: %" B_PRIx32 ");" 164 "size: %" B_PRId32 "\n", fPCIInfo->u.h0.base_registers[0], 165 fPCIInfo->u.h0.base_registers[1], physicalAddress, offset, 166 fPCIInfo->u.h0.base_register_sizes[0]); 167 168 fRegisterArea = map_physical_memory("XHCI memory mapped registers", 169 physicalAddress, mapSize, B_ANY_KERNEL_BLOCK_ADDRESS, 170 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, 171 (void **)&fRegisters); 172 if (fRegisterArea < B_OK) { 173 TRACE_ERROR("failed to map register memory\n"); 174 return; 175 } 176 177 // determine the register offsets 178 fCapabilityRegisterOffset = 0; 179 fOperationalRegisterOffset = HCI_CAPLENGTH(ReadCapReg32(XHCI_HCI_CAPLENGTH)); 180 fRuntimeRegisterOffset = ReadCapReg32(XHCI_RTSOFF) & ~0x1F; 181 fDoorbellRegisterOffset = ReadCapReg32(XHCI_DBOFF) & ~0x3; 182 183 TRACE("mapped registers: %p\n", fRegisters); 184 TRACE("operational register offset: %d\n", fOperationalRegisterOffset); 185 TRACE("runtime register offset: %p\n", fRuntimeRegisterOffset); 186 TRACE("doorbell register offset: %p\n", fDoorbellRegisterOffset); 187 188 TRACE_ALWAYS("interface version: 0x%04" B_PRIx32 "\n", 189 HCI_VERSION(ReadCapReg32(XHCI_HCI_VERSION))); 190 TRACE_ALWAYS("structural parameters: 1:0x%08" B_PRIx32 " 2:0x%08" 191 B_PRIx32 " 3:0x%08" B_PRIx32 "\n", ReadCapReg32(XHCI_HCSPARAMS1), 192 ReadCapReg32(XHCI_HCSPARAMS2), ReadCapReg32(XHCI_HCSPARAMS3)); 193 uint32 cparams = ReadCapReg32(XHCI_HCCPARAMS); 194 TRACE_ALWAYS("capability params: 0x%08" B_PRIx32 "\n", cparams); 195 196 // if 64 bytes context structures, then 1 197 fContextSizeShift = HCC_CSZ(cparams); 198 199 uint32 eec = 0xffffffff; 200 uint32 eecp = HCS0_XECP(cparams) << 2; 201 for (; eecp != 0 && XECP_NEXT(eec); eecp += XECP_NEXT(eec) << 2) { 202 TRACE("eecp register: 0x%08" B_PRIx32 "\n", eecp); 203 204 eec = ReadCapReg32(eecp); 205 if (XECP_ID(eec) != XHCI_LEGSUP_CAPID) 206 continue; 207 208 if (eec & XHCI_LEGSUP_BIOSOWNED) { 209 TRACE_ALWAYS("the host controller is bios owned, claiming" 210 " ownership\n"); 211 WriteCapReg32(eecp, eec | XHCI_LEGSUP_OSOWNED); 212 213 for (int32 i = 0; i < 20; i++) { 214 eec = ReadCapReg32(eecp); 215 216 if ((eec & XHCI_LEGSUP_BIOSOWNED) == 0) 217 break; 218 219 TRACE_ALWAYS("controller is still bios owned, waiting\n"); 220 snooze(50000); 221 } 222 223 if (eec & XHCI_LEGSUP_BIOSOWNED) { 224 TRACE_ERROR("bios won't give up control over the host " 225 "controller (ignoring)\n"); 226 } else if (eec & XHCI_LEGSUP_OSOWNED) { 227 TRACE_ALWAYS("successfully took ownership of the host " 228 "controller\n"); 229 } 230 231 // Force off the BIOS owned flag, and clear all SMIs. Some BIOSes 232 // do indicate a successful handover but do not remove their SMIs 233 // and then freeze the system when interrupts are generated. 234 WriteCapReg32(eecp, eec & ~XHCI_LEGSUP_BIOSOWNED); 235 } 236 break; 237 } 238 uint32 legctlsts = ReadCapReg32(eecp + XHCI_LEGCTLSTS); 239 legctlsts &= XHCI_LEGCTLSTS_DISABLE_SMI; 240 legctlsts |= XHCI_LEGCTLSTS_EVENTS_SMI; 241 WriteCapReg32(eecp + XHCI_LEGCTLSTS, legctlsts); 242 243 // On Intel's Panther Point and Lynx Point Chipset taking ownership 244 // of EHCI owned ports, is what we do here. 245 if (fPCIInfo->vendor_id == PCI_VENDOR_INTEL) { 246 switch (fPCIInfo->device_id) { 247 case PCI_DEVICE_INTEL_PANTHER_POINT_XHCI: 248 case PCI_DEVICE_INTEL_LYNX_POINT_XHCI: 249 case PCI_DEVICE_INTEL_LYNX_POINT_LP_XHCI: 250 case PCI_DEVICE_INTEL_BAYTRAIL_XHCI: 251 case PCI_DEVICE_INTEL_WILDCAT_POINT_XHCI: 252 case PCI_DEVICE_INTEL_WILDCAT_POINT_LP_XHCI: 253 _SwitchIntelPorts(); 254 break; 255 } 256 } 257 258 // halt the host controller 259 if (ControllerHalt() < B_OK) { 260 return; 261 } 262 263 // reset the host controller 264 if (ControllerReset() < B_OK) { 265 TRACE_ERROR("host controller failed to reset\n"); 266 return; 267 } 268 269 fCmdCompSem = create_sem(0, "XHCI Command Complete"); 270 fFinishTransfersSem = create_sem(0, "XHCI Finish Transfers"); 271 fEventSem = create_sem(0, "XHCI Event"); 272 if (fFinishTransfersSem < B_OK || fCmdCompSem < B_OK || fEventSem < B_OK) { 273 TRACE_ERROR("failed to create semaphores\n"); 274 return; 275 } 276 277 // create finisher service thread 278 fFinishThread = spawn_kernel_thread(FinishThread, "xhci finish thread", 279 B_NORMAL_PRIORITY, (void *)this); 280 resume_thread(fFinishThread); 281 282 // create finisher service thread 283 fEventThread = spawn_kernel_thread(EventThread, "xhci event thread", 284 B_NORMAL_PRIORITY, (void *)this); 285 resume_thread(fEventThread); 286 287 // Find the right interrupt vector, using MSIs if available. 288 fIRQ = fPCIInfo->u.h0.interrupt_line; 289 if (sPCIx86Module != NULL && sPCIx86Module->get_msi_count(fPCIInfo->bus, 290 fPCIInfo->device, fPCIInfo->function) >= 1) { 291 uint8 msiVector = 0; 292 if (sPCIx86Module->configure_msi(fPCIInfo->bus, fPCIInfo->device, 293 fPCIInfo->function, 1, &msiVector) == B_OK 294 && sPCIx86Module->enable_msi(fPCIInfo->bus, fPCIInfo->device, 295 fPCIInfo->function) == B_OK) { 296 TRACE_ALWAYS("using message signaled interrupts\n"); 297 fIRQ = msiVector; 298 fUseMSI = true; 299 } 300 } 301 302 if (fIRQ == 0 || fIRQ == 0xFF) { 303 TRACE_MODULE_ERROR("device was assigned an invalid IRQ\n"); 304 return; 305 } 306 307 // Install the interrupt handler 308 TRACE("installing interrupt handler\n"); 309 install_io_interrupt_handler(fIRQ, InterruptHandler, (void *)this, 0); 310 311 memset(fPortSpeeds, 0, sizeof(fPortSpeeds)); 312 memset(fPortSlots, 0, sizeof(fPortSlots)); 313 memset(fDevices, 0, sizeof(fDevices)); 314 315 fInitOK = true; 316 TRACE("XHCI host controller driver constructed\n"); 317 } 318 319 320 XHCI::~XHCI() 321 { 322 TRACE("tear down XHCI host controller driver\n"); 323 324 WriteOpReg(XHCI_CMD, 0); 325 326 int32 result = 0; 327 fStopThreads = true; 328 delete_sem(fCmdCompSem); 329 delete_sem(fFinishTransfersSem); 330 delete_sem(fEventSem); 331 wait_for_thread(fFinishThread, &result); 332 wait_for_thread(fEventThread, &result); 333 334 remove_io_interrupt_handler(fIRQ, InterruptHandler, (void *)this); 335 336 delete_area(fRegisterArea); 337 delete_area(fErstArea); 338 for (uint32 i = 0; i < fScratchpadCount; i++) 339 delete_area(fScratchpadArea[i]); 340 delete_area(fDcbaArea); 341 342 if (fUseMSI && sPCIx86Module != NULL) { 343 sPCIx86Module->disable_msi(fPCIInfo->bus, 344 fPCIInfo->device, fPCIInfo->function); 345 sPCIx86Module->unconfigure_msi(fPCIInfo->bus, 346 fPCIInfo->device, fPCIInfo->function); 347 } 348 put_module(B_PCI_MODULE_NAME); 349 if (sPCIx86Module != NULL) { 350 sPCIx86Module = NULL; 351 put_module(B_PCI_X86_MODULE_NAME); 352 } 353 } 354 355 356 void 357 XHCI::_SwitchIntelPorts() 358 { 359 TRACE("Intel xHC Controller\n"); 360 TRACE("Looking for EHCI owned ports\n"); 361 uint32 ports = sPCIModule->read_pci_config(fPCIInfo->bus, 362 fPCIInfo->device, fPCIInfo->function, XHCI_INTEL_USB3PRM, 4); 363 TRACE("Superspeed Ports: 0x%" B_PRIx32 "\n", ports); 364 sPCIModule->write_pci_config(fPCIInfo->bus, fPCIInfo->device, 365 fPCIInfo->function, XHCI_INTEL_USB3_PSSEN, 4, ports); 366 ports = sPCIModule->read_pci_config(fPCIInfo->bus, 367 fPCIInfo->device, fPCIInfo->function, XHCI_INTEL_USB3_PSSEN, 4); 368 TRACE("Superspeed ports now under XHCI : 0x%" B_PRIx32 "\n", ports); 369 ports = sPCIModule->read_pci_config(fPCIInfo->bus, 370 fPCIInfo->device, fPCIInfo->function, XHCI_INTEL_USB2PRM, 4); 371 TRACE("USB 2.0 Ports : 0x%" B_PRIx32 "\n", ports); 372 sPCIModule->write_pci_config(fPCIInfo->bus, fPCIInfo->device, 373 fPCIInfo->function, XHCI_INTEL_XUSB2PR, 4, ports); 374 ports = sPCIModule->read_pci_config(fPCIInfo->bus, 375 fPCIInfo->device, fPCIInfo->function, XHCI_INTEL_XUSB2PR, 4); 376 TRACE("USB 2.0 ports now under XHCI: 0x%" B_PRIx32 "\n", ports); 377 } 378 379 380 status_t 381 XHCI::Start() 382 { 383 TRACE_ALWAYS("starting XHCI host controller\n"); 384 TRACE("usbcmd: 0x%08" B_PRIx32 "; usbsts: 0x%08" B_PRIx32 "\n", 385 ReadOpReg(XHCI_CMD), ReadOpReg(XHCI_STS)); 386 387 if (WaitOpBits(XHCI_STS, STS_CNR, 0) != B_OK) { 388 TRACE("Start() failed STS_CNR\n"); 389 } 390 391 if ((ReadOpReg(XHCI_CMD) & CMD_RUN) != 0) { 392 TRACE_ERROR("Start() warning, starting running XHCI controller!\n"); 393 } 394 395 if ((ReadOpReg(XHCI_PAGESIZE) & (1 << 0)) == 0) { 396 TRACE_ERROR("Controller does not support 4K page size.\n"); 397 return B_ERROR; 398 } 399 400 // read port count from capability register 401 uint32 capabilities = ReadCapReg32(XHCI_HCSPARAMS1); 402 fPortCount = HCS_MAX_PORTS(capabilities); 403 if (fPortCount == 0) { 404 TRACE_ERROR("Invalid number of ports: %u\n", fPortCount); 405 fPortCount = 0; 406 return B_ERROR; 407 } 408 fSlotCount = HCS_MAX_SLOTS(capabilities); 409 WriteOpReg(XHCI_CONFIG, fSlotCount); 410 411 // find out which protocol is used for each port 412 uint8 portFound = 0; 413 uint32 cparams = ReadCapReg32(XHCI_HCCPARAMS); 414 uint32 eec = 0xffffffff; 415 uint32 eecp = HCS0_XECP(cparams) << 2; 416 for (; eecp != 0 && XECP_NEXT(eec) && portFound < fPortCount; 417 eecp += XECP_NEXT(eec) << 2) { 418 eec = ReadCapReg32(eecp); 419 if (XECP_ID(eec) != XHCI_SUPPORTED_PROTOCOLS_CAPID) 420 continue; 421 if (XHCI_SUPPORTED_PROTOCOLS_0_MAJOR(eec) > 3) 422 continue; 423 uint32 temp = ReadCapReg32(eecp + 8); 424 uint32 offset = XHCI_SUPPORTED_PROTOCOLS_1_OFFSET(temp); 425 uint32 count = XHCI_SUPPORTED_PROTOCOLS_1_COUNT(temp); 426 if (offset == 0 || count == 0) 427 continue; 428 offset--; 429 for (uint32 i = offset; i < offset + count; i++) { 430 if (XHCI_SUPPORTED_PROTOCOLS_0_MAJOR(eec) == 0x3) 431 fPortSpeeds[i] = USB_SPEED_SUPER; 432 else 433 fPortSpeeds[i] = USB_SPEED_HIGHSPEED; 434 TRACE("speed for port %" B_PRId32 " is %s\n", i, 435 fPortSpeeds[i] == USB_SPEED_SUPER ? "super" : "high"); 436 } 437 portFound += count; 438 } 439 440 uint32 params2 = ReadCapReg32(XHCI_HCSPARAMS2); 441 fScratchpadCount = HCS_MAX_SC_BUFFERS(params2); 442 if (fScratchpadCount > XHCI_MAX_SCRATCHPADS) { 443 TRACE_ERROR("Invalid number of scratchpads: %" B_PRIu32 "\n", 444 fScratchpadCount); 445 return B_ERROR; 446 } 447 448 uint32 params3 = ReadCapReg32(XHCI_HCSPARAMS3); 449 fExitLatMax = HCS_U1_DEVICE_LATENCY(params3) 450 + HCS_U2_DEVICE_LATENCY(params3); 451 452 WriteOpReg(XHCI_DNCTRL, 0); 453 454 // allocate Device Context Base Address array 455 phys_addr_t dmaAddress; 456 fDcbaArea = fStack->AllocateArea((void **)&fDcba, &dmaAddress, 457 sizeof(*fDcba), "DCBA Area"); 458 if (fDcbaArea < B_OK) { 459 TRACE_ERROR("unable to create the DCBA area\n"); 460 return B_ERROR; 461 } 462 memset(fDcba, 0, sizeof(*fDcba)); 463 memset(fScratchpadArea, 0, sizeof(fScratchpadArea)); 464 memset(fScratchpad, 0, sizeof(fScratchpad)); 465 466 // setting the first address to the scratchpad array address 467 fDcba->baseAddress[0] = dmaAddress 468 + offsetof(struct xhci_device_context_array, scratchpad); 469 470 // fill up the scratchpad array with scratchpad pages 471 for (uint32 i = 0; i < fScratchpadCount; i++) { 472 phys_addr_t scratchDmaAddress; 473 fScratchpadArea[i] = fStack->AllocateArea((void **)&fScratchpad[i], 474 &scratchDmaAddress, B_PAGE_SIZE, "Scratchpad Area"); 475 if (fScratchpadArea[i] < B_OK) { 476 TRACE_ERROR("unable to create the scratchpad area\n"); 477 return B_ERROR; 478 } 479 fDcba->scratchpad[i] = scratchDmaAddress; 480 } 481 482 TRACE("setting DCBAAP %" B_PRIxPHYSADDR "\n", dmaAddress); 483 WriteOpReg(XHCI_DCBAAP_LO, (uint32)dmaAddress); 484 WriteOpReg(XHCI_DCBAAP_HI, /*(uint32)(dmaAddress >> 32)*/0); 485 486 // allocate Event Ring Segment Table 487 uint8 *addr; 488 fErstArea = fStack->AllocateArea((void **)&addr, &dmaAddress, 489 (XHCI_MAX_COMMANDS + XHCI_MAX_EVENTS) * sizeof(xhci_trb) 490 + sizeof(xhci_erst_element), 491 "USB XHCI ERST CMD_RING and EVENT_RING Area"); 492 493 if (fErstArea < B_OK) { 494 TRACE_ERROR("unable to create the ERST AND RING area\n"); 495 delete_area(fDcbaArea); 496 return B_ERROR; 497 } 498 fErst = (xhci_erst_element *)addr; 499 memset(fErst, 0, (XHCI_MAX_COMMANDS + XHCI_MAX_EVENTS) * sizeof(xhci_trb) 500 + sizeof(xhci_erst_element)); 501 502 // fill with Event Ring Segment Base Address and Event Ring Segment Size 503 fErst->rs_addr = dmaAddress + sizeof(xhci_erst_element); 504 fErst->rs_size = XHCI_MAX_EVENTS; 505 fErst->rsvdz = 0; 506 507 addr += sizeof(xhci_erst_element); 508 fEventRing = (xhci_trb *)addr; 509 addr += XHCI_MAX_EVENTS * sizeof(xhci_trb); 510 fCmdRing = (xhci_trb *)addr; 511 512 TRACE("setting ERST size\n"); 513 WriteRunReg32(XHCI_ERSTSZ(0), XHCI_ERSTS_SET(1)); 514 515 TRACE("setting ERDP addr = 0x%" B_PRIx64 "\n", fErst->rs_addr); 516 WriteRunReg32(XHCI_ERDP_LO(0), (uint32)fErst->rs_addr); 517 WriteRunReg32(XHCI_ERDP_HI(0), (uint32)(fErst->rs_addr >> 32)); 518 519 TRACE("setting ERST base addr = 0x%" B_PRIxPHYSADDR "\n", dmaAddress); 520 WriteRunReg32(XHCI_ERSTBA_LO(0), (uint32)dmaAddress); 521 WriteRunReg32(XHCI_ERSTBA_HI(0), (uint32)(dmaAddress >> 32)); 522 523 dmaAddress += sizeof(xhci_erst_element) + XHCI_MAX_EVENTS 524 * sizeof(xhci_trb); 525 526 // Make sure the Command Ring is stopped 527 if ((ReadOpReg(XHCI_CRCR_LO) & CRCR_CRR) != 0) { 528 TRACE_ALWAYS("Command Ring is running, send stop/cancel\n"); 529 WriteOpReg(XHCI_CRCR_LO, CRCR_CS); 530 WriteOpReg(XHCI_CRCR_HI, 0); 531 WriteOpReg(XHCI_CRCR_LO, CRCR_CA); 532 WriteOpReg(XHCI_CRCR_HI, 0); 533 snooze(1000); 534 if ((ReadOpReg(XHCI_CRCR_LO) & CRCR_CRR) != 0) { 535 TRACE_ERROR("Command Ring still running after stop/cancel\n"); 536 } 537 } 538 TRACE("setting CRCR addr = 0x%" B_PRIxPHYSADDR "\n", dmaAddress); 539 WriteOpReg(XHCI_CRCR_LO, (uint32)dmaAddress | CRCR_RCS); 540 WriteOpReg(XHCI_CRCR_HI, (uint32)(dmaAddress >> 32)); 541 // link trb 542 fCmdRing[XHCI_MAX_COMMANDS - 1].qwtrb0 = dmaAddress; 543 544 TRACE("setting interrupt rate\n"); 545 546 // Setting IMOD below 0x3F8 on Intel Lynx Point can cause IRQ lockups 547 if (fPCIInfo->vendor_id == PCI_VENDOR_INTEL 548 && (fPCIInfo->device_id == PCI_DEVICE_INTEL_PANTHER_POINT_XHCI 549 || fPCIInfo->device_id == PCI_DEVICE_INTEL_LYNX_POINT_XHCI 550 || fPCIInfo->device_id == PCI_DEVICE_INTEL_LYNX_POINT_LP_XHCI 551 || fPCIInfo->device_id == PCI_DEVICE_INTEL_BAYTRAIL_XHCI 552 || fPCIInfo->device_id == PCI_DEVICE_INTEL_WILDCAT_POINT_XHCI)) { 553 WriteRunReg32(XHCI_IMOD(0), 0x000003f8); // 4000 irq/s 554 } else { 555 WriteRunReg32(XHCI_IMOD(0), 0x000001f4); // 8000 irq/s 556 } 557 558 TRACE("enabling interrupt\n"); 559 WriteRunReg32(XHCI_IMAN(0), ReadRunReg32(XHCI_IMAN(0)) | IMAN_INTR_ENA); 560 561 WriteOpReg(XHCI_CMD, CMD_RUN | CMD_INTE | CMD_HSEE); 562 563 // wait for start up state 564 if (WaitOpBits(XHCI_STS, STS_HCH, 0) != B_OK) { 565 TRACE_ERROR("HCH start up timeout\n"); 566 } 567 568 fRootHubAddress = AllocateAddress(); 569 fRootHub = new(std::nothrow) XHCIRootHub(RootObject(), fRootHubAddress); 570 if (!fRootHub) { 571 TRACE_ERROR("no memory to allocate root hub\n"); 572 return B_NO_MEMORY; 573 } 574 575 if (fRootHub->InitCheck() < B_OK) { 576 TRACE_ERROR("root hub failed init check\n"); 577 return fRootHub->InitCheck(); 578 } 579 580 SetRootHub(fRootHub); 581 582 TRACE_ALWAYS("successfully started the controller\n"); 583 #ifdef TRACE_USB 584 TRACE("No-Op test...\n"); 585 status_t noopResult = Noop(); 586 TRACE("No-Op %ssuccessful\n", noopResult < B_OK ? "un" : ""); 587 #endif 588 589 //DumpRing(fCmdRing, (XHCI_MAX_COMMANDS - 1)); 590 591 return BusManager::Start(); 592 } 593 594 595 status_t 596 XHCI::SubmitTransfer(Transfer *transfer) 597 { 598 // short circuit the root hub 599 if (transfer->TransferPipe()->DeviceAddress() == fRootHubAddress) 600 return fRootHub->ProcessTransfer(this, transfer); 601 602 TRACE("SubmitTransfer()\n"); 603 Pipe *pipe = transfer->TransferPipe(); 604 if ((pipe->Type() & USB_OBJECT_ISO_PIPE) != 0) 605 return B_UNSUPPORTED; 606 if ((pipe->Type() & USB_OBJECT_CONTROL_PIPE) != 0) 607 return SubmitControlRequest(transfer); 608 return SubmitNormalRequest(transfer); 609 } 610 611 612 status_t 613 XHCI::SubmitControlRequest(Transfer *transfer) 614 { 615 Pipe *pipe = transfer->TransferPipe(); 616 usb_request_data *requestData = transfer->RequestData(); 617 bool directionIn = (requestData->RequestType & USB_REQTYPE_DEVICE_IN) != 0; 618 619 TRACE("SubmitControlRequest() length %d\n", requestData->Length); 620 621 xhci_td *setupDescriptor = CreateDescriptor(requestData->Length); 622 623 // set SetupStage 624 uint8 index = 0; 625 setupDescriptor->trbs[index].qwtrb0 = 0; 626 setupDescriptor->trbs[index].dwtrb2 = TRB_2_IRQ(0) | TRB_2_BYTES(8); 627 setupDescriptor->trbs[index].dwtrb3 628 = B_HOST_TO_LENDIAN_INT32(TRB_3_TYPE(TRB_TYPE_SETUP_STAGE) 629 | TRB_3_IDT_BIT | TRB_3_CYCLE_BIT); 630 if (requestData->Length > 0) { 631 setupDescriptor->trbs[index].dwtrb3 |= B_HOST_TO_LENDIAN_INT32( 632 directionIn ? TRB_3_TRT_IN : TRB_3_TRT_OUT); 633 } 634 memcpy(&setupDescriptor->trbs[index].qwtrb0, requestData, 635 sizeof(usb_request_data)); 636 637 index++; 638 639 if (requestData->Length > 0) { 640 // set DataStage if any 641 setupDescriptor->trbs[index].qwtrb0 = setupDescriptor->buffer_phy[0]; 642 setupDescriptor->trbs[index].dwtrb2 = TRB_2_IRQ(0) 643 | TRB_2_BYTES(requestData->Length) 644 | TRB_2_TD_SIZE(transfer->VectorCount()); 645 setupDescriptor->trbs[index].dwtrb3 = B_HOST_TO_LENDIAN_INT32( 646 TRB_3_TYPE(TRB_TYPE_DATA_STAGE) 647 | (directionIn ? (TRB_3_DIR_IN | TRB_3_ISP_BIT) : 0) 648 | TRB_3_CYCLE_BIT); 649 650 // TODO copy data for out transfers 651 index++; 652 } 653 654 // set StatusStage 655 setupDescriptor->trbs[index].dwtrb2 = TRB_2_IRQ(0); 656 setupDescriptor->trbs[index].dwtrb3 = B_HOST_TO_LENDIAN_INT32( 657 TRB_3_TYPE(TRB_TYPE_STATUS_STAGE) 658 | ((directionIn && requestData->Length > 0) ? 0 : TRB_3_DIR_IN) 659 | TRB_3_IOC_BIT | TRB_3_CYCLE_BIT); 660 661 setupDescriptor->trb_count = index + 1; 662 663 xhci_endpoint *endpoint = (xhci_endpoint *)pipe->ControllerCookie(); 664 uint8 id = XHCI_ENDPOINT_ID(pipe); 665 if (id >= XHCI_MAX_ENDPOINTS) { 666 TRACE_ERROR("Invalid Endpoint"); 667 return B_BAD_VALUE; 668 } 669 setupDescriptor->transfer = transfer; 670 transfer->InitKernelAccess(); 671 _LinkDescriptorForPipe(setupDescriptor, endpoint); 672 673 TRACE("SubmitControlRequest() request linked\n"); 674 675 TRACE("Endpoint status 0x%08" B_PRIx32 " 0x%08" B_PRIx32 " 0x%016" B_PRIx64 "\n", 676 _ReadContext(&endpoint->device->device_ctx->endpoints[id - 1].dwendpoint0), 677 _ReadContext(&endpoint->device->device_ctx->endpoints[id - 1].dwendpoint1), 678 _ReadContext(&endpoint->device->device_ctx->endpoints[id - 1].qwendpoint2)); 679 Ring(endpoint->device->slot, id); 680 TRACE("Endpoint status 0x%08" B_PRIx32 " 0x%08" B_PRIx32 " 0x%016" B_PRIx64 "\n", 681 _ReadContext(&endpoint->device->device_ctx->endpoints[id - 1].dwendpoint0), 682 _ReadContext(&endpoint->device->device_ctx->endpoints[id - 1].dwendpoint1), 683 _ReadContext(&endpoint->device->device_ctx->endpoints[id - 1].qwendpoint2)); 684 return B_OK; 685 } 686 687 688 status_t 689 XHCI::SubmitNormalRequest(Transfer *transfer) 690 { 691 TRACE("SubmitNormalRequest() length %ld\n", transfer->DataLength()); 692 Pipe *pipe = transfer->TransferPipe(); 693 uint8 id = XHCI_ENDPOINT_ID(pipe); 694 if (id >= XHCI_MAX_ENDPOINTS) 695 return B_BAD_VALUE; 696 bool directionIn = (pipe->Direction() == Pipe::In); 697 698 int32 trbCount = 0; 699 xhci_td *descriptor = CreateDescriptorChain(transfer->DataLength(), trbCount); 700 if (descriptor == NULL) 701 return B_NO_MEMORY; 702 703 xhci_td *td_chain = descriptor; 704 xhci_td *last = descriptor; 705 int32 rest = trbCount - 1; 706 707 // set NormalStage 708 while (td_chain != NULL) { 709 td_chain->trb_count = td_chain->buffer_count; 710 uint8 index; 711 for (index = 0; index < td_chain->buffer_count; index++) { 712 td_chain->trbs[index].qwtrb0 = descriptor->buffer_phy[index]; 713 td_chain->trbs[index].dwtrb2 = TRB_2_IRQ(0) 714 | TRB_2_BYTES(descriptor->buffer_size[index]) 715 | TRB_2_TD_SIZE(rest); 716 td_chain->trbs[index].dwtrb3 = B_HOST_TO_LENDIAN_INT32( 717 TRB_3_TYPE(TRB_TYPE_NORMAL) | TRB_3_CYCLE_BIT | TRB_3_CHAIN_BIT 718 | (directionIn ? TRB_3_ISP_BIT : 0)); 719 rest--; 720 } 721 // link next td, if any 722 if (td_chain->next_chain != NULL) { 723 td_chain->trbs[td_chain->trb_count].qwtrb0 = td_chain->next_chain->this_phy; 724 td_chain->trbs[td_chain->trb_count].dwtrb2 = TRB_2_IRQ(0); 725 td_chain->trbs[td_chain->trb_count].dwtrb3 726 = B_HOST_TO_LENDIAN_INT32(TRB_3_TYPE(TRB_TYPE_LINK) 727 | TRB_3_CYCLE_BIT | TRB_3_CHAIN_BIT); 728 } 729 730 last = td_chain; 731 td_chain = td_chain->next_chain; 732 } 733 734 if (last->trb_count > 0) { 735 last->trbs[last->trb_count - 1].dwtrb3 736 |= B_HOST_TO_LENDIAN_INT32(TRB_3_IOC_BIT); 737 last->trbs[last->trb_count - 1].dwtrb3 738 &= B_HOST_TO_LENDIAN_INT32(~TRB_3_CHAIN_BIT); 739 } 740 741 if (!directionIn) { 742 TRACE("copying out iov count %ld\n", transfer->VectorCount()); 743 WriteDescriptorChain(descriptor, transfer->Vector(), 744 transfer->VectorCount()); 745 } 746 /* memcpy(descriptor->buffer_log[index], 747 (uint8 *)transfer->Vector()[index].iov_base, transfer->VectorLength()); 748 }*/ 749 750 xhci_endpoint *endpoint = (xhci_endpoint *)pipe->ControllerCookie(); 751 descriptor->transfer = transfer; 752 transfer->InitKernelAccess(); 753 _LinkDescriptorForPipe(descriptor, endpoint); 754 755 TRACE("SubmitNormalRequest() request linked\n"); 756 757 TRACE("Endpoint status 0x%08" B_PRIx32 " 0x%08" B_PRIx32 " 0x%016" B_PRIx64 "\n", 758 _ReadContext(&endpoint->device->device_ctx->endpoints[id - 1].dwendpoint0), 759 _ReadContext(&endpoint->device->device_ctx->endpoints[id - 1].dwendpoint1), 760 _ReadContext(&endpoint->device->device_ctx->endpoints[id - 1].qwendpoint2)); 761 Ring(endpoint->device->slot, id); 762 TRACE("Endpoint status 0x%08" B_PRIx32 " 0x%08" B_PRIx32 " 0x%016" B_PRIx64 "\n", 763 _ReadContext(&endpoint->device->device_ctx->endpoints[id - 1].dwendpoint0), 764 _ReadContext(&endpoint->device->device_ctx->endpoints[id - 1].dwendpoint1), 765 _ReadContext(&endpoint->device->device_ctx->endpoints[id - 1].qwendpoint2)); 766 return B_OK; 767 } 768 769 770 status_t 771 XHCI::CancelQueuedTransfers(Pipe *pipe, bool force) 772 { 773 TRACE_ALWAYS("cancel queued transfers for pipe %p (%d)\n", pipe, 774 pipe->EndpointAddress()); 775 return B_OK; 776 } 777 778 779 status_t 780 XHCI::NotifyPipeChange(Pipe *pipe, usb_change change) 781 { 782 TRACE("pipe change %d for pipe %p (%d)\n", change, pipe, 783 pipe->EndpointAddress()); 784 switch (change) { 785 case USB_CHANGE_CREATED: 786 _InsertEndpointForPipe(pipe); 787 break; 788 case USB_CHANGE_DESTROYED: 789 _RemoveEndpointForPipe(pipe); 790 break; 791 792 case USB_CHANGE_PIPE_POLICY_CHANGED: { 793 // ToDo: for isochronous pipes we might need to adapt to new 794 // pipe policy settings here 795 break; 796 } 797 } 798 799 return B_OK; 800 } 801 802 803 status_t 804 XHCI::AddTo(Stack *stack) 805 { 806 #ifdef TRACE_USB 807 set_dprintf_enabled(true); 808 #endif 809 810 if (!sPCIModule) { 811 status_t status = get_module(B_PCI_MODULE_NAME, 812 (module_info **)&sPCIModule); 813 if (status < B_OK) { 814 TRACE_MODULE_ERROR("getting pci module failed! 0x%08" B_PRIx32 815 "\n", status); 816 return status; 817 } 818 } 819 820 TRACE_MODULE("searching devices\n"); 821 bool found = false; 822 pci_info *item = new(std::nothrow) pci_info; 823 if (!item) { 824 sPCIModule = NULL; 825 put_module(B_PCI_MODULE_NAME); 826 return B_NO_MEMORY; 827 } 828 829 // Try to get the PCI x86 module as well so we can enable possible MSIs. 830 if (sPCIx86Module == NULL && get_module(B_PCI_X86_MODULE_NAME, 831 (module_info **)&sPCIx86Module) != B_OK) { 832 // If it isn't there, that's not critical though. 833 TRACE_MODULE_ERROR("failed to get pci x86 module\n"); 834 sPCIx86Module = NULL; 835 } 836 837 for (int32 i = 0; sPCIModule->get_nth_pci_info(i, item) >= B_OK; i++) { 838 if (item->class_base == PCI_serial_bus && item->class_sub == PCI_usb 839 && item->class_api == PCI_usb_xhci) { 840 TRACE_MODULE("found device at PCI:%d:%d:%d\n", 841 item->bus, item->device, item->funcion); 842 XHCI *bus = new(std::nothrow) XHCI(item, stack); 843 if (!bus) { 844 delete item; 845 sPCIModule = NULL; 846 put_module(B_PCI_MODULE_NAME); 847 return B_NO_MEMORY; 848 } 849 850 if (bus->InitCheck() < B_OK) { 851 TRACE_MODULE_ERROR("bus failed init check\n"); 852 delete bus; 853 continue; 854 } 855 856 // the bus took it away 857 item = new(std::nothrow) pci_info; 858 859 bus->Start(); 860 stack->AddBusManager(bus); 861 found = true; 862 } 863 } 864 865 if (!found) { 866 TRACE_MODULE_ERROR("no devices found\n"); 867 delete item; 868 sPCIModule = NULL; 869 put_module(B_PCI_MODULE_NAME); 870 return ENODEV; 871 } 872 873 delete item; 874 return B_OK; 875 } 876 877 878 xhci_td * 879 XHCI::CreateDescriptorChain(size_t bufferSize, int32 &trbCount) 880 { 881 size_t packetSize = B_PAGE_SIZE * 16; 882 trbCount = (bufferSize + packetSize - 1) / packetSize; 883 // keep one trb for linking 884 int32 tdCount = (trbCount + XHCI_MAX_TRBS_PER_TD - 2) 885 / (XHCI_MAX_TRBS_PER_TD - 1); 886 887 xhci_td *first = NULL; 888 xhci_td *last = NULL; 889 for (int32 i = 0; i < tdCount; i++) { 890 xhci_td *descriptor = CreateDescriptor(0); 891 if (!descriptor) { 892 if (first != NULL) 893 FreeDescriptor(first); 894 return NULL; 895 } else if (first == NULL) 896 first = descriptor; 897 898 uint8 trbs = min_c(trbCount, XHCI_MAX_TRBS_PER_TD - 1); 899 TRACE("CreateDescriptorChain trbs %d for td %" B_PRId32 "\n", trbs, i); 900 for (int j = 0; j < trbs; j++) { 901 if (fStack->AllocateChunk(&descriptor->buffer_log[j], 902 &descriptor->buffer_phy[j], 903 min_c(packetSize, bufferSize)) < B_OK) { 904 TRACE_ERROR("unable to allocate space for the buffer (size %" 905 B_PRIuSIZE ")\n", bufferSize); 906 return NULL; 907 } 908 909 descriptor->buffer_size[j] = min_c(packetSize, bufferSize); 910 bufferSize -= descriptor->buffer_size[j]; 911 TRACE("CreateDescriptorChain allocated %ld for trb %d\n", 912 descriptor->buffer_size[j], j); 913 } 914 915 descriptor->buffer_count = trbs; 916 trbCount -= trbs; 917 if (last != NULL) 918 last->next_chain = descriptor; 919 last = descriptor; 920 } 921 922 return first; 923 } 924 925 926 xhci_td * 927 XHCI::CreateDescriptor(size_t bufferSize) 928 { 929 xhci_td *result; 930 phys_addr_t physicalAddress; 931 932 if (fStack->AllocateChunk((void **)&result, &physicalAddress, 933 sizeof(xhci_td)) < B_OK) { 934 TRACE_ERROR("failed to allocate a transfer descriptor\n"); 935 return NULL; 936 } 937 938 result->this_phy = physicalAddress; 939 result->buffer_size[0] = bufferSize; 940 result->trb_count = 0; 941 result->buffer_count = 1; 942 result->next = NULL; 943 result->next_chain = NULL; 944 if (bufferSize <= 0) { 945 result->buffer_log[0] = NULL; 946 result->buffer_phy[0] = 0; 947 return result; 948 } 949 950 if (fStack->AllocateChunk(&result->buffer_log[0], 951 &result->buffer_phy[0], bufferSize) < B_OK) { 952 TRACE_ERROR("unable to allocate space for the buffer (size %ld)\n", 953 bufferSize); 954 fStack->FreeChunk(result, result->this_phy, sizeof(xhci_td)); 955 return NULL; 956 } 957 958 TRACE("CreateDescriptor allocated buffer_size %ld %p\n", 959 result->buffer_size[0], result->buffer_log[0]); 960 961 return result; 962 } 963 964 965 void 966 XHCI::FreeDescriptor(xhci_td *descriptor) 967 { 968 while (descriptor != NULL) { 969 970 for (int i = 0; i < descriptor->buffer_count; i++) { 971 if (descriptor->buffer_size[i] == 0) 972 continue; 973 TRACE("FreeDescriptor buffer %d buffer_size %ld %p\n", i, 974 descriptor->buffer_size[i], descriptor->buffer_log[i]); 975 fStack->FreeChunk(descriptor->buffer_log[i], 976 descriptor->buffer_phy[i], descriptor->buffer_size[i]); 977 } 978 979 xhci_td *next = descriptor->next_chain; 980 fStack->FreeChunk(descriptor, descriptor->this_phy, 981 sizeof(xhci_td)); 982 descriptor = next; 983 } 984 } 985 986 987 size_t 988 XHCI::WriteDescriptorChain(xhci_td *descriptor, iovec *vector, 989 size_t vectorCount) 990 { 991 xhci_td *current = descriptor; 992 uint8 trbIndex = 0; 993 size_t actualLength = 0; 994 uint8 vectorIndex = 0; 995 size_t vectorOffset = 0; 996 size_t bufferOffset = 0; 997 998 while (current != NULL) { 999 if (current->buffer_log[0] == NULL) 1000 break; 1001 1002 while (true) { 1003 size_t length = min_c(current->buffer_size[trbIndex] - bufferOffset, 1004 vector[vectorIndex].iov_len - vectorOffset); 1005 1006 TRACE("copying %ld bytes to bufferOffset %ld from" 1007 " vectorOffset %ld at index %d of %ld\n", length, bufferOffset, 1008 vectorOffset, vectorIndex, vectorCount); 1009 memcpy((uint8 *)current->buffer_log[trbIndex] + bufferOffset, 1010 (uint8 *)vector[vectorIndex].iov_base + vectorOffset, length); 1011 1012 actualLength += length; 1013 vectorOffset += length; 1014 bufferOffset += length; 1015 1016 if (vectorOffset >= vector[vectorIndex].iov_len) { 1017 if (++vectorIndex >= vectorCount) { 1018 TRACE("wrote descriptor chain (%ld bytes, no more vectors)\n", 1019 actualLength); 1020 return actualLength; 1021 } 1022 1023 vectorOffset = 0; 1024 } 1025 1026 if (bufferOffset >= current->buffer_size[trbIndex]) { 1027 bufferOffset = 0; 1028 if (++trbIndex >= current->buffer_count) 1029 break; 1030 } 1031 } 1032 1033 current = current->next_chain; 1034 trbIndex = 0; 1035 } 1036 1037 TRACE("wrote descriptor chain (%ld bytes)\n", actualLength); 1038 return actualLength; 1039 } 1040 1041 1042 size_t 1043 XHCI::ReadDescriptorChain(xhci_td *descriptor, iovec *vector, 1044 size_t vectorCount) 1045 { 1046 xhci_td *current = descriptor; 1047 uint8 trbIndex = 0; 1048 size_t actualLength = 0; 1049 uint8 vectorIndex = 0; 1050 size_t vectorOffset = 0; 1051 size_t bufferOffset = 0; 1052 1053 while (current != NULL) { 1054 if (current->buffer_log[0] == NULL) 1055 break; 1056 1057 while (true) { 1058 size_t length = min_c(current->buffer_size[trbIndex] - bufferOffset, 1059 vector[vectorIndex].iov_len - vectorOffset); 1060 1061 TRACE("copying %ld bytes to vectorOffset %ld from" 1062 " bufferOffset %ld at index %d of %ld\n", length, vectorOffset, 1063 bufferOffset, vectorIndex, vectorCount); 1064 memcpy((uint8 *)vector[vectorIndex].iov_base + vectorOffset, 1065 (uint8 *)current->buffer_log[trbIndex] + bufferOffset, length); 1066 1067 actualLength += length; 1068 vectorOffset += length; 1069 bufferOffset += length; 1070 1071 if (vectorOffset >= vector[vectorIndex].iov_len) { 1072 if (++vectorIndex >= vectorCount) { 1073 TRACE("read descriptor chain (%ld bytes, no more vectors)\n", 1074 actualLength); 1075 return actualLength; 1076 } 1077 vectorOffset = 0; 1078 1079 } 1080 1081 if (bufferOffset >= current->buffer_size[trbIndex]) { 1082 bufferOffset = 0; 1083 if (++trbIndex >= current->buffer_count) 1084 break; 1085 } 1086 } 1087 1088 current = current->next_chain; 1089 trbIndex = 0; 1090 } 1091 1092 TRACE("read descriptor chain (%ld bytes)\n", actualLength); 1093 return actualLength; 1094 } 1095 1096 1097 Device * 1098 XHCI::AllocateDevice(Hub *parent, int8 hubAddress, uint8 hubPort, 1099 usb_speed speed) 1100 { 1101 TRACE("AllocateDevice hubAddress %d hubPort %d speed %d\n", hubAddress, 1102 hubPort, speed); 1103 1104 uint8 slot = XHCI_MAX_SLOTS; 1105 if (EnableSlot(&slot) != B_OK) { 1106 TRACE_ERROR("AllocateDevice() failed enable slot\n"); 1107 return NULL; 1108 } 1109 1110 if (slot == 0 || slot > fSlotCount) { 1111 TRACE_ERROR("AllocateDevice() bad slot\n"); 1112 return NULL; 1113 } 1114 1115 if (fDevices[slot].state != XHCI_STATE_DISABLED) { 1116 TRACE_ERROR("AllocateDevice() slot already used\n"); 1117 return NULL; 1118 } 1119 1120 struct xhci_device *device = &fDevices[slot]; 1121 memset(device, 0, sizeof(struct xhci_device)); 1122 device->state = XHCI_STATE_ENABLED; 1123 device->slot = slot; 1124 1125 device->input_ctx_area = fStack->AllocateArea((void **)&device->input_ctx, 1126 &device->input_ctx_addr, sizeof(*device->input_ctx) << fContextSizeShift, 1127 "XHCI input context"); 1128 if (device->input_ctx_area < B_OK) { 1129 TRACE_ERROR("unable to create a input context area\n"); 1130 device->state = XHCI_STATE_DISABLED; 1131 return NULL; 1132 } 1133 1134 memset(device->input_ctx, 0, sizeof(*device->input_ctx) << fContextSizeShift); 1135 _WriteContext(&device->input_ctx->input.dropFlags, 0); 1136 _WriteContext(&device->input_ctx->input.addFlags, 3); 1137 1138 uint32 route = 0; 1139 uint8 routePort = hubPort; 1140 uint8 rhPort = hubPort; 1141 for (Device *hubDevice = parent; hubDevice != RootObject(); 1142 hubDevice = (Device *)hubDevice->Parent()) { 1143 1144 rhPort = routePort; 1145 if (hubDevice->Parent() == RootObject()) 1146 break; 1147 route *= 16; 1148 if (hubPort > 15) 1149 route += 15; 1150 else 1151 route += routePort; 1152 1153 routePort = hubDevice->HubPort(); 1154 } 1155 1156 // Get speed of port, only if device connected to root hub port 1157 // else we have to rely on value reported by the Hub Explore thread 1158 if (route == 0) { 1159 GetPortSpeed(hubPort - 1, &speed); 1160 TRACE("speed updated %d\n", speed); 1161 } 1162 1163 uint32 dwslot0 = SLOT_0_NUM_ENTRIES(1) | SLOT_0_ROUTE(route); 1164 1165 // add the speed 1166 switch (speed) { 1167 case USB_SPEED_LOWSPEED: 1168 dwslot0 |= SLOT_0_SPEED(2); 1169 break; 1170 case USB_SPEED_HIGHSPEED: 1171 dwslot0 |= SLOT_0_SPEED(3); 1172 break; 1173 case USB_SPEED_FULLSPEED: 1174 dwslot0 |= SLOT_0_SPEED(1); 1175 break; 1176 case USB_SPEED_SUPER: 1177 dwslot0 |= SLOT_0_SPEED(4); 1178 break; 1179 default: 1180 TRACE_ERROR("unknown usb speed\n"); 1181 break; 1182 } 1183 1184 _WriteContext(&device->input_ctx->slot.dwslot0, dwslot0); 1185 // TODO enable power save 1186 _WriteContext(&device->input_ctx->slot.dwslot1, SLOT_1_RH_PORT(rhPort)); 1187 uint32 dwslot2 = SLOT_2_IRQ_TARGET(0); 1188 1189 // If LS/FS device connected to non-root HS device 1190 if (route != 0 && parent->Speed() == USB_SPEED_HIGHSPEED 1191 && (speed == USB_SPEED_LOWSPEED || speed == USB_SPEED_FULLSPEED)) { 1192 struct xhci_device *parenthub = (struct xhci_device *) 1193 parent->ControllerCookie(); 1194 dwslot2 |= SLOT_2_PORT_NUM(hubPort); 1195 dwslot2 |= SLOT_2_TT_HUB_SLOT(parenthub->slot); 1196 } 1197 1198 _WriteContext(&device->input_ctx->slot.dwslot2, dwslot2); 1199 1200 _WriteContext(&device->input_ctx->slot.dwslot3, SLOT_3_SLOT_STATE(0) 1201 | SLOT_3_DEVICE_ADDRESS(0)); 1202 1203 TRACE("slot 0x%08" B_PRIx32 " 0x%08" B_PRIx32 " 0x%08" B_PRIx32 " 0x%08" B_PRIx32 1204 "\n", _ReadContext(&device->input_ctx->slot.dwslot0), 1205 _ReadContext(&device->input_ctx->slot.dwslot1), 1206 _ReadContext(&device->input_ctx->slot.dwslot2), 1207 _ReadContext(&device->input_ctx->slot.dwslot3)); 1208 1209 device->device_ctx_area = fStack->AllocateArea((void **)&device->device_ctx, 1210 &device->device_ctx_addr, sizeof(*device->device_ctx) << fContextSizeShift, 1211 "XHCI device context"); 1212 if (device->device_ctx_area < B_OK) { 1213 TRACE_ERROR("unable to create a device context area\n"); 1214 device->state = XHCI_STATE_DISABLED; 1215 delete_area(device->input_ctx_area); 1216 return NULL; 1217 } 1218 memset(device->device_ctx, 0, sizeof(*device->device_ctx) << fContextSizeShift); 1219 1220 device->trb_area = fStack->AllocateArea((void **)&device->trbs, 1221 &device->trb_addr, sizeof(*device->trbs) * (XHCI_MAX_ENDPOINTS - 1) 1222 * XHCI_MAX_TRANSFERS, "XHCI endpoint trbs"); 1223 if (device->trb_area < B_OK) { 1224 TRACE_ERROR("unable to create a device trbs area\n"); 1225 device->state = XHCI_STATE_DISABLED; 1226 delete_area(device->input_ctx_area); 1227 delete_area(device->device_ctx_area); 1228 return NULL; 1229 } 1230 1231 // set up slot pointer to device context 1232 fDcba->baseAddress[slot] = device->device_ctx_addr; 1233 1234 size_t maxPacketSize; 1235 switch (speed) { 1236 case USB_SPEED_LOWSPEED: 1237 case USB_SPEED_FULLSPEED: 1238 maxPacketSize = 8; 1239 break; 1240 case USB_SPEED_HIGHSPEED: 1241 maxPacketSize = 64; 1242 break; 1243 default: 1244 maxPacketSize = 512; 1245 break; 1246 } 1247 1248 // configure the Control endpoint 0 (type 4) 1249 if (ConfigureEndpoint(slot, 0, 4, device->trb_addr, 0, 1250 maxPacketSize, maxPacketSize & 0x7ff, speed) != B_OK) { 1251 TRACE_ERROR("unable to configure default control endpoint\n"); 1252 device->state = XHCI_STATE_DISABLED; 1253 delete_area(device->input_ctx_area); 1254 delete_area(device->device_ctx_area); 1255 delete_area(device->trb_area); 1256 return NULL; 1257 } 1258 1259 device->endpoints[0].device = device; 1260 device->endpoints[0].td_head = NULL; 1261 device->endpoints[0].trbs = device->trbs; 1262 device->endpoints[0].used = 0; 1263 device->endpoints[0].current = 0; 1264 device->endpoints[0].trb_addr = device->trb_addr; 1265 mutex_init(&device->endpoints[0].lock, "xhci endpoint lock"); 1266 1267 // device should get to addressed state (bsr = 0) 1268 if (SetAddress(device->input_ctx_addr, false, slot) != B_OK) { 1269 TRACE_ERROR("unable to set address\n"); 1270 device->state = XHCI_STATE_DISABLED; 1271 delete_area(device->input_ctx_area); 1272 delete_area(device->device_ctx_area); 1273 delete_area(device->trb_area); 1274 return NULL; 1275 } 1276 1277 device->state = XHCI_STATE_ADDRESSED; 1278 device->address = SLOT_3_DEVICE_ADDRESS_GET(_ReadContext( 1279 &device->device_ctx->slot.dwslot3)); 1280 1281 TRACE("device: address 0x%x state 0x%08" B_PRIx32 "\n", device->address, 1282 SLOT_3_SLOT_STATE_GET(_ReadContext( 1283 &device->device_ctx->slot.dwslot3))); 1284 TRACE("endpoint0 state 0x%08" B_PRIx32 "\n", 1285 ENDPOINT_0_STATE_GET(_ReadContext( 1286 &device->device_ctx->endpoints[0].dwendpoint0))); 1287 1288 // Create a temporary pipe with the new address 1289 ControlPipe pipe(parent); 1290 pipe.SetControllerCookie(&device->endpoints[0]); 1291 pipe.InitCommon(device->address + 1, 0, speed, Pipe::Default, maxPacketSize, 0, 1292 hubAddress, hubPort); 1293 1294 // Get the device descriptor 1295 // Just retrieve the first 8 bytes of the descriptor -> minimum supported 1296 // size of any device. It is enough because it includes the device type. 1297 1298 size_t actualLength = 0; 1299 usb_device_descriptor deviceDescriptor; 1300 1301 TRACE("getting the device descriptor\n"); 1302 pipe.SendRequest( 1303 USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD, // type 1304 USB_REQUEST_GET_DESCRIPTOR, // request 1305 USB_DESCRIPTOR_DEVICE << 8, // value 1306 0, // index 1307 8, // length 1308 (void *)&deviceDescriptor, // buffer 1309 8, // buffer length 1310 &actualLength); // actual length 1311 1312 if (actualLength != 8) { 1313 TRACE_ERROR("error while getting the device descriptor\n"); 1314 device->state = XHCI_STATE_DISABLED; 1315 delete_area(device->input_ctx_area); 1316 delete_area(device->device_ctx_area); 1317 delete_area(device->trb_area); 1318 return NULL; 1319 } 1320 1321 TRACE("device_class: %d device_subclass %d device_protocol %d\n", 1322 deviceDescriptor.device_class, deviceDescriptor.device_subclass, 1323 deviceDescriptor.device_protocol); 1324 1325 if (speed == USB_SPEED_FULLSPEED && deviceDescriptor.max_packet_size_0 != 8) { 1326 TRACE("Full speed device with different max packet size for Endpoint 0\n"); 1327 uint32 dwendpoint1 = _ReadContext( 1328 &device->input_ctx->endpoints[0].dwendpoint1); 1329 dwendpoint1 &= ~ENDPOINT_1_MAXPACKETSIZE(0xffff); 1330 dwendpoint1 |= ENDPOINT_1_MAXPACKETSIZE( 1331 deviceDescriptor.max_packet_size_0); 1332 _WriteContext(&device->input_ctx->endpoints[0].dwendpoint1, 1333 dwendpoint1); 1334 _WriteContext(&device->input_ctx->input.dropFlags, 0); 1335 _WriteContext(&device->input_ctx->input.addFlags, (1 << 1)); 1336 EvaluateContext(device->input_ctx_addr, device->slot); 1337 } 1338 1339 Device *deviceObject = NULL; 1340 if (deviceDescriptor.device_class == 0x09) { 1341 TRACE("creating new Hub\n"); 1342 TRACE("getting the hub descriptor\n"); 1343 size_t actualLength = 0; 1344 usb_hub_descriptor hubDescriptor; 1345 pipe.SendRequest( 1346 USB_REQTYPE_DEVICE_IN | USB_REQTYPE_CLASS, // type 1347 USB_REQUEST_GET_DESCRIPTOR, // request 1348 USB_DESCRIPTOR_HUB << 8, // value 1349 0, // index 1350 sizeof(usb_hub_descriptor), // length 1351 (void *)&hubDescriptor, // buffer 1352 sizeof(usb_hub_descriptor), // buffer length 1353 &actualLength); 1354 1355 if (actualLength != sizeof(usb_hub_descriptor)) { 1356 TRACE_ERROR("error while getting the hub descriptor\n"); 1357 device->state = XHCI_STATE_DISABLED; 1358 delete_area(device->input_ctx_area); 1359 delete_area(device->device_ctx_area); 1360 delete_area(device->trb_area); 1361 return NULL; 1362 } 1363 1364 uint32 dwslot0 = _ReadContext(&device->input_ctx->slot.dwslot0); 1365 dwslot0 |= SLOT_0_HUB_BIT; 1366 _WriteContext(&device->input_ctx->slot.dwslot0, dwslot0); 1367 uint32 dwslot1 = _ReadContext(&device->input_ctx->slot.dwslot1); 1368 dwslot1 |= SLOT_1_NUM_PORTS(hubDescriptor.num_ports); 1369 _WriteContext(&device->input_ctx->slot.dwslot1, dwslot1); 1370 if (speed == USB_SPEED_HIGHSPEED) { 1371 uint32 dwslot2 = _ReadContext(&device->input_ctx->slot.dwslot2); 1372 dwslot2 |= SLOT_2_TT_TIME(HUB_TTT_GET(hubDescriptor.characteristics)); 1373 _WriteContext(&device->input_ctx->slot.dwslot2, dwslot2); 1374 } 1375 1376 deviceObject = new(std::nothrow) Hub(parent, hubAddress, hubPort, 1377 deviceDescriptor, device->address + 1, speed, false, device); 1378 } else { 1379 TRACE("creating new device\n"); 1380 deviceObject = new(std::nothrow) Device(parent, hubAddress, hubPort, 1381 deviceDescriptor, device->address + 1, speed, false, device); 1382 } 1383 if (deviceObject == NULL) { 1384 TRACE_ERROR("no memory to allocate device\n"); 1385 device->state = XHCI_STATE_DISABLED; 1386 delete_area(device->input_ctx_area); 1387 delete_area(device->device_ctx_area); 1388 delete_area(device->trb_area); 1389 return NULL; 1390 } 1391 fPortSlots[hubPort] = slot; 1392 TRACE("AllocateDevice() port %d slot %d\n", hubPort, slot); 1393 return deviceObject; 1394 } 1395 1396 1397 void 1398 XHCI::FreeDevice(Device *device) 1399 { 1400 uint8 slot = fPortSlots[device->HubPort()]; 1401 TRACE("FreeDevice() port %d slot %d\n", device->HubPort(), slot); 1402 DisableSlot(slot); 1403 fDcba->baseAddress[slot] = 0; 1404 fPortSlots[device->HubPort()] = 0; 1405 delete_area(fDevices[slot].trb_area); 1406 delete_area(fDevices[slot].input_ctx_area); 1407 delete_area(fDevices[slot].device_ctx_area); 1408 fDevices[slot].state = XHCI_STATE_DISABLED; 1409 delete device; 1410 } 1411 1412 1413 status_t 1414 XHCI::_InsertEndpointForPipe(Pipe *pipe) 1415 { 1416 TRACE("_InsertEndpointForPipe endpoint address %" B_PRId8 "\n", 1417 pipe->EndpointAddress()); 1418 if (pipe->ControllerCookie() != NULL 1419 || pipe->Parent()->Type() != USB_OBJECT_DEVICE) { 1420 // default pipe is already referenced 1421 return B_OK; 1422 } 1423 1424 Device* usbDevice = (Device *)pipe->Parent(); 1425 struct xhci_device *device = (struct xhci_device *) 1426 usbDevice->ControllerCookie(); 1427 if (usbDevice->Parent() == RootObject()) 1428 return B_OK; 1429 if (device == NULL) { 1430 panic("_InsertEndpointForPipe device is NULL\n"); 1431 return B_OK; 1432 } 1433 1434 uint8 id = XHCI_ENDPOINT_ID(pipe) - 1; 1435 if (id >= XHCI_MAX_ENDPOINTS - 1) 1436 return B_BAD_VALUE; 1437 1438 if (id > 0) { 1439 uint32 devicedwslot0 = _ReadContext(&device->device_ctx->slot.dwslot0); 1440 if (SLOT_0_NUM_ENTRIES_GET(devicedwslot0) == 1) { 1441 uint32 inputdwslot0 = _ReadContext(&device->input_ctx->slot.dwslot0); 1442 inputdwslot0 &= ~(SLOT_0_NUM_ENTRIES(0x1f)); 1443 inputdwslot0 |= SLOT_0_NUM_ENTRIES(XHCI_MAX_ENDPOINTS - 1); 1444 _WriteContext(&device->input_ctx->slot.dwslot0, inputdwslot0); 1445 EvaluateContext(device->input_ctx_addr, device->slot); 1446 } 1447 1448 device->endpoints[id].device = device; 1449 device->endpoints[id].trbs = device->trbs 1450 + id * XHCI_MAX_TRANSFERS; 1451 device->endpoints[id].td_head = NULL; 1452 device->endpoints[id].used = 0; 1453 device->endpoints[id].trb_addr = device->trb_addr 1454 + id * XHCI_MAX_TRANSFERS * sizeof(xhci_trb); 1455 mutex_init(&device->endpoints[id].lock, "xhci endpoint lock"); 1456 1457 TRACE("_InsertEndpointForPipe trbs device %p endpoint %p\n", 1458 device->trbs, device->endpoints[id].trbs); 1459 TRACE("_InsertEndpointForPipe trb_addr device 0x%" B_PRIxPHYSADDR 1460 " endpoint 0x%" B_PRIxPHYSADDR "\n", device->trb_addr, 1461 device->endpoints[id].trb_addr); 1462 1463 uint8 endpoint = id + 1; 1464 1465 /* TODO: invalid Context State running the 3 following commands 1466 StopEndpoint(false, endpoint, device->slot); 1467 1468 ResetEndpoint(false, endpoint, device->slot); 1469 1470 SetTRDequeue(device->endpoints[id].trb_addr, 0, endpoint, 1471 device->slot); */ 1472 1473 _WriteContext(&device->input_ctx->input.dropFlags, 0); 1474 _WriteContext(&device->input_ctx->input.addFlags, 1475 (1 << endpoint) | (1 << 0)); 1476 1477 // configure the Control endpoint 0 (type 4) 1478 uint32 type = 4; 1479 if ((pipe->Type() & USB_OBJECT_INTERRUPT_PIPE) != 0) 1480 type = 3; 1481 if ((pipe->Type() & USB_OBJECT_BULK_PIPE) != 0) 1482 type = 2; 1483 if ((pipe->Type() & USB_OBJECT_ISO_PIPE) != 0) 1484 type = 1; 1485 type |= (pipe->Direction() == Pipe::In) ? (1 << 2) : 0; 1486 1487 TRACE("trb_addr 0x%" B_PRIxPHYSADDR "\n", device->endpoints[id].trb_addr); 1488 1489 if (ConfigureEndpoint(device->slot, id, type, 1490 device->endpoints[id].trb_addr, pipe->Interval(), 1491 pipe->MaxPacketSize(), pipe->MaxPacketSize() & 0x7ff, 1492 usbDevice->Speed()) != B_OK) { 1493 TRACE_ERROR("unable to configure endpoint\n"); 1494 return B_ERROR; 1495 } 1496 1497 EvaluateContext(device->input_ctx_addr, device->slot); 1498 1499 ConfigureEndpoint(device->input_ctx_addr, false, device->slot); 1500 TRACE("device: address 0x%x state 0x%08" B_PRIx32 "\n", 1501 device->address, SLOT_3_SLOT_STATE_GET(_ReadContext( 1502 &device->device_ctx->slot.dwslot3))); 1503 TRACE("endpoint[0] state 0x%08" B_PRIx32 "\n", 1504 ENDPOINT_0_STATE_GET(_ReadContext( 1505 &device->device_ctx->endpoints[0].dwendpoint0))); 1506 TRACE("endpoint[%d] state 0x%08" B_PRIx32 "\n", id, 1507 ENDPOINT_0_STATE_GET(_ReadContext( 1508 &device->device_ctx->endpoints[id].dwendpoint0))); 1509 device->state = XHCI_STATE_CONFIGURED; 1510 } 1511 pipe->SetControllerCookie(&device->endpoints[id]); 1512 1513 TRACE("_InsertEndpointForPipe for pipe %p at id %d\n", pipe, id); 1514 1515 return B_OK; 1516 } 1517 1518 1519 status_t 1520 XHCI::_RemoveEndpointForPipe(Pipe *pipe) 1521 { 1522 if (pipe->Parent()->Type() != USB_OBJECT_DEVICE) 1523 return B_OK; 1524 //Device* device = (Device *)pipe->Parent(); 1525 1526 return B_OK; 1527 } 1528 1529 1530 status_t 1531 XHCI::_LinkDescriptorForPipe(xhci_td *descriptor, xhci_endpoint *endpoint) 1532 { 1533 TRACE("_LinkDescriptorForPipe\n"); 1534 MutexLocker endpointLocker(endpoint->lock); 1535 if (endpoint->used >= XHCI_MAX_TRANSFERS) { 1536 TRACE_ERROR("_LinkDescriptorForPipe max transfers count exceeded\n"); 1537 return B_BAD_VALUE; 1538 } 1539 1540 endpoint->used++; 1541 if (endpoint->td_head == NULL) 1542 descriptor->next = NULL; 1543 else 1544 descriptor->next = endpoint->td_head; 1545 endpoint->td_head = descriptor; 1546 1547 uint8 current = endpoint->current; 1548 uint8 next = (current + 1) % (XHCI_MAX_TRANSFERS); 1549 1550 TRACE("_LinkDescriptorForPipe current %d, next %d\n", current, next); 1551 1552 xhci_td *last = descriptor; 1553 while (last->next_chain != NULL) 1554 last = last->next_chain; 1555 1556 // compute next link 1557 addr_t addr = endpoint->trb_addr + next * sizeof(struct xhci_trb); 1558 last->trbs[last->trb_count].qwtrb0 = addr; 1559 last->trbs[last->trb_count].dwtrb2 = TRB_2_IRQ(0); 1560 last->trbs[last->trb_count].dwtrb3 = B_HOST_TO_LENDIAN_INT32( 1561 TRB_3_TYPE(TRB_TYPE_LINK) | TRB_3_IOC_BIT | TRB_3_CYCLE_BIT); 1562 1563 endpoint->trbs[next].qwtrb0 = 0; 1564 endpoint->trbs[next].dwtrb2 = 0; 1565 endpoint->trbs[next].dwtrb3 = 0; 1566 1567 // link the descriptor 1568 endpoint->trbs[current].qwtrb0 = descriptor->this_phy; 1569 endpoint->trbs[current].dwtrb2 = TRB_2_IRQ(0); 1570 endpoint->trbs[current].dwtrb3 = B_HOST_TO_LENDIAN_INT32( 1571 TRB_3_TYPE(TRB_TYPE_LINK) | TRB_3_CYCLE_BIT); 1572 1573 TRACE("_LinkDescriptorForPipe pCurrent %p phys 0x%" B_PRIxPHYSADDR 1574 " 0x%" B_PRIxPHYSADDR " 0x%08" B_PRIx32 "\n", &endpoint->trbs[current], 1575 endpoint->trb_addr + current * sizeof(struct xhci_trb), 1576 endpoint->trbs[current].qwtrb0, 1577 B_LENDIAN_TO_HOST_INT32(endpoint->trbs[current].dwtrb3)); 1578 endpoint->current = next; 1579 1580 return B_OK; 1581 } 1582 1583 1584 status_t 1585 XHCI::_UnlinkDescriptorForPipe(xhci_td *descriptor, xhci_endpoint *endpoint) 1586 { 1587 TRACE("_UnlinkDescriptorForPipe\n"); 1588 MutexLocker endpointLocker(endpoint->lock); 1589 endpoint->used--; 1590 if (descriptor == endpoint->td_head) { 1591 endpoint->td_head = descriptor->next; 1592 descriptor->next = NULL; 1593 return B_OK; 1594 } else { 1595 for (xhci_td *td = endpoint->td_head; td->next != NULL; td = td->next) { 1596 if (td->next == descriptor) { 1597 td->next = descriptor->next; 1598 descriptor->next = NULL; 1599 return B_OK; 1600 } 1601 } 1602 } 1603 1604 endpoint->used++; 1605 return B_ERROR; 1606 } 1607 1608 1609 status_t 1610 XHCI::ConfigureEndpoint(uint8 slot, uint8 number, uint8 type, uint64 ringAddr, 1611 uint16 interval, uint16 maxPacketSize, uint16 maxFrameSize, usb_speed speed) 1612 { 1613 struct xhci_device* device = &fDevices[slot]; 1614 1615 uint8 maxBurst = (maxPacketSize & 0x1800) >> 11; 1616 maxPacketSize = (maxPacketSize & 0x7ff); 1617 1618 uint32 dwendpoint0 = 0; 1619 uint32 dwendpoint1 = 0; 1620 uint64 qwendpoint2 = 0; 1621 uint32 dwendpoint4 = 0; 1622 1623 // Assigning Interval 1624 uint16 calcInterval = 0; 1625 if (speed == USB_SPEED_HIGHSPEED && (type == 4 || type == 2)) { 1626 if (interval != 0) { 1627 while ((1<<calcInterval) <= interval) 1628 calcInterval++; 1629 calcInterval--; 1630 } 1631 } 1632 if ((type & 0x3) == 3 && 1633 (speed == USB_SPEED_FULLSPEED || speed == USB_SPEED_LOWSPEED)) { 1634 while ((1<<calcInterval) <= interval * 8) 1635 calcInterval++; 1636 calcInterval--; 1637 } 1638 if ((type & 0x3) == 1 && speed == USB_SPEED_FULLSPEED) { 1639 calcInterval = interval + 2; 1640 } 1641 if (((type & 0x3) == 1 || (type & 0x3) == 3) && 1642 (speed == USB_SPEED_HIGHSPEED || speed == USB_SPEED_SUPER)) { 1643 calcInterval = interval - 1; 1644 } 1645 1646 dwendpoint0 |= ENDPOINT_0_INTERVAL(calcInterval); 1647 1648 // Assigning CERR for non-isoch endpoints 1649 if ((type & 0x3) != 1) { 1650 dwendpoint1 |= ENDPOINT_1_CERR(3); 1651 } 1652 1653 dwendpoint1 |= ENDPOINT_1_EPTYPE(type); 1654 1655 // Assigning MaxBurst for HighSpeed 1656 if (speed == USB_SPEED_HIGHSPEED && 1657 ((type & 0x3) == 1 || (type & 0x3) == 3)) { 1658 dwendpoint1 |= ENDPOINT_1_MAXBURST(maxBurst); 1659 } 1660 1661 // TODO Assign MaxBurst for SuperSpeed 1662 1663 dwendpoint1 |= ENDPOINT_1_MAXPACKETSIZE(maxPacketSize); 1664 qwendpoint2 |= ENDPOINT_2_DCS_BIT | ringAddr; 1665 1666 // Assign MaxESITPayload 1667 // Assign AvgTRBLength 1668 switch (type) { 1669 case 4: 1670 dwendpoint4 = ENDPOINT_4_AVGTRBLENGTH(8); 1671 break; 1672 case 1: 1673 case 3: 1674 case 5: 1675 case 7: 1676 dwendpoint4 = ENDPOINT_4_AVGTRBLENGTH(min_c(maxFrameSize, 1677 B_PAGE_SIZE)) | ENDPOINT_4_MAXESITPAYLOAD(( 1678 (maxBurst+1) * maxPacketSize)); 1679 break; 1680 default: 1681 dwendpoint4 = ENDPOINT_4_AVGTRBLENGTH(B_PAGE_SIZE); 1682 break; 1683 } 1684 1685 _WriteContext(&device->input_ctx->endpoints[number].dwendpoint0, 1686 dwendpoint0); 1687 _WriteContext(&device->input_ctx->endpoints[number].dwendpoint1, 1688 dwendpoint1); 1689 _WriteContext(&device->input_ctx->endpoints[number].qwendpoint2, 1690 qwendpoint2); 1691 _WriteContext(&device->input_ctx->endpoints[number].dwendpoint4, 1692 dwendpoint4); 1693 1694 TRACE("endpoint 0x%" B_PRIx32 " 0x%" B_PRIx32 " 0x%" B_PRIx64 " 0x%" 1695 B_PRIx32 "\n", 1696 _ReadContext(&device->input_ctx->endpoints[number].dwendpoint0), 1697 _ReadContext(&device->input_ctx->endpoints[number].dwendpoint1), 1698 _ReadContext(&device->input_ctx->endpoints[number].qwendpoint2), 1699 _ReadContext(&device->input_ctx->endpoints[number].dwendpoint4)); 1700 1701 return B_OK; 1702 } 1703 1704 1705 status_t 1706 XHCI::GetPortSpeed(uint8 index, usb_speed* speed) 1707 { 1708 uint32 portStatus = ReadOpReg(XHCI_PORTSC(index)); 1709 1710 switch (PS_SPEED_GET(portStatus)) { 1711 case 3: 1712 *speed = USB_SPEED_HIGHSPEED; 1713 break; 1714 case 2: 1715 *speed = USB_SPEED_LOWSPEED; 1716 break; 1717 case 1: 1718 *speed = USB_SPEED_FULLSPEED; 1719 break; 1720 case 4: 1721 *speed = USB_SPEED_SUPER; 1722 break; 1723 default: 1724 TRACE("Non Standard Port Speed\n"); 1725 TRACE("Assuming Superspeed\n"); 1726 *speed = USB_SPEED_SUPER; 1727 break; 1728 } 1729 1730 return B_OK; 1731 } 1732 1733 1734 status_t 1735 XHCI::GetPortStatus(uint8 index, usb_port_status* status) 1736 { 1737 if (index >= fPortCount) 1738 return B_BAD_INDEX; 1739 1740 status->status = status->change = 0; 1741 uint32 portStatus = ReadOpReg(XHCI_PORTSC(index)); 1742 TRACE("port %" B_PRId8 " status=0x%08" B_PRIx32 "\n", index, portStatus); 1743 1744 // build the status 1745 switch (PS_SPEED_GET(portStatus)) { 1746 case 3: 1747 status->status |= PORT_STATUS_HIGH_SPEED; 1748 break; 1749 case 2: 1750 status->status |= PORT_STATUS_LOW_SPEED; 1751 break; 1752 default: 1753 break; 1754 } 1755 1756 if (portStatus & PS_CCS) 1757 status->status |= PORT_STATUS_CONNECTION; 1758 if (portStatus & PS_PED) 1759 status->status |= PORT_STATUS_ENABLE; 1760 if (portStatus & PS_OCA) 1761 status->status |= PORT_STATUS_OVER_CURRENT; 1762 if (portStatus & PS_PR) 1763 status->status |= PORT_STATUS_RESET; 1764 if (portStatus & PS_PP) { 1765 if (fPortSpeeds[index] == USB_SPEED_SUPER) 1766 status->status |= PORT_STATUS_SS_POWER; 1767 else 1768 status->status |= PORT_STATUS_POWER; 1769 } 1770 1771 // build the change 1772 if (portStatus & PS_CSC) 1773 status->change |= PORT_STATUS_CONNECTION; 1774 if (portStatus & PS_PEC) 1775 status->change |= PORT_STATUS_ENABLE; 1776 if (portStatus & PS_OCC) 1777 status->change |= PORT_STATUS_OVER_CURRENT; 1778 if (portStatus & PS_PRC) 1779 status->change |= PORT_STATUS_RESET; 1780 1781 if (fPortSpeeds[index] == USB_SPEED_SUPER) { 1782 if (portStatus & PS_PLC) 1783 status->change |= PORT_CHANGE_LINK_STATE; 1784 if (portStatus & PS_WRC) 1785 status->change |= PORT_CHANGE_BH_PORT_RESET; 1786 } 1787 1788 return B_OK; 1789 } 1790 1791 1792 status_t 1793 XHCI::SetPortFeature(uint8 index, uint16 feature) 1794 { 1795 TRACE("set port feature index %u feature %u\n", index, feature); 1796 if (index >= fPortCount) 1797 return B_BAD_INDEX; 1798 1799 uint32 portRegister = XHCI_PORTSC(index); 1800 uint32 portStatus = ReadOpReg(portRegister) & ~PS_CLEAR; 1801 1802 switch (feature) { 1803 case PORT_SUSPEND: 1804 if ((portStatus & PS_PED) == 0 || (portStatus & PS_PR) 1805 || (portStatus & PS_PLS_MASK) >= PS_XDEV_U3) { 1806 TRACE_ERROR("USB core suspending device not in U0/U1/U2.\n"); 1807 return B_BAD_VALUE; 1808 } 1809 portStatus &= ~PS_PLS_MASK; 1810 WriteOpReg(portRegister, portStatus | PS_LWS | PS_XDEV_U3); 1811 break; 1812 1813 case PORT_RESET: 1814 WriteOpReg(portRegister, portStatus | PS_PR); 1815 break; 1816 1817 case PORT_POWER: 1818 WriteOpReg(portRegister, portStatus | PS_PP); 1819 break; 1820 default: 1821 return B_BAD_VALUE; 1822 } 1823 ReadOpReg(portRegister); 1824 return B_OK; 1825 } 1826 1827 1828 status_t 1829 XHCI::ClearPortFeature(uint8 index, uint16 feature) 1830 { 1831 TRACE("clear port feature index %u feature %u\n", index, feature); 1832 if (index >= fPortCount) 1833 return B_BAD_INDEX; 1834 1835 uint32 portRegister = XHCI_PORTSC(index); 1836 uint32 portStatus = ReadOpReg(portRegister) & ~PS_CLEAR; 1837 1838 switch (feature) { 1839 case PORT_SUSPEND: 1840 portStatus = ReadOpReg(portRegister); 1841 if (portStatus & PS_PR) 1842 return B_BAD_VALUE; 1843 if (portStatus & PS_XDEV_U3) { 1844 if ((portStatus & PS_PED) == 0) 1845 return B_BAD_VALUE; 1846 portStatus &= ~PS_PLS_MASK; 1847 WriteOpReg(portRegister, portStatus | PS_XDEV_U0 | PS_LWS); 1848 } 1849 break; 1850 case PORT_ENABLE: 1851 WriteOpReg(portRegister, portStatus | PS_PED); 1852 break; 1853 case PORT_POWER: 1854 WriteOpReg(portRegister, portStatus & ~PS_PP); 1855 break; 1856 case C_PORT_CONNECTION: 1857 WriteOpReg(portRegister, portStatus | PS_CSC); 1858 break; 1859 case C_PORT_ENABLE: 1860 WriteOpReg(portRegister, portStatus | PS_PEC); 1861 break; 1862 case C_PORT_OVER_CURRENT: 1863 WriteOpReg(portRegister, portStatus | PS_OCC); 1864 break; 1865 case C_PORT_RESET: 1866 WriteOpReg(portRegister, portStatus | PS_PRC); 1867 break; 1868 case C_PORT_BH_PORT_RESET: 1869 WriteOpReg(portRegister, portStatus | PS_WRC); 1870 break; 1871 case C_PORT_LINK_STATE: 1872 WriteOpReg(portRegister, portStatus | PS_PLC); 1873 break; 1874 default: 1875 return B_BAD_VALUE; 1876 } 1877 1878 ReadOpReg(portRegister); 1879 return B_OK; 1880 } 1881 1882 1883 status_t 1884 XHCI::ControllerHalt() 1885 { 1886 // Mask off run state 1887 WriteOpReg(XHCI_CMD, ReadOpReg(XHCI_CMD) & ~CMD_RUN); 1888 1889 // wait for shutdown state 1890 if (WaitOpBits(XHCI_STS, STS_HCH, STS_HCH) != B_OK) { 1891 TRACE_ERROR("HCH shutdown timeout\n"); 1892 return B_ERROR; 1893 } 1894 return B_OK; 1895 } 1896 1897 1898 status_t 1899 XHCI::ControllerReset() 1900 { 1901 TRACE("ControllerReset() cmd: 0x%" B_PRIx32 " sts: 0x%" B_PRIx32 "\n", 1902 ReadOpReg(XHCI_CMD), ReadOpReg(XHCI_STS)); 1903 WriteOpReg(XHCI_CMD, ReadOpReg(XHCI_CMD) | CMD_HCRST); 1904 1905 if (WaitOpBits(XHCI_CMD, CMD_HCRST, 0) != B_OK) { 1906 TRACE_ERROR("ControllerReset() failed CMD_HCRST\n"); 1907 return B_ERROR; 1908 } 1909 1910 if (WaitOpBits(XHCI_STS, STS_CNR, 0) != B_OK) { 1911 TRACE_ERROR("ControllerReset() failed STS_CNR\n"); 1912 return B_ERROR; 1913 } 1914 1915 return B_OK; 1916 } 1917 1918 1919 int32 1920 XHCI::InterruptHandler(void* data) 1921 { 1922 return ((XHCI*)data)->Interrupt(); 1923 } 1924 1925 1926 int32 1927 XHCI::Interrupt() 1928 { 1929 SpinLocker _(&fSpinlock); 1930 1931 uint32 status = ReadOpReg(XHCI_STS); 1932 uint32 temp = ReadRunReg32(XHCI_IMAN(0)); 1933 WriteOpReg(XHCI_STS, status); 1934 WriteRunReg32(XHCI_IMAN(0), temp); 1935 1936 int32 result = B_HANDLED_INTERRUPT; 1937 1938 if ((status & STS_HCH) != 0) { 1939 TRACE_ERROR("Host Controller halted\n"); 1940 return result; 1941 } 1942 if ((status & STS_HSE) != 0) { 1943 TRACE_ERROR("Host System Error\n"); 1944 return result; 1945 } 1946 if ((status & STS_HCE) != 0) { 1947 TRACE_ERROR("Host Controller Error\n"); 1948 return result; 1949 } 1950 1951 if ((status & STS_EINT) == 0) { 1952 TRACE("STS: 0x%" B_PRIx32 " IRQ_PENDING: 0x%" B_PRIx32 "\n", 1953 status, temp); 1954 return B_UNHANDLED_INTERRUPT; 1955 } 1956 1957 TRACE("Event Interrupt\n"); 1958 release_sem_etc(fEventSem, 1, B_DO_NOT_RESCHEDULE); 1959 return B_INVOKE_SCHEDULER; 1960 } 1961 1962 1963 void 1964 XHCI::Ring(uint8 slot, uint8 endpoint) 1965 { 1966 TRACE("Ding Dong! slot:%d endpoint %d\n", slot, endpoint) 1967 if ((slot == 0 && endpoint > 0) || (slot > 0 && endpoint == 0)) 1968 panic("Ring() invalid slot/endpoint combination\n"); 1969 if (slot > fSlotCount || endpoint >= XHCI_MAX_ENDPOINTS) 1970 panic("Ring() invalid slot or endpoint\n"); 1971 WriteDoorReg32(XHCI_DOORBELL(slot), XHCI_DOORBELL_TARGET(endpoint) 1972 | XHCI_DOORBELL_STREAMID(0)); 1973 /* Flush PCI posted writes */ 1974 ReadDoorReg32(XHCI_DOORBELL(slot)); 1975 } 1976 1977 1978 void 1979 XHCI::QueueCommand(xhci_trb* trb) 1980 { 1981 uint8 i, j; 1982 uint32 temp; 1983 1984 i = fCmdIdx; 1985 j = fCmdCcs; 1986 1987 TRACE("command[%u] = %" B_PRId32 " (0x%016" B_PRIx64 ", 0x%08" B_PRIx32 1988 ", 0x%08" B_PRIx32 ")\n", i, TRB_3_TYPE_GET(trb->dwtrb3), trb->qwtrb0, 1989 trb->dwtrb2, trb->dwtrb3); 1990 1991 fCmdRing[i].qwtrb0 = trb->qwtrb0; 1992 fCmdRing[i].dwtrb2 = trb->dwtrb2; 1993 temp = trb->dwtrb3; 1994 1995 if (j) 1996 temp |= TRB_3_CYCLE_BIT; 1997 else 1998 temp &= ~TRB_3_CYCLE_BIT; 1999 temp &= ~TRB_3_TC_BIT; 2000 fCmdRing[i].dwtrb3 = B_HOST_TO_LENDIAN_INT32(temp); 2001 2002 fCmdAddr = fErst->rs_addr + (XHCI_MAX_EVENTS + i) * sizeof(xhci_trb); 2003 2004 i++; 2005 2006 if (i == (XHCI_MAX_COMMANDS - 1)) { 2007 temp = TRB_3_TYPE(TRB_TYPE_LINK) | TRB_3_TC_BIT; 2008 if (j) 2009 temp |= TRB_3_CYCLE_BIT; 2010 fCmdRing[i].dwtrb3 = B_HOST_TO_LENDIAN_INT32(temp); 2011 2012 i = 0; 2013 j ^= 1; 2014 } 2015 2016 fCmdIdx = i; 2017 fCmdCcs = j; 2018 } 2019 2020 2021 void 2022 XHCI::HandleCmdComplete(xhci_trb* trb) 2023 { 2024 if (fCmdAddr == trb->qwtrb0) { 2025 TRACE("Received command event\n"); 2026 fCmdResult[0] = trb->dwtrb2; 2027 fCmdResult[1] = B_LENDIAN_TO_HOST_INT32(trb->dwtrb3); 2028 release_sem_etc(fCmdCompSem, 1, B_DO_NOT_RESCHEDULE); 2029 } 2030 2031 } 2032 2033 2034 void 2035 XHCI::HandleTransferComplete(xhci_trb* trb) 2036 { 2037 TRACE("HandleTransferComplete trb %p\n", trb); 2038 addr_t source = trb->qwtrb0; 2039 uint8 completionCode = TRB_2_COMP_CODE_GET(trb->dwtrb2); 2040 uint32 remainder = TRB_2_REM_GET(trb->dwtrb2); 2041 uint8 endpointNumber 2042 = TRB_3_ENDPOINT_GET(B_LENDIAN_TO_HOST_INT32(trb->dwtrb3)); 2043 uint8 slot = TRB_3_SLOT_GET(B_LENDIAN_TO_HOST_INT32(trb->dwtrb3)); 2044 2045 if (slot > fSlotCount) 2046 TRACE_ERROR("invalid slot\n"); 2047 if (endpointNumber == 0 || endpointNumber >= XHCI_MAX_ENDPOINTS) 2048 TRACE_ERROR("invalid endpoint\n"); 2049 2050 xhci_device *device = &fDevices[slot]; 2051 xhci_endpoint *endpoint = &device->endpoints[endpointNumber - 1]; 2052 xhci_td *td = endpoint->td_head; 2053 for (; td != NULL; td = td->next) { 2054 xhci_td *td_chain = td; 2055 for (; td_chain != NULL; td_chain = td_chain->next_chain) { 2056 int64 offset = source - td_chain->this_phy; 2057 TRACE("HandleTransferComplete td %p offset %" B_PRId64 " %" 2058 B_PRIxADDR "\n", td_chain, offset, source); 2059 offset = offset / sizeof(xhci_trb) + 1; 2060 if (offset <= td_chain->trb_count && offset >= 1) { 2061 TRACE("HandleTransferComplete td %p trb %" B_PRId64 " found " 2062 "\n", td_chain, offset); 2063 // is it the last trb? 2064 if (offset == td_chain->trb_count) { 2065 _UnlinkDescriptorForPipe(td, endpoint); 2066 td->trb_completion_code = completionCode; 2067 td->trb_left = remainder; 2068 // add descriptor to finished list 2069 Lock(); 2070 td->next = fFinishedHead; 2071 fFinishedHead = td; 2072 Unlock(); 2073 release_sem(fFinishTransfersSem); 2074 TRACE("HandleTransferComplete td %p\n", td); 2075 } 2076 return; 2077 } 2078 } 2079 } 2080 2081 } 2082 2083 2084 void 2085 XHCI::DumpRing(xhci_trb *trbs, uint32 size) 2086 { 2087 if (!Lock()) { 2088 TRACE("Unable to get lock!\n"); 2089 return; 2090 } 2091 2092 for (uint32 i = 0; i < size; i++) { 2093 TRACE("command[%" B_PRId32 "] = %" B_PRId32 " (0x%016" B_PRIx64 "," 2094 " 0x%08" B_PRIx32 ", 0x%08" B_PRIx32 ")\n", i, 2095 TRB_3_TYPE_GET(B_LENDIAN_TO_HOST_INT32(trbs[i].dwtrb3)), 2096 trbs[i].qwtrb0, trbs[i].dwtrb2, trbs[i].dwtrb3); 2097 } 2098 2099 Unlock(); 2100 } 2101 2102 2103 status_t 2104 XHCI::DoCommand(xhci_trb* trb) 2105 { 2106 if (!Lock()) { 2107 TRACE("Unable to get lock!\n"); 2108 return B_ERROR; 2109 } 2110 2111 QueueCommand(trb); 2112 Ring(0, 0); 2113 2114 if (acquire_sem(fCmdCompSem) < B_OK) { 2115 TRACE("Unable to obtain fCmdCompSem semaphore!\n"); 2116 Unlock(); 2117 return B_ERROR; 2118 } 2119 // eat up sems that have been released by multiple interrupts 2120 int32 semCount = 0; 2121 get_sem_count(fCmdCompSem, &semCount); 2122 if (semCount > 0) 2123 acquire_sem_etc(fCmdCompSem, semCount, B_RELATIVE_TIMEOUT, 0); 2124 2125 status_t status = B_OK; 2126 uint32 completionCode = TRB_2_COMP_CODE_GET(fCmdResult[0]); 2127 TRACE("Command Complete. Result: %" B_PRId32 "\n", completionCode); 2128 if (completionCode != COMP_SUCCESS) { 2129 uint32 errorCode = TRB_2_COMP_CODE_GET(fCmdResult[0]); 2130 TRACE_ERROR("unsuccessful command, error %s (%" B_PRId32 ")\n", 2131 xhci_error_string(errorCode), errorCode); 2132 status = B_IO_ERROR; 2133 } 2134 2135 trb->dwtrb2 = fCmdResult[0]; 2136 trb->dwtrb3 = fCmdResult[1]; 2137 TRACE("Storing trb 0x%08" B_PRIx32 " 0x%08" B_PRIx32 "\n", trb->dwtrb2, 2138 trb->dwtrb3); 2139 2140 Unlock(); 2141 return status; 2142 } 2143 2144 2145 status_t 2146 XHCI::Noop() 2147 { 2148 TRACE("Issue No-Op\n"); 2149 xhci_trb trb; 2150 trb.qwtrb0 = 0; 2151 trb.dwtrb2 = 0; 2152 trb.dwtrb3 = TRB_3_TYPE(TRB_TYPE_CMD_NOOP); 2153 2154 return DoCommand(&trb); 2155 } 2156 2157 2158 status_t 2159 XHCI::EnableSlot(uint8* slot) 2160 { 2161 TRACE("Enable Slot\n"); 2162 xhci_trb trb; 2163 trb.qwtrb0 = 0; 2164 trb.dwtrb2 = 0; 2165 trb.dwtrb3 = TRB_3_TYPE(TRB_TYPE_ENABLE_SLOT); 2166 2167 status_t status = DoCommand(&trb); 2168 if (status != B_OK) 2169 return status; 2170 2171 *slot = TRB_3_SLOT_GET(trb.dwtrb3); 2172 return *slot != 0 ? B_OK : B_BAD_VALUE; 2173 } 2174 2175 2176 status_t 2177 XHCI::DisableSlot(uint8 slot) 2178 { 2179 TRACE("Disable Slot\n"); 2180 xhci_trb trb; 2181 trb.qwtrb0 = 0; 2182 trb.dwtrb2 = 0; 2183 trb.dwtrb3 = TRB_3_TYPE(TRB_TYPE_DISABLE_SLOT) | TRB_3_SLOT(slot); 2184 2185 return DoCommand(&trb); 2186 } 2187 2188 2189 status_t 2190 XHCI::SetAddress(uint64 inputContext, bool bsr, uint8 slot) 2191 { 2192 TRACE("Set Address\n"); 2193 xhci_trb trb; 2194 trb.qwtrb0 = inputContext; 2195 trb.dwtrb2 = 0; 2196 trb.dwtrb3 = TRB_3_TYPE(TRB_TYPE_ADDRESS_DEVICE) | TRB_3_SLOT(slot); 2197 2198 if (bsr) 2199 trb.dwtrb3 |= TRB_3_BSR_BIT; 2200 2201 return DoCommand(&trb); 2202 } 2203 2204 2205 status_t 2206 XHCI::ConfigureEndpoint(uint64 inputContext, bool deconfigure, uint8 slot) 2207 { 2208 TRACE("Configure Endpoint\n"); 2209 xhci_trb trb; 2210 trb.qwtrb0 = inputContext; 2211 trb.dwtrb2 = 0; 2212 trb.dwtrb3 = TRB_3_TYPE(TRB_TYPE_CONFIGURE_ENDPOINT) | TRB_3_SLOT(slot); 2213 2214 if (deconfigure) 2215 trb.dwtrb3 |= TRB_3_DCEP_BIT; 2216 2217 return DoCommand(&trb); 2218 } 2219 2220 2221 status_t 2222 XHCI::EvaluateContext(uint64 inputContext, uint8 slot) 2223 { 2224 TRACE("Evaluate Context\n"); 2225 xhci_trb trb; 2226 trb.qwtrb0 = inputContext; 2227 trb.dwtrb2 = 0; 2228 trb.dwtrb3 = TRB_3_TYPE(TRB_TYPE_EVALUATE_CONTEXT) | TRB_3_SLOT(slot); 2229 2230 return DoCommand(&trb); 2231 } 2232 2233 2234 status_t 2235 XHCI::ResetEndpoint(bool preserve, uint8 endpoint, uint8 slot) 2236 { 2237 TRACE("Reset Endpoint\n"); 2238 xhci_trb trb; 2239 trb.qwtrb0 = 0; 2240 trb.dwtrb2 = 0; 2241 trb.dwtrb3 = TRB_3_TYPE(TRB_TYPE_RESET_ENDPOINT) 2242 | TRB_3_SLOT(slot) | TRB_3_ENDPOINT(endpoint); 2243 if (preserve) 2244 trb.dwtrb3 |= TRB_3_PRSV_BIT; 2245 2246 return DoCommand(&trb); 2247 } 2248 2249 2250 status_t 2251 XHCI::StopEndpoint(bool suspend, uint8 endpoint, uint8 slot) 2252 { 2253 TRACE("Stop Endpoint\n"); 2254 xhci_trb trb; 2255 trb.qwtrb0 = 0; 2256 trb.dwtrb2 = 0; 2257 trb.dwtrb3 = TRB_3_TYPE(TRB_TYPE_STOP_ENDPOINT) 2258 | TRB_3_SLOT(slot) | TRB_3_ENDPOINT(endpoint); 2259 if (suspend) 2260 trb.dwtrb3 |= TRB_3_SUSPEND_ENDPOINT_BIT; 2261 2262 return DoCommand(&trb); 2263 } 2264 2265 2266 status_t 2267 XHCI::SetTRDequeue(uint64 dequeue, uint16 stream, uint8 endpoint, uint8 slot) 2268 { 2269 TRACE("Set TR Dequeue\n"); 2270 xhci_trb trb; 2271 trb.qwtrb0 = dequeue; 2272 trb.dwtrb2 = TRB_2_STREAM(stream); 2273 trb.dwtrb3 = TRB_3_TYPE(TRB_TYPE_SET_TR_DEQUEUE) 2274 | TRB_3_SLOT(slot) | TRB_3_ENDPOINT(endpoint); 2275 2276 return DoCommand(&trb); 2277 } 2278 2279 2280 status_t 2281 XHCI::ResetDevice(uint8 slot) 2282 { 2283 TRACE("Reset Device\n"); 2284 xhci_trb trb; 2285 trb.qwtrb0 = 0; 2286 trb.dwtrb2 = 0; 2287 trb.dwtrb3 = TRB_3_TYPE(TRB_TYPE_RESET_DEVICE) | TRB_3_SLOT(slot); 2288 2289 return DoCommand(&trb); 2290 } 2291 2292 2293 int32 2294 XHCI::EventThread(void* data) 2295 { 2296 ((XHCI *)data)->CompleteEvents(); 2297 return B_OK; 2298 } 2299 2300 2301 void 2302 XHCI::CompleteEvents() 2303 { 2304 while (!fStopThreads) { 2305 if (acquire_sem(fEventSem) < B_OK) 2306 continue; 2307 2308 // eat up sems that have been released by multiple interrupts 2309 int32 semCount = 0; 2310 get_sem_count(fEventSem, &semCount); 2311 if (semCount > 0) 2312 acquire_sem_etc(fEventSem, semCount, B_RELATIVE_TIMEOUT, 0); 2313 2314 uint16 i = fEventIdx; 2315 uint8 j = fEventCcs; 2316 uint8 t = 2; 2317 2318 while (1) { 2319 uint32 temp = B_LENDIAN_TO_HOST_INT32(fEventRing[i].dwtrb3); 2320 uint8 event = TRB_3_TYPE_GET(temp); 2321 TRACE("event[%u] = %u (0x%016" B_PRIx64 " 0x%08" B_PRIx32 " 0x%08" 2322 B_PRIx32 ")\n", i, event, fEventRing[i].qwtrb0, 2323 fEventRing[i].dwtrb2, B_LENDIAN_TO_HOST_INT32(fEventRing[i].dwtrb3)); 2324 uint8 k = (temp & TRB_3_CYCLE_BIT) ? 1 : 0; 2325 if (j != k) 2326 break; 2327 2328 2329 switch (event) { 2330 case TRB_TYPE_COMMAND_COMPLETION: 2331 HandleCmdComplete(&fEventRing[i]); 2332 break; 2333 case TRB_TYPE_TRANSFER: 2334 HandleTransferComplete(&fEventRing[i]); 2335 break; 2336 case TRB_TYPE_PORT_STATUS_CHANGE: 2337 TRACE("port change detected\n"); 2338 break; 2339 default: 2340 TRACE_ERROR("Unhandled event = %u\n", event); 2341 break; 2342 } 2343 2344 i++; 2345 if (i == XHCI_MAX_EVENTS) { 2346 i = 0; 2347 j ^= 1; 2348 if (!--t) 2349 break; 2350 } 2351 } 2352 2353 fEventIdx = i; 2354 fEventCcs = j; 2355 2356 uint64 addr = fErst->rs_addr + i * sizeof(xhci_trb); 2357 addr |= ERST_EHB; 2358 WriteRunReg32(XHCI_ERDP_LO(0), (uint32)addr); 2359 WriteRunReg32(XHCI_ERDP_HI(0), (uint32)(addr >> 32)); 2360 } 2361 } 2362 2363 2364 int32 2365 XHCI::FinishThread(void* data) 2366 { 2367 ((XHCI *)data)->FinishTransfers(); 2368 return B_OK; 2369 } 2370 2371 2372 void 2373 XHCI::FinishTransfers() 2374 { 2375 while (!fStopThreads) { 2376 if (acquire_sem(fFinishTransfersSem) < B_OK) 2377 continue; 2378 2379 // eat up sems that have been released by multiple interrupts 2380 int32 semCount = 0; 2381 get_sem_count(fFinishTransfersSem, &semCount); 2382 if (semCount > 0) 2383 acquire_sem_etc(fFinishTransfersSem, semCount, B_RELATIVE_TIMEOUT, 0); 2384 2385 Lock(); 2386 TRACE("finishing transfers\n"); 2387 while (fFinishedHead != NULL) { 2388 xhci_td* td = fFinishedHead; 2389 fFinishedHead = td->next; 2390 td->next = NULL; 2391 Unlock(); 2392 2393 TRACE("finishing transfer td %p\n", td); 2394 2395 Transfer* transfer = td->transfer; 2396 bool directionIn = (transfer->TransferPipe()->Direction() != Pipe::Out); 2397 usb_request_data *requestData = transfer->RequestData(); 2398 2399 status_t callbackStatus = B_OK; 2400 switch (td->trb_completion_code) { 2401 case COMP_SHORT_PACKET: 2402 case COMP_SUCCESS: 2403 callbackStatus = B_OK; 2404 break; 2405 case COMP_DATA_BUFFER: 2406 callbackStatus = directionIn ? B_DEV_DATA_OVERRUN 2407 : B_DEV_DATA_UNDERRUN; 2408 break; 2409 case COMP_BABBLE: 2410 callbackStatus = directionIn ? B_DEV_FIFO_OVERRUN 2411 : B_DEV_FIFO_UNDERRUN; 2412 break; 2413 case COMP_USB_TRANSACTION: 2414 callbackStatus = B_DEV_CRC_ERROR; 2415 break; 2416 case COMP_STALL: 2417 callbackStatus = B_DEV_STALLED; 2418 break; 2419 default: 2420 callbackStatus = B_DEV_STALLED; 2421 break; 2422 } 2423 2424 size_t actualLength = 0; 2425 if (callbackStatus == B_OK) { 2426 actualLength = requestData ? requestData->Length 2427 : transfer->DataLength(); 2428 2429 if (td->trb_completion_code == COMP_SHORT_PACKET) 2430 actualLength -= td->trb_left; 2431 2432 if (directionIn && actualLength > 0) { 2433 if (requestData) { 2434 TRACE("copying in data %d bytes\n", requestData->Length); 2435 transfer->PrepareKernelAccess(); 2436 memcpy((uint8 *)transfer->Vector()[0].iov_base, 2437 td->buffer_log[0], requestData->Length); 2438 } else { 2439 TRACE("copying in iov count %ld\n", transfer->VectorCount()); 2440 transfer->PrepareKernelAccess(); 2441 ReadDescriptorChain(td, transfer->Vector(), 2442 transfer->VectorCount()); 2443 } 2444 } 2445 } 2446 transfer->Finished(callbackStatus, actualLength); 2447 delete transfer; 2448 FreeDescriptor(td); 2449 Lock(); 2450 } 2451 Unlock(); 2452 } 2453 } 2454 2455 2456 inline void 2457 XHCI::WriteOpReg(uint32 reg, uint32 value) 2458 { 2459 *(volatile uint32 *)(fRegisters + fOperationalRegisterOffset + reg) = value; 2460 } 2461 2462 2463 inline uint32 2464 XHCI::ReadOpReg(uint32 reg) 2465 { 2466 return *(volatile uint32 *)(fRegisters + fOperationalRegisterOffset + reg); 2467 } 2468 2469 2470 inline status_t 2471 XHCI::WaitOpBits(uint32 reg, uint32 mask, uint32 expected) 2472 { 2473 int loops = 0; 2474 uint32 value = ReadOpReg(reg); 2475 while ((value & mask) != expected) { 2476 snooze(1000); 2477 value = ReadOpReg(reg); 2478 if (loops == 25) { 2479 TRACE("delay waiting on reg 0x%" B_PRIX32 " match 0x%" B_PRIX32 2480 " (0x%" B_PRIX32 ")\n", reg, expected, mask); 2481 } else if (loops > 100) { 2482 TRACE_ERROR("timeout waiting on reg 0x%" B_PRIX32 2483 " match 0x%" B_PRIX32 " (0x%" B_PRIX32 ")\n", reg, expected, 2484 mask); 2485 return B_ERROR; 2486 } 2487 loops++; 2488 } 2489 return B_OK; 2490 } 2491 2492 2493 inline uint32 2494 XHCI::ReadCapReg32(uint32 reg) 2495 { 2496 return *(volatile uint32 *)(fRegisters + fCapabilityRegisterOffset + reg); 2497 } 2498 2499 2500 inline void 2501 XHCI::WriteCapReg32(uint32 reg, uint32 value) 2502 { 2503 *(volatile uint32 *)(fRegisters + fCapabilityRegisterOffset + reg) = value; 2504 } 2505 2506 2507 inline uint32 2508 XHCI::ReadRunReg32(uint32 reg) 2509 { 2510 return *(volatile uint32 *)(fRegisters + fRuntimeRegisterOffset + reg); 2511 } 2512 2513 2514 inline void 2515 XHCI::WriteRunReg32(uint32 reg, uint32 value) 2516 { 2517 *(volatile uint32 *)(fRegisters + fRuntimeRegisterOffset + reg) = value; 2518 } 2519 2520 2521 inline uint32 2522 XHCI::ReadDoorReg32(uint32 reg) 2523 { 2524 return *(volatile uint32 *)(fRegisters + fDoorbellRegisterOffset + reg); 2525 } 2526 2527 2528 inline void 2529 XHCI::WriteDoorReg32(uint32 reg, uint32 value) 2530 { 2531 *(volatile uint32 *)(fRegisters + fDoorbellRegisterOffset + reg) = value; 2532 } 2533 2534 2535 inline addr_t 2536 XHCI::_OffsetContextAddr(addr_t p) 2537 { 2538 if (fContextSizeShift == 1) { 2539 // each structure is page aligned, each pointer is 32 bits aligned 2540 uint32 offset = p & ((B_PAGE_SIZE - 1) & ~31U); 2541 p += offset; 2542 } 2543 return p; 2544 } 2545 2546 inline uint32 2547 XHCI::_ReadContext(uint32* p) 2548 { 2549 p = (uint32*)_OffsetContextAddr((addr_t)p); 2550 return *p; 2551 } 2552 2553 2554 inline void 2555 XHCI::_WriteContext(uint32* p, uint32 value) 2556 { 2557 p = (uint32*)_OffsetContextAddr((addr_t)p); 2558 *p = value; 2559 } 2560 2561 2562 inline uint64 2563 XHCI::_ReadContext(uint64* p) 2564 { 2565 p = (uint64*)_OffsetContextAddr((addr_t)p); 2566 return *p; 2567 } 2568 2569 2570 inline void 2571 XHCI::_WriteContext(uint64* p, uint64 value) 2572 { 2573 p = (uint64*)_OffsetContextAddr((addr_t)p); 2574 *p = value; 2575 } 2576