From fd1e6f2b375d31347be55e2b1924618f9055711f Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sat, 17 May 2008 12:39:46 +0000 Subject: [PATCH] * Getting familiar with the existing code * Cleanup (whitespace, nameing, code style) * Move around methods so they match the header order * Fix some obvious stuff * Initialize all members * Sync roothub code (this will be reworked to a common roothub) * Only minor functional changes (to the worse for now) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25527 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/busses/usb/ohci.cpp | 1517 +++++++++-------- src/add-ons/kernel/busses/usb/ohci.h | 22 +- src/add-ons/kernel/busses/usb/ohci_hardware.h | 54 +- src/add-ons/kernel/busses/usb/ohci_rh.cpp | 109 +- 4 files changed, 857 insertions(+), 845 deletions(-) diff --git a/src/add-ons/kernel/busses/usb/ohci.cpp b/src/add-ons/kernel/busses/usb/ohci.cpp index 7a235cc34e..2b2bc778ce 100644 --- a/src/add-ons/kernel/busses/usb/ohci.cpp +++ b/src/add-ons/kernel/busses/usb/ohci.cpp @@ -3,10 +3,11 @@ * Distributed under the terms of the MIT License. * * Authors: - * Jan-Rixt Van Hoye - * Salvatore Benedetto + * Jan-Rixt Van Hoye + * Salvatore Benedetto + * Michael Lotz */ - +#define TRACE_USB #include #include #include @@ -50,30 +51,34 @@ module_info *modules[] = { }; -//------------------------------------------------------ -// OHCI:: Reverse the bits in a value between 0 and 31 -// (Section 3.3.2) -//------------------------------------------------------ -static uint8 revbits[OHCI_NUMBER_OF_INTERRUPTS] = - { 0x00, 0x10, 0x08, 0x18, 0x04, 0x14, 0x0c, 0x1c, - 0x02, 0x12, 0x0a, 0x1a, 0x06, 0x16, 0x0e, 0x1e, - 0x01, 0x11, 0x09, 0x19, 0x05, 0x15, 0x0d, 0x1d, - 0x03, 0x13, 0x0b, 0x1b, 0x07, 0x17, 0x0f, 0x1f }; - +// Reverse the bits in a value between 0 and 31 (Section 3.3.2) +static uint8 revbits[OHCI_NUMBER_OF_INTERRUPTS] = { + 0x00, 0x10, 0x08, 0x18, 0x04, 0x14, 0x0c, 0x1c, + 0x02, 0x12, 0x0a, 0x1a, 0x06, 0x16, 0x0e, 0x1e, + 0x01, 0x11, 0x09, 0x19, 0x05, 0x15, 0x0d, 0x1d, + 0x03, 0x13, 0x0b, 0x1b, 0x07, 0x17, 0x0f, 0x1f +}; + OHCI::OHCI(pci_info *info, Stack *stack) : BusManager(stack), fPCIInfo(info), fStack(stack), + fOperationalRegisters(NULL), fRegisterArea(-1), fHccaArea(-1), + fHcca(NULL), + fInterruptEndpoints(NULL), fDummyControl(NULL), fDummyBulk(NULL), fDummyIsochronous(NULL), fFirstTransfer(NULL), fLastTransfer(NULL), + fFinishTransfersSem(-1), fFinishThread(-1), fStopFinishThread(false), + fHashGenericTable(NULL), + fHashIsochronousTable(NULL), fRootHub(NULL), fRootHubAddress(0), fPortCount(0) @@ -99,7 +104,7 @@ OHCI::OHCI(pci_info *info, Stack *stack) uint32 offset = sPCIModule->read_pci_config(fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function, PCI_base_registers, 4); offset &= PCI_address_memory_32_mask; - TRACE(("usb_ohci: iospace offset: %lx\n", offset)); + TRACE(("usb_ohci: iospace offset: 0x%lx\n", offset)); fRegisterArea = map_physical_memory("OHCI memory mapped registers", (void *)offset, B_PAGE_SIZE, B_ANY_KERNEL_BLOCK_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_READ_AREA | B_WRITE_AREA, @@ -109,31 +114,29 @@ OHCI::OHCI(pci_info *info, Stack *stack) return; } - TRACE(("usb_ohci: mapped operational registers: 0x%08lx\n", - *fOperationalRegisters)); + TRACE(("usb_ohci: mapped operational registers: %p\n", + fOperationalRegisters)); // Check the revision of the controller, which should be 10h uint32 revision = _ReadReg(OHCI_REVISION) & 0xff; TRACE(("usb_ohci: version %ld.%ld%s\n", OHCI_REVISION_HIGH(revision), - OHCI_REVISION_LOW(revision), OHCI_REVISION_LEGACY(revision) + OHCI_REVISION_LOW(revision), OHCI_REVISION_LEGACY(revision) ? ", legacy support" : "")); if (OHCI_REVISION_HIGH(revision) != 1 || OHCI_REVISION_LOW(revision) != 0) { TRACE_ERROR(("usb_ohci: unsupported OHCI revision\n")); return; } - // Set up the Host Controller Communications Area - // which is 256 bytes (2048 bits) and must be aligned void *hccaPhysicalAddress; fHccaArea = fStack->AllocateArea((void **)&fHcca, &hccaPhysicalAddress, - 2048, "USB OHCI Host Controller Communication Area"); + sizeof(ohci_hcca), "USB OHCI Host Controller Communication Area"); if (fHccaArea < B_OK) { TRACE_ERROR(("usb_ohci: unable to create the HCCA block area\n")); return; } - memset((void *)fHcca, 0, sizeof(ohci_hcca)); + memset(fHcca, 0, sizeof(ohci_hcca)); // Allocate hash tables fHashGenericTable = (ohci_general_td **) @@ -142,6 +145,7 @@ OHCI::OHCI(pci_info *info, Stack *stack) TRACE_ERROR(("usb_ohci: unable to allocate hash generic table\n")); return; } + fHashIsochronousTable = (ohci_isochronous_td **) malloc(sizeof(ohci_isochronous_td *) * OHCI_HASH_SIZE); if (fHashIsochronousTable == NULL) { @@ -183,7 +187,8 @@ OHCI::OHCI(pci_info *info, Stack *stack) _FreeEndpoint(fDummyIsochronous); return; } - for (uint32 i = 0; i < OHCI_NUMBER_OF_INTERRUPTS; i++) { + + for (int32 i = 0; i < OHCI_NUMBER_OF_INTERRUPTS; i++) { fInterruptEndpoints[i] = _AllocateEndpoint(); if (!fInterruptEndpoints[i]) { TRACE_ERROR(("ohci_usb: cannot allocate memory for" @@ -195,6 +200,7 @@ OHCI::OHCI(pci_info *info, Stack *stack) _FreeEndpoint(fDummyIsochronous); return; } + // Make them point all to the dummy isochronous endpoint fInterruptEndpoints[i]->flags |= OHCI_ENDPOINT_SKIP; fInterruptEndpoints[i]->next_physical_endpoint @@ -211,10 +217,11 @@ OHCI::OHCI(pci_info *info, Stack *stack) TRACE(("usb_ohci: SMM is in control of the host controller\n")); uint32 status = _ReadReg(OHCI_COMMAND_STATUS); _WriteReg(OHCI_COMMAND_STATUS, status | OHCI_OWNERSHIP_CHANGE_REQUEST); - for (uint32 i = 0; i < 100 && (control & OHCI_INTERRUPT_ROUTING); i++) { + for (uint32 i = 0; i < 100 && (control & OHCI_INTERRUPT_ROUTING); i++) { snooze(1000); control = _ReadReg(OHCI_CONTROL); } + if (!(control & OHCI_INTERRUPT_ROUTING)) { TRACE(("usb_ohci: SMM does not respond. Resetting...\n")); _WriteReg(OHCI_CONTROL, OHCI_HC_FUNCTIONAL_STATE_RESET); @@ -242,12 +249,13 @@ OHCI::OHCI(pci_info *info, Stack *stack) for (uint32 i = 0; i < 10; i++) { spin(10); reset = _ReadReg(OHCI_COMMAND_STATUS) & OHCI_HOST_CONTROLLER_RESET; - if (!reset) + if (reset == 0) break; } + if (reset) { - TRACE_ERROR(("usb_ohci: Error resetting the host controller (timeout)\n")); restore_interrupts(former); + TRACE_ERROR(("usb_ohci: Error resetting the host controller (timeout)\n")); return; } @@ -281,7 +289,7 @@ OHCI::OHCI(pci_info *info, Stack *stack) // 90% periodic uint32 periodic = OHCI_PERIODIC(intervalValue); _WriteReg(OHCI_PERIODIC_START, periodic); - + // Fiddle the No Over Current Protection bit to avoid chip bug uint32 desca = _ReadReg(OHCI_RH_DESCRIPTOR_A); _WriteReg(OHCI_RH_DESCRIPTOR_A, desca | OHCI_RH_NO_OVER_CURRENT_PROTECTION); @@ -316,7 +324,7 @@ OHCI::OHCI(pci_info *info, Stack *stack) install_io_interrupt_handler(fPCIInfo->u.h0.interrupt_line, _InterruptHandler, (void *)this, 0); - TRACE(("usb_ohci: OHCI Host Controller Driver constructed\n")); + TRACE(("usb_ohci: OHCI Host Controller Driver constructed\n")); fInitOK = true; } @@ -328,30 +336,329 @@ OHCI::~OHCI() delete_sem(fFinishTransfersSem); wait_for_thread(fFinishThread, &result); - if (fHccaArea > 0) + if (fHccaArea >= B_OK) delete_area(fHccaArea); - if (fRegisterArea > 0) + if (fRegisterArea >= B_OK) delete_area(fRegisterArea); - if (fHashGenericTable) - free(fHashGenericTable); - if (fHashIsochronousTable) - free(fHashIsochronousTable); - if (fDummyControl) - _FreeEndpoint(fDummyControl); - if (fDummyBulk) - _FreeEndpoint(fDummyBulk); - if (fDummyIsochronous) - _FreeEndpoint(fDummyIsochronous); - if (fRootHub) - delete fRootHub; - for (int i = 0; i < OHCI_NUMBER_OF_INTERRUPTS; i++) - if (fInterruptEndpoints[i]) + + free(fHashGenericTable); + free(fHashIsochronousTable); + + _FreeEndpoint(fDummyControl); + _FreeEndpoint(fDummyBulk); + _FreeEndpoint(fDummyIsochronous); + + if (fInterruptEndpoints != NULL) { + for (int i = 0; i < OHCI_NUMBER_OF_INTERRUPTS; i++) _FreeEndpoint(fInterruptEndpoints[i]); + } + delete [] fInterruptEndpoints; + delete fRootHub; + put_module(B_PCI_MODULE_NAME); } +status_t +OHCI::Start() +{ + TRACE(("usb_ohci: starting OHCI Host Controller\n")); + + if ((_ReadReg(OHCI_CONTROL) & OHCI_HC_FUNCTIONAL_STATE_MASK) + != OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL) { + TRACE_ERROR(("usb_ohci: Controller not started!\n")); + return B_ERROR; + } else + TRACE(("usb_ohci: Controller is operational!\n")); + + fRootHubAddress = AllocateAddress(); + fRootHub = new(std::nothrow) OHCIRootHub(RootObject(), fRootHubAddress); + if (!fRootHub) { + TRACE_ERROR(("usb_ohci: no memory to allocate root hub\n")); + return B_NO_MEMORY; + } + + if (fRootHub->InitCheck() < B_OK) { + TRACE_ERROR(("usb_ohci: root hub failed init check\n")); + return B_ERROR; + } + + SetRootHub(fRootHub); + TRACE(("usb_ohci: Host Controller started\n")); + return BusManager::Start(); +} + + +status_t +OHCI::SubmitTransfer(Transfer *transfer) +{ + // short circuit the root hub + if (transfer->TransferPipe()->DeviceAddress() == fRootHubAddress) + return fRootHub->ProcessTransfer(this, transfer); + + uint32 type = transfer->TransferPipe()->Type(); + if ((type & USB_OBJECT_CONTROL_PIPE)) { + TRACE(("usb_ohci: submitting control request\n")); + return _SubmitControlTransfer(transfer); + } + + if ((type & USB_OBJECT_BULK_PIPE)) { + TRACE(("usb_ohci: submitting bulk transfer\n")); + return _SubmitBulkTransfer(transfer); + } + + if (((type & USB_OBJECT_ISO_PIPE) || (type & USB_OBJECT_INTERRUPT_PIPE))) { + TRACE(("usb_ohci: submitting periodic transfer\n")); + return _SubmitPeriodicTransfer(transfer); + } + + TRACE_ERROR(("usb_ohci: tried to submit transfer for unknown pipe" + " type %lu\n", type)); + return B_ERROR; +} + + +status_t +OHCI::CancelQueuedTransfers(Pipe *pipe, bool force) +{ + if (pipe->Type() & USB_OBJECT_ISO_PIPE) + return _CancelQueuedIsochronousTransfers(pipe, force); + + if (!Lock()) + return B_ERROR; + + transfer_data *current = fFirstTransfer; + while (current) { + if (current->transfer->TransferPipe() == pipe) { + // Check if the skip bit is already set + if (!(current->endpoint->flags & OHCI_ENDPOINT_SKIP)) { + current->endpoint->flags |= OHCI_ENDPOINT_SKIP; + // In case the controller is processing + // this endpoint, wait for it to finish + snooze(1000); + } + + // Clear the endpoint + current->endpoint->head_logical_descriptor = NULL; + current->endpoint->head_physical_descriptor = 0; + current->endpoint->tail_logical_descriptor = NULL; + current->endpoint->tail_physical_descriptor = 0; + + if (!force) { + // If the transfer is canceled by force, the one causing the + // cancel is probably not the one who initiated the transfer + // and the callback is likely not safe anymore + current->transfer->Finished(B_CANCELED, 0); + } + current->canceled = true; + } + current = current->link; + } + + Unlock(); + + // notify the finisher so it can clean up the canceled transfers + release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE); + return B_OK; +} + + +status_t +OHCI::NotifyPipeChange(Pipe *pipe, usb_change change) +{ + TRACE(("usb_ohci: pipe change %d for pipe 0x%08lx\n", change, (uint32)pipe)); + if (pipe->DeviceAddress() == fRootHubAddress) { + // no need to insert/remove endpoint descriptors for the root hub + return B_OK; + } + + switch (change) { + case USB_CHANGE_CREATED: { + TRACE(("usb_ohci: inserting endpoint\n")); + return _InsertEndpointForPipe(pipe); + } + + case USB_CHANGE_DESTROYED: { + TRACE(("usb_ohci: removing endpoint\n")); + return _RemoveEndpointForPipe(pipe); + } + + case USB_CHANGE_PIPE_POLICY_CHANGED: { + TRACE(("usb_ohci: pipe policy changing unhandled!\n")); + break; + } + + default: { + TRACE_ERROR(("usb_ohci: unknown pipe change!\n")); + return B_ERROR; + } + } + + return B_OK; +} + + +status_t +OHCI::AddTo(Stack *stack) +{ +#ifdef TRACE_USB + set_dprintf_enabled(true); +#ifndef __HAIKU__ + load_driver_symbols("ohci"); +#endif +#endif + + if (!sPCIModule) { + status_t status = get_module(B_PCI_MODULE_NAME, (module_info **)&sPCIModule); + if (status < B_OK) { + TRACE_ERROR(("usb_ohci: getting pci module failed! 0x%08lx\n", + status)); + return status; + } + } + + TRACE(("usb_ohci: searching devices\n")); + bool found = false; + pci_info *item = new(std::nothrow) pci_info; + if (!item) { + sPCIModule = NULL; + put_module(B_PCI_MODULE_NAME); + return B_NO_MEMORY; + } + + for (uint32 i = 0 ; sPCIModule->get_nth_pci_info(i, item) >= B_OK; i++) { + if (item->class_base == PCI_serial_bus && item->class_sub == PCI_usb + && item->class_api == PCI_usb_ohci) { + if (item->u.h0.interrupt_line == 0 + || item->u.h0.interrupt_line == 0xFF) { + TRACE_ERROR(("usb_ohci: found device with invalid IRQ -" + " check IRQ assignement\n")); + continue; + } + + TRACE(("usb_ohci: found device at IRQ %u\n", + item->u.h0.interrupt_line)); + OHCI *bus = new(std::nothrow) OHCI(item, stack); + if (!bus) { + delete item; + sPCIModule = NULL; + put_module(B_PCI_MODULE_NAME); + return B_NO_MEMORY; + } + + if (bus->InitCheck() < B_OK) { + TRACE_ERROR(("usb_ohci: bus failed init check\n")); + delete bus; + continue; + } + + // the bus took it away + item = new(std::nothrow) pci_info; + + bus->Start(); + stack->AddBusManager(bus); + found = true; + } + } + + if (!found) { + TRACE_ERROR(("usb_ohci: no devices found\n")); + delete item; + sPCIModule = NULL; + put_module(B_PCI_MODULE_NAME); + return ENODEV; + } + + delete item; + return B_OK; +} + + +status_t +OHCI::GetPortStatus(uint8 index, usb_port_status *status) +{ + TRACE(("usb_ohci::%s(%ud, )\n", __FUNCTION__, index)); + if (index >= fPortCount) + return B_BAD_INDEX; + + status->status = status->change = 0; + uint32 portStatus = _ReadReg(OHCI_RH_PORT_STATUS(index)); + + // status + if (portStatus & OHCI_RH_PORTSTATUS_CCS) + status->status |= PORT_STATUS_CONNECTION; + if (portStatus & OHCI_RH_PORTSTATUS_PES) + status->status |= PORT_STATUS_ENABLE; + if (portStatus & OHCI_RH_PORTSTATUS_PRS) + status->status |= PORT_STATUS_RESET; + if (portStatus & OHCI_RH_PORTSTATUS_LSDA) + status->status |= PORT_STATUS_LOW_SPEED; + if (portStatus & OHCI_RH_PORTSTATUS_PSS) + status->status |= PORT_STATUS_SUSPEND; + if (portStatus & OHCI_RH_PORTSTATUS_POCI) + status->status |= PORT_STATUS_OVER_CURRENT; + if (portStatus & OHCI_RH_PORTSTATUS_PPS) + status->status |= PORT_STATUS_POWER; + + // change + if (portStatus & OHCI_RH_PORTSTATUS_CSC) + status->change |= PORT_STATUS_CONNECTION; + if (portStatus & OHCI_RH_PORTSTATUS_PESC) + status->change |= PORT_STATUS_ENABLE; + if (portStatus & OHCI_RH_PORTSTATUS_PSSC) + status->change |= PORT_STATUS_SUSPEND; + if (portStatus & OHCI_RH_PORTSTATUS_OCIC) + status->change |= PORT_STATUS_OVER_CURRENT; + if (portStatus & OHCI_RH_PORTSTATUS_PRSC) + status->change |= PORT_STATUS_RESET; + + return B_OK; +} + + +status_t +OHCI::SetPortFeature(uint8 index, uint16 feature) +{ + TRACE(("usb_ohci: set port feature index %ud feature %ud)\n", index, feature)); + if (index > fPortCount) + return B_BAD_INDEX; + + switch (feature) { + case PORT_RESET: + _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PRS); + return B_OK; + + case PORT_POWER: + _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PPS); + return B_OK; + } + + return B_BAD_VALUE; +} + + +status_t +OHCI::ClearPortFeature(uint8 index, uint16 feature) +{ + TRACE(("usb_ohci: clear port feature index %ud feature %ud\n", index, feature)); + if (index > fPortCount) + return B_BAD_INDEX; + + switch (feature) { + case C_PORT_RESET: + _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CSC); + return B_OK; + + case C_PORT_CONNECTION: + _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CSC); + return B_OK; + } + + return B_BAD_VALUE; +} + + int32 OHCI::_InterruptHandler(void *data) { @@ -366,7 +673,6 @@ OHCI::_Interrupt() acquire_spinlock(&lock); uint32 status = 0; - uint32 acknowledge = 0; bool finishTransfers = false; int32 result = B_HANDLED_INTERRUPT; @@ -377,7 +683,7 @@ OHCI::_Interrupt() // HcInterruptStatus register needs to be accessed to determine that exact // interrupt cause. If HccDoneHead is nonzero, then a done list update // interrupt is indicated and if the LSb of the Dword is nonzero, then an - // additional interrupt event is indicated and HcInterruptStatus shuold be + // additional interrupt event is indicated and HcInterruptStatus should be // checked to determine its cause. uint32 doneHead = fHcca->done_head; if (doneHead != 0) { @@ -433,16 +739,100 @@ OHCI::_Interrupt() } +status_t +OHCI::_AddPendingTransfer(Transfer *transfer, ohci_endpoint_descriptor *endpoint, + ohci_general_td *firstDescriptor, ohci_general_td *dataDescriptor, bool directionIn) +{ + if (!transfer || !endpoint || !firstDescriptor) + return B_BAD_VALUE; + + transfer_data *data = new(std::nothrow) transfer_data; + if (!data) + return B_NO_MEMORY; + + status_t result = transfer->InitKernelAccess(); + if (result < B_OK) { + delete data; + return result; + } + + data->transfer = transfer; + data->endpoint = endpoint; + data->first_descriptor = firstDescriptor; + data->data_descriptor = dataDescriptor; + data->incoming = directionIn; + data->canceled = false; + data->link = NULL; + + if (!Lock()) { + delete data; + return B_ERROR; + } + + if (fLastTransfer) + fLastTransfer->link = data; + else + fFirstTransfer = data; + + fLastTransfer = data; + Unlock(); + + return B_OK; +} + + +status_t +OHCI::_CancelQueuedIsochronousTransfers(Pipe *pipe, bool force) +{ + // TODO + return B_ERROR; +} + + +status_t +OHCI::_UnlinkTransfer(transfer_data *transfer) +{ + if (!Lock()) + return B_ERROR; + + if (transfer == fFirstTransfer) { + // It was the first element + fFirstTransfer = fFirstTransfer->link; + if (transfer == fLastTransfer) { + // Also the only one + fLastTransfer = NULL; + } + } else { + transfer_data *current = fFirstTransfer->link; + transfer_data *previous = fFirstTransfer; + while (current != NULL) { + if (current == transfer) { + previous->link = current->link; + if (current == fLastTransfer) + fLastTransfer = previous; + break; + } + + previous = current; + current = current->link; + } + } + + Unlock(); + return B_OK; +} + + int32 OHCI::_FinishThread(void *data) { - ((OHCI *)data)->_FinishTransfer(); + ((OHCI *)data)->_FinishTransfers(); return B_OK; } void -OHCI::_FinishTransfer() +OHCI::_FinishTransfers() { while (!fStopFinishThread) { if (acquire_sem(fFinishTransfersSem) < B_OK) @@ -454,37 +844,41 @@ OHCI::_FinishTransfer() if (semCount > 0) acquire_sem_etc(fFinishTransfersSem, semCount, B_RELATIVE_TIMEOUT, 0); - uint32 done_list = fHcca->done_head & ~OHCI_DONE_INTERRUPTS; + uint32 doneList = fHcca->done_head & ~OHCI_DONE_INTERRUPTS; // If done_head is zero, there are not processed descriptors // in the done list and we have been woken up by CancelQueuedTransfers // or CancelQueuedIsochronousTransfers in order to do some clean up // and back to sleep. - if (done_list) { + if (doneList) { // Pull out the done list and reverse its order // for both general and isochronous descriptors - ohci_general_td *current, *top; - ohci_isochronous_td *isoCurrent, *isoTop; - for ( top = NULL, isoTop = NULL ; done_list != 0; ) { - if ((current = _FindDescriptorInHash(done_list))) { - done_list = current->next_physical_descriptor; + ohci_general_td *current = NULL; + ohci_general_td *top = NULL; + ohci_isochronous_td *isoCurrent = NULL; + ohci_isochronous_td *isoTop = NULL; + while (doneList != 0) { + current = _FindDescriptorInHash(doneList); + if (current != NULL) { + doneList = current->next_physical_descriptor; current->next_done_descriptor = (void *)top; top = current; continue; } - if ((isoCurrent = _FindIsoDescriptorInHash(done_list))) { - done_list = isoCurrent->next_physical_descriptor; + + isoCurrent = _FindIsoDescriptorInHash(doneList); + if (isoCurrent != NULL) { + doneList = isoCurrent->next_physical_descriptor; isoCurrent->next_done_descriptor = (void *)isoTop; isoTop = isoCurrent; continue; } - // TODO: Should I panic here? :) - TRACE_ERROR(("usb_ohci: address 0x%08lx not found!\n", - done_list)); + + TRACE_ERROR(("usb_ohci: address 0x%08lx not found!\n", doneList)); break; } // Acknowledge the interrupt - // TODO: Move the acknowledgement in the interrupt handler. + // TODO: Move the acknowledgement in the interrupt handler. // The done_head value can be passed through a shared variable. fHcca->done_head = 0; _WriteReg(OHCI_INTERRUPT_ENABLE, OHCI_WRITEBACK_DONE_HEAD); @@ -496,7 +890,7 @@ OHCI::_FinishTransfer() } // Now process the general list - for (current = top; current != NULL; ) { + for (current = top; current != NULL;) { ohci_general_td *next = (ohci_general_td *)current->next_done_descriptor; @@ -516,12 +910,12 @@ OHCI::_FinishTransfer() // endpoint. // NOTE: There can(should) not be more than one // invalid descriptor from the same transfer in the - // done list, as the controller halt the endpoint right + // done list, as the controller halts the endpoint right // away if a descriptor fails. This means that, if we reversed // the order of the done list (which we did), there is - // not reason to look for more failed descriptors in the + // no reason to look for more failed descriptors in the // done list from the same transfer, as *BSD code does. - TRACE(("usb_ohci: transfer failed! ohci error code: %d\n", + TRACE_ERROR(("usb_ohci: transfer failed! ohci error code: %lu\n", conditionCode)); // Remove remaining descriptors from the same transfer @@ -531,7 +925,6 @@ OHCI::_FinishTransfer() // TODO: Fix the following with the appropriate error callbackStatus = B_DEV_MULTIPLE_ERRORS; transferDone = true; - continue; } else if (current->is_last) transferDone = true; @@ -541,29 +934,28 @@ OHCI::_FinishTransfer() if (transfer->data_descriptor && transfer->incoming) { // Read data out } else { - // How much was transfer? + // How much was transfered? } + if (transfer->transfer->IsFragmented()) { // TODO } } + _UnlinkTransfer(transfer); transfer->transfer->Finished(callbackStatus, actualLength); - // Update next before current gets deleted next = (ohci_general_td *)current->next_done_descriptor; _FreeDescriptorChain(transfer->first_descriptor); delete transfer->transfer; delete transfer; - } + current = next; } - } - // Quick look for canceled transfer before - // we go back to sleep + // Quickly look for canceled transfer before we go back to sleep transfer_data *current = fFirstTransfer; while (current) { transfer_data *next = current->link; @@ -580,7 +972,108 @@ OHCI::_FinishTransfer() status_t -OHCI::_AppendChainDescriptorsToEndpoint(ohci_endpoint_descriptor *endpoint, +OHCI::_SubmitControlTransfer(Transfer *transfer) +{ + usb_request_data *requestData = transfer->RequestData(); + bool directionIn = (requestData->RequestType & USB_REQTYPE_DEVICE_IN) > 0; + + ohci_general_td *setupDescriptor + = _CreateGeneralDescriptor(sizeof(usb_request_data)); + if (!setupDescriptor) { + TRACE_ERROR(("usb_ohci: failed to allocate setup descriptor\n")); + return B_NO_MEMORY; + } + + setupDescriptor->flags |= OHCI_TD_DIRECTION_PID_SETUP + | OHCI_TD_NO_CONDITION_CODE + | OHCI_TD_TOGGLE_0 + | OHCI_TD_SET_DELAY_INTERRUPT(7); + + ohci_general_td *statusDescriptor = _CreateGeneralDescriptor(0); + if (!statusDescriptor) { + TRACE_ERROR(("usb_ohci: failed to allocate status descriptor\n")); + _FreeGeneralDescriptor(setupDescriptor); + return B_NO_MEMORY; + } + + statusDescriptor->flags + |= (directionIn ? OHCI_TD_DIRECTION_PID_OUT : OHCI_TD_DIRECTION_PID_IN) + | OHCI_TD_NO_CONDITION_CODE + | OHCI_TD_TOGGLE_1 + | OHCI_TD_SET_DELAY_INTERRUPT(0); + + iovec vector; + vector.iov_base = requestData; + vector.iov_len = sizeof(usb_request_data); + _WriteDescriptorChain(setupDescriptor, &vector, 1); + + status_t result; + ohci_general_td *dataDescriptor = NULL; + if (transfer->VectorCount() > 0) { + ohci_general_td *lastDescriptor = NULL; + result = _CreateDescriptorChain(&dataDescriptor, &lastDescriptor, + directionIn ? OHCI_TD_DIRECTION_PID_OUT : OHCI_TD_DIRECTION_PID_IN, + transfer->VectorLength()); + if (result < B_OK) { + _FreeGeneralDescriptor(setupDescriptor); + _FreeGeneralDescriptor(statusDescriptor); + return result; + } + + if (!directionIn) { + _WriteDescriptorChain(dataDescriptor, transfer->Vector(), + transfer->VectorCount()); + } + + _LinkDescriptors(setupDescriptor, dataDescriptor); + _LinkDescriptors(lastDescriptor, statusDescriptor); + } else { + _LinkDescriptors(setupDescriptor, statusDescriptor); + } + + // Append Transfer + ohci_endpoint_descriptor *endpoint + = (ohci_endpoint_descriptor *)transfer->TransferPipe()->ControllerCookie(); + result = _AddPendingTransfer(transfer, endpoint, setupDescriptor, + dataDescriptor, directionIn); + if (result < B_OK) { + TRACE_ERROR(("usb_ohci: failed to add pending transfer\n")); + _FreeDescriptorChain(setupDescriptor); + return result; + } + + // Append descriptor chain to the endpoint + result = _AppendDescriptorChainToEndpoint(endpoint, setupDescriptor, + statusDescriptor); + if (result < B_OK) { + TRACE_ERROR(("usb_ohci: failed to append descriptor chain to endpoint\n")); + // TODO: Remove transfer_data from list + _FreeDescriptorChain(setupDescriptor); + } + + // Tell the controller to process the control list + _WriteReg(OHCI_COMMAND_STATUS, OHCI_CONTROL_LIST_FILLED); + return B_OK; +} + + +status_t +OHCI::_SubmitBulkTransfer(Transfer *transfer) +{ + // TODO + return B_ERROR; +} + + +status_t +OHCI::_SubmitPeriodicTransfer(Transfer *transfer) +{ + return B_ERROR; +} + + +status_t +OHCI::_AppendDescriptorChainToEndpoint(ohci_endpoint_descriptor *endpoint, ohci_general_td *first, ohci_general_td *last) { endpoint->flags |= OHCI_ENDPOINT_SKIP; @@ -629,272 +1122,136 @@ OHCI::_RemoveTransferFromEndpoint(transfer_data *transfer) } -status_t -OHCI::_UnlinkTransfer(transfer_data *transfer) +ohci_endpoint_descriptor * +OHCI::_AllocateEndpoint() { - if (Lock()) { - if (transfer == fFirstTransfer) { - // It was the first element - fFirstTransfer = fFirstTransfer->link; - if (transfer == fLastTransfer) - // Also the only one - fLastTransfer = NULL; - } else { - transfer_data *data = fFirstTransfer->link; - transfer_data *previous = fFirstTransfer; - while (data != NULL) { - if (data == transfer) { - previous->link = data->link; - if (data == fLastTransfer) - fLastTransfer = previous; - break; - } - previous = data; - data = data->link; - } - } - Unlock(); - return B_OK; + ohci_endpoint_descriptor *endpoint; + void *physicalAddress; + + // Allocate memory chunk + if (fStack->AllocateChunk((void **)&endpoint, &physicalAddress, + sizeof(ohci_endpoint_descriptor)) < B_OK) { + TRACE_ERROR(("usb_ohci: failed to allocate endpoint descriptor\n")); + return NULL; } - return B_ERROR; + + endpoint->physical_address = (addr_t)physicalAddress; + endpoint->head_logical_descriptor = NULL; + endpoint->head_physical_descriptor = 0; + endpoint->tail_logical_descriptor = NULL; + endpoint->tail_physical_descriptor = 0; + return endpoint; } void -OHCI::_AddDescriptorToHash(ohci_general_td *descriptor) +OHCI::_FreeEndpoint(ohci_endpoint_descriptor *endpoint) { - // TODO -} + if (!endpoint) + return; - -void -OHCI::_RemoveDescriptorFromHash(ohci_general_td *descriptor) -{ - // TODO -} - - -ohci_general_td* -OHCI::_FindDescriptorInHash(uint32 physicalAddress) -{ - // TODO - return NULL; -} - - -void -OHCI::_AddIsoDescriptorToHash(ohci_isochronous_td *descriptor) -{ - // TODO -} - - -void -OHCI::_RemoveIsoDescriptorFromHash(ohci_isochronous_td *descriptor) -{ - // TODO -} - - -ohci_isochronous_td* -OHCI::_FindIsoDescriptorInHash(uint32 physicalAddress) -{ - // TODO - return NULL; + fStack->FreeChunk((void *)endpoint, (void *)endpoint->physical_address, + sizeof(ohci_endpoint_descriptor)); } status_t -OHCI::Start() +OHCI::_InsertEndpointForPipe(Pipe *pipe) { - TRACE(("usb_ohci: starting OHCI Host Controller\n")); + TRACE(("usb_ohci: inserting endpoint for device %u endpoint %u\n", + pipe->DeviceAddress(), pipe->EndpointAddress())); - if ((_ReadReg(OHCI_CONTROL) & OHCI_HC_FUNCTIONAL_STATE_MASK) - != OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL) { - TRACE_ERROR(("usb_ohci: Controller not started!\n")); - return B_ERROR; + ohci_endpoint_descriptor *endpoint = _AllocateEndpoint(); + if (!endpoint) { + TRACE_ERROR(("usb_ohci: cannot allocate memory for endpoint\n")); + return B_NO_MEMORY; + } + + uint32 flags = OHCI_ENDPOINT_SKIP; + + // Set up device and endpoint address + flags |= OHCI_ENDPOINT_SET_DEVICE_ADDRESS(pipe->DeviceAddress()) + | OHCI_ENDPOINT_SET_ENDPOINT_NUMBER(pipe->EndpointAddress()); + + // Set the direction + switch (pipe->Direction()) { + case Pipe::In: + flags |= OHCI_ENDPOINT_DIRECTION_IN; + break; + + case Pipe::Out: + flags |= OHCI_ENDPOINT_DIRECTION_OUT; + break; + + case Pipe::Default: + flags |= OHCI_ENDPOINT_DIRECTION_DESCRIPTOR; + break; + + default: + TRACE_ERROR(("usb_ohci: direction unknown\n")); + _FreeEndpoint(endpoint); + return B_ERROR; + } + + // Set up the speed + switch (pipe->Speed()) { + case USB_SPEED_LOWSPEED: + flags |= OHCI_ENDPOINT_LOW_SPEED; + break; + + case USB_SPEED_FULLSPEED: + flags |= OHCI_ENDPOINT_FULL_SPEED; + break; + + default: + TRACE_ERROR(("usb_ohci: unaccetable speed\n")); + _FreeEndpoint(endpoint); + return B_ERROR; + } + + // Set the maximum packet size + flags |= OHCI_ENDPOINT_SET_MAX_PACKET_SIZE(pipe->MaxPacketSize()); + endpoint->flags = flags; + + // Add the endpoint to the appropriate list + ohci_endpoint_descriptor *head = NULL; + uint32 type = pipe->Type(); + if (type & USB_OBJECT_CONTROL_PIPE) + head = fDummyControl; + else if (type & USB_OBJECT_BULK_PIPE) + head = fDummyBulk; + else if (type & USB_OBJECT_INTERRUPT_PIPE) + head = _FindInterruptEndpoint(pipe->Interval()); + else if (type & USB_OBJECT_ISO_PIPE) { + // Set the isochronous bit format + endpoint->flags |= OHCI_ENDPOINT_ISOCHRONOUS_FORMAT; + head = fDummyIsochronous; } else { - TRACE(("usb_ohci: Controller is OPERATIONAL!\n")); - } - - fRootHubAddress = AllocateAddress(); - fRootHub = new(std::nothrow) OHCIRootHub(RootObject(), fRootHubAddress); - if (!fRootHub) { - TRACE_ERROR(("usb_ohci: no memory to allocate root hub\n")); - return B_NO_MEMORY; - } - - if (fRootHub->InitCheck() < B_OK) { - TRACE_ERROR(("usb_ohci: root hub failed init check\n")); - return B_ERROR; - } - - SetRootHub(fRootHub); - TRACE(("usb_ohci: Host Controller started\n")); - return BusManager::Start(); -} - - -status_t -OHCI::SubmitTransfer(Transfer *transfer) -{ - // short circuit the root hub - if (transfer->TransferPipe()->DeviceAddress() == fRootHubAddress) - return fRootHub->ProcessTransfer(this, transfer); - - uint32 type = transfer->TransferPipe()->Type(); - if ((type & USB_OBJECT_CONTROL_PIPE)) { - TRACE(("usb_ohci: submitting control request\n")); - return _SubmitControlRequest(transfer); - } - - if ((type & USB_OBJECT_BULK_PIPE)) { - TRACE(("usb_ohci: submitting bulk transfer\n")); - return _SubmitBulkTransfer(transfer); - } - - if (((type & USB_OBJECT_ISO_PIPE) || (type & USB_OBJECT_INTERRUPT_PIPE))) { - TRACE(("usb_ohci: submitting periodic transfer\n")); - return _SubmitPeriodicTransfer(transfer); - } - - TRACE_ERROR(("usb_ohci: tried to submit transfer for unknown pipe" - " type %lu\n", type)); - return B_ERROR; -} - - -status_t -OHCI::_SubmitControlRequest(Transfer *transfer) -{ - usb_request_data *requestData = transfer->RequestData(); - bool directionIn = (requestData->RequestType & USB_REQTYPE_DEVICE_IN) > 0; - - ohci_general_td *setupDescriptor - = _CreateGeneralDescriptor(sizeof(usb_request_data)); - if (!setupDescriptor) { - TRACE_ERROR(("usb_ohci: failed to allocate setup descriptor\n")); - return B_NO_MEMORY; - } - // Flags set up could be moved into _CreateGeneralDescriptor - setupDescriptor->flags |= OHCI_TD_DIRECTION_PID_SETUP - | OHCI_TD_NO_CONDITION_CODE - | OHCI_TD_TOGGLE_0 - | OHCI_TD_SET_DELAY_INTERRUPT(6); // Not sure about this. - - ohci_general_td *statusDescriptor - = _CreateGeneralDescriptor(0); - if (!statusDescriptor) { - TRACE_ERROR(("usb_ohci: failed to allocate status descriptor\n")); - _FreeGeneralDescriptor(setupDescriptor); - return B_NO_MEMORY; - } - statusDescriptor->flags - |= (directionIn ? OHCI_TD_DIRECTION_PID_OUT : OHCI_TD_DIRECTION_PID_IN) - | OHCI_TD_NO_CONDITION_CODE - | OHCI_TD_TOGGLE_1 - | OHCI_TD_SET_DELAY_INTERRUPT(1); - - iovec vector; - vector.iov_base = requestData; - vector.iov_len = sizeof(usb_request_data); - _WriteDescriptorChain(setupDescriptor, &vector, 1); - - status_t result; - ohci_general_td *dataDescriptor = NULL; - if (transfer->VectorCount() > 0) { - ohci_general_td *lastDescriptor = NULL; - result = _CreateDescriptorChain(&dataDescriptor, - &lastDescriptor, - directionIn ? OHCI_TD_DIRECTION_PID_OUT : OHCI_TD_DIRECTION_PID_IN, - transfer->VectorLength()); - if (result < B_OK) { - _FreeGeneralDescriptor(setupDescriptor); - _FreeGeneralDescriptor(statusDescriptor); - return result; - } - - if (!directionIn) { - _WriteDescriptorChain(dataDescriptor, transfer->Vector(), - transfer->VectorCount()); - } - - _LinkDescriptors(setupDescriptor, dataDescriptor); - _LinkDescriptors(lastDescriptor, statusDescriptor); - } else { - _LinkDescriptors(setupDescriptor, statusDescriptor); - } - - // Append Transfer - ohci_endpoint_descriptor *endpoint - = (ohci_endpoint_descriptor *)transfer->TransferPipe()->ControllerCookie(); - result = _AddPendingTransfer(transfer, endpoint, setupDescriptor, - dataDescriptor, directionIn); - if (result < B_OK) { - TRACE_ERROR(("usb_ohci: failed to add pending transfer\n")); - _FreeDescriptorChain(setupDescriptor); - return result; - } - - // Append descriptors chain to the endpoint - result = _AppendChainDescriptorsToEndpoint(endpoint, setupDescriptor, - statusDescriptor); - if (result < B_OK) { - TRACE_ERROR(("usb_ohci: failed to append chain descriptors to endpoint\n")); - // TODO: Remove transfer_data from list - _FreeDescriptorChain(setupDescriptor); - } - - // Tell the controller to process the control list - _WriteReg(OHCI_COMMAND_STATUS, OHCI_CONTROL_LIST_FILLED); - return B_OK; -} - - -status_t -OHCI::_SubmitBulkTransfer(Transfer *transfer) -{ - // TODO - return B_ERROR; -} - - -status_t -OHCI::_AddPendingTransfer(Transfer *transfer, ohci_endpoint_descriptor *endpoint, - ohci_general_td *firstDescriptor, ohci_general_td *dataDescriptor, bool directionIn) -{ - if (!transfer || !endpoint || !firstDescriptor) + TRACE_ERROR(("usb_ohci: unknown pipe type\n")); + _FreeEndpoint(endpoint); return B_BAD_VALUE; - - transfer_data *data = new(std::nothrow) transfer_data; - if (!data) - return B_NO_MEMORY; - - status_t result = transfer->InitKernelAccess(); - if (result < B_OK) { - delete data; - return result; } - data->transfer = transfer; - data->endpoint = endpoint; - data->first_descriptor = firstDescriptor; - data->data_descriptor = dataDescriptor; - data->incoming = directionIn; - data->canceled = false; - data->link = NULL; - - if (!Lock()) { - delete data; - return B_ERROR; + // Create (necessary) dummy descriptor + if (pipe->Type() & USB_OBJECT_ISO_PIPE) { + // TODO + } else { + ohci_general_td *dummy = _CreateGeneralDescriptor(0); + dummy->next_logical_descriptor = NULL; + dummy->next_physical_descriptor = 0; + endpoint->head_logical_descriptor = dummy; + endpoint->tail_logical_descriptor = dummy; + endpoint->head_physical_descriptor = dummy->physical_address; + endpoint->tail_physical_descriptor = dummy->physical_address; } - if (fLastTransfer) - fLastTransfer->link = data; - else - fFirstTransfer = data; - - fLastTransfer = data; + // TODO: Change lock lo LockEndpoint() + Lock(); + pipe->SetControllerCookie((void *)endpoint); + endpoint->next_logical_endpoint = head->next_logical_endpoint; + endpoint->next_physical_endpoint = head->next_physical_endpoint; + head->next_logical_endpoint = (void *)endpoint; + head->next_physical_endpoint = (uint32)endpoint->physical_address; Unlock(); return B_OK; @@ -902,17 +1259,66 @@ OHCI::_AddPendingTransfer(Transfer *transfer, ohci_endpoint_descriptor *endpoint status_t -OHCI::_SubmitPeriodicTransfer(Transfer *transfer) +OHCI::_RemoveEndpointForPipe(Pipe *pipe) { return B_ERROR; } -void -OHCI::_LinkDescriptors(ohci_general_td *first, ohci_general_td *second) +ohci_endpoint_descriptor * +OHCI::_FindInterruptEndpoint(uint8 interval) { - first->next_physical_descriptor = second->physical_address; - first->next_logical_descriptor = second; + return NULL; +} + + +ohci_general_td * +OHCI::_CreateGeneralDescriptor(size_t bufferSize) +{ + ohci_general_td *descriptor; + void *physicalAddress; + + if (fStack->AllocateChunk((void **)&descriptor, &physicalAddress, + sizeof(ohci_general_td)) != B_OK) { + TRACE_ERROR(("usb_ohci: failed to allocate general descriptor\n")); + return NULL; + } + + descriptor->physical_address = (addr_t)physicalAddress; + if (bufferSize == 0) { + descriptor->buffer_physical = 0; + descriptor->buffer_logical = NULL; + descriptor->last_physical_byte_address = 0; + return descriptor; + } + + if (fStack->AllocateChunk(&descriptor->buffer_logical, + (void **)&descriptor->buffer_physical, bufferSize) != B_OK) { + TRACE_ERROR(("usb_ohci: failed to allocate space for buffer\n")); + fStack->FreeChunk(descriptor, (void *)descriptor->physical_address, + sizeof(ohci_general_td)); + return NULL; + } + descriptor->last_physical_byte_address + = descriptor->buffer_physical + bufferSize - 1; + + return descriptor; +} + + +void +OHCI::_FreeGeneralDescriptor(ohci_general_td *descriptor) +{ + if (!descriptor) + return; + + if (descriptor->buffer_logical) { + fStack->FreeChunk(descriptor->buffer_logical, + (void *)descriptor->buffer_physical, descriptor->buffer_size); + } + + fStack->FreeChunk((void *)descriptor, (void *)descriptor->physical_address, + sizeof(ohci_general_td)); } @@ -993,418 +1399,73 @@ OHCI::_WriteDescriptorChain(ohci_general_td *topDescriptor, iovec *vector, } -status_t -OHCI::NotifyPipeChange(Pipe *pipe, usb_change change) +void +OHCI::_LinkDescriptors(ohci_general_td *first, ohci_general_td *second) { - TRACE(("usb_ohci: pipe change %d for pipe 0x%08lx\n", change, (uint32)pipe)); - switch (change) { - case USB_CHANGE_CREATED: { - TRACE(("usb_ohci: inserting endpoint\n")); - return _InsertEndpointForPipe(pipe); - } - case USB_CHANGE_DESTROYED: { - TRACE(("usb_ohci: removing endpoint\n")); - return _RemoveEndpointForPipe(pipe); - } - case USB_CHANGE_PIPE_POLICY_CHANGED: { - TRACE(("usb_ohci: pipe policy changing unhandled!\n")); - break; - } - default: { - TRACE_ERROR(("usb_ohci: unknown pipe change!\n")); - return B_ERROR; - } - } - return B_OK; + first->next_physical_descriptor = second->physical_address; + first->next_logical_descriptor = second; } -status_t -OHCI::AddTo(Stack *stack) +ohci_isochronous_td * +OHCI::_CreateIsochronousDescriptor() { -#ifdef TRACE_USB - set_dprintf_enabled(true); -#ifndef __HAIKU__ - load_driver_symbols("ohci"); -#endif -#endif - - if (!sPCIModule) { - status_t status = get_module(B_PCI_MODULE_NAME, (module_info **)&sPCIModule); - if (status < B_OK) { - TRACE_ERROR(("usb_ohci: getting pci module failed! 0x%08lx\n", - status)); - return status; - } - } - - TRACE(("usb_ohci: searching devices\n")); - bool found = false; - pci_info *item = new(std::nothrow) pci_info; - if (!item) { - sPCIModule = NULL; - put_module(B_PCI_MODULE_NAME); - return B_NO_MEMORY; - } - - for (uint32 i = 0 ; sPCIModule->get_nth_pci_info(i, item) >= B_OK; i++) { - - if (item->class_base == PCI_serial_bus && item->class_sub == PCI_usb - && item->class_api == PCI_usb_ohci) { - if (item->u.h0.interrupt_line == 0 - || item->u.h0.interrupt_line == 0xFF) { - TRACE_ERROR(("usb_ohci: found device with invalid IRQ -" - " check IRQ assignement\n")); - continue; - } - - TRACE(("usb_ohci: found device at IRQ %u\n", - item->u.h0.interrupt_line)); - OHCI *bus = new(std::nothrow) OHCI(item, stack); - if (!bus) { - delete item; - sPCIModule = NULL; - put_module(B_PCI_MODULE_NAME); - return B_NO_MEMORY; - } - - if (bus->InitCheck() < B_OK) { - TRACE_ERROR(("usb_ohci: bus failed init check\n")); - delete bus; - continue; - } - - // the bus took it away - item = new(std::nothrow) pci_info; - - bus->Start(); - stack->AddBusManager(bus); - found = true; - } - } - - if (!found) { - TRACE_ERROR(("usb_ohci: no devices found\n")); - delete item; - sPCIModule = NULL; - put_module(B_PCI_MODULE_NAME); - return ENODEV; - } - - delete item; - return B_OK; -} - - -status_t -OHCI::GetPortStatus(uint8 index, usb_port_status *status) -{ - TRACE(("usb_ohci::%s(%ud, )\n", __FUNCTION__, index)); - if (index >= fPortCount) - return B_BAD_INDEX; - - status->status = status->change = 0; - uint32 portStatus = _ReadReg(OHCI_RH_PORT_STATUS(index)); - - TRACE(("usb_ohci: RootHub::GetPortStatus: Port %i Value 0x%lx\n", OHCI_RH_PORT_STATUS(index), portStatus)); - - // status - if (portStatus & OHCI_RH_PORTSTATUS_CCS) - status->status |= PORT_STATUS_CONNECTION; - if (portStatus & OHCI_RH_PORTSTATUS_PES) - status->status |= PORT_STATUS_ENABLE; - if (portStatus & OHCI_RH_PORTSTATUS_PRS) - status->status |= PORT_STATUS_RESET; - if (portStatus & OHCI_RH_PORTSTATUS_LSDA) - status->status |= PORT_STATUS_LOW_SPEED; - if (portStatus & OHCI_RH_PORTSTATUS_PSS) - status->status |= PORT_STATUS_SUSPEND; - if (portStatus & OHCI_RH_PORTSTATUS_POCI) - status->status |= PORT_STATUS_OVER_CURRENT; - if (portStatus & OHCI_RH_PORTSTATUS_PPS) - status->status |= PORT_STATUS_POWER; - - // change - if (portStatus & OHCI_RH_PORTSTATUS_CSC) - status->change |= PORT_STATUS_CONNECTION; - if (portStatus & OHCI_RH_PORTSTATUS_PESC) - status->change |= PORT_STATUS_ENABLE; - if (portStatus & OHCI_RH_PORTSTATUS_PSSC) - status->change |= PORT_STATUS_SUSPEND; - if (portStatus & OHCI_RH_PORTSTATUS_OCIC) - status->change |= PORT_STATUS_OVER_CURRENT; - if (portStatus & OHCI_RH_PORTSTATUS_PRSC) - status->change |= PORT_STATUS_RESET; - - return B_OK; -} - - -status_t -OHCI::SetPortFeature(uint8 index, uint16 feature) -{ - TRACE(("OHCI::%s(%ud, %ud)\n", __FUNCTION__, index, feature)); - if (index > fPortCount) - return B_BAD_INDEX; - - switch (feature) { - case PORT_RESET: - _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PRS); - return B_OK; - - case PORT_POWER: - _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_PPS); - return B_OK; - } - - return B_BAD_VALUE; -} - - -status_t -OHCI::ClearPortFeature(uint8 index, uint16 feature) -{ - TRACE(("OHCI::%s(%ud, %ud)\n", __FUNCTION__, index, feature)); - if (index > fPortCount) - return B_BAD_INDEX; - - switch (feature) { - case C_PORT_RESET: - _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CSC); - return B_OK; - - case C_PORT_CONNECTION: - _WriteReg(OHCI_RH_PORT_STATUS(index), OHCI_RH_PORTSTATUS_CSC); - return B_OK; - } - - return B_BAD_VALUE; -} - - -ohci_endpoint_descriptor* -OHCI::_AllocateEndpoint() -{ - ohci_endpoint_descriptor *endpoint; - void* physicalAddress; - - // Allocate memory chunk - if (fStack->AllocateChunk((void **)&endpoint, &physicalAddress, - sizeof(ohci_endpoint_descriptor)) < B_OK) { - TRACE_ERROR(("usb_ohci: failed to allocate endpoint descriptor\n")); - return NULL; - } - memset((void *)endpoint, 0, sizeof(ohci_endpoint_descriptor)); - - endpoint->physical_address = (addr_t)physicalAddress; - - endpoint->head_physical_descriptor = NULL; - endpoint->tail_physical_descriptor = NULL; - - endpoint->head_logical_descriptor = NULL; - endpoint->tail_logical_descriptor = NULL; - - return endpoint; + // TODO + return NULL; } void -OHCI::_FreeEndpoint(ohci_endpoint_descriptor *endpoint) +OHCI::_FreeIsochronousDescriptor(ohci_isochronous_td *descriptor) { - if (!endpoint) - return; + // TODO +} - fStack->FreeChunk((void *)endpoint, (void *)endpoint->physical_address, - sizeof(ohci_endpoint_descriptor)); + +void +OHCI::_AddDescriptorToHash(ohci_general_td *descriptor) +{ + // TODO +} + + +void +OHCI::_RemoveDescriptorFromHash(ohci_general_td *descriptor) +{ + // TODO } ohci_general_td* -OHCI::_CreateGeneralDescriptor(size_t bufferSize) +OHCI::_FindDescriptorInHash(uint32 physicalAddress) { - ohci_general_td *descriptor; - void *physicalAddress; - - if (fStack->AllocateChunk((void **)&descriptor, &physicalAddress, - sizeof(ohci_general_td)) != B_OK) { - TRACE_ERROR(("usb_ohci: failed to allocate general descriptor\n")); - return NULL; - } - memset((void *)descriptor, 0, sizeof(ohci_general_td)); - descriptor->physical_address = (addr_t)physicalAddress; - - if (!bufferSize) { - descriptor->buffer_physical = 0; - descriptor->buffer_logical = NULL; - descriptor->last_physical_byte_address = 0; - return descriptor; - } - - if (fStack->AllocateChunk(&descriptor->buffer_logical, - (void **)&descriptor->buffer_physical, bufferSize) != B_OK) { - TRACE_ERROR(("usb_ohci: failed to allocate space for buffer\n")); - fStack->FreeChunk(descriptor, (void *)descriptor->physical_address, - sizeof(ohci_general_td)); - return NULL; - } - descriptor->last_physical_byte_address - = descriptor->buffer_physical + bufferSize - 1; - - return descriptor; + // TODO + return NULL; } void -OHCI::_FreeGeneralDescriptor(ohci_general_td *descriptor) +OHCI::_AddIsoDescriptorToHash(ohci_isochronous_td *descriptor) { - if (!descriptor) - return; + // TODO +} - if (descriptor->buffer_logical) { - fStack->FreeChunk(descriptor->buffer_logical, - (void *)descriptor->buffer_physical, descriptor->buffer_size); - } - fStack->FreeChunk((void *)descriptor, (void *)descriptor->physical_address, - sizeof(ohci_general_td)); +void +OHCI::_RemoveIsoDescriptorFromHash(ohci_isochronous_td *descriptor) +{ + // TODO } ohci_isochronous_td* -_CreateIsochronousDescriptor() +OHCI::_FindIsoDescriptorInHash(uint32 physicalAddress) { // TODO return NULL; } -void _FreeIsochronousDescriptor(ohci_isochronous_td *descriptor) -{ - // TODO -} - - -status_t -OHCI::_InsertEndpointForPipe(Pipe *pipe) -{ - TRACE(("OHCI: Inserting Endpoint for device %u function %u\n", - pipe->DeviceAddress(), pipe->EndpointAddress())); - - ohci_endpoint_descriptor *endpoint = _AllocateEndpoint(); - if (!endpoint) { - TRACE_ERROR(("usb_ohci: cannot allocate memory for endpoint\n")); - return B_NO_MEMORY; - } - - uint32 flags = 0; - flags |= OHCI_ENDPOINT_SKIP; - - // Set up device and endpoint address - flags |= OHCI_ENDPOINT_SET_DEVICE_ADDRESS(pipe->DeviceAddress()) - | OHCI_ENDPOINT_SET_ENDPOINT_NUMBER(pipe->EndpointAddress()); - - // Set the direction - switch (pipe->Direction()) { - case Pipe::In: - flags |= OHCI_ENDPOINT_DIRECTION_IN; - break; - case Pipe::Out: - flags |= OHCI_ENDPOINT_DIRECTION_OUT; - break; - case Pipe::Default: - flags |= OHCI_ENDPOINT_DIRECTION_DESCRIPTOR; - break; - default: - TRACE_ERROR(("usb_ohci: direction unknown. Wrong value!\n")); - _FreeEndpoint(endpoint); - return B_ERROR; - } - - // Set up the speed - switch (pipe->Speed()) { - case USB_SPEED_LOWSPEED: - flags |= OHCI_ENDPOINT_LOW_SPEED; - break; - case USB_SPEED_FULLSPEED: - flags |= OHCI_ENDPOINT_FULL_SPEED; - break; - case USB_SPEED_HIGHSPEED: - default: - TRACE_ERROR(("usb_ohci: unaccetable speed. Wrong value!\n")); - _FreeEndpoint(endpoint); - return B_ERROR; - } - - // Set the maximum packet size - flags |= OHCI_ENDPOINT_SET_MAX_PACKET_SIZE(pipe->MaxPacketSize()); - - endpoint->flags = flags; - - // Add the endpoint to the appropriate list - ohci_endpoint_descriptor *head = NULL; - switch (pipe->Type()) { - case USB_OBJECT_CONTROL_PIPE: - head = fDummyControl; - break; - case USB_OBJECT_BULK_PIPE: - head = fDummyBulk; - break; - case USB_OBJECT_ISO_PIPE: - // Set the isochronous bit format - endpoint->flags |= OHCI_ENDPOINT_ISOCHRONOUS_FORMAT; - head = fDummyIsochronous; - break; - case USB_OBJECT_INTERRUPT_PIPE: - head = _FindInterruptEndpoint(pipe->Interval()); - break; - default: - TRACE_ERROR(("usb_ohci: unknown type of pipe. Wrong value!\n")); - _FreeEndpoint(endpoint); - return B_ERROR; - } - - // Create (necessary) dummy descriptor - if (pipe->Type() & USB_OBJECT_ISO_PIPE) { - // TODO - } else { - ohci_general_td *dummy = _CreateGeneralDescriptor(0); - dummy->next_logical_descriptor = NULL; - dummy->next_physical_descriptor = NULL; - endpoint->head_logical_descriptor - = endpoint->tail_logical_descriptor - = dummy; - endpoint->head_physical_descriptor - = endpoint->tail_physical_descriptor - = dummy->physical_address; - } - - // TODO: Change lock lo LockEndpoint() - Lock(); - pipe->SetControllerCookie((void *)endpoint); - endpoint->next_logical_endpoint = head->next_logical_endpoint; - endpoint->next_physical_endpoint = head->next_physical_endpoint; - head->next_logical_endpoint = (void *)endpoint; - head->next_physical_endpoint = (uint32)endpoint->physical_address; - Unlock(); - - return B_OK; -} - - -ohci_endpoint_descriptor* -OHCI::_FindInterruptEndpoint(uint8 interval) -{ - return NULL; -} - - -status_t -OHCI::_RemoveEndpointForPipe(Pipe *pipe) -{ - return B_ERROR; -} - - inline void OHCI::_WriteReg(uint32 reg, uint32 value) { @@ -1417,55 +1478,3 @@ OHCI::_ReadReg(uint32 reg) { return *(volatile uint32 *)(fOperationalRegisters + reg); } - - -status_t -OHCI::CancelQueuedTransfers(Pipe *pipe, bool force) -{ - if (pipe->Type() & USB_OBJECT_ISO_PIPE) - return _CancelQueuedIsochronousTransfers(pipe, force); - - if (!Lock()) - return B_ERROR; - - transfer_data *current = fFirstTransfer; - while (current) { - if (current->transfer->TransferPipe() == pipe) { - // Check if the skip bit is already set - if (!(current->endpoint->flags & OHCI_ENDPOINT_SKIP)) { - current->endpoint->flags |= OHCI_ENDPOINT_SKIP; - // In case the controller is processing - // this endpoint, wait for it to finish - snooze(1000); - } - // Clear the endpoint - current->endpoint->head_physical_descriptor = NULL; - current->endpoint->tail_physical_descriptor = NULL; - current->endpoint->head_logical_descriptor = NULL; - current->endpoint->tail_logical_descriptor = NULL; - - if (!force) { - // If the transfer is canceled by force, the one causing the - // cancel is probably not the one who initiated the transfer - // and the callback is likely not safe anymore - current->transfer->Finished(B_CANCELED, 0); - } - current->canceled = true; - } - current = current->link; - } - - Unlock(); - - // notify the finisher so it can clean up the canceled transfers - release_sem_etc(fFinishTransfersSem, 1, B_DO_NOT_RESCHEDULE); - return B_OK; -} - - -status_t -OHCI::_CancelQueuedIsochronousTransfers(Pipe *pipe, bool force) -{ - // TODO - return B_ERROR; -} diff --git a/src/add-ons/kernel/busses/usb/ohci.h b/src/add-ons/kernel/busses/usb/ohci.h index 4b279ef8a7..fd9c265375 100644 --- a/src/add-ons/kernel/busses/usb/ohci.h +++ b/src/add-ons/kernel/busses/usb/ohci.h @@ -105,13 +105,13 @@ static int32 _InterruptHandler(void *data); status_t _UnlinkTransfer(transfer_data *transfer); static int32 _FinishThread(void *data); - void _FinishTransfer(); + void _FinishTransfers(); - status_t _SubmitControlRequest(Transfer *transfer); + status_t _SubmitControlTransfer(Transfer *transfer); status_t _SubmitBulkTransfer(Transfer *transfer); status_t _SubmitPeriodicTransfer(Transfer *transfer); - status_t _AppendChainDescriptorsToEndpoint( + status_t _AppendDescriptorChainToEndpoint( ohci_endpoint_descriptor *endpoint, ohci_general_td *first, ohci_general_td *last); @@ -129,17 +129,22 @@ static int32 _FinishThread(void *data); // Transfer descriptor related methods ohci_general_td *_CreateGeneralDescriptor( size_t bufferSize); + void _FreeGeneralDescriptor( + ohci_general_td *descriptor); + status_t _CreateDescriptorChain( ohci_general_td **firstDescriptor, ohci_general_td **lastDescriptor, uint8 direction, size_t bufferSize); - - void _FreeGeneralDescriptor( - ohci_general_td *descriptor); void _FreeDescriptorChain( ohci_general_td *topDescriptor); + size_t _WriteDescriptorChain( + ohci_general_td *topDescriptor, + iovec *vector, + size_t vectorCount); + void _LinkDescriptors(ohci_general_td *first, ohci_general_td *second); @@ -147,11 +152,6 @@ static int32 _FinishThread(void *data); void _FreeIsochronousDescriptor( ohci_isochronous_td *descriptor); - size_t _WriteDescriptorChain( - ohci_general_td *topDescriptor, - iovec *vector, - size_t vectorCount); - // Hash tables related methods void _AddDescriptorToHash( ohci_general_td *descriptor); diff --git a/src/add-ons/kernel/busses/usb/ohci_hardware.h b/src/add-ons/kernel/busses/usb/ohci_hardware.h index 4d9779dae3..936a58c8b3 100644 --- a/src/add-ons/kernel/busses/usb/ohci_hardware.h +++ b/src/add-ons/kernel/busses/usb/ohci_hardware.h @@ -3,15 +3,15 @@ * Distributed under the terms of the MIT License. * * Authors: - * Jan-Rixt Van Hoye - * Salvatore Benedetto + * Jan-Rixt Van Hoye + * Salvatore Benedetto */ -#ifndef OHCI_HARD_H -#define OHCI_HARD_H +#ifndef OHCI_HARDWARE_H +#define OHCI_HARDWARE_H // -------------------------------- -// The OHCI registers +// The OHCI registers // -------------------------------- // -------------------------------- @@ -95,7 +95,7 @@ #define OHCI_HCCA 0x18 // -------------------------------- -// Period current ED register (section 7.2.2) +// Period current ED register (section 7.2.2) // -------------------------------- #define OHCI_PERIOD_CURRENT_ED 0x1c @@ -206,19 +206,19 @@ // Root Hub port status (n) register (section 7.4.4) // -------------------------------- -#define OHCI_RH_PORT_STATUS(n) (0x50 + (n) * 4) // 1 based indexing -#define OHCI_RH_PORTSTATUS_CCS 0x00000001 // Current Connection Status -#define OHCI_RH_PORTSTATUS_PES 0x00000002 // Port Enable Status -#define OHCI_RH_PORTSTATUS_PSS 0x00000004 // Port Suspend Status -#define OHCI_RH_PORTSTATUS_POCI 0x00000008 // Port Overcurrent Indicator -#define OHCI_RH_PORTSTATUS_PRS 0x00000010 // Port Reset Status -#define OHCI_RH_PORTSTATUS_PPS 0x00000100 // Port Power Status -#define OHCI_RH_PORTSTATUS_LSDA 0x00000200 // Low Speed Device Attached -#define OHCI_RH_PORTSTATUS_CSC 0x00010000 // Connection Status Change -#define OHCI_RH_PORTSTATUS_PESC 0x00020000 // Port Enable Status Change -#define OHCI_RH_PORTSTATUS_PSSC 0x00040000 // Port Suspend Status change -#define OHCI_RH_PORTSTATUS_OCIC 0x00080000 // Port Overcurrent Change -#define OHCI_RH_PORTSTATUS_PRSC 0x00100000 // Port Reset Status Change +#define OHCI_RH_PORT_STATUS(n) (0x50 + (n) * 4)// 1 based indexing +#define OHCI_RH_PORTSTATUS_CCS 0x00000001 // Current Connection Status +#define OHCI_RH_PORTSTATUS_PES 0x00000002 // Port Enable Status +#define OHCI_RH_PORTSTATUS_PSS 0x00000004 // Port Suspend Status +#define OHCI_RH_PORTSTATUS_POCI 0x00000008 // Port Overcurrent Indicator +#define OHCI_RH_PORTSTATUS_PRS 0x00000010 // Port Reset Status +#define OHCI_RH_PORTSTATUS_PPS 0x00000100 // Port Power Status +#define OHCI_RH_PORTSTATUS_LSDA 0x00000200 // Low Speed Device Attached +#define OHCI_RH_PORTSTATUS_CSC 0x00010000 // Connection Status Change +#define OHCI_RH_PORTSTATUS_PESC 0x00020000 // Port Enable Status Change +#define OHCI_RH_PORTSTATUS_PSSC 0x00040000 // Port Suspend Status change +#define OHCI_RH_PORTSTATUS_OCIC 0x00080000 // Port Overcurrent Change +#define OHCI_RH_PORTSTATUS_PRSC 0x00100000 // Port Reset Status Change // -------------------------------- // Enable List @@ -244,8 +244,8 @@ // -------------------------------- // All normal interupts -// -------------------------------- - +// -------------------------------- + #define OHCI_NORMAL_INTERRUPTS (OHCI_SCHEDULING_OVERRUN \ | OHCI_WRITEBACK_DONE_HEAD \ | OHCI_RESUME_DETECTED \ @@ -271,7 +271,7 @@ #define OHCI_NUMBER_OF_INTERRUPTS 32 -typedef struct ohci_hcca +typedef struct ohci_hcca { uint32 interrupt_table[OHCI_NUMBER_OF_INTERRUPTS]; uint32 current_frame_number; @@ -338,8 +338,8 @@ typedef struct ohci_general_td // Hardware part 16 bytes uint32 flags; // Flags field uint32 buffer_physical; // Physical buffer pointer - uint32 next_physical_descriptor; // Physical pointer next descriptor - uint32 last_physical_byte_address; // Physical pointer to buffer end + uint32 next_physical_descriptor; // Physical pointer next descriptor + uint32 last_physical_byte_address; // Physical pointer to buffer end // Software part addr_t physical_address; // Physical address of this descriptor void *buffer_logical; // Logical pointer to the buffer @@ -403,7 +403,7 @@ typedef struct ohci_isochronous_td #define OHCI_ITD_PAGE_SELECT 0x00001000 #define OHCI_ITD_MK_OFFS(len) (0xe000 | ((len) & 0x1fff)) #define OHCI_ITD_GET_BUFFER_LENGTH(x) ((x) & 0xfff) -#define OHCI_ITD_GET_BUFFER_CONDITION_CODE(x) ((x) >> 12) +#define OHCI_ITD_GET_BUFFER_CONDITION_CODE(x) ((x) >> 12) #define OHCI_ISOCHRONOUS_TD_ALIGN 32 @@ -426,11 +426,11 @@ typedef struct ohci_isochronous_td #define OHCI_NOT_ACCESSED 15 // -------------------------------- -// Some delay needed when changing +// Some delay needed when changing // certain registers. // -------------------------------- #define OHCI_ENABLE_POWER_DELAY 5000 #define OHCI_READ_DESC_DELAY 5000 -#endif // OHCI_HARD_H +#endif // OHCI_HARDWARE_H diff --git a/src/add-ons/kernel/busses/usb/ohci_rh.cpp b/src/add-ons/kernel/busses/usb/ohci_rh.cpp index c6561df620..b88b46e705 100644 --- a/src/add-ons/kernel/busses/usb/ohci_rh.cpp +++ b/src/add-ons/kernel/busses/usb/ohci_rh.cpp @@ -3,28 +3,29 @@ * Distributed under the terms of the MIT License. * * Authors: - * Jan-Rixt Van Hoye - * Salvatore Benedetto + * Jan-Rixt Van Hoye + * Salvatore Benedetto + * Michael Lotz */ #include "ohci.h" static usb_device_descriptor sOHCIRootHubDevice = { - 0x12, // Descriptor size - USB_DESCRIPTOR_DEVICE, // Type of descriptor - 0x110, // USB 1.1 - 0x09, // Hub type - 0, // Subclass - 0, // Protocol - 64, // Max packet size - 0, // Vendor - 0, // Product - 0x110, // Version - 1, // Index of manufacture string - 2, // Index of product string - 0, // Index of serial number string - 1 // Number of configurations + 18, // Descriptor length + USB_DESCRIPTOR_DEVICE, // Descriptor type + 0x110, // USB 1.1 + 0x09, // Class (9 = Hub) + 0, // Subclass + 0, // Protocol + 64, // Max packet size on endpoint 0 + 0, // Vendor ID + 0, // Product ID + 0x110, // Version + 1, // Index of manufacturer string + 2, // Index of product string + 0, // Index of serial number string + 1 // Number of configurations }; @@ -41,48 +42,50 @@ static ohci_root_hub_configuration_s sOHCIRootHubConfig = { // configuration descriptor 9, // Descriptor length USB_DESCRIPTOR_CONFIGURATION, // Descriptor type - 34, // Total size of the configuration - 1, // Number interfaces - 1, // Value of configuration - 0, // Number of configuration - 0x40, // Self powered - 0 // Max power (0, because of self power) + 34, // Total length of configuration (including + // interface, endpoint and hub descriptors) + 1, // Number of interfaces + 1, // Value of this configuration + 0, // Index of configuration string + 0x40, // Attributes (0x40 = self powered) + 0 // Max power (0, since self powered) }, { // interface descriptor - 9, // Size - USB_DESCRIPTOR_INTERFACE, // Type + 9, // Descriptor length + USB_DESCRIPTOR_INTERFACE, // Descriptor type 0, // Interface number 0, // Alternate setting - 1, // Num endpoints - 0x09, // Interface class + 1, // Number of endpoints + 0x09, // Interface class (9 = Hub) 0, // Interface subclass 0, // Interface protocol - 0 // Interface + 0 // Index of interface string }, { // endpoint descriptor - 7, // Size - USB_DESCRIPTOR_ENDPOINT, // Type - USB_REQTYPE_DEVICE_IN | 1, // Endpoint address (first in IN endpoint) + 7, // Descriptor length + USB_DESCRIPTOR_ENDPOINT, // Descriptor type + USB_REQTYPE_DEVICE_IN | 1, // Endpoint address (first in IN endpoint) 0x03, // Attributes (0x03 = interrupt endpoint) 8, // Max packet size - 0xFF // Interval 256 + 0xff // Interval 256 }, - - { // hub descriptor - 9, // Lenght (including deprecated power - // control mask) - USB_DESCRIPTOR_HUB, // Type - 0, // Number of ports - 0x0000, // Hub characteristics - 0, // Power on to power good - 0, // Current - 0x00, // Both ports are removable - 0xff // Depricated power control mask + + { // hub descriptor + 9, // Descriptor length (including + // deprecated power control mask) + USB_DESCRIPTOR_HUB, // Descriptor type + 2, // Number of ports + 0x0000, // Hub characteristics + 0, // Power on to power good (in 2ms units) + 0, // Maximum current (in mA) + 0x00, // Both ports are removable + 0xff // Depricated power control mask } }; + struct ohci_root_hub_string_s { uint8 length; uint8 descriptor_type; @@ -121,11 +124,12 @@ static ohci_root_hub_string_s sOHCIRootHubStrings[3] = { OHCIRootHub::OHCIRootHub(Object *rootObject, int8 deviceAddress) - : Hub(rootObject, rootObject->GetStack()->IndexOfBusManager(rootObject->GetBusManager()), - sOHCIRootHubDevice, deviceAddress, USB_SPEED_FULLSPEED, true) + : Hub(rootObject, rootObject->GetStack()->IndexOfBusManager(rootObject->GetBusManager()), + sOHCIRootHubDevice, deviceAddress, USB_SPEED_FULLSPEED, true) { } + status_t OHCIRootHub::ProcessTransfer(OHCI *ohci, Transfer *transfer) { @@ -133,8 +137,7 @@ OHCIRootHub::ProcessTransfer(OHCI *ohci, Transfer *transfer) return B_ERROR; usb_request_data *request = transfer->RequestData(); - - TRACE(("usb_ohci_roothub(): request: %d\n", request->Request)); + TRACE(("usb_ohci_roothub: request: %d\n", request->Request)); status_t status = B_TIMED_OUT; size_t actualLength = 0; @@ -147,7 +150,6 @@ OHCIRootHub::ProcessTransfer(OHCI *ohci, Transfer *transfer) // the hub reports whether the local power failed (bit 0) // and if there is a over-current condition (bit 1). // everything as 0 means all is ok. - // TODO (?) actually check for the value memset(transfer->Data(), 0, actualLength); status = B_OK; break; @@ -159,6 +161,7 @@ OHCIRootHub::ProcessTransfer(OHCI *ohci, Transfer *transfer) memcpy(transfer->Data(), (void *)&portStatus, actualLength); status = B_OK; } + break; } @@ -168,12 +171,12 @@ OHCIRootHub::ProcessTransfer(OHCI *ohci, Transfer *transfer) break; } - TRACE(("usb_ohci_roothub(): set address: %d\n", request->Value)); + TRACE(("usb_ohci_roothub: set address: %d\n", request->Value)); status = B_OK; break; case USB_REQUEST_GET_DESCRIPTOR: - TRACE(("usb_ohci_roothub(): get descriptor: %d\n", request->Value >> 8)); + TRACE(("usb_ohci_roothub: get descriptor: %d\n", request->Value >> 8)); switch (request->Value >> 8) { case USB_DESCRIPTOR_DEVICE: { @@ -227,11 +230,11 @@ OHCIRootHub::ProcessTransfer(OHCI *ohci, Transfer *transfer) case USB_REQUEST_CLEAR_FEATURE: { if (request->Index == 0) { // we don't support any hub changes - TRACE_ERROR(("usb_ohci_roothub(): clear feature: no hub changes\n")); + TRACE_ERROR(("usb_ohci_roothub: clear feature: no hub changes\n")); break; } - TRACE(("usb_ohci_roothub(): clear feature: %d\n", request->Value)); + TRACE(("usb_ohci_roothub: clear feature: %d\n", request->Value)); if (ohci->ClearPortFeature(request->Index - 1, request->Value) >= B_OK) status = B_OK; break; @@ -240,11 +243,11 @@ OHCIRootHub::ProcessTransfer(OHCI *ohci, Transfer *transfer) case USB_REQUEST_SET_FEATURE: { if (request->Index == 0) { // we don't support any hub changes - TRACE_ERROR(("usb_ohci_roothub(): set feature: no hub changes\n")); + TRACE_ERROR(("usb_ohci_roothub: set feature: no hub changes\n")); break; } - TRACE(("usb_ohci_roothub(): set feature: %d\n", request->Value)); + TRACE(("usb_ohci_roothub: set feature: %d\n", request->Value)); if (ohci->SetPortFeature(request->Index - 1, request->Value) >= B_OK) status = B_OK; break;