Summary: Merge in changes in busses / bus-manager loading
Keywords: Patches applied: * [email protected]/usb-busmanager--development--0.1--patch-24 Rename AllocArea to AllocateArea for consistency * [email protected]/usb-busmanager--development--0.1--patch-25 Make the memory allocation routines more global and share it with the hc * [email protected]/usb-busmanager--development--0.1--patch-26 Change from uint32 to addr_t to be safe on 64 bit in the future * [email protected]/usb-busmanager--development--0.1--patch-27 AllocateChunk returns an area_id * [email protected]/usb-busmanager--development--0.1--patch-28 Really fixing AllocateChunk now * [email protected]/usb-busmanager--development--0.1--patch-29 Fix a bug where data was uninitialised when used and load debug symbols * [email protected]/usb-busmanager--development--0.1--patch-30 Integrate host_controller.h * [email protected]/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
This commit is contained in:
@@ -30,6 +30,9 @@ int32 usb_explore_thread( void *data )
|
|||||||
{
|
{
|
||||||
Hub *roothub = (Hub *)data;
|
Hub *roothub = (Hub *)data;
|
||||||
|
|
||||||
|
if ( roothub == 0 )
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
while (true )
|
while (true )
|
||||||
{
|
{
|
||||||
//Go to the hubs
|
//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_initok = false;
|
||||||
m_roothub = 0;
|
m_roothub = 0;
|
||||||
|
|
||||||
@@ -56,15 +58,9 @@ BusManager::BusManager( host_controller_info *info )
|
|||||||
memset( &m_devicemap , false , 128 );
|
memset( &m_devicemap , false , 128 );
|
||||||
|
|
||||||
// Set up the default pipes
|
// Set up the default pipes
|
||||||
m_defaultPipe = new ControlPipe( this , 0 , Default , NormalSpeed , 0 );
|
m_defaultPipe = new ControlPipe( this , 0 , Pipe::Default , Pipe::NormalSpeed , 0 );
|
||||||
m_defaultLowSpeedPipe = new ControlPipe( this , 0 , Default , LowSpeed , 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'
|
// Start the 'explore thread'
|
||||||
m_explore_thread = spawn_kernel_thread( usb_explore_thread , "usb_busmanager_explore" ,
|
m_explore_thread = spawn_kernel_thread( usb_explore_thread , "usb_busmanager_explore" ,
|
||||||
B_LOW_PRIORITY , (void *)m_roothub );
|
B_LOW_PRIORITY , (void *)m_roothub );
|
||||||
@@ -75,7 +71,6 @@ BusManager::BusManager( host_controller_info *info )
|
|||||||
|
|
||||||
BusManager::~BusManager()
|
BusManager::~BusManager()
|
||||||
{
|
{
|
||||||
put_module( hcpointer->info.name );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t BusManager::InitCheck()
|
status_t BusManager::InitCheck()
|
||||||
@@ -118,7 +113,7 @@ Device * BusManager::AllocateNewDevice( Device *parent , bool lowspeed )
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Create a temporary pipe
|
//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
|
//3. Get the device descriptor
|
||||||
// Just retrieve the first 8 bytes of the descriptor -> minimum supported
|
// Just retrieve the first 8 bytes of the descriptor -> minimum supported
|
||||||
@@ -173,3 +168,18 @@ int8 BusManager::AllocateAddress()
|
|||||||
return devicenum;
|
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;
|
||||||
|
};
|
||||||
|
|||||||
@@ -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_maxpacketin[0] = m_maxpacketout[0] = m_device_descriptor.max_packet_size_0;
|
||||||
m_device_descriptor = desc;
|
m_device_descriptor = desc;
|
||||||
m_lowspeed = lowspeed;
|
m_lowspeed = lowspeed;
|
||||||
m_defaultPipe = new ControlPipe( this , Default , 0 );
|
m_defaultPipe = new ControlPipe( this , Pipe::Default , 0 );
|
||||||
|
|
||||||
//4. Get the device descriptor
|
//4. Get the device descriptor
|
||||||
// We already have a part of it, but we want it all
|
// 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 ,
|
dprintf( "usb Device %d: Vendor id: %d , Product id: %d\n" , devicenum ,
|
||||||
m_device_descriptor.vendor_id , m_device_descriptor.product_id );
|
m_device_descriptor.vendor_id , m_device_descriptor.product_id );
|
||||||
|
|
||||||
|
|
||||||
// 4. Get the configurations
|
// 4. Get the configurations
|
||||||
m_configurations = (usb_configuration_descriptor *)malloc( m_device_descriptor.num_configurations * sizeof (usb_configuration_descriptor) );
|
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 );
|
SetConfiguration( 0 );
|
||||||
|
|
||||||
//6. TODO: Find drivers for the device
|
//6. TODO: Find drivers for the device
|
||||||
|
|
||||||
|
m_initok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Returns the length that was copied (index gives the number of the config)
|
//Returns the length that was copied (index gives the number of the config)
|
||||||
int16 Device::GetDescriptor( uint8 descriptor_type , uint16 index ,
|
int16 Device::GetDescriptor( uint8 descriptor_type , uint16 index ,
|
||||||
void *buffer , size_t size )
|
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
|
m_defaultPipe->SendRequest(USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD , //Type
|
||||||
USB_REQUEST_GET_DESCRIPTOR , //Request
|
USB_REQUEST_GET_DESCRIPTOR , //Request
|
||||||
( descriptor_type << 8 ) | index , //Value
|
( descriptor_type << 8 ) | index , //Value
|
||||||
@@ -124,4 +125,5 @@ status_t Device::SetConfiguration( uint8 value )
|
|||||||
|
|
||||||
//Set current configuration
|
//Set current configuration
|
||||||
m_current_configuration = m_configurations + value;
|
m_current_configuration = m_configurations + value;
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,9 +25,16 @@ Hub::Hub( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8
|
|||||||
: Device ( bus , parent , desc , devicenum , lowspeed )
|
: Device ( bus , parent , desc , devicenum , lowspeed )
|
||||||
{
|
{
|
||||||
dprintf( "USB Hub is being initialised\n" );
|
dprintf( "USB Hub is being initialised\n" );
|
||||||
m_initok = false; // We're not yet ready!
|
|
||||||
size_t actual_length;
|
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 )
|
if( m_device_descriptor.device_subclass != 0 || m_device_descriptor.device_protocol != 0 )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,12 +4,17 @@ UsePrivateHeaders [ FDirName kernel ] ;
|
|||||||
|
|
||||||
AddResources usb : usb.rdef ;
|
AddResources usb : usb.rdef ;
|
||||||
|
|
||||||
R5KernelAddon usb : [ FDirName kernel bus_managers ] :
|
R5KernelStaticLibrary usb :
|
||||||
usb.cpp
|
|
||||||
Stack.cpp
|
Stack.cpp
|
||||||
Device.cpp
|
Device.cpp
|
||||||
Hub.cpp
|
Hub.cpp
|
||||||
BusManager.cpp
|
BusManager.cpp
|
||||||
Transfer.cpp
|
Transfer.cpp
|
||||||
Pipe.cpp
|
Pipe.cpp
|
||||||
|
;
|
||||||
|
|
||||||
|
R5KernelAddon usb : [ FDirName kernel bus_managers ] :
|
||||||
|
usb.cpp
|
||||||
;
|
;
|
||||||
|
|
||||||
|
LinkSharedOSLibs usb : libusb.a ;
|
||||||
@@ -23,26 +23,23 @@
|
|||||||
|
|
||||||
Pipe::Pipe( Device *dev , Direction &dir , uint8 &endpointaddress )
|
Pipe::Pipe( Device *dev , Direction &dir , uint8 &endpointaddress )
|
||||||
{
|
{
|
||||||
d = new usb_pipe_t;
|
m_direction = dir;
|
||||||
|
|
||||||
d->direction = dir;
|
|
||||||
m_device = dev;
|
m_device = dev;
|
||||||
|
m_endpoint = endpointaddress;
|
||||||
if ( m_device != NULL ) //Default pipe
|
if ( m_device != NULL )
|
||||||
{
|
m_bus = m_device->GetBusManager();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Pipe::~Pipe()
|
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 )
|
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 )
|
: Pipe( NULL , dir , endpointaddress )
|
||||||
{
|
{
|
||||||
m_bus = bus;
|
m_bus = bus;
|
||||||
d->deviceid = dev_id;
|
m_deviceaddress = dev_address;
|
||||||
d->speed = speed;
|
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 ,
|
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 )
|
bigtime_t timeout )
|
||||||
{
|
{
|
||||||
// this method should build an usb packet (new class) with the needed data
|
// this method should build an usb packet (new class) with the needed data
|
||||||
Transfer transfer( *this );
|
Transfer transfer( this );
|
||||||
|
|
||||||
transfer.SetRequestData( command );
|
transfer.SetRequestData( command );
|
||||||
transfer.SetBuffer( (uint8 *)data );
|
transfer.SetBuffer( (uint8 *)data );
|
||||||
transfer.SetBufferLength( data_length );
|
transfer.SetBufferLength( data_length );
|
||||||
transfer.SetActualLength( actual_length );
|
transfer.SetActualLength( actual_length );
|
||||||
|
|
||||||
status_t retval = m_bus->hcpointer->SubmitPacket( transfer.GetData() );
|
status_t retval = m_bus->SubmitTransfer( transfer );
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,13 +29,16 @@
|
|||||||
Stack::Stack()
|
Stack::Stack()
|
||||||
{
|
{
|
||||||
//Init the master lock
|
//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 );
|
set_sem_owner( m_master , B_SYSTEM_TEAM );
|
||||||
|
|
||||||
//Create the data lock
|
//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_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
|
//Initialise the memory chunks: create 8, 16 and 32 byte-heaps
|
||||||
//NOTE: This is probably the most ugly code you will see in the
|
//NOTE: This is probably the most ugly code you will see in the
|
||||||
//whole stack. Unfortunately this is needed because of the fact
|
//whole stack. Unfortunately this is needed because of the fact
|
||||||
@@ -44,7 +47,7 @@ Stack::Stack()
|
|||||||
|
|
||||||
// 8-byte heap
|
// 8-byte heap
|
||||||
m_areafreecount[0] = 0;
|
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" );
|
"8-byte chunk area" );
|
||||||
if ( m_areas[0] < B_OK )
|
if ( m_areas[0] < B_OK )
|
||||||
{
|
{
|
||||||
@@ -56,17 +59,17 @@ Stack::Stack()
|
|||||||
|
|
||||||
for ( int i = 0 ; i < B_PAGE_SIZE/8 ; i++ )
|
for ( int i = 0 ; i < B_PAGE_SIZE/8 ; i++ )
|
||||||
{
|
{
|
||||||
memory_chunk *chunk = (memory_chunk *)((uint32)m_logical[0] + 8 * i);
|
memory_chunk *chunk = (memory_chunk *)((addr_t)m_logical[0] + 8 * i);
|
||||||
chunk->physical = (void *)((uint32)m_physical[0] + 8 * i);
|
chunk->physical = (void *)((addr_t)m_physical[0] + 8 * i);
|
||||||
if ( i != B_PAGE_SIZE / 8 - 1 )
|
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
|
else
|
||||||
chunk->next_item = NULL;
|
chunk->next_item = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 16-byte heap
|
// 16-byte heap
|
||||||
m_areafreecount[1] = 0;
|
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" );
|
"16-byte chunk area" );
|
||||||
if ( m_areas[1] < B_OK )
|
if ( m_areas[1] < B_OK )
|
||||||
{
|
{
|
||||||
@@ -78,17 +81,17 @@ Stack::Stack()
|
|||||||
|
|
||||||
for ( int i = 0 ; i < B_PAGE_SIZE/16 ; i++ )
|
for ( int i = 0 ; i < B_PAGE_SIZE/16 ; i++ )
|
||||||
{
|
{
|
||||||
memory_chunk *chunk = (memory_chunk *)((uint32)m_logical[1] + 16 * i);
|
memory_chunk *chunk = (memory_chunk *)((addr_t)m_logical[1] + 16 * i);
|
||||||
chunk->physical = (void *)((uint32)m_physical[1] + 16 * i);
|
chunk->physical = (void *)((addr_t)m_physical[1] + 16 * i);
|
||||||
if ( i != B_PAGE_SIZE / 16 - 1 )
|
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
|
else
|
||||||
chunk->next_item = NULL;
|
chunk->next_item = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 32-byte heap
|
// 32-byte heap
|
||||||
m_areafreecount[2] = 0;
|
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" );
|
"32-byte chunk area" );
|
||||||
if ( m_areas[2] < B_OK )
|
if ( m_areas[2] < B_OK )
|
||||||
{
|
{
|
||||||
@@ -100,14 +103,15 @@ Stack::Stack()
|
|||||||
|
|
||||||
for ( int i = 0 ; i < B_PAGE_SIZE/32 ; i++ )
|
for ( int i = 0 ; i < B_PAGE_SIZE/32 ; i++ )
|
||||||
{
|
{
|
||||||
memory_chunk *chunk = (memory_chunk *)((uint32)m_logical[2] + 32 * i);
|
memory_chunk *chunk = (memory_chunk *)((addr_t)m_logical[2] + 32 * i);
|
||||||
chunk->physical = (void *)((uint32)m_physical[2] + 32 * i);
|
chunk->physical = (void *)((addr_t)m_physical[2] + 32 * i);
|
||||||
if ( i != B_PAGE_SIZE / 32 - 1 )
|
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
|
else
|
||||||
chunk->next_item = NULL;
|
chunk->next_item = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//Check for host controller modules
|
//Check for host controller modules
|
||||||
void *list = open_module_list( "busses/usb" );
|
void *list = open_module_list( "busses/usb" );
|
||||||
char modulename[B_PATH_NAME_LENGTH];
|
char modulename[B_PATH_NAME_LENGTH];
|
||||||
@@ -119,7 +123,8 @@ Stack::Stack()
|
|||||||
host_controller_info *module = 0;
|
host_controller_info *module = 0;
|
||||||
if ( get_module( modulename , (module_info **)&module ) != B_OK )
|
if ( get_module( modulename , (module_info **)&module ) != B_OK )
|
||||||
continue;
|
continue;
|
||||||
m_busmodules.Insert( new BusManager( module ) , 0 );
|
if ( module->add_to( *this) != B_OK )
|
||||||
|
continue;
|
||||||
dprintf( "USB: module %s successfully loaded\n" , modulename );
|
dprintf( "USB: module %s successfully loaded\n" , modulename );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,6 +160,12 @@ void Stack::Unlock()
|
|||||||
release_sem( m_master );
|
release_sem( m_master );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Stack::AddBusManager( BusManager *bus )
|
||||||
|
{
|
||||||
|
m_busmodules.PushBack( bus );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t Stack::AllocateChunk( void **log , void **phy , uint8 size )
|
status_t Stack::AllocateChunk( void **log , void **phy , uint8 size )
|
||||||
{
|
{
|
||||||
Lock();
|
Lock();
|
||||||
@@ -188,6 +199,7 @@ status_t Stack::AllocateChunk( void **log , void **phy , uint8 size )
|
|||||||
else
|
else
|
||||||
m_8_listhead = chunk->next_item;
|
m_8_listhead = chunk->next_item;
|
||||||
Unlock();
|
Unlock();
|
||||||
|
dprintf( "USB Stack: allocated a new chunk with size %u\n" , size );
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,7 +229,7 @@ status_t Stack::FreeChunk( void *log , void *phy , uint8 size )
|
|||||||
return B_OK;
|
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;
|
physical_entry pe;
|
||||||
void * logadr;
|
void * logadr;
|
||||||
|
|||||||
@@ -21,38 +21,31 @@
|
|||||||
|
|
||||||
#include "usb_p.h"
|
#include "usb_p.h"
|
||||||
|
|
||||||
Transfer::Transfer( Pipe &pipe )
|
Transfer::Transfer( Pipe *pipe )
|
||||||
{
|
{
|
||||||
d = new usb_transfer_t;
|
m_pipe = pipe;
|
||||||
d->pipe = pipe.d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Transfer::~Transfer()
|
Transfer::~Transfer()
|
||||||
{
|
{
|
||||||
delete d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transfer::SetRequestData( usb_request_data *data )
|
void Transfer::SetRequestData( usb_request_data *data )
|
||||||
{
|
{
|
||||||
d->request = data;
|
m_request = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transfer::SetBuffer( uint8 *buffer )
|
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 )
|
void Transfer::SetActualLength( size_t *actual_length )
|
||||||
{
|
{
|
||||||
d->actual_length = actual_length;
|
m_actual_length = actual_length;
|
||||||
};
|
};
|
||||||
|
|
||||||
usb_transfer_t * Transfer::GetData()
|
|
||||||
{
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
|
|
||||||
@@ -39,13 +39,18 @@ Loading/unloading the module
|
|||||||
static int32
|
static int32
|
||||||
bus_std_ops(int32 op, ...)
|
bus_std_ops(int32 op, ...)
|
||||||
{
|
{
|
||||||
|
Stack *stack;
|
||||||
switch(op) {
|
switch(op) {
|
||||||
case B_MODULE_INIT:
|
case B_MODULE_INIT:
|
||||||
|
#ifdef USB_DEBUG
|
||||||
|
set_dprintf_enabled( true );
|
||||||
|
load_driver_symbols( "usb" );
|
||||||
|
#endif
|
||||||
TRACE(("usb_nielx: bus module: init\n"));
|
TRACE(("usb_nielx: bus module: init\n"));
|
||||||
data = new Stack();
|
stack = new Stack();
|
||||||
if( data->InitCheck() != B_OK )
|
if( stack->InitCheck() != B_OK )
|
||||||
{
|
{
|
||||||
delete data;
|
delete stack;
|
||||||
return ENODEV;
|
return ENODEV;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -25,17 +25,19 @@
|
|||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
#include <util/Vector.h>
|
#include <util/Vector.h>
|
||||||
#include <USB.h>
|
#include <USB.h>
|
||||||
#include "host_controller.h"
|
|
||||||
#include <util/kernel_cpp.h>
|
#include <util/kernel_cpp.h>
|
||||||
|
|
||||||
|
|
||||||
/* ++++++++++
|
/* ++++++++++
|
||||||
Forward declarations
|
Forward declarations
|
||||||
++++++++++ */
|
++++++++++ */
|
||||||
|
class Stack;
|
||||||
class Device;
|
class Device;
|
||||||
|
class Transfer;
|
||||||
class BusManager;
|
class BusManager;
|
||||||
class ControlPipe;
|
class ControlPipe;
|
||||||
|
|
||||||
|
|
||||||
#define USB_MAX_AREAS 8
|
#define USB_MAX_AREAS 8
|
||||||
struct memory_chunk
|
struct memory_chunk
|
||||||
{
|
{
|
||||||
@@ -49,6 +51,72 @@ Important data from the USB spec (not interesting for drivers)
|
|||||||
|
|
||||||
#define POWER_DELAY
|
#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
|
Internal classes
|
||||||
++++++++++ */
|
++++++++++ */
|
||||||
@@ -63,10 +131,11 @@ public:
|
|||||||
void Lock();
|
void Lock();
|
||||||
void Unlock();
|
void Unlock();
|
||||||
|
|
||||||
|
void AddBusManager( BusManager *bus );
|
||||||
|
|
||||||
status_t AllocateChunk( void **log , void **phy , uint8 size );
|
status_t AllocateChunk( void **log , void **phy , uint8 size );
|
||||||
status_t FreeChunk( void *log , void *phy , uint8 size );
|
status_t FreeChunk( void *log , void *phy , uint8 size );
|
||||||
|
area_id AllocateArea( void **log , void **phy , size_t size , const char *name );
|
||||||
area_id AllocArea( void **log , void **phy , size_t size , const char *name );
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vector<BusManager *> m_busmodules;//Stores all the bus modules
|
Vector<BusManager *> m_busmodules;//Stores all the bus modules
|
||||||
@@ -94,6 +163,7 @@ public:
|
|||||||
uint8 GetAddress() { return m_devicenum; };
|
uint8 GetAddress() { return m_devicenum; };
|
||||||
int16 GetDescriptor( uint8 descriptor_type , uint16 index , void *buffer ,
|
int16 GetDescriptor( uint8 descriptor_type , uint16 index , void *buffer ,
|
||||||
size_t size );
|
size_t size );
|
||||||
|
BusManager *GetBusManager() { return m_bus; };
|
||||||
status_t SetConfiguration( uint8 value );
|
status_t SetConfiguration( uint8 value );
|
||||||
protected:
|
protected:
|
||||||
usb_device_descriptor m_device_descriptor;
|
usb_device_descriptor m_device_descriptor;
|
||||||
@@ -135,16 +205,22 @@ class BusManager
|
|||||||
friend class Device;
|
friend class Device;
|
||||||
friend class ControlPipe;
|
friend class ControlPipe;
|
||||||
public:
|
public:
|
||||||
BusManager( host_controller_info *info );
|
BusManager();
|
||||||
~BusManager();
|
virtual ~BusManager();
|
||||||
|
|
||||||
status_t InitCheck();
|
virtual status_t InitCheck();
|
||||||
|
|
||||||
Device *AllocateNewDevice( Device *parent , bool speed );
|
Device *AllocateNewDevice( Device *parent , bool speed );
|
||||||
int8 AllocateAddress();
|
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;
|
bool m_initok;
|
||||||
|
private:
|
||||||
bool m_devicemap[128];
|
bool m_devicemap[128];
|
||||||
ControlPipe *m_defaultLowSpeedPipe;
|
ControlPipe *m_defaultLowSpeedPipe;
|
||||||
ControlPipe *m_defaultPipe;
|
ControlPipe *m_defaultPipe;
|
||||||
@@ -165,12 +241,18 @@ class Pipe
|
|||||||
{
|
{
|
||||||
friend class Transfer;
|
friend class Transfer;
|
||||||
public:
|
public:
|
||||||
|
enum Direction { In , Out , Default };
|
||||||
|
enum Speed { LowSpeed , NormalSpeed };
|
||||||
|
|
||||||
Pipe( Device *dev , Direction &dir , uint8 &endpointaddress );
|
Pipe( Device *dev , Direction &dir , uint8 &endpointaddress );
|
||||||
virtual ~Pipe();
|
virtual ~Pipe();
|
||||||
|
|
||||||
|
virtual int8 GetDeviceAddress();
|
||||||
protected:
|
protected:
|
||||||
Device *m_device;
|
Device *m_device;
|
||||||
BusManager *m_bus;
|
BusManager *m_bus;
|
||||||
usb_pipe_t *d;
|
Direction m_direction;
|
||||||
|
uint8 m_endpoint;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ControlPipe : public Pipe
|
class ControlPipe : public Pipe
|
||||||
@@ -178,12 +260,16 @@ class ControlPipe : public Pipe
|
|||||||
public:
|
public:
|
||||||
ControlPipe( Device *dev , Direction dir , uint8 endpointaddress );
|
ControlPipe( Device *dev , Direction dir , uint8 endpointaddress );
|
||||||
//Special constructor for default control pipe
|
//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 ,
|
status_t SendRequest( uint8 request_type , uint8 request ,
|
||||||
uint16 value , uint16 index , uint16 length , void *data ,
|
uint16 value , uint16 index , uint16 length , void *data ,
|
||||||
size_t data_len , size_t *actual_len );
|
size_t data_len , size_t *actual_len );
|
||||||
status_t SendControlMessage( usb_request_data *command , void *data ,
|
status_t SendControlMessage( usb_request_data *command , void *data ,
|
||||||
size_t data_length , size_t *actual_length , bigtime_t timeout );
|
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
|
class Transfer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Transfer( Pipe &pipe );
|
Transfer( Pipe *pipe );
|
||||||
~Transfer();
|
~Transfer();
|
||||||
void SetRequestData( usb_request_data *data );
|
void SetRequestData( usb_request_data *data );
|
||||||
void SetBuffer( uint8 *buffer );
|
void SetBuffer( uint8 *buffer );
|
||||||
void SetBufferLength( int16 length );
|
void SetBufferLength( size_t length );
|
||||||
void SetActualLength( size_t * );
|
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:
|
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
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user