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