Modules/USB - Cleaning up code
[tpg/acess2.git] / Modules / USB / Core / hub.c
1 /*
2  * Acess2 USB Stack
3  * - By John Hodge (thePowersGang)
4  *
5  * hub.c
6  * - Basic hub driver
7  */
8 #include <usb_hub.h>
9
10 #define MAX_PORTS       32      // Not actually a max, but used for DeviceRemovable
11
12 struct sHubDescriptor
13 {
14         Uint8   DescLength;
15         Uint8   DescType;       // = 0x29
16         Uint8   NbrPorts;
17         Uint16  HubCharacteristics;
18         Uint8   PwrOn2PwrGood;  // 2 ms intervals
19         Uint8   HubContrCurrent;        // Max internal current (mA)
20         Uint8   DeviceRemovable[MAX_PORTS];
21 };
22
23 // === PROTOTYPES ===
24 void    Hub_Connected(tUSBInterface *Dev);
25 void    Hub_Disconnected(tUSBInterface *Dev);
26 void    Hub_PortStatusChange(tUSBInterface *Dev, int Length, void *Data);
27
28 // === GLOBALS ===
29 tUSBDriver      gUSBHub_Driver = {
30         .Name = "Hub",
31         .Match = {.Class = {0x090000, 0xFF0000}},
32         .Connected = Hub_Connected,
33         .Disconnected = Hub_Disconnected,
34         .MaxEndpoints = 1,
35         .Endpoints = {
36                 {0x83, Hub_PortStatusChange}
37         };
38 };
39
40 // === CODE ===
41 void Hub_Connected(tUSBInterface *Dev)
42 {
43         struct sHubDescriptor   *hub_desc;
44         
45         hub_desc = malloc(sizeof(*hub_desc));
46         if(!hub_desc) {
47                 Log_Error("USBHub", "malloc() failed");
48                 return ;
49         }
50         USB_SetDeviceDataPtr(Dev, hub_desc);
51
52         USB_ReadDescriptor(Dev, 0, 0x29, 0, sizeof(hub_desc), hub_desc);
53
54         // Register poll on endpoint
55         USB_PollEndpoint(Dev, 1);
56         
57         USB_RegisterHub(Dev, hub_desc->NbrPorts);
58 }
59
60 void Hub_Disconnected(tUSBInterface *Dev)
61 {
62 }
63
64 void Hub_PortStatusChange(tUSBInterface *Dev, int Length, void *Data)
65 {
66         Uint8   *status = Data;
67         struct sHubDescriptor   *info = USB_GetDeviceDataPtr(Dev);
68          int    i;
69         for( i = 0; i < info->NbrPorts; i += 8, status ++ )
70         {
71                 if( i/8 >= Length )     break;
72                 if( *status == 0 )      continue;
73         
74                 for( int j = 0; j < 8; j ++ )
75                         if( *status & (1 << j) )
76                                 Hub_int_HandleChange(Dev, i+j);
77         }
78 }
79
80 void Hub_int_HandleChange(tUSBInterface *Dev, int Port)
81 {
82         Uint16  status[2];      // Status, Change
83         // Get change status
84         USB_Request(Dev, 0, 0xA3, 0, 0, Port, 4, status);
85 }
86

UCC git Repository :: git.ucc.asn.au