Modules/USB - Working on HID support (and fixed some little bugs)
authorJohn Hodge <[email protected]>
Thu, 16 Feb 2012 13:14:29 +0000 (21:14 +0800)
committerJohn Hodge <[email protected]>
Thu, 16 Feb 2012 13:14:29 +0000 (21:14 +0800)
- Had to do slight API changes (currently not documented)

13 files changed:
BuildConf/x86/default.mk
KernelLand/Modules/USB/Core/hub.c
KernelLand/Modules/USB/Core/include/usb_core.h
KernelLand/Modules/USB/Core/usb.c
KernelLand/Modules/USB/Core/usb_devinit.c
KernelLand/Modules/USB/Core/usb_lowlevel.c
KernelLand/Modules/USB/HID/Makefile [new file with mode: 0644]
KernelLand/Modules/USB/HID/hid.h
KernelLand/Modules/USB/HID/hid_reports.h [new file with mode: 0644]
KernelLand/Modules/USB/HID/keyboard.c [new file with mode: 0644]
KernelLand/Modules/USB/HID/main.c
KernelLand/Modules/USB/HID/mouse.c [new file with mode: 0644]
KernelLand/Modules/USB/UHCI/uhci.c

index ee427a1..11881b0 100644 (file)
@@ -6,5 +6,7 @@ MODULES += Display/VESA
 MODULES += Display/BochsGA
 MODULES += Input/PS2KbMouse
 MODULES += x86/ISADMA x86/VGAText
+
 MODULES += USB/Core USB/UHCI USB/OHCI
+MODULES += USB/HID
 #MODULES += Interfaces/UDI
index eccaa3f..69599e1 100644 (file)
@@ -52,7 +52,7 @@ struct sHubInfo
 };
 
 // === PROTOTYPES ===
-void   Hub_Connected(tUSBInterface *Dev);
+void   Hub_Connected(tUSBInterface *Dev, void *Descriptors, size_t Length);
 void   Hub_Disconnected(tUSBInterface *Dev);
 void   Hub_PortStatusChange(tUSBInterface *Dev, int Endpoint, int Length, void *Data);
 void   Hub_int_HandleChange(tUSBInterface *Dev, int Port);
@@ -78,13 +78,13 @@ int Hub_DriverInitialise(char **Arguments)
 }
 #endif
 
-void Hub_Connected(tUSBInterface *Dev)
+void Hub_Connected(tUSBInterface *Dev, void *Descriptors, size_t Length)
 {
        struct sHubDescriptor   hub_desc;
        struct sHubInfo *info;  
 
-       // Read hub descriptor (Class descriptor 0x29)
-       USB_ReadDescriptor(Dev, 0x129, 0, sizeof(hub_desc), &hub_desc);
+       // Read hub descriptor (Class descriptor 0x9, destined for device)
+       USB_ReadDescriptor(Dev, 0x0129, 0, sizeof(hub_desc), &hub_desc);
 
        LOG("%i Ports", hub_desc.NbrPorts);
        LOG("Takes %i ms for power to stabilise", hub_desc.PwrOn2PwrGood*2);
index d0f449f..0b03d75 100644 (file)
@@ -38,7 +38,7 @@ struct sUSBDriver
                } VendorDev;
        } Match;
 
-       void    (*Connected)(tUSBInterface *Dev);
+       void    (*Connected)(tUSBInterface *Dev, void *Descriptors, size_t Size);
        void    (*Disconnected)(tUSBInterface *Dev);
 
         int    MaxEndpoints;   
index a265be9..3ebb0b3 100644 (file)
@@ -61,7 +61,6 @@ tUSBHub *USB_RegisterHost(tUSBHostDef *HostDef, void *ControllerPtr, int nPorts)
 // --- Drivers ---
 void USB_RegisterDriver(tUSBDriver *Driver)
 {
-       Log_Warning("USB", "TODO: Implement USB_RegisterDriver");
        Driver->Next = gpUSB_InterfaceDrivers;
        gpUSB_InterfaceDrivers = Driver;
 }
index d01d7d1..4b18b30 100644 (file)
@@ -5,7 +5,7 @@
  * usb_devinit.c
  * - USB Device Initialisation
  */
-#define DEBUG  1
+#define DEBUG  0
 
 #include <acess.h>
 #include <vfs.h>
@@ -99,8 +99,9 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port)
        for( int i = 0; i < 1; i ++ )
        {
                struct sDescriptor_Configuration        desc;
-               void    *full_buf;
-               char    *cur_ptr;
+               Uint8   *full_buf;
+               size_t  ptr_ofs = 0;
+               size_t  total_length;
        
                USB_int_ReadDescriptor(dev, 0, 2, i, sizeof(desc), &desc);
                LOG("Configuration Descriptor %i = {", i);
@@ -127,19 +128,32 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port)
                dev->nInterfaces = desc.NumInterfaces;
        
                // Allocate a temp buffer for config info
-               cur_ptr = full_buf = malloc( LittleEndian16(desc.TotalLength) );
-               USB_int_ReadDescriptor(dev, 0, 2, i, desc.TotalLength, full_buf);
+               total_length = LittleEndian16(desc.TotalLength);
+               full_buf = malloc( total_length );
+               USB_int_ReadDescriptor(dev, 0, 2, i, total_length, full_buf);
 
-               cur_ptr += desc.Length;
+               ptr_ofs += desc.Length;
 
                // TODO: Interfaces
-               for( int j = 0; j < desc.NumInterfaces; j ++ )
+               for( int j = 0; ptr_ofs < total_length && j < desc.NumInterfaces; j ++ )
                {
                        struct sDescriptor_Interface *iface;
                        tUSBInterface   *dev_if;
-                       iface = (void*)cur_ptr;
-                       // TODO: Sanity check with remaining space
-                       cur_ptr += sizeof(*iface);
+                       size_t  iface_base_ofs;
+
+                       iface = (void*)(full_buf + ptr_ofs);
+                       ptr_ofs += iface->Length;
+                       if( ptr_ofs > total_length ) {
+                               // Sanity fail
+                               break;
+                       }
+                       iface_base_ofs = ptr_ofs;
+                       // Check type
+                       if( iface->Type != 4 ) {
+                               LOG("Not an interface (type = %i)", iface->Type);
+                               j --;   // Counteract j++ in loop
+                               continue ;
+                       }
 
                        LOG("Interface %i/%i = {", i, j);
                        LOG(" .InterfaceNum = %i", iface->InterfaceNum);
@@ -147,7 +161,6 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port)
                        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);
@@ -163,13 +176,25 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port)
                        dev->Interfaces[j] = dev_if;
 
                        // Copy interface data
-                       for( int k = 0; k < iface->NumEndpoints; k ++ )
+                       for( int k = 0; ptr_ofs < total_length && k < iface->NumEndpoints; k ++ )
                        {
                                struct sDescriptor_Endpoint *endpt;
-                               endpt = (void*)cur_ptr;
-                               // TODO: Sanity check with remaining space
-                               cur_ptr += sizeof(*endpt);
                                
+                               endpt = (void*)(full_buf + ptr_ofs);
+                               ptr_ofs += endpt->Length;
+                               if( ptr_ofs > total_length ) {
+                                       // Sanity fail
+                                       break;
+                               }
+
+                               // Check type
+                               if( endpt->Type != 5 ) {
+                                       // Oops?
+                                       LOG("Not endpoint, Type = %i", endpt->Type);
+                                       k --;
+                                       continue ;
+                               }
+
                                LOG("Endpoint %i/%i/%i = {", i, j, k);
                                LOG(" .Address = 0x%2x", endpt->Address);
                                LOG(" .Attributes = 0b%8b", endpt->Attributes);
@@ -200,7 +225,11 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port)
                                        );
                        }
                        else {
-                               dev_if->Driver->Connected( dev_if );
+                               dev_if->Driver->Connected(
+                                       dev_if,
+                                       full_buf + iface_base_ofs, ptr_ofs - iface_base_ofs
+                                       );
+                       //      dev_if->Driver->Connected( dev_if );
                        }
                }
                
index 3450bd8..1eba637 100644 (file)
@@ -78,16 +78,12 @@ int USB_int_ReadDescriptor(tUSBDevice *Dev, int Endpoint, int Type, int Index, i
         int    dest = Dev->Address*16 + Endpoint;
 
        req.ReqType = 0x80;
-       switch( Type & 0xF00 )
-       {
-       case 0x000:     req.ReqType |= (0 << 5);        break;  // Standard
-       case 0x100:     req.ReqType |= (1 << 5);        break;  // Class
-       case 0x200:     req.ReqType |= (2 << 5);        break;  // Vendor
-       }
+       req.ReqType |= ((Type >> 8) & 0x3) << 5;        // Bits 5/6
+       req.ReqType |= (Type >> 12) & 3;        // Destination (Device, Interface, Endpoint, Other);
 
        req.Request = 6;        // GET_DESCRIPTOR
        req.Value = LittleEndian16( ((Type & 0xFF) << 8) | (Index & 0xFF) );
-       req.Index = LittleEndian16( 0 );        // TODO: Language ID
+       req.Index = LittleEndian16( 0 );        // TODO: Language ID / Interface
        req.Length = LittleEndian16( Length );
        
        Dev->Host->HostDef->SendSETUP(
diff --git a/KernelLand/Modules/USB/HID/Makefile b/KernelLand/Modules/USB/HID/Makefile
new file mode 100644 (file)
index 0000000..e862a26
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# Acess2 HID Driver
+#
+
+OBJ = main.o mouse.o
+CPPFLAGS = -I../Core/include
+NAME = HID
+
+-include ../Makefile.tpl
index 373496e..ae251c5 100644 (file)
@@ -41,7 +41,7 @@ struct sDescriptor_HID
        struct {
                Uint8   DescType;
                Uint16  DescLen;
-       } Descriptors[];
-}
+       } PACKED Descriptors[];
+} PACKED;
 
 #endif
diff --git a/KernelLand/Modules/USB/HID/hid_reports.h b/KernelLand/Modules/USB/HID/hid_reports.h
new file mode 100644 (file)
index 0000000..fa46451
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Acess2 USB Stack - HID Driver
+ * - By John Hodge (thePowersGang)
+ *
+ * hid_reports.h
+ * - Report parsing definitions
+ */
+#ifndef _USB_HID_REPORTS_H_
+#define _USB_HID_REPORTS_H_
+
+#include <usb_core.h>
+
+typedef struct sHID_ReportCallbacks    tHID_ReportCallbacks;
+typedef struct sHID_ReportGlobalState  tHID_ReportGlobalState;
+typedef struct sHID_ReportLocalState   tHID_ReportLocalState;
+
+struct sHID_ReportCallbacks
+{
+       void    (*Input)(
+               tUSBInterface *Dev,
+               tHID_ReportGlobalState *Global, tHID_ReportLocalState *Local, Uint32 Data
+               );
+       void    (*Output)(
+               tUSBInterface *Dev,
+               tHID_ReportGlobalState *Global, tHID_ReportLocalState *Local, Uint32 Data
+               );
+       void    (*Feature)(
+               tUSBInterface *Dev,
+               tHID_ReportGlobalState *Global, tHID_ReportLocalState *Local, Uint32 Data
+               );
+       
+       tHID_ReportCallbacks    *(*Collection)(
+               tUSBInterface *Dev,
+               tHID_ReportGlobalState *Global, tHID_ReportLocalState *Local, Uint32 Data
+               );
+       
+       void    (*EndCollection)(tUSBInterface *Dev);
+};
+
+struct sHID_ReportGlobalState
+{
+       Uint32  UsagePage;
+       Uint32  LogMin;
+       Uint32  LogMax;
+       Uint32  PhysMin;
+       Uint32  PhysMax;
+       
+       Uint8   UnitExp;
+       Uint8   Unit;
+       
+       Uint32  ReportSize;
+       Uint32  ReportID;
+       Uint32  ReportCount;
+};
+
+struct sHID_IntList
+{
+        int    Space;
+        int    nItems;
+       Uint32  *Items;
+};
+
+struct sHID_ReportLocalState
+{
+       struct sHID_IntList     Usages;
+       Uint32  UsageMin;
+       struct sHID_IntList     Designators;
+       Uint32  DesignatorMin;
+       struct sHID_IntList     Strings;
+       Uint32  StringMin;
+
+};
+
+#endif
+
diff --git a/KernelLand/Modules/USB/HID/keyboard.c b/KernelLand/Modules/USB/HID/keyboard.c
new file mode 100644 (file)
index 0000000..90ad63f
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Acess2 USB Stack HID Driver
+ * - By John Hodge (thePowersGang)
+ *
+ * keyboard.c
+ * - Keyboard translation
+ */
+#define DEBUG  0
+#include <fs_devfs.h>
+
+// === GLOBALS ===
+tDevFS_Driver  gHID_DevFS_Keyboard = {
+       .Name = "USBKeyboard",
+};
index 31375b0..336609d 100644 (file)
  * main.c
  * - Driver Core
  */
-#define DEBUG  0
+#define DEBUG  1
 #define VERSION        VER2(0,1)
 #include <acess.h>
+#include <modules.h>
 #include <usb_core.h>
+#include "hid.h"
+#include "hid_reports.h"
 
 // === PROTOTYPES ===
- int   HID_Initialise(const char **Arguments);
-void   HID_DeviceConnected(tUSBInterface *Dev);
+ int   HID_Initialise(char **Arguments);
+void   HID_DeviceConnected(tUSBInterface *Dev, void *Descriptors, size_t DescriptorsLen);
+tHID_ReportCallbacks   *HID_RootCollection(tUSBInterface *Dev, tHID_ReportGlobalState *Global, tHID_ReportLocalState *Local, Uint32 Value);
+void   HID_int_ParseReport(tUSBInterface *Dev, Uint8 *Data, size_t Length, tHID_ReportCallbacks *StartCBs);
+
+static void    _AddItem(struct sHID_IntList *List, Uint32 Value);
+static void    _AddItems(struct sHID_IntList *List, Uint32 First, Uint32 Last);
+static void    _FreeList(struct sHID_IntList *List);
 
 // === GLOBALS ===
 MODULE_DEFINE(0, VERSION, USB_HID, HID_Initialise, NULL, "USB_Core", NULL);
-tUSBDriver     gHID_Driver = {
+tUSBDriver     gHID_USBDriver = {
        .Name = "HID",
        .Match = {.Class = {0x030000, 0xFF0000}},
        .Connected = HID_DeviceConnected,
 };
+tHID_ReportCallbacks   gHID_RootCallbacks = {
+       .Collection = HID_RootCollection
+};
 
 // === CODE ===
-int HID_Initialise(const char **Arguments)
+int HID_Initialise(char **Arguments)
 {
-       USB_RegisterDriver( &gHID_Driver );
+       USB_RegisterDriver( &gHID_USBDriver );
        return 0;
 }
 
-void HID_DeviceConnected(tUSBInterface *Dev)
+void HID_DeviceConnected(tUSBInterface *Dev, void *Descriptors, size_t DescriptorsLen)
+{
+       struct sDescriptor_HID  *hid_desc;
+       size_t  ofs = 0;
+       size_t  report_len = 0;
+       
+       ENTER("pDev pDescriptors iDescriptorsLen", Dev, Descriptors, DescriptorsLen);
+
+       // Locate HID descriptor
+       hid_desc = NULL;
+       while(ofs + 2 <= DescriptorsLen)
+       {
+               hid_desc = (void*)( (char*)Descriptors + ofs );
+               ofs += hid_desc->Length;
+               // Sanity check length
+               if( ofs > DescriptorsLen ) {
+                       hid_desc = NULL;
+                       break ;
+               }
+               // Check for correct type
+               if( hid_desc->Type == 0x21 )
+                       break ;
+               // On to the next one then
+       }
+       if( hid_desc == NULL ) {
+               Log_Warning("USB_HID", "Device doesn't have a HID descritor");
+               LEAVE('-');
+               return ;
+       }
+       
+
+       // Dump descriptor header
+       LOG("hid_desc = {");
+       LOG("  .Length  = %i", hid_desc->Length);
+       LOG("  .Type    = 0x%x", hid_desc->Type);
+       LOG("  .Version = 0x%x", hid_desc->Version);
+       LOG("  .NumDescriptors = %i", hid_desc->NumDescriptors);
+       LOG("}");
+
+       if( hid_desc->Length < sizeof(*hid_desc) + hid_desc->NumDescriptors * sizeof(hid_desc->Descriptors[0]) )
+       {
+               // Too small!
+               Log_Warning("USB_HID", "HID Descriptor undersized (%i < %i)",
+                       hid_desc->Length,
+                       sizeof(*hid_desc) + hid_desc->NumDescriptors * sizeof(hid_desc->Descriptors[0]));
+               LEAVE('-');
+               return ;
+       }
+
+       // Locate report descriptor
+       for( int i = 0; i < hid_desc->NumDescriptors; i ++ )
+       {
+               if( hid_desc->Descriptors[i].DescType == 0x22 ) {
+                       report_len = LittleEndian16( hid_desc->Descriptors[i].DescLen );
+                       break ;
+               }
+       }
+       if( report_len == 0 ) {
+               Log_Warning("USB_HID", "No report descriptor");
+               LEAVE('-');
+               return ;
+       }
+       
+       // Read and parse report descriptor
+       Uint8   *report_data = alloca(report_len);
+       USB_ReadDescriptor(Dev, 0x1022, 0, report_len, report_data);
+       HID_int_ParseReport(Dev, report_data, report_len, &gHID_RootCallbacks);
+       
+       LEAVE('-');
+}
+
+/**
+ * \brief Handle a Collection item in a report
+ * 
+ * When an application collection is found in the root of the tree, the approriate
+ * sub-handler is invoked (mouse, keyboard, gamepad, ...)
+ */
+tHID_ReportCallbacks *HID_RootCollection(
+       tUSBInterface *Dev,
+       tHID_ReportGlobalState *Global, tHID_ReportLocalState *Local, Uint32 Value
+       )
+{
+       Uint32  usage;
+       
+       // Check for "Application" collection
+       if( Value != 1 )        return NULL;
+       
+       // Check usages
+       if( Local->Usages.nItems == 0 ) return NULL;
+       usage = Local->Usages.Items[0];
+       switch(usage >> 16)
+       {
+       case 0x0001:    // General Desktop
+               switch(usage & 0xFFFF)
+               {
+               case 0x0001:    // Pointer
+                       LOG("Desktop->Pointer");
+                       break;
+               case 0x0002:    // Mouse
+                       LOG("Desktop->Mouse");
+                       break;
+               case 0x0004:    // Joystick
+               case 0x0005:    // Game Pad
+                       LOG("Desktop->Gamepad");
+                       break;
+               case 0x0006:    // Keyboard
+                       LOG("Desktop->Keyboard");
+                       break;
+               }
+               break;
+       case 0x0007:    // Keyboard / Keypad
+               LOG("Keyboard");
+               break;
+       }
+       return NULL;
+}
+
+void HID_int_ParseReport(tUSBInterface *Dev, Uint8 *Data, size_t Length, tHID_ReportCallbacks *StartCBs)
 {
+       const int       max_cb_level = 8;
+        int    cb_level = 0;
+       tHID_ReportCallbacks    *cur_cbs;
+       tHID_ReportCallbacks    *cb_stack[max_cb_level];
+       tHID_ReportGlobalState  global_state;
+       tHID_ReportLocalState   local_state;
        
+       ENTER("pData iLength pStartCBs", Data, Length, StartCBs);
+
+       cb_stack[0] = StartCBs;
+       cur_cbs = StartCBs;
+
+       memset(&global_state, 0, sizeof(global_state));
+       memset(&local_state, 0, sizeof(local_state));
+
+       for( int ofs = 0; ofs < Length; )
+       {
+               Uint8   byte;
+               Uint32  val;
+               
+               byte = Data[ofs];
+               // Get value (and increase offset)
+               switch(byte & 3)
+               {
+               case 0:
+                       val = 0;
+                       ofs += 1;
+                       break;
+               case 1:
+                       val = Data[ofs+1];
+                       ofs += 2;
+                       break;
+               case 2:
+                       val = Data[ofs + 1] | (Data[ofs + 1]<<8);
+                       ofs += 3;
+                       break;
+               case 3:
+                       val = Data[ofs + 1] | (Data[ofs + 2] << 8) | (Data[ofs + 3] << 16) | (Data[ofs + 4] << 24);
+                       ofs += 5;
+                       break;
+               }
+       
+               LOG("Type = 0x%x, len = %i, val = 0x%x", byte & 0xFC, byte & 3, val);
+               switch(byte & 0xFC)
+               {
+               // Main items
+               // - Input
+               case 0x80:
+                       LOG("Input 0x%x", val);
+                       if( cur_cbs && cur_cbs->Input )
+                               cur_cbs->Input( Dev, &global_state, &local_state, val );
+                       goto _clear_local;
+               // - Output
+               case 0x90:
+                       LOG("Output 0x%x", val);
+                       if( cur_cbs && cur_cbs->Output )
+                               cur_cbs->Output( Dev, &global_state, &local_state, val );
+                       goto _clear_local;
+               // - Collection
+               case 0xA0:
+                       LOG("Collection 0x%x", val);
+                       
+                       tHID_ReportCallbacks    *next_cbs = NULL;
+                       if( cur_cbs && cur_cbs->Collection )
+                               next_cbs = cur_cbs->Collection( Dev, &global_state, &local_state, val );
+                       cb_level ++;
+                       if( cb_level < max_cb_level )
+                               cb_stack[cb_level] = next_cbs;
+                       else
+                               next_cbs = NULL;
+                       cur_cbs = next_cbs;
+                       break;
+               // - Feature
+               case 0xB0:
+                       LOG("Feature 0x%x", val);
+                       if( cur_cbs && cur_cbs->Feature )
+                               cur_cbs->Feature( Dev, &global_state, &local_state, val );
+                       goto _clear_local;
+               // - End collection
+               case 0xC0:
+                       if( cur_cbs && cur_cbs->EndCollection )
+                               cur_cbs->EndCollection(Dev);
+                       if( cb_level == 0 ) {
+                               Log_Warning("USB_HID", "Inbalance in HID collections");
+                               LEAVE('-');
+                               return ;
+                       }
+                       cb_level --;
+                       if( cb_level < max_cb_level )
+                               cur_cbs = cb_stack[cb_level];
+                       goto _clear_local;
+               // -- Helper to clear the local state
+               _clear_local:
+                       _FreeList( &local_state.Strings );
+                       _FreeList( &local_state.Usages );
+                       _FreeList( &local_state.Designators );
+                       memset( &local_state, 0, sizeof(local_state) );
+                       break;
+               
+               // Global Items
+               case 0x04:      global_state.UsagePage = val<<16;       break;  // - Usage Page
+               case 0x14:      global_state.LogMin = val;      break;  // - Logical Min
+               case 0x24:      global_state.LogMax = val;      break;  // - Logical Max
+               case 0x34:      global_state.PhysMin = val;     break;  // - Physical Min
+               case 0x44:      global_state.PhysMax = val;     break;  // - Physical Max
+               case 0x54:      global_state.UnitExp = val;     break;  // - Unit Exp
+               case 0x64:      global_state.Unit = val;        break;  // - Unit
+               case 0x74:      global_state.ReportSize = val;  break;  // - Report Size
+               case 0x84:      global_state.ReportID = val;    break;  // - Report ID (TODO: Flag when used)
+               case 0x94:      global_state.ReportCount = val; break;  // - Report Count
+               case 0xA4:      LOG("TODO: Implement Global Push");     break;  // - Push
+               case 0xB4:      LOG("TODO: Implement Global Pop");      break;  // - Pop
+               
+               // Local Items
+               // - Usages
+               case 0x08:      // Single
+                       if( (byte & 3) != 3 )   val |= global_state.UsagePage;
+                       _AddItem(&local_state.Usages, val);
+                       break;
+               case 0x18:      // Range start
+                       if( (byte & 3) != 3 )   val |= global_state.UsagePage;
+                       local_state.UsageMin = val;
+                       break;
+               case 0x28:      // Range end (apply)
+                       if( (byte & 3) != 3 )   val |= global_state.UsagePage;
+                       _AddItems(&local_state.Usages, local_state.UsageMin, val);
+                       break;
+               // - Designators (Index into Physical report)
+               case 0x38:
+                       _AddItem(&local_state.Designators, val);
+                       break;
+               case 0x48:
+                       local_state.DesignatorMin = val;
+                       break;
+               case 0x58:
+                       _AddItems(&local_state.Designators, local_state.DesignatorMin, val);
+                       break;
+               // - Reserved/hole
+               case 0x68:
+                       break;
+               // - Strings
+               case 0x78:
+                       _AddItem(&local_state.Strings, val);
+                       break;
+               case 0x88:
+                       local_state.StringMin = val;
+                       break;
+               case 0x98:
+                       _AddItems(&local_state.Strings, local_state.StringMin, val);
+                       break;
+               // - Delimiter
+               case 0xA8:
+                       break;
+               
+               // Long Item
+               case 0xFC:
+                       LOG("Long Item");
+                       break;
+               
+               // Reserved
+               default:
+                       LOG("0x%x RESVD", byte & 0xFC);
+                       break;
+               }
+       }
+
+       LEAVE('-');
+}
+
+static void _AddItem(struct sHID_IntList *List, Uint32 Value)
+{
+       if( List->Space == List->nItems )
+       {
+               List->Space += 10;
+               List->Items = realloc( List->Items, List->Space * sizeof(List->Items[0]) );
+       }
+       
+       List->Items[ List->nItems ] = Value;
+       List->nItems ++;
+}
+
+static void _AddItems(struct sHID_IntList *List, Uint32 First, Uint32 Last)
+{
+       while( First <= Last )
+       {
+               _AddItem(List, First);
+               First ++;
+       }
+}
+
+static void _FreeList(struct sHID_IntList *List)
+{
+       free(List->Items);
 }
 
diff --git a/KernelLand/Modules/USB/HID/mouse.c b/KernelLand/Modules/USB/HID/mouse.c
new file mode 100644 (file)
index 0000000..b7737f9
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Acess2 USB Stack HID Driver
+ * - By John Hodge (thePowersGang)
+ *
+ * mouse.c
+ * - USB Mouse driver
+ */
+#define DEBUG  0
+#include <acess.h>
+#include "hid_reports.h"
+#include <fs_devfs.h>
+
+
+// === PROTOTYES ===
+tHID_ReportCallbacks   *HID_Mouse_Report_Collection(tUSBInterface *Dev, tHID_ReportGlobalState *Global, tHID_ReportLocalState *Local, Uint32 Value);
+void   HID_Mouse_Report_Input(tUSBInterface *Dev, tHID_ReportGlobalState *Global, tHID_ReportLocalState *Local, Uint32 Value);
+void   HID_Mouse_Report_Output(tUSBInterface *Dev, tHID_ReportGlobalState *Global, tHID_ReportLocalState *Local, Uint32 Value);
+void   HID_Mouse_Report_Feature(tUSBInterface *Dev, tHID_ReportGlobalState *Global, tHID_ReportLocalState *Local, Uint32 Value);
+
+// === GLOBALS ===
+tDevFS_Driver  gHID_Mouse_DevFS = {
+       .Name = "USBKeyboard",
+};
+tHID_ReportCallbacks   gHID_Mouse_ReportCBs = {
+       .Collection = HID_Mouse_Report_Collection,
+       .Input = HID_Mouse_Report_Input,
+       .Output = HID_Mouse_Report_Output,
+       .Feature = HID_Mouse_Report_Feature
+};
+
+// === CODE ===
+tHID_ReportCallbacks *HID_Mouse_Report_Collection(
+       tUSBInterface *Dev,
+       tHID_ReportGlobalState *Global, tHID_ReportLocalState *Local,
+       Uint32 Value
+       )
+{
+       return &gHID_Mouse_ReportCBs;
+}
+
+void HID_Mouse_Report_Input(
+       tUSBInterface *Dev,
+       tHID_ReportGlobalState *Global, tHID_ReportLocalState *Local,
+       Uint32 Value
+       )
+{
+       
+}
+
+void HID_Mouse_Report_Output(
+       tUSBInterface *Dev,
+       tHID_ReportGlobalState *Global, tHID_ReportLocalState *Local,
+       Uint32 Value
+       )
+{
+       
+}
+
+void HID_Mouse_Report_Feature(
+       tUSBInterface *Dev,
+       tHID_ReportGlobalState *Global, tHID_ReportLocalState *Local,
+       Uint32 Value
+       )
+{
+       
+}
+
index 8477c8f..76b0ba4 100644 (file)
@@ -22,6 +22,7 @@
  int   UHCI_Initialise(char **Arguments);
 void   UHCI_Cleanup();
 tUHCI_TD       *UHCI_int_AllocateTD(tUHCI_Controller *Cont);
+tUHCI_TD       *UHCI_int_GetTDFromPhys(tPAddr PAddr);
 void   UHCI_int_AppendTD(tUHCI_Controller *Cont, tUHCI_TD *TD);
 void   *UHCI_int_SendTransaction(tUHCI_Controller *Cont, int Addr, Uint8 Type, int bTgl, tUSBHostCb Cb, void *CbData, void *Buf, size_t Length);
 void   *UHCI_DataIN(void *Ptr, int Dest, int DataTgl, tUSBHostCb Cb, void *CbData, void *Buf, size_t Length);
@@ -166,19 +167,23 @@ tUHCI_TD *UHCI_int_GetTDFromPhys(tPAddr PAddr)
 
 void UHCI_int_AppendTD(tUHCI_Controller *Cont, tUHCI_TD *TD)
 {
-        int    next_frame = (_InWord(Cont, FRNUM) + 2) & (1024-1);
+        int    next_frame;
        tUHCI_TD        *prev_td;
        Uint32  link;
 
-       // TODO: How to handle FRNUM incrementing while we are in this function?
+       ENTER("pCont pTD", Cont, TD);
 
+       // TODO: How to handle FRNUM incrementing while we are in this function?
+       next_frame = (_InWord(Cont, FRNUM) + 2) & (1024-1);
+       
        // Empty list
        if( Cont->FrameList[next_frame] & 1 )
        {
                // TODO: Ensure 32-bit paddr
                Cont->FrameList[next_frame] = MM_GetPhysAddr( (tVAddr)TD );
                TD->Control |= (1 << 24);       // Ensure that there is an interrupt for each used frame
-               LOG("next_frame = %i", next_frame);     
+               LOG("next_frame = %i", next_frame);
+               LEAVE('-');
                return;
        }
 
@@ -193,6 +198,7 @@ void UHCI_int_AppendTD(tUHCI_Controller *Cont, tUHCI_TD *TD)
        prev_td->Link = MM_GetPhysAddr( (tVAddr)TD );
 
        LOG("next_frame = %i, prev_td = %p", next_frame, prev_td);
+       LEAVE('-');
 }
 
 /**
@@ -307,7 +313,8 @@ int UHCI_Int_InitHost(tUHCI_Controller *Host)
                return -1;
        }
        LOG("Allocated frame list 0x%x (0x%x)", Host->FrameList, Host->PhysFrameList);
-       memsetd( Host->FrameList, 1, 1024 );    // Clear List (Disabling all entries)
+       for( int i = 0; i < 1024; i ++ )
+               Host->FrameList[i] = 1; // Clear List (Disabling all entries)
        
        //! \todo Properly fill frame list
        

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