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