X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Modules%2FUSB%2FCore%2Fhub.c;h=04a9cc525992b38051260d47b8b706cb6c01c787;hb=8aad7ffe6c2e7e5dbb06a5baf59ca43ce1c12317;hp=22fed9dd912afb0088f4090bae83227b8673075d;hpb=3e39f3e998538521830c10da09fe14c7a7dc66bd;p=tpg%2Facess2.git diff --git a/Modules/USB/Core/hub.c b/Modules/USB/Core/hub.c index 22fed9dd..04a9cc52 100644 --- a/Modules/USB/Core/hub.c +++ b/Modules/USB/Core/hub.c @@ -5,10 +5,32 @@ * hub.c * - Basic hub driver */ +#define DEBUG 1 #include #define MAX_PORTS 32 // Not actually a max, but used for DeviceRemovable + +#define GET_STATUS 0 +#define CLEAR_FEATURE 1 +// resvd +#define SET_FEATURE 3 + +#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 +#define PORT_TEST 21 +#define PORT_INDICATOR 21 + struct sHubDescriptor { Uint8 DescLength; @@ -26,12 +48,13 @@ struct sHubInfo int PowerOnDelay; // in ms int nPorts; Uint8 DeviceRemovable[]; -} +}; // === PROTOTYPES === void Hub_Connected(tUSBInterface *Dev); void Hub_Disconnected(tUSBInterface *Dev); -void Hub_PortStatusChange(tUSBInterface *Dev, int Length, void *Data); +void Hub_PortStatusChange(tUSBInterface *Dev, int Endpoint, int Length, void *Data); +void Hub_int_HandleChange(tUSBInterface *Dev, int Port); // === GLOBALS === tUSBDriver gUSBHub_Driver = { @@ -42,17 +65,28 @@ tUSBDriver gUSBHub_Driver = { .MaxEndpoints = 1, .Endpoints = { {0x83, Hub_PortStatusChange} - }; + } }; // === CODE === +#if 0 +int Hub_DriverInitialise(char **Arguments) +{ + USB_RegisterDriver( &gUSBHub_Driver ); + return 0; +} +#endif + void Hub_Connected(tUSBInterface *Dev) { struct sHubDescriptor hub_desc; struct sHubInfo *info; - // Read hub descriptor - USB_ReadDescriptor(Dev, 0x29, 0, sizeof(*hub_desc), hub_desc); + // Read hub descriptor (Class descriptor 0x29) + USB_ReadDescriptor(Dev, 0x129, 0, sizeof(hub_desc), &hub_desc); + + LOG("%i Ports", hub_desc.NbrPorts); + LOG("Takes %i ms for power to stabilise", hub_desc.PwrOn2PwrGood*2); // Allocate infomation structure info = malloc(sizeof(*info) + (hub_desc.NbrPorts+7)/8); @@ -75,10 +109,12 @@ void Hub_Connected(tUSBInterface *Dev) void Hub_Disconnected(tUSBInterface *Dev) { - USB_RemoveHub(Dev); + struct sHubInfo *info = USB_GetDeviceDataPtr(Dev); + USB_RemoveHub(info->HubPtr); + free(info); } -void Hub_PortStatusChange(tUSBInterface *Dev, int Length, void *Data) +void Hub_PortStatusChange(tUSBInterface *Dev, int Endpoint, int Length, void *Data) { Uint8 *status = Data; struct sHubInfo *info = USB_GetDeviceDataPtr(Dev); @@ -96,11 +132,35 @@ void Hub_PortStatusChange(tUSBInterface *Dev, int Length, void *Data) void Hub_int_HandleChange(tUSBInterface *Dev, int Port) { + struct sHubInfo *info = USB_GetDeviceDataPtr(Dev); Uint16 status[2]; // Status, Change // Get port status - USB_Request(Dev, 0, 0xA3, 0, 0, Port, 4, status); + USB_Request(Dev, 0, 0xA3, GET_STATUS, 0, Port, 4, status); + + LOG("Port %i: status = {0b%b, 0b%b}", Port, status[0], status[1]); // Handle connections / disconnections + if( status[1] & 0x0001 ) + { + if( status[0] & 0x0001 ) { + // Connected + // - Power on port + USB_Request(Dev, 0, 0x23, SET_FEATURE, PORT_POWER, Port, 0, NULL); + Time_Delay(info->PowerOnDelay); + // - Reset + USB_Request(Dev, 0, 0x23, SET_FEATURE, PORT_RESET, Port, 0, NULL); + Time_Delay(20); // Spec says 10ms after reset, but how long is reset? + // - Enable + USB_Request(Dev, 0, 0x23, SET_FEATURE, PORT_ENABLE, Port, 0, NULL); + // - Poke USB Stack + USB_DeviceConnected(info->HubPtr, Port); + } + else { + // Disconnected + USB_DeviceDisconnected(info->HubPtr, Port); + } + + USB_Request(Dev, 0, 0x23, CLEAR_FEATURE, C_PORT_CONNECTION, Port, 0, NULL); + } } -