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