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:
@@ -21,6 +21,25 @@
|
|||||||
|
|
||||||
#include "usb_p.h"
|
#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 )
|
BusManager::BusManager( host_controller_info *info )
|
||||||
{
|
{
|
||||||
hcpointer = info;
|
hcpointer = info;
|
||||||
@@ -41,6 +60,11 @@ BusManager::BusManager( host_controller_info *info )
|
|||||||
|
|
||||||
if( m_roothub == 0 )
|
if( m_roothub == 0 )
|
||||||
return;
|
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;
|
m_initok = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,4 +121,7 @@ status_t Device::SetConfiguration( uint8 value )
|
|||||||
NULL , //Buffer
|
NULL , //Buffer
|
||||||
0 , //Bufferlength
|
0 , //Bufferlength
|
||||||
0 ); //length
|
0 ); //length
|
||||||
|
|
||||||
|
//Set current configuration
|
||||||
|
m_current_configuration = m_configurations + value;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,5 +24,128 @@
|
|||||||
Hub::Hub( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum )
|
Hub::Hub( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum )
|
||||||
: Device ( bus , parent , desc , 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 ] ;
|
UsePrivateHeaders [ FDirName kernel ] ;
|
||||||
|
|
||||||
|
AddResources usb : usb.rdef ;
|
||||||
|
|
||||||
R5KernelAddon usb : [ FDirName kernel bus_managers ] :
|
R5KernelAddon usb : [ FDirName kernel bus_managers ] :
|
||||||
usb.cpp
|
usb.cpp
|
||||||
Stack.cpp
|
Stack.cpp
|
||||||
|
|||||||
@@ -1,6 +1,55 @@
|
|||||||
#ifndef HOST_CONTROLLER_INFO_H
|
#ifndef HOST_CONTROLLER_INFO_H
|
||||||
#define 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
|
Internally used types
|
||||||
++++++++++ */
|
++++++++++ */
|
||||||
|
|||||||
@@ -34,6 +34,12 @@ Forward declarations
|
|||||||
class Device;
|
class Device;
|
||||||
class BusManager;
|
class BusManager;
|
||||||
|
|
||||||
|
/* ++++++++++
|
||||||
|
Important data from the USB spec (not interesting for drivers)
|
||||||
|
++++++++++ */
|
||||||
|
|
||||||
|
#define POWER_DELAY
|
||||||
|
|
||||||
/* ++++++++++
|
/* ++++++++++
|
||||||
Internal classes
|
Internal classes
|
||||||
++++++++++ */
|
++++++++++ */
|
||||||
@@ -81,6 +87,14 @@ class Hub : public Device
|
|||||||
public:
|
public:
|
||||||
Hub( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum);
|
Hub( BusManager *bus , Device *parent , usb_device_descriptor &desc , int8 devicenum);
|
||||||
virtual bool IsHub() { return true; };
|
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 );
|
Device *AllocateNewDevice( Device *parent );
|
||||||
int8 AllocateAddress();
|
int8 AllocateAddress();
|
||||||
status_t SendRequest( Device *dev, uint8 request_type , uint8 request , uint16 value ,
|
status_t SendRequest( Device *dev, uint8 request_type , uint8 request ,
|
||||||
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 );
|
||||||
private:
|
private:
|
||||||
status_t SendControlMessage( Device *dev , uint16 pipe ,
|
status_t SendControlMessage( Device *dev , uint16 pipe ,
|
||||||
@@ -113,8 +127,12 @@ private:
|
|||||||
bool m_devicemap[128];
|
bool m_devicemap[128];
|
||||||
sem_id m_lock;
|
sem_id m_lock;
|
||||||
Device *m_roothub;
|
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
|
* 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
|
* packets. The class is only used in the bus_manager: the host controllers
|
||||||
|
|||||||
Reference in New Issue
Block a user