Sorting source tree a bit
[tpg/acess2.git] / KernelLand / Modules / USB / Core / usb_io.c
1 /*
2  * Acess2 USB Stack
3  * - By John Hodge (thePowersGang)
4  *
5  * usb_io.c
6  * - High-level IO
7  */
8 #define DEBUG   0
9
10 #include <usb_core.h>
11 #include "usb.h"
12 #include "usb_lowlevel.h"
13 #include <workqueue.h>
14
15 typedef struct sAsyncOp tAsyncOp;
16
17 struct sAsyncOp
18 {
19         tAsyncOp        *Next;
20         tUSBEndpoint    *Endpt;
21          int    Length;
22         void    *Data;
23 };
24
25 // === PROTOTYPES ===
26 void    USB_ReadDescriptor(tUSBInterface *Iface, int Type, int Index, int Length, void *Data);
27 void    USB_Request(tUSBInterface *Iface, int Endpoint, int Type, int Req, int Value, int Index, int Len, void *Data);
28 void    USB_AsyncCallback(void *Ptr, void *Buf, int Length);
29 void    USB_AsyncThread(void *unused);
30
31 // === GLOBALS ===
32 tWorkqueue      gUSB_AsyncQueue;
33
34 // === CODE ===
35 void USB_ReadDescriptor(tUSBInterface *Iface, int Type, int Index, int Length, void *Data)
36 {
37         USB_int_ReadDescriptor(Iface->Dev, 0, Type, Index, Length, Data);
38 }
39
40 void USB_Request(tUSBInterface *Iface, int Endpoint, int Type, int Req, int Value, int Index, int Len, void *Data)
41 {
42          int    endpt;
43
44         // Sanity check
45         if(Endpoint < 0 || Endpoint >= Iface->nEndpoints)
46                 return ;        
47
48         // Get endpoint number
49         if(Endpoint)
50                 endpt = Iface->Endpoints[Endpoint-1].EndpointNum;
51         else
52                 endpt = 0;
53         
54         USB_int_Request(Iface->Dev->Host, Iface->Dev->Address, endpt, Type, Req, Value, Index, Len, Data);
55 }
56
57
58 void USB_SendData(tUSBInterface *Dev, int Endpoint, int Length, void *Data)
59 {
60         Log_Warning("USB", "TODO: Implement USB_SendData");
61 }
62
63 void USB_RecvData(tUSBInterface *Dev, int Endpoint, int Length, void *Data)
64 {
65         Log_Warning("USB", "TODO: Implement USB_RecvData");
66 }
67
68 void USB_RecvDataA(tUSBInterface *Dev, int Endpoint, int Length, void *DataBuf, tUSB_DataCallback Callback)
69 {
70         tAsyncOp *op;
71         tUSBHost *host;
72
73         ENTER("pDev iEndpoint iLength pDataBuf", Dev, Endpoint, Length, DataBuf); 
74
75         op = malloc(sizeof(*op));
76         op->Next = NULL;
77         op->Endpt = &Dev->Endpoints[Endpoint-1];
78         op->Length = Length;
79         op->Data = DataBuf;
80
81         // TODO: Handle transfers that are larger than one packet
82
83         host = Dev->Dev->Host;
84         LOG("IN from %p %i:%i", host->Ptr, Dev->Dev->Address, op->Endpt->EndpointNum);
85         host->HostDef->SendIN(
86                 host->Ptr, Dev->Dev->Address, op->Endpt->EndpointNum,
87                 0, USB_AsyncCallback, op,
88                 DataBuf, Length
89                 );
90         
91         LEAVE('-');
92
93 //      Log_Warning("USB", "TODO: Implement USB_RecvDataA");
94 }
95
96 void USB_AsyncCallback(void *Ptr, void *Buf, int Length)
97 {
98         tAsyncOp *op = Ptr;
99         op->Length = Length;
100         LOG("adding %p to work queue", op);
101         Workqueue_AddWork(&gUSB_AsyncQueue, op);
102 }
103
104 void USB_AsyncThread(void *Unused)
105 {
106         Threads_SetName("USB Async IO Thread");
107         for(;;)
108         {
109                 tAsyncOp *op = Workqueue_GetWork(&gUSB_AsyncQueue);
110                 tUSBInterface   *iface = op->Endpt->Interface;
111
112                 LOG("op = %p", op);     
113
114                 iface->Driver->Endpoints[op->Endpt->EndpointIdx].DataAvail(
115                         iface, op->Endpt->EndpointIdx,
116                         op->Length, op->Data);
117         }
118 }
119

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