Summary: Continued work on hub initialisation

Keywords:

Patches applied:

 * [email protected]/usb-busmanager--development--0.1--patch-5
   Commit (in between) because of a switch of development-machines

 * [email protected]/usb-busmanager--development--0.1--patch-6
   Implement basic hub init

 * [email protected]/usb-busmanager--development--0.1--patch-7
   Implement a bit more of hub operation


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7193 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Niels Sascha Reedijk
2004-04-13 06:27:32 +00:00
parent df870398e8
commit 8b485af874
6 changed files with 223 additions and 4 deletions
@@ -21,6 +21,25 @@
#include "usb_p.h"
/* +++++++++
This is the 'main' function of the explore thread, which keeps track of
the hub statuses.
+++++++++ */
int32 usb_explore_thread( void *data )
{
Hub *roothub = (Hub *)data;
while (true )
{
//Go to the hubs
roothub->Explore();
snooze(10000); //Wait one second before continueing
}
return B_OK;
}
BusManager::BusManager( host_controller_info *info )
{
hcpointer = info;
@@ -41,6 +60,11 @@ BusManager::BusManager( host_controller_info *info )
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 );
resume_thread( m_explore_thread );
m_initok = true;
}
@@ -121,4 +121,7 @@ status_t Device::SetConfiguration( uint8 value )
NULL , //Buffer
0 , //Bufferlength
0 ); //length
//Set current configuration
m_current_configuration = m_configurations + value;
}
+125 -2
View File
@@ -24,5 +24,128 @@
Hub::Hub( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum )
: Device ( bus , parent , desc , devicenum )
{
dprintf( "USB Hub::Attach()\n" );
}
dprintf( "USB Hub is being initialised\n" );
m_initok = false; // We're not yet ready!
size_t actual_length;
if( m_device_descriptor.device_subclass != 0 || m_device_descriptor.device_protocol != 0 )
{
dprintf( "USB Hub: wrong class/subclass/protocol! Bailing out\n" );
return;
}
if ( m_current_configuration->number_interfaces > 1 )
{
dprintf( "USB Hub: too much interfaces! Bailing out\n" );
return;
}
dprintf( "USB Hub this: %p" , this );
if ( GetDescriptor( USB_DESCRIPTOR_INTERFACE , 0 ,
(void *)&m_interrupt_interface ,
sizeof (usb_interface_descriptor) ) != sizeof( usb_interface_descriptor ) )
{
dprintf( "USB Hub: error getting the interrupt interface! Bailing out.\n" );
return;
}
if ( m_interrupt_interface.num_endpoints > 1 )
{
dprintf( "USB Hub: too much endpoints! Bailing out.\n" );
return;
}
if ( GetDescriptor( USB_DESCRIPTOR_ENDPOINT , 0 ,
(void *)&m_interrupt_endpoint ,
sizeof (usb_endpoint_descriptor) ) != sizeof (usb_endpoint_descriptor ) )
{
dprintf( "USB Hub: Error getting the endpoint. Bailing out\n" );
return;
}
if ( m_interrupt_endpoint.attributes != 0x03 ) //interrupt transfer
{
dprintf( "USB Hub: Not an interrupt endpoint. Bailing out\n" );
return;
}
dprintf( "USB Hub: Getting hub descriptor...\n" );
if ( GetDescriptor( USB_DESCRIPTOR_HUB , 0 ,
(void *)&m_hub_descriptor ,
sizeof (usb_hub_descriptor) ) != sizeof (usb_hub_descriptor ) )
{
dprintf( "USB Hub: Error getting hub descriptor\n" );
return;
}
// Enable port power on all ports
for ( int i = 0 ; i < m_hub_descriptor.bNbrPorts ; i++ )
m_bus->SendRequest( this , USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT ,
USB_REQUEST_SET_FEATURE ,
PORT_POWER ,
i + 1 , //index
0 ,
NULL ,
0 ,
&actual_length );
//Wait for power to stabilize
snooze( m_hub_descriptor.bPwrOn2PwrGood * 2 );
//We're basically done now
m_initok = true;
}
void Hub::Explore()
{
size_t actual_length;
for ( int i = 0 ; i < m_hub_descriptor.bNbrPorts ; i++ )
{
// Get the current port status
m_bus->SendRequest( this , USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_IN ,
USB_REQUEST_GET_STATUS ,
0 , //Value
i + 1 , //Index
4 , //length
(void *)&m_port_status[i],
4 ,
&actual_length );
if ( actual_length < 4 )
{
dprintf( "USB Hub: ERROR getting port status" );
return;
}
//We need to test the port change against a number of things
if ( m_port_status[i].change & PORT_STATUS_CONNECTION )
{
if ( m_port_status[i].status & PORT_STATUS_CONNECTION )
{
//New device attached!
//DO something
dprintf( "USB Hub Explore(): New device connected\n" );
}
else
{
//Device removed...
//DO something
dprintf( "USB Hub Explore(): Device removed\n" );
}
//Clear status
m_bus->SendRequest( this , USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT ,
USB_REQUEST_CLEAR_FEATURE ,
C_PORT_CONNECTION ,
i + 1 , //index
0 ,
NULL ,
0 ,
&actual_length );
} // PORT_STATUS_CONNECTION
}//for (...)
}
@@ -2,6 +2,8 @@ SubDir OBOS_TOP src add-ons kernel bus_managers usb ;
UsePrivateHeaders [ FDirName kernel ] ;
AddResources usb : usb.rdef ;
R5KernelAddon usb : [ FDirName kernel bus_managers ] :
usb.cpp
Stack.cpp
@@ -1,6 +1,55 @@
#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
++++++++++ */
+20 -2
View File
@@ -34,6 +34,12 @@ Forward declarations
class Device;
class BusManager;
/* ++++++++++
Important data from the USB spec (not interesting for drivers)
++++++++++ */
#define POWER_DELAY
/* ++++++++++
Internal classes
++++++++++ */
@@ -81,6 +87,14 @@ class Hub : public Device
public:
Hub( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum);
virtual bool IsHub() { return true; };
void Explore();
private:
usb_interface_descriptor m_interrupt_interface;
usb_endpoint_descriptor m_interrupt_endpoint;
usb_hub_descriptor m_hub_descriptor;
usb_port_status m_port_status[8]; //Max of 8 ports, for the moment
};
/*
@@ -99,8 +113,8 @@ public:
Device *AllocateNewDevice( Device *parent );
int8 AllocateAddress();
status_t SendRequest( Device *dev, uint8 request_type , uint8 request , uint16 value ,
uint16 index , uint16 length , void *data ,
status_t SendRequest( Device *dev, uint8 request_type , uint8 request ,
uint16 value , uint16 index , uint16 length , void *data ,
size_t data_len , size_t *actual_len );
private:
status_t SendControlMessage( Device *dev , uint16 pipe ,
@@ -113,8 +127,12 @@ private:
bool m_devicemap[128];
sem_id m_lock;
Device *m_roothub;
thread_id m_explore_thread;
};
// Located in the BusManager.cpp
int32 usb_explore_thread( void *data );
/*
* This class is more like an utility class that performs all functions on
* packets. The class is only used in the bus_manager: the host controllers