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