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