From 253e9e4a08af1d1d73fe4e3643c3c63e478d4b04 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Mon, 6 Aug 2012 18:09:35 +0800 Subject: [PATCH] USB - Updated code to use endpoint registration --- .../Modules/USB/Core/include/usb_core.h | 2 +- KernelLand/Modules/USB/Core/usb.c | 1 + KernelLand/Modules/USB/Core/usb.h | 3 ++ KernelLand/Modules/USB/Core/usb_devinit.c | 8 +++- KernelLand/Modules/USB/Core/usb_io.c | 37 +++++++++++++----- KernelLand/Modules/USB/Core/usb_lowlevel.c | 38 +++++++++++++------ KernelLand/Modules/USB/Core/usb_lowlevel.h | 2 +- KernelLand/Modules/USB/HID/main.c | 2 +- KernelLand/Modules/USB/UHCI/uhci.c | 15 +++++++- 9 files changed, 82 insertions(+), 26 deletions(-) diff --git a/KernelLand/Modules/USB/Core/include/usb_core.h b/KernelLand/Modules/USB/Core/include/usb_core.h index 5f494cb0..04a6ab9d 100644 --- a/KernelLand/Modules/USB/Core/include/usb_core.h +++ b/KernelLand/Modules/USB/Core/include/usb_core.h @@ -69,7 +69,7 @@ extern void USB_Request(tUSBInterface *Dev, int Endpoint, int Type, int Req, int // TODO: Async extern void USB_SendData(tUSBInterface *Dev, int Endpoint, size_t Length, const void *Data); extern void USB_RecvData(tUSBInterface *Dev, int Endpoint, size_t Length, void *Data); -extern void USB_RecvDataA(tUSBInterface *Dev, int Endpoint, size_t Length, void *DataBuf, tUSB_DataCallback Callback); +extern void USB_RecvDataA(tUSBInterface *Dev, int Endpoint, size_t Length, void *DataBuf); #endif diff --git a/KernelLand/Modules/USB/Core/usb.c b/KernelLand/Modules/USB/Core/usb.c index e20f53cd..ab2427a4 100644 --- a/KernelLand/Modules/USB/Core/usb.c +++ b/KernelLand/Modules/USB/Core/usb.c @@ -43,6 +43,7 @@ tUSBHub *USB_RegisterHost(tUSBHostDef *HostDef, void *ControllerPtr, int nPorts) host->RootHubDev.ParentHub = NULL; host->RootHubDev.Host = host; host->RootHubDev.Address = 0; + host->RootHubDev.EndpointHandles[0] = HostDef->InitControl(ControllerPtr, 0); // host->RootHubIf.Next = NULL; host->RootHubIf.Dev = &host->RootHubDev; diff --git a/KernelLand/Modules/USB/Core/usb.h b/KernelLand/Modules/USB/Core/usb.h index 0b6a3c19..24cd80ad 100644 --- a/KernelLand/Modules/USB/Core/usb.h +++ b/KernelLand/Modules/USB/Core/usb.h @@ -35,6 +35,7 @@ struct sUSBEndpoint tUSBInterface *Interface; int EndpointIdx; // Interface endpoint index int EndpointNum; // Device endpoint num + void *EndpointHandle; int PollingPeriod; // In 1ms intervals int MaxPacketSize; // In bytes @@ -74,6 +75,8 @@ struct sUSBDevice tUSBHost *Host; int Address; + void *EndpointHandles[16]; + struct sDescriptor_Device DevDesc; int nInterfaces; diff --git a/KernelLand/Modules/USB/Core/usb_devinit.c b/KernelLand/Modules/USB/Core/usb_devinit.c index 821cf301..30807ff4 100644 --- a/KernelLand/Modules/USB/Core/usb_devinit.c +++ b/KernelLand/Modules/USB/Core/usb_devinit.c @@ -50,7 +50,11 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port) } USB_int_SendSetupSetAddress(dev->Host, dev->Address); LOG("Assigned address %i", dev->Address); - + + dev->EndpointHandles[0] = dev->Host->HostDef->InitControl(dev->Host->Ptr, dev->Address << 4); + for( int i = 1; i < 16; i ++ ) + dev->EndpointHandles[i] = 0; + // 2. Get device information { struct sDescriptor_Device desc; @@ -262,6 +266,8 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port) dev_if->Endpoints[k].Type = endpt->Attributes | (endpt->Address & 0x80); dev_if->Endpoints[k].PollingAtoms = 0; dev_if->Endpoints[k].InputData = NULL; + + // TODO: Register endpoint early } // Initialise driver diff --git a/KernelLand/Modules/USB/Core/usb_io.c b/KernelLand/Modules/USB/Core/usb_io.c index 9a3c4173..346c4cd7 100644 --- a/KernelLand/Modules/USB/Core/usb_io.c +++ b/KernelLand/Modules/USB/Core/usb_io.c @@ -45,7 +45,7 @@ void USB_Request(tUSBInterface *Iface, int Endpoint, int Type, int Req, int Valu else endpt = 0; - USB_int_Request(Iface->Dev->Host, Iface->Dev->Address, endpt, Type, Req, Value, Index, Len, Data); + USB_int_Request(Iface->Dev, endpt, Type, Req, Value, Index, Len, Data); } @@ -53,11 +53,18 @@ void USB_SendData(tUSBInterface *Dev, int Endpoint, size_t Length, const void *D { tUSBHost *host; tUSBEndpoint *ep; - void *dest_hdl = (void*)(Dev->Dev->Address*16 + Dev->Endpoints[Endpoint-1].EndpointNum + 1); + void *dest_hdl; ENTER("pDev iEndpoint iLength pData", Dev, Endpoint, Length, Data); - ep = &Dev->Endpoints[Endpoint-1]; host = Dev->Dev->Host; + ep = &Dev->Endpoints[Endpoint-1]; + dest_hdl = Dev->Dev->EndpointHandles[ep->EndpointNum]; + LOG("dest_hdl = %p", dest_hdl); + if( !dest_hdl ) { + dest_hdl = host->HostDef->InitControl(host->Ptr, Dev->Dev->Address*16 + ep->EndpointNum); + Dev->Dev->EndpointHandles[ep->EndpointNum] = dest_hdl; + LOG("dest_hdl = %p (allocated)", dest_hdl); + } Threads_ClearEvent(THREAD_EVENT_SHORTWAIT); host->HostDef->SendBulk(host->Ptr, dest_hdl, USB_WakeCallback, Proc_GetCurThread(), 1, (void*)Data, Length); @@ -70,11 +77,18 @@ void USB_RecvData(tUSBInterface *Dev, int Endpoint, size_t Length, void *Data) { tUSBHost *host; tUSBEndpoint *ep; - void *dest_hdl = (void*)(Dev->Dev->Address*16 + Dev->Endpoints[Endpoint-1].EndpointNum + 1); + void *dest_hdl; ENTER("pDev iEndpoint iLength pData", Dev, Endpoint, Length, Data); - ep = &Dev->Endpoints[Endpoint-1]; host = Dev->Dev->Host; + ep = &Dev->Endpoints[Endpoint-1]; + dest_hdl = Dev->Dev->EndpointHandles[ep->EndpointNum]; + LOG("dest_hdl = %p", dest_hdl); + if( !dest_hdl ) { + dest_hdl = host->HostDef->InitControl(host->Ptr, Dev->Dev->Address*16 + ep->EndpointNum); + Dev->Dev->EndpointHandles[ep->EndpointNum] = dest_hdl; + LOG("dest_hdl = %p (allocated)", dest_hdl); + } Threads_ClearEvent(THREAD_EVENT_SHORTWAIT); host->HostDef->SendBulk(host->Ptr, dest_hdl, USB_WakeCallback, Proc_GetCurThread(), 0, Data, Length); @@ -83,11 +97,11 @@ void USB_RecvData(tUSBInterface *Dev, int Endpoint, size_t Length, void *Data) LEAVE('-'); } -void USB_RecvDataA(tUSBInterface *Dev, int Endpoint, size_t Length, void *DataBuf, tUSB_DataCallback Callback) +void USB_RecvDataA(tUSBInterface *Dev, int Endpoint, size_t Length, void *DataBuf) { tAsyncOp *op; tUSBHost *host; - void *dest_hdl = (void*)(Dev->Dev->Address*16 + Dev->Endpoints[Endpoint-1].EndpointNum + 1); + void *dest_hdl; ENTER("pDev iEndpoint iLength pDataBuf", Dev, Endpoint, Length, DataBuf); @@ -97,10 +111,13 @@ void USB_RecvDataA(tUSBInterface *Dev, int Endpoint, size_t Length, void *DataBu op->Length = Length; op->Data = DataBuf; - // TODO: Handle transfers that are larger than one packet - // TODO: Data toggle - host = Dev->Dev->Host; + dest_hdl = Dev->Dev->EndpointHandles[op->Endpt->EndpointNum]; + if( !dest_hdl ) { + dest_hdl = host->HostDef->InitControl(host->Ptr, Dev->Dev->Address*16 + op->Endpt->EndpointNum); + Dev->Dev->EndpointHandles[op->Endpt->EndpointNum] = dest_hdl; + LOG("dest_hdl = %p (allocated)", dest_hdl); + } LOG("IN from %p %i:%i", host->Ptr, Dev->Dev->Address, op->Endpt->EndpointNum); host->HostDef->SendBulk(host->Ptr, dest_hdl, USB_AsyncCallback, op, 0, DataBuf, Length); diff --git a/KernelLand/Modules/USB/Core/usb_lowlevel.c b/KernelLand/Modules/USB/Core/usb_lowlevel.c index 7cea58aa..4c62c3b1 100644 --- a/KernelLand/Modules/USB/Core/usb_lowlevel.c +++ b/KernelLand/Modules/USB/Core/usb_lowlevel.c @@ -14,7 +14,7 @@ #include // === PROTOTYPES === -void *USB_int_Request(tUSBHost *Host, int Addr, int EndPt, int Type, int Req, int Val, int Indx, int Len, void *Data); +void *USB_int_Request(tUSBDevice *Dev, int EndPt, int Type, int Req, int Val, int Indx, int Len, void *Data); void USB_int_WakeThread(void *Thread, void *Data, size_t Length); int USB_int_SendSetupSetAddress(tUSBHost *Host, int Address); int USB_int_ReadDescriptor(tUSBDevice *Dev, int Endpoint, int Type, int Index, int Length, void *Dest); @@ -22,17 +22,28 @@ char *USB_int_GetDeviceString(tUSBDevice *Dev, int Endpoint, int Index); int _UTF16to8(Uint16 *Input, int InputLen, char *Dest); // === CODE === -void *USB_int_Request(tUSBHost *Host, int Addr, int EndPt, int Type, int Req, int Val, int Indx, int Len, void *Data) +void *USB_int_Request(tUSBDevice *Device, int EndPt, int Type, int Req, int Val, int Indx, int Len, void *Data) { + tUSBHost *Host = Device->Host; void *hdl; // TODO: Sanity check (and check that Type is valid) struct sDeviceRequest req; - int dest = Addr * 16 + EndPt; // TODO: Validate - void *dest_hdl = (void*)(dest+1); // TODO: Get registered handle instead tThread *thisthread = Proc_GetCurThread(); + void *dest_hdl; + + ENTER("pDevice xEndPt iType iReq iVal iIndx iLen pData", + Device, EndPt, Type, Req, Val, Indx, Len, Data); - ENTER("pHost xdest iType iReq iVal iIndx iLen pData", - Host, dest, Type, Req, Val, Indx, Len, Data); + if( EndPt < 0 || EndPt >= 16 ) { + LEAVE('n'); + return NULL; + } + + dest_hdl = Device->EndpointHandles[EndPt]; + if( !dest_hdl ) { + dest_hdl = Host->HostDef->InitControl(Host->Ptr, Device->Address*16 + EndPt); + Device->EndpointHandles[EndPt] = dest_hdl; + } req.ReqType = Type; req.Request = Req; @@ -73,18 +84,23 @@ void USB_int_WakeThread(void *Thread, void *Data, size_t Length) int USB_int_SendSetupSetAddress(tUSBHost *Host, int Address) { - USB_int_Request(Host, 0, 0, 0x00, 5, Address & 0x7F, 0, 0, NULL); + USB_int_Request(&Host->RootHubDev, 0, 0x00, 5, Address & 0x7F, 0, 0, NULL); return 0; } int USB_int_ReadDescriptor(tUSBDevice *Dev, int Endpoint, int Type, int Index, int Length, void *Dest) { struct sDeviceRequest req; - int dest = Dev->Address*16 + Endpoint; - void *dest_hdl = (void*)(dest+1); // TODO: Get correct handle + void *dest_hdl; + + dest_hdl = Dev->EndpointHandles[Endpoint]; + if( !dest_hdl ) { + dest_hdl = Dev->Host->HostDef->InitControl(Dev->Host->Ptr, Dev->Address*16 + Endpoint); + Dev->EndpointHandles[Endpoint] = dest_hdl; + } - ENTER("pDev xdest iType iIndex iLength pDest", - Dev, dest, Type, Index, Length, Dest); + ENTER("pDev xEndpoint iType iIndex iLength pDest", + Dev, Endpoint, Type, Index, Length, Dest); req.ReqType = 0x80; req.ReqType |= ((Type >> 8) & 0x3) << 5; // Bits 5/6 diff --git a/KernelLand/Modules/USB/Core/usb_lowlevel.h b/KernelLand/Modules/USB/Core/usb_lowlevel.h index 9159cbac..4282f282 100644 --- a/KernelLand/Modules/USB/Core/usb_lowlevel.h +++ b/KernelLand/Modules/USB/Core/usb_lowlevel.h @@ -8,7 +8,7 @@ #ifndef _USB_LOWLEVEL_H_ #define _USB_LOWLEVEL_H_ -extern void *USB_int_Request(tUSBHost *Host, int Addr, int EndPt, int Type, int Req, int Val, int Indx, int Len, void *Data); +extern void *USB_int_Request(tUSBDevice *Dev, int EndPt, int Type, int Req, int Val, int Indx, int Len, void *Data); extern int USB_int_SendSetupSetAddress(tUSBHost *Host, int Address); extern int USB_int_ReadDescriptor(tUSBDevice *Dev, int Endpoint, int Type, int Index, int Length, void *Dest); extern char *USB_int_GetDeviceString(tUSBDevice *Dev, int Endpoint, int Index); diff --git a/KernelLand/Modules/USB/HID/main.c b/KernelLand/Modules/USB/HID/main.c index 6b36809a..c2802737 100644 --- a/KernelLand/Modules/USB/HID/main.c +++ b/KernelLand/Modules/USB/HID/main.c @@ -149,7 +149,7 @@ void HID_DeviceConnected(tUSBInterface *Dev, void *Descriptors, size_t Descripto // --- Read and parse report descriptor --- // NOTE: Also does sub-driver selection and initialisation - Uint8 *report_data = alloca(report_len); + Uint8 report_data[report_len]; USB_ReadDescriptor(Dev, 0x1022, 0, report_len, report_data); HID_int_ParseReport(Dev, report_data, report_len, &gHID_RootCallbacks); diff --git a/KernelLand/Modules/USB/UHCI/uhci.c b/KernelLand/Modules/USB/UHCI/uhci.c index 9c5a4bd6..61b71cad 100644 --- a/KernelLand/Modules/USB/UHCI/uhci.c +++ b/KernelLand/Modules/USB/UHCI/uhci.c @@ -550,8 +550,14 @@ void *UHCI_SendControl(void *Ptr, void *Endpt, tUSBHostCb Cb, void *CbData, int Dest = (int)Endpt-1; int Tgl = 0; + if( Endpt == NULL ) { + Log_Error("UHCI", "Passed a NULL Endpoint handle"); + LEAVE('n'); + return NULL; + } + // Sanity check Endpt - if( (tVAddr)Endpt > 0x7FF ) { + if( (tVAddr)Endpt > 0x800 ) { LEAVE('n'); return NULL; } @@ -617,6 +623,13 @@ void *UHCI_SendBulk(void *Ptr, void *Endpt, tUSBHostCb Cb, void *CbData, int bOu ENTER("pPtr pEndpt pCb pCbData bOutbound pData iLength", Ptr, Dest, Cb, CbData, bOutbound, Data, Length); + if( Endpt == NULL ) { + Log_Error("UHCI", "Passed a NULL Endpoint handle"); + LEAVE('n'); + return NULL; + } + + // Sanity check Endpt // TODO: Validation // TODO: Data toggle -- 2.20.1