From 46a41c432c78ffede0165f705000468672bbd681 Mon Sep 17 00:00:00 2001 From: Salvatore Benedetto Date: Fri, 12 Oct 2007 22:17:27 +0000 Subject: [PATCH] * Clean up (removing unneeded comment) * Renaming, fixing coding guidelines * Re-writing AddTo method * Removing ohci_software.h file (its content has been moved to ohci.h) but it will probably be deleted in the future. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22522 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/busses/usb/ohci.cpp | 224 +++++++++--------- src/add-ons/kernel/busses/usb/ohci.h | 122 ++++++---- src/add-ons/kernel/busses/usb/ohci_hardware.h | 202 ++++++++-------- 3 files changed, 271 insertions(+), 277 deletions(-) diff --git a/src/add-ons/kernel/busses/usb/ohci.cpp b/src/add-ons/kernel/busses/usb/ohci.cpp index 31dbdadb05..4f8d221c86 100644 --- a/src/add-ons/kernel/busses/usb/ohci.cpp +++ b/src/add-ons/kernel/busses/usb/ohci.cpp @@ -1,67 +1,32 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2005, Jan-Rixt Van Hoye -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// explanation of this file: -// ------------------------- -// -// This is the implementation of the OHCI module for the Haiku USB stack -// It is bases on the hcir1_0a documentation that can be found on www.usb.org -// Some parts are derive from source-files from openbsd, netbsd and linux. -// -// ------------------------------------------------------------------------ +/* + * Copyright 2005-2008, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Jan-Rixt Van Hoye + * Salvatore Benedetto + */ -// --------------------------- -// OHCI:: Includes -// --------------------------- #include #include #include #include #include -// --------------------------- -// OHCI:: Local includes -// --------------------------- - #include "ohci.h" -#include "ohci_hardware.h" -#include "usb_p.h" + +pci_module_info *OHCI::sPCIModule = NULL; //------------------------------------------------------ // OHCI:: Reverse the bits in a value between 0 and 31 // (Section 3.3.2) //------------------------------------------------------ - -static uint8 revbits[OHCI_NO_INTRS] = +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:: These are the OHCI operations that can be done. -// -// parameters: -// - op: operation -//------------------------------------------------------------------------ static int32 ohci_std_ops( int32 op , ... ) @@ -69,14 +34,15 @@ ohci_std_ops( int32 op , ... ) switch (op) { case B_MODULE_INIT: - TRACE(("ohci_module: init the module\n")); + TRACE(("usb_ohci_module: init module\n")); return B_OK; case B_MODULE_UNINIT: - TRACE(("ohci_module: uninit the module\n")); + TRACE(("usb_ohci_module: uninit module\n")); break; default: return EINVAL; } + return B_OK; } @@ -87,67 +53,82 @@ ohci_std_ops( int32 op , ... ) // - &stack: reference to a stack instance form stack.cpp //------------------------------------------------------------------------ -static status_t -ohci_add_to(Stack *stack) +status_t +OHCI::AddTo(Stack *stack) { - status_t status; - pci_info *item; - bool found = false; - int i; - #ifdef TRACE_USB set_dprintf_enabled(true); load_driver_symbols("ohci"); #endif - // - // Try if the PCI module is loaded - // - if( ( status = get_module( B_PCI_MODULE_NAME, (module_info **)&( OHCI::pci_module ) ) ) != B_OK) { - TRACE(("USB_ OHCI: init_hardware(): Get PCI module failed! %lu \n", status)); - return status; + if (!sPCIModule) { + status_t status = get_module(B_PCI_MODULE_NAME, (module_info **)&sPCIModule); + if (status < B_OK) { + TRACE_ERROR(("usb_ohci: AddTo(): getting pci module failed! 0x%08lx\n", + status)); + return status; + } } - TRACE(("usb_ohci init_hardware(): Setting up hardware\n")); - item = new pci_info; - for ( i = 0 ; OHCI::pci_module->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(("USB OHCI: init_hardware(): found with invalid IRQ - check IRQ assignement\n")); + + TRACE(("usb_ohci: AddTo(): setting up hardware\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: AddTo(): found with invalid IRQ -" + " check IRQ assignement\n")); continue; } - TRACE(("USB OHCI: init_hardware(): found at IRQ %u \n", item->u.h0.interrupt_line)); + + TRACE(("usb_ohci: AddTo(): found at IRQ %u\n", + item->u.h0.interrupt_line)); OHCI *bus = new(std::nothrow) OHCI(item, stack); - if (!bus) { delete item; - OHCI::pci_module = NULL; + sPCIModule = NULL; put_module(B_PCI_MODULE_NAME); return B_NO_MEMORY; } - - if (bus->InitCheck() != B_OK) { - TRACE(("usb_ohci: bus failed to initialize...\n")); + + if (bus->InitCheck() < B_OK) { + TRACE_ERROR(("usb_ohci: AddTo(): InitCheck() failed 0x%08lx\n", + bus->InitCheck())); delete bus; continue; } - bus->Start(); - stack->AddBusManager( bus ); + // the bus took it away + item = new(std::nothrow) pci_info; + + bus->Start(); + stack->AddBusManager(bus); found = true; } } - + if (!found) { - TRACE(("USB OHCI: init hardware(): no devices found\n")); - free( item ); - put_module( B_PCI_MODULE_NAME ); + TRACE_ERROR(("usb_ohci: no devices found\n")); + delete item; + put_module(B_PCI_MODULE_NAME); return ENODEV; } - return B_OK; //Hardware found + + delete item; + return B_OK; } + //------------------------------------------------------------------------ // OHCI:: Host controller information // @@ -157,11 +138,11 @@ ohci_add_to(Stack *stack) host_controller_info ohci_module = { { "busses/usb/ohci", - 0, // No flag like B_KEEP_LOADED : the usb module does that + 0, ohci_std_ops }, - NULL , - ohci_add_to + NULL, + OHCI::AddTo }; //------------------------------------------------------------------------ @@ -194,10 +175,10 @@ OHCI::OHCI(pci_info *info, Stack *stack) fRootHubAddress(0), fNumPorts(0) { - fPcii = info; + fPCIInfo = info; fStack = stack; int i; - TRACE(("USB OHCI: constructing new BusManager\n")); + TRACE(("usb_ohci: constructing new BusManager\n")); fInitOK = false; @@ -205,22 +186,22 @@ OHCI::OHCI(pci_info *info, Stack *stack) fInterruptEndpoints[i] = 0; // enable busmaster and memory mapped access - uint16 cmd = OHCI::pci_module->read_pci_config(fPcii->bus, fPcii->device, fPcii->function, PCI_command, 2); + uint16 cmd = sPCIModule->read_pci_config(fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function, PCI_command, 2); cmd &= ~PCI_command_io; cmd |= PCI_command_master | PCI_command_memory; - OHCI::pci_module->write_pci_config(fPcii->bus, fPcii->device, fPcii->function, PCI_command, 2, cmd ); + sPCIModule->write_pci_config(fPCIInfo->bus, fPCIInfo->device, fPCIInfo->function, PCI_command, 2, cmd ); // // 5.1.1.2 map the registers // - addr_t registeroffset = pci_module->read_pci_config(info->bus, + addr_t registeroffset = sPCIModule->read_pci_config(info->bus, info->device, info->function, PCI_base_registers, 4); registeroffset &= PCI_address_memory_32_mask; TRACE(("OHCI: iospace offset: %lx\n" , registeroffset)); fRegisterArea = map_physical_memory("OHCI base registers", (void *)registeroffset, - B_PAGE_SIZE, B_ANY_KERNEL_BLOCK_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_READ_AREA | B_WRITE_AREA, (void **)&fRegisters); + B_PAGE_SIZE, B_ANY_KERNEL_BLOCK_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_READ_AREA | B_WRITE_AREA, (void **)&fRegisterBase); if (fRegisterArea < B_OK) { - TRACE(("USB OHCI: error mapping the registers\n")); + TRACE(("usb_ohci: error mapping the registers\n")); return; } @@ -230,7 +211,7 @@ OHCI::OHCI(pci_info *info, Stack *stack) // Check the revision of the controller. The revision should be 10xh TRACE((" OHCI: Version %ld.%ld%s\n", OHCI_REV_HI(rev), OHCI_REV_LO(rev),OHCI_REV_LEGACY(rev) ? ", legacy support" : "")); if (OHCI_REV_HI(rev) != 1 || OHCI_REV_LO(rev) != 0) { - TRACE(("USB OHCI: Unsupported OHCI revision of the ohci device\n")); + TRACE(("usb_ohci: Unsupported OHCI revision of the ohci device\n")); return; } @@ -239,7 +220,7 @@ OHCI::OHCI(pci_info *info, Stack *stack) fHccaArea = fStack->AllocateArea((void**)&fHcca, &hcca_phy, B_PAGE_SIZE, "OHCI HCCA"); if (fHccaArea < B_OK) { - TRACE(("USB OHCI: Error allocating HCCA block\n")); + TRACE(("usb_ohci: Error allocating HCCA block\n")); return; } memset((void*)fHcca, 0, sizeof(ohci_hcca)); @@ -248,14 +229,14 @@ OHCI::OHCI(pci_info *info, Stack *stack) // 5.1.1.3 Take control of the host controller // if (ReadReg(OHCI_CONTROL) & OHCI_IR) { - TRACE(("USB OHCI: SMM is in control of the host controller\n")); + TRACE(("usb_ohci: SMM is in control of the host controller\n")); WriteReg(OHCI_COMMAND_STATUS, OHCI_OCR); for (int i = 0; i < 100 && (ReadReg(OHCI_CONTROL) & OHCI_IR); i++) snooze(1000); if (ReadReg(OHCI_CONTROL) & OHCI_IR) - TRACE(("USB OHCI: SMM doesn't respond... continueing anyway...\n")); + TRACE(("usb_ohci: SMM doesn't respond... continueing anyway...\n")); } else if (!(ReadReg(OHCI_CONTROL) & OHCI_HCFS_RESET)) { - TRACE(("USB OHCI: BIOS is in control of the host controller\n")); + TRACE(("usb_ohci: BIOS is in control of the host controller\n")); if (!(ReadReg(OHCI_CONTROL) & OHCI_HCFS_OPERATIONAL)) { WriteReg(OHCI_CONTROL, OHCI_HCFS_RESUME); snooze(USB_DELAY_BUS_RESET); @@ -287,9 +268,9 @@ OHCI::OHCI(pci_info *info, Stack *stack) else fInterruptEndpoints[i]->SetNext(fDummyIsochronous); } - for (i = 0; i < OHCI_NO_INTRS; i++) + for (i = 0; i < OHCI_NUMBER_OF_INTERRUPTS; i++) fHcca->hcca_interrupt_table[revbits[i]] = - fInterruptEndpoints[OHCI_NO_EDS-OHCI_NO_INTRS+i]->physicaladdress; + fInterruptEndpoints[OHCI_NO_EDS-OHCI_NUMBER_OF_INTERRUPTS+i]->physicaladdress; //Go to the hardware part of the initialisation uint32 frameinterval = ReadReg(OHCI_FM_INTERVAL); @@ -301,7 +282,7 @@ OHCI::OHCI(pci_info *info, Stack *stack) break; } if (ReadReg(OHCI_COMMAND_STATUS) & OHCI_HCR) { - TRACE(("USB OHCI: Error resetting the host controller\n")); + TRACE(("usb_ohci: Error resetting the host controller\n")); return; } @@ -368,7 +349,7 @@ OHCI::Start() return B_ERROR; if (!(ReadReg(OHCI_CONTROL) & OHCI_HCFS_OPERATIONAL)) { - TRACE(("USB OHCI::Start(): Controller not started. TODO: find out what happens.\n")); + TRACE(("usb_ohci::Start(): Controller not started. TODO: find out what happens.\n")); return B_ERROR; } @@ -377,17 +358,17 @@ OHCI::Start() fRootHub = new(std::nothrow) OHCIRootHub(this, fRootHubAddress); if (!fRootHub) { - TRACE_ERROR(("USB OHCI::Start(): no memory to allocate root hub\n")); + TRACE_ERROR(("usb_ohci::Start(): no memory to allocate root hub\n")); return B_NO_MEMORY; } if (fRootHub->InitCheck() < B_OK) { - TRACE_ERROR(("USB OHCI::Start(): root hub failed init check\n")); + TRACE_ERROR(("usb_ohci::Start(): root hub failed init check\n")); return B_ERROR; } SetRootHub(fRootHub); - TRACE(("USB OHCI::Start(): Succesful start\n")); + TRACE(("usb_ohci::Start(): Succesful start\n")); return B_OK; } @@ -525,7 +506,7 @@ OHCI::AllocateEndpoint() //Add a NULL list by creating one TransferDescriptor TransferDescriptor *trans = new(std::nothrow) TransferDescriptor; endpoint->head = endpoint->tail = trans; - endpoint->ed->headp = endpoint->ed->tailp = trans->physicaladdress; + endpoint->ed->head_pointer = endpoint->ed->tail_pointer = trans->physicaladdress; return endpoint; } @@ -544,12 +525,12 @@ OHCI::AllocateTransfer() TRACE(("OHCI::%s()\n", __FUNCTION__)); TransferDescriptor *transfer = new TransferDescriptor; void *phy; - if (fStack->AllocateChunk((void **)&transfer->td, &phy, sizeof(ohci_transfer_descriptor)) != B_OK) { + if (fStack->AllocateChunk((void **)&transfer->td, &phy, sizeof(ohci_general_transfer_descriptor)) != B_OK) { TRACE(("OHCI::AllocateTransfer(): Error Allocating Transfer\n")); return 0; } transfer->physicaladdress = (addr_t)phy; - memset((void *)transfer->td, 0, sizeof(ohci_transfer_descriptor)); + memset((void *)transfer->td, 0, sizeof(ohci_general_transfer_descriptor)); return transfer; } @@ -557,7 +538,7 @@ void OHCI::FreeTransfer(TransferDescriptor *trans) { TRACE(("OHCI::%s(%p)\n", __FUNCTION__, trans)); - fStack->FreeChunk((void *)trans->td, (void *) trans->physicaladdress, sizeof(ohci_transfer_descriptor)); + fStack->FreeChunk((void *)trans->td, (void *) trans->physicaladdress, sizeof(ohci_general_transfer_descriptor)); delete trans; } @@ -579,21 +560,21 @@ OHCI::InsertEndpointForPipe(Pipe *p) uint32 properties = 0; //Set the device address - properties |= OHCI_ENDPOINT_SET_FA(p->DeviceAddress()); + properties |= OHCI_ENDPOINT_SET_DEVICE_ADDRESS(p->DeviceAddress()); //Set the endpoint number - properties |= OHCI_ENDPOINT_SET_EN(p->EndpointAddress()); + properties |= OHCI_ENDPOINT_SET_ENDPOINT_NUMBER(p->EndpointAddress()); //Set the direction switch (p->Direction()) { case Pipe::In: - properties |= OHCI_ENDPOINT_DIR_IN; + properties |= OHCI_ENDPOINT_DIRECTION_IN; break; case Pipe::Out: - properties |= OHCI_ENDPOINT_DIR_OUT; + properties |= OHCI_ENDPOINT_DIRECTION_OUT; break; case Pipe::Default: - properties |= OHCI_ENDPOINT_DIR_TD; + properties |= OHCI_ENDPOINT_DIRECTION_DESCRIPTOR; break; default: //TODO: error @@ -616,10 +597,10 @@ OHCI::InsertEndpointForPipe(Pipe *p) //Assign the format. Isochronous endpoints require this switch if (p->Type() & USB_OBJECT_ISO_PIPE) - properties |= OHCI_ENDPOINT_FORMAT_ISO; + properties |= OHCI_ENDPOINT_ISOCHRONOUS_FORMAT; //Set the maximum packet size - properties |= OHCI_ENDPOINT_SET_MAXP(p->MaxPacketSize()); + properties |= OHCI_ENDPOINT_SET_MAX_PACKET_SIZE(p->MaxPacketSize()); endpoint->ed->flags = properties; } @@ -653,18 +634,25 @@ OHCI::InsertEndpointForPipe(Pipe *p) return B_OK; } -pci_module_info *OHCI::pci_module = 0; +pci_module_info *sPCIModule = 0; void OHCI::WriteReg(uint32 reg, uint32 value) { TRACE(("OHCI::%s(%lu, %lu)\n", __FUNCTION__, reg, value)); - *(volatile uint32 *)(fRegisters + reg) = value; + *(volatile uint32 *)(fRegisterBase + reg) = value; } uint32 OHCI::ReadReg(uint32 reg) { TRACE(("OHCI::%s(%lu)\n", __FUNCTION__, reg)); - return *(volatile uint32 *)(fRegisters + reg); + return *(volatile uint32 *)(fRegisterBase + reg); } + +status_t +OHCI::CancelQueuedTransfers(Pipe *pipe) +{ + return B_ERROR; +} + diff --git a/src/add-ons/kernel/busses/usb/ohci.h b/src/add-ons/kernel/busses/usb/ohci.h index c9a0fda9aa..1d8f3fb954 100644 --- a/src/add-ons/kernel/busses/usb/ohci.h +++ b/src/add-ons/kernel/busses/usb/ohci.h @@ -1,42 +1,52 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2005, Jan-Rixt Van Hoye -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -//------------------------------------------------------------------------------- - +/* + * Copyright 2005-2008, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Jan-Rixt Van Hoye + * Salvatore Benedetto + */ #ifndef OHCI_H #define OHCI_H -// --------------------------- -// OHCI:: Includes -// --------------------------- - #include "usb_p.h" -#include "ohci_software.h" +#include "ohci_hardware.h" +#include struct pci_info; struct pci_module_info; class OHCIRootHub; + struct Endpoint; struct TransferDescriptor; +// -------------------------------------- +// OHCI:: Software isonchronous +// transfer descriptor +// -------------------------------------- +typedef struct hcd_soft_itransfer +{ + ohci_isochronous_transfer_descriptor itd; + struct hcd_soft_itransfer *nextitd; // mirrors nexttd in ITD + struct hcd_soft_itransfer *dnext; // next in done list + addr_t physaddr; // physical address to the host controller isonchronous transfer + //LIST_ENTRY(hcd_soft_itransfer) hnext; + uint16 flags; // flags +#ifdef DIAGNOSTIC + char isdone; // is the transfer done? +#endif +}hcd_soft_itransfer; + +#define OHCI_SITD_SIZE ((sizeof (struct hcd_soft_itransfer) + OHCI_ITD_ALIGN - 1) / OHCI_ITD_ALIGN * OHCI_ITD_ALIGN) +#define OHCI_SITD_CHUNK 64 + +// ------------------------------------------ +// OHCI:: Number of enpoint descriptors (63) +// ------------------------------------------ + +#define OHCI_NO_EDS (2 * OHCI_NUMBER_OF_INTERRUPTS - 1) + // -------------------------------- // OHCI: The OHCI class derived // from the BusManager @@ -46,31 +56,40 @@ class OHCI : public BusManager { friend class OHCIRootHub; public: - - OHCI(pci_info *info, Stack *stack); - ~OHCI(); - status_t Start(); - status_t SubmitTransfer(Transfer *t); //Override from BusManager. - status_t NotifyPipeChange(Pipe *pipe, //Override from BusManager. - usb_change change); - static pci_module_info *pci_module; // Global data for the module. + OHCI(pci_info *info, Stack *stack); + ~OHCI(); - status_t GetPortStatus(uint8 index, usb_port_status *status); - status_t ClearPortFeature(uint8 index, uint16 feature); - status_t SetPortFeature(uint8 index, uint16 feature); - - uint8 PortCount() { return fNumPorts; }; + status_t Start(); +virtual status_t SubmitTransfer(Transfer *transfer); +virtual status_t CancelQueuedTransfers(Pipe *pipe); + +virtual status_t NotifyPipeChange(Pipe *pipe, + usb_change change); + +static status_t AddTo(Stack *stack); + + // Port operations + status_t GetPortStatus(uint8 index, usb_port_status *status); + status_t SetPortFeature(uint8 index, uint16 feature); + status_t ClearPortFeature(uint8 index, uint16 feature); + + uint8 PortCount() { return fNumPorts; }; private: - inline void WriteReg(uint32 reg, uint32 value); - inline uint32 ReadReg(uint32 reg); + // Register functions +inline void WriteReg(uint32 reg, uint32 value); +inline uint32 ReadReg(uint32 reg); // Global - pci_info *fPcii; // pci-info struct - Stack *fStack; // Pointer to the stack - uint8 *fRegisters; // Base address of the operational registers - area_id fRegisterArea; // Area id of the +static pci_module_info *sPCIModule; + + uint32 *fRegisterBase; + pci_info *fPCIInfo; + Stack *fStack; + + area_id fRegisterArea; + // HCCA area_id fHccaArea; struct ohci_hcca *fHcca; // The HCCA structure for the interupt communication @@ -79,10 +98,6 @@ private: Endpoint *fDummyControl; Endpoint *fDummyBulk; Endpoint *fDummyIsochronous; - // Root Hub - OHCIRootHub *fRootHub; // the root hub - uint8 fRootHubAddress; // the usb address of the roothub - uint8 fNumPorts; // the number of ports // functions Endpoint *AllocateEndpoint(); // allocate memory for an endpoint void FreeEndpoint(Endpoint *end); // Free endpoint @@ -90,6 +105,11 @@ private: void FreeTransfer(TransferDescriptor *trans); // Free transfer status_t InsertEndpointForPipe(Pipe *p); + + // Root Hub + OHCIRootHub *fRootHub; + uint8 fRootHubAddress; + uint8 fNumPorts; }; // -------------------------------- @@ -132,7 +152,7 @@ struct Endpoint struct TransferDescriptor { addr_t physicaladdress; - ohci_transfer_descriptor *td; + ohci_general_transfer_descriptor *td; }; #endif // OHCI_H diff --git a/src/add-ons/kernel/busses/usb/ohci_hardware.h b/src/add-ons/kernel/busses/usb/ohci_hardware.h index 89e1447179..024a6c9068 100644 --- a/src/add-ons/kernel/busses/usb/ohci_hardware.h +++ b/src/add-ons/kernel/busses/usb/ohci_hardware.h @@ -1,24 +1,11 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2005, Jan-Rixt Van Hoye -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -//------------------------------------------------------------------------------ +/* + * Copyright 2005-2008, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Jan-Rixt Van Hoye + * Salvatore Benedetto + */ #ifndef OHCI_HARD_H #define OHCI_HARD_H @@ -31,9 +18,9 @@ // Revision register (section 7.1.1) // -------------------------------- -#define OHCI_REVISION 0x00 // OHCI revision -#define OHCI_REV_LO(rev) ((rev)&0x0f) -#define OHCI_REV_HI(rev) (((rev)>>4)&0x03) +#define OHCI_REVISION 0x00 +#define OHCI_REV_LO(rev) ((rev) & 0x0f) +#define OHCI_REV_HI(rev) (((rev) >> 4) & 0x03) #define OHCI_REV_LEGACY(rev) ((rev) & 0x10) // -------------------------------- @@ -71,7 +58,7 @@ #define OHCI_SOC_MASK 0x00030000 // Scheduling Overrun Count // -------------------------------- -// Interupt status register (section 7.1.4) +// Interrupt status register (section 7.1.4) // -------------------------------- #define OHCI_INTERRUPT_STATUS 0x0c @@ -273,11 +260,11 @@ typedef uint32 ohci_physaddr_t; // HCCA structure (section 4.4) // -------------------------------- -#define OHCI_NO_INTRS 32 +#define OHCI_NUMBER_OF_INTERRUPTS 32 -struct ohci_hcca +typedef struct ohci_hcca { - addr_t hcca_interrupt_table[OHCI_NO_INTRS]; + addr_t hcca_interrupt_table[OHCI_NUMBER_OF_INTERRUPTS]; uint32 hcca_frame_number; addr_t hcca_done_head; uint8 hcca_reserved_for_hc[116]; @@ -297,114 +284,113 @@ struct ohci_hcca typedef struct ohci_endpoint_descriptor { uint32 flags; - addr_t tailp; // Queue tail pointer - addr_t headp; // Queue head pointer - addr_t next_endpoint; // Next endpoint in the list + uint32 tail_pointer; // Queue tail pointer + uint32 head_pointer; // Queue head pointer + uint32 next_endpoint; // Next endpoint in the list }; -#define OHCI_ENDPOINT_GET_FA(s) ((s) & 0x7f) -#define OHCI_ENDPOINT_ADDRMASK 0x0000007f -#define OHCI_ENDPOINT_SET_FA(s) (s) -#define OHCI_ENDPOINT_GET_EN(s) (((s) >> 7) & 0xf) -#define OHCI_ENDPOINT_SET_EN(s) ((s) << 7) -#define OHCI_ENDPOINT_DIR_MASK 0x00001800 -#define OHCI_ENDPOINT_DIR_TD 0x00000000 -#define OHCI_ENDPOINT_DIR_OUT 0x00000800 -#define OHCI_ENDPOINT_DIR_IN 0x00001000 -#define OHCI_ENDPOINT_SPEED 0x00002000 -#define OHCI_ENDPOINT_SKIP 0x00004000 -#define OHCI_ENDPOINT_FORMAT_GEN 0x00000000 -#define OHCI_ENDPOINT_FORMAT_ISO 0x00008000 -#define OHCI_ENDPOINT_GET_MAXP(s) (((s) >> 16) & 0x07ff) -#define OHCI_ENDPOINT_SET_MAXP(s) ((s) << 16) -#define OHCI_ENDPOINT_MAXPMASK (0x7ff << 16) - -#define OHCI_HALTED 0x00000001 -#define OHCI_TOGGLECARRY 0x00000002 -#define OHCI_HEADMASK 0xfffffffc +#define OHCI_ENDPOINT_ADDRESS_MASK 0x0000007f +#define OHCI_ENDPOINT_GET_DEVICE_ADDRESS(s) ((s) & 0x7f) +#define OHCI_ENDPOINT_SET_DEVICE_ADDRESS(s) (s) +#define OHCI_ENDPOINT_GET_ENDPOINT_NUMBER(s) (((s) >> 7) & 0xf) +#define OHCI_ENDPOINT_SET_ENDPOINT_NUMBER(s) ((s) << 7) +#define OHCI_ENDPOINT_DIRECTION_MASK 0x00001800 +#define OHCI_ENDPOINT_DIRECTION_DESCRIPTOR 0x00000000 +#define OHCI_ENDPOINT_DIRECTION_OUT 0x00000800 +#define OHCI_ENDPOINT_DIRECTION_IN 0x00001000 +#define OHCI_ENDPOINT_SPEED 0x00002000 +#define OHCI_ENDPOINT_SKIP 0x00004000 +#define OHCI_ENDPOINT_GENERAL_FORMAT 0x00000000 +#define OHCI_ENDPOINT_ISOCHRONOUS_FORMAT 0x00008000 +#define OHCI_ENDPOINT_MAX_PACKET_SIZE_MASK (0x7ff << 16) +#define OHCI_ENDPOINT_GET_MAX_PACKET_SIZE(s) (((s) >> 16) & 0x07ff) +#define OHCI_ENDPOINT_SET_MAX_PACKET_SIZE(s) ((s) << 16) +#define OHCI_ENDPOINT_HALTED 0x00000001 +#define OHCI_ENDPOINT_TOGGLE_CARRY 0x00000002 +#define OHCI_ENDPOINT_HEAD_MASK 0xfffffffc // -------------------------------- // General transfer descriptor structure (section 4.3.1) // -------------------------------- -typedef struct ohci_transfer_descriptor +typedef struct ohci_general_transfer_descriptor { uint32 flags; - addr_t td_cbp; // Current Buffer Pointer - addr_t td_nexttd; // Next Transfer Descriptor - addr_t td_be; // Buffer End -} ; + uint32 buffer_phy; // Physical buffer pointer + uint32 next_descriptor; // Next transfer descriptor + uint32 last_byte_address; // Physical buffer end +}; -#define OHCI_TD_R 0x00040000 // Buffer Rounding -#define OHCI_TD_DP_MASK 0x00180000 // Direction / PID -#define OHCI_TD_SETUP 0x00000000 -#define OHCI_TD_OUT 0x00080000 -#define OHCI_TD_IN 0x00100000 -#define OHCI_TD_GET_DI(x) (((x) >> 21) & 7) // Delay Interrupt -#define OHCI_TD_SET_DI(x) ((x) << 21) -#define OHCI_TD_NOINTR 0x00e00000 -#define OHCI_TD_INTR_MASK 0x00e00000 -#define OHCI_TD_TOGGLE_CARRY 0x00000000 -#define OHCI_TD_TOGGLE_0 0x02000000 -#define OHCI_TD_TOGGLE_1 0x03000000 -#define OHCI_TD_TOGGLE_MASK 0x03000000 -#define OHCI_TD_GET_EC(x) (((x) >> 26) & 3) // Error Count -#define OHCI_TD_GET_CC(x) ((x) >> 28) // Condition Code -#define OHCI_TD_NOCC 0xf0000000 +#define OHCI_BUFFER_ROUNDING 0x00040000 // Buffer Rounding +#define OHCI_TD_DIRECTION_PID_MASK 0x00180000 // Direction / PID +#define OHCI_TD_DIRECTION_PID_SETUP 0x00000000 +#define OHCI_TD_DIRECTION_PID_OUT 0x00080000 +#define OHCI_TD_DIRECTION_PID_IN 0x00100000 +#define OHCI_TD_GET_DELAY_INTERRUPT(x) (((x) >> 21) & 7) // Delay Interrupt +#define OHCI_TD_SET_DELAY_INTERRUPT(x) ((x) << 21) +#define OHCI_TD_NO_INTERRUPT 0x00e00000 +#define OHCI_TD_INTERRUPT_MASK 0x00e00000 +#define OHCI_TD_TOGGLE_CARRY 0x00000000 +#define OHCI_TD_TOGGLE_0 0x02000000 +#define OHCI_TD_TOGGLE_1 0x03000000 +#define OHCI_TD_TOGGLE_MASK 0x03000000 +#define OHCI_TD_GET_ERROR_COUNT(x) (((x) >> 26) & 3) // Error Count +#define OHCI_TD_GET_CONDITION_CODE(x) ((x) >> 28) // Condition Code +#define OHCI_TD_NO_CONDITION_CODE 0xf0000000 -#define OHCI_TD_ALIGN 16 +#define OHCI_GENERAL_TD_ALIGN 16 // -------------------------------- // Isonchronous transfer descriptor structure (section 4.3.2) // -------------------------------- #define OHCI_ITD_NOFFSET 8 -typedef struct hc_itransfer_descriptor +typedef struct ohci_isochronous_transfer_descriptor { - uint32 itd_flags; - addr_t itd_bp0; // Buffer Page 0 - addr_t itd_nextitd; // Next Isochronous Transfer Descriptor - addr_t itd_be; // Buffer End - uint16 itd_offset[OHCI_ITD_NOFFSET]; // Buffer offsets - + uint32 flags; + uint32 buffer_page_byte_0; // Physical page number of byte 0 + uint32 next_descriptor; // Next isochronous transfer descriptor + uint32 last_byte_address; // Physical buffer end + uint16 offset[OHCI_ITD_NOFFSET]; // Buffer offsets }; -#define OHCI_ITD_GET_SF(x) ((x) & 0x0000ffff) -#define OHCI_ITD_SET_SF(x) ((x) & 0xffff) -#define OHCI_ITD_GET_DI(x) (((x) >> 21) & 7) // Delay Interrupt -#define OHCI_ITD_SET_DI(x) ((x) << 21) -#define OHCI_ITD_NOINTR 0x00e00000 -#define OHCI_ITD_GET_FC(x) ((((x) >> 24) & 7)+1) // Frame Count -#define OHCI_ITD_SET_FC(x) (((x)-1) << 24) -#define OHCI_ITD_GET_CC(x) ((x) >> 28) // Condition Code -#define OHCI_ITD_NOCC 0xf0000000 +#define OHCI_ITD_GET_STARTING_FRAME(x) ((x) & 0x0000ffff) +#define OHCI_ITD_SET_STARTING_FRAME(x) ((x) & 0xffff) +#define OHCI_ITD_GET_DELAY_INTERRUPT(x) (((x) >> 21) & 7) +#define OHCI_ITD_SET_DELAY_INTERRUPT(x) ((x) << 21) +#define OHCI_ITD_NO_INTERRUPT 0x00e00000 +#define OHCI_ITD_GET_FRAME_COUNT(x) ((((x) >> 24) & 7) + 1) +#define OHCI_ITD_SET_FRAME_COUNT(x) (((x) - 1) << 24) +#define OHCI_ITD_GET_CONDITION_CODE(x) ((x) >> 28) +#define OHCI_ITD_NO_CONDITION_CODE 0xf0000000 -#define itd_pswn itd_offset // Packet Status Word -#define OHCI_ITD_PAGE_SELECT 0x00001000 -#define OHCI_ITD_MK_OFFS(len) (0xe000 | ((len) & 0x1fff)) -#define OHCI_ITD_PSW_LENGTH(x) ((x) & 0xfff) // Transfer length -#define OHCI_ITD_PSW_GET_CC(x) ((x) >> 12) // Condition Code +// TO FIX +#define itd_pswn itd_offset // Packet Status Word +#define OHCI_ITD_PAGE_SELECT 0x00001000 +#define OHCI_ITD_MK_OFFS(len) (0xe000 | ((len) & 0x1fff)) +#define OHCI_ITD_GET_BUFFER_LENGTH(x) ((x) & 0xfff) // Transfer length +#define OHCI_ITD_GET_BUFFER_CONDITION_CODE(x) ((x) >> 12) // Condition Code -#define OHCI_ITD_ALIGN 32 +#define OHCI_ISOCHRONOUS_TD_ALIGN 32 // -------------------------------- // Completion Codes (section 4.3.3) // -------------------------------- -#define OHCI_CC_NO_ERROR 0 -#define OHCI_CC_CRC 1 -#define OHCI_CC_BIT_STUFFING 2 -#define OHCI_CC_DATA_TOGGLE_MISMATCH 3 -#define OHCI_CC_STALL 4 -#define OHCI_CC_DEVICE_NOT_RESPONDING 5 -#define OHCI_CC_PID_CHECK_FAILURE 6 -#define OHCI_CC_UNEXPECTED_PID 7 -#define OHCI_CC_DATA_OVERRUN 8 -#define OHCI_CC_DATA_UNDERRUN 9 -#define OHCI_CC_BUFFER_OVERRUN 12 -#define OHCI_CC_BUFFER_UNDERRUN 13 -#define OHCI_CC_NOT_ACCESSED 15 +#define OHCI_NO_ERROR 0 +#define OHCI_CRC 1 +#define OHCI_BIT_STUFFING 2 +#define OHCI_DATA_TOGGLE_MISMATCH 3 +#define OHCI_STALL 4 +#define OHCI_DEVICE_NOT_RESPONDING 5 +#define OHCI_PID_CHECK_FAILURE 6 +#define OHCI_UNEXPECTED_PID 7 +#define OHCI_DATA_OVERRUN 8 +#define OHCI_DATA_UNDERRUN 9 +#define OHCI_BUFFER_OVERRUN 12 +#define OHCI_BUFFER_UNDERRUN 13 +#define OHCI_NOT_ACCESSED 15 // -------------------------------- // Some delay needed when changing