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 (pipe->Type() & USB_OBJECT_ISO_PIPE) { 708 ohci_isochronous_td *descriptor 709 = (ohci_isochronous_td *)current->first_descriptor; 710 while (descriptor) { 711 uint16 frame = OHCI_ITD_GET_STARTING_FRAME( 712 descriptor->flags); 713 _ReleaseIsochronousBandwidth(frame, 714 OHCI_ITD_GET_FRAME_COUNT(descriptor->flags)); 715 if (descriptor 716 == (ohci_isochronous_td*)current->last_descriptor) 717 // this is the last ITD of the transfer 718 break; 719 720 descriptor 721 = (ohci_isochronous_td *) 722 descriptor->next_done_descriptor; 723 } 724 } 725 726 transfer_entry *entry 727 = (transfer_entry *)malloc(sizeof(transfer_entry)); 728 if (entry != NULL) { 729 entry->transfer = current->transfer; 730 current->transfer = NULL; 731 entry->next = list; 732 list = entry; 733 } 734 735 current->canceled = true; 736 } 737 current = current->link; 738 } 739 740 Unlock(); 741 742 while (list != NULL) { 743 transfer_entry *next = list->next; 744 745 // If the transfer is canceled by force, the one causing the 746 // cancel is possibly not the one who initiated the transfer 747 // and the callback is likely not safe anymore 748 if (!force) 749 list->transfer->Finished(B_CANCELED, 0); 750 751 delete list->transfer; 752 free(list); 753 list = next; 754 } 755 756 // wait for any transfers that might have made it before canceling 757 while (fProcessingPipe == pipe) 758 snooze(1000); 759 760 // notify the finisher so it can clean up the canceled transfers 761 release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE); 762 return B_OK; 763 } 764 765 766 status_t 767 OHCI::NotifyPipeChange(Pipe *pipe, usb_change change) 768 { 769 TRACE("pipe change %d for pipe %p\n", change, pipe); 770 if (pipe->DeviceAddress() == fRootHubAddress) { 771 // no need to insert/remove endpoint descriptors for the root hub 772 return B_OK; 773 } 774 775 switch (change) { 776 case USB_CHANGE_CREATED: 777 return _InsertEndpointForPipe(pipe); 778 779 case USB_CHANGE_DESTROYED: 780 return _RemoveEndpointForPipe(pipe); 781 782 case USB_CHANGE_PIPE_POLICY_CHANGED: 783 TRACE("pipe policy changing unhandled!\n"); 784 break; 785 786 default: 787 TRACE_ERROR("unknown pipe change!\n"); 788 return B_ERROR; 789 } 790 791 return B_OK; 792 } 793 794 795 status_t 796 OHCI::GetPortStatus(uint8 index, usb_port_status *status) 797 { 798 if (index >= fPortCount) { 799 TRACE_ERROR("get port status for invalid port %u\n", index); 800 return B_BAD_INDEX; 801 } 802 803 status->status = status->change = 0; 804 uint32 portStatus = _ReadReg(OHCI_RH_PORT_STATUS(index)); 805 806 // status 807 if (portStatus & OHCI_RH_PORTSTATUS_CCS) 808 status->status |= PORT_STATUS_CONNECTION; 809 if (portStatus & OHCI_RH_PORTSTATUS_PES) 810 status->status |= PORT_STATUS_ENABLE; 811 if (portStatus & OHCI_RH_PORTSTATUS_PSS) 812 status->status |= PORT_STATUS_SUSPEND; 813 if (portStatus & OHCI_RH_PORTSTATUS_POCI) 814 status->status |= PORT_STATUS_OVER_CURRENT; 815 if (portStatus & OHCI_RH_PORTSTATUS_PRS) 816 status->status |= PORT_STATUS_RESET; 817 if (portStatus & OHCI_RH_PORTSTATUS_PPS) 818 status->status |= PORT_STATUS_POWER; 819 if (portStatus & OHCI_RH_PORTSTATUS_LSDA) 820 status->status |= PORT_STATUS_LOW_SPEED; 821 822 // change 823 if (portStatus & OHCI_RH_PORTSTATUS_CSC) 824 status->change |= PORT_STATUS_CONNECTION; 825 if (portStatus & OHCI_RH_PORTSTATUS_PESC) 826 status->change |= PORT_STATUS_ENABLE; 827 if (portStatus & OHCI_RH_PORTSTATUS_PSSC) 828 status->change |= PORT_STATUS_SUSPEND; 829 if (portStatus & OHCI_RH_PORTSTATUS_OCIC) 830 status->change |= PORT_STATUS_OVER_CURRENT; 831 if (portStatus & OHCI_RH_PORTSTATUS_PRSC) 832 status->change |= PORT_STATUS_RESET; 833 834 TRACE("port %u status 0x%04x change 0x%04x\n", index, 835 status->status, status->change); 836 return B_OK; 837 } 838 839 840 status_t 841 OHCI::SetPortFeature(uint8 index, uint16 feature) 842 { 843 TRACE("set port feature index %u feature %u\n", index, feature); 844 if (index > fPortCount) 845 return B_BAD_INDEX; 846 847 switch (feature) { 848 case PORT_ENABLE: 849 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PES); 850 return B_OK; 851 852 case PORT_SUSPEND: 853 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PSS); 854 return B_OK; 855 856 case PORT_RESET: 857 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PRS); 858 return B_OK; 859 860 case PORT_POWER: 861 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PPS); 862 return B_OK; 863 } 864 865 return B_BAD_VALUE; 866 } 867 868 869 status_t 870 OHCI::ClearPortFeature(uint8 index, uint16 feature) 871 { 872 TRACE("clear port feature index %u feature %u\n", index, feature); 873 if (index > fPortCount) 874 return B_BAD_INDEX; 875 876 switch (feature) { 877 case PORT_ENABLE: 878 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CCS); 879 return B_OK; 880 881 case PORT_SUSPEND: 882 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_POCI); 883 return B_OK; 884 885 case PORT_POWER: 886 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_LSDA); 887 return B_OK; 888 889 case C_PORT_CONNECTION: 890 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CSC); 891 return B_OK; 892 893 case C_PORT_ENABLE: 894 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PESC); 895 return B_OK; 896 897 case C_PORT_SUSPEND: 898 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PSSC); 899 return B_OK; 900 901 case C_PORT_OVER_CURRENT: 902 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_OCIC); 903 return B_OK; 904 905 case C_PORT_RESET: 906 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PRSC); 907 return B_OK; 908 } 909 910 return B_BAD_VALUE; 911 } 912 913 914 int32 915 OHCI::_InterruptHandler(void *data) 916 { 917 return ((OHCI *)data)->_Interrupt(); 918 } 919 920 921 int32 922 OHCI::_Interrupt() 923 { 924 static spinlock lock = B_SPINLOCK_INITIALIZER; 925 acquire_spinlock(&lock); 926 927 uint32 status = 0; 928 uint32 acknowledge = 0; 929 bool finishTransfers = false; 930 int32 result = B_HANDLED_INTERRUPT; 931 932 // The LSb of done_head is used to inform the HCD that an interrupt 933 // condition exists for both the done list and for another event recorded in 934 // the HcInterruptStatus register. If done_head is 0, then the interrupt 935 // was caused by other than the HccaDoneHead update and the 936 // HcInterruptStatus register needs to be accessed to determine that exact 937 // interrupt cause. If HccDoneHead is nonzero, then a done list update 938 // interrupt is indicated and if the LSb of the Dword is nonzero, then an 939 // additional interrupt event is indicated and HcInterruptStatus should be 940 // checked to determine its cause. 941 uint32 doneHead = fHcca->done_head; 942 if (doneHead != 0) { 943 status = OHCI_WRITEBACK_DONE_HEAD; 944 if (doneHead & OHCI_DONE_INTERRUPTS) 945 status |= _ReadReg(OHCI_INTERRUPT_STATUS) 946 & _ReadReg(OHCI_INTERRUPT_ENABLE); 947 } else { 948 status = _ReadReg(OHCI_INTERRUPT_STATUS) & _ReadReg(OHCI_INTERRUPT_ENABLE) 949 & ~OHCI_WRITEBACK_DONE_HEAD; 950 if (status == 0) { 951 // Nothing to be done (PCI shared interrupt) 952 release_spinlock(&lock); 953 return B_UNHANDLED_INTERRUPT; 954 } 955 } 956 957 if (status & OHCI_SCHEDULING_OVERRUN) { 958 TRACE_MODULE("scheduling overrun occured\n"); 959 acknowledge |= OHCI_SCHEDULING_OVERRUN; 960 } 961 962 if (status & OHCI_WRITEBACK_DONE_HEAD) { 963 TRACE_MODULE("transfer descriptors processed\n"); 964 fHcca->done_head = 0; 965 acknowledge |= OHCI_WRITEBACK_DONE_HEAD; 966 result = B_INVOKE_SCHEDULER; 967 finishTransfers = true; 968 } 969 970 if (status & OHCI_RESUME_DETECTED) { 971 TRACE_MODULE("resume detected\n"); 972 acknowledge |= OHCI_RESUME_DETECTED; 973 } 974 975 if (status & OHCI_UNRECOVERABLE_ERROR) { 976 TRACE_MODULE_ERROR("unrecoverable error - controller halted\n"); 977 _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET); 978 // TODO: clear all pending transfers, reset and resetup the controller 979 } 980 981 if (status & OHCI_ROOT_HUB_STATUS_CHANGE) { 982 TRACE_MODULE("root hub status change\n"); 983 // Disable the interrupt as it will otherwise be retriggered until the 984 // port has been reset and the change is cleared explicitly. 985 // TODO: renable it once we use status changes instead of polling 986 _WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ROOT_HUB_STATUS_CHANGE); 987 acknowledge |= OHCI_ROOT_HUB_STATUS_CHANGE; 988 } 989 990 if (acknowledge != 0) 991 _WriteReg(OHCI_INTERRUPT_STATUS, acknowledge); 992 993 release_spinlock(&lock); 994 995 if (finishTransfers) 996 release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE); 997 998 return result; 999 } 1000 1001 1002 status_t 1003 OHCI::_AddPendingTransfer(Transfer *transfer, 1004 ohci_endpoint_descriptor *endpoint, ohci_general_td *firstDescriptor, 1005 ohci_general_td *dataDescriptor, ohci_general_td *lastDescriptor, 1006 bool directionIn) 1007 { 1008 if (!transfer || !endpoint || !lastDescriptor) 1009 return B_BAD_VALUE; 1010 1011 transfer_data *data = new(std::nothrow) transfer_data; 1012 if (!data) 1013 return B_NO_MEMORY; 1014 1015 status_t result = transfer->InitKernelAccess(); 1016 if (result < B_OK) { 1017 delete data; 1018 return result; 1019 } 1020 1021 data->transfer = transfer; 1022 data->endpoint = endpoint; 1023 data->incoming = directionIn; 1024 data->canceled = false; 1025 data->link = NULL; 1026 1027 // the current tail will become the first descriptor 1028 data->first_descriptor = (ohci_general_td *)endpoint->tail_logical_descriptor; 1029 1030 // the data and first descriptors might be the same 1031 if (dataDescriptor == firstDescriptor) 1032 data->data_descriptor = data->first_descriptor; 1033 else 1034 data->data_descriptor = dataDescriptor; 1035 1036 // even the last and the first descriptor might be the same 1037 if (lastDescriptor == firstDescriptor) 1038 data->last_descriptor = data->first_descriptor; 1039 else 1040 data->last_descriptor = lastDescriptor; 1041 1042 if (!Lock()) { 1043 delete data; 1044 return B_ERROR; 1045 } 1046 1047 if (fLastTransfer) 1048 fLastTransfer->link = data; 1049 else 1050 fFirstTransfer = data; 1051 1052 fLastTransfer = data; 1053 Unlock(); 1054 1055 return B_OK; 1056 } 1057 1058 1059 status_t 1060 OHCI::_AddPendingIsochronousTransfer(Transfer *transfer, 1061 ohci_endpoint_descriptor *endpoint, ohci_isochronous_td *firstDescriptor, 1062 ohci_isochronous_td *lastDescriptor, bool directionIn) 1063 { 1064 if (!transfer || !endpoint || !lastDescriptor) 1065 return B_BAD_VALUE; 1066 1067 transfer_data *data = new(std::nothrow) transfer_data; 1068 if (!data) 1069 return B_NO_MEMORY; 1070 1071 status_t result = transfer->InitKernelAccess(); 1072 if (result < B_OK) { 1073 delete data; 1074 return result; 1075 } 1076 1077 data->transfer = transfer; 1078 data->endpoint = endpoint; 1079 data->incoming = directionIn; 1080 data->canceled = false; 1081 data->link = NULL; 1082 1083 // the current tail will become the first descriptor 1084 data->first_descriptor = (ohci_general_td*)endpoint->tail_logical_descriptor; 1085 1086 // the data and first descriptors are the same 1087 data->data_descriptor = data->first_descriptor; 1088 1089 // the last and the first descriptor might be the same 1090 if (lastDescriptor == firstDescriptor) 1091 data->last_descriptor = data->first_descriptor; 1092 else 1093 data->last_descriptor = (ohci_general_td*)lastDescriptor; 1094 1095 if (!Lock()) { 1096 delete data; 1097 return B_ERROR; 1098 } 1099 1100 if (fLastTransfer) 1101 fLastTransfer->link = data; 1102 else 1103 fFirstTransfer = data; 1104 1105 fLastTransfer = data; 1106 Unlock(); 1107 1108 return B_OK; 1109 } 1110 1111 1112 int32 1113 OHCI::_FinishThread(void *data) 1114 { 1115 ((OHCI *)data)->_FinishTransfers(); 1116 return B_OK; 1117 } 1118 1119 1120 void 1121 OHCI::_FinishTransfers() 1122 { 1123 while (!fStopFinishThread) { 1124 if (acquire_sem(fFinishTransfersSem) < B_OK) 1125 continue; 1126 1127 // eat up sems that have been released by multiple interrupts 1128 int32 semCount = 0; 1129 get_sem_count(fFinishTransfersSem, &semCount); 1130 if (semCount > 0) 1131 acquire_sem_etc(fFinishTransfersSem, semCount, B_RELATIVE_TIMEOUT, 0); 1132 1133 if (!Lock()) 1134 continue; 1135 1136 TRACE("finishing transfers (first transfer: %p; last" 1137 " transfer: %p)\n", fFirstTransfer, fLastTransfer); 1138 transfer_data *lastTransfer = NULL; 1139 transfer_data *transfer = fFirstTransfer; 1140 Unlock(); 1141 1142 while (transfer) { 1143 bool transferDone = false; 1144 ohci_general_td *descriptor = transfer->first_descriptor; 1145 ohci_endpoint_descriptor *endpoint = transfer->endpoint; 1146 status_t callbackStatus = B_OK; 1147 1148 if (endpoint->flags & OHCI_ENDPOINT_ISOCHRONOUS_FORMAT) { 1149 transfer_data *next = transfer->link; 1150 if (_FinishIsochronousTransfer(transfer, &lastTransfer)) { 1151 delete transfer->transfer; 1152 delete transfer; 1153 } 1154 transfer = next; 1155 continue; 1156 } 1157 1158 MutexLocker endpointLocker(endpoint->lock); 1159 1160 if ((endpoint->head_physical_descriptor & OHCI_ENDPOINT_HEAD_MASK) 1161 != endpoint->tail_physical_descriptor 1162 && (endpoint->head_physical_descriptor 1163 & OHCI_ENDPOINT_HALTED) == 0) { 1164 // there are still active transfers on this endpoint, we need 1165 // to wait for all of them to complete, otherwise we'd read 1166 // a potentially bogus data toggle value below 1167 TRACE("endpoint %p still has active tds\n", endpoint); 1168 lastTransfer = transfer; 1169 transfer = transfer->link; 1170 continue; 1171 } 1172 1173 endpointLocker.Unlock(); 1174 1175 while (descriptor && !transfer->canceled) { 1176 uint32 status = OHCI_TD_GET_CONDITION_CODE(descriptor->flags); 1177 if (status == OHCI_TD_CONDITION_NOT_ACCESSED) { 1178 // td is still active 1179 TRACE("td %p still active\n", descriptor); 1180 break; 1181 } 1182 1183 if (status != OHCI_TD_CONDITION_NO_ERROR) { 1184 // an error occured, but we must ensure that the td 1185 // was actually done 1186 if (endpoint->head_physical_descriptor & OHCI_ENDPOINT_HALTED) { 1187 // the endpoint is halted, this guaratees us that this 1188 // descriptor has passed (we don't know if the endpoint 1189 // was halted because of this td, but we do not need 1190 // to know, as when it was halted by another td this 1191 // still ensures that this td was handled before). 1192 TRACE_ERROR("td error: 0x%08" B_PRIx32 "\n", status); 1193 1194 callbackStatus = _GetStatusOfConditionCode(status); 1195 1196 transferDone = true; 1197 break; 1198 } else { 1199 // an error occured but the endpoint is not halted so 1200 // the td is in fact still active 1201 TRACE("td %p active with error\n", descriptor); 1202 break; 1203 } 1204 } 1205 1206 // the td has completed without an error 1207 TRACE("td %p done\n", descriptor); 1208 1209 if (descriptor == transfer->last_descriptor 1210 || descriptor->buffer_physical != 0) { 1211 // this is the last td of the transfer or a short packet 1212 callbackStatus = B_OK; 1213 transferDone = true; 1214 break; 1215 } 1216 1217 descriptor 1218 = (ohci_general_td *)descriptor->next_logical_descriptor; 1219 } 1220 1221 if (transfer->canceled) { 1222 // when a transfer is canceled, all transfers to that endpoint 1223 // are canceled by setting the head pointer to the tail pointer 1224 // which causes all of the tds to become "free" (as they are 1225 // inaccessible and not accessed anymore (as setting the head 1226 // pointer required disabling the endpoint)) 1227 callbackStatus = B_OK; 1228 transferDone = true; 1229 } 1230 1231 if (!transferDone) { 1232 lastTransfer = transfer; 1233 transfer = transfer->link; 1234 continue; 1235 } 1236 1237 // remove the transfer from the list first so we are sure 1238 // it doesn't get canceled while we still process it 1239 transfer_data *next = transfer->link; 1240 if (Lock()) { 1241 if (lastTransfer) 1242 lastTransfer->link = transfer->link; 1243 1244 if (transfer == fFirstTransfer) 1245 fFirstTransfer = transfer->link; 1246 if (transfer == fLastTransfer) 1247 fLastTransfer = lastTransfer; 1248 1249 // store the currently processing pipe here so we can wait 1250 // in cancel if we are processing something on the target pipe 1251 if (!transfer->canceled) 1252 fProcessingPipe = transfer->transfer->TransferPipe(); 1253 1254 transfer->link = NULL; 1255 Unlock(); 1256 } 1257 1258 // break the descriptor chain on the last descriptor 1259 transfer->last_descriptor->next_logical_descriptor = NULL; 1260 TRACE("transfer %p done with status 0x%08" B_PRIx32 "\n", 1261 transfer, callbackStatus); 1262 1263 // if canceled the callback has already been called 1264 if (!transfer->canceled) { 1265 size_t actualLength = 0; 1266 if (callbackStatus == B_OK) { 1267 if (transfer->data_descriptor && transfer->incoming) { 1268 // data to read out 1269 generic_io_vec *vector = transfer->transfer->Vector(); 1270 size_t vectorCount = transfer->transfer->VectorCount(); 1271 1272 transfer->transfer->PrepareKernelAccess(); 1273 actualLength = _ReadDescriptorChain( 1274 transfer->data_descriptor, 1275 vector, vectorCount, transfer->transfer->IsPhysical()); 1276 } else if (transfer->data_descriptor) { 1277 // read the actual length that was sent 1278 actualLength = _ReadActualLength( 1279 transfer->data_descriptor); 1280 } 1281 1282 // get the last data toggle and store it for next time 1283 transfer->transfer->TransferPipe()->SetDataToggle( 1284 (endpoint->head_physical_descriptor 1285 & OHCI_ENDPOINT_TOGGLE_CARRY) != 0); 1286 1287 if (transfer->transfer->IsFragmented()) { 1288 // this transfer may still have data left 1289 TRACE("advancing fragmented transfer\n"); 1290 transfer->transfer->AdvanceByFragment(actualLength); 1291 if (transfer->transfer->FragmentLength() > 0) { 1292 TRACE("still %ld bytes left on transfer\n", 1293 transfer->transfer->FragmentLength()); 1294 // TODO actually resubmit the transfer 1295 } 1296 1297 // the transfer is done, but we already set the 1298 // actualLength with AdvanceByFragment() 1299 actualLength = 0; 1300 } 1301 } 1302 1303 transfer->transfer->Finished(callbackStatus, actualLength); 1304 fProcessingPipe = NULL; 1305 } 1306 1307 if (callbackStatus != B_OK) { 1308 // remove the transfer and make the head pointer valid again 1309 // (including clearing the halt state) 1310 _RemoveTransferFromEndpoint(transfer); 1311 } 1312 1313 // free the descriptors 1314 _FreeDescriptorChain(transfer->first_descriptor); 1315 1316 delete transfer->transfer; 1317 delete transfer; 1318 transfer = next; 1319 } 1320 } 1321 } 1322 1323 1324 bool 1325 OHCI::_FinishIsochronousTransfer(transfer_data *transfer, 1326 transfer_data **_lastTransfer) 1327 { 1328 status_t callbackStatus = B_OK; 1329 size_t actualLength = 0; 1330 uint32 packet = 0; 1331 1332 if (transfer->canceled) 1333 callbackStatus = B_CANCELED; 1334 else { 1335 // at first check if ALL ITDs are retired by HC 1336 ohci_isochronous_td *descriptor 1337 = (ohci_isochronous_td *)transfer->first_descriptor; 1338 while (descriptor) { 1339 if (OHCI_TD_GET_CONDITION_CODE(descriptor->flags) 1340 == OHCI_TD_CONDITION_NOT_ACCESSED) { 1341 TRACE("ITD %p still active\n", descriptor); 1342 *_lastTransfer = transfer; 1343 return false; 1344 } 1345 1346 if (descriptor == (ohci_isochronous_td*)transfer->last_descriptor) { 1347 // this is the last ITD of the transfer 1348 descriptor = (ohci_isochronous_td *)transfer->first_descriptor; 1349 break; 1350 } 1351 1352 descriptor 1353 = (ohci_isochronous_td *)descriptor->next_done_descriptor; 1354 } 1355 1356 while (descriptor) { 1357 uint32 status = OHCI_TD_GET_CONDITION_CODE(descriptor->flags); 1358 if (status != OHCI_TD_CONDITION_NO_ERROR) { 1359 TRACE_ERROR("ITD error: 0x%08" B_PRIx32 "\n", status); 1360 // spec says that in most cases condition code 1361 // of retired ITDs is set to NoError, but for the 1362 // time overrun it can be DataOverrun. We assume 1363 // the _first_ occurience of such error as status 1364 // reported to the callback 1365 if (callbackStatus == B_OK) 1366 callbackStatus = _GetStatusOfConditionCode(status); 1367 } 1368 1369 usb_isochronous_data *isochronousData 1370 = transfer->transfer->IsochronousData(); 1371 1372 uint32 frameCount = OHCI_ITD_GET_FRAME_COUNT(descriptor->flags); 1373 for (size_t i = 0; i < frameCount; i++, packet++) { 1374 usb_iso_packet_descriptor* packet_descriptor 1375 = &isochronousData->packet_descriptors[packet]; 1376 1377 uint16 offset = descriptor->offset[OHCI_ITD_OFFSET_IDX(i)]; 1378 uint8 code = OHCI_ITD_GET_BUFFER_CONDITION_CODE(offset); 1379 packet_descriptor->status = _GetStatusOfConditionCode(code); 1380 1381 // not touched by HC - sheduled too late to be processed 1382 // in the requested frame - so we ignore it too 1383 if (packet_descriptor->status == B_DEV_TOO_LATE) 1384 continue; 1385 1386 size_t len = OHCI_ITD_GET_BUFFER_LENGTH(offset); 1387 if (!transfer->incoming) 1388 len = packet_descriptor->request_length - len; 1389 1390 packet_descriptor->actual_length = len; 1391 actualLength += len; 1392 } 1393 1394 uint16 frame = OHCI_ITD_GET_STARTING_FRAME(descriptor->flags); 1395 _ReleaseIsochronousBandwidth(frame, 1396 OHCI_ITD_GET_FRAME_COUNT(descriptor->flags)); 1397 1398 TRACE("ITD %p done\n", descriptor); 1399 1400 if (descriptor == (ohci_isochronous_td*)transfer->last_descriptor) 1401 break; 1402 1403 descriptor 1404 = (ohci_isochronous_td *)descriptor->next_done_descriptor; 1405 } 1406 } 1407 1408 // remove the transfer from the list first so we are sure 1409 // it doesn't get canceled while we still process it 1410 if (Lock()) { 1411 if (*_lastTransfer) 1412 (*_lastTransfer)->link = transfer->link; 1413 1414 if (transfer == fFirstTransfer) 1415 fFirstTransfer = transfer->link; 1416 if (transfer == fLastTransfer) 1417 fLastTransfer = *_lastTransfer; 1418 1419 // store the currently processing pipe here so we can wait 1420 // in cancel if we are processing something on the target pipe 1421 if (!transfer->canceled) 1422 fProcessingPipe = transfer->transfer->TransferPipe(); 1423 1424 transfer->link = NULL; 1425 Unlock(); 1426 } 1427 1428 // break the descriptor chain on the last descriptor 1429 transfer->last_descriptor->next_logical_descriptor = NULL; 1430 TRACE("iso.transfer %p done with status 0x%08" B_PRIx32 " len:%ld\n", 1431 transfer, callbackStatus, actualLength); 1432 1433 // if canceled the callback has already been called 1434 if (!transfer->canceled) { 1435 if (callbackStatus == B_OK && actualLength > 0) { 1436 if (transfer->data_descriptor && transfer->incoming) { 1437 // data to read out 1438 generic_io_vec *vector = transfer->transfer->Vector(); 1439 size_t vectorCount = transfer->transfer->VectorCount(); 1440 1441 transfer->transfer->PrepareKernelAccess(); 1442 _ReadIsochronousDescriptorChain( 1443 (ohci_isochronous_td*)transfer->data_descriptor, 1444 vector, vectorCount, transfer->transfer->IsPhysical()); 1445 } 1446 } 1447 1448 transfer->transfer->Finished(callbackStatus, actualLength); 1449 fProcessingPipe = NULL; 1450 } 1451 1452 _FreeIsochronousDescriptorChain( 1453 (ohci_isochronous_td*)transfer->first_descriptor); 1454 1455 return true; 1456 } 1457 1458 1459 status_t 1460 OHCI::_SubmitRequest(Transfer *transfer) 1461 { 1462 usb_request_data *requestData = transfer->RequestData(); 1463 bool directionIn = (requestData->RequestType & USB_REQTYPE_DEVICE_IN) != 0; 1464 1465 ohci_general_td *setupDescriptor 1466 = _CreateGeneralDescriptor(sizeof(usb_request_data)); 1467 if (!setupDescriptor) { 1468 TRACE_ERROR("failed to allocate setup descriptor\n"); 1469 return B_NO_MEMORY; 1470 } 1471 1472 setupDescriptor->flags = OHCI_TD_DIRECTION_PID_SETUP 1473 | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) 1474 | OHCI_TD_TOGGLE_0 1475 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE); 1476 1477 ohci_general_td *statusDescriptor = _CreateGeneralDescriptor(0); 1478 if (!statusDescriptor) { 1479 TRACE_ERROR("failed to allocate status descriptor\n"); 1480 _FreeGeneralDescriptor(setupDescriptor); 1481 return B_NO_MEMORY; 1482 } 1483 1484 statusDescriptor->flags 1485 = (directionIn ? OHCI_TD_DIRECTION_PID_OUT : OHCI_TD_DIRECTION_PID_IN) 1486 | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) 1487 | OHCI_TD_TOGGLE_1 1488 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE); 1489 1490 generic_io_vec vector; 1491 vector.base = (generic_addr_t)requestData; 1492 vector.length = sizeof(usb_request_data); 1493 _WriteDescriptorChain(setupDescriptor, &vector, 1, false); 1494 1495 status_t result; 1496 ohci_general_td *dataDescriptor = NULL; 1497 if (transfer->VectorCount() > 0) { 1498 ohci_general_td *lastDescriptor = NULL; 1499 result = _CreateDescriptorChain(&dataDescriptor, &lastDescriptor, 1500 directionIn ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT, 1501 transfer->FragmentLength()); 1502 if (result < B_OK) { 1503 _FreeGeneralDescriptor(setupDescriptor); 1504 _FreeGeneralDescriptor(statusDescriptor); 1505 return result; 1506 } 1507 1508 if (!directionIn) { 1509 _WriteDescriptorChain(dataDescriptor, transfer->Vector(), 1510 transfer->VectorCount(), transfer->IsPhysical()); 1511 } 1512 1513 _LinkDescriptors(setupDescriptor, dataDescriptor); 1514 _LinkDescriptors(lastDescriptor, statusDescriptor); 1515 } else { 1516 _LinkDescriptors(setupDescriptor, statusDescriptor); 1517 } 1518 1519 // Add to the transfer list 1520 ohci_endpoint_descriptor *endpoint 1521 = (ohci_endpoint_descriptor *)transfer->TransferPipe()->ControllerCookie(); 1522 1523 MutexLocker endpointLocker(endpoint->lock); 1524 result = _AddPendingTransfer(transfer, endpoint, setupDescriptor, 1525 dataDescriptor, statusDescriptor, directionIn); 1526 if (result < B_OK) { 1527 TRACE_ERROR("failed to add pending transfer\n"); 1528 _FreeDescriptorChain(setupDescriptor); 1529 return result; 1530 } 1531 1532 // Add the descriptor chain to the endpoint 1533 _SwitchEndpointTail(endpoint, setupDescriptor, statusDescriptor); 1534 endpointLocker.Unlock(); 1535 1536 // Tell the controller to process the control list 1537 endpoint->flags &= ~OHCI_ENDPOINT_SKIP; 1538 _WriteReg(OHCI_COMMAND_STATUS, OHCI_CONTROL_LIST_FILLED); 1539 return B_OK; 1540 } 1541 1542 1543 status_t 1544 OHCI::_SubmitTransfer(Transfer *transfer) 1545 { 1546 Pipe *pipe = transfer->TransferPipe(); 1547 bool directionIn = (pipe->Direction() == Pipe::In); 1548 1549 ohci_general_td *firstDescriptor = NULL; 1550 ohci_general_td *lastDescriptor = NULL; 1551 status_t result = _CreateDescriptorChain(&firstDescriptor, &lastDescriptor, 1552 directionIn ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT, 1553 transfer->FragmentLength()); 1554 1555 if (result < B_OK) 1556 return result; 1557 1558 // Apply data toggle to the first descriptor (the others will use the carry) 1559 firstDescriptor->flags &= ~OHCI_TD_TOGGLE_CARRY; 1560 firstDescriptor->flags |= pipe->DataToggle() ? OHCI_TD_TOGGLE_1 1561 : OHCI_TD_TOGGLE_0; 1562 1563 // Set the last descriptor to generate an interrupt 1564 lastDescriptor->flags &= ~OHCI_TD_INTERRUPT_MASK; 1565 lastDescriptor->flags |= 1566 OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE); 1567 1568 if (!directionIn) { 1569 _WriteDescriptorChain(firstDescriptor, transfer->Vector(), 1570 transfer->VectorCount(), transfer->IsPhysical()); 1571 } 1572 1573 // Add to the transfer list 1574 ohci_endpoint_descriptor *endpoint 1575 = (ohci_endpoint_descriptor *)pipe->ControllerCookie(); 1576 1577 MutexLocker endpointLocker(endpoint->lock); 1578 1579 // We do not support queuing other transfers in tandem with a fragmented one. 1580 transfer_data *it = fFirstTransfer; 1581 while (it) { 1582 if (it->transfer && it->transfer->TransferPipe() == pipe && it->transfer->IsFragmented()) { 1583 TRACE_ERROR("cannot submit transfer: a fragmented transfer is queued\n"); 1584 _FreeDescriptorChain(firstDescriptor); 1585 return B_DEV_RESOURCE_CONFLICT; 1586 } 1587 1588 it = it->link; 1589 } 1590 1591 result = _AddPendingTransfer(transfer, endpoint, firstDescriptor, 1592 firstDescriptor, lastDescriptor, directionIn); 1593 if (result < B_OK) { 1594 TRACE_ERROR("failed to add pending transfer\n"); 1595 _FreeDescriptorChain(firstDescriptor); 1596 return result; 1597 } 1598 1599 // Add the descriptor chain to the endpoint 1600 _SwitchEndpointTail(endpoint, firstDescriptor, lastDescriptor); 1601 endpointLocker.Unlock(); 1602 1603 endpoint->flags &= ~OHCI_ENDPOINT_SKIP; 1604 if (pipe->Type() & USB_OBJECT_BULK_PIPE) { 1605 // Tell the controller to process the bulk list 1606 _WriteReg(OHCI_COMMAND_STATUS, OHCI_BULK_LIST_FILLED); 1607 } 1608 1609 return B_OK; 1610 } 1611 1612 1613 status_t 1614 OHCI::_SubmitIsochronousTransfer(Transfer *transfer) 1615 { 1616 Pipe *pipe = transfer->TransferPipe(); 1617 bool directionIn = (pipe->Direction() == Pipe::In); 1618 1619 ohci_isochronous_td *firstDescriptor = NULL; 1620 ohci_isochronous_td *lastDescriptor = NULL; 1621 status_t result = _CreateIsochronousDescriptorChain(&firstDescriptor, 1622 &lastDescriptor, transfer); 1623 1624 if (firstDescriptor == 0 || lastDescriptor == 0) 1625 return B_ERROR; 1626 1627 if (result < B_OK) 1628 return result; 1629 1630 // Set the last descriptor to generate an interrupt 1631 lastDescriptor->flags &= ~OHCI_ITD_INTERRUPT_MASK; 1632 // let the controller retire last ITD 1633 lastDescriptor->flags |= OHCI_ITD_SET_DELAY_INTERRUPT(1); 1634 1635 // If direction is out set every descriptor data 1636 if (pipe->Direction() == Pipe::Out) 1637 _WriteIsochronousDescriptorChain(firstDescriptor, 1638 transfer->Vector(), transfer->VectorCount(), transfer->IsPhysical()); 1639 1640 // Add to the transfer list 1641 ohci_endpoint_descriptor *endpoint 1642 = (ohci_endpoint_descriptor *)pipe->ControllerCookie(); 1643 1644 MutexLocker endpointLocker(endpoint->lock); 1645 result = _AddPendingIsochronousTransfer(transfer, endpoint, 1646 firstDescriptor, lastDescriptor, directionIn); 1647 if (result < B_OK) { 1648 TRACE_ERROR("failed to add pending iso.transfer:" 1649 "0x%08" B_PRIx32 "\n", result); 1650 _FreeIsochronousDescriptorChain(firstDescriptor); 1651 return result; 1652 } 1653 1654 // Add the descriptor chain to the endpoint 1655 _SwitchIsochronousEndpointTail(endpoint, firstDescriptor, lastDescriptor); 1656 endpointLocker.Unlock(); 1657 1658 endpoint->flags &= ~OHCI_ENDPOINT_SKIP; 1659 1660 return B_OK; 1661 } 1662 1663 1664 void 1665 OHCI::_SwitchEndpointTail(ohci_endpoint_descriptor *endpoint, 1666 ohci_general_td *first, ohci_general_td *last) 1667 { 1668 // fill in the information of the first descriptor into the current tail 1669 ohci_general_td *tail = (ohci_general_td *)endpoint->tail_logical_descriptor; 1670 tail->flags = first->flags; 1671 tail->buffer_physical = first->buffer_physical; 1672 tail->next_physical_descriptor = first->next_physical_descriptor; 1673 tail->last_physical_byte_address = first->last_physical_byte_address; 1674 tail->buffer_size = first->buffer_size; 1675 tail->buffer_logical = first->buffer_logical; 1676 tail->next_logical_descriptor = first->next_logical_descriptor; 1677 1678 // the first descriptor becomes the new tail 1679 first->flags = 0; 1680 first->buffer_physical = 0; 1681 first->next_physical_descriptor = 0; 1682 first->last_physical_byte_address = 0; 1683 first->buffer_size = 0; 1684 first->buffer_logical = NULL; 1685 first->next_logical_descriptor = NULL; 1686 1687 if (first == last) 1688 _LinkDescriptors(tail, first); 1689 else 1690 _LinkDescriptors(last, first); 1691 1692 // update the endpoint tail pointer to reflect the change 1693 endpoint->tail_logical_descriptor = first; 1694 endpoint->tail_physical_descriptor = (uint32)first->physical_address; 1695 TRACE("switched tail from %p to %p\n", tail, first); 1696 1697 #if 0 1698 _PrintEndpoint(endpoint); 1699 _PrintDescriptorChain(tail); 1700 #endif 1701 } 1702 1703 1704 void 1705 OHCI::_SwitchIsochronousEndpointTail(ohci_endpoint_descriptor *endpoint, 1706 ohci_isochronous_td *first, ohci_isochronous_td *last) 1707 { 1708 // fill in the information of the first descriptor into the current tail 1709 ohci_isochronous_td *tail 1710 = (ohci_isochronous_td*)endpoint->tail_logical_descriptor; 1711 tail->flags = first->flags; 1712 tail->buffer_page_byte_0 = first->buffer_page_byte_0; 1713 tail->next_physical_descriptor = first->next_physical_descriptor; 1714 tail->last_byte_address = first->last_byte_address; 1715 tail->buffer_size = first->buffer_size; 1716 tail->buffer_logical = first->buffer_logical; 1717 tail->next_logical_descriptor = first->next_logical_descriptor; 1718 tail->next_done_descriptor = first->next_done_descriptor; 1719 1720 // the first descriptor becomes the new tail 1721 first->flags = 0; 1722 first->buffer_page_byte_0 = 0; 1723 first->next_physical_descriptor = 0; 1724 first->last_byte_address = 0; 1725 first->buffer_size = 0; 1726 first->buffer_logical = NULL; 1727 first->next_logical_descriptor = NULL; 1728 first->next_done_descriptor = NULL; 1729 1730 for (int i = 0; i < OHCI_ITD_NOFFSET; i++) { 1731 tail->offset[i] = first->offset[i]; 1732 first->offset[i] = 0; 1733 } 1734 1735 if (first == last) 1736 _LinkIsochronousDescriptors(tail, first, NULL); 1737 else 1738 _LinkIsochronousDescriptors(last, first, NULL); 1739 1740 // update the endpoint tail pointer to reflect the change 1741 endpoint->tail_logical_descriptor = first; 1742 endpoint->tail_physical_descriptor = (uint32)first->physical_address; 1743 TRACE("switched tail from %p to %p\n", tail, first); 1744 1745 #if 0 1746 _PrintEndpoint(endpoint); 1747 _PrintDescriptorChain(tail); 1748 #endif 1749 } 1750 1751 1752 void 1753 OHCI::_RemoveTransferFromEndpoint(transfer_data *transfer) 1754 { 1755 // The transfer failed and the endpoint was halted. This means that the 1756 // endpoint head pointer might point somewhere into the descriptor chain 1757 // of this transfer. As we do not know if this transfer actually caused 1758 // the halt on the endpoint we have to make sure this is the case. If we 1759 // find the head to point to somewhere into the descriptor chain then 1760 // simply advancing the head pointer to the link of the last transfer 1761 // will bring the endpoint into a valid state again. This operation is 1762 // safe as the endpoint is currently halted and we therefore can change 1763 // the head pointer. 1764 ohci_endpoint_descriptor *endpoint = transfer->endpoint; 1765 ohci_general_td *descriptor = transfer->first_descriptor; 1766 while (descriptor) { 1767 if ((endpoint->head_physical_descriptor & OHCI_ENDPOINT_HEAD_MASK) 1768 == descriptor->physical_address) { 1769 // This descriptor caused the halt. Advance the head pointer. This 1770 // will either move the head to the next valid transfer that can 1771 // then be restarted, or it will move the head to the tail when 1772 // there are no more transfer descriptors. Setting the head will 1773 // also clear the halt state as it is stored in the first bit of 1774 // the head pointer. 1775 endpoint->head_physical_descriptor 1776 = transfer->last_descriptor->next_physical_descriptor; 1777 return; 1778 } 1779 1780 descriptor = (ohci_general_td *)descriptor->next_logical_descriptor; 1781 } 1782 } 1783 1784 1785 ohci_endpoint_descriptor * 1786 OHCI::_AllocateEndpoint() 1787 { 1788 ohci_endpoint_descriptor *endpoint; 1789 phys_addr_t physicalAddress; 1790 1791 mutex *lock = (mutex *)malloc(sizeof(mutex)); 1792 if (lock == NULL) { 1793 TRACE_ERROR("no memory to allocate endpoint lock\n"); 1794 return NULL; 1795 } 1796 1797 // Allocate memory chunk 1798 if (fStack->AllocateChunk((void **)&endpoint, &physicalAddress, 1799 sizeof(ohci_endpoint_descriptor)) < B_OK) { 1800 TRACE_ERROR("failed to allocate endpoint descriptor\n"); 1801 free(lock); 1802 return NULL; 1803 } 1804 1805 mutex_init(lock, "ohci endpoint lock"); 1806 1807 endpoint->flags = OHCI_ENDPOINT_SKIP; 1808 endpoint->physical_address = (uint32)physicalAddress; 1809 endpoint->head_physical_descriptor = 0; 1810 endpoint->tail_logical_descriptor = NULL; 1811 endpoint->tail_physical_descriptor = 0; 1812 endpoint->next_logical_endpoint = NULL; 1813 endpoint->next_physical_endpoint = 0; 1814 endpoint->lock = lock; 1815 return endpoint; 1816 } 1817 1818 1819 void 1820 OHCI::_FreeEndpoint(ohci_endpoint_descriptor *endpoint) 1821 { 1822 if (!endpoint) 1823 return; 1824 1825 mutex_destroy(endpoint->lock); 1826 free(endpoint->lock); 1827 1828 fStack->FreeChunk((void *)endpoint, endpoint->physical_address, 1829 sizeof(ohci_endpoint_descriptor)); 1830 } 1831 1832 1833 status_t 1834 OHCI::_InsertEndpointForPipe(Pipe *pipe) 1835 { 1836 TRACE("inserting endpoint for device %u endpoint %u\n", 1837 pipe->DeviceAddress(), pipe->EndpointAddress()); 1838 1839 ohci_endpoint_descriptor *endpoint = _AllocateEndpoint(); 1840 if (!endpoint) { 1841 TRACE_ERROR("cannot allocate memory for endpoint\n"); 1842 return B_NO_MEMORY; 1843 } 1844 1845 uint32 flags = OHCI_ENDPOINT_SKIP; 1846 1847 // Set up device and endpoint address 1848 flags |= OHCI_ENDPOINT_SET_DEVICE_ADDRESS(pipe->DeviceAddress()) 1849 | OHCI_ENDPOINT_SET_ENDPOINT_NUMBER(pipe->EndpointAddress()); 1850 1851 // Set the direction 1852 switch (pipe->Direction()) { 1853 case Pipe::In: 1854 flags |= OHCI_ENDPOINT_DIRECTION_IN; 1855 break; 1856 1857 case Pipe::Out: 1858 flags |= OHCI_ENDPOINT_DIRECTION_OUT; 1859 break; 1860 1861 case Pipe::Default: 1862 flags |= OHCI_ENDPOINT_DIRECTION_DESCRIPTOR; 1863 break; 1864 1865 default: 1866 TRACE_ERROR("direction unknown\n"); 1867 _FreeEndpoint(endpoint); 1868 return B_ERROR; 1869 } 1870 1871 // Set up the speed 1872 switch (pipe->Speed()) { 1873 case USB_SPEED_LOWSPEED: 1874 flags |= OHCI_ENDPOINT_LOW_SPEED; 1875 break; 1876 1877 case USB_SPEED_FULLSPEED: 1878 flags |= OHCI_ENDPOINT_FULL_SPEED; 1879 break; 1880 1881 default: 1882 TRACE_ERROR("unacceptable speed\n"); 1883 _FreeEndpoint(endpoint); 1884 return B_ERROR; 1885 } 1886 1887 // Set the maximum packet size 1888 flags |= OHCI_ENDPOINT_SET_MAX_PACKET_SIZE(pipe->MaxPacketSize()); 1889 endpoint->flags = flags; 1890 1891 // Add the endpoint to the appropriate list 1892 uint32 type = pipe->Type(); 1893 ohci_endpoint_descriptor *head = NULL; 1894 if (type & USB_OBJECT_CONTROL_PIPE) 1895 head = fDummyControl; 1896 else if (type & USB_OBJECT_BULK_PIPE) 1897 head = fDummyBulk; 1898 else if (type & USB_OBJECT_INTERRUPT_PIPE) 1899 head = _FindInterruptEndpoint(pipe->Interval()); 1900 else if (type & USB_OBJECT_ISO_PIPE) 1901 head = fDummyIsochronous; 1902 else 1903 TRACE_ERROR("unknown pipe type\n"); 1904 1905 if (head == NULL) { 1906 TRACE_ERROR("no list found for endpoint\n"); 1907 _FreeEndpoint(endpoint); 1908 return B_ERROR; 1909 } 1910 1911 // Create (necessary) tail descriptor 1912 if (pipe->Type() & USB_OBJECT_ISO_PIPE) { 1913 // Set the isochronous bit format 1914 endpoint->flags |= OHCI_ENDPOINT_ISOCHRONOUS_FORMAT; 1915 ohci_isochronous_td *tail = _CreateIsochronousDescriptor(0); 1916 tail->flags = 0; 1917 endpoint->tail_logical_descriptor = tail; 1918 endpoint->head_physical_descriptor = tail->physical_address; 1919 endpoint->tail_physical_descriptor = tail->physical_address; 1920 } else { 1921 ohci_general_td *tail = _CreateGeneralDescriptor(0); 1922 tail->flags = 0; 1923 endpoint->tail_logical_descriptor = tail; 1924 endpoint->head_physical_descriptor = tail->physical_address; 1925 endpoint->tail_physical_descriptor = tail->physical_address; 1926 } 1927 1928 if (!_LockEndpoints()) { 1929 if (endpoint->tail_logical_descriptor) { 1930 _FreeGeneralDescriptor( 1931 (ohci_general_td *)endpoint->tail_logical_descriptor); 1932 } 1933 1934 _FreeEndpoint(endpoint); 1935 return B_ERROR; 1936 } 1937 1938 pipe->SetControllerCookie((void *)endpoint); 1939 endpoint->next_logical_endpoint = head->next_logical_endpoint; 1940 endpoint->next_physical_endpoint = head->next_physical_endpoint; 1941 head->next_logical_endpoint = (void *)endpoint; 1942 head->next_physical_endpoint = (uint32)endpoint->physical_address; 1943 1944 _UnlockEndpoints(); 1945 return B_OK; 1946 } 1947 1948 1949 status_t 1950 OHCI::_RemoveEndpointForPipe(Pipe *pipe) 1951 { 1952 TRACE("removing endpoint for device %u endpoint %u\n", 1953 pipe->DeviceAddress(), pipe->EndpointAddress()); 1954 1955 ohci_endpoint_descriptor *endpoint 1956 = (ohci_endpoint_descriptor *)pipe->ControllerCookie(); 1957 if (endpoint == NULL) 1958 return B_OK; 1959 1960 // TODO implement properly, but at least disable it for now 1961 endpoint->flags |= OHCI_ENDPOINT_SKIP; 1962 return B_OK; 1963 } 1964 1965 1966 ohci_endpoint_descriptor * 1967 OHCI::_FindInterruptEndpoint(uint8 interval) 1968 { 1969 uint32 index = 0; 1970 uint32 power = 1; 1971 while (power <= OHCI_BIGGEST_INTERVAL / 2) { 1972 if (power * 2 > interval) 1973 break; 1974 1975 power *= 2; 1976 index++; 1977 } 1978 1979 return fInterruptEndpoints[index]; 1980 } 1981 1982 1983 ohci_general_td * 1984 OHCI::_CreateGeneralDescriptor(size_t bufferSize) 1985 { 1986 ohci_general_td *descriptor; 1987 phys_addr_t physicalAddress; 1988 1989 if (fStack->AllocateChunk((void **)&descriptor, &physicalAddress, 1990 sizeof(ohci_general_td)) != B_OK) { 1991 TRACE_ERROR("failed to allocate general descriptor\n"); 1992 return NULL; 1993 } 1994 1995 descriptor->physical_address = (uint32)physicalAddress; 1996 descriptor->next_physical_descriptor = 0; 1997 descriptor->next_logical_descriptor = NULL; 1998 descriptor->buffer_size = bufferSize; 1999 if (bufferSize == 0) { 2000 descriptor->buffer_physical = 0; 2001 descriptor->buffer_logical = NULL; 2002 descriptor->last_physical_byte_address = 0; 2003 return descriptor; 2004 } 2005 2006 if (fStack->AllocateChunk(&descriptor->buffer_logical, 2007 &physicalAddress, bufferSize) != B_OK) { 2008 TRACE_ERROR("failed to allocate space for buffer\n"); 2009 fStack->FreeChunk(descriptor, descriptor->physical_address, 2010 sizeof(ohci_general_td)); 2011 return NULL; 2012 } 2013 descriptor->buffer_physical = physicalAddress; 2014 2015 descriptor->last_physical_byte_address 2016 = descriptor->buffer_physical + bufferSize - 1; 2017 return descriptor; 2018 } 2019 2020 2021 void 2022 OHCI::_FreeGeneralDescriptor(ohci_general_td *descriptor) 2023 { 2024 if (!descriptor) 2025 return; 2026 2027 if (descriptor->buffer_logical) { 2028 fStack->FreeChunk(descriptor->buffer_logical, 2029 descriptor->buffer_physical, descriptor->buffer_size); 2030 } 2031 2032 fStack->FreeChunk((void *)descriptor, descriptor->physical_address, 2033 sizeof(ohci_general_td)); 2034 } 2035 2036 2037 status_t 2038 OHCI::_CreateDescriptorChain(ohci_general_td **_firstDescriptor, 2039 ohci_general_td **_lastDescriptor, uint32 direction, size_t bufferSize) 2040 { 2041 size_t blockSize = 8192; 2042 int32 descriptorCount = (bufferSize + blockSize - 1) / blockSize; 2043 if (descriptorCount == 0) 2044 descriptorCount = 1; 2045 2046 ohci_general_td *firstDescriptor = NULL; 2047 ohci_general_td *lastDescriptor = *_firstDescriptor; 2048 for (int32 i = 0; i < descriptorCount; i++) { 2049 ohci_general_td *descriptor = _CreateGeneralDescriptor( 2050 min_c(blockSize, bufferSize)); 2051 2052 if (!descriptor) { 2053 _FreeDescriptorChain(firstDescriptor); 2054 return B_NO_MEMORY; 2055 } 2056 2057 descriptor->flags = direction 2058 | OHCI_TD_BUFFER_ROUNDING 2059 | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) 2060 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE) 2061 | OHCI_TD_TOGGLE_CARRY; 2062 2063 // link to previous 2064 if (lastDescriptor) 2065 _LinkDescriptors(lastDescriptor, descriptor); 2066 2067 bufferSize -= blockSize; 2068 lastDescriptor = descriptor; 2069 if (!firstDescriptor) 2070 firstDescriptor = descriptor; 2071 } 2072 2073 *_firstDescriptor = firstDescriptor; 2074 *_lastDescriptor = lastDescriptor; 2075 return B_OK; 2076 } 2077 2078 2079 void 2080 OHCI::_FreeDescriptorChain(ohci_general_td *topDescriptor) 2081 { 2082 ohci_general_td *current = topDescriptor; 2083 ohci_general_td *next = NULL; 2084 2085 while (current) { 2086 next = (ohci_general_td *)current->next_logical_descriptor; 2087 _FreeGeneralDescriptor(current); 2088 current = next; 2089 } 2090 } 2091 2092 2093 ohci_isochronous_td * 2094 OHCI::_CreateIsochronousDescriptor(size_t bufferSize) 2095 { 2096 ohci_isochronous_td *descriptor = NULL; 2097 phys_addr_t physicalAddress; 2098 2099 if (fStack->AllocateChunk((void **)&descriptor, &physicalAddress, 2100 sizeof(ohci_isochronous_td)) != B_OK) { 2101 TRACE_ERROR("failed to allocate isochronous descriptor\n"); 2102 return NULL; 2103 } 2104 2105 descriptor->physical_address = (uint32)physicalAddress; 2106 descriptor->next_physical_descriptor = 0; 2107 descriptor->next_logical_descriptor = NULL; 2108 descriptor->next_done_descriptor = NULL; 2109 descriptor->buffer_size = bufferSize; 2110 if (bufferSize == 0) { 2111 descriptor->buffer_page_byte_0 = 0; 2112 descriptor->buffer_logical = NULL; 2113 descriptor->last_byte_address = 0; 2114 return descriptor; 2115 } 2116 2117 if (fStack->AllocateChunk(&descriptor->buffer_logical, 2118 &physicalAddress, bufferSize) != B_OK) { 2119 TRACE_ERROR("failed to allocate space for iso.buffer\n"); 2120 fStack->FreeChunk(descriptor, descriptor->physical_address, 2121 sizeof(ohci_isochronous_td)); 2122 return NULL; 2123 } 2124 descriptor->buffer_page_byte_0 = (uint32)physicalAddress; 2125 descriptor->last_byte_address 2126 = descriptor->buffer_page_byte_0 + bufferSize - 1; 2127 2128 return descriptor; 2129 } 2130 2131 2132 void 2133 OHCI::_FreeIsochronousDescriptor(ohci_isochronous_td *descriptor) 2134 { 2135 if (!descriptor) 2136 return; 2137 2138 if (descriptor->buffer_logical) { 2139 fStack->FreeChunk(descriptor->buffer_logical, 2140 descriptor->buffer_page_byte_0, descriptor->buffer_size); 2141 } 2142 2143 fStack->FreeChunk((void *)descriptor, descriptor->physical_address, 2144 sizeof(ohci_general_td)); 2145 } 2146 2147 2148 status_t 2149 OHCI::_CreateIsochronousDescriptorChain(ohci_isochronous_td **_firstDescriptor, 2150 ohci_isochronous_td **_lastDescriptor, Transfer *transfer) 2151 { 2152 Pipe *pipe = transfer->TransferPipe(); 2153 usb_isochronous_data *isochronousData = transfer->IsochronousData(); 2154 2155 size_t dataLength = transfer->FragmentLength(); 2156 size_t packet_count = isochronousData->packet_count; 2157 2158 if (packet_count == 0) { 2159 TRACE_ERROR("isochronous packet_count should not be equal to zero."); 2160 return B_BAD_VALUE; 2161 } 2162 2163 size_t packetSize = dataLength / packet_count; 2164 if (dataLength % packet_count != 0) 2165 packetSize++; 2166 2167 if (packetSize > pipe->MaxPacketSize()) { 2168 TRACE_ERROR("isochronous packetSize %ld is bigger" 2169 " than pipe MaxPacketSize %ld.", packetSize, pipe->MaxPacketSize()); 2170 return B_BAD_VALUE; 2171 } 2172 2173 uint16 bandwidth = transfer->Bandwidth() / packet_count; 2174 if (transfer->Bandwidth() % packet_count != 0) 2175 bandwidth++; 2176 2177 ohci_isochronous_td *firstDescriptor = NULL; 2178 ohci_isochronous_td *lastDescriptor = *_firstDescriptor; 2179 2180 // the frame number currently processed by the host controller 2181 uint16 currentFrame = fHcca->current_frame_number & 0xFFFF; 2182 uint16 safeFrames = 5; 2183 2184 // The entry where to start inserting the first Isochronous descriptor 2185 // real frame number may differ in case provided one has not bandwidth 2186 if (isochronousData->flags & USB_ISO_ASAP || 2187 isochronousData->starting_frame_number == NULL) 2188 // We should stay about 5-10 ms ahead of the controller 2189 // USB1 frame is equal to 1 ms 2190 currentFrame += safeFrames; 2191 else 2192 currentFrame = *isochronousData->starting_frame_number; 2193 2194 uint16 packets = packet_count; 2195 uint16 frameOffset = 0; 2196 while (packets > 0) { 2197 // look for up to 8 continous frames with available bandwidth 2198 uint16 frameCount = 0; 2199 while (frameCount < min_c(OHCI_ITD_NOFFSET, packets) 2200 && _AllocateIsochronousBandwidth(frameOffset + currentFrame 2201 + frameCount, bandwidth)) 2202 frameCount++; 2203 2204 if (frameCount == 0) { 2205 // starting frame has no bandwidth for our transaction - try next 2206 if (++frameOffset >= 0xFFFF) { 2207 TRACE_ERROR("failed to allocate bandwidth\n"); 2208 _FreeIsochronousDescriptorChain(firstDescriptor); 2209 return B_NO_MEMORY; 2210 } 2211 continue; 2212 } 2213 2214 ohci_isochronous_td *descriptor = _CreateIsochronousDescriptor( 2215 packetSize * frameCount); 2216 2217 if (!descriptor) { 2218 TRACE_ERROR("failed to allocate ITD\n"); 2219 _ReleaseIsochronousBandwidth(currentFrame + frameOffset, frameCount); 2220 _FreeIsochronousDescriptorChain(firstDescriptor); 2221 return B_NO_MEMORY; 2222 } 2223 2224 uint16 pageOffset = descriptor->buffer_page_byte_0 & 0xfff; 2225 descriptor->buffer_page_byte_0 &= ~0xfff; 2226 for (uint16 i = 0; i < frameCount; i++) { 2227 descriptor->offset[OHCI_ITD_OFFSET_IDX(i)] 2228 = OHCI_ITD_MK_OFFS(pageOffset + packetSize * i); 2229 } 2230 2231 descriptor->flags = OHCI_ITD_SET_FRAME_COUNT(frameCount) 2232 | OHCI_ITD_SET_CONDITION_CODE(OHCI_ITD_CONDITION_NOT_ACCESSED) 2233 | OHCI_ITD_SET_DELAY_INTERRUPT(OHCI_ITD_INTERRUPT_NONE) 2234 | OHCI_ITD_SET_STARTING_FRAME(currentFrame + frameOffset); 2235 2236 // the last packet may be shorter than other ones in this transfer 2237 if (packets <= OHCI_ITD_NOFFSET) 2238 descriptor->last_byte_address 2239 += dataLength - packetSize * (packet_count); 2240 2241 // link to previous 2242 if (lastDescriptor) 2243 _LinkIsochronousDescriptors(lastDescriptor, descriptor, descriptor); 2244 2245 lastDescriptor = descriptor; 2246 if (!firstDescriptor) 2247 firstDescriptor = descriptor; 2248 2249 packets -= frameCount; 2250 2251 frameOffset += frameCount; 2252 2253 if (packets == 0 && isochronousData->starting_frame_number) 2254 *isochronousData->starting_frame_number = currentFrame + frameOffset; 2255 } 2256 2257 *_firstDescriptor = firstDescriptor; 2258 *_lastDescriptor = lastDescriptor; 2259 2260 return B_OK; 2261 } 2262 2263 2264 void 2265 OHCI::_FreeIsochronousDescriptorChain(ohci_isochronous_td *topDescriptor) 2266 { 2267 ohci_isochronous_td *current = topDescriptor; 2268 ohci_isochronous_td *next = NULL; 2269 2270 while (current) { 2271 next = (ohci_isochronous_td *)current->next_done_descriptor; 2272 _FreeIsochronousDescriptor(current); 2273 current = next; 2274 } 2275 } 2276 2277 2278 size_t 2279 OHCI::_WriteDescriptorChain(ohci_general_td *topDescriptor, generic_io_vec *vector, 2280 size_t vectorCount, bool physical) 2281 { 2282 ohci_general_td *current = topDescriptor; 2283 size_t actualLength = 0; 2284 size_t vectorIndex = 0; 2285 size_t vectorOffset = 0; 2286 size_t bufferOffset = 0; 2287 2288 while (current) { 2289 if (!current->buffer_logical) 2290 break; 2291 2292 while (true) { 2293 size_t length = min_c(current->buffer_size - bufferOffset, 2294 vector[vectorIndex].length - vectorOffset); 2295 2296 TRACE("copying %ld bytes to bufferOffset %ld from" 2297 " vectorOffset %ld at index %ld of %ld\n", length, bufferOffset, 2298 vectorOffset, vectorIndex, vectorCount); 2299 status_t status = generic_memcpy( 2300 (generic_addr_t)current->buffer_logical + bufferOffset, false, 2301 vector[vectorIndex].base + vectorOffset, physical, length); 2302 ASSERT_ALWAYS(status == B_OK); 2303 2304 actualLength += length; 2305 vectorOffset += length; 2306 bufferOffset += length; 2307 2308 if (vectorOffset >= vector[vectorIndex].length) { 2309 if (++vectorIndex >= vectorCount) { 2310 TRACE("wrote descriptor chain (%ld bytes, no" 2311 " more vectors)\n", actualLength); 2312 return actualLength; 2313 } 2314 2315 vectorOffset = 0; 2316 } 2317 2318 if (bufferOffset >= current->buffer_size) { 2319 bufferOffset = 0; 2320 break; 2321 } 2322 } 2323 2324 if (!current->next_logical_descriptor) 2325 break; 2326 2327 current = (ohci_general_td *)current->next_logical_descriptor; 2328 } 2329 2330 TRACE("wrote descriptor chain (%ld bytes)\n", actualLength); 2331 return actualLength; 2332 } 2333 2334 2335 size_t 2336 OHCI::_WriteIsochronousDescriptorChain(ohci_isochronous_td *topDescriptor, 2337 generic_io_vec *vector, size_t vectorCount, bool physical) 2338 { 2339 ohci_isochronous_td *current = topDescriptor; 2340 size_t actualLength = 0; 2341 size_t vectorIndex = 0; 2342 size_t vectorOffset = 0; 2343 size_t bufferOffset = 0; 2344 2345 while (current) { 2346 if (!current->buffer_logical) 2347 break; 2348 2349 while (true) { 2350 size_t length = min_c(current->buffer_size - bufferOffset, 2351 vector[vectorIndex].length - vectorOffset); 2352 2353 TRACE("copying %ld bytes to bufferOffset %ld from" 2354 " vectorOffset %ld at index %ld of %ld\n", length, bufferOffset, 2355 vectorOffset, vectorIndex, vectorCount); 2356 status_t status = generic_memcpy( 2357 (generic_addr_t)current->buffer_logical + bufferOffset, false, 2358 vector[vectorIndex].base + vectorOffset, physical, length); 2359 ASSERT_ALWAYS(status == B_OK); 2360 2361 actualLength += length; 2362 vectorOffset += length; 2363 bufferOffset += length; 2364 2365 if (vectorOffset >= vector[vectorIndex].length) { 2366 if (++vectorIndex >= vectorCount) { 2367 TRACE("wrote descriptor chain (%ld bytes, no" 2368 " more vectors)\n", actualLength); 2369 return actualLength; 2370 } 2371 2372 vectorOffset = 0; 2373 } 2374 2375 if (bufferOffset >= current->buffer_size) { 2376 bufferOffset = 0; 2377 break; 2378 } 2379 } 2380 2381 if (!current->next_logical_descriptor) 2382 break; 2383 2384 current = (ohci_isochronous_td *)current->next_logical_descriptor; 2385 } 2386 2387 TRACE("wrote descriptor chain (%ld bytes)\n", actualLength); 2388 return actualLength; 2389 } 2390 2391 2392 size_t 2393 OHCI::_ReadDescriptorChain(ohci_general_td *topDescriptor, generic_io_vec *vector, 2394 size_t vectorCount, bool physical) 2395 { 2396 ohci_general_td *current = topDescriptor; 2397 size_t actualLength = 0; 2398 size_t vectorIndex = 0; 2399 size_t vectorOffset = 0; 2400 size_t bufferOffset = 0; 2401 2402 while (current && OHCI_TD_GET_CONDITION_CODE(current->flags) 2403 != OHCI_TD_CONDITION_NOT_ACCESSED) { 2404 if (!current->buffer_logical) 2405 break; 2406 2407 size_t bufferSize = current->buffer_size; 2408 if (current->buffer_physical != 0) { 2409 bufferSize -= current->last_physical_byte_address 2410 - current->buffer_physical + 1; 2411 } 2412 2413 while (true) { 2414 size_t length = min_c(bufferSize - bufferOffset, 2415 vector[vectorIndex].length - vectorOffset); 2416 2417 TRACE("copying %ld bytes to vectorOffset %ld from" 2418 " bufferOffset %ld at index %ld of %ld\n", length, vectorOffset, 2419 bufferOffset, vectorIndex, vectorCount); 2420 status_t status = generic_memcpy( 2421 vector[vectorIndex].base + vectorOffset, physical, 2422 (generic_addr_t)current->buffer_logical + bufferOffset, false, length); 2423 ASSERT_ALWAYS(status == B_OK); 2424 2425 actualLength += length; 2426 vectorOffset += length; 2427 bufferOffset += length; 2428 2429 if (vectorOffset >= vector[vectorIndex].length) { 2430 if (++vectorIndex >= vectorCount) { 2431 TRACE("read descriptor chain (%ld bytes, no more vectors)\n", 2432 actualLength); 2433 return actualLength; 2434 } 2435 2436 vectorOffset = 0; 2437 } 2438 2439 if (bufferOffset >= bufferSize) { 2440 bufferOffset = 0; 2441 break; 2442 } 2443 } 2444 2445 current = (ohci_general_td *)current->next_logical_descriptor; 2446 } 2447 2448 TRACE("read descriptor chain (%ld bytes)\n", actualLength); 2449 return actualLength; 2450 } 2451 2452 2453 void 2454 OHCI::_ReadIsochronousDescriptorChain(ohci_isochronous_td *topDescriptor, 2455 generic_io_vec *vector, size_t vectorCount, bool physical) 2456 { 2457 ohci_isochronous_td *current = topDescriptor; 2458 size_t actualLength = 0; 2459 size_t vectorIndex = 0; 2460 size_t vectorOffset = 0; 2461 size_t bufferOffset = 0; 2462 2463 while (current && OHCI_ITD_GET_CONDITION_CODE(current->flags) 2464 != OHCI_ITD_CONDITION_NOT_ACCESSED) { 2465 size_t bufferSize = current->buffer_size; 2466 if (current->buffer_logical != NULL && bufferSize > 0) { 2467 while (true) { 2468 size_t length = min_c(bufferSize - bufferOffset, 2469 vector[vectorIndex].length - vectorOffset); 2470 2471 TRACE("copying %ld bytes to vectorOffset %ld from bufferOffset" 2472 " %ld at index %ld of %ld\n", length, vectorOffset, 2473 bufferOffset, vectorIndex, vectorCount); 2474 status_t status = generic_memcpy( 2475 vector[vectorIndex].base + vectorOffset, physical, 2476 (generic_addr_t)current->buffer_logical + bufferOffset, false, length); 2477 ASSERT_ALWAYS(status == B_OK); 2478 2479 actualLength += length; 2480 vectorOffset += length; 2481 bufferOffset += length; 2482 2483 if (vectorOffset >= vector[vectorIndex].length) { 2484 if (++vectorIndex >= vectorCount) { 2485 TRACE("read descriptor chain (%ld bytes, " 2486 "no more vectors)\n", actualLength); 2487 return; 2488 } 2489 2490 vectorOffset = 0; 2491 } 2492 2493 if (bufferOffset >= bufferSize) { 2494 bufferOffset = 0; 2495 break; 2496 } 2497 } 2498 } 2499 2500 current = (ohci_isochronous_td *)current->next_done_descriptor; 2501 } 2502 2503 TRACE("read descriptor chain (%ld bytes)\n", actualLength); 2504 return; 2505 } 2506 2507 2508 size_t 2509 OHCI::_ReadActualLength(ohci_general_td *topDescriptor) 2510 { 2511 ohci_general_td *current = topDescriptor; 2512 size_t actualLength = 0; 2513 2514 while (current && OHCI_TD_GET_CONDITION_CODE(current->flags) 2515 != OHCI_TD_CONDITION_NOT_ACCESSED) { 2516 size_t length = current->buffer_size; 2517 if (current->buffer_physical != 0) { 2518 length -= current->last_physical_byte_address 2519 - current->buffer_physical + 1; 2520 } 2521 2522 actualLength += length; 2523 current = (ohci_general_td *)current->next_logical_descriptor; 2524 } 2525 2526 TRACE("read actual length (%ld bytes)\n", actualLength); 2527 return actualLength; 2528 } 2529 2530 2531 void 2532 OHCI::_LinkDescriptors(ohci_general_td *first, ohci_general_td *second) 2533 { 2534 first->next_physical_descriptor = second->physical_address; 2535 first->next_logical_descriptor = second; 2536 } 2537 2538 2539 void 2540 OHCI::_LinkIsochronousDescriptors(ohci_isochronous_td *first, 2541 ohci_isochronous_td *second, ohci_isochronous_td *nextDone) 2542 { 2543 first->next_physical_descriptor = second->physical_address; 2544 first->next_logical_descriptor = second; 2545 first->next_done_descriptor = nextDone; 2546 } 2547 2548 2549 bool 2550 OHCI::_AllocateIsochronousBandwidth(uint16 frame, uint16 size) 2551 { 2552 frame %= NUMBER_OF_FRAMES; 2553 if (size > fFrameBandwidth[frame]) 2554 return false; 2555 2556 fFrameBandwidth[frame]-= size; 2557 return true; 2558 } 2559 2560 2561 void 2562 OHCI::_ReleaseIsochronousBandwidth(uint16 startFrame, uint16 frameCount) 2563 { 2564 for (size_t index = 0; index < frameCount; index++) { 2565 uint16 frame = (startFrame + index) % NUMBER_OF_FRAMES; 2566 fFrameBandwidth[frame] = MAX_AVAILABLE_BANDWIDTH; 2567 } 2568 } 2569 2570 2571 status_t 2572 OHCI::_GetStatusOfConditionCode(uint8 conditionCode) 2573 { 2574 switch (conditionCode) { 2575 case OHCI_TD_CONDITION_NO_ERROR: 2576 return B_OK; 2577 2578 case OHCI_TD_CONDITION_CRC_ERROR: 2579 case OHCI_TD_CONDITION_BIT_STUFFING: 2580 case OHCI_TD_CONDITION_TOGGLE_MISMATCH: 2581 return B_DEV_CRC_ERROR; 2582 2583 case OHCI_TD_CONDITION_STALL: 2584 return B_DEV_STALLED; 2585 2586 case OHCI_TD_CONDITION_NO_RESPONSE: 2587 return B_TIMED_OUT; 2588 2589 case OHCI_TD_CONDITION_PID_CHECK_FAILURE: 2590 return B_DEV_BAD_PID; 2591 2592 case OHCI_TD_CONDITION_UNEXPECTED_PID: 2593 return B_DEV_UNEXPECTED_PID; 2594 2595 case OHCI_TD_CONDITION_DATA_OVERRUN: 2596 return B_DEV_DATA_OVERRUN; 2597 2598 case OHCI_TD_CONDITION_DATA_UNDERRUN: 2599 return B_DEV_DATA_UNDERRUN; 2600 2601 case OHCI_TD_CONDITION_BUFFER_OVERRUN: 2602 return B_DEV_WRITE_ERROR; 2603 2604 case OHCI_TD_CONDITION_BUFFER_UNDERRUN: 2605 return B_DEV_READ_ERROR; 2606 2607 case OHCI_TD_CONDITION_NOT_ACCESSED: 2608 return B_DEV_PENDING; 2609 2610 case 0x0E: 2611 return B_DEV_TOO_LATE; // PSW: _NOT_ACCESSED 2612 2613 default: 2614 break; 2615 } 2616 2617 return B_ERROR; 2618 } 2619 2620 2621 bool 2622 OHCI::_LockEndpoints() 2623 { 2624 return (mutex_lock(&fEndpointLock) == B_OK); 2625 } 2626 2627 2628 void 2629 OHCI::_UnlockEndpoints() 2630 { 2631 mutex_unlock(&fEndpointLock); 2632 } 2633 2634 2635 inline void 2636 OHCI::_WriteReg(uint32 reg, uint32 value) 2637 { 2638 *(volatile uint32 *)(fOperationalRegisters + reg) = value; 2639 } 2640 2641 2642 inline uint32 2643 OHCI::_ReadReg(uint32 reg) 2644 { 2645 return *(volatile uint32 *)(fOperationalRegisters + reg); 2646 } 2647 2648 2649 void 2650 OHCI::_PrintEndpoint(ohci_endpoint_descriptor *endpoint) 2651 { 2652 dprintf("endpoint %p\n", endpoint); 2653 dprintf("\tflags........... 0x%08" B_PRIx32 "\n", endpoint->flags); 2654 dprintf("\ttail_physical... 0x%08" B_PRIx32 "\n", endpoint->tail_physical_descriptor); 2655 dprintf("\thead_physical... 0x%08" B_PRIx32 "\n", endpoint->head_physical_descriptor); 2656 dprintf("\tnext_physical... 0x%08" B_PRIx32 "\n", endpoint->next_physical_endpoint); 2657 dprintf("\tphysical........ 0x%08" B_PRIx32 "\n", endpoint->physical_address); 2658 dprintf("\ttail_logical.... %p\n", endpoint->tail_logical_descriptor); 2659 dprintf("\tnext_logical.... %p\n", endpoint->next_logical_endpoint); 2660 } 2661 2662 2663 void 2664 OHCI::_PrintDescriptorChain(ohci_general_td *topDescriptor) 2665 { 2666 while (topDescriptor) { 2667 dprintf("descriptor %p\n", topDescriptor); 2668 dprintf("\tflags........... 0x%08" B_PRIx32 "\n", topDescriptor->flags); 2669 dprintf("\tbuffer_physical. 0x%08" B_PRIx32 "\n", topDescriptor->buffer_physical); 2670 dprintf("\tnext_physical... 0x%08" B_PRIx32 "\n", topDescriptor->next_physical_descriptor); 2671 dprintf("\tlast_byte....... 0x%08" B_PRIx32 "\n", topDescriptor->last_physical_byte_address); 2672 dprintf("\tphysical........ 0x%08" B_PRIx32 "\n", topDescriptor->physical_address); 2673 dprintf("\tbuffer_size..... %lu\n", topDescriptor->buffer_size); 2674 dprintf("\tbuffer_logical.. %p\n", topDescriptor->buffer_logical); 2675 dprintf("\tnext_logical.... %p\n", topDescriptor->next_logical_descriptor); 2676 2677 topDescriptor = (ohci_general_td *)topDescriptor->next_logical_descriptor; 2678 } 2679 } 2680 2681 2682 void 2683 OHCI::_PrintDescriptorChain(ohci_isochronous_td *topDescriptor) 2684 { 2685 while (topDescriptor) { 2686 dprintf("iso.descriptor %p\n", topDescriptor); 2687 dprintf("\tflags........... 0x%08" B_PRIx32 "\n", topDescriptor->flags); 2688 dprintf("\tbuffer_pagebyte0 0x%08" B_PRIx32 "\n", topDescriptor->buffer_page_byte_0); 2689 dprintf("\tnext_physical... 0x%08" B_PRIx32 "\n", topDescriptor->next_physical_descriptor); 2690 dprintf("\tlast_byte....... 0x%08" B_PRIx32 "\n", topDescriptor->last_byte_address); 2691 dprintf("\toffset:\n\t0x%04x 0x%04x 0x%04x 0x%04x\n" 2692 "\t0x%04x 0x%04x 0x%04x 0x%04x\n", 2693 topDescriptor->offset[0], topDescriptor->offset[1], 2694 topDescriptor->offset[2], topDescriptor->offset[3], 2695 topDescriptor->offset[4], topDescriptor->offset[5], 2696 topDescriptor->offset[6], topDescriptor->offset[7]); 2697 dprintf("\tphysical........ 0x%08" B_PRIx32 "\n", topDescriptor->physical_address); 2698 dprintf("\tbuffer_size..... %lu\n", topDescriptor->buffer_size); 2699 dprintf("\tbuffer_logical.. %p\n", topDescriptor->buffer_logical); 2700 dprintf("\tnext_logical.... %p\n", topDescriptor->next_logical_descriptor); 2701 dprintf("\tnext_done....... %p\n", topDescriptor->next_done_descriptor); 2702 2703 topDescriptor = (ohci_isochronous_td *)topDescriptor->next_done_descriptor; 2704 } 2705 } 2706 2707