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