X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FModules%2FUSB%2FCore%2Fusb_io.c;h=9d58c7503169b4abecb6cb5eb38b2426bfcd6d81;hb=e02f66c7125bf18f77c6c53587238cbd49da2c89;hp=25ff59d260dcb3f8d19cb20de1c79341c62d3145;hpb=51ab5f489bc356940c95cc936fd0508e8f07ea97;p=tpg%2Facess2.git diff --git a/KernelLand/Modules/USB/Core/usb_io.c b/KernelLand/Modules/USB/Core/usb_io.c index 25ff59d2..9d58c750 100644 --- a/KernelLand/Modules/USB/Core/usb_io.c +++ b/KernelLand/Modules/USB/Core/usb_io.c @@ -11,21 +11,15 @@ #include "usb.h" #include "usb_lowlevel.h" #include - -typedef struct sAsyncOp tAsyncOp; - -struct sAsyncOp -{ - tAsyncOp *Next; - tUSBEndpoint *Endpt; - int Length; - void *Data; -}; +#include +#include "usb_async.h" // === PROTOTYPES === void USB_ReadDescriptor(tUSBInterface *Iface, int Type, int Index, int Length, void *Data); void USB_Request(tUSBInterface *Iface, int Endpoint, int Type, int Req, int Value, int Index, int Len, void *Data); -void USB_AsyncCallback(void *Ptr, void *Buf, int Length); +void USB_SendData(tUSBInterface *Dev, int Endpoint, size_t Length, const void *Data); +void USB_WakeCallback(void *Ptr, void *Buf, size_t Length); +void USB_AsyncCallback(void *Ptr, void *Buf, size_t Length); void USB_AsyncThread(void *unused); // === GLOBALS === @@ -55,17 +49,57 @@ void USB_Request(tUSBInterface *Iface, int Endpoint, int Type, int Req, int Valu } -void USB_SendData(tUSBInterface *Dev, int Endpoint, int Length, void *Data) +void USB_SendData(tUSBInterface *Dev, int Endpoint, size_t Length, const void *Data) { - Log_Warning("USB", "TODO: Implement USB_SendData"); + tUSBHost *host; + tUSBEndpoint *ep; + ENTER("pDev iEndpoint iLength pData", Dev, Endpoint, Length, Data); + + ep = &Dev->Endpoints[Endpoint-1]; + host = Dev->Dev->Host; + + Threads_ClearEvent(THREAD_EVENT_SHORTWAIT); + for( size_t ofs = 0; ofs < Length; ofs += ep->MaxPacketSize ) + { + size_t len = MIN(Length - ofs, ep->MaxPacketSize); + + host->HostDef->BulkOUT( + host->Ptr, Dev->Dev->Address*16 + Dev->Endpoints[Endpoint-1].EndpointNum, + 0, (len == Length - ofs ? USB_WakeCallback : NULL), Proc_GetCurThread(), + (char*)Data + ofs, len + ); + } + Threads_WaitEvents(THREAD_EVENT_SHORTWAIT); + + LEAVE('-'); } -void USB_RecvData(tUSBInterface *Dev, int Endpoint, int Length, void *Data) +void USB_RecvData(tUSBInterface *Dev, int Endpoint, size_t Length, void *Data) { - Log_Warning("USB", "TODO: Implement USB_RecvData"); + tUSBHost *host; + tUSBEndpoint *ep; + ENTER("pDev iEndpoint iLength pData", Dev, Endpoint, Length, Data); + + ep = &Dev->Endpoints[Endpoint-1]; + host = Dev->Dev->Host; + + Threads_ClearEvent(THREAD_EVENT_SHORTWAIT); + for( size_t ofs = 0; ofs < Length; ofs += ep->MaxPacketSize ) + { + size_t len = MIN(Length - ofs, ep->MaxPacketSize); + + host->HostDef->BulkIN( + host->Ptr, Dev->Dev->Address*16 + Dev->Endpoints[Endpoint-1].EndpointNum, + 0, (len == Length - ofs ? USB_WakeCallback : NULL), Proc_GetCurThread(), + (char*)Data + ofs, len + ); + } + Threads_WaitEvents(THREAD_EVENT_SHORTWAIT); + + LEAVE('-'); } -void USB_RecvDataA(tUSBInterface *Dev, int Endpoint, int Length, void *DataBuf, tUSB_DataCallback Callback) +void USB_RecvDataA(tUSBInterface *Dev, int Endpoint, size_t Length, void *DataBuf, tUSB_DataCallback Callback) { tAsyncOp *op; tUSBHost *host; @@ -79,21 +113,33 @@ void USB_RecvDataA(tUSBInterface *Dev, int Endpoint, int Length, void *DataBuf, op->Data = DataBuf; // TODO: Handle transfers that are larger than one packet + // TODO: Data toggle host = Dev->Dev->Host; + LOG("IN from %p %i:%i", host->Ptr, Dev->Dev->Address, op->Endpt->EndpointNum); - host->HostDef->SendIN( - host->Ptr, Dev->Dev->Address, op->Endpt->EndpointNum, - 0, USB_AsyncCallback, op, - DataBuf, Length - ); + for( size_t ofs = 0; ofs < Length; ofs += op->Endpt->MaxPacketSize ) + { + size_t len = MIN(Length - ofs, op->Endpt->MaxPacketSize); + + host->HostDef->BulkIN( + host->Ptr, Dev->Dev->Address*16 + op->Endpt->EndpointNum, + 0, (len == Length - ofs ? USB_AsyncCallback : NULL), op, + (char*)DataBuf + ofs, len + ); + } LEAVE('-'); // Log_Warning("USB", "TODO: Implement USB_RecvDataA"); } -void USB_AsyncCallback(void *Ptr, void *Buf, int Length) +void USB_WakeCallback(void *Ptr, void *Buf, size_t Length) +{ + Threads_PostEvent(Ptr, THREAD_EVENT_SHORTWAIT); +} + +void USB_AsyncCallback(void *Ptr, void *Buf, size_t Length) { tAsyncOp *op = Ptr; op->Length = Length; @@ -114,6 +160,8 @@ void USB_AsyncThread(void *Unused) iface->Driver->Endpoints[op->Endpt->EndpointIdx].DataAvail( iface, op->Endpt->EndpointIdx, op->Length, op->Data); + + free(op); } }