Modules/USB - Cleanup and sorting, added hub code to build
authorJohn Hodge <[email protected]>
Tue, 29 Nov 2011 03:22:59 +0000 (11:22 +0800)
committerJohn Hodge <[email protected]>
Tue, 29 Nov 2011 03:22:59 +0000 (11:22 +0800)
- Polling code in the works
- TODO: Better Async support

12 files changed:
Modules/USB/Core/Makefile
Modules/USB/Core/hub.c
Modules/USB/Core/include/usb_core.h
Modules/USB/Core/main.c
Modules/USB/Core/usb.c
Modules/USB/Core/usb.h
Modules/USB/Core/usb_devinit.c [new file with mode: 0644]
Modules/USB/Core/usb_io.c [new file with mode: 0644]
Modules/USB/Core/usb_lowlevel.c
Modules/USB/Core/usb_lowlevel.h
Modules/USB/Core/usb_poll.c [new file with mode: 0644]
Modules/USB/UHCI/uhci.c

index 6ef0f03..4d6e684 100644 (file)
@@ -1,7 +1,9 @@
 #
 #
 
-OBJ = main.o usb.o usb_lowlevel.o
+OBJ  = main.o
+OBJ += usb.o usb_lowlevel.o usb_devinit.o usb_io.o usb_poll.o
+OBJ += hub.o
 CPPFLAGS = -Iinclude
 NAME = Core
 
index 1e56bee..08295b1 100644 (file)
@@ -34,12 +34,13 @@ struct sHubInfo
         int    PowerOnDelay;   // in ms
         int    nPorts;
        Uint8   DeviceRemovable[];
-}
+};
 
 // === PROTOTYPES ===
 void   Hub_Connected(tUSBInterface *Dev);
 void   Hub_Disconnected(tUSBInterface *Dev);
 void   Hub_PortStatusChange(tUSBInterface *Dev, int Length, void *Data);
+void   Hub_int_HandleChange(tUSBInterface *Dev, int Port);
 
 // === GLOBALS ===
 tUSBDriver     gUSBHub_Driver = {
@@ -50,17 +51,28 @@ tUSBDriver  gUSBHub_Driver = {
        .MaxEndpoints = 1,
        .Endpoints = {
                {0x83, Hub_PortStatusChange}
-       };
+       }
 };
 
 // === CODE ===
+#if 0
+int Hub_DriverInitialise(char **Arguments)
+{
+       USB_RegisterDriver( &gUSBHub_Driver );
+       return 0;
+}
+#endif
+
 void Hub_Connected(tUSBInterface *Dev)
 {
        struct sHubDescriptor   hub_desc;
        struct sHubInfo *info;  
 
        // Read hub descriptor
-       USB_ReadDescriptor(Dev, 0x29, 0, sizeof(*hub_desc), hub_desc);
+       USB_ReadDescriptor(Dev, 0x29, 0, sizeof(hub_desc), &hub_desc);
+
+       LOG("%i Ports", hub_desc.NbrPorts);
+       LOG("Takes %i ms for power to stabilise", hub_desc.PwrOn2PwrGood*2);
 
        // Allocate infomation structure
        info = malloc(sizeof(*info) + (hub_desc.NbrPorts+7)/8);
@@ -83,7 +95,9 @@ void Hub_Connected(tUSBInterface *Dev)
 
 void Hub_Disconnected(tUSBInterface *Dev)
 {
-       USB_RemoveHub(Dev);
+       struct sHubInfo *info = USB_GetDeviceDataPtr(Dev);
+       USB_RemoveHub(info->HubPtr);
+       free(info);
 }
 
 void Hub_PortStatusChange(tUSBInterface *Dev, int Length, void *Data)
@@ -120,7 +134,7 @@ void Hub_int_HandleChange(tUSBInterface *Dev, int Port)
                        Time_Delay(info->PowerOnDelay);
                        // - Reset
                        USB_Request(Dev, 0, 0x23, SET_FEATURE, PORT_RESET, Port, 0, NULL);
-                       Time_Delay(50);
+                       Time_Delay(20); // Spec says 10ms after reset, but how long is reset?
                        // - Enable
                        USB_Request(Dev, 0, 0x23, SET_FEATURE, PORT_ENABLE, Port, 0, NULL);
                        // - Poke USB Stack
index 104d0e3..369de5e 100644 (file)
@@ -8,6 +8,8 @@
 #ifndef _USB_CORE_H_
 #define _USB_CORE_H_
 
+#include <acess.h>
+
 typedef struct sUSBInterface   tUSBInterface;
 typedef struct sUSBDriver      tUSBDriver;
 
@@ -52,6 +54,7 @@ extern void   USB_SetDeviceDataPtr(tUSBInterface *Dev, void *Ptr);
 
 extern void    USB_StartPollingEndpoint(tUSBInterface *Dev, int Endpoint);
 extern void    USB_ReadDescriptor(tUSBInterface *Dev, int Type, int Index, int Length, void *Data);
+extern void    USB_Request(tUSBInterface *Dev, int Endpoint, int Type, int Req, int Value, int Index, int Len, void *Data);
 // TODO: Async
 extern void    USB_SendData(tUSBInterface *Dev, int Endpoint, int Length, void *Data);
 extern void    USB_RecvData(tUSBInterface *Dev, int Endpoint, int Length, void *Data);
index 277cf7c..d92c772 100644 (file)
@@ -30,8 +30,6 @@ tDevFS_Driver gUSB_DrvInfo = {
        }
 };
 tUSBHost       *gUSB_Hosts = NULL;
-tUSBInterface  *gUSB_InterruptDevs = NULL;
-tUSBInterface  *gUSB_InterruptLast = NULL;
 
 // === CODE ===
 /**
@@ -43,22 +41,6 @@ int USB_Install(char **Arguments)
        return MODULE_ERR_OK;
 }
 
-/**
- * \brief USB polling thread
- */
-int USB_PollThread(void *unused)
-{
-       for(;;)
-       {
-               for( tUSBInterface *dev = gUSB_InterruptDevs; dev; dev = dev->Next )
-               {
-//                     hub->CheckPorts(hub, hub->Device);
-               }
-               // TODO: Fine tune
-               Time_Delay(250);
-       }
-}
-
 /**
  * \brief Called just before module is unloaded
  */
index ca86a2b..ae80a11 100644 (file)
@@ -1,30 +1,27 @@
 /*
- * Acess 2 USB Stack
+ * Acess2 USB Stack
  * - By John Hodge (thePowersGang)
  *
  * usb.c
- * - USB Packet Control
+ * - USB Structure
  */
 #define DEBUG  1
 #include <acess.h>
 #include <vfs.h>
 #include <drv_pci.h>
 #include "usb.h"
-#include "usb_proto.h"
-#include "usb_lowlevel.h"
 
 // === IMPORTS ===
 extern tUSBHost        *gUSB_Hosts;
+extern tUSBDriver gUSBHub_Driver;
 
 // === STRUCTURES ===
 
 // === PROTOTYPES ===
 tUSBHub        *USB_RegisterHost(tUSBHostDef *HostDef, void *ControllerPtr, int nPorts);
-void   USB_DeviceConnected(tUSBHub *Hub, int Port);
-void   USB_DeviceDisconnected(tUSBHub *Hub, int Port);
-void   *USB_GetDeviceDataPtr(tUSBInterface *Dev);
-void   USB_SetDeviceDataPtr(tUSBInterface *Dev, void *Ptr);
- int   USB_int_AllocateAddress(tUSBHost *Host);
+
+// === GLOBALS ===
+tUSBDriver     *gUSB_InterfaceDrivers = &gUSBHub_Driver;
 
 // === CODE ===
 tUSBHub *USB_RegisterHost(tUSBHostDef *HostDef, void *ControllerPtr, int nPorts)
@@ -61,174 +58,33 @@ tUSBHub *USB_RegisterHost(tUSBHostDef *HostDef, void *ControllerPtr, int nPorts)
        return &host->RootHub;
 }
 
-void USB_DeviceConnected(tUSBHub *Hub, int Port)
+void USB_RegisterDriver(tUSBDriver *Driver)
 {
-       tUSBDevice      *dev;
-       if( Port >= Hub->nPorts )       return ;
-       if( Hub->Devices[Port] )        return ;
-
-       ENTER("pHub iPort", Hub, Port);
-
-       // 0. Perform port init? (done in hub?) 
-       
-       // Create structure
-       dev = malloc(sizeof(tUSBDevice));
-       dev->ParentHub = Hub;
-       dev->Host = Hub->Interface->Dev->Host;
-       dev->Address = 0;
-
-       // 1. Assign an address
-       dev->Address = USB_int_AllocateAddress(dev->Host);
-       if(dev->Address == 0) {
-               Log_Error("USB", "No addresses avaliable on host %p", dev->Host);
-               free(dev);
-               LEAVE('-');
-               return ;
-       }
-       USB_int_SendSetupSetAddress(dev->Host, dev->Address);
-       LOG("Assigned address %i", dev->Address);
-       
-       // 2. Get device information
-       {
-               struct sDescriptor_Device       desc;
-               LOG("Getting device descriptor");
-               // Endpoint 0, Desc Type 1, Index 0
-               USB_int_ReadDescriptor(dev, 0, 1, 0, sizeof(desc), &desc);
-               
-               LOG("Device Descriptor = {");
-               LOG(" .Length = %i", desc.Length);
-               LOG(" .Type = %i", desc.Type);
-               LOG(" .USBVersion = 0x%04x", desc.USBVersion);
-               LOG(" .DeviceClass = 0x%02x", desc.DeviceClass);
-               LOG(" .DeviceSubClass = 0x%02x", desc.DeviceSubClass);
-               LOG(" .DeviceProtocol = 0x%02x", desc.DeviceProtocol);
-               LOG(" .MaxPacketSize = 0x%02x", desc.MaxPacketSize);
-               LOG(" .VendorID = 0x%04x", desc.VendorID);
-               LOG(" .ProductID = 0x%04x", desc.ProductID);
-               LOG(" .DeviceID = 0x%04x", desc.DeviceID);
-               LOG(" .ManufacturerStr = Str %i", desc.ManufacturerStr);
-               LOG(" .ProductStr = Str %i", desc.ProductStr);
-               LOG(" .SerialNumberStr = Str %i", desc.SerialNumberStr);
-               LOG(" .NumConfigurations = %i", desc.SerialNumberStr);
-               LOG("}");
-               
-               if( desc.ManufacturerStr )
-               {
-                       char    *tmp = USB_int_GetDeviceString(dev, 0, desc.ManufacturerStr);
-                       LOG("ManufacturerStr = '%s'", tmp);
-                       free(tmp);
-               }
-               if( desc.ProductStr )
-               {
-                       char    *tmp = USB_int_GetDeviceString(dev, 0, desc.ProductStr);
-                       LOG("ProductStr = '%s'", tmp);
-                       free(tmp);
-               }
-               if( desc.SerialNumberStr )
-               {
-                       char    *tmp = USB_int_GetDeviceString(dev, 0, desc.SerialNumberStr);
-                       LOG("SerialNumbertStr = '%s'", tmp);
-                       free(tmp);
-               }
-       }
-       
-       // 3. Get configurations
-       for( int i = 0; i < 1; i ++ )
-       {
-               struct sDescriptor_Configuration        desc;
-               void    *full_buf;
-               char    *cur_ptr;
-               
-               USB_int_ReadDescriptor(dev, 0, 2, i, sizeof(desc), &desc);
-               LOG("Configuration Descriptor %i = {", i);
-               LOG(" .Length = %i", desc.Length);
-               LOG(" .Type = %i", desc.Type);
-               LOG(" .TotalLength = 0x%x", LittleEndian16(desc.TotalLength));
-               LOG(" .NumInterfaces = %i", desc.NumInterfaces);
-               LOG(" .ConfigurationValue = %i", desc.ConfigurationValue);
-               LOG(" .ConfigurationStr = %i", desc.ConfigurationStr);
-               LOG(" .AttributesBmp = 0b%b", desc.AttributesBmp);
-               LOG(" .MaxPower = %i (*2mA)", desc.MaxPower);
-               LOG("}");
-               if( desc.ConfigurationStr ) {
-                       char    *tmp = USB_int_GetDeviceString(dev, 0, desc.ConfigurationStr);
-                       LOG("ConfigurationStr = '%s'", tmp);
-                       free(tmp);
-               }
-
-               cur_ptr = full_buf = malloc( LittleEndian16(desc.TotalLength) );
-               USB_int_ReadDescriptor(dev, 0, 2, i, desc.TotalLength, full_buf);
-
-               cur_ptr += desc.Length;
-
-               // TODO: Interfaces
-               for( int j = 0; j < desc.NumInterfaces; j ++ )
-               {
-                       struct sDescriptor_Interface *iface;
-                       iface = (void*)cur_ptr;
-                       // TODO: Sanity check with remaining space
-                       cur_ptr += sizeof(*iface);
-                       
-                       LOG("Interface %i/%i = {", i, j);
-                       LOG(" .InterfaceNum = %i", iface->InterfaceNum);
-                       LOG(" .NumEndpoints = %i", iface->NumEndpoints);
-                       LOG(" .InterfaceClass = 0x%x", iface->InterfaceClass);
-                       LOG(" .InterfaceSubClass = 0x%x", iface->InterfaceSubClass);
-                       LOG(" .InterfaceProcol = 0x%x", iface->InterfaceProtocol);
-
-                       if( iface->InterfaceStr ) {
-                               char    *tmp = USB_int_GetDeviceString(dev, 0, iface->InterfaceStr);
-                               LOG(" .InterfaceStr = %i '%s'", iface->InterfaceStr, tmp);
-                               free(tmp);
-                       }
-                       LOG("}");
-
-                       for( int k = 0; k < iface->NumEndpoints; k ++ )
-                       {
-                               struct sDescriptor_Endpoint *endpt;
-                               endpt = (void*)cur_ptr;
-                               // TODO: Sanity check with remaining space
-                               cur_ptr += sizeof(*endpt);
-                               
-                               LOG("Endpoint %i/%i/%i = {", i, j, k);
-                               LOG(" .Address = 0x%2x", endpt->Address);
-                               LOG(" .Attributes = 0b%8b", endpt->Attributes);
-                               LOG(" .MaxPacketSize = %i", LittleEndian16(endpt->MaxPacketSize));
-                               LOG(" .PollingInterval = %i", endpt->PollingInterval);
-                               LOG("}");
-                       }
-               }
-               
-               free(full_buf);
-       }
-
-       // Done.
-       LEAVE('-');
+       Log_Warning("USB", "TODO: Implement USB_RegisterDriver");
 }
 
-void USB_DeviceDisconnected(tUSBHub *Hub, int Port)
+// --- Hub Registration ---
+// NOTE: Doesn't do much nowdays
+tUSBHub *USB_RegisterHub(tUSBInterface *Device, int PortCount)
 {
+       tUSBHub *ret;
        
+       ret = malloc(sizeof(tUSBHub) + sizeof(ret->Devices[0])*PortCount);
+       ret->Interface = Device;
+       ret->nPorts = PortCount;
+       memset(ret->Devices, 0, sizeof(ret->Devices[0])*PortCount);
+       return ret;
 }
 
-void *USB_GetDeviceDataPtr(tUSBInterface *Dev) { return Dev->Data; }
-void USB_SetDeviceDataPtr(tUSBInterface *Dev, void *Ptr) { Dev->Data = Ptr; }
-
-int USB_int_AllocateAddress(tUSBHost *Host)
+void USB_RemoveHub(tUSBHub *Hub)
 {
-        int    i;
-       for( i = 1; i < 128; i ++ )
+       for( int i = 0; i < Hub->nPorts; i ++ )
        {
-               if(Host->AddressBitmap[i/8] & (1 << (i%8)))
-                       continue ;
-               Host->AddressBitmap[i/8] |= 1 << (i%8);
-               return i;
+               if( Hub->Devices[i] )
+               {
+                       USB_DeviceDisconnected( Hub, i );
+               }
        }
-       return 0;
-}
-
-void USB_int_DeallocateAddress(tUSBHost *Host, int Address)
-{
-       Host->AddressBitmap[Address/8] &= ~(1 << (Address%8));
+       free(Hub);
 }
 
index 8759ee1..a61ce00 100644 (file)
@@ -1,6 +1,9 @@
 /*
- * AcessOS Version 1
- * USB Stack
+ * Acess2 USB Stack
+ * - By John Hodge (thePowersGang)
+ * 
+ * usb.h
+ * - USB Internal definitions
  */
 #ifndef _USB_H_
 #define _USB_H_
@@ -27,11 +30,12 @@ struct sUSBHub
 
 struct sUSBEndpoint
 {
-       tUSBEndpoint    *Next;  // In the poll list
+       tUSBEndpoint    *Next;  // In the segmented list
        tUSBInterface   *Interface;
         int    EndpointNum;
        
         int    PollingPeriod;  // In 1ms intervals
+        int    PollingAtoms;   // *INTERNAL* usb_poll.c
         int    MaxPacketSize;  // In bytes
 
        Uint8   Type;   // Same as sUSBDriver.Endpoints.Type
diff --git a/Modules/USB/Core/usb_devinit.c b/Modules/USB/Core/usb_devinit.c
new file mode 100644 (file)
index 0000000..8d901a5
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Acess 2 USB Stack
+ * - By John Hodge (thePowersGang)
+ *
+ * usb_devinit.c
+ * - USB Device Initialisation
+ */
+#define DEBUG  1
+
+#include <acess.h>
+#include <vfs.h>
+#include <drv_pci.h>
+#include "usb.h"
+#include "usb_proto.h"
+#include "usb_lowlevel.h"
+
+// === PROTOTYPES ===
+void   USB_DeviceConnected(tUSBHub *Hub, int Port);
+void   USB_DeviceDisconnected(tUSBHub *Hub, int Port);
+void   *USB_GetDeviceDataPtr(tUSBInterface *Dev);
+void   USB_SetDeviceDataPtr(tUSBInterface *Dev, void *Ptr);
+ int   USB_int_AllocateAddress(tUSBHost *Host);
+
+// === CODE ===
+void USB_DeviceConnected(tUSBHub *Hub, int Port)
+{
+       tUSBDevice      *dev;
+       if( Port >= Hub->nPorts )       return ;
+       if( Hub->Devices[Port] )        return ;
+
+       ENTER("pHub iPort", Hub, Port);
+
+       // Device should be in 'Default' state
+       
+       // Create structure
+       dev = malloc(sizeof(tUSBDevice));
+       dev->ParentHub = Hub;
+       dev->Host = Hub->Interface->Dev->Host;
+       dev->Address = 0;
+
+       // 1. Assign an address
+       dev->Address = USB_int_AllocateAddress(dev->Host);
+       if(dev->Address == 0) {
+               Log_Error("USB", "No addresses avaliable on host %p", dev->Host);
+               free(dev);
+               LEAVE('-');
+               return ;
+       }
+       USB_int_SendSetupSetAddress(dev->Host, dev->Address);
+       LOG("Assigned address %i", dev->Address);
+       
+       // 2. Get device information
+       {
+               struct sDescriptor_Device       desc;
+               LOG("Getting device descriptor");
+               // Endpoint 0, Desc Type 1, Index 0
+               USB_int_ReadDescriptor(dev, 0, 1, 0, sizeof(desc), &desc);
+               
+               LOG("Device Descriptor = {");
+               LOG(" .Length = %i", desc.Length);
+               LOG(" .Type = %i", desc.Type);
+               LOG(" .USBVersion = 0x%04x", desc.USBVersion);
+               LOG(" .DeviceClass = 0x%02x", desc.DeviceClass);
+               LOG(" .DeviceSubClass = 0x%02x", desc.DeviceSubClass);
+               LOG(" .DeviceProtocol = 0x%02x", desc.DeviceProtocol);
+               LOG(" .MaxPacketSize = 0x%02x", desc.MaxPacketSize);
+               LOG(" .VendorID = 0x%04x", desc.VendorID);
+               LOG(" .ProductID = 0x%04x", desc.ProductID);
+               LOG(" .DeviceID = 0x%04x", desc.DeviceID);
+               LOG(" .ManufacturerStr = Str %i", desc.ManufacturerStr);
+               LOG(" .ProductStr = Str %i", desc.ProductStr);
+               LOG(" .SerialNumberStr = Str %i", desc.SerialNumberStr);
+               LOG(" .NumConfigurations = %i", desc.SerialNumberStr);
+               LOG("}");
+               
+               if( desc.ManufacturerStr )
+               {
+                       char    *tmp = USB_int_GetDeviceString(dev, 0, desc.ManufacturerStr);
+                       LOG("ManufacturerStr = '%s'", tmp);
+                       free(tmp);
+               }
+               if( desc.ProductStr )
+               {
+                       char    *tmp = USB_int_GetDeviceString(dev, 0, desc.ProductStr);
+                       LOG("ProductStr = '%s'", tmp);
+                       free(tmp);
+               }
+               if( desc.SerialNumberStr )
+               {
+                       char    *tmp = USB_int_GetDeviceString(dev, 0, desc.SerialNumberStr);
+                       LOG("SerialNumbertStr = '%s'", tmp);
+                       free(tmp);
+               }
+       }
+       
+       // 3. Get configurations
+       for( int i = 0; i < 1; i ++ )
+       {
+               struct sDescriptor_Configuration        desc;
+               void    *full_buf;
+               char    *cur_ptr;
+               
+               USB_int_ReadDescriptor(dev, 0, 2, i, sizeof(desc), &desc);
+               LOG("Configuration Descriptor %i = {", i);
+               LOG(" .Length = %i", desc.Length);
+               LOG(" .Type = %i", desc.Type);
+               LOG(" .TotalLength = 0x%x", LittleEndian16(desc.TotalLength));
+               LOG(" .NumInterfaces = %i", desc.NumInterfaces);
+               LOG(" .ConfigurationValue = %i", desc.ConfigurationValue);
+               LOG(" .ConfigurationStr = %i", desc.ConfigurationStr);
+               LOG(" .AttributesBmp = 0b%b", desc.AttributesBmp);
+               LOG(" .MaxPower = %i (*2mA)", desc.MaxPower);
+               LOG("}");
+               if( desc.ConfigurationStr ) {
+                       char    *tmp = USB_int_GetDeviceString(dev, 0, desc.ConfigurationStr);
+                       LOG("ConfigurationStr = '%s'", tmp);
+                       free(tmp);
+               }
+
+               cur_ptr = full_buf = malloc( LittleEndian16(desc.TotalLength) );
+               USB_int_ReadDescriptor(dev, 0, 2, i, desc.TotalLength, full_buf);
+
+               cur_ptr += desc.Length;
+
+               // TODO: Interfaces
+               for( int j = 0; j < desc.NumInterfaces; j ++ )
+               {
+                       struct sDescriptor_Interface *iface;
+                       iface = (void*)cur_ptr;
+                       // TODO: Sanity check with remaining space
+                       cur_ptr += sizeof(*iface);
+                       
+                       LOG("Interface %i/%i = {", i, j);
+                       LOG(" .InterfaceNum = %i", iface->InterfaceNum);
+                       LOG(" .NumEndpoints = %i", iface->NumEndpoints);
+                       LOG(" .InterfaceClass = 0x%x", iface->InterfaceClass);
+                       LOG(" .InterfaceSubClass = 0x%x", iface->InterfaceSubClass);
+                       LOG(" .InterfaceProcol = 0x%x", iface->InterfaceProtocol);
+
+                       if( iface->InterfaceStr ) {
+                               char    *tmp = USB_int_GetDeviceString(dev, 0, iface->InterfaceStr);
+                               LOG(" .InterfaceStr = %i '%s'", iface->InterfaceStr, tmp);
+                               free(tmp);
+                       }
+                       LOG("}");
+
+                       for( int k = 0; k < iface->NumEndpoints; k ++ )
+                       {
+                               struct sDescriptor_Endpoint *endpt;
+                               endpt = (void*)cur_ptr;
+                               // TODO: Sanity check with remaining space
+                               cur_ptr += sizeof(*endpt);
+                               
+                               LOG("Endpoint %i/%i/%i = {", i, j, k);
+                               LOG(" .Address = 0x%2x", endpt->Address);
+                               LOG(" .Attributes = 0b%8b", endpt->Attributes);
+                               LOG(" .MaxPacketSize = %i", LittleEndian16(endpt->MaxPacketSize));
+                               LOG(" .PollingInterval = %i", endpt->PollingInterval);
+                               LOG("}");
+                       }
+               }
+               
+               free(full_buf);
+       }
+
+       // Done.
+       LEAVE('-');
+}
+
+void USB_DeviceDisconnected(tUSBHub *Hub, int Port)
+{
+       
+}
+
+void *USB_GetDeviceDataPtr(tUSBInterface *Dev) { return Dev->Data; }
+void USB_SetDeviceDataPtr(tUSBInterface *Dev, void *Ptr) { Dev->Data = Ptr; }
+
+int USB_int_AllocateAddress(tUSBHost *Host)
+{
+        int    i;
+       for( i = 1; i < 128; i ++ )
+       {
+               if(Host->AddressBitmap[i/8] & (1 << (i%8)))
+                       continue ;
+               Host->AddressBitmap[i/8] |= 1 << (i%8);
+               return i;
+       }
+       return 0;
+}
+
+void USB_int_DeallocateAddress(tUSBHost *Host, int Address)
+{
+       Host->AddressBitmap[Address/8] &= ~(1 << (Address%8));
+}
+
diff --git a/Modules/USB/Core/usb_io.c b/Modules/USB/Core/usb_io.c
new file mode 100644 (file)
index 0000000..ec88d75
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Acess2 USB Stack
+ * - By John Hodge (thePowersGang)
+ *
+ * usb_io.c
+ * - High-level IO
+ */
+#define DEBUG  1
+
+#include <usb_core.h>
+#include "usb.h"
+#include "usb_lowlevel.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);
+
+// === GLOBALS ===
+
+// === CODE ===
+void USB_ReadDescriptor(tUSBInterface *Iface, int Type, int Index, int Length, void *Data)
+{
+       USB_int_ReadDescriptor(Iface->Dev, 0, Type, Index, Length, Data);
+}
+
+void USB_Request(tUSBInterface *Iface, int Endpoint, int Type, int Req, int Value, int Index, int Len, void *Data)
+{
+        int    endpt;
+
+       // Sanity check
+       if(Endpoint < 0 || Endpoint >= Iface->nEndpoints)
+               return ;        
+
+       // Get endpoint number
+       if(Endpoint)
+               endpt = Iface->Endpoints[Endpoint-1].EndpointNum;
+       else
+               endpt = 0;
+       
+       USB_int_Request(Iface->Dev->Host, Iface->Dev->Address, endpt, Type, Req, Value, Index, Len, Data);
+}
+
index 7cde67f..4c0fb73 100644 (file)
@@ -12,6 +12,7 @@
 #include "usb_lowlevel.h"
 
 // === PROTOTYPES ===
+void   *USB_int_Request(tUSBHost *Host, int Addr, int EndPt, int Type, int Req, int Val, int Indx, int Len, void *Data);
  int   USB_int_SendSetupSetAddress(tUSBHost *Host, int Address);
  int   USB_int_ReadDescriptor(tUSBDevice *Dev, int Endpoint, int Type, int Index, int Length, void *Dest);
 char   *USB_int_GetDeviceString(tUSBDevice *Dev, int Endpoint, int Index);
index 903dd2e..9159cba 100644 (file)
@@ -8,6 +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 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/Modules/USB/Core/usb_poll.c b/Modules/USB/Core/usb_poll.c
new file mode 100644 (file)
index 0000000..a4e8d44
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Acess2 USB Stack
+ * - By John Hodge (thePowersGang)
+ *
+ * usb_poll.c
+ * - Endpoint polling
+ */
+#define DEBUG  1
+#include <usb_core.h>
+#include "usb.h"
+
+#define POLL_ATOM      25      // 25ms atom
+#define POLL_MAX       256     // Max period that can be nominated
+#define POLL_SLOTS     ((int)(POLL_MAX/POLL_ATOM))
+
+// === PROTOTYPES ===
+void   USB_StartPollingEndpoint(tUSBInterface *Iface, int Endpoint);
+
+// === GLOBALS ===
+tUSBEndpoint   *gUSB_PollQueues[POLL_MAX/POLL_ATOM];
+ int   giUSB_PollPosition;     // Index into gUSB_PollQueues
+
+// === CODE ===
+void USB_StartPollingEndpoint(tUSBInterface *Iface, int Endpoint)
+{
+       tUSBEndpoint    *endpt;
+
+       // Some sanity checks
+       if(Endpoint <= 0 || Endpoint >= Iface->nEndpoints)      return ;
+       endpt = &Iface->Endpoints[Endpoint-1];
+       if(endpt->PollingPeriod > POLL_MAX || endpt->PollingPeriod <= 0)
+               return ;
+
+       // TODO: Check that this endpoint isn't already on the queue
+
+       // Determine polling period in atoms
+       endpt->PollingAtoms = (endpt->PollingPeriod + POLL_ATOM-1) / POLL_ATOM;
+       if(endpt->PollingAtoms > POLL_SLOTS)    endpt->PollingAtoms = POLL_SLOTS;
+       // Add to poll queue
+       endpt->Next = gUSB_PollQueues[endpt->PollingAtoms];
+       gUSB_PollQueues[endpt->PollingAtoms] = endpt;
+}
+
+/**
+ * \brief USB polling thread
+ */
+int USB_PollThread(void *unused)
+{
+       for(;;)
+       {
+               tUSBEndpoint    *ep, *prev;
+
+               // A little evil for neater code
+               prev = (void*)( (tVAddr)&gUSB_PollQueues[giUSB_PollPosition] - offsetof(tUSBEndpoint, Next) );
+
+               // Process queue
+               for( ep = gUSB_PollQueues[giUSB_PollPosition]; ep; prev = ep, ep = ep->Next )
+               {
+                        int    period_in_atoms = ep->PollingAtoms;
+
+                       // Check for invalid entries
+                       if(period_in_atoms < 0 || period_in_atoms > POLL_ATOM)
+                       {
+                               Log_Warning("USB", "Endpoint on polling queue with invalid period");
+                               continue ;
+                       }
+                       // Check for entries to delete
+                       if(period_in_atoms == 0)
+                       {
+                               // Remove
+                               prev->Next = ep->Next;
+                               ep->PollingAtoms = -1;  // Mark as removed
+                               ep = prev;      // Make sure prev is kept valid
+                               continue ;
+                       }
+
+                       // Read data
+                       // TODO: Check the endpoint
+                       // TODO: Async checking?
+                       // - Send the read request on all of them then wait for the first to complete
+                       // Call callback
+
+                       // Reschedule
+                       if( period_in_atoms != POLL_SLOTS )
+                       {
+                                int    newqueue_id = (giUSB_PollPosition + period_in_atoms) % POLL_SLOTS;
+                               tUSBEndpoint    **newqueue = &gUSB_PollQueues[newqueue_id];
+                               
+                               prev->Next = ep->Next;
+                               
+                               ep->Next = *newqueue;
+                               *newqueue = ep;
+                       }
+               }
+               giUSB_PollPosition ++;
+               if(giUSB_PollPosition == POLL_SLOTS)
+                       giUSB_PollPosition = 0;
+               // TODO: Check for a longer delay
+               Time_Delay(POLL_ATOM);
+       }
+}
+
index 9fd8230..18fd3e8 100644 (file)
@@ -28,7 +28,7 @@ void  *UHCI_DataOUT(void *Ptr, int Fcn, int Endpt, int DataTgl, tUSBHostCb Cb, vo
 void   *UHCI_SendSetup(void *Ptr, int Fcn, int Endpt, int DataTgl, tUSBHostCb Cb, void *Data, size_t Length);
  int   UHCI_IsTransferComplete(void *Ptr, void *Handle);
  int   UHCI_Int_InitHost(tUHCI_Controller *Host);
-void   UHCI_CheckPortUpdate(tUHCI_Controller *Host);
+void   UHCI_CheckPortUpdate(void *Ptr);
 void   UHCI_InterruptHandler(int IRQ, void *Ptr);
 
 // === GLOBALS ===
@@ -39,7 +39,7 @@ tUSBHostDef   gUHCI_HostDef = {
        .SendIN = UHCI_DataIN,
        .SendOUT = UHCI_DataOUT,
        .SendSETUP = UHCI_SendSetup,
-       .CheckPorts = (void*)UHCI_CheckPortUpdate,
+       .CheckPorts = UHCI_CheckPortUpdate,
        .IsOpComplete = UHCI_IsTransferComplete
        };
 
@@ -291,8 +291,9 @@ int UHCI_Int_InitHost(tUHCI_Controller *Host)
        return 0;
 }
 
-void UHCI_CheckPortUpdate(tUHCI_Controller *Host)
+void UHCI_CheckPortUpdate(void *Ptr)
 {
+       tUHCI_Controller        *Host = Ptr;
        // Enable ports
        for( int i = 0; i < 2; i ++ )
        {

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