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