Modules/USB - Interrupt endpoints work
[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 #include "usb_async.h"
15
16 // === PROTOTYPES ===
17 void    USB_ReadDescriptor(tUSBInterface *Iface, int Type, int Index, int Length, void *Data);
18 void    USB_Request(tUSBInterface *Iface, int Endpoint, int Type, int Req, int Value, int Index, int Len, void *Data);
19 void    USB_AsyncCallback(void *Ptr, void *Buf, size_t Length);
20 void    USB_AsyncThread(void *unused);
21
22 // === GLOBALS ===
23 tWorkqueue      gUSB_AsyncQueue;
24
25 // === CODE ===
26 void USB_ReadDescriptor(tUSBInterface *Iface, int Type, int Index, int Length, void *Data)
27 {
28         USB_int_ReadDescriptor(Iface->Dev, 0, Type, Index, Length, Data);
29 }
30
31 void USB_Request(tUSBInterface *Iface, int Endpoint, int Type, int Req, int Value, int Index, int Len, void *Data)
32 {
33          int    endpt;
34
35         // Sanity check
36         if(Endpoint < 0 || Endpoint >= Iface->nEndpoints)
37                 return ;        
38
39         // Get endpoint number
40         if(Endpoint)
41                 endpt = Iface->Endpoints[Endpoint-1].EndpointNum;
42         else
43                 endpt = 0;
44         
45         USB_int_Request(Iface->Dev->Host, Iface->Dev->Address, endpt, Type, Req, Value, Index, Len, Data);
46 }
47
48
49 void USB_SendData(tUSBInterface *Dev, int Endpoint, int Length, void *Data)
50 {
51         Log_Warning("USB", "TODO: Implement USB_SendData");
52 }
53
54 void USB_RecvData(tUSBInterface *Dev, int Endpoint, int Length, void *Data)
55 {
56         Log_Warning("USB", "TODO: Implement USB_RecvData");
57 }
58
59 void USB_RecvDataA(tUSBInterface *Dev, int Endpoint, int Length, void *DataBuf, tUSB_DataCallback Callback)
60 {
61         tAsyncOp *op;
62         tUSBHost *host;
63
64         ENTER("pDev iEndpoint iLength pDataBuf", Dev, Endpoint, Length, DataBuf); 
65
66         op = malloc(sizeof(*op));
67         op->Next = NULL;
68         op->Endpt = &Dev->Endpoints[Endpoint-1];
69         op->Length = Length;
70         op->Data = DataBuf;
71
72         // TODO: Handle transfers that are larger than one packet
73         // TODO: Data toggle
74
75         host = Dev->Dev->Host;
76         LOG("IN from %p %i:%i", host->Ptr, Dev->Dev->Address, op->Endpt->EndpointNum);
77         host->HostDef->BulkIN(
78                 host->Ptr, Dev->Dev->Address*16 + op->Endpt->EndpointNum,
79                 0, USB_AsyncCallback, op,
80                 DataBuf, Length
81                 );
82         
83         LEAVE('-');
84
85 //      Log_Warning("USB", "TODO: Implement USB_RecvDataA");
86 }
87
88 void USB_AsyncCallback(void *Ptr, void *Buf, size_t Length)
89 {
90         tAsyncOp *op = Ptr;
91         op->Length = Length;
92         LOG("adding %p to work queue", op);
93         Workqueue_AddWork(&gUSB_AsyncQueue, op);
94 }
95
96 void USB_AsyncThread(void *Unused)
97 {
98         Threads_SetName("USB Async IO Thread");
99         for(;;)
100         {
101                 tAsyncOp *op = Workqueue_GetWork(&gUSB_AsyncQueue);
102                 tUSBInterface   *iface = op->Endpt->Interface;
103
104                 LOG("op = %p", op);     
105
106                 iface->Driver->Endpoints[op->Endpt->EndpointIdx].DataAvail(
107                         iface, op->Endpt->EndpointIdx,
108                         op->Length, op->Data);
109                 
110                 free(op);
111         }
112 }
113

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