USB - Updated code to use endpoint registration
authorJohn Hodge <[email protected]>
Mon, 6 Aug 2012 10:09:35 +0000 (18:09 +0800)
committerJohn Hodge <[email protected]>
Mon, 6 Aug 2012 10:09:35 +0000 (18:09 +0800)
KernelLand/Modules/USB/Core/include/usb_core.h
KernelLand/Modules/USB/Core/usb.c
KernelLand/Modules/USB/Core/usb.h
KernelLand/Modules/USB/Core/usb_devinit.c
KernelLand/Modules/USB/Core/usb_io.c
KernelLand/Modules/USB/Core/usb_lowlevel.c
KernelLand/Modules/USB/Core/usb_lowlevel.h
KernelLand/Modules/USB/HID/main.c
KernelLand/Modules/USB/UHCI/uhci.c

index 5f494cb..04a6ab9 100644 (file)
@@ -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
 
index e20f53c..ab2427a 100644 (file)
@@ -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;
index 0b6a3c1..24cd80a 100644 (file)
@@ -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;
index 821cf30..30807ff 100644 (file)
@@ -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
index 9a3c417..346c4cd 100644 (file)
@@ -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);
index 7cea58a..4c62c3b 100644 (file)
@@ -14,7 +14,7 @@
 #include <events.h>
 
 // === 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
index 9159cba..4282f28 100644 (file)
@@ -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);
index 6b36809..c280273 100644 (file)
@@ -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);
        
index 9c5a4bd..61b71ca 100644 (file)
@@ -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
 

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