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