From 1ba64c63a4a3a8ce27155f9463f0442ea7f7dc89 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 16 Feb 2012 21:14:29 +0800 Subject: [PATCH] Modules/USB - Working on HID support (and fixed some little bugs) - Had to do slight API changes (currently not documented) --- BuildConf/x86/default.mk | 2 + KernelLand/Modules/USB/Core/hub.c | 8 +- .../Modules/USB/Core/include/usb_core.h | 2 +- KernelLand/Modules/USB/Core/usb.c | 1 - KernelLand/Modules/USB/Core/usb_devinit.c | 61 +++- KernelLand/Modules/USB/Core/usb_lowlevel.c | 10 +- KernelLand/Modules/USB/HID/Makefile | 9 + KernelLand/Modules/USB/HID/hid.h | 4 +- KernelLand/Modules/USB/HID/hid_reports.h | 75 ++++ KernelLand/Modules/USB/HID/keyboard.c | 14 + KernelLand/Modules/USB/HID/main.c | 335 +++++++++++++++++- KernelLand/Modules/USB/HID/mouse.c | 67 ++++ KernelLand/Modules/USB/UHCI/uhci.c | 15 +- 13 files changed, 561 insertions(+), 42 deletions(-) create mode 100644 KernelLand/Modules/USB/HID/Makefile create mode 100644 KernelLand/Modules/USB/HID/hid_reports.h create mode 100644 KernelLand/Modules/USB/HID/keyboard.c create mode 100644 KernelLand/Modules/USB/HID/mouse.c diff --git a/BuildConf/x86/default.mk b/BuildConf/x86/default.mk index ee427a16..11881b0f 100644 --- a/BuildConf/x86/default.mk +++ b/BuildConf/x86/default.mk @@ -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 diff --git a/KernelLand/Modules/USB/Core/hub.c b/KernelLand/Modules/USB/Core/hub.c index eccaa3fc..69599e18 100644 --- a/KernelLand/Modules/USB/Core/hub.c +++ b/KernelLand/Modules/USB/Core/hub.c @@ -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); diff --git a/KernelLand/Modules/USB/Core/include/usb_core.h b/KernelLand/Modules/USB/Core/include/usb_core.h index d0f449fb..0b03d75e 100644 --- a/KernelLand/Modules/USB/Core/include/usb_core.h +++ b/KernelLand/Modules/USB/Core/include/usb_core.h @@ -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; diff --git a/KernelLand/Modules/USB/Core/usb.c b/KernelLand/Modules/USB/Core/usb.c index a265be93..3ebb0b34 100644 --- a/KernelLand/Modules/USB/Core/usb.c +++ b/KernelLand/Modules/USB/Core/usb.c @@ -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; } diff --git a/KernelLand/Modules/USB/Core/usb_devinit.c b/KernelLand/Modules/USB/Core/usb_devinit.c index d01d7d1c..4b18b30a 100644 --- a/KernelLand/Modules/USB/Core/usb_devinit.c +++ b/KernelLand/Modules/USB/Core/usb_devinit.c @@ -5,7 +5,7 @@ * usb_devinit.c * - USB Device Initialisation */ -#define DEBUG 1 +#define DEBUG 0 #include #include @@ -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 ); } } diff --git a/KernelLand/Modules/USB/Core/usb_lowlevel.c b/KernelLand/Modules/USB/Core/usb_lowlevel.c index 3450bd80..1eba637f 100644 --- a/KernelLand/Modules/USB/Core/usb_lowlevel.c +++ b/KernelLand/Modules/USB/Core/usb_lowlevel.c @@ -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 index 00000000..e862a26b --- /dev/null +++ b/KernelLand/Modules/USB/HID/Makefile @@ -0,0 +1,9 @@ +# +# Acess2 HID Driver +# + +OBJ = main.o mouse.o +CPPFLAGS = -I../Core/include +NAME = HID + +-include ../Makefile.tpl diff --git a/KernelLand/Modules/USB/HID/hid.h b/KernelLand/Modules/USB/HID/hid.h index 373496e8..ae251c5b 100644 --- a/KernelLand/Modules/USB/HID/hid.h +++ b/KernelLand/Modules/USB/HID/hid.h @@ -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 index 00000000..fa464514 --- /dev/null +++ b/KernelLand/Modules/USB/HID/hid_reports.h @@ -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 + +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 index 00000000..90ad63fb --- /dev/null +++ b/KernelLand/Modules/USB/HID/keyboard.c @@ -0,0 +1,14 @@ +/* + * Acess2 USB Stack HID Driver + * - By John Hodge (thePowersGang) + * + * keyboard.c + * - Keyboard translation + */ +#define DEBUG 0 +#include + +// === GLOBALS === +tDevFS_Driver gHID_DevFS_Keyboard = { + .Name = "USBKeyboard", +}; diff --git a/KernelLand/Modules/USB/HID/main.c b/KernelLand/Modules/USB/HID/main.c index 31375b0b..336609da 100644 --- a/KernelLand/Modules/USB/HID/main.c +++ b/KernelLand/Modules/USB/HID/main.c @@ -5,32 +5,353 @@ * main.c * - Driver Core */ -#define DEBUG 0 +#define DEBUG 1 #define VERSION VER2(0,1) #include +#include #include +#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 index 00000000..b7737f9d --- /dev/null +++ b/KernelLand/Modules/USB/HID/mouse.c @@ -0,0 +1,67 @@ +/* + * Acess2 USB Stack HID Driver + * - By John Hodge (thePowersGang) + * + * mouse.c + * - USB Mouse driver + */ +#define DEBUG 0 +#include +#include "hid_reports.h" +#include + + +// === 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 + ) +{ + +} + diff --git a/KernelLand/Modules/USB/UHCI/uhci.c b/KernelLand/Modules/USB/UHCI/uhci.c index 8477c8f7..76b0ba4e 100644 --- a/KernelLand/Modules/USB/UHCI/uhci.c +++ b/KernelLand/Modules/USB/UHCI/uhci.c @@ -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 -- 2.20.1