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