1 /* 2 * Copyright 2005-2008, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Jan-Rixt Van Hoye 7 * Salvatore Benedetto <salvatore.benedetto@gmail.com> 8 * Michael Lotz <mmlr@mlotz.ch> 9 */ 10 11 #include <module.h> 12 #include <PCI.h> 13 #include <PCI_x86.h> 14 #include <USB3.h> 15 #include <KernelExport.h> 16 #include <util/AutoLock.h> 17 18 #include "ohci.h" 19 20 #define USB_MODULE_NAME "ohci" 21 22 pci_module_info *OHCI::sPCIModule = NULL; 23 pci_x86_module_info *OHCI::sPCIx86Module = NULL; 24 25 26 static int32 27 ohci_std_ops(int32 op, ...) 28 { 29 switch (op) { 30 case B_MODULE_INIT: 31 TRACE_MODULE("init module\n"); 32 return B_OK; 33 case B_MODULE_UNINIT: 34 TRACE_MODULE("uninit module\n"); 35 return B_OK; 36 } 37 38 return EINVAL; 39 } 40 41 42 usb_host_controller_info ohci_module = { 43 { 44 "busses/usb/ohci", 45 0, 46 ohci_std_ops 47 }, 48 NULL, 49 OHCI::AddTo 50 }; 51 52 53 module_info *modules[] = { 54 (module_info *)&ohci_module, 55 NULL 56 }; 57 58 59 OHCI::OHCI(pci_info *info, Stack *stack) 60 : BusManager(stack), 61 fPCIInfo(info), 62 fStack(stack), 63 fOperationalRegisters(NULL), 64 fRegisterArea(-1), 65 fHccaArea(-1), 66 fHcca(NULL), 67 fInterruptEndpoints(NULL), 68 fDummyControl(NULL), 69 fDummyBulk(NULL), 70 fDummyIsochronous(NULL), 71 fFirstTransfer(NULL), 72 fLastTransfer(NULL), 73 fFinishTransfersSem(-1), 74 fFinishThread(-1), 75 fStopFinishThread(false), 76 fProcessingPipe(NULL), 77 fRootHub(NULL), 78 fRootHubAddress(0), 79 fPortCount(0) 80 { 81 if (!fInitOK) { 82 TRACE_ERROR("bus manager failed to init\n"); 83 return; 84 } 85 86 TRACE("constructing new OHCI host controller driver\n"); 87 fInitOK = false; 88 89 mutex_init(&fEndpointLock, "ohci endpoint lock"); 90 91 // enable busmaster and memory mapped access 92 uint16 command = sPCIModule->read_pci_config(fPCIInfo->bus, 93 fPCIInfo->device, fPCIInfo->function, PCI_command, 2); 94 command &= ~PCI_command_io; 95 command |= PCI_command_master | PCI_command_memory; 96 97 sPCIModule->write_pci_config(fPCIInfo->bus, fPCIInfo->device, 98 fPCIInfo->function, PCI_command, 2, command); 99 100 // map the registers 101 uint32 offset = sPCIModule->read_pci_config(fPCIInfo->bus, 102 fPCIInfo->device, fPCIInfo->function, PCI_base_registers, 4); 103 offset &= PCI_address_memory_32_mask; 104 TRACE_ALWAYS("iospace offset: 0x%lx\n", offset); 105 fRegisterArea = map_physical_memory("OHCI memory mapped registers", 106 offset, B_PAGE_SIZE, B_ANY_KERNEL_BLOCK_ADDRESS, 107 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_READ_AREA | B_WRITE_AREA, 108 (void **)&fOperationalRegisters); 109 if (fRegisterArea < B_OK) { 110 TRACE_ERROR("failed to map register memory\n"); 111 return; 112 } 113 114 TRACE("mapped operational registers: %p\n", fOperationalRegisters); 115 116 // Check the revision of the controller, which should be 10h 117 uint32 revision = _ReadReg(OHCI_REVISION) & 0xff; 118 TRACE("version %ld.%ld%s\n", OHCI_REVISION_HIGH(revision), 119 OHCI_REVISION_LOW(revision), OHCI_REVISION_LEGACY(revision) 120 ? ", legacy support" : ""); 121 if (OHCI_REVISION_HIGH(revision) != 1 || OHCI_REVISION_LOW(revision) != 0) { 122 TRACE_ERROR("unsupported OHCI revision\n"); 123 return; 124 } 125 126 void *hccaPhysicalAddress; 127 fHccaArea = fStack->AllocateArea((void **)&fHcca, &hccaPhysicalAddress, 128 sizeof(ohci_hcca), "USB OHCI Host Controller Communication Area"); 129 130 if (fHccaArea < B_OK) { 131 TRACE_ERROR("unable to create the HCCA block area\n"); 132 return; 133 } 134 135 memset(fHcca, 0, sizeof(ohci_hcca)); 136 137 // Set Up Host controller 138 // Dummy endpoints 139 fDummyControl = _AllocateEndpoint(); 140 if (!fDummyControl) 141 return; 142 143 fDummyBulk = _AllocateEndpoint(); 144 if (!fDummyBulk) { 145 _FreeEndpoint(fDummyControl); 146 return; 147 } 148 149 fDummyIsochronous = _AllocateEndpoint(); 150 if (!fDummyIsochronous) { 151 _FreeEndpoint(fDummyControl); 152 _FreeEndpoint(fDummyBulk); 153 return; 154 } 155 156 // Static endpoints that get linked in the HCCA 157 fInterruptEndpoints = new(std::nothrow) 158 ohci_endpoint_descriptor *[OHCI_STATIC_ENDPOINT_COUNT]; 159 if (!fInterruptEndpoints) { 160 TRACE_ERROR("failed to allocate memory for interrupt endpoints\n"); 161 _FreeEndpoint(fDummyControl); 162 _FreeEndpoint(fDummyBulk); 163 _FreeEndpoint(fDummyIsochronous); 164 return; 165 } 166 167 for (int32 i = 0; i < OHCI_STATIC_ENDPOINT_COUNT; i++) { 168 fInterruptEndpoints[i] = _AllocateEndpoint(); 169 if (!fInterruptEndpoints[i]) { 170 TRACE_ERROR("failed to allocate interrupt endpoint %ld", i); 171 while (--i >= 0) 172 _FreeEndpoint(fInterruptEndpoints[i]); 173 _FreeEndpoint(fDummyBulk); 174 _FreeEndpoint(fDummyControl); 175 _FreeEndpoint(fDummyIsochronous); 176 return; 177 } 178 } 179 180 // build flat tree so that at each of the static interrupt endpoints 181 // fInterruptEndpoints[i] == interrupt endpoint for interval 2^i 182 uint32 interval = OHCI_BIGGEST_INTERVAL; 183 uint32 intervalIndex = OHCI_STATIC_ENDPOINT_COUNT - 1; 184 while (interval > 1) { 185 uint32 insertIndex = interval / 2; 186 while (insertIndex < OHCI_BIGGEST_INTERVAL) { 187 fHcca->interrupt_table[insertIndex] 188 = fInterruptEndpoints[intervalIndex]->physical_address; 189 insertIndex += interval; 190 } 191 192 intervalIndex--; 193 interval /= 2; 194 } 195 196 // setup the empty slot in the list and linking of all -> first 197 fHcca->interrupt_table[0] = fInterruptEndpoints[0]->physical_address; 198 for (int32 i = 1; i < OHCI_STATIC_ENDPOINT_COUNT; i++) { 199 fInterruptEndpoints[i]->next_physical_endpoint 200 = fInterruptEndpoints[0]->physical_address; 201 fInterruptEndpoints[i]->next_logical_endpoint 202 = fInterruptEndpoints[0]; 203 } 204 205 // Now link the first endpoint to the isochronous endpoint 206 fInterruptEndpoints[0]->next_physical_endpoint 207 = fDummyIsochronous->physical_address; 208 209 // When the handover from SMM takes place, all interrupts are routed to the 210 // OS. As we don't yet have an interrupt handler installed at this point, 211 // this may cause interrupt storms if the firmware does not disable the 212 // interrupts during handover. Therefore we disable interrupts before 213 // requesting ownership. We have to keep the ownership change interrupt 214 // enabled though, as otherwise the SMM will not be notified of the 215 // ownership change request we trigger below. 216 _WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTERRUPTS & 217 ~OHCI_OWNERSHIP_CHANGE) ; 218 219 // Determine in what context we are running (Kindly copied from FreeBSD) 220 uint32 control = _ReadReg(OHCI_CONTROL); 221 if (control & OHCI_INTERRUPT_ROUTING) { 222 TRACE_ALWAYS("smm is in control of the host controller\n"); 223 uint32 status = _ReadReg(OHCI_COMMAND_STATUS); 224 _WriteReg(OHCI_COMMAND_STATUS, status | OHCI_OWNERSHIP_CHANGE_REQUEST); 225 for (uint32 i = 0; i < 100 && (control & OHCI_INTERRUPT_ROUTING); i++) { 226 snooze(1000); 227 control = _ReadReg(OHCI_CONTROL); 228 } 229 230 if ((control & OHCI_INTERRUPT_ROUTING) != 0) { 231 TRACE_ERROR("smm does not respond.\n"); 232 233 // TODO: Enable this reset as soon as the non-specified 234 // reset a few lines later is replaced by a better solution. 235 //_WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET); 236 //snooze(USB_DELAY_BUS_RESET); 237 } else 238 TRACE_ALWAYS("ownership change successful\n"); 239 } else { 240 TRACE("cold started\n"); 241 snooze(USB_DELAY_BUS_RESET); 242 } 243 244 // TODO: This reset delays system boot time. It should not be necessary 245 // according to the OHCI spec, but without it some controllers don't start. 246 _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET); 247 snooze(USB_DELAY_BUS_RESET); 248 249 // We now own the host controller and the bus has been reset 250 uint32 frameInterval = _ReadReg(OHCI_FRAME_INTERVAL); 251 uint32 intervalValue = OHCI_GET_INTERVAL_VALUE(frameInterval); 252 253 _WriteReg(OHCI_COMMAND_STATUS, OHCI_HOST_CONTROLLER_RESET); 254 // Nominal time for a reset is 10 us 255 uint32 reset = 0; 256 for (uint32 i = 0; i < 10; i++) { 257 spin(10); 258 reset = _ReadReg(OHCI_COMMAND_STATUS) & OHCI_HOST_CONTROLLER_RESET; 259 if (reset == 0) 260 break; 261 } 262 263 if (reset) { 264 TRACE_ERROR("error resetting the host controller (timeout)\n"); 265 return; 266 } 267 268 // The controller is now in SUSPEND state, we have 2ms to go OPERATIONAL. 269 270 // Set up host controller register 271 _WriteReg(OHCI_HCCA, (uint32)hccaPhysicalAddress); 272 _WriteReg(OHCI_CONTROL_HEAD_ED, (uint32)fDummyControl->physical_address); 273 _WriteReg(OHCI_BULK_HEAD_ED, (uint32)fDummyBulk->physical_address); 274 // Switch on desired functional features 275 control = _ReadReg(OHCI_CONTROL); 276 control &= ~(OHCI_CONTROL_BULK_SERVICE_RATIO_MASK | OHCI_ENABLE_LIST 277 | OHCI_HC_FUNCTIONAL_STATE_MASK | OHCI_INTERRUPT_ROUTING); 278 control |= OHCI_ENABLE_LIST | OHCI_CONTROL_BULK_RATIO_1_4 279 | OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL; 280 // And finally start the controller 281 _WriteReg(OHCI_CONTROL, control); 282 283 // The controller is now OPERATIONAL. 284 frameInterval = (_ReadReg(OHCI_FRAME_INTERVAL) & OHCI_FRAME_INTERVAL_TOGGLE) 285 ^ OHCI_FRAME_INTERVAL_TOGGLE; 286 frameInterval |= OHCI_FSMPS(intervalValue) | intervalValue; 287 _WriteReg(OHCI_FRAME_INTERVAL, frameInterval); 288 // 90% periodic 289 uint32 periodic = OHCI_PERIODIC(intervalValue); 290 _WriteReg(OHCI_PERIODIC_START, periodic); 291 292 // Fiddle the No Over Current Protection bit to avoid chip bug 293 uint32 desca = _ReadReg(OHCI_RH_DESCRIPTOR_A); 294 _WriteReg(OHCI_RH_DESCRIPTOR_A, desca | OHCI_RH_NO_OVER_CURRENT_PROTECTION); 295 _WriteReg(OHCI_RH_STATUS, OHCI_RH_LOCAL_POWER_STATUS_CHANGE); 296 snooze(OHCI_ENABLE_POWER_DELAY); 297 _WriteReg(OHCI_RH_DESCRIPTOR_A, desca); 298 299 // The AMD756 requires a delay before re-reading the register, 300 // otherwise it will occasionally report 0 ports. 301 uint32 numberOfPorts = 0; 302 for (uint32 i = 0; i < 10 && numberOfPorts == 0; i++) { 303 snooze(OHCI_READ_DESC_DELAY); 304 uint32 descriptor = _ReadReg(OHCI_RH_DESCRIPTOR_A); 305 numberOfPorts = OHCI_RH_GET_PORT_COUNT(descriptor); 306 } 307 if (numberOfPorts > OHCI_MAX_PORT_COUNT) 308 numberOfPorts = OHCI_MAX_PORT_COUNT; 309 fPortCount = numberOfPorts; 310 TRACE("port count is %d\n", fPortCount); 311 312 // Create semaphore the finisher thread will wait for 313 fFinishTransfersSem = create_sem(0, "OHCI Finish Transfers"); 314 if (fFinishTransfersSem < B_OK) { 315 TRACE_ERROR("failed to create semaphore\n"); 316 return; 317 } 318 319 // Create the finisher service thread 320 fFinishThread = spawn_kernel_thread(_FinishThread, "ohci finish thread", 321 B_URGENT_DISPLAY_PRIORITY, (void *)this); 322 resume_thread(fFinishThread); 323 324 // Find the right interrupt vector, using MSIs if available. 325 uint8 interruptVector = fPCIInfo->u.h0.interrupt_line; 326 if (sPCIx86Module != NULL && sPCIx86Module->get_msi_count(fPCIInfo->bus, 327 fPCIInfo->device, fPCIInfo->function) >= 1) { 328 uint8 msiVector = 0; 329 if (sPCIx86Module->configure_msi(fPCIInfo->bus, fPCIInfo->device, 330 fPCIInfo->function, 1, &msiVector) == B_OK 331 && sPCIx86Module->enable_msi(fPCIInfo->bus, fPCIInfo->device, 332 fPCIInfo->function) == B_OK) { 333 TRACE_ALWAYS("using message signaled interrupts\n"); 334 interruptVector = msiVector; 335 } 336 } 337 338 // Install the interrupt handler 339 TRACE("installing interrupt handler\n"); 340 install_io_interrupt_handler(interruptVector, _InterruptHandler, 341 (void *)this, 0); 342 343 // Enable interesting interrupts now that the handler is in place 344 _WriteReg(OHCI_INTERRUPT_ENABLE, OHCI_NORMAL_INTERRUPTS 345 | OHCI_MASTER_INTERRUPT_ENABLE); 346 347 TRACE("OHCI host controller driver constructed\n"); 348 fInitOK = true; 349 } 350 351 352 OHCI::~OHCI() 353 { 354 int32 result = 0; 355 fStopFinishThread = true; 356 delete_sem(fFinishTransfersSem); 357 wait_for_thread(fFinishThread, &result); 358 359 _LockEndpoints(); 360 mutex_destroy(&fEndpointLock); 361 362 if (fHccaArea >= B_OK) 363 delete_area(fHccaArea); 364 if (fRegisterArea >= B_OK) 365 delete_area(fRegisterArea); 366 367 _FreeEndpoint(fDummyControl); 368 _FreeEndpoint(fDummyBulk); 369 _FreeEndpoint(fDummyIsochronous); 370 371 if (fInterruptEndpoints != NULL) { 372 for (int i = 0; i < OHCI_STATIC_ENDPOINT_COUNT; i++) 373 _FreeEndpoint(fInterruptEndpoints[i]); 374 } 375 376 delete [] fInterruptEndpoints; 377 delete fRootHub; 378 379 put_module(B_PCI_MODULE_NAME); 380 } 381 382 383 status_t 384 OHCI::Start() 385 { 386 TRACE("starting OHCI host controller\n"); 387 388 uint32 control = _ReadReg(OHCI_CONTROL); 389 if ((control & OHCI_HC_FUNCTIONAL_STATE_MASK) 390 != OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL) { 391 TRACE_ERROR("controller not started (0x%08lx)!\n", control); 392 return B_ERROR; 393 } else 394 TRACE("controller is operational!\n"); 395 396 fRootHubAddress = AllocateAddress(); 397 fRootHub = new(std::nothrow) OHCIRootHub(RootObject(), fRootHubAddress); 398 if (!fRootHub) { 399 TRACE_ERROR("no memory to allocate root hub\n"); 400 return B_NO_MEMORY; 401 } 402 403 if (fRootHub->InitCheck() < B_OK) { 404 TRACE_ERROR("root hub failed init check\n"); 405 return B_ERROR; 406 } 407 408 SetRootHub(fRootHub); 409 TRACE_ALWAYS("successfully started the controller\n"); 410 return BusManager::Start(); 411 } 412 413 414 status_t 415 OHCI::SubmitTransfer(Transfer *transfer) 416 { 417 // short circuit the root hub 418 if (transfer->TransferPipe()->DeviceAddress() == fRootHubAddress) 419 return fRootHub->ProcessTransfer(this, transfer); 420 421 uint32 type = transfer->TransferPipe()->Type(); 422 if (type & USB_OBJECT_CONTROL_PIPE) { 423 TRACE("submitting request\n"); 424 return _SubmitRequest(transfer); 425 } 426 427 if ((type & USB_OBJECT_BULK_PIPE) || (type & USB_OBJECT_INTERRUPT_PIPE)) { 428 TRACE("submitting %s transfer\n", 429 (type & USB_OBJECT_BULK_PIPE) ? "bulk" : "interrupt"); 430 return _SubmitTransfer(transfer); 431 } 432 433 if (type & USB_OBJECT_ISO_PIPE) { 434 TRACE("submitting isochronous transfer\n"); 435 return _SubmitIsochronousTransfer(transfer); 436 } 437 438 TRACE_ERROR("tried to submit transfer for unknown pipe type %lu\n", type); 439 return B_ERROR; 440 } 441 442 443 status_t 444 OHCI::CancelQueuedTransfers(Pipe *pipe, bool force) 445 { 446 if (pipe->Type() & USB_OBJECT_ISO_PIPE) 447 return _CancelQueuedIsochronousTransfers(pipe, force); 448 449 if (!Lock()) 450 return B_ERROR; 451 452 struct transfer_entry { 453 Transfer * transfer; 454 transfer_entry * next; 455 }; 456 457 transfer_entry *list = NULL; 458 transfer_data *current = fFirstTransfer; 459 while (current) { 460 if (current->transfer && current->transfer->TransferPipe() == pipe) { 461 // Check if the skip bit is already set 462 if (!(current->endpoint->flags & OHCI_ENDPOINT_SKIP)) { 463 current->endpoint->flags |= OHCI_ENDPOINT_SKIP; 464 // In case the controller is processing 465 // this endpoint, wait for it to finish 466 snooze(1000); 467 } 468 469 // Clear the endpoint 470 current->endpoint->head_physical_descriptor 471 = current->endpoint->tail_physical_descriptor; 472 473 if (!force) { 474 // If the transfer is canceled by force, the one causing the 475 // cancel is probably not the one who initiated the transfer 476 // and the callback is likely not safe anymore 477 transfer_entry *entry 478 = (transfer_entry *)malloc(sizeof(transfer_entry)); 479 if (entry != NULL) { 480 entry->transfer = current->transfer; 481 current->transfer = NULL; 482 entry->next = list; 483 list = entry; 484 } 485 } 486 current->canceled = true; 487 } 488 current = current->link; 489 } 490 491 Unlock(); 492 493 while (list != NULL) { 494 transfer_entry *next = list->next; 495 list->transfer->Finished(B_CANCELED, 0); 496 delete list->transfer; 497 free(list); 498 list = next; 499 } 500 501 // wait for any transfers that might have made it before canceling 502 while (fProcessingPipe == pipe) 503 snooze(1000); 504 505 // notify the finisher so it can clean up the canceled transfers 506 release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE); 507 return B_OK; 508 } 509 510 511 status_t 512 OHCI::NotifyPipeChange(Pipe *pipe, usb_change change) 513 { 514 TRACE("pipe change %d for pipe 0x%08lx\n", change, (uint32)pipe); 515 if (pipe->DeviceAddress() == fRootHubAddress) { 516 // no need to insert/remove endpoint descriptors for the root hub 517 return B_OK; 518 } 519 520 switch (change) { 521 case USB_CHANGE_CREATED: 522 return _InsertEndpointForPipe(pipe); 523 524 case USB_CHANGE_DESTROYED: 525 return _RemoveEndpointForPipe(pipe); 526 527 case USB_CHANGE_PIPE_POLICY_CHANGED: 528 TRACE("pipe policy changing unhandled!\n"); 529 break; 530 531 default: 532 TRACE_ERROR("unknown pipe change!\n"); 533 return B_ERROR; 534 } 535 536 return B_OK; 537 } 538 539 540 status_t 541 OHCI::AddTo(Stack *stack) 542 { 543 #ifdef TRACE_USB 544 set_dprintf_enabled(true); 545 #ifndef HAIKU_TARGET_PLATFORM_HAIKU 546 load_driver_symbols("ohci"); 547 #endif 548 #endif 549 550 if (!sPCIModule) { 551 status_t status = get_module(B_PCI_MODULE_NAME, (module_info **)&sPCIModule); 552 if (status < B_OK) { 553 TRACE_MODULE_ERROR("getting pci module failed! 0x%08lx\n", status); 554 return status; 555 } 556 } 557 558 TRACE_MODULE("searching devices\n"); 559 bool found = false; 560 pci_info *item = new(std::nothrow) pci_info; 561 if (!item) { 562 sPCIModule = NULL; 563 put_module(B_PCI_MODULE_NAME); 564 return B_NO_MEMORY; 565 } 566 567 // Try to get the PCI x86 module as well so we can enable possible MSIs. 568 if (sPCIx86Module == NULL && get_module(B_PCI_X86_MODULE_NAME, 569 (module_info **)&sPCIx86Module) != B_OK) { 570 // If it isn't there, that's not critical though. 571 TRACE_MODULE_ERROR("failed to get pci x86 module\n"); 572 sPCIx86Module = NULL; 573 } 574 575 for (uint32 i = 0 ; sPCIModule->get_nth_pci_info(i, item) >= B_OK; i++) { 576 if (item->class_base == PCI_serial_bus && item->class_sub == PCI_usb 577 && item->class_api == PCI_usb_ohci) { 578 if (item->u.h0.interrupt_line == 0 579 || item->u.h0.interrupt_line == 0xFF) { 580 TRACE_MODULE_ERROR("found device with invalid IRQ -" 581 " check IRQ assignement\n"); 582 continue; 583 } 584 585 TRACE_MODULE("found device at IRQ %u\n", 586 item->u.h0.interrupt_line); 587 OHCI *bus = new(std::nothrow) OHCI(item, stack); 588 if (!bus) { 589 delete item; 590 sPCIModule = NULL; 591 put_module(B_PCI_MODULE_NAME); 592 593 if (sPCIx86Module != NULL) { 594 sPCIx86Module = NULL; 595 put_module(B_PCI_X86_MODULE_NAME); 596 } 597 598 return B_NO_MEMORY; 599 } 600 601 if (bus->InitCheck() < B_OK) { 602 TRACE_MODULE_ERROR("bus failed init check\n"); 603 delete bus; 604 continue; 605 } 606 607 // the bus took it away 608 item = new(std::nothrow) pci_info; 609 610 bus->Start(); 611 stack->AddBusManager(bus); 612 found = true; 613 } 614 } 615 616 if (!found) { 617 TRACE_MODULE_ERROR("no devices found\n"); 618 delete item; 619 sPCIModule = NULL; 620 put_module(B_PCI_MODULE_NAME); 621 622 if (sPCIx86Module != NULL) { 623 sPCIx86Module = NULL; 624 put_module(B_PCI_X86_MODULE_NAME); 625 } 626 627 return ENODEV; 628 } 629 630 delete item; 631 return B_OK; 632 } 633 634 635 status_t 636 OHCI::GetPortStatus(uint8 index, usb_port_status *status) 637 { 638 if (index >= fPortCount) { 639 TRACE_ERROR("get port status for invalid port %u\n", index); 640 return B_BAD_INDEX; 641 } 642 643 status->status = status->change = 0; 644 uint32 portStatus = _ReadReg(OHCI_RH_PORT_STATUS(index)); 645 646 // status 647 if (portStatus & OHCI_RH_PORTSTATUS_CCS) 648 status->status |= PORT_STATUS_CONNECTION; 649 if (portStatus & OHCI_RH_PORTSTATUS_PES) 650 status->status |= PORT_STATUS_ENABLE; 651 if (portStatus & OHCI_RH_PORTSTATUS_PSS) 652 status->status |= PORT_STATUS_SUSPEND; 653 if (portStatus & OHCI_RH_PORTSTATUS_POCI) 654 status->status |= PORT_STATUS_OVER_CURRENT; 655 if (portStatus & OHCI_RH_PORTSTATUS_PRS) 656 status->status |= PORT_STATUS_RESET; 657 if (portStatus & OHCI_RH_PORTSTATUS_PPS) 658 status->status |= PORT_STATUS_POWER; 659 if (portStatus & OHCI_RH_PORTSTATUS_LSDA) 660 status->status |= PORT_STATUS_LOW_SPEED; 661 662 // change 663 if (portStatus & OHCI_RH_PORTSTATUS_CSC) 664 status->change |= PORT_STATUS_CONNECTION; 665 if (portStatus & OHCI_RH_PORTSTATUS_PESC) 666 status->change |= PORT_STATUS_ENABLE; 667 if (portStatus & OHCI_RH_PORTSTATUS_PSSC) 668 status->change |= PORT_STATUS_SUSPEND; 669 if (portStatus & OHCI_RH_PORTSTATUS_OCIC) 670 status->change |= PORT_STATUS_OVER_CURRENT; 671 if (portStatus & OHCI_RH_PORTSTATUS_PRSC) 672 status->change |= PORT_STATUS_RESET; 673 674 TRACE("port %u status 0x%04x change 0x%04x\n", index, 675 status->status, status->change); 676 return B_OK; 677 } 678 679 680 status_t 681 OHCI::SetPortFeature(uint8 index, uint16 feature) 682 { 683 TRACE("set port feature index %u feature %u\n", index, feature); 684 if (index > fPortCount) 685 return B_BAD_INDEX; 686 687 switch (feature) { 688 case PORT_ENABLE: 689 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PES); 690 return B_OK; 691 692 case PORT_SUSPEND: 693 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PSS); 694 return B_OK; 695 696 case PORT_RESET: 697 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PRS); 698 return B_OK; 699 700 case PORT_POWER: 701 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PPS); 702 return B_OK; 703 } 704 705 return B_BAD_VALUE; 706 } 707 708 709 status_t 710 OHCI::ClearPortFeature(uint8 index, uint16 feature) 711 { 712 TRACE("clear port feature index %u feature %u\n", index, feature); 713 if (index > fPortCount) 714 return B_BAD_INDEX; 715 716 switch (feature) { 717 case PORT_ENABLE: 718 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CCS); 719 return B_OK; 720 721 case PORT_SUSPEND: 722 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_POCI); 723 return B_OK; 724 725 case PORT_POWER: 726 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_LSDA); 727 return B_OK; 728 729 case C_PORT_CONNECTION: 730 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CSC); 731 return B_OK; 732 733 case C_PORT_ENABLE: 734 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PESC); 735 return B_OK; 736 737 case C_PORT_SUSPEND: 738 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PSSC); 739 return B_OK; 740 741 case C_PORT_OVER_CURRENT: 742 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_OCIC); 743 return B_OK; 744 745 case C_PORT_RESET: 746 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PRSC); 747 return B_OK; 748 } 749 750 return B_BAD_VALUE; 751 } 752 753 754 int32 755 OHCI::_InterruptHandler(void *data) 756 { 757 return ((OHCI *)data)->_Interrupt(); 758 } 759 760 761 int32 762 OHCI::_Interrupt() 763 { 764 static spinlock lock = B_SPINLOCK_INITIALIZER; 765 acquire_spinlock(&lock); 766 767 uint32 status = 0; 768 uint32 acknowledge = 0; 769 bool finishTransfers = false; 770 int32 result = B_HANDLED_INTERRUPT; 771 772 // The LSb of done_head is used to inform the HCD that an interrupt 773 // condition exists for both the done list and for another event recorded in 774 // the HcInterruptStatus register. If done_head is 0, then the interrupt 775 // was caused by other than the HccaDoneHead update and the 776 // HcInterruptStatus register needs to be accessed to determine that exact 777 // interrupt cause. If HccDoneHead is nonzero, then a done list update 778 // interrupt is indicated and if the LSb of the Dword is nonzero, then an 779 // additional interrupt event is indicated and HcInterruptStatus should be 780 // checked to determine its cause. 781 uint32 doneHead = fHcca->done_head; 782 if (doneHead != 0) { 783 status = OHCI_WRITEBACK_DONE_HEAD; 784 if (doneHead & OHCI_DONE_INTERRUPTS) 785 status |= _ReadReg(OHCI_INTERRUPT_STATUS) 786 & _ReadReg(OHCI_INTERRUPT_ENABLE); 787 } else { 788 status = _ReadReg(OHCI_INTERRUPT_STATUS) & _ReadReg(OHCI_INTERRUPT_ENABLE) 789 & ~OHCI_WRITEBACK_DONE_HEAD; 790 if (status == 0) { 791 // Nothing to be done (PCI shared interrupt) 792 release_spinlock(&lock); 793 return B_UNHANDLED_INTERRUPT; 794 } 795 } 796 797 if (status & OHCI_SCHEDULING_OVERRUN) { 798 TRACE_MODULE("scheduling overrun occured\n"); 799 acknowledge |= OHCI_SCHEDULING_OVERRUN; 800 } 801 802 if (status & OHCI_WRITEBACK_DONE_HEAD) { 803 TRACE_MODULE("transfer descriptors processed\n"); 804 fHcca->done_head = 0; 805 acknowledge |= OHCI_WRITEBACK_DONE_HEAD; 806 result = B_INVOKE_SCHEDULER; 807 finishTransfers = true; 808 } 809 810 if (status & OHCI_RESUME_DETECTED) { 811 TRACE_MODULE("resume detected\n"); 812 acknowledge |= OHCI_RESUME_DETECTED; 813 } 814 815 if (status & OHCI_UNRECOVERABLE_ERROR) { 816 TRACE_MODULE_ERROR("unrecoverable error - controller halted\n"); 817 _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET); 818 // TODO: clear all pending transfers, reset and resetup the controller 819 } 820 821 if (status & OHCI_ROOT_HUB_STATUS_CHANGE) { 822 TRACE_MODULE("root hub status change\n"); 823 // Disable the interrupt as it will otherwise be retriggered until the 824 // port has been reset and the change is cleared explicitly. 825 // TODO: renable it once we use status changes instead of polling 826 _WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ROOT_HUB_STATUS_CHANGE); 827 acknowledge |= OHCI_ROOT_HUB_STATUS_CHANGE; 828 } 829 830 if (acknowledge != 0) 831 _WriteReg(OHCI_INTERRUPT_STATUS, acknowledge); 832 833 release_spinlock(&lock); 834 835 if (finishTransfers) 836 release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE); 837 838 return result; 839 } 840 841 842 status_t 843 OHCI::_AddPendingTransfer(Transfer *transfer, 844 ohci_endpoint_descriptor *endpoint, ohci_general_td *firstDescriptor, 845 ohci_general_td *dataDescriptor, ohci_general_td *lastDescriptor, 846 bool directionIn) 847 { 848 if (!transfer || !endpoint || !lastDescriptor) 849 return B_BAD_VALUE; 850 851 transfer_data *data = new(std::nothrow) transfer_data; 852 if (!data) 853 return B_NO_MEMORY; 854 855 status_t result = transfer->InitKernelAccess(); 856 if (result < B_OK) { 857 delete data; 858 return result; 859 } 860 861 data->transfer = transfer; 862 data->endpoint = endpoint; 863 data->incoming = directionIn; 864 data->canceled = false; 865 data->link = NULL; 866 867 // the current tail will become the first descriptor 868 data->first_descriptor = (ohci_general_td *)endpoint->tail_logical_descriptor; 869 870 // the data and first descriptors might be the same 871 if (dataDescriptor == firstDescriptor) 872 data->data_descriptor = data->first_descriptor; 873 else 874 data->data_descriptor = dataDescriptor; 875 876 // even the last and the first descriptor might be the same 877 if (lastDescriptor == firstDescriptor) 878 data->last_descriptor = data->first_descriptor; 879 else 880 data->last_descriptor = lastDescriptor; 881 882 if (!Lock()) { 883 delete data; 884 return B_ERROR; 885 } 886 887 if (fLastTransfer) 888 fLastTransfer->link = data; 889 else 890 fFirstTransfer = data; 891 892 fLastTransfer = data; 893 Unlock(); 894 895 return B_OK; 896 } 897 898 899 status_t 900 OHCI::_CancelQueuedIsochronousTransfers(Pipe *pipe, bool force) 901 { 902 // TODO 903 return B_ERROR; 904 } 905 906 907 int32 908 OHCI::_FinishThread(void *data) 909 { 910 ((OHCI *)data)->_FinishTransfers(); 911 return B_OK; 912 } 913 914 915 void 916 OHCI::_FinishTransfers() 917 { 918 while (!fStopFinishThread) { 919 if (acquire_sem(fFinishTransfersSem) < B_OK) 920 continue; 921 922 // eat up sems that have been released by multiple interrupts 923 int32 semCount = 0; 924 get_sem_count(fFinishTransfersSem, &semCount); 925 if (semCount > 0) 926 acquire_sem_etc(fFinishTransfersSem, semCount, B_RELATIVE_TIMEOUT, 0); 927 928 if (!Lock()) 929 continue; 930 931 TRACE("finishing transfers (first transfer: %p; last" 932 " transfer: %p)\n", fFirstTransfer, fLastTransfer); 933 transfer_data *lastTransfer = NULL; 934 transfer_data *transfer = fFirstTransfer; 935 Unlock(); 936 937 while (transfer) { 938 bool transferDone = false; 939 ohci_general_td *descriptor = transfer->first_descriptor; 940 ohci_endpoint_descriptor *endpoint = transfer->endpoint; 941 status_t callbackStatus = B_OK; 942 943 MutexLocker endpointLocker(endpoint->lock); 944 945 if ((endpoint->head_physical_descriptor & OHCI_ENDPOINT_HEAD_MASK) 946 != endpoint->tail_physical_descriptor) { 947 // there are still active transfers on this endpoint, we need 948 // to wait for all of them to complete, otherwise we'd read 949 // a potentially bogus data toggle value below 950 TRACE("endpoint %p still has active tds\n", endpoint); 951 lastTransfer = transfer; 952 transfer = transfer->link; 953 continue; 954 } 955 956 endpointLocker.Unlock(); 957 958 while (descriptor && !transfer->canceled) { 959 uint32 status = OHCI_TD_GET_CONDITION_CODE(descriptor->flags); 960 if (status == OHCI_TD_CONDITION_NOT_ACCESSED) { 961 // td is still active 962 TRACE("td %p still active\n", descriptor); 963 break; 964 } 965 966 if (status != OHCI_TD_CONDITION_NO_ERROR) { 967 // an error occured, but we must ensure that the td 968 // was actually done 969 if (endpoint->head_physical_descriptor & OHCI_ENDPOINT_HALTED) { 970 // the endpoint is halted, this guaratees us that this 971 // descriptor has passed (we don't know if the endpoint 972 // was halted because of this td, but we do not need 973 // to know, as when it was halted by another td this 974 // still ensures that this td was handled before). 975 TRACE_ERROR("td error: 0x%08lx\n", status); 976 977 switch (status) { 978 case OHCI_TD_CONDITION_CRC_ERROR: 979 case OHCI_TD_CONDITION_BIT_STUFFING: 980 case OHCI_TD_CONDITION_TOGGLE_MISMATCH: 981 callbackStatus = B_DEV_CRC_ERROR; 982 break; 983 984 case OHCI_TD_CONDITION_STALL: 985 callbackStatus = B_DEV_STALLED; 986 break; 987 988 case OHCI_TD_CONDITION_NO_RESPONSE: 989 callbackStatus = B_TIMED_OUT; 990 break; 991 992 case OHCI_TD_CONDITION_PID_CHECK_FAILURE: 993 callbackStatus = B_DEV_BAD_PID; 994 break; 995 996 case OHCI_TD_CONDITION_UNEXPECTED_PID: 997 callbackStatus = B_DEV_UNEXPECTED_PID; 998 break; 999 1000 case OHCI_TD_CONDITION_DATA_OVERRUN: 1001 callbackStatus = B_DEV_DATA_OVERRUN; 1002 break; 1003 1004 case OHCI_TD_CONDITION_DATA_UNDERRUN: 1005 callbackStatus = B_DEV_DATA_UNDERRUN; 1006 break; 1007 1008 case OHCI_TD_CONDITION_BUFFER_OVERRUN: 1009 callbackStatus = B_DEV_FIFO_OVERRUN; 1010 break; 1011 1012 case OHCI_TD_CONDITION_BUFFER_UNDERRUN: 1013 callbackStatus = B_DEV_FIFO_UNDERRUN; 1014 break; 1015 1016 default: 1017 callbackStatus = B_ERROR; 1018 break; 1019 } 1020 1021 transferDone = true; 1022 break; 1023 } else { 1024 // an error occured but the endpoint is not halted so 1025 // the td is in fact still active 1026 TRACE("td %p active with error\n", descriptor); 1027 break; 1028 } 1029 } 1030 1031 // the td has completed without an error 1032 TRACE("td %p done\n", descriptor); 1033 1034 if (descriptor == transfer->last_descriptor 1035 || descriptor->buffer_physical != 0) { 1036 // this is the last td of the transfer or a short packet 1037 callbackStatus = B_OK; 1038 transferDone = true; 1039 break; 1040 } 1041 1042 descriptor 1043 = (ohci_general_td *)descriptor->next_logical_descriptor; 1044 } 1045 1046 if (transfer->canceled) { 1047 // when a transfer is canceled, all transfers to that endpoint 1048 // are canceled by setting the head pointer to the tail pointer 1049 // which causes all of the tds to become "free" (as they are 1050 // inaccessible and not accessed anymore (as setting the head 1051 // pointer required disabling the endpoint)) 1052 callbackStatus = B_OK; 1053 transferDone = true; 1054 } 1055 1056 if (!transferDone) { 1057 lastTransfer = transfer; 1058 transfer = transfer->link; 1059 continue; 1060 } 1061 1062 // remove the transfer from the list first so we are sure 1063 // it doesn't get canceled while we still process it 1064 transfer_data *next = transfer->link; 1065 if (Lock()) { 1066 if (lastTransfer) 1067 lastTransfer->link = transfer->link; 1068 1069 if (transfer == fFirstTransfer) 1070 fFirstTransfer = transfer->link; 1071 if (transfer == fLastTransfer) 1072 fLastTransfer = lastTransfer; 1073 1074 // store the currently processing pipe here so we can wait 1075 // in cancel if we are processing something on the target pipe 1076 if (!transfer->canceled) 1077 fProcessingPipe = transfer->transfer->TransferPipe(); 1078 1079 transfer->link = NULL; 1080 Unlock(); 1081 } 1082 1083 // break the descriptor chain on the last descriptor 1084 transfer->last_descriptor->next_logical_descriptor = NULL; 1085 TRACE("transfer %p done with status 0x%08lx\n", 1086 transfer, callbackStatus); 1087 1088 // if canceled the callback has already been called 1089 if (!transfer->canceled) { 1090 size_t actualLength = 0; 1091 if (callbackStatus == B_OK) { 1092 if (transfer->data_descriptor && transfer->incoming) { 1093 // data to read out 1094 iovec *vector = transfer->transfer->Vector(); 1095 size_t vectorCount = transfer->transfer->VectorCount(); 1096 1097 transfer->transfer->PrepareKernelAccess(); 1098 actualLength = _ReadDescriptorChain( 1099 transfer->data_descriptor, 1100 vector, vectorCount); 1101 } else if (transfer->data_descriptor) { 1102 // read the actual length that was sent 1103 actualLength = _ReadActualLength( 1104 transfer->data_descriptor); 1105 } 1106 1107 // get the last data toggle and store it for next time 1108 transfer->transfer->TransferPipe()->SetDataToggle( 1109 (endpoint->head_physical_descriptor 1110 & OHCI_ENDPOINT_TOGGLE_CARRY) != 0); 1111 1112 if (transfer->transfer->IsFragmented()) { 1113 // this transfer may still have data left 1114 TRACE("advancing fragmented transfer\n"); 1115 transfer->transfer->AdvanceByFragment(actualLength); 1116 if (transfer->transfer->VectorLength() > 0) { 1117 TRACE("still %ld bytes left on transfer\n", 1118 transfer->transfer->VectorLength()); 1119 // TODO actually resubmit the transfer 1120 } 1121 1122 // the transfer is done, but we already set the 1123 // actualLength with AdvanceByFragment() 1124 actualLength = 0; 1125 } 1126 } 1127 1128 transfer->transfer->Finished(callbackStatus, actualLength); 1129 fProcessingPipe = NULL; 1130 } 1131 1132 if (callbackStatus != B_OK) { 1133 // remove the transfer and make the head pointer valid again 1134 // (including clearing the halt state) 1135 _RemoveTransferFromEndpoint(transfer); 1136 } 1137 1138 // free the descriptors 1139 _FreeDescriptorChain(transfer->first_descriptor); 1140 1141 delete transfer->transfer; 1142 delete transfer; 1143 transfer = next; 1144 } 1145 } 1146 } 1147 1148 1149 status_t 1150 OHCI::_SubmitRequest(Transfer *transfer) 1151 { 1152 usb_request_data *requestData = transfer->RequestData(); 1153 bool directionIn = (requestData->RequestType & USB_REQTYPE_DEVICE_IN) != 0; 1154 1155 ohci_general_td *setupDescriptor 1156 = _CreateGeneralDescriptor(sizeof(usb_request_data)); 1157 if (!setupDescriptor) { 1158 TRACE_ERROR("failed to allocate setup descriptor\n"); 1159 return B_NO_MEMORY; 1160 } 1161 1162 setupDescriptor->flags = OHCI_TD_DIRECTION_PID_SETUP 1163 | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) 1164 | OHCI_TD_TOGGLE_0 1165 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE); 1166 1167 ohci_general_td *statusDescriptor = _CreateGeneralDescriptor(0); 1168 if (!statusDescriptor) { 1169 TRACE_ERROR("failed to allocate status descriptor\n"); 1170 _FreeGeneralDescriptor(setupDescriptor); 1171 return B_NO_MEMORY; 1172 } 1173 1174 statusDescriptor->flags 1175 = (directionIn ? OHCI_TD_DIRECTION_PID_OUT : OHCI_TD_DIRECTION_PID_IN) 1176 | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) 1177 | OHCI_TD_TOGGLE_1 1178 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE); 1179 1180 iovec vector; 1181 vector.iov_base = requestData; 1182 vector.iov_len = sizeof(usb_request_data); 1183 _WriteDescriptorChain(setupDescriptor, &vector, 1); 1184 1185 status_t result; 1186 ohci_general_td *dataDescriptor = NULL; 1187 if (transfer->VectorCount() > 0) { 1188 ohci_general_td *lastDescriptor = NULL; 1189 result = _CreateDescriptorChain(&dataDescriptor, &lastDescriptor, 1190 directionIn ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT, 1191 transfer->VectorLength()); 1192 if (result < B_OK) { 1193 _FreeGeneralDescriptor(setupDescriptor); 1194 _FreeGeneralDescriptor(statusDescriptor); 1195 return result; 1196 } 1197 1198 if (!directionIn) { 1199 _WriteDescriptorChain(dataDescriptor, transfer->Vector(), 1200 transfer->VectorCount()); 1201 } 1202 1203 _LinkDescriptors(setupDescriptor, dataDescriptor); 1204 _LinkDescriptors(lastDescriptor, statusDescriptor); 1205 } else { 1206 _LinkDescriptors(setupDescriptor, statusDescriptor); 1207 } 1208 1209 // Add to the transfer list 1210 ohci_endpoint_descriptor *endpoint 1211 = (ohci_endpoint_descriptor *)transfer->TransferPipe()->ControllerCookie(); 1212 1213 MutexLocker endpointLocker(endpoint->lock); 1214 result = _AddPendingTransfer(transfer, endpoint, setupDescriptor, 1215 dataDescriptor, statusDescriptor, directionIn); 1216 if (result < B_OK) { 1217 TRACE_ERROR("failed to add pending transfer\n"); 1218 _FreeDescriptorChain(setupDescriptor); 1219 return result; 1220 } 1221 1222 // Add the descriptor chain to the endpoint 1223 _SwitchEndpointTail(endpoint, setupDescriptor, statusDescriptor); 1224 endpointLocker.Unlock(); 1225 1226 // Tell the controller to process the control list 1227 endpoint->flags &= ~OHCI_ENDPOINT_SKIP; 1228 _WriteReg(OHCI_COMMAND_STATUS, OHCI_CONTROL_LIST_FILLED); 1229 return B_OK; 1230 } 1231 1232 1233 status_t 1234 OHCI::_SubmitTransfer(Transfer *transfer) 1235 { 1236 Pipe *pipe = transfer->TransferPipe(); 1237 bool directionIn = (pipe->Direction() == Pipe::In); 1238 1239 ohci_general_td *firstDescriptor = NULL; 1240 ohci_general_td *lastDescriptor = NULL; 1241 status_t result = _CreateDescriptorChain(&firstDescriptor, &lastDescriptor, 1242 directionIn ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT, 1243 transfer->VectorLength()); 1244 1245 if (result < B_OK) 1246 return result; 1247 1248 // Apply data toggle to the first descriptor (the others will use the carry) 1249 firstDescriptor->flags &= ~OHCI_TD_TOGGLE_CARRY; 1250 firstDescriptor->flags |= pipe->DataToggle() ? OHCI_TD_TOGGLE_1 1251 : OHCI_TD_TOGGLE_0; 1252 1253 // Set the last descriptor to generate an interrupt 1254 lastDescriptor->flags &= ~OHCI_TD_INTERRUPT_MASK; 1255 lastDescriptor->flags |= 1256 OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE); 1257 1258 if (!directionIn) { 1259 _WriteDescriptorChain(firstDescriptor, transfer->Vector(), 1260 transfer->VectorCount()); 1261 } 1262 1263 // Add to the transfer list 1264 ohci_endpoint_descriptor *endpoint 1265 = (ohci_endpoint_descriptor *)pipe->ControllerCookie(); 1266 1267 MutexLocker endpointLocker(endpoint->lock); 1268 result = _AddPendingTransfer(transfer, endpoint, firstDescriptor, 1269 firstDescriptor, lastDescriptor, directionIn); 1270 if (result < B_OK) { 1271 TRACE_ERROR("failed to add pending transfer\n"); 1272 _FreeDescriptorChain(firstDescriptor); 1273 return result; 1274 } 1275 1276 // Add the descriptor chain to the endpoint 1277 _SwitchEndpointTail(endpoint, firstDescriptor, lastDescriptor); 1278 endpointLocker.Unlock(); 1279 1280 endpoint->flags &= ~OHCI_ENDPOINT_SKIP; 1281 if (pipe->Type() & USB_OBJECT_BULK_PIPE) { 1282 // Tell the controller to process the bulk list 1283 _WriteReg(OHCI_COMMAND_STATUS, OHCI_BULK_LIST_FILLED); 1284 } 1285 1286 return B_OK; 1287 } 1288 1289 1290 status_t 1291 OHCI::_SubmitIsochronousTransfer(Transfer *transfer) 1292 { 1293 TRACE_ERROR("isochronous transfers not implemented\n"); 1294 return B_ERROR; 1295 } 1296 1297 1298 void 1299 OHCI::_SwitchEndpointTail(ohci_endpoint_descriptor *endpoint, 1300 ohci_general_td *first, ohci_general_td *last) 1301 { 1302 // fill in the information of the first descriptor into the current tail 1303 ohci_general_td *tail = (ohci_general_td *)endpoint->tail_logical_descriptor; 1304 tail->flags = first->flags; 1305 tail->buffer_physical = first->buffer_physical; 1306 tail->next_physical_descriptor = first->next_physical_descriptor; 1307 tail->last_physical_byte_address = first->last_physical_byte_address; 1308 tail->buffer_size = first->buffer_size; 1309 tail->buffer_logical = first->buffer_logical; 1310 tail->next_logical_descriptor = first->next_logical_descriptor; 1311 1312 // the first descriptor becomes the new tail 1313 first->flags = 0; 1314 first->buffer_physical = 0; 1315 first->next_physical_descriptor = 0; 1316 first->last_physical_byte_address = 0; 1317 first->buffer_size = 0; 1318 first->buffer_logical = NULL; 1319 first->next_logical_descriptor = NULL; 1320 1321 if (first == last) 1322 _LinkDescriptors(tail, first); 1323 else 1324 _LinkDescriptors(last, first); 1325 1326 // update the endpoint tail pointer to reflect the change 1327 endpoint->tail_logical_descriptor = first; 1328 endpoint->tail_physical_descriptor = (uint32)first->physical_address; 1329 TRACE("switched tail from %p to %p\n", tail, first); 1330 1331 #if 0 1332 _PrintEndpoint(endpoint); 1333 _PrintDescriptorChain(tail); 1334 #endif 1335 } 1336 1337 1338 void 1339 OHCI::_RemoveTransferFromEndpoint(transfer_data *transfer) 1340 { 1341 // The transfer failed and the endpoint was halted. This means that the 1342 // endpoint head pointer might point somewhere into the descriptor chain 1343 // of this transfer. As we do not know if this transfer actually caused 1344 // the halt on the endpoint we have to make sure this is the case. If we 1345 // find the head to point to somewhere into the descriptor chain then 1346 // simply advancing the head pointer to the link of the last transfer 1347 // will bring the endpoint into a valid state again. This operation is 1348 // safe as the endpoint is currently halted and we therefore can change 1349 // the head pointer. 1350 ohci_endpoint_descriptor *endpoint = transfer->endpoint; 1351 ohci_general_td *descriptor = transfer->first_descriptor; 1352 while (descriptor) { 1353 if ((endpoint->head_physical_descriptor & OHCI_ENDPOINT_HEAD_MASK) 1354 == descriptor->physical_address) { 1355 // This descriptor caused the halt. Advance the head pointer. This 1356 // will either move the head to the next valid transfer that can 1357 // then be restarted, or it will move the head to the tail when 1358 // there are no more transfer descriptors. Setting the head will 1359 // also clear the halt state as it is stored in the first bit of 1360 // the head pointer. 1361 endpoint->head_physical_descriptor 1362 = transfer->last_descriptor->next_physical_descriptor; 1363 return; 1364 } 1365 1366 descriptor = (ohci_general_td *)descriptor->next_logical_descriptor; 1367 } 1368 } 1369 1370 1371 ohci_endpoint_descriptor * 1372 OHCI::_AllocateEndpoint() 1373 { 1374 ohci_endpoint_descriptor *endpoint; 1375 void *physicalAddress; 1376 1377 mutex *lock = (mutex *)malloc(sizeof(mutex)); 1378 if (lock == NULL) { 1379 TRACE_ERROR("no memory to allocate endpoint lock\n"); 1380 return NULL; 1381 } 1382 1383 // Allocate memory chunk 1384 if (fStack->AllocateChunk((void **)&endpoint, &physicalAddress, 1385 sizeof(ohci_endpoint_descriptor)) < B_OK) { 1386 TRACE_ERROR("failed to allocate endpoint descriptor\n"); 1387 free(lock); 1388 return NULL; 1389 } 1390 1391 mutex_init(lock, "ohci endpoint lock"); 1392 1393 endpoint->flags = OHCI_ENDPOINT_SKIP; 1394 endpoint->physical_address = (addr_t)physicalAddress; 1395 endpoint->head_physical_descriptor = 0; 1396 endpoint->tail_logical_descriptor = NULL; 1397 endpoint->tail_physical_descriptor = 0; 1398 endpoint->next_logical_endpoint = NULL; 1399 endpoint->next_physical_endpoint = 0; 1400 endpoint->lock = lock; 1401 return endpoint; 1402 } 1403 1404 1405 void 1406 OHCI::_FreeEndpoint(ohci_endpoint_descriptor *endpoint) 1407 { 1408 if (!endpoint) 1409 return; 1410 1411 mutex_destroy(endpoint->lock); 1412 free(endpoint->lock); 1413 1414 fStack->FreeChunk((void *)endpoint, (void *)endpoint->physical_address, 1415 sizeof(ohci_endpoint_descriptor)); 1416 } 1417 1418 1419 status_t 1420 OHCI::_InsertEndpointForPipe(Pipe *pipe) 1421 { 1422 TRACE("inserting endpoint for device %u endpoint %u\n", 1423 pipe->DeviceAddress(), pipe->EndpointAddress()); 1424 1425 ohci_endpoint_descriptor *endpoint = _AllocateEndpoint(); 1426 if (!endpoint) { 1427 TRACE_ERROR("cannot allocate memory for endpoint\n"); 1428 return B_NO_MEMORY; 1429 } 1430 1431 uint32 flags = OHCI_ENDPOINT_SKIP; 1432 1433 // Set up device and endpoint address 1434 flags |= OHCI_ENDPOINT_SET_DEVICE_ADDRESS(pipe->DeviceAddress()) 1435 | OHCI_ENDPOINT_SET_ENDPOINT_NUMBER(pipe->EndpointAddress()); 1436 1437 // Set the direction 1438 switch (pipe->Direction()) { 1439 case Pipe::In: 1440 flags |= OHCI_ENDPOINT_DIRECTION_IN; 1441 break; 1442 1443 case Pipe::Out: 1444 flags |= OHCI_ENDPOINT_DIRECTION_OUT; 1445 break; 1446 1447 case Pipe::Default: 1448 flags |= OHCI_ENDPOINT_DIRECTION_DESCRIPTOR; 1449 break; 1450 1451 default: 1452 TRACE_ERROR("direction unknown\n"); 1453 _FreeEndpoint(endpoint); 1454 return B_ERROR; 1455 } 1456 1457 // Set up the speed 1458 switch (pipe->Speed()) { 1459 case USB_SPEED_LOWSPEED: 1460 flags |= OHCI_ENDPOINT_LOW_SPEED; 1461 break; 1462 1463 case USB_SPEED_FULLSPEED: 1464 flags |= OHCI_ENDPOINT_FULL_SPEED; 1465 break; 1466 1467 default: 1468 TRACE_ERROR("unacceptable speed\n"); 1469 _FreeEndpoint(endpoint); 1470 return B_ERROR; 1471 } 1472 1473 // Set the maximum packet size 1474 flags |= OHCI_ENDPOINT_SET_MAX_PACKET_SIZE(pipe->MaxPacketSize()); 1475 endpoint->flags = flags; 1476 1477 // Add the endpoint to the appropriate list 1478 uint32 type = pipe->Type(); 1479 ohci_endpoint_descriptor *head = NULL; 1480 if (type & USB_OBJECT_CONTROL_PIPE) 1481 head = fDummyControl; 1482 else if (type & USB_OBJECT_BULK_PIPE) 1483 head = fDummyBulk; 1484 else if (type & USB_OBJECT_INTERRUPT_PIPE) 1485 head = _FindInterruptEndpoint(pipe->Interval()); 1486 else if (type & USB_OBJECT_ISO_PIPE) 1487 head = fDummyIsochronous; 1488 else 1489 TRACE_ERROR("unknown pipe type\n"); 1490 1491 if (head == NULL) { 1492 TRACE_ERROR("no list found for endpoint\n"); 1493 _FreeEndpoint(endpoint); 1494 return B_ERROR; 1495 } 1496 1497 // Create (necessary) tail descriptor 1498 if (pipe->Type() & USB_OBJECT_ISO_PIPE) { 1499 // Set the isochronous bit format 1500 endpoint->flags |= OHCI_ENDPOINT_ISOCHRONOUS_FORMAT; 1501 // TODO 1502 _FreeEndpoint(endpoint); 1503 return B_ERROR; 1504 } else { 1505 ohci_general_td *tail = _CreateGeneralDescriptor(0); 1506 tail->flags = 0; 1507 endpoint->tail_logical_descriptor = tail; 1508 endpoint->head_physical_descriptor = tail->physical_address; 1509 endpoint->tail_physical_descriptor = tail->physical_address; 1510 } 1511 1512 if (!_LockEndpoints()) { 1513 if (endpoint->tail_logical_descriptor) { 1514 _FreeGeneralDescriptor( 1515 (ohci_general_td *)endpoint->tail_logical_descriptor); 1516 } 1517 1518 _FreeEndpoint(endpoint); 1519 return B_ERROR; 1520 } 1521 1522 pipe->SetControllerCookie((void *)endpoint); 1523 endpoint->next_logical_endpoint = head->next_logical_endpoint; 1524 endpoint->next_physical_endpoint = head->next_physical_endpoint; 1525 head->next_logical_endpoint = (void *)endpoint; 1526 head->next_physical_endpoint = (uint32)endpoint->physical_address; 1527 1528 _UnlockEndpoints(); 1529 return B_OK; 1530 } 1531 1532 1533 status_t 1534 OHCI::_RemoveEndpointForPipe(Pipe *pipe) 1535 { 1536 TRACE("removing endpoint for device %u endpoint %u\n", 1537 pipe->DeviceAddress(), pipe->EndpointAddress()); 1538 1539 ohci_endpoint_descriptor *endpoint 1540 = (ohci_endpoint_descriptor *)pipe->ControllerCookie(); 1541 if (endpoint == NULL) 1542 return B_OK; 1543 1544 // TODO implement properly, but at least disable it for now 1545 endpoint->flags |= OHCI_ENDPOINT_SKIP; 1546 return B_OK; 1547 } 1548 1549 1550 ohci_endpoint_descriptor * 1551 OHCI::_FindInterruptEndpoint(uint8 interval) 1552 { 1553 uint32 index = 0; 1554 uint32 power = 1; 1555 while (power <= OHCI_BIGGEST_INTERVAL / 2) { 1556 if (power * 2 > interval) 1557 break; 1558 1559 power *= 2; 1560 index++; 1561 } 1562 1563 return fInterruptEndpoints[index]; 1564 } 1565 1566 1567 ohci_general_td * 1568 OHCI::_CreateGeneralDescriptor(size_t bufferSize) 1569 { 1570 ohci_general_td *descriptor; 1571 void *physicalAddress; 1572 1573 if (fStack->AllocateChunk((void **)&descriptor, &physicalAddress, 1574 sizeof(ohci_general_td)) != B_OK) { 1575 TRACE_ERROR("failed to allocate general descriptor\n"); 1576 return NULL; 1577 } 1578 1579 descriptor->physical_address = (addr_t)physicalAddress; 1580 descriptor->next_physical_descriptor = 0; 1581 descriptor->next_logical_descriptor = NULL; 1582 descriptor->buffer_size = bufferSize; 1583 if (bufferSize == 0) { 1584 descriptor->buffer_physical = 0; 1585 descriptor->buffer_logical = NULL; 1586 descriptor->last_physical_byte_address = 0; 1587 return descriptor; 1588 } 1589 1590 if (fStack->AllocateChunk(&descriptor->buffer_logical, 1591 (void **)&descriptor->buffer_physical, bufferSize) != B_OK) { 1592 TRACE_ERROR("failed to allocate space for buffer\n"); 1593 fStack->FreeChunk(descriptor, (void *)descriptor->physical_address, 1594 sizeof(ohci_general_td)); 1595 return NULL; 1596 } 1597 1598 descriptor->last_physical_byte_address 1599 = descriptor->buffer_physical + bufferSize - 1; 1600 return descriptor; 1601 } 1602 1603 1604 void 1605 OHCI::_FreeGeneralDescriptor(ohci_general_td *descriptor) 1606 { 1607 if (!descriptor) 1608 return; 1609 1610 if (descriptor->buffer_logical) { 1611 fStack->FreeChunk(descriptor->buffer_logical, 1612 (void *)descriptor->buffer_physical, descriptor->buffer_size); 1613 } 1614 1615 fStack->FreeChunk((void *)descriptor, (void *)descriptor->physical_address, 1616 sizeof(ohci_general_td)); 1617 } 1618 1619 1620 status_t 1621 OHCI::_CreateDescriptorChain(ohci_general_td **_firstDescriptor, 1622 ohci_general_td **_lastDescriptor, uint32 direction, size_t bufferSize) 1623 { 1624 size_t blockSize = 8192; 1625 int32 descriptorCount = (bufferSize + blockSize - 1) / blockSize; 1626 if (descriptorCount == 0) 1627 descriptorCount = 1; 1628 1629 ohci_general_td *firstDescriptor = NULL; 1630 ohci_general_td *lastDescriptor = *_firstDescriptor; 1631 for (int32 i = 0; i < descriptorCount; i++) { 1632 ohci_general_td *descriptor = _CreateGeneralDescriptor( 1633 min_c(blockSize, bufferSize)); 1634 1635 if (!descriptor) { 1636 _FreeDescriptorChain(firstDescriptor); 1637 return B_NO_MEMORY; 1638 } 1639 1640 descriptor->flags = direction 1641 | OHCI_TD_BUFFER_ROUNDING 1642 | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) 1643 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE) 1644 | OHCI_TD_TOGGLE_CARRY; 1645 1646 // link to previous 1647 if (lastDescriptor) 1648 _LinkDescriptors(lastDescriptor, descriptor); 1649 1650 bufferSize -= blockSize; 1651 lastDescriptor = descriptor; 1652 if (!firstDescriptor) 1653 firstDescriptor = descriptor; 1654 } 1655 1656 *_firstDescriptor = firstDescriptor; 1657 *_lastDescriptor = lastDescriptor; 1658 return B_OK; 1659 } 1660 1661 1662 void 1663 OHCI::_FreeDescriptorChain(ohci_general_td *topDescriptor) 1664 { 1665 ohci_general_td *current = topDescriptor; 1666 ohci_general_td *next = NULL; 1667 1668 while (current) { 1669 next = (ohci_general_td *)current->next_logical_descriptor; 1670 _FreeGeneralDescriptor(current); 1671 current = next; 1672 } 1673 } 1674 1675 1676 size_t 1677 OHCI::_WriteDescriptorChain(ohci_general_td *topDescriptor, iovec *vector, 1678 size_t vectorCount) 1679 { 1680 ohci_general_td *current = topDescriptor; 1681 size_t actualLength = 0; 1682 size_t vectorIndex = 0; 1683 size_t vectorOffset = 0; 1684 size_t bufferOffset = 0; 1685 1686 while (current) { 1687 if (!current->buffer_logical) 1688 break; 1689 1690 while (true) { 1691 size_t length = min_c(current->buffer_size - bufferOffset, 1692 vector[vectorIndex].iov_len - vectorOffset); 1693 1694 TRACE("copying %ld bytes to bufferOffset %ld from" 1695 " vectorOffset %ld at index %ld of %ld\n", length, bufferOffset, 1696 vectorOffset, vectorIndex, vectorCount); 1697 memcpy((uint8 *)current->buffer_logical + bufferOffset, 1698 (uint8 *)vector[vectorIndex].iov_base + vectorOffset, length); 1699 1700 actualLength += length; 1701 vectorOffset += length; 1702 bufferOffset += length; 1703 1704 if (vectorOffset >= vector[vectorIndex].iov_len) { 1705 if (++vectorIndex >= vectorCount) { 1706 TRACE("wrote descriptor chain (%ld bytes, no" 1707 " more vectors)\n", actualLength); 1708 return actualLength; 1709 } 1710 1711 vectorOffset = 0; 1712 } 1713 1714 if (bufferOffset >= current->buffer_size) { 1715 bufferOffset = 0; 1716 break; 1717 } 1718 } 1719 1720 if (!current->next_logical_descriptor) 1721 break; 1722 1723 current = (ohci_general_td *)current->next_logical_descriptor; 1724 } 1725 1726 TRACE("wrote descriptor chain (%ld bytes)\n", actualLength); 1727 return actualLength; 1728 } 1729 1730 1731 size_t 1732 OHCI::_ReadDescriptorChain(ohci_general_td *topDescriptor, iovec *vector, 1733 size_t vectorCount) 1734 { 1735 ohci_general_td *current = topDescriptor; 1736 size_t actualLength = 0; 1737 size_t vectorIndex = 0; 1738 size_t vectorOffset = 0; 1739 size_t bufferOffset = 0; 1740 1741 while (current && OHCI_TD_GET_CONDITION_CODE(current->flags) 1742 != OHCI_TD_CONDITION_NOT_ACCESSED) { 1743 if (!current->buffer_logical) 1744 break; 1745 1746 size_t bufferSize = current->buffer_size; 1747 if (current->buffer_physical != 0) { 1748 bufferSize -= current->last_physical_byte_address 1749 - current->buffer_physical + 1; 1750 } 1751 1752 while (true) { 1753 size_t length = min_c(bufferSize - bufferOffset, 1754 vector[vectorIndex].iov_len - vectorOffset); 1755 1756 TRACE("copying %ld bytes to vectorOffset %ld from" 1757 " bufferOffset %ld at index %ld of %ld\n", length, vectorOffset, 1758 bufferOffset, vectorIndex, vectorCount); 1759 memcpy((uint8 *)vector[vectorIndex].iov_base + vectorOffset, 1760 (uint8 *)current->buffer_logical + bufferOffset, length); 1761 1762 actualLength += length; 1763 vectorOffset += length; 1764 bufferOffset += length; 1765 1766 if (vectorOffset >= vector[vectorIndex].iov_len) { 1767 if (++vectorIndex >= vectorCount) { 1768 TRACE("read descriptor chain (%ld bytes, no more vectors)\n", 1769 actualLength); 1770 return actualLength; 1771 } 1772 1773 vectorOffset = 0; 1774 } 1775 1776 if (bufferOffset >= bufferSize) { 1777 bufferOffset = 0; 1778 break; 1779 } 1780 } 1781 1782 current = (ohci_general_td *)current->next_logical_descriptor; 1783 } 1784 1785 TRACE("read descriptor chain (%ld bytes)\n", actualLength); 1786 return actualLength; 1787 } 1788 1789 1790 size_t 1791 OHCI::_ReadActualLength(ohci_general_td *topDescriptor) 1792 { 1793 ohci_general_td *current = topDescriptor; 1794 size_t actualLength = 0; 1795 1796 while (current && OHCI_TD_GET_CONDITION_CODE(current->flags) 1797 != OHCI_TD_CONDITION_NOT_ACCESSED) { 1798 size_t length = current->buffer_size; 1799 if (current->buffer_physical != 0) { 1800 length -= current->last_physical_byte_address 1801 - current->buffer_physical + 1; 1802 } 1803 1804 actualLength += length; 1805 current = (ohci_general_td *)current->next_logical_descriptor; 1806 } 1807 1808 TRACE("read actual length (%ld bytes)\n", actualLength); 1809 return actualLength; 1810 } 1811 1812 1813 void 1814 OHCI::_LinkDescriptors(ohci_general_td *first, ohci_general_td *second) 1815 { 1816 first->next_physical_descriptor = second->physical_address; 1817 first->next_logical_descriptor = second; 1818 } 1819 1820 1821 ohci_isochronous_td * 1822 OHCI::_CreateIsochronousDescriptor() 1823 { 1824 // TODO 1825 return NULL; 1826 } 1827 1828 1829 void 1830 OHCI::_FreeIsochronousDescriptor(ohci_isochronous_td *descriptor) 1831 { 1832 // TODO 1833 } 1834 1835 1836 bool 1837 OHCI::_LockEndpoints() 1838 { 1839 return (mutex_lock(&fEndpointLock) == B_OK); 1840 } 1841 1842 1843 void 1844 OHCI::_UnlockEndpoints() 1845 { 1846 mutex_unlock(&fEndpointLock); 1847 } 1848 1849 1850 inline void 1851 OHCI::_WriteReg(uint32 reg, uint32 value) 1852 { 1853 *(volatile uint32 *)(fOperationalRegisters + reg) = value; 1854 } 1855 1856 1857 inline uint32 1858 OHCI::_ReadReg(uint32 reg) 1859 { 1860 return *(volatile uint32 *)(fOperationalRegisters + reg); 1861 } 1862 1863 1864 void 1865 OHCI::_PrintEndpoint(ohci_endpoint_descriptor *endpoint) 1866 { 1867 TRACE_ALWAYS("endpoint %p\n", endpoint); 1868 dprintf("\tflags........... 0x%08lx\n", endpoint->flags); 1869 dprintf("\ttail_physical... 0x%08lx\n", endpoint->tail_physical_descriptor); 1870 dprintf("\thead_physical... 0x%08lx\n", endpoint->head_physical_descriptor); 1871 dprintf("\tnext_physical... 0x%08lx\n", endpoint->next_physical_endpoint); 1872 dprintf("\tphysical........ 0x%08lx\n", endpoint->physical_address); 1873 dprintf("\ttail_logical.... %p\n", endpoint->tail_logical_descriptor); 1874 dprintf("\tnext_logical.... %p\n", endpoint->next_logical_endpoint); 1875 } 1876 1877 1878 void 1879 OHCI::_PrintDescriptorChain(ohci_general_td *topDescriptor) 1880 { 1881 while (topDescriptor) { 1882 TRACE_ALWAYS("descriptor %p\n", topDescriptor); 1883 dprintf("\tflags........... 0x%08lx\n", topDescriptor->flags); 1884 dprintf("\tbuffer_physical. 0x%08lx\n", topDescriptor->buffer_physical); 1885 dprintf("\tnext_physical... 0x%08lx\n", topDescriptor->next_physical_descriptor); 1886 dprintf("\tlast_byte....... 0x%08lx\n", topDescriptor->last_physical_byte_address); 1887 dprintf("\tphysical........ 0x%08lx\n", topDescriptor->physical_address); 1888 dprintf("\tbuffer_size..... %lu\n", topDescriptor->buffer_size); 1889 dprintf("\tbuffer_logical.. %p\n", topDescriptor->buffer_logical); 1890 dprintf("\tnext_logical.... %p\n", topDescriptor->next_logical_descriptor); 1891 1892 topDescriptor = (ohci_general_td *)topDescriptor->next_logical_descriptor; 1893 } 1894 } 1895