1 /* 2 * Copyright 2005-2008, 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 */ 10 11 #include <module.h> 12 #include <PCI.h> 13 #include <USB3.h> 14 #include <KernelExport.h> 15 16 #include "ohci.h" 17 18 pci_module_info *OHCI::sPCIModule = NULL; 19 20 21 static int32 22 ohci_std_ops(int32 op, ...) 23 { 24 switch (op) { 25 case B_MODULE_INIT: 26 TRACE(("usb_ohci_module: init module\n")); 27 return B_OK; 28 case B_MODULE_UNINIT: 29 TRACE(("usb_ohci_module: uninit module\n")); 30 return B_OK; 31 } 32 33 return EINVAL; 34 } 35 36 37 usb_host_controller_info ohci_module = { 38 { 39 "busses/usb/ohci", 40 0, 41 ohci_std_ops 42 }, 43 NULL, 44 OHCI::AddTo 45 }; 46 47 48 module_info *modules[] = { 49 (module_info *)&ohci_module, 50 NULL 51 }; 52 53 54 OHCI::OHCI(pci_info *info, Stack *stack) 55 : BusManager(stack), 56 fPCIInfo(info), 57 fStack(stack), 58 fOperationalRegisters(NULL), 59 fRegisterArea(-1), 60 fHccaArea(-1), 61 fHcca(NULL), 62 fInterruptEndpoints(NULL), 63 fDummyControl(NULL), 64 fDummyBulk(NULL), 65 fDummyIsochronous(NULL), 66 fFirstTransfer(NULL), 67 fLastTransfer(NULL), 68 fFinishTransfersSem(-1), 69 fFinishThread(-1), 70 fStopFinishThread(false), 71 fRootHub(NULL), 72 fRootHubAddress(0), 73 fPortCount(0) 74 { 75 if (!fInitOK) { 76 TRACE_ERROR(("usb_ohci: bus manager failed to init\n")); 77 return; 78 } 79 80 TRACE(("usb_ohci: constructing new OHCI Host Controller Driver\n")); 81 fInitOK = false; 82 83 mutex_init(&fEndpointLock, "ohci endpoint lock"); 84 85 // enable busmaster and memory mapped access 86 uint16 command = sPCIModule->read_pci_config(fPCIInfo->bus, 87 fPCIInfo->device, fPCIInfo->function, PCI_command, 2); 88 command &= ~PCI_command_io; 89 command |= PCI_command_master | PCI_command_memory; 90 91 sPCIModule->write_pci_config(fPCIInfo->bus, fPCIInfo->device, 92 fPCIInfo->function, PCI_command, 2, command); 93 94 // map the registers 95 uint32 offset = sPCIModule->read_pci_config(fPCIInfo->bus, 96 fPCIInfo->device, fPCIInfo->function, PCI_base_registers, 4); 97 offset &= PCI_address_memory_32_mask; 98 TRACE(("usb_ohci: iospace offset: 0x%lx\n", offset)); 99 fRegisterArea = map_physical_memory("OHCI memory mapped registers", 100 (void *)offset, B_PAGE_SIZE, B_ANY_KERNEL_BLOCK_ADDRESS, 101 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_READ_AREA | B_WRITE_AREA, 102 (void **)&fOperationalRegisters); 103 if (fRegisterArea < B_OK) { 104 TRACE_ERROR(("usb_ohci: failed to map register memory\n")); 105 return; 106 } 107 108 TRACE(("usb_ohci: mapped operational registers: %p\n", 109 fOperationalRegisters)); 110 111 // Check the revision of the controller, which should be 10h 112 uint32 revision = _ReadReg(OHCI_REVISION) & 0xff; 113 TRACE(("usb_ohci: version %ld.%ld%s\n", OHCI_REVISION_HIGH(revision), 114 OHCI_REVISION_LOW(revision), OHCI_REVISION_LEGACY(revision) 115 ? ", legacy support" : "")); 116 if (OHCI_REVISION_HIGH(revision) != 1 || OHCI_REVISION_LOW(revision) != 0) { 117 TRACE_ERROR(("usb_ohci: unsupported OHCI revision\n")); 118 return; 119 } 120 121 void *hccaPhysicalAddress; 122 fHccaArea = fStack->AllocateArea((void **)&fHcca, &hccaPhysicalAddress, 123 sizeof(ohci_hcca), "USB OHCI Host Controller Communication Area"); 124 125 if (fHccaArea < B_OK) { 126 TRACE_ERROR(("usb_ohci: unable to create the HCCA block area\n")); 127 return; 128 } 129 130 memset(fHcca, 0, sizeof(ohci_hcca)); 131 132 // Set Up Host controller 133 // Dummy endpoints 134 fDummyControl = _AllocateEndpoint(); 135 if (!fDummyControl) 136 return; 137 138 fDummyBulk = _AllocateEndpoint(); 139 if (!fDummyBulk) { 140 _FreeEndpoint(fDummyControl); 141 return; 142 } 143 144 fDummyIsochronous = _AllocateEndpoint(); 145 if (!fDummyIsochronous) { 146 _FreeEndpoint(fDummyControl); 147 _FreeEndpoint(fDummyBulk); 148 return; 149 } 150 151 // Static endpoints that get linked in the HCCA 152 fInterruptEndpoints = new(std::nothrow) 153 ohci_endpoint_descriptor *[OHCI_STATIC_ENDPOINT_COUNT]; 154 if (!fInterruptEndpoints) { 155 TRACE_ERROR(("ohci_usb: failed to allocate memory for interrupt endpoints\n")); 156 _FreeEndpoint(fDummyControl); 157 _FreeEndpoint(fDummyBulk); 158 _FreeEndpoint(fDummyIsochronous); 159 return; 160 } 161 162 for (int32 i = 0; i < OHCI_STATIC_ENDPOINT_COUNT; i++) { 163 fInterruptEndpoints[i] = _AllocateEndpoint(); 164 if (!fInterruptEndpoints[i]) { 165 TRACE_ERROR(("ohci_usb: failed to allocate interrupt endpoint %ld", i)); 166 while (--i >= 0) 167 _FreeEndpoint(fInterruptEndpoints[i]); 168 _FreeEndpoint(fDummyBulk); 169 _FreeEndpoint(fDummyControl); 170 _FreeEndpoint(fDummyIsochronous); 171 return; 172 } 173 } 174 175 // build flat tree so that at each of the static interrupt endpoints 176 // fInterruptEndpoints[i] == interrupt endpoint for interval 2^i 177 uint32 interval = OHCI_BIGGEST_INTERVAL; 178 uint32 intervalIndex = OHCI_STATIC_ENDPOINT_COUNT - 1; 179 while (interval > 1) { 180 uint32 insertIndex = interval / 2; 181 while (insertIndex < OHCI_BIGGEST_INTERVAL) { 182 fHcca->interrupt_table[insertIndex] 183 = fInterruptEndpoints[intervalIndex]->physical_address; 184 insertIndex += interval; 185 } 186 187 intervalIndex--; 188 interval /= 2; 189 } 190 191 // setup the empty slot in the list and linking of all -> first 192 fHcca->interrupt_table[0] = fInterruptEndpoints[0]->physical_address; 193 for (int32 i = 1; i < OHCI_STATIC_ENDPOINT_COUNT; i++) { 194 fInterruptEndpoints[i]->next_physical_endpoint 195 = fInterruptEndpoints[0]->physical_address; 196 fInterruptEndpoints[i]->next_logical_endpoint 197 = fInterruptEndpoints[0]; 198 } 199 200 // Now link the first endpoint to the isochronous endpoint 201 fInterruptEndpoints[0]->next_physical_endpoint 202 = fDummyIsochronous->physical_address; 203 204 // Determine in what context we are running (Kindly copied from FreeBSD) 205 uint32 control = _ReadReg(OHCI_CONTROL); 206 if (control & OHCI_INTERRUPT_ROUTING) { 207 TRACE(("usb_ohci: smm is in control of the host controller\n")); 208 uint32 status = _ReadReg(OHCI_COMMAND_STATUS); 209 _WriteReg(OHCI_COMMAND_STATUS, status | OHCI_OWNERSHIP_CHANGE_REQUEST); 210 for (uint32 i = 0; i < 100 && (control & OHCI_INTERRUPT_ROUTING); i++) { 211 snooze(1000); 212 control = _ReadReg(OHCI_CONTROL); 213 } 214 215 if ((control & OHCI_INTERRUPT_ROUTING) != 0) { 216 TRACE_ERROR(("usb_ohci: smm does not respond. resetting...\n")); 217 _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET); 218 snooze(USB_DELAY_BUS_RESET); 219 } else 220 TRACE(("usb_ohci: ownership change successful\n")); 221 } else { 222 TRACE(("usb_ohci: cold started\n")); 223 snooze(USB_DELAY_BUS_RESET); 224 } 225 226 // This reset should not be necessary according to the OHCI spec, but 227 // without it some controllers do not start. 228 _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET); 229 snooze(USB_DELAY_BUS_RESET); 230 231 // We now own the host controller and the bus has been reset 232 uint32 frameInterval = _ReadReg(OHCI_FRAME_INTERVAL); 233 uint32 intervalValue = OHCI_GET_INTERVAL_VALUE(frameInterval); 234 235 // Disable interrupts right before we reset 236 _WriteReg(OHCI_COMMAND_STATUS, OHCI_HOST_CONTROLLER_RESET); 237 // Nominal time for a reset is 10 us 238 uint32 reset = 0; 239 for (uint32 i = 0; i < 10; i++) { 240 spin(10); 241 reset = _ReadReg(OHCI_COMMAND_STATUS) & OHCI_HOST_CONTROLLER_RESET; 242 if (reset == 0) 243 break; 244 } 245 246 if (reset) { 247 TRACE_ERROR(("usb_ohci: Error resetting the host controller (timeout)\n")); 248 return; 249 } 250 251 // The controller is now in SUSPEND state, we have 2ms to go OPERATIONAL. 252 // Interrupts are disabled. 253 254 // Set up host controller register 255 _WriteReg(OHCI_HCCA, (uint32)hccaPhysicalAddress); 256 _WriteReg(OHCI_CONTROL_HEAD_ED, (uint32)fDummyControl->physical_address); 257 _WriteReg(OHCI_BULK_HEAD_ED, (uint32)fDummyBulk->physical_address); 258 // Disable all interrupts 259 _WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTERRUPTS); 260 // Switch on desired functional features 261 control = _ReadReg(OHCI_CONTROL); 262 control &= ~(OHCI_CONTROL_BULK_SERVICE_RATIO_MASK | OHCI_ENABLE_LIST 263 | OHCI_HC_FUNCTIONAL_STATE_MASK | OHCI_INTERRUPT_ROUTING); 264 control |= OHCI_ENABLE_LIST | OHCI_CONTROL_BULK_RATIO_1_4 265 | OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL; 266 // And finally start the controller 267 _WriteReg(OHCI_CONTROL, control); 268 269 // The controller is now OPERATIONAL. 270 frameInterval = (_ReadReg(OHCI_FRAME_INTERVAL) & OHCI_FRAME_INTERVAL_TOGGLE) 271 ^ OHCI_FRAME_INTERVAL_TOGGLE; 272 frameInterval |= OHCI_FSMPS(intervalValue) | intervalValue; 273 _WriteReg(OHCI_FRAME_INTERVAL, frameInterval); 274 // 90% periodic 275 uint32 periodic = OHCI_PERIODIC(intervalValue); 276 _WriteReg(OHCI_PERIODIC_START, periodic); 277 278 // Fiddle the No Over Current Protection bit to avoid chip bug 279 uint32 desca = _ReadReg(OHCI_RH_DESCRIPTOR_A); 280 _WriteReg(OHCI_RH_DESCRIPTOR_A, desca | OHCI_RH_NO_OVER_CURRENT_PROTECTION); 281 _WriteReg(OHCI_RH_STATUS, OHCI_RH_LOCAL_POWER_STATUS_CHANGE); 282 snooze(OHCI_ENABLE_POWER_DELAY); 283 _WriteReg(OHCI_RH_DESCRIPTOR_A, desca); 284 285 // The AMD756 requires a delay before re-reading the register, 286 // otherwise it will occasionally report 0 ports. 287 uint32 numberOfPorts = 0; 288 for (uint32 i = 0; i < 10 && numberOfPorts == 0; i++) { 289 snooze(OHCI_READ_DESC_DELAY); 290 uint32 descriptor = _ReadReg(OHCI_RH_DESCRIPTOR_A); 291 numberOfPorts = OHCI_RH_GET_PORT_COUNT(descriptor); 292 } 293 if (numberOfPorts > OHCI_MAX_PORT_COUNT) 294 numberOfPorts = OHCI_MAX_PORT_COUNT; 295 fPortCount = numberOfPorts; 296 TRACE(("usb_ohci: port count is %d\n", fPortCount)); 297 298 // Create semaphore the finisher thread will wait for 299 fFinishTransfersSem = create_sem(0, "OHCI Finish Transfers"); 300 if (fFinishTransfersSem < B_OK) { 301 TRACE_ERROR(("usb_ohci: failed to create semaphore\n")); 302 return; 303 } 304 305 // Create the finisher service thread 306 fFinishThread = spawn_kernel_thread(_FinishThread, "ohci finish thread", 307 B_URGENT_DISPLAY_PRIORITY, (void *)this); 308 resume_thread(fFinishThread); 309 310 // Install the interrupt handler 311 TRACE(("usb_ohci: installing interrupt handler\n")); 312 install_io_interrupt_handler(fPCIInfo->u.h0.interrupt_line, 313 _InterruptHandler, (void *)this, 0); 314 315 // Enable interesting interrupts now that the handler is in place 316 _WriteReg(OHCI_INTERRUPT_ENABLE, OHCI_NORMAL_INTERRUPTS 317 | OHCI_MASTER_INTERRUPT_ENABLE); 318 319 TRACE(("usb_ohci: OHCI Host Controller Driver constructed\n")); 320 fInitOK = true; 321 } 322 323 324 OHCI::~OHCI() 325 { 326 int32 result = 0; 327 fStopFinishThread = true; 328 delete_sem(fFinishTransfersSem); 329 wait_for_thread(fFinishThread, &result); 330 331 _LockEndpoints(); 332 mutex_destroy(&fEndpointLock); 333 334 if (fHccaArea >= B_OK) 335 delete_area(fHccaArea); 336 if (fRegisterArea >= B_OK) 337 delete_area(fRegisterArea); 338 339 _FreeEndpoint(fDummyControl); 340 _FreeEndpoint(fDummyBulk); 341 _FreeEndpoint(fDummyIsochronous); 342 343 if (fInterruptEndpoints != NULL) { 344 for (int i = 0; i < OHCI_STATIC_ENDPOINT_COUNT; i++) 345 _FreeEndpoint(fInterruptEndpoints[i]); 346 } 347 348 delete [] fInterruptEndpoints; 349 delete fRootHub; 350 351 put_module(B_PCI_MODULE_NAME); 352 } 353 354 355 status_t 356 OHCI::Start() 357 { 358 TRACE(("usb_ohci: starting OHCI Host Controller\n")); 359 360 uint32 control = _ReadReg(OHCI_CONTROL); 361 if ((control & OHCI_HC_FUNCTIONAL_STATE_MASK) 362 != OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL) { 363 TRACE_ERROR(("usb_ohci: Controller not started (0x%08lx)!\n", 364 control)); 365 return B_ERROR; 366 } else 367 TRACE(("usb_ohci: Controller is operational!\n")); 368 369 fRootHubAddress = AllocateAddress(); 370 fRootHub = new(std::nothrow) OHCIRootHub(RootObject(), fRootHubAddress); 371 if (!fRootHub) { 372 TRACE_ERROR(("usb_ohci: no memory to allocate root hub\n")); 373 return B_NO_MEMORY; 374 } 375 376 if (fRootHub->InitCheck() < B_OK) { 377 TRACE_ERROR(("usb_ohci: root hub failed init check\n")); 378 return B_ERROR; 379 } 380 381 SetRootHub(fRootHub); 382 dprintf("usb_ohci: successfully started the controller\n"); 383 return BusManager::Start(); 384 } 385 386 387 status_t 388 OHCI::SubmitTransfer(Transfer *transfer) 389 { 390 // short circuit the root hub 391 if (transfer->TransferPipe()->DeviceAddress() == fRootHubAddress) 392 return fRootHub->ProcessTransfer(this, transfer); 393 394 uint32 type = transfer->TransferPipe()->Type(); 395 if (type & USB_OBJECT_CONTROL_PIPE) { 396 TRACE(("usb_ohci: submitting request\n")); 397 return _SubmitRequest(transfer); 398 } 399 400 if ((type & USB_OBJECT_BULK_PIPE) || (type & USB_OBJECT_INTERRUPT_PIPE)) { 401 TRACE(("usb_ohci: submitting %s transfer\n", 402 (type & USB_OBJECT_BULK_PIPE) ? "bulk" : "interrupt")); 403 return _SubmitTransfer(transfer); 404 } 405 406 if (type & USB_OBJECT_ISO_PIPE) { 407 TRACE(("usb_ohci: submitting isochronous transfer\n")); 408 return _SubmitIsochronousTransfer(transfer); 409 } 410 411 TRACE_ERROR(("usb_ohci: tried to submit transfer for unknown pipe" 412 " type %lu\n", type)); 413 return B_ERROR; 414 } 415 416 417 status_t 418 OHCI::CancelQueuedTransfers(Pipe *pipe, bool force) 419 { 420 if (pipe->Type() & USB_OBJECT_ISO_PIPE) 421 return _CancelQueuedIsochronousTransfers(pipe, force); 422 423 if (!Lock()) 424 return B_ERROR; 425 426 struct transfer_entry { 427 Transfer * transfer; 428 transfer_entry * next; 429 }; 430 431 transfer_entry *list = NULL; 432 transfer_data *current = fFirstTransfer; 433 while (current) { 434 if (current->transfer && current->transfer->TransferPipe() == pipe) { 435 // Check if the skip bit is already set 436 if (!(current->endpoint->flags & OHCI_ENDPOINT_SKIP)) { 437 current->endpoint->flags |= OHCI_ENDPOINT_SKIP; 438 // In case the controller is processing 439 // this endpoint, wait for it to finish 440 snooze(1000); 441 } 442 443 // Clear the endpoint 444 current->endpoint->head_physical_descriptor 445 = current->endpoint->tail_physical_descriptor; 446 447 if (!force) { 448 // If the transfer is canceled by force, the one causing the 449 // cancel is probably not the one who initiated the transfer 450 // and the callback is likely not safe anymore 451 transfer_entry *entry 452 = (transfer_entry *)malloc(sizeof(transfer_entry)); 453 if (entry != NULL) { 454 entry->transfer = current->transfer; 455 current->transfer = NULL; 456 entry->next = list; 457 list = entry; 458 } 459 } 460 current->canceled = true; 461 } 462 current = current->link; 463 } 464 465 Unlock(); 466 467 while (list != NULL) { 468 transfer_entry *next = list->next; 469 list->transfer->Finished(B_CANCELED, 0); 470 delete list->transfer; 471 free(list); 472 list = next; 473 } 474 475 // notify the finisher so it can clean up the canceled transfers 476 release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE); 477 return B_OK; 478 } 479 480 481 status_t 482 OHCI::NotifyPipeChange(Pipe *pipe, usb_change change) 483 { 484 TRACE(("usb_ohci: pipe change %d for pipe 0x%08lx\n", change, (uint32)pipe)); 485 if (pipe->DeviceAddress() == fRootHubAddress) { 486 // no need to insert/remove endpoint descriptors for the root hub 487 return B_OK; 488 } 489 490 switch (change) { 491 case USB_CHANGE_CREATED: 492 return _InsertEndpointForPipe(pipe); 493 494 case USB_CHANGE_DESTROYED: 495 return _RemoveEndpointForPipe(pipe); 496 497 case USB_CHANGE_PIPE_POLICY_CHANGED: 498 TRACE(("usb_ohci: pipe policy changing unhandled!\n")); 499 break; 500 501 default: 502 TRACE_ERROR(("usb_ohci: unknown pipe change!\n")); 503 return B_ERROR; 504 } 505 506 return B_OK; 507 } 508 509 510 status_t 511 OHCI::AddTo(Stack *stack) 512 { 513 #ifdef TRACE_USB 514 set_dprintf_enabled(true); 515 #ifndef __HAIKU__ 516 load_driver_symbols("ohci"); 517 #endif 518 #endif 519 520 if (!sPCIModule) { 521 status_t status = get_module(B_PCI_MODULE_NAME, (module_info **)&sPCIModule); 522 if (status < B_OK) { 523 TRACE_ERROR(("usb_ohci: getting pci module failed! 0x%08lx\n", 524 status)); 525 return status; 526 } 527 } 528 529 TRACE(("usb_ohci: searching devices\n")); 530 bool found = false; 531 pci_info *item = new(std::nothrow) pci_info; 532 if (!item) { 533 sPCIModule = NULL; 534 put_module(B_PCI_MODULE_NAME); 535 return B_NO_MEMORY; 536 } 537 538 for (uint32 i = 0 ; sPCIModule->get_nth_pci_info(i, item) >= B_OK; i++) { 539 if (item->class_base == PCI_serial_bus && item->class_sub == PCI_usb 540 && item->class_api == PCI_usb_ohci) { 541 if (item->u.h0.interrupt_line == 0 542 || item->u.h0.interrupt_line == 0xFF) { 543 TRACE_ERROR(("usb_ohci: found device with invalid IRQ -" 544 " check IRQ assignement\n")); 545 continue; 546 } 547 548 TRACE(("usb_ohci: found device at IRQ %u\n", 549 item->u.h0.interrupt_line)); 550 OHCI *bus = new(std::nothrow) OHCI(item, stack); 551 if (!bus) { 552 delete item; 553 sPCIModule = NULL; 554 put_module(B_PCI_MODULE_NAME); 555 return B_NO_MEMORY; 556 } 557 558 if (bus->InitCheck() < B_OK) { 559 TRACE_ERROR(("usb_ohci: bus failed init check\n")); 560 delete bus; 561 continue; 562 } 563 564 // the bus took it away 565 item = new(std::nothrow) pci_info; 566 567 bus->Start(); 568 stack->AddBusManager(bus); 569 found = true; 570 } 571 } 572 573 if (!found) { 574 TRACE_ERROR(("usb_ohci: no devices found\n")); 575 delete item; 576 sPCIModule = NULL; 577 put_module(B_PCI_MODULE_NAME); 578 return ENODEV; 579 } 580 581 delete item; 582 return B_OK; 583 } 584 585 586 status_t 587 OHCI::GetPortStatus(uint8 index, usb_port_status *status) 588 { 589 if (index >= fPortCount) { 590 TRACE_ERROR(("usb_ohci: get port status for invalid port %u\n", index)); 591 return B_BAD_INDEX; 592 } 593 594 status->status = status->change = 0; 595 uint32 portStatus = _ReadReg(OHCI_RH_PORT_STATUS(index)); 596 597 // status 598 if (portStatus & OHCI_RH_PORTSTATUS_CCS) 599 status->status |= PORT_STATUS_CONNECTION; 600 if (portStatus & OHCI_RH_PORTSTATUS_PES) 601 status->status |= PORT_STATUS_ENABLE; 602 if (portStatus & OHCI_RH_PORTSTATUS_PSS) 603 status->status |= PORT_STATUS_SUSPEND; 604 if (portStatus & OHCI_RH_PORTSTATUS_POCI) 605 status->status |= PORT_STATUS_OVER_CURRENT; 606 if (portStatus & OHCI_RH_PORTSTATUS_PRS) 607 status->status |= PORT_STATUS_RESET; 608 if (portStatus & OHCI_RH_PORTSTATUS_PPS) 609 status->status |= PORT_STATUS_POWER; 610 if (portStatus & OHCI_RH_PORTSTATUS_LSDA) 611 status->status |= PORT_STATUS_LOW_SPEED; 612 613 // change 614 if (portStatus & OHCI_RH_PORTSTATUS_CSC) 615 status->change |= PORT_STATUS_CONNECTION; 616 if (portStatus & OHCI_RH_PORTSTATUS_PESC) 617 status->change |= PORT_STATUS_ENABLE; 618 if (portStatus & OHCI_RH_PORTSTATUS_PSSC) 619 status->change |= PORT_STATUS_SUSPEND; 620 if (portStatus & OHCI_RH_PORTSTATUS_OCIC) 621 status->change |= PORT_STATUS_OVER_CURRENT; 622 if (portStatus & OHCI_RH_PORTSTATUS_PRSC) 623 status->change |= PORT_STATUS_RESET; 624 625 TRACE(("usb_ohci: port %u status 0x%04x change 0x%04x\n", index, 626 status->status, status->change)); 627 return B_OK; 628 } 629 630 631 status_t 632 OHCI::SetPortFeature(uint8 index, uint16 feature) 633 { 634 TRACE(("usb_ohci: set port feature index %u feature %u\n", index, feature)); 635 if (index > fPortCount) 636 return B_BAD_INDEX; 637 638 switch (feature) { 639 case PORT_ENABLE: 640 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PES); 641 return B_OK; 642 643 case PORT_SUSPEND: 644 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PSS); 645 return B_OK; 646 647 case PORT_RESET: 648 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PRS); 649 return B_OK; 650 651 case PORT_POWER: 652 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PPS); 653 return B_OK; 654 } 655 656 return B_BAD_VALUE; 657 } 658 659 660 status_t 661 OHCI::ClearPortFeature(uint8 index, uint16 feature) 662 { 663 TRACE(("usb_ohci: clear port feature index %u feature %u\n", index, feature)); 664 if (index > fPortCount) 665 return B_BAD_INDEX; 666 667 switch (feature) { 668 case PORT_ENABLE: 669 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CCS); 670 return B_OK; 671 672 case PORT_SUSPEND: 673 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_POCI); 674 return B_OK; 675 676 case PORT_POWER: 677 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_LSDA); 678 return B_OK; 679 680 case C_PORT_CONNECTION: 681 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CSC); 682 return B_OK; 683 684 case C_PORT_ENABLE: 685 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PESC); 686 return B_OK; 687 688 case C_PORT_SUSPEND: 689 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PSSC); 690 return B_OK; 691 692 case C_PORT_OVER_CURRENT: 693 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_OCIC); 694 return B_OK; 695 696 case C_PORT_RESET: 697 _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PRSC); 698 return B_OK; 699 } 700 701 return B_BAD_VALUE; 702 } 703 704 705 int32 706 OHCI::_InterruptHandler(void *data) 707 { 708 return ((OHCI *)data)->_Interrupt(); 709 } 710 711 712 int32 713 OHCI::_Interrupt() 714 { 715 static spinlock lock = B_SPINLOCK_INITIALIZER; 716 acquire_spinlock(&lock); 717 718 uint32 status = 0; 719 uint32 acknowledge = 0; 720 bool finishTransfers = false; 721 int32 result = B_HANDLED_INTERRUPT; 722 723 // The LSb of done_head is used to inform the HCD that an interrupt 724 // condition exists for both the done list and for another event recorded in 725 // the HcInterruptStatus register. If done_head is 0, then the interrupt 726 // was caused by other than the HccaDoneHead update and the 727 // HcInterruptStatus register needs to be accessed to determine that exact 728 // interrupt cause. If HccDoneHead is nonzero, then a done list update 729 // interrupt is indicated and if the LSb of the Dword is nonzero, then an 730 // additional interrupt event is indicated and HcInterruptStatus should be 731 // checked to determine its cause. 732 uint32 doneHead = fHcca->done_head; 733 if (doneHead != 0) { 734 status = OHCI_WRITEBACK_DONE_HEAD; 735 if (doneHead & OHCI_DONE_INTERRUPTS) 736 status |= _ReadReg(OHCI_INTERRUPT_STATUS) 737 & _ReadReg(OHCI_INTERRUPT_ENABLE); 738 } else { 739 status = _ReadReg(OHCI_INTERRUPT_STATUS) & _ReadReg(OHCI_INTERRUPT_ENABLE) 740 & ~OHCI_WRITEBACK_DONE_HEAD; 741 if (status == 0) { 742 // Nothing to be done (PCI shared interrupt) 743 release_spinlock(&lock); 744 return B_UNHANDLED_INTERRUPT; 745 } 746 } 747 748 if (status & OHCI_SCHEDULING_OVERRUN) { 749 TRACE(("usb_ohci: scheduling overrun occured\n")); 750 acknowledge |= OHCI_SCHEDULING_OVERRUN; 751 } 752 753 if (status & OHCI_WRITEBACK_DONE_HEAD) { 754 TRACE(("usb_ohci: transfer descriptors processed\n")); 755 fHcca->done_head = 0; 756 acknowledge |= OHCI_WRITEBACK_DONE_HEAD; 757 result = B_INVOKE_SCHEDULER; 758 finishTransfers = true; 759 } 760 761 if (status & OHCI_RESUME_DETECTED) { 762 TRACE(("usb_ohci: resume detected\n")); 763 acknowledge |= OHCI_RESUME_DETECTED; 764 } 765 766 if (status & OHCI_UNRECOVERABLE_ERROR) { 767 TRACE_ERROR(("usb_ohci: unrecoverable error - controller halted\n")); 768 _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET); 769 // TODO: clear all pending transfers, reset and resetup the controller 770 } 771 772 if (status & OHCI_ROOT_HUB_STATUS_CHANGE) { 773 TRACE(("usb_ohci: root hub status change\n")); 774 // Disable the interrupt as it will otherwise be retriggered until the 775 // port has been reset and the change is cleared explicitly. 776 // TODO: renable it once we use status changes instead of polling 777 _WriteReg(OHCI_INTERRUPT_DISABLE, OHCI_ROOT_HUB_STATUS_CHANGE); 778 acknowledge |= OHCI_ROOT_HUB_STATUS_CHANGE; 779 } 780 781 if (acknowledge != 0) 782 _WriteReg(OHCI_INTERRUPT_STATUS, acknowledge); 783 784 release_spinlock(&lock); 785 786 if (finishTransfers) 787 release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE); 788 789 return result; 790 } 791 792 793 status_t 794 OHCI::_AddPendingTransfer(Transfer *transfer, 795 ohci_endpoint_descriptor *endpoint, ohci_general_td *firstDescriptor, 796 ohci_general_td *dataDescriptor, ohci_general_td *lastDescriptor, 797 bool directionIn) 798 { 799 if (!transfer || !endpoint || !lastDescriptor) 800 return B_BAD_VALUE; 801 802 transfer_data *data = new(std::nothrow) transfer_data; 803 if (!data) 804 return B_NO_MEMORY; 805 806 status_t result = transfer->InitKernelAccess(); 807 if (result < B_OK) { 808 delete data; 809 return result; 810 } 811 812 data->transfer = transfer; 813 data->endpoint = endpoint; 814 data->incoming = directionIn; 815 data->canceled = false; 816 data->link = NULL; 817 818 // the current tail will become the fist descriptor 819 data->first_descriptor = (ohci_general_td *)endpoint->tail_logical_descriptor; 820 821 // the data and first descriptors might be the same 822 if (dataDescriptor == firstDescriptor) 823 data->data_descriptor = data->first_descriptor; 824 else 825 data->data_descriptor = dataDescriptor; 826 827 // even the last and the first descriptor might be the same 828 if (lastDescriptor == firstDescriptor) 829 data->last_descriptor = data->first_descriptor; 830 else 831 data->last_descriptor = lastDescriptor; 832 833 if (!Lock()) { 834 delete data; 835 return B_ERROR; 836 } 837 838 if (fLastTransfer) 839 fLastTransfer->link = data; 840 else 841 fFirstTransfer = data; 842 843 fLastTransfer = data; 844 Unlock(); 845 846 return B_OK; 847 } 848 849 850 status_t 851 OHCI::_CancelQueuedIsochronousTransfers(Pipe *pipe, bool force) 852 { 853 // TODO 854 return B_ERROR; 855 } 856 857 858 int32 859 OHCI::_FinishThread(void *data) 860 { 861 ((OHCI *)data)->_FinishTransfers(); 862 return B_OK; 863 } 864 865 866 void 867 OHCI::_FinishTransfers() 868 { 869 while (!fStopFinishThread) { 870 if (acquire_sem(fFinishTransfersSem) < B_OK) 871 continue; 872 873 // eat up sems that have been released by multiple interrupts 874 int32 semCount = 0; 875 get_sem_count(fFinishTransfersSem, &semCount); 876 if (semCount > 0) 877 acquire_sem_etc(fFinishTransfersSem, semCount, B_RELATIVE_TIMEOUT, 0); 878 879 if (!Lock()) 880 continue; 881 882 TRACE(("usb_ohci: finishing transfers (first transfer: %p; last" 883 " transfer: %p)\n", fFirstTransfer, fLastTransfer)); 884 transfer_data *lastTransfer = NULL; 885 transfer_data *transfer = fFirstTransfer; 886 Unlock(); 887 888 while (transfer) { 889 bool transferDone = false; 890 ohci_general_td *descriptor = transfer->first_descriptor; 891 status_t callbackStatus = B_OK; 892 893 while (descriptor && !transfer->canceled) { 894 uint32 status = OHCI_TD_GET_CONDITION_CODE(descriptor->flags); 895 if (status == OHCI_TD_CONDITION_NOT_ACCESSED) { 896 // td is still active 897 TRACE(("usb_ohci: td %p still active\n", descriptor)); 898 break; 899 } 900 901 if (status != OHCI_TD_CONDITION_NO_ERROR) { 902 // an error occured, but we must ensure that the td 903 // was actually done 904 ohci_endpoint_descriptor *endpoint = transfer->endpoint; 905 if (endpoint->head_physical_descriptor & OHCI_ENDPOINT_HALTED) { 906 // the endpoint is halted, this guaratees us that this 907 // descriptor has passed (we don't know if the endpoint 908 // was halted because of this td, but we do not need 909 // to know, as when it was halted by another td this 910 // still ensures that this td was handled before). 911 TRACE_ERROR(("usb_ohci: td error: 0x%08lx\n", status)); 912 913 switch (status) { 914 case OHCI_TD_CONDITION_CRC_ERROR: 915 case OHCI_TD_CONDITION_BIT_STUFFING: 916 case OHCI_TD_CONDITION_TOGGLE_MISMATCH: 917 callbackStatus = B_DEV_CRC_ERROR; 918 break; 919 920 case OHCI_TD_CONDITION_STALL: 921 callbackStatus = B_DEV_STALLED; 922 break; 923 924 case OHCI_TD_CONDITION_NO_RESPONSE: 925 callbackStatus = B_TIMED_OUT; 926 break; 927 928 case OHCI_TD_CONDITION_PID_CHECK_FAILURE: 929 callbackStatus = B_DEV_BAD_PID; 930 break; 931 932 case OHCI_TD_CONDITION_UNEXPECTED_PID: 933 callbackStatus = B_DEV_UNEXPECTED_PID; 934 break; 935 936 case OHCI_TD_CONDITION_DATA_OVERRUN: 937 callbackStatus = B_DEV_DATA_OVERRUN; 938 break; 939 940 case OHCI_TD_CONDITION_DATA_UNDERRUN: 941 callbackStatus = B_DEV_DATA_UNDERRUN; 942 break; 943 944 case OHCI_TD_CONDITION_BUFFER_OVERRUN: 945 callbackStatus = B_DEV_FIFO_OVERRUN; 946 break; 947 948 case OHCI_TD_CONDITION_BUFFER_UNDERRUN: 949 callbackStatus = B_DEV_FIFO_UNDERRUN; 950 break; 951 952 default: 953 callbackStatus = B_ERROR; 954 break; 955 } 956 957 transferDone = true; 958 break; 959 } else { 960 // an error occured but the endpoint is not halted so 961 // the td is in fact still active 962 TRACE(("usb_ohci: td %p active with error\n", descriptor)); 963 break; 964 } 965 } 966 967 // the td has complete without an error 968 TRACE(("usb_ohci: td %p done\n", descriptor)); 969 970 if (descriptor == transfer->last_descriptor 971 || descriptor->buffer_physical != 0) { 972 // this is the last td of the transfer or a short packet 973 callbackStatus = B_OK; 974 transferDone = true; 975 break; 976 } 977 978 descriptor 979 = (ohci_general_td *)descriptor->next_logical_descriptor; 980 } 981 982 if (transfer->canceled) { 983 // when a transfer is canceled, all transfers to that endpoint 984 // are canceled by setting the head pointer to the tail pointer 985 // which causes all of the tds to become "free" (as they are 986 // inaccessible and not accessed anymore (as setting the head 987 // pointer required disabling the endpoint)) 988 callbackStatus = B_OK; 989 transferDone = true; 990 } 991 992 if (!transferDone) { 993 lastTransfer = transfer; 994 transfer = transfer->link; 995 continue; 996 } 997 998 // remove the transfer from the list first so we are sure 999 // it doesn't get canceled while we still process it 1000 transfer_data *next = transfer->link; 1001 if (Lock()) { 1002 if (lastTransfer) 1003 lastTransfer->link = transfer->link; 1004 1005 if (transfer == fFirstTransfer) 1006 fFirstTransfer = transfer->link; 1007 if (transfer == fLastTransfer) 1008 fLastTransfer = lastTransfer; 1009 1010 transfer->link = NULL; 1011 Unlock(); 1012 } 1013 1014 // break the descriptor chain on the last descriptor 1015 transfer->last_descriptor->next_logical_descriptor = NULL; 1016 TRACE(("usb_ohci: transfer %p done with status 0x%08lx\n", 1017 transfer, callbackStatus)); 1018 1019 // if canceled the callback has already been called 1020 if (!transfer->canceled) { 1021 size_t actualLength = 0; 1022 if (callbackStatus == B_OK) { 1023 if (transfer->data_descriptor && transfer->incoming) { 1024 // data to read out 1025 iovec *vector = transfer->transfer->Vector(); 1026 size_t vectorCount = transfer->transfer->VectorCount(); 1027 1028 transfer->transfer->PrepareKernelAccess(); 1029 actualLength = _ReadDescriptorChain( 1030 transfer->data_descriptor, 1031 vector, vectorCount); 1032 } else if (transfer->data_descriptor) { 1033 // read the actual length that was sent 1034 actualLength = _ReadActualLength( 1035 transfer->data_descriptor); 1036 } 1037 1038 if (transfer->transfer->IsFragmented()) { 1039 // this transfer may still have data left 1040 TRACE(("usb_ohci: advancing fragmented transfer\n")); 1041 transfer->transfer->AdvanceByFragment(actualLength); 1042 if (transfer->transfer->VectorLength() > 0) { 1043 TRACE(("usb_ohci: still %ld bytes left on transfer\n", 1044 transfer->transfer->VectorLength())); 1045 // TODO actually resubmit the transfer 1046 } 1047 1048 // the transfer is done, but we already set the 1049 // actualLength with AdvanceByFragment() 1050 actualLength = 0; 1051 } 1052 } 1053 1054 transfer->transfer->Finished(callbackStatus, actualLength); 1055 } 1056 1057 if (callbackStatus != B_OK) { 1058 // remove the transfer and make the head pointer valid again 1059 // (including clearing the halt state) 1060 _RemoveTransferFromEndpoint(transfer); 1061 } 1062 1063 // free the descriptors 1064 _FreeDescriptorChain(transfer->first_descriptor); 1065 1066 delete transfer->transfer; 1067 delete transfer; 1068 transfer = next; 1069 } 1070 } 1071 } 1072 1073 1074 status_t 1075 OHCI::_SubmitRequest(Transfer *transfer) 1076 { 1077 usb_request_data *requestData = transfer->RequestData(); 1078 bool directionIn = (requestData->RequestType & USB_REQTYPE_DEVICE_IN) > 0; 1079 1080 ohci_general_td *setupDescriptor 1081 = _CreateGeneralDescriptor(sizeof(usb_request_data)); 1082 if (!setupDescriptor) { 1083 TRACE_ERROR(("usb_ohci: failed to allocate setup descriptor\n")); 1084 return B_NO_MEMORY; 1085 } 1086 1087 setupDescriptor->flags = OHCI_TD_DIRECTION_PID_SETUP 1088 | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) 1089 | OHCI_TD_TOGGLE_0 1090 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE); 1091 1092 ohci_general_td *statusDescriptor = _CreateGeneralDescriptor(0); 1093 if (!statusDescriptor) { 1094 TRACE_ERROR(("usb_ohci: failed to allocate status descriptor\n")); 1095 _FreeGeneralDescriptor(setupDescriptor); 1096 return B_NO_MEMORY; 1097 } 1098 1099 statusDescriptor->flags 1100 = (directionIn ? OHCI_TD_DIRECTION_PID_OUT : OHCI_TD_DIRECTION_PID_IN) 1101 | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) 1102 | OHCI_TD_TOGGLE_1 1103 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE); 1104 1105 iovec vector; 1106 vector.iov_base = requestData; 1107 vector.iov_len = sizeof(usb_request_data); 1108 _WriteDescriptorChain(setupDescriptor, &vector, 1); 1109 1110 status_t result; 1111 ohci_general_td *dataDescriptor = NULL; 1112 if (transfer->VectorCount() > 0) { 1113 ohci_general_td *lastDescriptor = NULL; 1114 result = _CreateDescriptorChain(&dataDescriptor, &lastDescriptor, 1115 directionIn ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT, 1116 transfer->VectorLength()); 1117 if (result < B_OK) { 1118 _FreeGeneralDescriptor(setupDescriptor); 1119 _FreeGeneralDescriptor(statusDescriptor); 1120 return result; 1121 } 1122 1123 if (!directionIn) { 1124 _WriteDescriptorChain(dataDescriptor, transfer->Vector(), 1125 transfer->VectorCount()); 1126 } 1127 1128 _LinkDescriptors(setupDescriptor, dataDescriptor); 1129 _LinkDescriptors(lastDescriptor, statusDescriptor); 1130 } else { 1131 _LinkDescriptors(setupDescriptor, statusDescriptor); 1132 } 1133 1134 // Add to the transfer list 1135 ohci_endpoint_descriptor *endpoint 1136 = (ohci_endpoint_descriptor *)transfer->TransferPipe()->ControllerCookie(); 1137 result = _AddPendingTransfer(transfer, endpoint, setupDescriptor, 1138 dataDescriptor, statusDescriptor, directionIn); 1139 if (result < B_OK) { 1140 TRACE_ERROR(("usb_ohci: failed to add pending transfer\n")); 1141 _FreeDescriptorChain(setupDescriptor); 1142 return result; 1143 } 1144 1145 // Add the descriptor chain to the endpoint 1146 _SwitchEndpointTail(endpoint, setupDescriptor, statusDescriptor); 1147 1148 // Tell the controller to process the control list 1149 endpoint->flags &= ~OHCI_ENDPOINT_SKIP; 1150 _WriteReg(OHCI_COMMAND_STATUS, OHCI_CONTROL_LIST_FILLED); 1151 return B_OK; 1152 } 1153 1154 1155 status_t 1156 OHCI::_SubmitTransfer(Transfer *transfer) 1157 { 1158 Pipe *pipe = transfer->TransferPipe(); 1159 bool directionIn = (pipe->Direction() == Pipe::In); 1160 1161 ohci_general_td *firstDescriptor = NULL; 1162 ohci_general_td *lastDescriptor = NULL; 1163 status_t result = _CreateDescriptorChain(&firstDescriptor, &lastDescriptor, 1164 directionIn ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT, 1165 transfer->VectorLength()); 1166 1167 if (result < B_OK) 1168 return result; 1169 1170 // Set the last descriptor to generate an interrupt 1171 lastDescriptor->flags &= ~OHCI_TD_INTERRUPT_MASK; 1172 lastDescriptor->flags |= 1173 OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_IMMEDIATE); 1174 1175 if (!directionIn) { 1176 _WriteDescriptorChain(firstDescriptor, transfer->Vector(), 1177 transfer->VectorCount()); 1178 } 1179 1180 // Add to the transfer list 1181 ohci_endpoint_descriptor *endpoint 1182 = (ohci_endpoint_descriptor *)pipe->ControllerCookie(); 1183 result = _AddPendingTransfer(transfer, endpoint, firstDescriptor, 1184 firstDescriptor, lastDescriptor, directionIn); 1185 if (result < B_OK) { 1186 TRACE_ERROR(("usb_ohci: failed to add pending transfer\n")); 1187 _FreeDescriptorChain(firstDescriptor); 1188 return result; 1189 } 1190 1191 // Add the descriptor chain to the endpoint 1192 _SwitchEndpointTail(endpoint, firstDescriptor, lastDescriptor); 1193 endpoint->flags &= ~OHCI_ENDPOINT_SKIP; 1194 1195 if (pipe->Type() & USB_OBJECT_BULK_PIPE) { 1196 // Tell the controller to process the bulk list 1197 _WriteReg(OHCI_COMMAND_STATUS, OHCI_BULK_LIST_FILLED); 1198 } 1199 1200 return B_OK; 1201 } 1202 1203 1204 status_t 1205 OHCI::_SubmitIsochronousTransfer(Transfer *transfer) 1206 { 1207 return B_ERROR; 1208 } 1209 1210 1211 void 1212 OHCI::_SwitchEndpointTail(ohci_endpoint_descriptor *endpoint, 1213 ohci_general_td *first, ohci_general_td *last) 1214 { 1215 // fill in the information of the first descriptor into the current tail 1216 ohci_general_td *tail = (ohci_general_td *)endpoint->tail_logical_descriptor; 1217 tail->flags = first->flags; 1218 tail->buffer_physical = first->buffer_physical; 1219 tail->next_physical_descriptor = first->next_physical_descriptor; 1220 tail->last_physical_byte_address = first->last_physical_byte_address; 1221 tail->buffer_size = first->buffer_size; 1222 tail->buffer_logical = first->buffer_logical; 1223 tail->next_logical_descriptor = first->next_logical_descriptor; 1224 1225 // the first descriptor becomes the new tail 1226 first->flags = 0; 1227 first->buffer_physical = 0; 1228 first->next_physical_descriptor = 0; 1229 first->last_physical_byte_address = 0; 1230 first->buffer_size = 0; 1231 first->buffer_logical = NULL; 1232 first->next_logical_descriptor = NULL; 1233 1234 if (first == last) 1235 _LinkDescriptors(tail, first); 1236 else 1237 _LinkDescriptors(last, first); 1238 1239 // update the endpoint tail pointer to reflect the change 1240 endpoint->tail_logical_descriptor = first; 1241 endpoint->tail_physical_descriptor = (uint32)first->physical_address; 1242 1243 #if 0 1244 _PrintEndpoint(endpoint); 1245 _PrintDescriptorChain(tail); 1246 #endif 1247 } 1248 1249 1250 void 1251 OHCI::_RemoveTransferFromEndpoint(transfer_data *transfer) 1252 { 1253 // The transfer failed and the endpoint was halted. This means that the 1254 // endpoint head pointer might point somewhere into the descriptor chain 1255 // of this transfer. As we do not know if this transfer actually caused 1256 // the halt on the endpoint we have to make sure this is the case. If we 1257 // find the head to point to somewhere into the descriptor chain then 1258 // simply advancing the head pointer to the link of the last transfer 1259 // will bring the endpoint into a valid state again. This operation is 1260 // safe as the endpoint is currently halted and we therefore can change 1261 // the head pointer. 1262 ohci_endpoint_descriptor *endpoint = transfer->endpoint; 1263 ohci_general_td *descriptor = transfer->first_descriptor; 1264 while (descriptor) { 1265 if ((endpoint->head_physical_descriptor & OHCI_ENDPOINT_HEAD_MASK) 1266 == descriptor->physical_address) { 1267 // This descriptor caused the halt. Advance the head pointer. This 1268 // will either move the head to the next valid transfer that can 1269 // then be restarted, or it will move the head to the tail when 1270 // there are no more transfer descriptors. Setting the head will 1271 // also clear the halt state as it is stored in the first bit of 1272 // the head pointer. 1273 endpoint->head_physical_descriptor 1274 = transfer->last_descriptor->next_physical_descriptor; 1275 return; 1276 } 1277 1278 descriptor = (ohci_general_td *)descriptor->next_logical_descriptor; 1279 } 1280 } 1281 1282 1283 ohci_endpoint_descriptor * 1284 OHCI::_AllocateEndpoint() 1285 { 1286 ohci_endpoint_descriptor *endpoint; 1287 void *physicalAddress; 1288 1289 // Allocate memory chunk 1290 if (fStack->AllocateChunk((void **)&endpoint, &physicalAddress, 1291 sizeof(ohci_endpoint_descriptor)) < B_OK) { 1292 TRACE_ERROR(("usb_ohci: failed to allocate endpoint descriptor\n")); 1293 return NULL; 1294 } 1295 1296 endpoint->flags = OHCI_ENDPOINT_SKIP; 1297 endpoint->physical_address = (addr_t)physicalAddress; 1298 endpoint->head_physical_descriptor = 0; 1299 endpoint->tail_logical_descriptor = NULL; 1300 endpoint->tail_physical_descriptor = 0; 1301 endpoint->next_logical_endpoint = NULL; 1302 endpoint->next_physical_endpoint = 0; 1303 return endpoint; 1304 } 1305 1306 1307 void 1308 OHCI::_FreeEndpoint(ohci_endpoint_descriptor *endpoint) 1309 { 1310 if (!endpoint) 1311 return; 1312 1313 fStack->FreeChunk((void *)endpoint, (void *)endpoint->physical_address, 1314 sizeof(ohci_endpoint_descriptor)); 1315 } 1316 1317 1318 status_t 1319 OHCI::_InsertEndpointForPipe(Pipe *pipe) 1320 { 1321 TRACE(("usb_ohci: inserting endpoint for device %u endpoint %u\n", 1322 pipe->DeviceAddress(), pipe->EndpointAddress())); 1323 1324 ohci_endpoint_descriptor *endpoint = _AllocateEndpoint(); 1325 if (!endpoint) { 1326 TRACE_ERROR(("usb_ohci: cannot allocate memory for endpoint\n")); 1327 return B_NO_MEMORY; 1328 } 1329 1330 uint32 flags = OHCI_ENDPOINT_SKIP; 1331 1332 // Set up device and endpoint address 1333 flags |= OHCI_ENDPOINT_SET_DEVICE_ADDRESS(pipe->DeviceAddress()) 1334 | OHCI_ENDPOINT_SET_ENDPOINT_NUMBER(pipe->EndpointAddress()); 1335 1336 // Set the direction 1337 switch (pipe->Direction()) { 1338 case Pipe::In: 1339 flags |= OHCI_ENDPOINT_DIRECTION_IN; 1340 break; 1341 1342 case Pipe::Out: 1343 flags |= OHCI_ENDPOINT_DIRECTION_OUT; 1344 break; 1345 1346 case Pipe::Default: 1347 flags |= OHCI_ENDPOINT_DIRECTION_DESCRIPTOR; 1348 break; 1349 1350 default: 1351 TRACE_ERROR(("usb_ohci: direction unknown\n")); 1352 _FreeEndpoint(endpoint); 1353 return B_ERROR; 1354 } 1355 1356 // Set up the speed 1357 switch (pipe->Speed()) { 1358 case USB_SPEED_LOWSPEED: 1359 flags |= OHCI_ENDPOINT_LOW_SPEED; 1360 break; 1361 1362 case USB_SPEED_FULLSPEED: 1363 flags |= OHCI_ENDPOINT_FULL_SPEED; 1364 break; 1365 1366 default: 1367 TRACE_ERROR(("usb_ohci: unaccetable speed\n")); 1368 _FreeEndpoint(endpoint); 1369 return B_ERROR; 1370 } 1371 1372 // Set the maximum packet size 1373 flags |= OHCI_ENDPOINT_SET_MAX_PACKET_SIZE(pipe->MaxPacketSize()); 1374 endpoint->flags = flags; 1375 1376 // Add the endpoint to the appropriate list 1377 uint32 type = pipe->Type(); 1378 ohci_endpoint_descriptor *head = NULL; 1379 if (type & USB_OBJECT_CONTROL_PIPE) 1380 head = fDummyControl; 1381 else if (type & USB_OBJECT_BULK_PIPE) 1382 head = fDummyBulk; 1383 else if (type & USB_OBJECT_INTERRUPT_PIPE) 1384 head = _FindInterruptEndpoint(pipe->Interval()); 1385 else if (type & USB_OBJECT_ISO_PIPE) 1386 head = fDummyIsochronous; 1387 else 1388 TRACE_ERROR(("usb_ohci: unknown pipe type\n")); 1389 1390 if (head == NULL) { 1391 TRACE_ERROR(("usb_ohci: no list found for endpoint\n")); 1392 _FreeEndpoint(endpoint); 1393 return B_ERROR; 1394 } 1395 1396 // Create (necessary) tail descriptor 1397 if (pipe->Type() & USB_OBJECT_ISO_PIPE) { 1398 // Set the isochronous bit format 1399 endpoint->flags |= OHCI_ENDPOINT_ISOCHRONOUS_FORMAT; 1400 // TODO 1401 _FreeEndpoint(endpoint); 1402 return B_ERROR; 1403 } else { 1404 ohci_general_td *tail = _CreateGeneralDescriptor(0); 1405 endpoint->tail_logical_descriptor = tail; 1406 endpoint->head_physical_descriptor = tail->physical_address; 1407 endpoint->tail_physical_descriptor = tail->physical_address; 1408 } 1409 1410 if (!_LockEndpoints()) { 1411 if (endpoint->tail_logical_descriptor) { 1412 _FreeGeneralDescriptor( 1413 (ohci_general_td *)endpoint->tail_logical_descriptor); 1414 } 1415 1416 _FreeEndpoint(endpoint); 1417 return B_ERROR; 1418 } 1419 1420 pipe->SetControllerCookie((void *)endpoint); 1421 endpoint->next_logical_endpoint = head->next_logical_endpoint; 1422 endpoint->next_physical_endpoint = head->next_physical_endpoint; 1423 head->next_logical_endpoint = (void *)endpoint; 1424 head->next_physical_endpoint = (uint32)endpoint->physical_address; 1425 1426 _UnlockEndpoints(); 1427 return B_OK; 1428 } 1429 1430 1431 status_t 1432 OHCI::_RemoveEndpointForPipe(Pipe *pipe) 1433 { 1434 TRACE(("usb_ohci: removing endpoint for device %u endpoint %u\n", 1435 pipe->DeviceAddress(), pipe->EndpointAddress())); 1436 1437 ohci_endpoint_descriptor *endpoint 1438 = (ohci_endpoint_descriptor *)pipe->ControllerCookie(); 1439 if (endpoint == NULL) 1440 return B_OK; 1441 1442 // TODO implement properly, but at least disable it for now 1443 endpoint->flags |= OHCI_ENDPOINT_SKIP; 1444 return B_OK; 1445 } 1446 1447 1448 ohci_endpoint_descriptor * 1449 OHCI::_FindInterruptEndpoint(uint8 interval) 1450 { 1451 uint32 index = 0; 1452 uint32 power = 1; 1453 while (power <= OHCI_BIGGEST_INTERVAL / 2) { 1454 if (power * 2 > interval) 1455 break; 1456 1457 power *= 2; 1458 index++; 1459 } 1460 1461 return fInterruptEndpoints[index]; 1462 } 1463 1464 1465 ohci_general_td * 1466 OHCI::_CreateGeneralDescriptor(size_t bufferSize) 1467 { 1468 ohci_general_td *descriptor; 1469 void *physicalAddress; 1470 1471 if (fStack->AllocateChunk((void **)&descriptor, &physicalAddress, 1472 sizeof(ohci_general_td)) != B_OK) { 1473 TRACE_ERROR(("usb_ohci: failed to allocate general descriptor\n")); 1474 return NULL; 1475 } 1476 1477 descriptor->physical_address = (addr_t)physicalAddress; 1478 descriptor->next_physical_descriptor = 0; 1479 descriptor->next_logical_descriptor = NULL; 1480 descriptor->buffer_size = bufferSize; 1481 if (bufferSize == 0) { 1482 descriptor->buffer_physical = 0; 1483 descriptor->buffer_logical = NULL; 1484 descriptor->last_physical_byte_address = 0; 1485 return descriptor; 1486 } 1487 1488 if (fStack->AllocateChunk(&descriptor->buffer_logical, 1489 (void **)&descriptor->buffer_physical, bufferSize) != B_OK) { 1490 TRACE_ERROR(("usb_ohci: failed to allocate space for buffer\n")); 1491 fStack->FreeChunk(descriptor, (void *)descriptor->physical_address, 1492 sizeof(ohci_general_td)); 1493 return NULL; 1494 } 1495 1496 descriptor->last_physical_byte_address 1497 = descriptor->buffer_physical + bufferSize - 1; 1498 return descriptor; 1499 } 1500 1501 1502 void 1503 OHCI::_FreeGeneralDescriptor(ohci_general_td *descriptor) 1504 { 1505 if (!descriptor) 1506 return; 1507 1508 if (descriptor->buffer_logical) { 1509 fStack->FreeChunk(descriptor->buffer_logical, 1510 (void *)descriptor->buffer_physical, descriptor->buffer_size); 1511 } 1512 1513 fStack->FreeChunk((void *)descriptor, (void *)descriptor->physical_address, 1514 sizeof(ohci_general_td)); 1515 } 1516 1517 1518 status_t 1519 OHCI::_CreateDescriptorChain(ohci_general_td **_firstDescriptor, 1520 ohci_general_td **_lastDescriptor, uint32 direction, size_t bufferSize) 1521 { 1522 size_t blockSize = 8192; 1523 int32 descriptorCount = (bufferSize + blockSize - 1) / blockSize; 1524 if (descriptorCount == 0) 1525 descriptorCount = 1; 1526 1527 ohci_general_td *firstDescriptor = NULL; 1528 ohci_general_td *lastDescriptor = *_firstDescriptor; 1529 for (int32 i = 0; i < descriptorCount; i++) { 1530 ohci_general_td *descriptor = _CreateGeneralDescriptor( 1531 min_c(blockSize, bufferSize)); 1532 1533 if (!descriptor) { 1534 _FreeDescriptorChain(firstDescriptor); 1535 return B_NO_MEMORY; 1536 } 1537 1538 descriptor->flags = direction 1539 | OHCI_TD_BUFFER_ROUNDING 1540 | OHCI_TD_SET_CONDITION_CODE(OHCI_TD_CONDITION_NOT_ACCESSED) 1541 | OHCI_TD_TOGGLE_CARRY 1542 | OHCI_TD_SET_DELAY_INTERRUPT(OHCI_TD_INTERRUPT_NONE); 1543 1544 // link to previous 1545 if (lastDescriptor) 1546 _LinkDescriptors(lastDescriptor, descriptor); 1547 1548 bufferSize -= blockSize; 1549 lastDescriptor = descriptor; 1550 if (!firstDescriptor) 1551 firstDescriptor = descriptor; 1552 } 1553 1554 *_firstDescriptor = firstDescriptor; 1555 *_lastDescriptor = lastDescriptor; 1556 return B_OK; 1557 } 1558 1559 1560 void 1561 OHCI::_FreeDescriptorChain(ohci_general_td *topDescriptor) 1562 { 1563 ohci_general_td *current = topDescriptor; 1564 ohci_general_td *next = NULL; 1565 1566 while (current) { 1567 next = (ohci_general_td *)current->next_logical_descriptor; 1568 _FreeGeneralDescriptor(current); 1569 current = next; 1570 } 1571 } 1572 1573 1574 size_t 1575 OHCI::_WriteDescriptorChain(ohci_general_td *topDescriptor, iovec *vector, 1576 size_t vectorCount) 1577 { 1578 ohci_general_td *current = topDescriptor; 1579 size_t actualLength = 0; 1580 size_t vectorIndex = 0; 1581 size_t vectorOffset = 0; 1582 size_t bufferOffset = 0; 1583 1584 while (current) { 1585 if (!current->buffer_logical) 1586 break; 1587 1588 while (true) { 1589 size_t length = min_c(current->buffer_size - bufferOffset, 1590 vector[vectorIndex].iov_len - vectorOffset); 1591 1592 TRACE(("usb_ohci: copying %ld bytes to bufferOffset %ld from" 1593 " vectorOffset %ld at index %ld of %ld\n", length, bufferOffset, 1594 vectorOffset, vectorIndex, vectorCount)); 1595 memcpy((uint8 *)current->buffer_logical + bufferOffset, 1596 (uint8 *)vector[vectorIndex].iov_base + vectorOffset, length); 1597 1598 actualLength += length; 1599 vectorOffset += length; 1600 bufferOffset += length; 1601 1602 if (vectorOffset >= vector[vectorIndex].iov_len) { 1603 if (++vectorIndex >= vectorCount) { 1604 TRACE(("usb_ohci: wrote descriptor chain (%ld bytes, no" 1605 " more vectors)\n", actualLength)); 1606 return actualLength; 1607 } 1608 1609 vectorOffset = 0; 1610 } 1611 1612 if (bufferOffset >= current->buffer_size) { 1613 bufferOffset = 0; 1614 break; 1615 } 1616 } 1617 1618 if (!current->next_logical_descriptor) 1619 break; 1620 1621 current = (ohci_general_td *)current->next_logical_descriptor; 1622 } 1623 1624 TRACE(("usb_ohci: wrote descriptor chain (%ld bytes)\n", actualLength)); 1625 return actualLength; 1626 } 1627 1628 1629 size_t 1630 OHCI::_ReadDescriptorChain(ohci_general_td *topDescriptor, iovec *vector, 1631 size_t vectorCount) 1632 { 1633 ohci_general_td *current = topDescriptor; 1634 size_t actualLength = 0; 1635 size_t vectorIndex = 0; 1636 size_t vectorOffset = 0; 1637 size_t bufferOffset = 0; 1638 1639 while (current && OHCI_TD_GET_CONDITION_CODE(current->flags) 1640 != OHCI_TD_CONDITION_NOT_ACCESSED) { 1641 if (!current->buffer_logical) 1642 break; 1643 1644 size_t bufferSize = current->buffer_size; 1645 if (current->buffer_physical != 0) { 1646 bufferSize = current->last_physical_byte_address 1647 - current->buffer_physical + 1; 1648 } 1649 1650 while (true) { 1651 size_t length = min_c(bufferSize - bufferOffset, 1652 vector[vectorIndex].iov_len - vectorOffset); 1653 1654 TRACE(("usb_ohci: copying %ld bytes to vectorOffset %ld from" 1655 " bufferOffset %ld at index %ld of %ld\n", length, vectorOffset, 1656 bufferOffset, vectorIndex, vectorCount)); 1657 memcpy((uint8 *)vector[vectorIndex].iov_base + vectorOffset, 1658 (uint8 *)current->buffer_logical + bufferOffset, length); 1659 1660 actualLength += length; 1661 vectorOffset += length; 1662 bufferOffset += length; 1663 1664 if (vectorOffset >= vector[vectorIndex].iov_len) { 1665 if (++vectorIndex >= vectorCount) { 1666 TRACE(("usb_ohci: read descriptor chain (%ld bytes, no more vectors)\n", actualLength)); 1667 return actualLength; 1668 } 1669 1670 vectorOffset = 0; 1671 } 1672 1673 if (bufferOffset >= bufferSize) { 1674 bufferOffset = 0; 1675 break; 1676 } 1677 } 1678 1679 current = (ohci_general_td *)current->next_logical_descriptor; 1680 } 1681 1682 TRACE(("usb_ohci: read descriptor chain (%ld bytes)\n", actualLength)); 1683 return actualLength; 1684 } 1685 1686 1687 size_t 1688 OHCI::_ReadActualLength(ohci_general_td *topDescriptor) 1689 { 1690 ohci_general_td *current = topDescriptor; 1691 size_t actualLength = 0; 1692 1693 while (current && OHCI_TD_GET_CONDITION_CODE(current->flags) 1694 != OHCI_TD_CONDITION_NOT_ACCESSED) { 1695 size_t length = current->buffer_size; 1696 if (current->buffer_physical != 0) { 1697 length = current->last_physical_byte_address 1698 - current->buffer_physical + 1; 1699 } 1700 1701 actualLength += length; 1702 current = (ohci_general_td *)current->next_logical_descriptor; 1703 } 1704 1705 TRACE(("usb_ohci: read actual length (%ld bytes)\n", actualLength)); 1706 return actualLength; 1707 } 1708 1709 1710 void 1711 OHCI::_LinkDescriptors(ohci_general_td *first, ohci_general_td *second) 1712 { 1713 first->next_physical_descriptor = second->physical_address; 1714 first->next_logical_descriptor = second; 1715 } 1716 1717 1718 ohci_isochronous_td * 1719 OHCI::_CreateIsochronousDescriptor() 1720 { 1721 // TODO 1722 return NULL; 1723 } 1724 1725 1726 void 1727 OHCI::_FreeIsochronousDescriptor(ohci_isochronous_td *descriptor) 1728 { 1729 // TODO 1730 } 1731 1732 1733 bool 1734 OHCI::_LockEndpoints() 1735 { 1736 return (mutex_lock(&fEndpointLock) == B_OK); 1737 } 1738 1739 1740 void 1741 OHCI::_UnlockEndpoints() 1742 { 1743 mutex_unlock(&fEndpointLock); 1744 } 1745 1746 1747 inline void 1748 OHCI::_WriteReg(uint32 reg, uint32 value) 1749 { 1750 *(volatile uint32 *)(fOperationalRegisters + reg) = value; 1751 } 1752 1753 1754 inline uint32 1755 OHCI::_ReadReg(uint32 reg) 1756 { 1757 return *(volatile uint32 *)(fOperationalRegisters + reg); 1758 } 1759 1760 1761 void 1762 OHCI::_PrintEndpoint(ohci_endpoint_descriptor *endpoint) 1763 { 1764 dprintf("usb_ohci: endpoint %p\n", endpoint); 1765 dprintf("\tflags........... 0x%08lx\n", endpoint->flags); 1766 dprintf("\ttail_physical... 0x%08lx\n", endpoint->tail_physical_descriptor); 1767 dprintf("\thead_physical... 0x%08lx\n", endpoint->head_physical_descriptor); 1768 dprintf("\tnext_physical... 0x%08lx\n", endpoint->next_physical_endpoint); 1769 dprintf("\tphysical........ 0x%08lx\n", endpoint->physical_address); 1770 dprintf("\ttail_logical.... %p\n", endpoint->tail_logical_descriptor); 1771 dprintf("\tnext_logical.... %p\n", endpoint->next_logical_endpoint); 1772 } 1773 1774 1775 void 1776 OHCI::_PrintDescriptorChain(ohci_general_td *topDescriptor) 1777 { 1778 while (topDescriptor) { 1779 dprintf("usb_ohci: descriptor %p\n", topDescriptor); 1780 dprintf("\tflags........... 0x%08lx\n", topDescriptor->flags); 1781 dprintf("\tbuffer_physical. 0x%08lx\n", topDescriptor->buffer_physical); 1782 dprintf("\tnext_physical... 0x%08lx\n", topDescriptor->next_physical_descriptor); 1783 dprintf("\tlast_byte....... 0x%08lx\n", topDescriptor->last_physical_byte_address); 1784 dprintf("\tphysical........ 0x%08lx\n", topDescriptor->physical_address); 1785 dprintf("\tbuffer_size..... %lu\n", topDescriptor->buffer_size); 1786 dprintf("\tbuffer_logical.. %p\n", topDescriptor->buffer_logical); 1787 dprintf("\tnext_logical.... %p\n", topDescriptor->next_logical_descriptor); 1788 1789 topDescriptor = (ohci_general_td *)topDescriptor->next_logical_descriptor; 1790 } 1791 } 1792