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