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