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