From 1a2e81b52cfafb4a0ec65f935ce32b69923638dd Mon Sep 17 00:00:00 2001 From: Niels Sascha Reedijk Date: Mon, 19 Jul 2004 10:18:35 +0000 Subject: [PATCH] Summary: Merge in changes in busses / bus-manager loading Keywords: Patches applied: * n.reedijk@planet.nl--nielx-2003/usb-busmanager--development--0.1--patch-24 Rename AllocArea to AllocateArea for consistency * n.reedijk@planet.nl--nielx-2003/usb-busmanager--development--0.1--patch-25 Make the memory allocation routines more global and share it with the hc * n.reedijk@planet.nl--nielx-2003/usb-busmanager--development--0.1--patch-26 Change from uint32 to addr_t to be safe on 64 bit in the future * n.reedijk@planet.nl--nielx-2003/usb-busmanager--development--0.1--patch-27 AllocateChunk returns an area_id * n.reedijk@planet.nl--nielx-2003/usb-busmanager--development--0.1--patch-28 Really fixing AllocateChunk now * n.reedijk@planet.nl--nielx-2003/usb-busmanager--development--0.1--patch-29 Fix a bug where data was uninitialised when used and load debug symbols * n.reedijk@planet.nl--nielx-2003/usb-busmanager--development--0.1--patch-30 Integrate host_controller.h * n.reedijk@planet.nl--nielx-2003/usb-busmanager--development--0.1--patch-31 Many changes to accomodate for new bus_manager handling git-svn-id: file:///srv/svn/repos/haiku/trunk/current@8421 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/bus_managers/usb/BusManager.cpp | 34 +++-- .../kernel/bus_managers/usb/Device.cpp | 8 +- src/add-ons/kernel/bus_managers/usb/Hub.cpp | 9 +- src/add-ons/kernel/bus_managers/usb/Jamfile | 9 +- src/add-ons/kernel/bus_managers/usb/Pipe.cpp | 48 ++++--- src/add-ons/kernel/bus_managers/usb/Stack.cpp | 44 +++--- .../kernel/bus_managers/usb/Transfer.cpp | 21 +-- .../kernel/bus_managers/usb/host_controller.h | 125 ----------------- src/add-ons/kernel/bus_managers/usb/usb.cpp | 11 +- src/add-ons/kernel/bus_managers/usb/usb_p.h | 127 ++++++++++++++++-- 10 files changed, 226 insertions(+), 210 deletions(-) delete mode 100644 src/add-ons/kernel/bus_managers/usb/host_controller.h diff --git a/src/add-ons/kernel/bus_managers/usb/BusManager.cpp b/src/add-ons/kernel/bus_managers/usb/BusManager.cpp index f64187d392..43b1222852 100644 --- a/src/add-ons/kernel/bus_managers/usb/BusManager.cpp +++ b/src/add-ons/kernel/bus_managers/usb/BusManager.cpp @@ -30,6 +30,9 @@ int32 usb_explore_thread( void *data ) { Hub *roothub = (Hub *)data; + if ( roothub == 0 ) + return B_ERROR; + while (true ) { //Go to the hubs @@ -40,9 +43,8 @@ int32 usb_explore_thread( void *data ) } -BusManager::BusManager( host_controller_info *info ) +BusManager::BusManager() { - hcpointer = info; m_initok = false; m_roothub = 0; @@ -56,15 +58,9 @@ BusManager::BusManager( host_controller_info *info ) memset( &m_devicemap , false , 128 ); // Set up the default pipes - m_defaultPipe = new ControlPipe( this , 0 , Default , NormalSpeed , 0 ); - m_defaultLowSpeedPipe = new ControlPipe( this , 0 , Default , LowSpeed , 0 ); + m_defaultPipe = new ControlPipe( this , 0 , Pipe::Default , Pipe::NormalSpeed , 0 ); + m_defaultLowSpeedPipe = new ControlPipe( this , 0 , Pipe::Default , Pipe::LowSpeed , 0 ); - // Set up the new root hub - AllocateNewDevice( 0 , false ); - - if( m_roothub == 0 ) - return; - // Start the 'explore thread' m_explore_thread = spawn_kernel_thread( usb_explore_thread , "usb_busmanager_explore" , B_LOW_PRIORITY , (void *)m_roothub ); @@ -75,7 +71,6 @@ BusManager::BusManager( host_controller_info *info ) BusManager::~BusManager() { - put_module( hcpointer->info.name ); } status_t BusManager::InitCheck() @@ -118,7 +113,7 @@ Device * BusManager::AllocateNewDevice( Device *parent , bool lowspeed ) } //Create a temporary pipe - ControlPipe pipe( this , devicenum , Default , LowSpeed , 0 ); + ControlPipe pipe( this , devicenum , Pipe::Default , Pipe::LowSpeed , 0 ); //3. Get the device descriptor // Just retrieve the first 8 bytes of the descriptor -> minimum supported @@ -173,3 +168,18 @@ int8 BusManager::AllocateAddress() return devicenum; } +status_t BusManager::Start() +{ + if ( InitCheck() != B_OK ) + return InitCheck(); + + // Start the 'explore thread' + m_explore_thread = spawn_kernel_thread( usb_explore_thread , "usb_busmanager_explore" , + B_LOW_PRIORITY , (void *)m_roothub ); + resume_thread( m_explore_thread ); +} + +status_t BusManager::SubmitTransfer( Transfer &t ) +{ + return B_ERROR; +}; diff --git a/src/add-ons/kernel/bus_managers/usb/Device.cpp b/src/add-ons/kernel/bus_managers/usb/Device.cpp index 6557ad930f..f64e70e547 100644 --- a/src/add-ons/kernel/bus_managers/usb/Device.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Device.cpp @@ -50,7 +50,7 @@ Device::Device( BusManager *bus , Device *parent , usb_device_descriptor &desc , m_maxpacketin[0] = m_maxpacketout[0] = m_device_descriptor.max_packet_size_0; m_device_descriptor = desc; m_lowspeed = lowspeed; - m_defaultPipe = new ControlPipe( this , Default , 0 ); + m_defaultPipe = new ControlPipe( this , Pipe::Default , 0 ); //4. Get the device descriptor // We already have a part of it, but we want it all @@ -65,7 +65,6 @@ Device::Device( BusManager *bus , Device *parent , usb_device_descriptor &desc , dprintf( "usb Device %d: Vendor id: %d , Product id: %d\n" , devicenum , m_device_descriptor.vendor_id , m_device_descriptor.product_id ); - // 4. Get the configurations m_configurations = (usb_configuration_descriptor *)malloc( m_device_descriptor.num_configurations * sizeof (usb_configuration_descriptor) ); @@ -90,13 +89,15 @@ Device::Device( BusManager *bus , Device *parent , usb_device_descriptor &desc , SetConfiguration( 0 ); //6. TODO: Find drivers for the device + + m_initok = true; } //Returns the length that was copied (index gives the number of the config) int16 Device::GetDescriptor( uint8 descriptor_type , uint16 index , void *buffer , size_t size ) { - size_t actual_length; + size_t actual_length = 0; m_defaultPipe->SendRequest(USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD , //Type USB_REQUEST_GET_DESCRIPTOR , //Request ( descriptor_type << 8 ) | index , //Value @@ -124,4 +125,5 @@ status_t Device::SetConfiguration( uint8 value ) //Set current configuration m_current_configuration = m_configurations + value; + return B_OK; } diff --git a/src/add-ons/kernel/bus_managers/usb/Hub.cpp b/src/add-ons/kernel/bus_managers/usb/Hub.cpp index 4f27bcaed2..0d5ec73834 100644 --- a/src/add-ons/kernel/bus_managers/usb/Hub.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Hub.cpp @@ -25,9 +25,16 @@ Hub::Hub( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 : Device ( bus , parent , desc , devicenum , lowspeed ) { dprintf( "USB Hub is being initialised\n" ); - m_initok = false; // We're not yet ready! size_t actual_length; + if ( m_initok == false ) + { + dprintf( "Hub::Hub() Device failed to initialize\n" ); + return; + } + + //Set to false again for the hub init. + m_initok = false; if( m_device_descriptor.device_subclass != 0 || m_device_descriptor.device_protocol != 0 ) { diff --git a/src/add-ons/kernel/bus_managers/usb/Jamfile b/src/add-ons/kernel/bus_managers/usb/Jamfile index 69457a535d..49804bc604 100644 --- a/src/add-ons/kernel/bus_managers/usb/Jamfile +++ b/src/add-ons/kernel/bus_managers/usb/Jamfile @@ -4,12 +4,17 @@ UsePrivateHeaders [ FDirName kernel ] ; AddResources usb : usb.rdef ; -R5KernelAddon usb : [ FDirName kernel bus_managers ] : - usb.cpp +R5KernelStaticLibrary usb : Stack.cpp Device.cpp Hub.cpp BusManager.cpp Transfer.cpp Pipe.cpp + ; + +R5KernelAddon usb : [ FDirName kernel bus_managers ] : + usb.cpp ; + +LinkSharedOSLibs usb : libusb.a ; \ No newline at end of file diff --git a/src/add-ons/kernel/bus_managers/usb/Pipe.cpp b/src/add-ons/kernel/bus_managers/usb/Pipe.cpp index 33ea88db25..0e445febdd 100644 --- a/src/add-ons/kernel/bus_managers/usb/Pipe.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Pipe.cpp @@ -23,26 +23,23 @@ Pipe::Pipe( Device *dev , Direction &dir , uint8 &endpointaddress ) { - d = new usb_pipe_t; - - d->direction = dir; + m_direction = dir; m_device = dev; - - if ( m_device != NULL ) //Default pipe - { - d->deviceid = dev->m_devicenum; - if ( dev->m_lowspeed == true ) - d->speed = LowSpeed; - else - d->speed = NormalSpeed; - m_bus = m_device->m_bus; - } - d->endpoint = endpointaddress; + m_endpoint = endpointaddress; + if ( m_device != NULL ) + m_bus = m_device->GetBusManager(); } Pipe::~Pipe() { - delete d; +} + +int8 Pipe::GetDeviceAddress() +{ + if ( m_device == NULL ) + return -1; + else + return m_device->GetAddress(); } ControlPipe::ControlPipe( Device *dev , Direction dir , uint8 endpointaddress ) @@ -51,12 +48,23 @@ ControlPipe::ControlPipe( Device *dev , Direction dir , uint8 endpointaddress ) } -ControlPipe::ControlPipe( BusManager *bus , int8 dev_id , Direction dir , Speed speed , uint8 endpointaddress ) +ControlPipe::ControlPipe( BusManager *bus , int8 dev_address , Direction dir , Speed speed , uint8 endpointaddress ) : Pipe( NULL , dir , endpointaddress ) { m_bus = bus; - d->deviceid = dev_id; - d->speed = speed; + m_deviceaddress = dev_address; + if ( speed == LowSpeed ) + m_lowspeed = true; + else + m_lowspeed = false; +} + +int8 ControlPipe::GetDeviceAddress() +{ + if ( m_device == NULL ) + return m_deviceaddress; + else + return m_device->GetAddress(); } status_t ControlPipe::SendRequest( uint8 request_type , uint8 request , uint16 value , @@ -83,13 +91,13 @@ status_t ControlPipe::SendControlMessage( usb_request_data *command , void *data bigtime_t timeout ) { // this method should build an usb packet (new class) with the needed data - Transfer transfer( *this ); + Transfer transfer( this ); transfer.SetRequestData( command ); transfer.SetBuffer( (uint8 *)data ); transfer.SetBufferLength( data_length ); transfer.SetActualLength( actual_length ); - status_t retval = m_bus->hcpointer->SubmitPacket( transfer.GetData() ); + status_t retval = m_bus->SubmitTransfer( transfer ); return retval; } diff --git a/src/add-ons/kernel/bus_managers/usb/Stack.cpp b/src/add-ons/kernel/bus_managers/usb/Stack.cpp index 1988ff9f0a..7662690a92 100644 --- a/src/add-ons/kernel/bus_managers/usb/Stack.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Stack.cpp @@ -29,13 +29,16 @@ Stack::Stack() { //Init the master lock - m_master = create_sem( 0 , "usb master lock" ); + m_master = create_sem( 1 , "usb master lock" ); set_sem_owner( m_master , B_SYSTEM_TEAM ); //Create the data lock - m_datalock = create_sem( 0 , "usb data lock" ); + m_datalock = create_sem( 1 , "usb data lock" ); set_sem_owner( m_datalock , B_SYSTEM_TEAM ); + //Set the global "data" variable to this + data = this; + //Initialise the memory chunks: create 8, 16 and 32 byte-heaps //NOTE: This is probably the most ugly code you will see in the //whole stack. Unfortunately this is needed because of the fact @@ -44,7 +47,7 @@ Stack::Stack() // 8-byte heap m_areafreecount[0] = 0; - m_areas[0] = AllocArea( &m_logical[0] , &m_physical[0] , B_PAGE_SIZE , + m_areas[0] = AllocateArea( &m_logical[0] , &m_physical[0] , B_PAGE_SIZE , "8-byte chunk area" ); if ( m_areas[0] < B_OK ) { @@ -56,17 +59,17 @@ Stack::Stack() for ( int i = 0 ; i < B_PAGE_SIZE/8 ; i++ ) { - memory_chunk *chunk = (memory_chunk *)((uint32)m_logical[0] + 8 * i); - chunk->physical = (void *)((uint32)m_physical[0] + 8 * i); + memory_chunk *chunk = (memory_chunk *)((addr_t)m_logical[0] + 8 * i); + chunk->physical = (void *)((addr_t)m_physical[0] + 8 * i); if ( i != B_PAGE_SIZE / 8 - 1 ) - chunk->next_item = (void *)((uint32)m_logical[0] + 8 * ( i + 1 ) ); + chunk->next_item = (void *)((addr_t)m_logical[0] + 8 * ( i + 1 ) ); else chunk->next_item = NULL; } // 16-byte heap m_areafreecount[1] = 0; - m_areas[1] = AllocArea( &m_logical[1] , &m_physical[1] , B_PAGE_SIZE , + m_areas[1] = AllocateArea( &m_logical[1] , &m_physical[1] , B_PAGE_SIZE , "16-byte chunk area" ); if ( m_areas[1] < B_OK ) { @@ -78,17 +81,17 @@ Stack::Stack() for ( int i = 0 ; i < B_PAGE_SIZE/16 ; i++ ) { - memory_chunk *chunk = (memory_chunk *)((uint32)m_logical[1] + 16 * i); - chunk->physical = (void *)((uint32)m_physical[1] + 16 * i); + memory_chunk *chunk = (memory_chunk *)((addr_t)m_logical[1] + 16 * i); + chunk->physical = (void *)((addr_t)m_physical[1] + 16 * i); if ( i != B_PAGE_SIZE / 16 - 1 ) - chunk->next_item = (void *)((uint32)m_logical[1] + 16 * ( i + 1 )); + chunk->next_item = (void *)((addr_t)m_logical[1] + 16 * ( i + 1 )); else chunk->next_item = NULL; } // 32-byte heap m_areafreecount[2] = 0; - m_areas[2] = AllocArea( &m_logical[2] , &m_physical[2] , B_PAGE_SIZE , + m_areas[2] = AllocateArea( &m_logical[2] , &m_physical[2] , B_PAGE_SIZE , "32-byte chunk area" ); if ( m_areas[2] < B_OK ) { @@ -100,14 +103,15 @@ Stack::Stack() for ( int i = 0 ; i < B_PAGE_SIZE/32 ; i++ ) { - memory_chunk *chunk = (memory_chunk *)((uint32)m_logical[2] + 32 * i); - chunk->physical = (void *)((uint32)m_physical[2] + 32 * i); + memory_chunk *chunk = (memory_chunk *)((addr_t)m_logical[2] + 32 * i); + chunk->physical = (void *)((addr_t)m_physical[2] + 32 * i); if ( i != B_PAGE_SIZE / 32 - 1 ) - chunk->next_item = (void *)((uint32)m_logical[2] + 32 * ( i + 1 )); + chunk->next_item = (void *)((addr_t)m_logical[2] + 32 * ( i + 1 )); else chunk->next_item = NULL; } + //Check for host controller modules void *list = open_module_list( "busses/usb" ); char modulename[B_PATH_NAME_LENGTH]; @@ -119,7 +123,8 @@ Stack::Stack() host_controller_info *module = 0; if ( get_module( modulename , (module_info **)&module ) != B_OK ) continue; - m_busmodules.Insert( new BusManager( module ) , 0 ); + if ( module->add_to( *this) != B_OK ) + continue; dprintf( "USB: module %s successfully loaded\n" , modulename ); } @@ -155,6 +160,12 @@ void Stack::Unlock() release_sem( m_master ); } +void Stack::AddBusManager( BusManager *bus ) +{ + m_busmodules.PushBack( bus ); +} + + status_t Stack::AllocateChunk( void **log , void **phy , uint8 size ) { Lock(); @@ -188,6 +199,7 @@ status_t Stack::AllocateChunk( void **log , void **phy , uint8 size ) else m_8_listhead = chunk->next_item; Unlock(); + dprintf( "USB Stack: allocated a new chunk with size %u\n" , size ); return B_OK; } @@ -217,7 +229,7 @@ status_t Stack::FreeChunk( void *log , void *phy , uint8 size ) return B_OK; } -area_id Stack::AllocArea( void **log , void **phy , size_t size , const char *name ) +area_id Stack::AllocateArea( void **log , void **phy , size_t size , const char *name ) { physical_entry pe; void * logadr; diff --git a/src/add-ons/kernel/bus_managers/usb/Transfer.cpp b/src/add-ons/kernel/bus_managers/usb/Transfer.cpp index 8d97a5717e..3b50ed0c84 100644 --- a/src/add-ons/kernel/bus_managers/usb/Transfer.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Transfer.cpp @@ -21,38 +21,31 @@ #include "usb_p.h" -Transfer::Transfer( Pipe &pipe ) +Transfer::Transfer( Pipe *pipe ) { - d = new usb_transfer_t; - d->pipe = pipe.d; + m_pipe = pipe; } Transfer::~Transfer() { - delete d; } void Transfer::SetRequestData( usb_request_data *data ) { - d->request = data; + m_request = data; } void Transfer::SetBuffer( uint8 *buffer ) { - d->buffer = buffer; + m_buffer = buffer; } -void Transfer::SetBufferLength( int16 length ) +void Transfer::SetBufferLength( size_t length ) { - d->bufferlength = length; + m_bufferlength = length; } void Transfer::SetActualLength( size_t *actual_length ) { - d->actual_length = actual_length; + m_actual_length = actual_length; }; - -usb_transfer_t * Transfer::GetData() -{ - return d; -} diff --git a/src/add-ons/kernel/bus_managers/usb/host_controller.h b/src/add-ons/kernel/bus_managers/usb/host_controller.h deleted file mode 100644 index 932ef1efa3..0000000000 --- a/src/add-ons/kernel/bus_managers/usb/host_controller.h +++ /dev/null @@ -1,125 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2003-2004, Niels S. Reedijk -// -// 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. -#ifndef HOST_CONTROLLER_INFO_H -#define HOST_CONTROLLER_INFO_H - -/* +++++++++ -USB Spec definitions (not interesting for the outside world -+++++++++ */ -typedef struct -{ - uint8 bDescLength; - uint8 bDescriptorType; - uint8 bNbrPorts; - uint16 wHubCharacteristics; - uint8 bPwrOn2PwrGood; - uint8 bHucContrCurrent; - uint8 DeviceRemovable; //Should be variable!!! - uint8 PortPwrCtrlMask; //Deprecated -} usb_hub_descriptor; - -#define USB_DESCRIPTOR_HUB 0x29 - -// USB Spec 1.1 page 273 -typedef struct -{ - uint16 status; - uint16 change; -} usb_port_status; - -//The bits in the usb_port_status struct -// USB 1.1 spec page 274 -#define PORT_STATUS_CONNECTION 0x1 -#define PORT_STATUS_ENABLE 0x2 -#define PORT_STATUS_SUSPEND 0x4 -#define PORT_STATUS_OVER_CURRENT 0x8 -#define PORT_STATUS_RESET 0x10 -#define PORT_STATUS_POWER 0x100 -#define PORT_STATUS_LOW_SPEED 0x200 - -//The feature requests with ports -// USB 1.1 spec page 268 -#define PORT_CONNECTION 0 -#define PORT_ENABLE 1 -#define PORT_SUSPEND 2 -#define PORT_OVER_CURRENT 3 -#define PORT_RESET 4 -#define PORT_POWER 8 -#define PORT_LOW_SPEED 9 -#define C_PORT_CONNECTION 16 -#define C_PORT_ENABLE 17 -#define C_PORT_SUSPEND 18 -#define C_PORT_OVER_CURRENT 19 -#define C_PORT_RESET 20 - -/* ++++++++++ -Internally used types -++++++++++ */ - -//This embodies a request that can be send -typedef struct -{ - uint8 RequestType; - uint8 Request; - uint16 Value; - uint16 Index; - uint16 Length; -} usb_request_data; - -// Describes the internals of a pipe -enum Direction { In , Out , Default }; -enum Speed { LowSpeed , NormalSpeed }; - -typedef struct usb_pipe_t -{ - enum Direction direction; - enum Speed speed; - int8 deviceid; - uint8 endpoint; -} usb_pipe_t; - - -// Describes the internal organs of an usb packet -typedef struct usb_transfer_t -{ - //Data that is related to the transfer - usb_pipe_t *pipe; - uint8 *buffer; - size_t bufferlength; - size_t *actual_length; - bigtime_t timeout; - status_t status; - - //For control transfers - usb_request_data *request; -} usb_transfer_t; - -// -// -typedef struct host_controller_info -{ - module_info info; - status_t (*hwstart)(void); - status_t (*SubmitPacket)(usb_transfer_t *); -} host_controller_info; - -#endif //HOST_CONTROLLER_INFO_H - diff --git a/src/add-ons/kernel/bus_managers/usb/usb.cpp b/src/add-ons/kernel/bus_managers/usb/usb.cpp index 57bbf01622..0f61d3e1cf 100644 --- a/src/add-ons/kernel/bus_managers/usb/usb.cpp +++ b/src/add-ons/kernel/bus_managers/usb/usb.cpp @@ -39,13 +39,18 @@ Loading/unloading the module static int32 bus_std_ops(int32 op, ...) { + Stack *stack; switch(op) { case B_MODULE_INIT: + #ifdef USB_DEBUG + set_dprintf_enabled( true ); + load_driver_symbols( "usb" ); + #endif TRACE(("usb_nielx: bus module: init\n")); - data = new Stack(); - if( data->InitCheck() != B_OK ) + stack = new Stack(); + if( stack->InitCheck() != B_OK ) { - delete data; + delete stack; return ENODEV; } break; diff --git a/src/add-ons/kernel/bus_managers/usb/usb_p.h b/src/add-ons/kernel/bus_managers/usb/usb_p.h index 738dabcc0a..9057241c32 100644 --- a/src/add-ons/kernel/bus_managers/usb/usb_p.h +++ b/src/add-ons/kernel/bus_managers/usb/usb_p.h @@ -25,17 +25,19 @@ #include #include #include -#include "host_controller.h" #include /* ++++++++++ Forward declarations ++++++++++ */ +class Stack; class Device; +class Transfer; class BusManager; class ControlPipe; + #define USB_MAX_AREAS 8 struct memory_chunk { @@ -49,6 +51,72 @@ Important data from the USB spec (not interesting for drivers) #define POWER_DELAY +/* ++++++++++ +The host_controller_info +++++++++++ */ +struct host_controller_info +{ + module_info info; + status_t (*control)(uint32 op, void *data, size_t length); + bool (*add_to)(Stack &stack); +}; + +struct usb_request_data +{ + uint8 RequestType; + uint8 Request; + uint16 Value; + uint16 Index; + uint16 Length; +}; + +struct usb_hub_descriptor +{ + uint8 bDescLength; + uint8 bDescriptorType; + uint8 bNbrPorts; + uint16 wHubCharacteristics; + uint8 bPwrOn2PwrGood; + uint8 bHucContrCurrent; + uint8 DeviceRemovable; //Should be variable!!! + uint8 PortPwrCtrlMask; //Deprecated +}; + +#define USB_DESCRIPTOR_HUB 0x29 + +// USB Spec 1.1 page 273 +struct usb_port_status +{ + uint16 status; + uint16 change; +}; + +//The bits in the usb_port_status struct +// USB 1.1 spec page 274 +#define PORT_STATUS_CONNECTION 0x1 +#define PORT_STATUS_ENABLE 0x2 +#define PORT_STATUS_SUSPEND 0x4 +#define PORT_STATUS_OVER_CURRENT 0x8 +#define PORT_STATUS_RESET 0x10 +#define PORT_STATUS_POWER 0x100 +#define PORT_STATUS_LOW_SPEED 0x200 + +//The feature requests with ports +// USB 1.1 spec page 268 +#define PORT_CONNECTION 0 +#define PORT_ENABLE 1 +#define PORT_SUSPEND 2 +#define PORT_OVER_CURRENT 3 +#define PORT_RESET 4 +#define PORT_POWER 8 +#define PORT_LOW_SPEED 9 +#define C_PORT_CONNECTION 16 +#define C_PORT_ENABLE 17 +#define C_PORT_SUSPEND 18 +#define C_PORT_OVER_CURRENT 19 +#define C_PORT_RESET 20 + + /* ++++++++++ Internal classes ++++++++++ */ @@ -63,10 +131,11 @@ public: void Lock(); void Unlock(); + void AddBusManager( BusManager *bus ); + status_t AllocateChunk( void **log , void **phy , uint8 size ); status_t FreeChunk( void *log , void *phy , uint8 size ); - - area_id AllocArea( void **log , void **phy , size_t size , const char *name ); + area_id AllocateArea( void **log , void **phy , size_t size , const char *name ); private: Vector m_busmodules;//Stores all the bus modules @@ -94,6 +163,7 @@ public: uint8 GetAddress() { return m_devicenum; }; int16 GetDescriptor( uint8 descriptor_type , uint16 index , void *buffer , size_t size ); + BusManager *GetBusManager() { return m_bus; }; status_t SetConfiguration( uint8 value ); protected: usb_device_descriptor m_device_descriptor; @@ -135,16 +205,22 @@ class BusManager friend class Device; friend class ControlPipe; public: - BusManager( host_controller_info *info ); - ~BusManager(); + BusManager(); + virtual ~BusManager(); - status_t InitCheck(); + virtual status_t InitCheck(); Device *AllocateNewDevice( Device *parent , bool speed ); int8 AllocateAddress(); -private: - host_controller_info *hcpointer; + + virtual status_t Start(); +// virtual status_t Stop(); + virtual status_t SubmitTransfer( Transfer &t ); +protected: + void SetRootHub( Hub *hub ) { m_roothub = hub; }; + Device* GetRootHub() { return m_roothub; }; bool m_initok; +private: bool m_devicemap[128]; ControlPipe *m_defaultLowSpeedPipe; ControlPipe *m_defaultPipe; @@ -165,12 +241,18 @@ class Pipe { friend class Transfer; public: + enum Direction { In , Out , Default }; + enum Speed { LowSpeed , NormalSpeed }; + Pipe( Device *dev , Direction &dir , uint8 &endpointaddress ); virtual ~Pipe(); + + virtual int8 GetDeviceAddress(); protected: Device *m_device; BusManager *m_bus; - usb_pipe_t *d; + Direction m_direction; + uint8 m_endpoint; }; class ControlPipe : public Pipe @@ -178,12 +260,16 @@ class ControlPipe : public Pipe public: ControlPipe( Device *dev , Direction dir , uint8 endpointaddress ); //Special constructor for default control pipe - ControlPipe( BusManager *bus , int8 dev_id , Direction dir , Speed speed , uint8 endpointaddress ); + ControlPipe( BusManager *bus , int8 dev_address , Direction dir , Speed speed , uint8 endpointaddress ); + virtual int8 GetDeviceAddress(); status_t SendRequest( uint8 request_type , uint8 request , uint16 value , uint16 index , uint16 length , void *data , size_t data_len , size_t *actual_len ); status_t SendControlMessage( usb_request_data *command , void *data , size_t data_length , size_t *actual_length , bigtime_t timeout ); +private: + int8 m_deviceaddress; + bool m_lowspeed; }; /* @@ -195,16 +281,29 @@ public: class Transfer { public: - Transfer( Pipe &pipe ); + Transfer( Pipe *pipe ); ~Transfer(); void SetRequestData( usb_request_data *data ); void SetBuffer( uint8 *buffer ); - void SetBufferLength( int16 length ); + void SetBufferLength( size_t length ); void SetActualLength( size_t * ); - usb_transfer_t *GetData(); + Pipe *GetPipe() { return m_pipe; }; + uint8 *GetBuffer() { return m_buffer; }; + size_t GetBufferLength() { return m_bufferlength; }; + size_t *GetActualLength() { return m_actual_length; }; + usb_request_data *GetRequestData() {return m_request;}; private: - usb_transfer_t *d; + //Data that is related to the transfer + Pipe *m_pipe; + uint8 *m_buffer; + size_t m_bufferlength; + size_t *m_actual_length; + bigtime_t m_timeout; + status_t m_status; + + //For control transfers + usb_request_data *m_request; }; #endif