Usermode/libc - Fix strchr and strrchr behavior
[tpg/acess2.git] / KernelLand / Modules / USB / Core / portctl.c
1 /*
2  * Acess2 USB Stack
3  * - By John Hodge (thePowersGang)
4  *
5  * portctl.c
6  * - Port control code
7  */
8 #define DEBUG   1
9 #define SANITY  1
10 #include <acess.h>
11 #include "usb.h"
12 #include <workqueue.h>
13 #include <timers.h>
14 #include <usb_hub.h>
15
16 // === PROTOTYPES ===
17 void    USB_PortCtl_Init(void);
18 void    USB_PortCtl_Worker(void *Unused);
19 void    USB_PortCtl_SetPortFeature(tUSBHub *Hub, int Port, int Feat);
20 void    USB_PortCtl_ClearPortFeature(tUSBHub *Hub, int Port, int Feat);
21  int    USB_PortCtl_GetPortStatus(tUSBHub *Hub, int Port, int Flag);
22
23 // === GLOBALS === 
24 tWorkqueue      gUSB_PortCtl_WorkQueue;
25
26 // === CODE ===
27 void USB_PortCtl_Init(void)
28 {
29         Workqueue_Init(&gUSB_PortCtl_WorkQueue, "USB Port Reset Work Queue", offsetof(tUSBHubPort, ListNext));
30         Proc_SpawnWorker(USB_PortCtl_Worker, NULL);
31 }
32
33 void USB_PortCtl_Worker(void *Unused)
34 {
35         Threads_SetName("USB PortCtl Worker");
36         for(;;)
37         {
38                 tUSBHubPort *port;
39                 tUSBHub *hub;
40                
41                 port = Workqueue_GetWork(&gUSB_PortCtl_WorkQueue);
42                 if( !port ) {
43                         Log_Warning("USB", "PortCtl Workqueue returned NULL");
44                         break;
45                 }
46                 hub = (tUSBHub*)(port - port->PortNum) - 1;
47
48                 LOG("port = %p, hub = %p", port, hub);
49
50                 switch(port->Status)
51                 {
52                 case 1:
53                         // Assert reset
54                         USB_PortCtl_SetPortFeature(hub, port->PortNum, PORT_RESET);
55                         LOG("Port reset starting");
56                         // Wait 50 ms
57                         Time_Delay(50);
58                         USB_PortCtl_ClearPortFeature(hub, port->PortNum, PORT_RESET);
59                         Time_Delay(10); // May take up to 2ms for reset to clear
60                         // Enable port
61                         LOG("Port enabling");
62                         USB_PortCtl_SetPortFeature(hub, port->PortNum, PORT_ENABLE);
63                         // Begin connect processing
64                         LOG("Reset complete, marking connection");
65                         port->Status = 2;
66                         USB_DeviceConnected(hub, port->PortNum);
67                         break;
68                 default:
69                         Log_Warning("USB", "PortCtl worker: Unknown port state %i",
70                                 port->Status);
71                         break;
72                 }
73         }
74 }
75
76 void USB_PortCtl_BeginReset(tUSBHub *Hub, int Port)
77 {
78         LOG("Starting %p %i", Hub, Port);
79         // Set status field in hub structure
80         Hub->Ports[Port].Status = 1;
81         Hub->Ports[Port].PortNum = Port;
82         // Add to the work queue
83         Workqueue_AddWork(&gUSB_PortCtl_WorkQueue, &Hub->Ports[Port]);
84         LOG("Queue added");
85 }
86
87 void USB_PortCtl_SetPortFeature(tUSBHub *Hub, int Port, int Feat)
88 {
89         if( Hub->Interface->Driver == NULL ) {
90                 // - Host Port
91                 tUSBHost        *host = Hub->Interface->Dev->Host;
92                 ASSERT(host->HostDef->SetPortFeature);
93                 host->HostDef->SetPortFeature(host->Ptr, Port, Feat);
94         }
95         else {
96                 // - Hub Port
97                 Hub_SetPortFeature(Hub->Interface, Port, Feat);
98         }
99 }
100
101 void USB_PortCtl_ClearPortFeature(tUSBHub *Hub, int Port, int Feat)
102 {
103         if( Hub->Interface->Driver == NULL ) {
104                 // - Host Port
105                 tUSBHost        *host = Hub->Interface->Dev->Host;
106                 ASSERT(host->HostDef->ClearPortFeature);
107                 host->HostDef->ClearPortFeature(host->Ptr, Port, Feat);
108         }
109         else {
110                 // - Hub Port
111                 Hub_ClearPortFeature(Hub->Interface, Port, Feat);
112         }
113 }
114
115 int USB_PortCtl_GetPortStatus(tUSBHub *Hub, int Port, int Flag)
116 {
117         if( Hub->Interface->Driver == NULL ) {
118                 // - Host Port
119                 tUSBHost        *host = Hub->Interface->Dev->Host;
120                 ASSERT(host->HostDef->GetPortStatus);
121                 return host->HostDef->GetPortStatus(host->Ptr, Port, Flag);
122         }
123         else {
124                 // - Hub Port
125                 return Hub_GetPortStatus(Hub->Interface, Port, Flag);
126         }
127         return 0;
128 }
129

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