1 /* 2 * Copyright 2005-2013, 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 * Siarzhuk Zharski <imker@gmx.li> 10 */ 11 12 13 #include <stdio.h> 14 15 #include <module.h> 16 #include <bus/PCI.h> 17 #include <USB3.h> 18 #include <KernelExport.h> 19 #include <util/AutoLock.h> 20 21 #include "ohci.h" 22 23 24 #define CALLED(x...) TRACE_MODULE("CALLED %s\n", __PRETTY_FUNCTION__) 25 26 #define USB_MODULE_NAME "ohci" 27 28 device_manager_info* gDeviceManager; 29 static usb_for_controller_interface* gUSB; 30 31 32 #define OHCI_PCI_DEVICE_MODULE_NAME "busses/usb/ohci/pci/driver_v1" 33 #define OHCI_PCI_USB_BUS_MODULE_NAME "busses/usb/ohci/device_v1" 34 35 36 typedef struct { 37 OHCI* ohci; 38 pci_device_module_info* pci; 39 pci_device* device; 40 41 pci_info pciinfo; 42 43 device_node* node; 44 device_node* driver_node; 45 } ohci_pci_sim_info; 46 47 48 // #pragma mark - 49 50 51 static status_t 52 init_bus(device_node* node, void** bus_cookie) 53 { 54 CALLED(); 55 56 driver_module_info* driver; 57 ohci_pci_sim_info* bus; 58 device_node* parent = gDeviceManager->get_parent_node(node); 59 gDeviceManager->get_driver(parent, &driver, (void**)&bus); 60 gDeviceManager->put_node(parent); 61 62 Stack *stack; 63 if (gUSB->get_stack((void**)&stack) != B_OK) 64 return B_ERROR; 65 66 OHCI *ohci = new(std::nothrow) OHCI(&bus->pciinfo, bus->pci, bus->device, stack, node); 67 if (ohci == NULL) { 68 return B_NO_MEMORY; 69 } 70 71 if (ohci->InitCheck() < B_OK) { 72 TRACE_MODULE_ERROR("bus failed init check\n"); 73 delete ohci; 74 return B_ERROR; 75 } 76 77 if (ohci->Start() != B_OK) { 78 delete ohci; 79 return B_ERROR; 80 } 81 82 *bus_cookie = ohci; 83 84 return B_OK; 85 } 86 87 88 static void 89 uninit_bus(void* bus_cookie) 90 { 91 CALLED(); 92 OHCI* ohci = (OHCI*)bus_cookie; 93 delete ohci; 94 } 95 96 97 static status_t 98 register_child_devices(void* cookie) 99 { 100 CALLED(); 101 ohci_pci_sim_info* bus = (ohci_pci_sim_info*)cookie; 102 device_node* node = bus->driver_node; 103 104 char prettyName[25]; 105 sprintf(prettyName, "OHCI Controller %" B_PRIu16, 0); 106 107 device_attr attrs[] = { 108 // properties of this controller for the usb bus manager 109 { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, 110 { .string = prettyName }}, 111 { B_DEVICE_FIXED_CHILD, B_STRING_TYPE, 112 { .string = USB_FOR_CONTROLLER_MODULE_NAME }}, 113 114 // private data to identify the device 115 { NULL } 116 }; 117 118 return gDeviceManager->register_node(node, OHCI_PCI_USB_BUS_MODULE_NAME, 119 attrs, NULL, NULL); 120 } 121 122 123 static status_t 124 init_device(device_node* node, void** device_cookie) 125 { 126 CALLED(); 127 ohci_pci_sim_info* bus = (ohci_pci_sim_info*)calloc(1, 128 sizeof(ohci_pci_sim_info)); 129 if (bus == NULL) 130 return B_NO_MEMORY; 131 132 pci_device_module_info* pci; 133 pci_device* device; 134 { 135 device_node* pciParent = gDeviceManager->get_parent_node(node); 136 gDeviceManager->get_driver(pciParent, (driver_module_info**)&pci, 137 (void**)&device); 138 gDeviceManager->put_node(pciParent); 139 } 140 141 bus->pci = pci; 142 bus->device = device; 143 bus->driver_node = node; 144 145 pci_info *pciInfo = &bus->pciinfo; 146 pci->get_pci_info(device, pciInfo); 147 148 *device_cookie = bus; 149 return B_OK; 150 } 151 152 153 static void 154 uninit_device(void* device_cookie) 155 { 156 CALLED(); 157 ohci_pci_sim_info* bus = (ohci_pci_sim_info*)device_cookie; 158 free(bus); 159 } 160 161 162 static status_t 163 register_device(device_node* parent) 164 { 165 CALLED(); 166 device_attr attrs[] = { 167 {B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {.string = "OHCI PCI"}}, 168 {} 169 }; 170 171 return gDeviceManager->register_node(parent, 172 OHCI_PCI_DEVICE_MODULE_NAME, attrs, NULL, NULL); 173 } 174 175 176 static float 177 supports_device(device_node* parent) 178 { 179 CALLED(); 180 const char* bus; 181 uint16 type, subType, api; 182 183 // make sure parent is a OHCI PCI device node 184 if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false) 185 < B_OK) { 186 return -1; 187 } 188 189 if (strcmp(bus, "pci") != 0) 190 return 0.0f; 191 192 if (gDeviceManager->get_attr_uint16(parent, B_DEVICE_SUB_TYPE, &subType, 193 false) < B_OK 194 || gDeviceManager->get_attr_uint16(parent, B_DEVICE_TYPE, &type, 195 false) < B_OK 196 || gDeviceManager->get_attr_uint16(parent, B_DEVICE_INTERFACE, &api, 197 false) < B_OK) { 198 TRACE_MODULE("Could not find type/subtype/interface attributes\n"); 199 return -1; 200 } 201 202 if (type == PCI_serial_bus && subType == PCI_usb && api == PCI_usb_ohci) { 203 pci_device_module_info* pci; 204 pci_device* device; 205 gDeviceManager->get_driver(parent, (driver_module_info**)&pci, 206 (void**)&device); 207 TRACE_MODULE("OHCI Device found!\n"); 208 209 return 0.8f; 210 } 211 212 return 0.0f; 213 } 214 215 216 module_dependency module_dependencies[] = { 217 { USB_FOR_CONTROLLER_MODULE_NAME, (module_info**)&gUSB }, 218 { B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&gDeviceManager }, 219 {} 220 }; 221 222 223 static usb_bus_interface gOHCIPCIDeviceModule = { 224 { 225 { 226 OHCI_PCI_USB_BUS_MODULE_NAME, 227 0, 228 NULL 229 }, 230 NULL, // supports device 231 NULL, // register device 232 init_bus, 233 uninit_bus, 234 NULL, // register child devices 235 NULL, // rescan 236 NULL, // device removed 237 }, 238 }; 239 240 // Root device that binds to the PCI bus. It will register an usb_bus_interface 241 // node for each device. 242 static driver_module_info sOHCIDevice = { 243 { 244 OHCI_PCI_DEVICE_MODULE_NAME, 245 0, 246 NULL 247 }, 248 supports_device, 249 register_device, 250 init_device, 251 uninit_device, 252 register_child_devices, 253 NULL, // rescan 254 NULL, // device removed 255 }; 256 257 module_info* modules[] = { 258 (module_info* )&sOHCIDevice, 259 (module_info* )&gOHCIPCIDeviceModule, 260 NULL 261 }; 262 263 264 // 265 // #pragma mark - 266 // 267 268 269 OHCI::OHCI(pci_info *info, pci_device_module_info* pci, pci_device* device, Stack *stack, 270 device_node* node) 271 : BusManager(stack, node), 272 fPCIInfo(info), 273 fPci(pci), 274 fDevice(device), 275 fStack(stack), 276 fOperationalRegisters(NULL), 277 fRegisterArea(-1), 278 fHccaArea(-1), 279 fHcca(NULL), 280 fInterruptEndpoints(NULL), 281 fDummyControl(NULL), 282 fDummyBulk(NULL), 283 fDummyIsochronous(NULL), 284 fFirstTransfer(NULL), 285 fLastTransfer(NULL), 286 fFinishTransfersSem(-1), 287 fFinishThread(-1), 288 fStopFinishThread(false), 289 fProcessingPipe(NULL), 290 fFrameBandwidth(NULL), 291 fRootHub(NULL), 292 fRootHubAddress(0), 293 fPortCount(0), 294 fIRQ(0), 295 fUseMSI(false) 296 { 297 if (!fInitOK) { 298 TRACE_ERROR("bus manager failed to init\n"); 299 return; 300 } 301 302 TRACE("constructing new OHCI host controller driver\n"); 303 fInitOK = false; 304 305 mutex_init(&fEndpointLock, "ohci endpoint lock"); 306 307 // enable busmaster and memory mapped access 308 uint16 command = fPci->read_pci_config(fDevice, PCI_command, 2); 309 command &= ~PCI_command_io; 310 command |= PCI_command_master | PCI_command_memory; 311 312 fPci->write_pci_config(fDevice, PCI_command, 2, command); 313 314 // map the registers 315 uint32 offset = fPci->read_pci_config(fDevice, PCI_base_registers, 4); 316 offset &= PCI_address_memory_32_mask; 317 TRACE_ALWAYS("iospace offset: 0x%" B_PRIx32 "\n", offset); 318 fRegisterArea = map_physical_memory("OHCI memory mapped registers", 319 offset, B_PAGE_SIZE, B_ANY_KERNEL_BLOCK_ADDRESS, 320 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, 321 (void **)&fOperationalRegisters); 322 if (fRegisterArea < B_OK) { 323 TRACE_ERROR("failed to map register memory\n"); 324 return; 325 } 326 327 TRACE("mapped operational registers: %p\n", fOperationalRegisters); 328 329 // Check the revision of the controller, which should be 10h 330 uint32 revision = _ReadReg(OHCI_REVISION) & 0xff; 331 TRACE("version %" B_PRId32 ".%" B_PRId32 "%s\n", 332 OHCI_REVISION_HIGH(revision), OHCI_REVISION_LOW(revision), 333 OHCI_REVISION_LEGACY(revision) ? ", legacy support" : ""); 334 335 if (OHCI_REVISION_HIGH(revision) != 1 || OHCI_REVISION_LOW(revision) != 0) { 336 TRACE_ERROR("unsupported OHCI revision\n"); 337 return; 338 } 339 340 phys_addr_t hccaPhysicalAddress; 341 fHccaArea = fStack->AllocateArea((void **)&fHcca, &hccaPhysicalAddress, 342 sizeof(ohci_hcca), "USB OHCI Host Controller Communication Area"); 343 344 if (fHccaArea < B_OK) { 345 TRACE_ERROR("unable to create the HCCA block area\n"); 346 return; 347 } 348 349 memset(fHcca, 0, sizeof(ohci_hcca)); 350 351 // Set Up Host controller 352 // Dummy endpoints 353 fDummyControl = _AllocateEndpoint(); 354 if (!fDummyControl) 355 return; 356 357 fDummyBulk = _AllocateEndpoint(); 358 if (!fDummyBulk) { 359 _FreeEndpoint(fDummyControl); 360 return; 361 } 362 363 fDummyIsochronous = _AllocateEndpoint(); 364 if (!fDummyIsochronous) { 365 _FreeEndpoint(fDummyControl); 366 _FreeEndpoint(fDummyBulk); 367 return; 368 } 369 370 // Static endpoints that get linked in the HCCA 371 fInterruptEndpoints = new(std::nothrow) 372 ohci_endpoint_descriptor *[OHCI_STATIC_ENDPOINT_COUNT]; 373 if (!fInterruptEndpoints) { 374 TRACE_ERROR("failed to allocate memory for interrupt endpoints\n"); 375 _FreeEndpoint(fDummyControl); 376 _FreeEndpoint(fDummyBulk); 377 _FreeEndpoint(fDummyIsochronous); 378 return; 379 } 380 381 for (int32 i = 0; i < OHCI_STATIC_ENDPOINT_COUNT; i++) { 382 fInterruptEndpoints[i] = _AllocateEndpoint(); 383 if (!fInterruptEndpoints[i]) { 384 TRACE_ERROR("failed to allocate interrupt endpoint %" B_PRId32 "\n", 385 i); 386 while (--i >= 0) 387 _FreeEndpoint(fInterruptEndpoints[i]); 388 _FreeEndpoint(fDummyBulk); 389 _FreeEndpoint(fDummyControl); 390 _FreeEndpoint(fDummyIsochronous); 391 return; 392 } 393 } 394 395 // build flat tree so that at each of the static interrupt endpoints 396 // fInterruptEndpoints[i] == interrupt endpoint for interval 2^i 397 uint32 interval = OHCI_BIGGEST_INTERVAL; 398 uint32 intervalIndex = OHCI_STATIC_ENDPOINT_COUNT - 1; 399 while (interval > 1) { 400 uint32 insertIndex = interval / 2; 401 while (insertIndex < OHCI_BIGGEST_INTERVAL) { 402 fHcca->interrupt_table[insertIndex] 403 = fInterruptEndpoints[intervalIndex]->physical_address; 404 insertIndex += interval; 405 } 406 407 intervalIndex--; 408 interval /= 2; 409 } 410 411 // setup the empty slot in the list and linking of all -> first 412 fHcca->interrupt_table[0] = fInterruptEndpoints[0]->physical_address; 413 for (int32 i = 1; i < OHCI_STATIC_ENDPOINT_COUNT; i++) { 414 fInterruptEndpoints[i]->next_physical_endpoint 415 = fInterruptEndpoints[0]->physical_address; 416 fInterruptEndpoints[i]->next_logical_endpoint 417 = fInterruptEndpoints[0]; 418 } 419 420 // Now link the first endpoint to the isochronous endpoint 421 fInterruptEndpoints[0]->next_physical_endpoint 422 = fDummyIsochronous->physical_address; 423 424 // When the handover from SMM takes place, all interrupts are routed to the 425 // OS. As we don't yet have an interrupt handler installed at this point, 426 // this may cause interrupt storms if the firmware does not disable the 427 // interrupts during handover. Therefore we disable interrupts before 428 // requesting ownership. We have to keep the ownership change interrupt 429 // enabled though, as otherwise the SMM will not be notified of the 430 // ownership change request we trigger below. 431 _WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTERRUPTS & 432 ~OHCI_OWNERSHIP_CHANGE) ; 433 434 // Determine in what context we are running (Kindly copied from FreeBSD) 435 uint32 control = _ReadReg(OHCI_CONTROL); 436 if (control & OHCI_INTERRUPT_ROUTING) { 437 TRACE_ALWAYS("smm is in control of the host controller\n"); 438 uint32 status = _ReadReg(OHCI_COMMAND_STATUS); 439 _WriteReg(OHCI_COMMAND_STATUS, status | OHCI_OWNERSHIP_CHANGE_REQUEST); 440 for (uint32 i = 0; i < 100 && (control & OHCI_INTERRUPT_ROUTING); i++) { 441 snooze(1000); 442 control = _ReadReg(OHCI_CONTROL); 443 } 444 445 if ((control & OHCI_INTERRUPT_ROUTING) != 0) { 446 TRACE_ERROR("smm does not respond.\n"); 447 448 // TODO: Enable this reset as soon as the non-specified 449 // reset a few lines later is replaced by a better solution. 450 //_WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET); 451 //snooze(USB_DELAY_BUS_RESET); 452 } else 453 TRACE_ALWAYS("ownership change successful\n"); 454 } else { 455 TRACE("cold started\n"); 456 snooze(USB_DELAY_BUS_RESET); 457 } 458 459 // TODO: This reset delays system boot time. It should not be necessary 460 // according to the OHCI spec, but without it some controllers don't start. 461 _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET); 462 snooze(USB_DELAY_BUS_RESET); 463 464 // We now own the host controller and the bus has been reset 465 uint32 frameInterval = _ReadReg(OHCI_FRAME_INTERVAL); 466 uint32 intervalValue = OHCI_GET_INTERVAL_VALUE(frameInterval); 467 468 _WriteReg(OHCI_COMMAND_STATUS, OHCI_HOST_CONTROLLER_RESET); 469 // Nominal time for a reset is 10 us 470 uint32 reset = 0; 471 for (uint32 i = 0; i < 10; i++) { 472 spin(10); 473 reset = _ReadReg(OHCI_COMMAND_STATUS) & OHCI_HOST_CONTROLLER_RESET; 474 if (reset == 0) 475 break; 476 } 477 478 if (reset) { 479 TRACE_ERROR("error resetting the host controller (timeout)\n"); 480 return; 481 } 482 483 // The controller is now in SUSPEND state, we have 2ms to go OPERATIONAL. 484 485 // Set up host controller register 486 _WriteReg(OHCI_HCCA, (uint32)hccaPhysicalAddress); 487 _WriteReg(OHCI_CONTROL_HEAD_ED, (uint32)fDummyControl->physical_address); 488 _WriteReg(OHCI_BULK_HEAD_ED, (uint32)fDummyBulk->physical_address); 489 // Switch on desired functional features 490 control = _ReadReg(OHCI_CONTROL); 491 control &= ~(OHCI_CONTROL_BULK_SERVICE_RATIO_MASK | OHCI_ENABLE_LIST 492 | OHCI_HC_FUNCTIONAL_STATE_MASK | OHCI_INTERRUPT_ROUTING); 493 control |= OHCI_ENABLE_LIST | OHCI_CONTROL_BULK_RATIO_1_4 494 | OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL; 495 // And finally start the controller 496 _WriteReg(OHCI_CONTROL, control); 497 498 // The controller is now OPERATIONAL. 499 frameInterval = (_ReadReg(OHCI_FRAME_INTERVAL) & OHCI_FRAME_INTERVAL_TOGGLE) 500 ^ OHCI_FRAME_INTERVAL_TOGGLE; 501 frameInterval |= OHCI_FSMPS(intervalValue) | intervalValue; 502 _WriteReg(OHCI_FRAME_INTERVAL, frameInterval); 503 // 90% periodic 504 uint32 periodic = OHCI_PERIODIC(intervalValue); 505 _WriteReg(OHCI_PERIODIC_START, periodic); 506 507 // Fiddle the No Over Current Protection bit to avoid chip bug 508 uint32 desca = _ReadReg(OHCI_RH_DESCRIPTOR_A); 509 _WriteReg(OHCI_RH_DESCRIPTOR_A, desca | OHCI_RH_NO_OVER_CURRENT_PROTECTION); 510 _WriteReg(OHCI_RH_STATUS, OHCI_RH_LOCAL_POWER_STATUS_CHANGE); 511 snooze(OHCI_ENABLE_POWER_DELAY); 512 _WriteReg(OHCI_RH_DESCRIPTOR_A, desca); 513 514 // The AMD756 requires a delay before re-reading the register, 515 // otherwise it will occasionally report 0 ports. 516 uint32 numberOfPorts = 0; 517 for (uint32 i = 0; i < 10 && numberOfPorts == 0; i++) { 518 snooze(OHCI_READ_DESC_DELAY); 519 uint32 descriptor = _ReadReg(OHCI_RH_DESCRIPTOR_A); 520 numberOfPorts = OHCI_RH_GET_PORT_COUNT(descriptor); 521 } 522 if (numberOfPorts > OHCI_MAX_PORT_COUNT) 523 numberOfPorts = OHCI_MAX_PORT_COUNT; 524 fPortCount = numberOfPorts; 525 TRACE("port count is %d\n", fPortCount); 526 527 // Create the array that will keep bandwidth information 528 fFrameBandwidth = new(std::nothrow) uint16[NUMBER_OF_FRAMES]; 529 530 for (int32 i = 0; i < NUMBER_OF_FRAMES; i++) 531 fFrameBandwidth[i] = MAX_AVAILABLE_BANDWIDTH; 532 533 // Create semaphore the finisher thread will wait for 534 fFinishTransfersSem = create_sem(0, "OHCI Finish Transfers"); 535 if (fFinishTransfersSem < B_OK) { 536 TRACE_ERROR("failed to create semaphore\n"); 537 return; 538 } 539 540 // Create the finisher service thread 541 fFinishThread = spawn_kernel_thread(_FinishThread, "ohci finish thread", 542 B_URGENT_DISPLAY_PRIORITY, (void *)this); 543 resume_thread(fFinishThread); 544 545 // Find the right interrupt vector, using MSIs if available. 546 fIRQ = fPCIInfo->u.h0.interrupt_line; 547 if (fIRQ == 0xFF) 548 fIRQ = 0; 549 550 if (fPci->get_msi_count(fDevice) >= 1) { 551 uint32 msiVector = 0; 552 if (fPci->configure_msi(fDevice, 1, &msiVector) == B_OK 553 && fPci->enable_msi(fDevice) == B_OK) { 554 TRACE_ALWAYS("using message signaled interrupts\n"); 555 fIRQ = msiVector; 556 fUseMSI = true; 557 } 558 } 559 560 if (fIRQ == 0) { 561 TRACE_MODULE_ERROR("device PCI:%d:%d:%d was assigned an invalid IRQ\n", 562 fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function); 563 return; 564 } 565 566 // Install the interrupt handler 567 TRACE("installing interrupt handler\n"); 568 install_io_interrupt_handler(fIRQ, _InterruptHandler, (void *)this, 0); 569 570 // Enable interesting interrupts now that the handler is in place 571 _WriteReg(OHCI_INTERRUPT_ENABLE, OHCI_NORMAL_INTERRUPTS 572 | OHCI_MASTER_INTERRUPT_ENABLE); 573 574 TRACE("OHCI host controller driver constructed\n"); 575 fInitOK = true; 576 } 577 578 579 OHCI::~OHCI() 580 { 581 int32 result = 0; 582 fStopFinishThread = true; 583 delete_sem(fFinishTransfersSem); 584 wait_for_thread(fFinishThread, &result); 585 586 remove_io_interrupt_handler(fIRQ, _InterruptHandler, (void *)this); 587 588 _LockEndpoints(); 589 mutex_destroy(&fEndpointLock); 590 591 if (fHccaArea >= B_OK) 592 delete_area(fHccaArea); 593 if (fRegisterArea >= B_OK) 594 delete_area(fRegisterArea); 595 596 _FreeEndpoint(fDummyControl); 597 _FreeEndpoint(fDummyBulk); 598 _FreeEndpoint(fDummyIsochronous); 599 600 if (fInterruptEndpoints != NULL) { 601 for (int i = 0; i < OHCI_STATIC_ENDPOINT_COUNT; i++) 602 _FreeEndpoint(fInterruptEndpoints[i]); 603 } 604 605 delete [] fFrameBandwidth; 606 delete [] fInterruptEndpoints; 607 delete fRootHub; 608 609 if (fUseMSI) { 610 fPci->disable_msi(fDevice); 611 fPci->unconfigure_msi(fDevice); 612 } 613 } 614 615 616 status_t 617 OHCI::Start() 618 { 619 TRACE("starting OHCI host controller\n"); 620 621 uint32 control = _ReadReg(OHCI_CONTROL); 622 if ((control & OHCI_HC_FUNCTIONAL_STATE_MASK) 623 != OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL) { 624 TRACE_ERROR("controller not started (0x%08" B_PRIx32 ")!\n", control); 625 return B_ERROR; 626 } else 627 TRACE("controller is operational!\n"); 628 629 fRootHubAddress = AllocateAddress(); 630 fRootHub = new(std::nothrow) OHCIRootHub(RootObject(), fRootHubAddress); 631 if (!fRootHub) { 632 TRACE_ERROR("no memory to allocate root hub\n"); 633 return B_NO_MEMORY; 634 } 635 636 if (fRootHub->InitCheck() < B_OK) { 637 TRACE_ERROR("root hub failed init check\n"); 638 return B_ERROR; 639 } 640 641 SetRootHub(fRootHub); 642 643 fRootHub->RegisterNode(Node()); 644 645 TRACE_ALWAYS("successfully started the controller\n"); 646 return BusManager::Start(); 647 } 648 649 650 status_t 651 OHCI::SubmitTransfer(Transfer *transfer) 652 { 653 // short circuit the root hub 654 if (transfer->TransferPipe()->DeviceAddress() == fRootHubAddress) 655 return fRootHub->ProcessTransfer(this, transfer); 656 657 uint32 type = transfer->TransferPipe()->Type(); 658 if (type & USB_OBJECT_CONTROL_PIPE) { 659 TRACE("submitting request\n"); 660 return _SubmitRequest(transfer); 661 } 662 663 if ((type & USB_OBJECT_BULK_PIPE) || (type & USB_OBJECT_INTERRUPT_PIPE)) { 664 TRACE("submitting %s transfer\n", 665 (type & USB_OBJECT_BULK_PIPE) ? "bulk" : "interrupt"); 666 return _SubmitTransfer(transfer); 667 } 668 669 if (type & USB_OBJECT_ISO_PIPE) { 670 TRACE("submitting isochronous transfer\n"); 671 return _SubmitIsochronousTransfer(transfer); 672 } 673 674 TRACE_ERROR("tried to submit transfer for unknown pipe type %" B_PRIu32 "\n", 675 type); 676 return B_ERROR; 677 } 678 679 680 status_t 681 OHCI::CancelQueuedTransfers(Pipe *pipe, bool force) 682 { 683 if (!Lock()) 684 return B_ERROR; 685 686 struct transfer_entry { 687 Transfer * transfer; 688 transfer_entry * next; 689 }; 690 691 transfer_entry *list = NULL; 692 transfer_data *current = fFirstTransfer; 693 while (current) { 694 if (current->transfer && current->transfer->TransferPipe() == pipe) { 695 // Check if the skip bit is already set 696 if (!(current->endpoint->flags & OHCI_ENDPOINT_SKIP)) { 697 current->endpoint->flags |= OHCI_ENDPOINT_SKIP; 698 // In case the controller is processing 699 // this endpoint, wait for it to finish 700 snooze(1000); 701 } 702 703 // Clear the endpoint 704 current->endpoint->head_physical_descriptor 705 = current->endpoint->tail_physical_descriptor; 706 707 if (!force) { 708 if (pipe->Type() & USB_OBJECT_ISO_PIPE) { 709 ohci_isochronous_td *descriptor 710 = (ohci_isochronous_td *)current->first_descriptor; 711 while (descriptor) { 712 uint16 frame = OHCI_ITD_GET_STARTING_FRAME( 713 descriptor->flags); 714 _ReleaseIsochronousBandwidth(frame, 715 OHCI_ITD_GET_FRAME_COUNT(descriptor->flags)); 716 if (descriptor 717 == (ohci_isochronous_td*)current->last_descriptor) 718 // this is the last ITD of the transfer 719 break; 720 721 descriptor 722 = (ohci_isochronous_td *) 723 descriptor->next_done_descriptor; 724 } 725 } 726 727 // If the transfer is canceled by force, the one causing the 728 // cancel is probably not the one who initiated the transfer 729 // and the callback is likely not safe anymore 730 transfer_entry *entry 731 = (transfer_entry *)malloc(sizeof(transfer_entry)); 732 if (entry != NULL) { 733 entry->transfer = current->transfer; 734 current->transfer = NULL; 735 entry->next = list; 736 list = entry; 737 } 738 } 739 current->canceled = true; 740 } 741 current = current->link; 742 } 743 744 Unlock(); 745 746 while (list != NULL) { 747 transfer_entry *next = list->next; 748 list->transfer->Finished(B_CANCELED, 0); 749 delete list->transfer; 750 free(list); 751 list = next; 752 } 753 754 // wait for any transfers that might have made it before canceling 755 while (fProcessingPipe == pipe) 756 snooze(1000); 757 758 // notify the finisher so it can clean up the canceled transfers 759 release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE); 760 return B_OK; 761 } 762 763 764 status_t 765 OHCI::NotifyPipeChange(Pipe *pipe, usb_change change) 766 { 767 TRACE("pipe change %d for pipe %p\n", change, pipe); 768 if (pipe->DeviceAddress() == fRootHubAddress) { 769 // no need to insert/remove endpoint descriptors for the root hub 770 return B_OK; 771 } 772 773 switch (change) { 774 case USB_CHANGE_CREATED: 775 return _InsertEndpointForPipe(pipe); 776 777 case USB_CHANGE_DESTROYED: 778 return _RemoveEndpointForPipe(pipe); 779 780 case USB_CHANGE_PIPE_POLICY_CHANGED: 781 TRACE("pipe policy changing unhandled!\n"); 782 break; 783 784 default: 785 TRACE_ERROR("unknown pipe change!\n"); 786 return B_ERROR; 787 } 788 789 return B_OK; 790 } 791 792 793 status_t 794 OHCI::GetPortStatus(uint8 index, usb_port_status *status) 795 { 796 if (index >= fPortCount) { 797 TRACE_ERROR("get port status for invalid port %u\n", index); 798 return B_BAD_INDEX; 799 } 800 801 status->status = status->change = 0; 802 uint32 portStatus = _ReadReg(OHCI_RH_PORT_STATUS(index)); 803 804 // status 805 if (portStatus & OHCI_RH_PORTSTATUS_CCS) 806 status->status |= PORT_STATUS_CONNECTION; 807 if (portStatus & OHCI_RH_PORTSTATUS_PES) 808 status->status |= PORT_STATUS_ENABLE; 809 if (portStatus & OHCI_RH_PORTSTATUS_PSS) 810 status->status |= PORT_STATUS_SUSPEND; 811 if (portStatus & OHCI_RH_PORTSTATUS_POCI) 812 status->status |= PORT_STATUS_OVER_CURRENT; 813 if (portStatus & OHCI_RH_PORTSTATUS_PRS) 814 status->status |= PORT_STATUS_RESET; 815 if (portStatus & OHCI_RH_PORTSTATUS_PPS) 816 status->status |= PORT_STATUS_POWER; 817 if (portStatus & OHCI_RH_PORTSTATUS_LSDA) 818 status->status |= PORT_STATUS_LOW_SPEED; 819 820 // change 821 if (portStatus & OHCI_RH_PORTSTATUS_CSC) 822 status->change |= PORT_STATUS_CONNECTION; 823 if (portStatus & OHCI_RH_PORTSTATUS_PESC) 824 status->change |= PORT_STATUS_ENABLE; 825 if (portStatus & OHCI_RH_PORTSTATUS_PSSC) 826 status->change |= PORT_STATUS_SUSPEND; 827 if (portStatus & OHCI_RH_PORTSTATUS_OCIC) 828 status->change |= PORT_STATUS_OVER_CURRENT; 829 if (portStatus & OHCI_RH_PORTSTATUS_PRSC) 830 status->change |= PORT_STATUS_RESET; 831 832 TRACE("port %u status 0x%04x change 0x%04x\n", index, 833 status->status, status->change); 834 return B_OK; 835 } 836 837 838 status_t 839 OHCI::SetPortFeature(uint8 index, uint16 feature) 840 { 841 TRACE("set port feature index %u feature %u\n", index, feature); 842 if (index > fPortCount) 843 return B_BAD_INDEX; 844 845 switch (feature) { 846 case PORT_ENABLE: 847 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PES); 848 return B_OK; 849 850 case PORT_SUSPEND: 851 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PSS); 852 return B_OK; 853 854 case PORT_RESET: 855 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PRS); 856 return B_OK; 857 858 case PORT_POWER: 859 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PPS); 860 return B_OK; 861 } 862 863 return B_BAD_VALUE; 864 } 865 866 867 status_t 868 OHCI::ClearPortFeature(uint8 index, uint16 feature) 869 { 870 TRACE("clear port feature index %u feature %u\n", index, feature); 871 if (index > fPortCount) 872 return B_BAD_INDEX; 873 874 switch (feature) { 875 case PORT_ENABLE: 876 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CCS); 877 return B_OK; 878 879 case PORT_SUSPEND: 880 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_POCI); 881 return B_OK; 882 883 case PORT_POWER: 884 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_LSDA); 885 return B_OK; 886 887 case C_PORT_CONNECTION: 888 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CSC); 889 return B_OK; 890 891 case C_PORT_ENABLE: 892 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PESC); 893 return B_OK; 894 895 case C_PORT_SUSPEND: 896 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PSSC); 897 return B_OK; 898 899 case C_PORT_OVER_CURRENT: 900 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_OCIC); 901 return B_OK; 902 903 case C_PORT_RESET: 904 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PRSC); 905 return B_OK; 906 } 907 908 return B_BAD_VALUE; 909 } 910 911 912 int32 913 OHCI::_InterruptHandler(void *data) 914 { 915 return ((OHCI *)data)->_Interrupt(); 916 } 917 918 919 int32 920 OHCI::_Interrupt() 921 { 922 static spinlock lock = B_SPINLOCK_INITIALIZER; 923 acquire_spinlock(&lock); 924 925 uint32 status = 0; 926 uint32 acknowledge = 0; 927 bool finishTransfers = false; 928 int32 result = B_HANDLED_INTERRUPT; 929 930 // The LSb of done_head is used to inform the HCD that an interrupt 931 // condition exists for both the done list and for another event recorded in 932 // the HcInterruptStatus register. If done_head is 0, then the interrupt 933 // was caused by other than the HccaDoneHead update and the 934 // HcInterruptStatus register needs to be accessed to determine that exact 935 // interrupt cause. If HccDoneHead is nonzero, then a done list update 936 // interrupt is indicated and if the LSb of the Dword is nonzero, then an 937 // additional interrupt event is indicated and HcInterruptStatus should be 938 // checked to determine its cause. 939 uint32 doneHead = fHcca->done_head; 940 if (doneHead != 0) { 941 status = OHCI_WRITEBACK_DONE_HEAD; 942 if (doneHead & OHCI_DONE_INTERRUPTS) 943 status |= _ReadReg(OHCI_INTERRUPT_STATUS) 944 & _ReadReg(OHCI_INTERRUPT_ENABLE); 945 } else { 946 status = _ReadReg(OHCI_INTERRUPT_STATUS) & _ReadReg(OHCI_INTERRUPT_ENABLE) 947 & ~OHCI_WRITEBACK_DONE_HEAD; 948 if (status == 0) { 949 // Nothing to be done (PCI shared interrupt) 950 release_spinlock(&lock); 951 return B_UNHANDLED_INTERRUPT; 952 } 953 } 954 955 if (status & OHCI_SCHEDULING_OVERRUN) { 956 TRACE_MODULE("scheduling overrun occured\n"); 957 acknowledge |= OHCI_SCHEDULING_OVERRUN; 958 } 959 960 if (status & OHCI_WRITEBACK_DONE_HEAD) { 961 TRACE_MODULE("transfer descriptors processed\n"); 962 fHcca->done_head = 0; 963 acknowledge |= OHCI_WRITEBACK_DONE_HEAD; 964 result = B_INVOKE_SCHEDULER; 965 finishTransfers = true; 966 } 967 968 if (status & OHCI_RESUME_DETECTED) { 969 TRACE_MODULE("resume detected\n"); 970 acknowledge |= OHCI_RESUME_DETECTED; 971 } 972 973 if (status & OHCI_UNRECOVERABLE_ERROR) { 974 TRACE_MODULE_ERROR("unrecoverable error - controller halted\n"); 975 _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET); 976 // TODO: clear all pending transfers, reset and resetup the controller 977 } 978 979 if (status & OHCI_ROOT_HUB_STATUS_CHANGE) { 980 TRACE_MODULE("root hub status change\n"); 981 // Disable the interrupt as it will otherwise be retriggered until the 982 // port has been reset and the change is cleared explicitly. 983 // TODO: renable it once we use status changes instead of polling 984 _WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ROOT_HUB_STATUS_CHANGE); 985 acknowledge |= OHCI_ROOT_HUB_STATUS_CHANGE; 986 } 987 988 if (acknowledge != 0) 989 _WriteReg(OHCI_INTERRUPT_STATUS, acknowledge); 990 991 release_spinlock(&lock); 992 993 if (finishTransfers) 994 release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE); 995 996 return result; 997 } 998 999 1000 status_t 1001 OHCI::_AddPendingTransfer(Transfer *transfer, 1002 ohci_endpoint_descriptor *endpoint, ohci_general_td *firstDescriptor, 1003 ohci_general_td *dataDescriptor, ohci_general_td *lastDescriptor, 1004 bool directionIn) 1005 { 1006 if (!transfer || !endpoint || !lastDescriptor) 1007 return B_BAD_VALUE; 1008 1009 transfer_data *data = new(std::nothrow) transfer_data; 1010 if (!data) 1011 return B_NO_MEMORY; 1012 1013 status_t result = transfer->InitKernelAccess(); 1014 if (result < B_OK) { 1015 delete data; 1016 return result; 1017 } 1018 1019 data->transfer = transfer; 1020 data->endpoint = endpoint; 1021 data->incoming = directionIn; 1022 data->canceled = false; 1023 data->link = NULL; 1024 1025 // the current tail will become the first descriptor 1026 data->first_descriptor = (ohci_general_td *)endpoint->tail_logical_descriptor; 1027 1028 // the data and first descriptors might be the same 1029 if (dataDescriptor == firstDescriptor) 1030 data->data_descriptor = data->first_descriptor; 1031 else 1032 data->data_descriptor = dataDescriptor; 1033 1034 // even the last and the first descriptor might be the same 1035 if (lastDescriptor == firstDescriptor) 1036 data->last_descriptor = data->first_descriptor; 1037 else 1038 data->last_descriptor = lastDescriptor; 1039 1040 if (!Lock()) { 1041 delete data; 1042 return B_ERROR; 1043 } 1044 1045 if (fLastTransfer) 1046 fLastTransfer->link = data; 1047 else 1048 fFirstTransfer = data; 1049 1050 fLastTransfer = data; 1051 Unlock(); 1052 1053 return B_OK; 1054 } 1055 1056 1057 status_t 1058 OHCI::_AddPendingIsochronousTransfer(Transfer *transfer, 1059 ohci_endpoint_descriptor *endpoint, ohci_isochronous_td *firstDescriptor, 1060 ohci_isochronous_td *lastDescriptor, bool directionIn) 1061 { 1062 if (!transfer || !endpoint || !lastDescriptor) 1063 return B_BAD_VALUE; 1064 1065 transfer_data *data = new(std::nothrow) transfer_data; 1066 if (!data) 1067 return B_NO_MEMORY; 1068 1069 status_t result = transfer->InitKernelAccess(); 1070 if (result < B_OK) { 1071 delete data; 1072 return result; 1073 } 1074 1075 data->transfer = transfer; 1076 data->endpoint = endpoint; 1077 data->incoming = directionIn; 1078 data->canceled = false; 1079 data->link = NULL; 1080 1081 // the current tail will become the first descriptor 1082 data->first_descriptor = (ohci_general_td*)endpoint->tail_logical_descriptor; 1083 1084 // the data and first descriptors are the same 1085 data->data_descriptor = data->first_descriptor; 1086 1087 // the last and the first descriptor might be the same 1088 if (lastDescriptor == firstDescriptor) 1089 data->last_descriptor = data->first_descriptor; 1090 else 1091 data->last_descriptor = (ohci_general_td*)lastDescriptor; 1092 1093 if (!Lock()) { 1094 delete data; 1095 return B_ERROR; 1096 } 1097 1098 if (fLastTransfer) 1099 fLastTransfer->link = data; 1100 else 1101 fFirstTransfer = data; 1102 1103 fLastTransfer = data; 1104 Unlock(); 1105 1106 return B_OK; 1107 } 1108 1109 1110 int32 1111 OHCI::_FinishThread(void *data) 1112 { 1113 ((OHCI *)data)->_FinishTransfers(); 1114 return B_OK; 1115 } 1116 1117 1118 void 1119 OHCI::_FinishTransfers() 1120 { 1121 while (!fStopFinishThread) { 1122 if (acquire_sem(fFinishTransfersSem) < B_OK) 1123 continue; 1124 1125 // eat up sems that have been released by multiple interrupts 1126 int32 semCount = 0; 1127 get_sem_count(fFinishTransfersSem, &semCount); 1128 if (semCount > 0) 1129 acquire_sem_etc(fFinishTransfersSem, semCount, B_RELATIVE_TIMEOUT, 0); 1130 1131 if (!Lock()) 1132 continue; 1133 1134 TRACE("finishing transfers (first transfer: %p; last" 1135 " transfer: %p)\n", fFirstTransfer, fLastTransfer); 1136 transfer_data *lastTransfer = NULL; 1137 transfer_data *transfer = fFirstTransfer; 1138 Unlock(); 1139 1140 while (transfer) { 1141 bool transferDone = false; 1142 ohci_general_td *descriptor = transfer->first_descriptor; 1143 ohci_endpoint_descriptor *endpoint = transfer->endpoint; 1144 status_t callbackStatus = B_OK; 1145 1146 if (endpoint->flags & OHCI_ENDPOINT_ISOCHRONOUS_FORMAT) { 1147 transfer_data *next = transfer->link; 1148 if (_FinishIsochronousTransfer(transfer, &lastTransfer)) { 1149 delete transfer->transfer; 1150 delete transfer; 1151 } 1152 transfer = next; 1153 continue; 1154 } 1155 1156 MutexLocker endpointLocker(endpoint->lock); 1157 1158 if ((endpoint->head_physical_descriptor & OHCI_ENDPOINT_HEAD_MASK) 1159 != endpoint->tail_physical_descriptor 1160 && (endpoint->head_physical_descriptor 1161 & OHCI_ENDPOINT_HALTED) == 0) { 1162 // there are still active transfers on this endpoint, we need 1163 // to wait for all of them to complete, otherwise we'd read 1164 // a potentially bogus data toggle value below 1165 TRACE("endpoint %p still has active tds\n", endpoint); 1166 lastTransfer = transfer; 1167 transfer = transfer->link; 1168 continue; 1169 } 1170 1171 endpointLocker.Unlock(); 1172 1173 while (descriptor && !transfer->canceled) { 1174 uint32 status = OHCI_TD_GET_CONDITION_CODE(descriptor->flags); 1175 if (status == OHCI_TD_CONDITION_NOT_ACCESSED) { 1176 // td is still active 1177 TRACE("td %p still active\n", descriptor); 1178 break; 1179 } 1180 1181 if (status != OHCI_TD_CONDITION_NO_ERROR) { 1182 // an error occured, but we must ensure that the td 1183 // was actually done 1184 if (endpoint->head_physical_descriptor & OHCI_ENDPOINT_HALTED) { 1185 // the endpoint is halted, this guaratees us that this 1186 // descriptor has passed (we don't know if the endpoint 1187 // was halted because of this td, but we do not need 1188 // to know, as when it was halted by another td this 1189 // still ensures that this td was handled before). 1190 TRACE_ERROR("td error: 0x%08" B_PRIx32 "\n", status); 1191 1192 callbackStatus = _GetStatusOfConditionCode(status); 1193 1194 transferDone = true; 1195 break; 1196 } else { 1197 // an error occured but the endpoint is not halted so 1198 // the td is in fact still active 1199 TRACE("td %p active with error\n", descriptor); 1200 break; 1201 } 1202 } 1203 1204 // the td has completed without an error 1205 TRACE("td %p done\n", descriptor); 1206 1207 if (descriptor == transfer->last_descriptor 1208 || descriptor->buffer_physical != 0) { 1209 // this is the last td of the transfer or a short packet 1210 callbackStatus = B_OK; 1211 transferDone = true; 1212 break; 1213 } 1214 1215 descriptor 1216 = (ohci_general_td *)descriptor->next_logical_descriptor; 1217 } 1218 1219 if (transfer->canceled) { 1220 // when a transfer is canceled, all transfers to that endpoint 1221 // are canceled by setting the head pointer to the tail pointer 1222 // which causes all of the tds to become "free" (as they are 1223 // inaccessible and not accessed anymore (as setting the head 1224 // pointer required disabling the endpoint)) 1225 callbackStatus = B_OK; 1226 transferDone = true; 1227 } 1228 1229 if (!transferDone) { 1230 lastTransfer = transfer; 1231 transfer = transfer->link; 1232 continue; 1233 } 1234 1235 // remove the transfer from the list first so we are sure 1236 // it doesn't get canceled while we still process it 1237 transfer_data *next = transfer->link; 1238 if (Lock()) { 1239 if (lastTransfer) 1240 lastTransfer->link = transfer->link; 1241 1242 if (transfer == fFirstTransfer) 1243 fFirstTransfer = transfer->link; 1244 if (transfer == fLastTransfer) 1245 fLastTransfer = lastTransfer; 1246 1247 // store the currently processing pipe here so we can wait 1248 // in cancel if we are processing something on the target pipe 1249 if (!transfer->canceled) 1250 fProcessingPipe = transfer->transfer->TransferPipe(); 1251 1252 transfer->link = NULL; 1253 Unlock(); 1254 } 1255 1256 // break the descriptor chain on the last descriptor 1257 transfer->last_descriptor->next_logical_descriptor = NULL; 1258 TRACE("transfer %p done with status 0x%08" B_PRIx32 "\n", 1259 transfer, callbackStatus); 1260 1261 // if canceled the callback has already been called 1262 if (!transfer->canceled) { 1263 size_t actualLength = 0; 1264 if (callbackStatus == B_OK) { 1265 if (transfer->data_descriptor && transfer->incoming) { 1266 // data to read out 1267 generic_io_vec *vector = transfer->transfer->Vector(); 1268 size_t vectorCount = transfer->transfer->VectorCount(); 1269 1270 transfer->transfer->PrepareKernelAccess(); 1271 actualLength = _ReadDescriptorChain( 1272 transfer->data_descriptor, 1273 vector, vectorCount, transfer->transfer->IsPhysical()); 1274 } else if (transfer->data_descriptor) { 1275 // read the actual length that was sent 1276 actualLength = _ReadActualLength( 1277 transfer->data_descriptor); 1278 } 1279 1280 // get the last data toggle and store it for next time 1281 transfer->transfer->TransferPipe()->SetDataToggle( 1282 (endpoint->head_physical_descriptor 1283 & OHCI_ENDPOINT_TOGGLE_CARRY) != 0); 1284 1285 if (transfer->transfer->IsFragmented()) { 1286 // this transfer may still have data left 1287 TRACE("advancing fragmented transfer\n"); 1288 transfer->transfer->AdvanceByFragment(actualLength); 1289 if (transfer->transfer->FragmentLength() > 0) { 1290 TRACE("still %ld bytes left on transfer\n", 1291 transfer->transfer->FragmentLength()); 1292 // TODO actually resubmit the transfer 1293 } 1294 1295 // the transfer is done, but we already set the 1296 // actualLength with AdvanceByFragment() 1297 actualLength = 0; 1298 } 1299 } 1300 1301 transfer->transfer->Finished(callbackStatus, actualLength); 1302 fProcessingPipe = NULL; 1303 } 1304 1305 if (callbackStatus != B_OK) { 1306 // remove the transfer and make the head pointer valid again 1307 // (including clearing the halt state) 1308 _RemoveTransferFromEndpoint(transfer); 1309 } 1310 1311 // free the descriptors 1312 _FreeDescriptorChain(transfer->first_descriptor); 1313 1314 delete transfer->transfer; 1315 delete transfer; 1316 transfer = next; 1317 } 1318 } 1319 } 1320 1321 1322 bool 1323 OHCI::_FinishIsochronousTransfer(transfer_data *transfer, 1324 transfer_data **_lastTransfer) 1325 { 1326 status_t callbackStatus = B_OK; 1327 size_t actualLength = 0; 1328 uint32 packet = 0; 1329 1330 if (transfer->canceled) 1331 callbackStatus = B_CANCELED; 1332 else { 1333 // at first check if ALL ITDs are retired by HC 1334 ohci_isochronous_td *descriptor 1335 = (ohci_isochronous_td *)transfer->first_descriptor; 1336 while (descriptor) { 1337 if (OHCI_TD_GET_CONDITION_CODE(descriptor->flags) 1338 == OHCI_TD_CONDITION_NOT_ACCESSED) { 1339 TRACE("ITD %p still active\n", descriptor); 1340 *_lastTransfer = transfer; 1341 return false; 1342 } 1343 1344 if (descriptor == (ohci_isochronous_td*)transfer->last_descriptor) { 1345 // this is the last ITD of the transfer 1346 descriptor = (ohci_isochronous_td *)transfer->first_descriptor; 1347 break; 1348 } 1349 1350 descriptor 1351 = (ohci_isochronous_td *)descriptor->next_done_descriptor; 1352 } 1353 1354 while (descriptor) { 1355 uint32 status = OHCI_TD_GET_CONDITION_CODE(descriptor->flags); 1356 if (status != OHCI_TD_CONDITION_NO_ERROR) { 1357 TRACE_ERROR("ITD error: 0x%08" B_PRIx32 "\n", status); 1358 // spec says that in most cases condition code 1359 // of retired ITDs is set to NoError, but for the 1360 // time overrun it can be DataOverrun. We assume 1361 // the _first_ occurience of such error as status 1362 // reported to the callback 1363 if (callbackStatus == B_OK) 1364 callbackStatus = _GetStatusOfConditionCode(status); 1365 } 1366 1367 usb_isochronous_data *isochronousData 1368 = transfer->transfer->IsochronousData(); 1369 1370 uint32 frameCount = OHCI_ITD_GET_FRAME_COUNT(descriptor->flags); 1371 for (size_t i = 0; i < frameCount; i++, packet++) { 1372 usb_iso_packet_descriptor* packet_descriptor 1373 = &isochronousData->packet_descriptors[packet]; 1374 1375 uint16 offset = descriptor->offset[OHCI_ITD_OFFSET_IDX(i)]; 1376 uint8 code = OHCI_ITD_GET_BUFFER_CONDITION_CODE(offset); 1377 packet_descriptor->status = _GetStatusOfConditionCode(code); 1378 1379 // not touched by HC - sheduled too late to be processed 1380 // in the requested frame - so we ignore it too 1381 if (packet_descriptor->status == B_DEV_TOO_LATE) 1382 continue; 1383 1384 size_t len = OHCI_ITD_GET_BUFFER_LENGTH(offset); 1385 if (!transfer->incoming) 1386 len = packet_descriptor->request_length - len; 1387 1388 packet_descriptor->actual_length = len; 1389 actualLength += len; 1390 } 1391 1392 uint16 frame = OHCI_ITD_GET_STARTING_FRAME(descriptor->flags); 1393 _ReleaseIsochronousBandwidth(frame, 1394 OHCI_ITD_GET_FRAME_COUNT(descriptor->flags)); 1395 1396 TRACE("ITD %p done\n", descriptor); 1397 1398 if (descriptor == (ohci_isochronous_td*)transfer->last_descriptor) 1399 break; 1400 1401 descriptor 1402 = (ohci_isochronous_td *)descriptor->next_done_descriptor; 1403 } 1404 } 1405 1406 // remove the transfer from the list first so we are sure 1407 // it doesn't get canceled while we still process it 1408 if (Lock()) { 1409 if (*_lastTransfer) 1410 (*_lastTransfer)->link = transfer->link; 1411 1412 if (transfer == fFirstTransfer) 1413 fFirstTransfer = transfer->link; 1414 if (transfer == fLastTransfer) 1415 fLastTransfer = *_lastTransfer; 1416 1417 // store the currently processing pipe here so we can wait 1418 // in cancel if we are processing something on the target pipe 1419 if (!transfer->canceled) 1420 fProcessingPipe = transfer->transfer->TransferPipe(); 1421 1422 transfer->link = NULL; 1423 Unlock(); 1424 } 1425 1426 // break the descriptor chain on the last descriptor 1427 transfer->last_descriptor->next_logical_descriptor = NULL; 1428 TRACE("iso.transfer %p done with status 0x%08" B_PRIx32 " len:%ld\n", 1429 transfer, callbackStatus, actualLength); 1430 1431 // if canceled the callback has already been called 1432 if (!transfer->canceled) { 1433 if (callbackStatus == B_OK && actualLength > 0) { 1434 if (transfer->data_descriptor && transfer->incoming) { 1435 // data to read out 1436 generic_io_vec *vector = transfer->transfer->Vector(); 1437 size_t vectorCount = transfer->transfer->VectorCount(); 1438 1439 transfer->transfer->PrepareKernelAccess(); 1440 _ReadIsochronousDescriptorChain( 1441 (ohci_isochronous_td*)transfer->data_descriptor, 1442 vector, vectorCount, transfer->transfer->IsPhysical()); 1443 } 1444 } 1445 1446 transfer->transfer->Finished(callbackStatus, actualLength); 1447 fProcessingPipe = NULL; 1448 } 1449 1450 _FreeIsochronousDescriptorChain( 1451 (ohci_isochronous_td*)transfer->first_descriptor); 1452 1453 return true; 1454 } 1455 1456 1457 status_t 1458 OHCI::_SubmitRequest(Transfer *transfer) 1459 { 1460 usb_request_data *requestData = transfer->RequestData(); 1461 bool directionIn = (requestData->RequestType & USB_REQTYPE_DEVICE_IN) != 0; 1462 1463 ohci_general_td *setupDescriptor 1464 = _CreateGeneralDescriptor(sizeof(usb_request_data)); 1465 if (!setupDescriptor) { 1466 TRACE_ERROR("failed to allocate setup descriptor\n"); 1467 return B_NO_MEMORY; 1468 } 1469 1470 setupDescriptor->flags = OHCI_TD_DIRECTION_PID_SETUP 1471 | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) 1472 | OHCI_TD_TOGGLE_0 1473 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE); 1474 1475 ohci_general_td *statusDescriptor = _CreateGeneralDescriptor(0); 1476 if (!statusDescriptor) { 1477 TRACE_ERROR("failed to allocate status descriptor\n"); 1478 _FreeGeneralDescriptor(setupDescriptor); 1479 return B_NO_MEMORY; 1480 } 1481 1482 statusDescriptor->flags 1483 = (directionIn ? OHCI_TD_DIRECTION_PID_OUT : OHCI_TD_DIRECTION_PID_IN) 1484 | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) 1485 | OHCI_TD_TOGGLE_1 1486 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE); 1487 1488 generic_io_vec vector; 1489 vector.base = (generic_addr_t)requestData; 1490 vector.length = sizeof(usb_request_data); 1491 _WriteDescriptorChain(setupDescriptor, &vector, 1, false); 1492 1493 status_t result; 1494 ohci_general_td *dataDescriptor = NULL; 1495 if (transfer->VectorCount() > 0) { 1496 ohci_general_td *lastDescriptor = NULL; 1497 result = _CreateDescriptorChain(&dataDescriptor, &lastDescriptor, 1498 directionIn ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT, 1499 transfer->FragmentLength()); 1500 if (result < B_OK) { 1501 _FreeGeneralDescriptor(setupDescriptor); 1502 _FreeGeneralDescriptor(statusDescriptor); 1503 return result; 1504 } 1505 1506 if (!directionIn) { 1507 _WriteDescriptorChain(dataDescriptor, transfer->Vector(), 1508 transfer->VectorCount(), transfer->IsPhysical()); 1509 } 1510 1511 _LinkDescriptors(setupDescriptor, dataDescriptor); 1512 _LinkDescriptors(lastDescriptor, statusDescriptor); 1513 } else { 1514 _LinkDescriptors(setupDescriptor, statusDescriptor); 1515 } 1516 1517 // Add to the transfer list 1518 ohci_endpoint_descriptor *endpoint 1519 = (ohci_endpoint_descriptor *)transfer->TransferPipe()->ControllerCookie(); 1520 1521 MutexLocker endpointLocker(endpoint->lock); 1522 result = _AddPendingTransfer(transfer, endpoint, setupDescriptor, 1523 dataDescriptor, statusDescriptor, directionIn); 1524 if (result < B_OK) { 1525 TRACE_ERROR("failed to add pending transfer\n"); 1526 _FreeDescriptorChain(setupDescriptor); 1527 return result; 1528 } 1529 1530 // Add the descriptor chain to the endpoint 1531 _SwitchEndpointTail(endpoint, setupDescriptor, statusDescriptor); 1532 endpointLocker.Unlock(); 1533 1534 // Tell the controller to process the control list 1535 endpoint->flags &= ~OHCI_ENDPOINT_SKIP; 1536 _WriteReg(OHCI_COMMAND_STATUS, OHCI_CONTROL_LIST_FILLED); 1537 return B_OK; 1538 } 1539 1540 1541 status_t 1542 OHCI::_SubmitTransfer(Transfer *transfer) 1543 { 1544 Pipe *pipe = transfer->TransferPipe(); 1545 bool directionIn = (pipe->Direction() == Pipe::In); 1546 1547 ohci_general_td *firstDescriptor = NULL; 1548 ohci_general_td *lastDescriptor = NULL; 1549 status_t result = _CreateDescriptorChain(&firstDescriptor, &lastDescriptor, 1550 directionIn ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT, 1551 transfer->FragmentLength()); 1552 1553 if (result < B_OK) 1554 return result; 1555 1556 // Apply data toggle to the first descriptor (the others will use the carry) 1557 firstDescriptor->flags &= ~OHCI_TD_TOGGLE_CARRY; 1558 firstDescriptor->flags |= pipe->DataToggle() ? OHCI_TD_TOGGLE_1 1559 : OHCI_TD_TOGGLE_0; 1560 1561 // Set the last descriptor to generate an interrupt 1562 lastDescriptor->flags &= ~OHCI_TD_INTERRUPT_MASK; 1563 lastDescriptor->flags |= 1564 OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE); 1565 1566 if (!directionIn) { 1567 _WriteDescriptorChain(firstDescriptor, transfer->Vector(), 1568 transfer->VectorCount(), transfer->IsPhysical()); 1569 } 1570 1571 // Add to the transfer list 1572 ohci_endpoint_descriptor *endpoint 1573 = (ohci_endpoint_descriptor *)pipe->ControllerCookie(); 1574 1575 MutexLocker endpointLocker(endpoint->lock); 1576 1577 // We do not support queuing other transfers in tandem with a fragmented one. 1578 transfer_data *it = fFirstTransfer; 1579 while (it) { 1580 if (it->transfer && it->transfer->TransferPipe() == pipe && it->transfer->IsFragmented()) { 1581 TRACE_ERROR("cannot submit transfer: a fragmented transfer is queued\n"); 1582 _FreeDescriptorChain(firstDescriptor); 1583 return B_DEV_RESOURCE_CONFLICT; 1584 } 1585 1586 it = it->link; 1587 } 1588 1589 result = _AddPendingTransfer(transfer, endpoint, firstDescriptor, 1590 firstDescriptor, lastDescriptor, directionIn); 1591 if (result < B_OK) { 1592 TRACE_ERROR("failed to add pending transfer\n"); 1593 _FreeDescriptorChain(firstDescriptor); 1594 return result; 1595 } 1596 1597 // Add the descriptor chain to the endpoint 1598 _SwitchEndpointTail(endpoint, firstDescriptor, lastDescriptor); 1599 endpointLocker.Unlock(); 1600 1601 endpoint->flags &= ~OHCI_ENDPOINT_SKIP; 1602 if (pipe->Type() & USB_OBJECT_BULK_PIPE) { 1603 // Tell the controller to process the bulk list 1604 _WriteReg(OHCI_COMMAND_STATUS, OHCI_BULK_LIST_FILLED); 1605 } 1606 1607 return B_OK; 1608 } 1609 1610 1611 status_t 1612 OHCI::_SubmitIsochronousTransfer(Transfer *transfer) 1613 { 1614 Pipe *pipe = transfer->TransferPipe(); 1615 bool directionIn = (pipe->Direction() == Pipe::In); 1616 1617 ohci_isochronous_td *firstDescriptor = NULL; 1618 ohci_isochronous_td *lastDescriptor = NULL; 1619 status_t result = _CreateIsochronousDescriptorChain(&firstDescriptor, 1620 &lastDescriptor, transfer); 1621 1622 if (firstDescriptor == 0 || lastDescriptor == 0) 1623 return B_ERROR; 1624 1625 if (result < B_OK) 1626 return result; 1627 1628 // Set the last descriptor to generate an interrupt 1629 lastDescriptor->flags &= ~OHCI_ITD_INTERRUPT_MASK; 1630 // let the controller retire last ITD 1631 lastDescriptor->flags |= OHCI_ITD_SET_DELAY_INTERRUPT(1); 1632 1633 // If direction is out set every descriptor data 1634 if (pipe->Direction() == Pipe::Out) 1635 _WriteIsochronousDescriptorChain(firstDescriptor, 1636 transfer->Vector(), transfer->VectorCount(), transfer->IsPhysical()); 1637 1638 // Add to the transfer list 1639 ohci_endpoint_descriptor *endpoint 1640 = (ohci_endpoint_descriptor *)pipe->ControllerCookie(); 1641 1642 MutexLocker endpointLocker(endpoint->lock); 1643 result = _AddPendingIsochronousTransfer(transfer, endpoint, 1644 firstDescriptor, lastDescriptor, directionIn); 1645 if (result < B_OK) { 1646 TRACE_ERROR("failed to add pending iso.transfer:" 1647 "0x%08" B_PRIx32 "\n", result); 1648 _FreeIsochronousDescriptorChain(firstDescriptor); 1649 return result; 1650 } 1651 1652 // Add the descriptor chain to the endpoint 1653 _SwitchIsochronousEndpointTail(endpoint, firstDescriptor, lastDescriptor); 1654 endpointLocker.Unlock(); 1655 1656 endpoint->flags &= ~OHCI_ENDPOINT_SKIP; 1657 1658 return B_OK; 1659 } 1660 1661 1662 void 1663 OHCI::_SwitchEndpointTail(ohci_endpoint_descriptor *endpoint, 1664 ohci_general_td *first, ohci_general_td *last) 1665 { 1666 // fill in the information of the first descriptor into the current tail 1667 ohci_general_td *tail = (ohci_general_td *)endpoint->tail_logical_descriptor; 1668 tail->flags = first->flags; 1669 tail->buffer_physical = first->buffer_physical; 1670 tail->next_physical_descriptor = first->next_physical_descriptor; 1671 tail->last_physical_byte_address = first->last_physical_byte_address; 1672 tail->buffer_size = first->buffer_size; 1673 tail->buffer_logical = first->buffer_logical; 1674 tail->next_logical_descriptor = first->next_logical_descriptor; 1675 1676 // the first descriptor becomes the new tail 1677 first->flags = 0; 1678 first->buffer_physical = 0; 1679 first->next_physical_descriptor = 0; 1680 first->last_physical_byte_address = 0; 1681 first->buffer_size = 0; 1682 first->buffer_logical = NULL; 1683 first->next_logical_descriptor = NULL; 1684 1685 if (first == last) 1686 _LinkDescriptors(tail, first); 1687 else 1688 _LinkDescriptors(last, first); 1689 1690 // update the endpoint tail pointer to reflect the change 1691 endpoint->tail_logical_descriptor = first; 1692 endpoint->tail_physical_descriptor = (uint32)first->physical_address; 1693 TRACE("switched tail from %p to %p\n", tail, first); 1694 1695 #if 0 1696 _PrintEndpoint(endpoint); 1697 _PrintDescriptorChain(tail); 1698 #endif 1699 } 1700 1701 1702 void 1703 OHCI::_SwitchIsochronousEndpointTail(ohci_endpoint_descriptor *endpoint, 1704 ohci_isochronous_td *first, ohci_isochronous_td *last) 1705 { 1706 // fill in the information of the first descriptor into the current tail 1707 ohci_isochronous_td *tail 1708 = (ohci_isochronous_td*)endpoint->tail_logical_descriptor; 1709 tail->flags = first->flags; 1710 tail->buffer_page_byte_0 = first->buffer_page_byte_0; 1711 tail->next_physical_descriptor = first->next_physical_descriptor; 1712 tail->last_byte_address = first->last_byte_address; 1713 tail->buffer_size = first->buffer_size; 1714 tail->buffer_logical = first->buffer_logical; 1715 tail->next_logical_descriptor = first->next_logical_descriptor; 1716 tail->next_done_descriptor = first->next_done_descriptor; 1717 1718 // the first descriptor becomes the new tail 1719 first->flags = 0; 1720 first->buffer_page_byte_0 = 0; 1721 first->next_physical_descriptor = 0; 1722 first->last_byte_address = 0; 1723 first->buffer_size = 0; 1724 first->buffer_logical = NULL; 1725 first->next_logical_descriptor = NULL; 1726 first->next_done_descriptor = NULL; 1727 1728 for (int i = 0; i < OHCI_ITD_NOFFSET; i++) { 1729 tail->offset[i] = first->offset[i]; 1730 first->offset[i] = 0; 1731 } 1732 1733 if (first == last) 1734 _LinkIsochronousDescriptors(tail, first, NULL); 1735 else 1736 _LinkIsochronousDescriptors(last, first, NULL); 1737 1738 // update the endpoint tail pointer to reflect the change 1739 endpoint->tail_logical_descriptor = first; 1740 endpoint->tail_physical_descriptor = (uint32)first->physical_address; 1741 TRACE("switched tail from %p to %p\n", tail, first); 1742 1743 #if 0 1744 _PrintEndpoint(endpoint); 1745 _PrintDescriptorChain(tail); 1746 #endif 1747 } 1748 1749 1750 void 1751 OHCI::_RemoveTransferFromEndpoint(transfer_data *transfer) 1752 { 1753 // The transfer failed and the endpoint was halted. This means that the 1754 // endpoint head pointer might point somewhere into the descriptor chain 1755 // of this transfer. As we do not know if this transfer actually caused 1756 // the halt on the endpoint we have to make sure this is the case. If we 1757 // find the head to point to somewhere into the descriptor chain then 1758 // simply advancing the head pointer to the link of the last transfer 1759 // will bring the endpoint into a valid state again. This operation is 1760 // safe as the endpoint is currently halted and we therefore can change 1761 // the head pointer. 1762 ohci_endpoint_descriptor *endpoint = transfer->endpoint; 1763 ohci_general_td *descriptor = transfer->first_descriptor; 1764 while (descriptor) { 1765 if ((endpoint->head_physical_descriptor & OHCI_ENDPOINT_HEAD_MASK) 1766 == descriptor->physical_address) { 1767 // This descriptor caused the halt. Advance the head pointer. This 1768 // will either move the head to the next valid transfer that can 1769 // then be restarted, or it will move the head to the tail when 1770 // there are no more transfer descriptors. Setting the head will 1771 // also clear the halt state as it is stored in the first bit of 1772 // the head pointer. 1773 endpoint->head_physical_descriptor 1774 = transfer->last_descriptor->next_physical_descriptor; 1775 return; 1776 } 1777 1778 descriptor = (ohci_general_td *)descriptor->next_logical_descriptor; 1779 } 1780 } 1781 1782 1783 ohci_endpoint_descriptor * 1784 OHCI::_AllocateEndpoint() 1785 { 1786 ohci_endpoint_descriptor *endpoint; 1787 phys_addr_t physicalAddress; 1788 1789 mutex *lock = (mutex *)malloc(sizeof(mutex)); 1790 if (lock == NULL) { 1791 TRACE_ERROR("no memory to allocate endpoint lock\n"); 1792 return NULL; 1793 } 1794 1795 // Allocate memory chunk 1796 if (fStack->AllocateChunk((void **)&endpoint, &physicalAddress, 1797 sizeof(ohci_endpoint_descriptor)) < B_OK) { 1798 TRACE_ERROR("failed to allocate endpoint descriptor\n"); 1799 free(lock); 1800 return NULL; 1801 } 1802 1803 mutex_init(lock, "ohci endpoint lock"); 1804 1805 endpoint->flags = OHCI_ENDPOINT_SKIP; 1806 endpoint->physical_address = (uint32)physicalAddress; 1807 endpoint->head_physical_descriptor = 0; 1808 endpoint->tail_logical_descriptor = NULL; 1809 endpoint->tail_physical_descriptor = 0; 1810 endpoint->next_logical_endpoint = NULL; 1811 endpoint->next_physical_endpoint = 0; 1812 endpoint->lock = lock; 1813 return endpoint; 1814 } 1815 1816 1817 void 1818 OHCI::_FreeEndpoint(ohci_endpoint_descriptor *endpoint) 1819 { 1820 if (!endpoint) 1821 return; 1822 1823 mutex_destroy(endpoint->lock); 1824 free(endpoint->lock); 1825 1826 fStack->FreeChunk((void *)endpoint, endpoint->physical_address, 1827 sizeof(ohci_endpoint_descriptor)); 1828 } 1829 1830 1831 status_t 1832 OHCI::_InsertEndpointForPipe(Pipe *pipe) 1833 { 1834 TRACE("inserting endpoint for device %u endpoint %u\n", 1835 pipe->DeviceAddress(), pipe->EndpointAddress()); 1836 1837 ohci_endpoint_descriptor *endpoint = _AllocateEndpoint(); 1838 if (!endpoint) { 1839 TRACE_ERROR("cannot allocate memory for endpoint\n"); 1840 return B_NO_MEMORY; 1841 } 1842 1843 uint32 flags = OHCI_ENDPOINT_SKIP; 1844 1845 // Set up device and endpoint address 1846 flags |= OHCI_ENDPOINT_SET_DEVICE_ADDRESS(pipe->DeviceAddress()) 1847 | OHCI_ENDPOINT_SET_ENDPOINT_NUMBER(pipe->EndpointAddress()); 1848 1849 // Set the direction 1850 switch (pipe->Direction()) { 1851 case Pipe::In: 1852 flags |= OHCI_ENDPOINT_DIRECTION_IN; 1853 break; 1854 1855 case Pipe::Out: 1856 flags |= OHCI_ENDPOINT_DIRECTION_OUT; 1857 break; 1858 1859 case Pipe::Default: 1860 flags |= OHCI_ENDPOINT_DIRECTION_DESCRIPTOR; 1861 break; 1862 1863 default: 1864 TRACE_ERROR("direction unknown\n"); 1865 _FreeEndpoint(endpoint); 1866 return B_ERROR; 1867 } 1868 1869 // Set up the speed 1870 switch (pipe->Speed()) { 1871 case USB_SPEED_LOWSPEED: 1872 flags |= OHCI_ENDPOINT_LOW_SPEED; 1873 break; 1874 1875 case USB_SPEED_FULLSPEED: 1876 flags |= OHCI_ENDPOINT_FULL_SPEED; 1877 break; 1878 1879 default: 1880 TRACE_ERROR("unacceptable speed\n"); 1881 _FreeEndpoint(endpoint); 1882 return B_ERROR; 1883 } 1884 1885 // Set the maximum packet size 1886 flags |= OHCI_ENDPOINT_SET_MAX_PACKET_SIZE(pipe->MaxPacketSize()); 1887 endpoint->flags = flags; 1888 1889 // Add the endpoint to the appropriate list 1890 uint32 type = pipe->Type(); 1891 ohci_endpoint_descriptor *head = NULL; 1892 if (type & USB_OBJECT_CONTROL_PIPE) 1893 head = fDummyControl; 1894 else if (type & USB_OBJECT_BULK_PIPE) 1895 head = fDummyBulk; 1896 else if (type & USB_OBJECT_INTERRUPT_PIPE) 1897 head = _FindInterruptEndpoint(pipe->Interval()); 1898 else if (type & USB_OBJECT_ISO_PIPE) 1899 head = fDummyIsochronous; 1900 else 1901 TRACE_ERROR("unknown pipe type\n"); 1902 1903 if (head == NULL) { 1904 TRACE_ERROR("no list found for endpoint\n"); 1905 _FreeEndpoint(endpoint); 1906 return B_ERROR; 1907 } 1908 1909 // Create (necessary) tail descriptor 1910 if (pipe->Type() & USB_OBJECT_ISO_PIPE) { 1911 // Set the isochronous bit format 1912 endpoint->flags |= OHCI_ENDPOINT_ISOCHRONOUS_FORMAT; 1913 ohci_isochronous_td *tail = _CreateIsochronousDescriptor(0); 1914 tail->flags = 0; 1915 endpoint->tail_logical_descriptor = tail; 1916 endpoint->head_physical_descriptor = tail->physical_address; 1917 endpoint->tail_physical_descriptor = tail->physical_address; 1918 } else { 1919 ohci_general_td *tail = _CreateGeneralDescriptor(0); 1920 tail->flags = 0; 1921 endpoint->tail_logical_descriptor = tail; 1922 endpoint->head_physical_descriptor = tail->physical_address; 1923 endpoint->tail_physical_descriptor = tail->physical_address; 1924 } 1925 1926 if (!_LockEndpoints()) { 1927 if (endpoint->tail_logical_descriptor) { 1928 _FreeGeneralDescriptor( 1929 (ohci_general_td *)endpoint->tail_logical_descriptor); 1930 } 1931 1932 _FreeEndpoint(endpoint); 1933 return B_ERROR; 1934 } 1935 1936 pipe->SetControllerCookie((void *)endpoint); 1937 endpoint->next_logical_endpoint = head->next_logical_endpoint; 1938 endpoint->next_physical_endpoint = head->next_physical_endpoint; 1939 head->next_logical_endpoint = (void *)endpoint; 1940 head->next_physical_endpoint = (uint32)endpoint->physical_address; 1941 1942 _UnlockEndpoints(); 1943 return B_OK; 1944 } 1945 1946 1947 status_t 1948 OHCI::_RemoveEndpointForPipe(Pipe *pipe) 1949 { 1950 TRACE("removing endpoint for device %u endpoint %u\n", 1951 pipe->DeviceAddress(), pipe->EndpointAddress()); 1952 1953 ohci_endpoint_descriptor *endpoint 1954 = (ohci_endpoint_descriptor *)pipe->ControllerCookie(); 1955 if (endpoint == NULL) 1956 return B_OK; 1957 1958 // TODO implement properly, but at least disable it for now 1959 endpoint->flags |= OHCI_ENDPOINT_SKIP; 1960 return B_OK; 1961 } 1962 1963 1964 ohci_endpoint_descriptor * 1965 OHCI::_FindInterruptEndpoint(uint8 interval) 1966 { 1967 uint32 index = 0; 1968 uint32 power = 1; 1969 while (power <= OHCI_BIGGEST_INTERVAL / 2) { 1970 if (power * 2 > interval) 1971 break; 1972 1973 power *= 2; 1974 index++; 1975 } 1976 1977 return fInterruptEndpoints[index]; 1978 } 1979 1980 1981 ohci_general_td * 1982 OHCI::_CreateGeneralDescriptor(size_t bufferSize) 1983 { 1984 ohci_general_td *descriptor; 1985 phys_addr_t physicalAddress; 1986 1987 if (fStack->AllocateChunk((void **)&descriptor, &physicalAddress, 1988 sizeof(ohci_general_td)) != B_OK) { 1989 TRACE_ERROR("failed to allocate general descriptor\n"); 1990 return NULL; 1991 } 1992 1993 descriptor->physical_address = (uint32)physicalAddress; 1994 descriptor->next_physical_descriptor = 0; 1995 descriptor->next_logical_descriptor = NULL; 1996 descriptor->buffer_size = bufferSize; 1997 if (bufferSize == 0) { 1998 descriptor->buffer_physical = 0; 1999 descriptor->buffer_logical = NULL; 2000 descriptor->last_physical_byte_address = 0; 2001 return descriptor; 2002 } 2003 2004 if (fStack->AllocateChunk(&descriptor->buffer_logical, 2005 &physicalAddress, bufferSize) != B_OK) { 2006 TRACE_ERROR("failed to allocate space for buffer\n"); 2007 fStack->FreeChunk(descriptor, descriptor->physical_address, 2008 sizeof(ohci_general_td)); 2009 return NULL; 2010 } 2011 descriptor->buffer_physical = physicalAddress; 2012 2013 descriptor->last_physical_byte_address 2014 = descriptor->buffer_physical + bufferSize - 1; 2015 return descriptor; 2016 } 2017 2018 2019 void 2020 OHCI::_FreeGeneralDescriptor(ohci_general_td *descriptor) 2021 { 2022 if (!descriptor) 2023 return; 2024 2025 if (descriptor->buffer_logical) { 2026 fStack->FreeChunk(descriptor->buffer_logical, 2027 descriptor->buffer_physical, descriptor->buffer_size); 2028 } 2029 2030 fStack->FreeChunk((void *)descriptor, descriptor->physical_address, 2031 sizeof(ohci_general_td)); 2032 } 2033 2034 2035 status_t 2036 OHCI::_CreateDescriptorChain(ohci_general_td **_firstDescriptor, 2037 ohci_general_td **_lastDescriptor, uint32 direction, size_t bufferSize) 2038 { 2039 size_t blockSize = 8192; 2040 int32 descriptorCount = (bufferSize + blockSize - 1) / blockSize; 2041 if (descriptorCount == 0) 2042 descriptorCount = 1; 2043 2044 ohci_general_td *firstDescriptor = NULL; 2045 ohci_general_td *lastDescriptor = *_firstDescriptor; 2046 for (int32 i = 0; i < descriptorCount; i++) { 2047 ohci_general_td *descriptor = _CreateGeneralDescriptor( 2048 min_c(blockSize, bufferSize)); 2049 2050 if (!descriptor) { 2051 _FreeDescriptorChain(firstDescriptor); 2052 return B_NO_MEMORY; 2053 } 2054 2055 descriptor->flags = direction 2056 | OHCI_TD_BUFFER_ROUNDING 2057 | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) 2058 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE) 2059 | OHCI_TD_TOGGLE_CARRY; 2060 2061 // link to previous 2062 if (lastDescriptor) 2063 _LinkDescriptors(lastDescriptor, descriptor); 2064 2065 bufferSize -= blockSize; 2066 lastDescriptor = descriptor; 2067 if (!firstDescriptor) 2068 firstDescriptor = descriptor; 2069 } 2070 2071 *_firstDescriptor = firstDescriptor; 2072 *_lastDescriptor = lastDescriptor; 2073 return B_OK; 2074 } 2075 2076 2077 void 2078 OHCI::_FreeDescriptorChain(ohci_general_td *topDescriptor) 2079 { 2080 ohci_general_td *current = topDescriptor; 2081 ohci_general_td *next = NULL; 2082 2083 while (current) { 2084 next = (ohci_general_td *)current->next_logical_descriptor; 2085 _FreeGeneralDescriptor(current); 2086 current = next; 2087 } 2088 } 2089 2090 2091 ohci_isochronous_td * 2092 OHCI::_CreateIsochronousDescriptor(size_t bufferSize) 2093 { 2094 ohci_isochronous_td *descriptor = NULL; 2095 phys_addr_t physicalAddress; 2096 2097 if (fStack->AllocateChunk((void **)&descriptor, &physicalAddress, 2098 sizeof(ohci_isochronous_td)) != B_OK) { 2099 TRACE_ERROR("failed to allocate isochronous descriptor\n"); 2100 return NULL; 2101 } 2102 2103 descriptor->physical_address = (uint32)physicalAddress; 2104 descriptor->next_physical_descriptor = 0; 2105 descriptor->next_logical_descriptor = NULL; 2106 descriptor->next_done_descriptor = NULL; 2107 descriptor->buffer_size = bufferSize; 2108 if (bufferSize == 0) { 2109 descriptor->buffer_page_byte_0 = 0; 2110 descriptor->buffer_logical = NULL; 2111 descriptor->last_byte_address = 0; 2112 return descriptor; 2113 } 2114 2115 if (fStack->AllocateChunk(&descriptor->buffer_logical, 2116 &physicalAddress, bufferSize) != B_OK) { 2117 TRACE_ERROR("failed to allocate space for iso.buffer\n"); 2118 fStack->FreeChunk(descriptor, descriptor->physical_address, 2119 sizeof(ohci_isochronous_td)); 2120 return NULL; 2121 } 2122 descriptor->buffer_page_byte_0 = (uint32)physicalAddress; 2123 descriptor->last_byte_address 2124 = descriptor->buffer_page_byte_0 + bufferSize - 1; 2125 2126 return descriptor; 2127 } 2128 2129 2130 void 2131 OHCI::_FreeIsochronousDescriptor(ohci_isochronous_td *descriptor) 2132 { 2133 if (!descriptor) 2134 return; 2135 2136 if (descriptor->buffer_logical) { 2137 fStack->FreeChunk(descriptor->buffer_logical, 2138 descriptor->buffer_page_byte_0, descriptor->buffer_size); 2139 } 2140 2141 fStack->FreeChunk((void *)descriptor, descriptor->physical_address, 2142 sizeof(ohci_general_td)); 2143 } 2144 2145 2146 status_t 2147 OHCI::_CreateIsochronousDescriptorChain(ohci_isochronous_td **_firstDescriptor, 2148 ohci_isochronous_td **_lastDescriptor, Transfer *transfer) 2149 { 2150 Pipe *pipe = transfer->TransferPipe(); 2151 usb_isochronous_data *isochronousData = transfer->IsochronousData(); 2152 2153 size_t dataLength = transfer->FragmentLength(); 2154 size_t packet_count = isochronousData->packet_count; 2155 2156 if (packet_count == 0) { 2157 TRACE_ERROR("isochronous packet_count should not be equal to zero."); 2158 return B_BAD_VALUE; 2159 } 2160 2161 size_t packetSize = dataLength / packet_count; 2162 if (dataLength % packet_count != 0) 2163 packetSize++; 2164 2165 if (packetSize > pipe->MaxPacketSize()) { 2166 TRACE_ERROR("isochronous packetSize %ld is bigger" 2167 " than pipe MaxPacketSize %ld.", packetSize, pipe->MaxPacketSize()); 2168 return B_BAD_VALUE; 2169 } 2170 2171 uint16 bandwidth = transfer->Bandwidth() / packet_count; 2172 if (transfer->Bandwidth() % packet_count != 0) 2173 bandwidth++; 2174 2175 ohci_isochronous_td *firstDescriptor = NULL; 2176 ohci_isochronous_td *lastDescriptor = *_firstDescriptor; 2177 2178 // the frame number currently processed by the host controller 2179 uint16 currentFrame = fHcca->current_frame_number & 0xFFFF; 2180 uint16 safeFrames = 5; 2181 2182 // The entry where to start inserting the first Isochronous descriptor 2183 // real frame number may differ in case provided one has not bandwidth 2184 if (isochronousData->flags & USB_ISO_ASAP || 2185 isochronousData->starting_frame_number == NULL) 2186 // We should stay about 5-10 ms ahead of the controller 2187 // USB1 frame is equal to 1 ms 2188 currentFrame += safeFrames; 2189 else 2190 currentFrame = *isochronousData->starting_frame_number; 2191 2192 uint16 packets = packet_count; 2193 uint16 frameOffset = 0; 2194 while (packets > 0) { 2195 // look for up to 8 continous frames with available bandwidth 2196 uint16 frameCount = 0; 2197 while (frameCount < min_c(OHCI_ITD_NOFFSET, packets) 2198 && _AllocateIsochronousBandwidth(frameOffset + currentFrame 2199 + frameCount, bandwidth)) 2200 frameCount++; 2201 2202 if (frameCount == 0) { 2203 // starting frame has no bandwidth for our transaction - try next 2204 if (++frameOffset >= 0xFFFF) { 2205 TRACE_ERROR("failed to allocate bandwidth\n"); 2206 _FreeIsochronousDescriptorChain(firstDescriptor); 2207 return B_NO_MEMORY; 2208 } 2209 continue; 2210 } 2211 2212 ohci_isochronous_td *descriptor = _CreateIsochronousDescriptor( 2213 packetSize * frameCount); 2214 2215 if (!descriptor) { 2216 TRACE_ERROR("failed to allocate ITD\n"); 2217 _ReleaseIsochronousBandwidth(currentFrame + frameOffset, frameCount); 2218 _FreeIsochronousDescriptorChain(firstDescriptor); 2219 return B_NO_MEMORY; 2220 } 2221 2222 uint16 pageOffset = descriptor->buffer_page_byte_0 & 0xfff; 2223 descriptor->buffer_page_byte_0 &= ~0xfff; 2224 for (uint16 i = 0; i < frameCount; i++) { 2225 descriptor->offset[OHCI_ITD_OFFSET_IDX(i)] 2226 = OHCI_ITD_MK_OFFS(pageOffset + packetSize * i); 2227 } 2228 2229 descriptor->flags = OHCI_ITD_SET_FRAME_COUNT(frameCount) 2230 | OHCI_ITD_SET_CONDITION_CODE(OHCI_ITD_CONDITION_NOT_ACCESSED) 2231 | OHCI_ITD_SET_DELAY_INTERRUPT(OHCI_ITD_INTERRUPT_NONE) 2232 | OHCI_ITD_SET_STARTING_FRAME(currentFrame + frameOffset); 2233 2234 // the last packet may be shorter than other ones in this transfer 2235 if (packets <= OHCI_ITD_NOFFSET) 2236 descriptor->last_byte_address 2237 += dataLength - packetSize * (packet_count); 2238 2239 // link to previous 2240 if (lastDescriptor) 2241 _LinkIsochronousDescriptors(lastDescriptor, descriptor, descriptor); 2242 2243 lastDescriptor = descriptor; 2244 if (!firstDescriptor) 2245 firstDescriptor = descriptor; 2246 2247 packets -= frameCount; 2248 2249 frameOffset += frameCount; 2250 2251 if (packets == 0 && isochronousData->starting_frame_number) 2252 *isochronousData->starting_frame_number = currentFrame + frameOffset; 2253 } 2254 2255 *_firstDescriptor = firstDescriptor; 2256 *_lastDescriptor = lastDescriptor; 2257 2258 return B_OK; 2259 } 2260 2261 2262 void 2263 OHCI::_FreeIsochronousDescriptorChain(ohci_isochronous_td *topDescriptor) 2264 { 2265 ohci_isochronous_td *current = topDescriptor; 2266 ohci_isochronous_td *next = NULL; 2267 2268 while (current) { 2269 next = (ohci_isochronous_td *)current->next_done_descriptor; 2270 _FreeIsochronousDescriptor(current); 2271 current = next; 2272 } 2273 } 2274 2275 2276 size_t 2277 OHCI::_WriteDescriptorChain(ohci_general_td *topDescriptor, generic_io_vec *vector, 2278 size_t vectorCount, bool physical) 2279 { 2280 ohci_general_td *current = topDescriptor; 2281 size_t actualLength = 0; 2282 size_t vectorIndex = 0; 2283 size_t vectorOffset = 0; 2284 size_t bufferOffset = 0; 2285 2286 while (current) { 2287 if (!current->buffer_logical) 2288 break; 2289 2290 while (true) { 2291 size_t length = min_c(current->buffer_size - bufferOffset, 2292 vector[vectorIndex].length - vectorOffset); 2293 2294 TRACE("copying %ld bytes to bufferOffset %ld from" 2295 " vectorOffset %ld at index %ld of %ld\n", length, bufferOffset, 2296 vectorOffset, vectorIndex, vectorCount); 2297 status_t status = generic_memcpy( 2298 (generic_addr_t)current->buffer_logical + bufferOffset, false, 2299 vector[vectorIndex].base + vectorOffset, physical, length); 2300 ASSERT_ALWAYS(status == B_OK); 2301 2302 actualLength += length; 2303 vectorOffset += length; 2304 bufferOffset += length; 2305 2306 if (vectorOffset >= vector[vectorIndex].length) { 2307 if (++vectorIndex >= vectorCount) { 2308 TRACE("wrote descriptor chain (%ld bytes, no" 2309 " more vectors)\n", actualLength); 2310 return actualLength; 2311 } 2312 2313 vectorOffset = 0; 2314 } 2315 2316 if (bufferOffset >= current->buffer_size) { 2317 bufferOffset = 0; 2318 break; 2319 } 2320 } 2321 2322 if (!current->next_logical_descriptor) 2323 break; 2324 2325 current = (ohci_general_td *)current->next_logical_descriptor; 2326 } 2327 2328 TRACE("wrote descriptor chain (%ld bytes)\n", actualLength); 2329 return actualLength; 2330 } 2331 2332 2333 size_t 2334 OHCI::_WriteIsochronousDescriptorChain(ohci_isochronous_td *topDescriptor, 2335 generic_io_vec *vector, size_t vectorCount, bool physical) 2336 { 2337 ohci_isochronous_td *current = topDescriptor; 2338 size_t actualLength = 0; 2339 size_t vectorIndex = 0; 2340 size_t vectorOffset = 0; 2341 size_t bufferOffset = 0; 2342 2343 while (current) { 2344 if (!current->buffer_logical) 2345 break; 2346 2347 while (true) { 2348 size_t length = min_c(current->buffer_size - bufferOffset, 2349 vector[vectorIndex].length - vectorOffset); 2350 2351 TRACE("copying %ld bytes to bufferOffset %ld from" 2352 " vectorOffset %ld at index %ld of %ld\n", length, bufferOffset, 2353 vectorOffset, vectorIndex, vectorCount); 2354 status_t status = generic_memcpy( 2355 (generic_addr_t)current->buffer_logical + bufferOffset, false, 2356 vector[vectorIndex].base + vectorOffset, physical, length); 2357 ASSERT_ALWAYS(status == B_OK); 2358 2359 actualLength += length; 2360 vectorOffset += length; 2361 bufferOffset += length; 2362 2363 if (vectorOffset >= vector[vectorIndex].length) { 2364 if (++vectorIndex >= vectorCount) { 2365 TRACE("wrote descriptor chain (%ld bytes, no" 2366 " more vectors)\n", actualLength); 2367 return actualLength; 2368 } 2369 2370 vectorOffset = 0; 2371 } 2372 2373 if (bufferOffset >= current->buffer_size) { 2374 bufferOffset = 0; 2375 break; 2376 } 2377 } 2378 2379 if (!current->next_logical_descriptor) 2380 break; 2381 2382 current = (ohci_isochronous_td *)current->next_logical_descriptor; 2383 } 2384 2385 TRACE("wrote descriptor chain (%ld bytes)\n", actualLength); 2386 return actualLength; 2387 } 2388 2389 2390 size_t 2391 OHCI::_ReadDescriptorChain(ohci_general_td *topDescriptor, generic_io_vec *vector, 2392 size_t vectorCount, bool physical) 2393 { 2394 ohci_general_td *current = topDescriptor; 2395 size_t actualLength = 0; 2396 size_t vectorIndex = 0; 2397 size_t vectorOffset = 0; 2398 size_t bufferOffset = 0; 2399 2400 while (current && OHCI_TD_GET_CONDITION_CODE(current->flags) 2401 != OHCI_TD_CONDITION_NOT_ACCESSED) { 2402 if (!current->buffer_logical) 2403 break; 2404 2405 size_t bufferSize = current->buffer_size; 2406 if (current->buffer_physical != 0) { 2407 bufferSize -= current->last_physical_byte_address 2408 - current->buffer_physical + 1; 2409 } 2410 2411 while (true) { 2412 size_t length = min_c(bufferSize - bufferOffset, 2413 vector[vectorIndex].length - vectorOffset); 2414 2415 TRACE("copying %ld bytes to vectorOffset %ld from" 2416 " bufferOffset %ld at index %ld of %ld\n", length, vectorOffset, 2417 bufferOffset, vectorIndex, vectorCount); 2418 status_t status = generic_memcpy( 2419 vector[vectorIndex].base + vectorOffset, physical, 2420 (generic_addr_t)current->buffer_logical + bufferOffset, false, length); 2421 ASSERT_ALWAYS(status == B_OK); 2422 2423 actualLength += length; 2424 vectorOffset += length; 2425 bufferOffset += length; 2426 2427 if (vectorOffset >= vector[vectorIndex].length) { 2428 if (++vectorIndex >= vectorCount) { 2429 TRACE("read descriptor chain (%ld bytes, no more vectors)\n", 2430 actualLength); 2431 return actualLength; 2432 } 2433 2434 vectorOffset = 0; 2435 } 2436 2437 if (bufferOffset >= bufferSize) { 2438 bufferOffset = 0; 2439 break; 2440 } 2441 } 2442 2443 current = (ohci_general_td *)current->next_logical_descriptor; 2444 } 2445 2446 TRACE("read descriptor chain (%ld bytes)\n", actualLength); 2447 return actualLength; 2448 } 2449 2450 2451 void 2452 OHCI::_ReadIsochronousDescriptorChain(ohci_isochronous_td *topDescriptor, 2453 generic_io_vec *vector, size_t vectorCount, bool physical) 2454 { 2455 ohci_isochronous_td *current = topDescriptor; 2456 size_t actualLength = 0; 2457 size_t vectorIndex = 0; 2458 size_t vectorOffset = 0; 2459 size_t bufferOffset = 0; 2460 2461 while (current && OHCI_ITD_GET_CONDITION_CODE(current->flags) 2462 != OHCI_ITD_CONDITION_NOT_ACCESSED) { 2463 size_t bufferSize = current->buffer_size; 2464 if (current->buffer_logical != NULL && bufferSize > 0) { 2465 while (true) { 2466 size_t length = min_c(bufferSize - bufferOffset, 2467 vector[vectorIndex].length - vectorOffset); 2468 2469 TRACE("copying %ld bytes to vectorOffset %ld from bufferOffset" 2470 " %ld at index %ld of %ld\n", length, vectorOffset, 2471 bufferOffset, vectorIndex, vectorCount); 2472 status_t status = generic_memcpy( 2473 vector[vectorIndex].base + vectorOffset, physical, 2474 (generic_addr_t)current->buffer_logical + bufferOffset, false, length); 2475 ASSERT_ALWAYS(status == B_OK); 2476 2477 actualLength += length; 2478 vectorOffset += length; 2479 bufferOffset += length; 2480 2481 if (vectorOffset >= vector[vectorIndex].length) { 2482 if (++vectorIndex >= vectorCount) { 2483 TRACE("read descriptor chain (%ld bytes, " 2484 "no more vectors)\n", actualLength); 2485 return; 2486 } 2487 2488 vectorOffset = 0; 2489 } 2490 2491 if (bufferOffset >= bufferSize) { 2492 bufferOffset = 0; 2493 break; 2494 } 2495 } 2496 } 2497 2498 current = (ohci_isochronous_td *)current->next_done_descriptor; 2499 } 2500 2501 TRACE("read descriptor chain (%ld bytes)\n", actualLength); 2502 return; 2503 } 2504 2505 2506 size_t 2507 OHCI::_ReadActualLength(ohci_general_td *topDescriptor) 2508 { 2509 ohci_general_td *current = topDescriptor; 2510 size_t actualLength = 0; 2511 2512 while (current && OHCI_TD_GET_CONDITION_CODE(current->flags) 2513 != OHCI_TD_CONDITION_NOT_ACCESSED) { 2514 size_t length = current->buffer_size; 2515 if (current->buffer_physical != 0) { 2516 length -= current->last_physical_byte_address 2517 - current->buffer_physical + 1; 2518 } 2519 2520 actualLength += length; 2521 current = (ohci_general_td *)current->next_logical_descriptor; 2522 } 2523 2524 TRACE("read actual length (%ld bytes)\n", actualLength); 2525 return actualLength; 2526 } 2527 2528 2529 void 2530 OHCI::_LinkDescriptors(ohci_general_td *first, ohci_general_td *second) 2531 { 2532 first->next_physical_descriptor = second->physical_address; 2533 first->next_logical_descriptor = second; 2534 } 2535 2536 2537 void 2538 OHCI::_LinkIsochronousDescriptors(ohci_isochronous_td *first, 2539 ohci_isochronous_td *second, ohci_isochronous_td *nextDone) 2540 { 2541 first->next_physical_descriptor = second->physical_address; 2542 first->next_logical_descriptor = second; 2543 first->next_done_descriptor = nextDone; 2544 } 2545 2546 2547 bool 2548 OHCI::_AllocateIsochronousBandwidth(uint16 frame, uint16 size) 2549 { 2550 frame %= NUMBER_OF_FRAMES; 2551 if (size > fFrameBandwidth[frame]) 2552 return false; 2553 2554 fFrameBandwidth[frame]-= size; 2555 return true; 2556 } 2557 2558 2559 void 2560 OHCI::_ReleaseIsochronousBandwidth(uint16 startFrame, uint16 frameCount) 2561 { 2562 for (size_t index = 0; index < frameCount; index++) { 2563 uint16 frame = (startFrame + index) % NUMBER_OF_FRAMES; 2564 fFrameBandwidth[frame] = MAX_AVAILABLE_BANDWIDTH; 2565 } 2566 } 2567 2568 2569 status_t 2570 OHCI::_GetStatusOfConditionCode(uint8 conditionCode) 2571 { 2572 switch (conditionCode) { 2573 case OHCI_TD_CONDITION_NO_ERROR: 2574 return B_OK; 2575 2576 case OHCI_TD_CONDITION_CRC_ERROR: 2577 case OHCI_TD_CONDITION_BIT_STUFFING: 2578 case OHCI_TD_CONDITION_TOGGLE_MISMATCH: 2579 return B_DEV_CRC_ERROR; 2580 2581 case OHCI_TD_CONDITION_STALL: 2582 return B_DEV_STALLED; 2583 2584 case OHCI_TD_CONDITION_NO_RESPONSE: 2585 return B_TIMED_OUT; 2586 2587 case OHCI_TD_CONDITION_PID_CHECK_FAILURE: 2588 return B_DEV_BAD_PID; 2589 2590 case OHCI_TD_CONDITION_UNEXPECTED_PID: 2591 return B_DEV_UNEXPECTED_PID; 2592 2593 case OHCI_TD_CONDITION_DATA_OVERRUN: 2594 return B_DEV_DATA_OVERRUN; 2595 2596 case OHCI_TD_CONDITION_DATA_UNDERRUN: 2597 return B_DEV_DATA_UNDERRUN; 2598 2599 case OHCI_TD_CONDITION_BUFFER_OVERRUN: 2600 return B_DEV_WRITE_ERROR; 2601 2602 case OHCI_TD_CONDITION_BUFFER_UNDERRUN: 2603 return B_DEV_READ_ERROR; 2604 2605 case OHCI_TD_CONDITION_NOT_ACCESSED: 2606 return B_DEV_PENDING; 2607 2608 case 0x0E: 2609 return B_DEV_TOO_LATE; // PSW: _NOT_ACCESSED 2610 2611 default: 2612 break; 2613 } 2614 2615 return B_ERROR; 2616 } 2617 2618 2619 bool 2620 OHCI::_LockEndpoints() 2621 { 2622 return (mutex_lock(&fEndpointLock) == B_OK); 2623 } 2624 2625 2626 void 2627 OHCI::_UnlockEndpoints() 2628 { 2629 mutex_unlock(&fEndpointLock); 2630 } 2631 2632 2633 inline void 2634 OHCI::_WriteReg(uint32 reg, uint32 value) 2635 { 2636 *(volatile uint32 *)(fOperationalRegisters + reg) = value; 2637 } 2638 2639 2640 inline uint32 2641 OHCI::_ReadReg(uint32 reg) 2642 { 2643 return *(volatile uint32 *)(fOperationalRegisters + reg); 2644 } 2645 2646 2647 void 2648 OHCI::_PrintEndpoint(ohci_endpoint_descriptor *endpoint) 2649 { 2650 dprintf("endpoint %p\n", endpoint); 2651 dprintf("\tflags........... 0x%08" B_PRIx32 "\n", endpoint->flags); 2652 dprintf("\ttail_physical... 0x%08" B_PRIx32 "\n", endpoint->tail_physical_descriptor); 2653 dprintf("\thead_physical... 0x%08" B_PRIx32 "\n", endpoint->head_physical_descriptor); 2654 dprintf("\tnext_physical... 0x%08" B_PRIx32 "\n", endpoint->next_physical_endpoint); 2655 dprintf("\tphysical........ 0x%08" B_PRIx32 "\n", endpoint->physical_address); 2656 dprintf("\ttail_logical.... %p\n", endpoint->tail_logical_descriptor); 2657 dprintf("\tnext_logical.... %p\n", endpoint->next_logical_endpoint); 2658 } 2659 2660 2661 void 2662 OHCI::_PrintDescriptorChain(ohci_general_td *topDescriptor) 2663 { 2664 while (topDescriptor) { 2665 dprintf("descriptor %p\n", topDescriptor); 2666 dprintf("\tflags........... 0x%08" B_PRIx32 "\n", topDescriptor->flags); 2667 dprintf("\tbuffer_physical. 0x%08" B_PRIx32 "\n", topDescriptor->buffer_physical); 2668 dprintf("\tnext_physical... 0x%08" B_PRIx32 "\n", topDescriptor->next_physical_descriptor); 2669 dprintf("\tlast_byte....... 0x%08" B_PRIx32 "\n", topDescriptor->last_physical_byte_address); 2670 dprintf("\tphysical........ 0x%08" B_PRIx32 "\n", topDescriptor->physical_address); 2671 dprintf("\tbuffer_size..... %lu\n", topDescriptor->buffer_size); 2672 dprintf("\tbuffer_logical.. %p\n", topDescriptor->buffer_logical); 2673 dprintf("\tnext_logical.... %p\n", topDescriptor->next_logical_descriptor); 2674 2675 topDescriptor = (ohci_general_td *)topDescriptor->next_logical_descriptor; 2676 } 2677 } 2678 2679 2680 void 2681 OHCI::_PrintDescriptorChain(ohci_isochronous_td *topDescriptor) 2682 { 2683 while (topDescriptor) { 2684 dprintf("iso.descriptor %p\n", topDescriptor); 2685 dprintf("\tflags........... 0x%08" B_PRIx32 "\n", topDescriptor->flags); 2686 dprintf("\tbuffer_pagebyte0 0x%08" B_PRIx32 "\n", topDescriptor->buffer_page_byte_0); 2687 dprintf("\tnext_physical... 0x%08" B_PRIx32 "\n", topDescriptor->next_physical_descriptor); 2688 dprintf("\tlast_byte....... 0x%08" B_PRIx32 "\n", topDescriptor->last_byte_address); 2689 dprintf("\toffset:\n\t0x%04x 0x%04x 0x%04x 0x%04x\n" 2690 "\t0x%04x 0x%04x 0x%04x 0x%04x\n", 2691 topDescriptor->offset[0], topDescriptor->offset[1], 2692 topDescriptor->offset[2], topDescriptor->offset[3], 2693 topDescriptor->offset[4], topDescriptor->offset[5], 2694 topDescriptor->offset[6], topDescriptor->offset[7]); 2695 dprintf("\tphysical........ 0x%08" B_PRIx32 "\n", topDescriptor->physical_address); 2696 dprintf("\tbuffer_size..... %lu\n", topDescriptor->buffer_size); 2697 dprintf("\tbuffer_logical.. %p\n", topDescriptor->buffer_logical); 2698 dprintf("\tnext_logical.... %p\n", topDescriptor->next_logical_descriptor); 2699 dprintf("\tnext_done....... %p\n", topDescriptor->next_done_descriptor); 2700 2701 topDescriptor = (ohci_isochronous_td *)topDescriptor->next_done_descriptor; 2702 } 2703 } 2704 2705