From 1797e6eb24e9840405ef348ed5b7cb73b12fdc7d Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 17 Feb 2012 11:18:15 +0800 Subject: [PATCH] Modules/USB - Crash prevention in UHCI, VFS interface for HIDMouse --- KernelLand/Modules/USB/Core/usb_poll.c | 12 +++- KernelLand/Modules/USB/HID/main.c | 23 +++++- KernelLand/Modules/USB/HID/mouse.c | 97 ++++++++++++++++++++++++-- KernelLand/Modules/USB/UHCI/uhci.c | 6 ++ 4 files changed, 128 insertions(+), 10 deletions(-) diff --git a/KernelLand/Modules/USB/Core/usb_poll.c b/KernelLand/Modules/USB/Core/usb_poll.c index 84703f84..6285a11e 100644 --- a/KernelLand/Modules/USB/Core/usb_poll.c +++ b/KernelLand/Modules/USB/Core/usb_poll.c @@ -5,7 +5,7 @@ * usb_poll.c * - Endpoint polling */ -#define DEBUG 1 +#define DEBUG 0 #include #include "usb.h" #include @@ -29,9 +29,14 @@ void USB_StartPollingEndpoint(tUSBInterface *Iface, int Endpoint) { tUSBEndpoint *endpt; + ENTER("pIface iEndpoint", Iface, Endpoint); + LEAVE('-'); + // Some sanity checks - if(Endpoint <= 0 || Endpoint > Iface->nEndpoints) return ; + if(Endpoint <= 0 || Endpoint > Iface->nEndpoints) + return ; endpt = &Iface->Endpoints[Endpoint-1]; + LOG("endpt(%p)->PollingPeriod = %i", endpt, endpt->PollingPeriod); if(endpt->PollingPeriod > POLL_MAX || endpt->PollingPeriod <= 0) return ; @@ -42,6 +47,7 @@ void USB_StartPollingEndpoint(tUSBInterface *Iface, int Endpoint) // Determine polling period in atoms endpt->PollingAtoms = (endpt->PollingPeriod + POLL_ATOM-1) / POLL_ATOM; if(endpt->PollingAtoms > POLL_SLOTS) endpt->PollingAtoms = POLL_SLOTS; + LOG("endpt(%p)->PollingAtoms = %i", endpt, endpt->PollingAtoms); // Add to poll queue // TODO: Locking { @@ -81,7 +87,7 @@ int USB_PollThread(void *unused) for( ep = gUSB_PollQueues[giUSB_PollPosition]; ep; prev = ep, ep = ep->Next ) { int period_in_atoms = ep->PollingAtoms; -// LOG("%i: ep = %p", giUSB_PollPosition, ep); + LOG("%i: ep = %p", giUSB_PollPosition, ep); // Check for invalid entries if(period_in_atoms < 0 || period_in_atoms > POLL_ATOM) diff --git a/KernelLand/Modules/USB/HID/main.c b/KernelLand/Modules/USB/HID/main.c index 68e301e2..25b533db 100644 --- a/KernelLand/Modules/USB/HID/main.c +++ b/KernelLand/Modules/USB/HID/main.c @@ -12,6 +12,7 @@ #include #include "hid.h" #include "hid_reports.h" +#include // === TYPES === typedef struct sHID_Device tHID_Device; @@ -23,6 +24,10 @@ struct sHID_Device // ... Device-specific data }; +// === IMPORTS === +extern tHID_ReportCallbacks gHID_Mouse_ReportCBs; +extern tDevFS_Driver gHID_Mouse_DevFS; + // === PROTOTYPES === int HID_Initialise(char **Arguments); void HID_InterruptCallback(tUSBInterface *Dev, int EndPt, int Length, void *Data); @@ -54,6 +59,9 @@ tHID_ReportCallbacks gHID_RootCallbacks = { int HID_Initialise(char **Arguments) { USB_RegisterDriver( &gHID_USBDriver ); + + DevFS_AddDevice( &gHID_Mouse_DevFS ); + return 0; } @@ -146,6 +154,19 @@ void HID_DeviceConnected(tUSBInterface *Dev, void *Descriptors, size_t Descripto USB_ReadDescriptor(Dev, 0x1022, 0, report_len, report_data); HID_int_ParseReport(Dev, report_data, report_len, &gHID_RootCallbacks); + // --- Start polling --- + // Only if the device was initialised + if( USB_GetDeviceDataPtr(Dev) ) + { + // Poll Endpoint .+1 (interupt) + USB_StartPollingEndpoint(Dev, 1); + } + else + { + Log_Log("USB_HID", "Device not intitialised"); + } + + LEAVE('-'); } @@ -178,7 +199,7 @@ tHID_ReportCallbacks *HID_RootCollection( break; case 0x0002: // Mouse LOG("Desktop->Mouse"); - break; + return &gHID_Mouse_ReportCBs; case 0x0004: // Joystick case 0x0005: // Game Pad LOG("Desktop->Gamepad"); diff --git a/KernelLand/Modules/USB/HID/mouse.c b/KernelLand/Modules/USB/HID/mouse.c index be015add..233465a9 100644 --- a/KernelLand/Modules/USB/HID/mouse.c +++ b/KernelLand/Modules/USB/HID/mouse.c @@ -5,7 +5,7 @@ * mouse.c * - USB Mouse driver */ -#define DEBUG 0 +#define DEBUG 1 #include #include "hid_reports.h" #include @@ -14,6 +14,7 @@ // === CONSTANTS === #define MAX_AXIES 3 // X, Y, Scroll #define MAX_BUTTONS 5 // Left, Right, Middle, ... +#define FILE_SIZE (sizeof(tJoystick_FileHeader) + MAX_AXIES*sizeof(tJoystick_Axis) + MAX_BUTTONS) // === TYPES === typedef struct sHID_Mouse tHID_Mouse; @@ -26,7 +27,7 @@ struct sHID_Mouse tVFS_Node Node; int CollectionDepth; - Uint8 FileData[ sizeof(tJoystick_FileHeader) + MAX_AXIES*sizeof(tJoystick_Axis) + MAX_BUTTONS ]; + Uint8 FileData[ FILE_SIZE ]; tJoystick_FileHeader *FileHeader; tJoystick_Axis *Axies; Uint8 *Buttons; @@ -41,17 +42,31 @@ struct sHID_Mouse }; // === PROTOTYES === +char *HID_Mouse_Root_ReadDir(tVFS_Node *Node, int Pos); +tVFS_Node *HID_Mouse_Root_FindDir(tVFS_Node *Node, const char *Name); +Uint64 HID_Mouse_Dev_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer); + int HID_Mouse_Dev_IOCtl(tVFS_Node *Node, int ID, void *Data); +void HID_Mouse_Dev_Reference(tVFS_Node *Node); +void HID_Mouse_Dev_Close(tVFS_Node *Node); + void HID_Mouse_DataAvail(tUSBInterface *Dev, int EndPt, int Length, void *Data); + tHID_ReportCallbacks *HID_Mouse_Report_Collection(tUSBInterface *Dev, tHID_ReportGlobalState *Global, tHID_ReportLocalState *Local, Uint32 Value); void HID_Mouse_Report_EndCollection(tUSBInterface *Dev); void HID_Mouse_Report_Input(tUSBInterface *Dev, tHID_ReportGlobalState *Global, tHID_ReportLocalState *Local, Uint32 Value); // === GLOBALS === tVFS_NodeType gHID_Mouse_RootNodeType = { - .TypeName = "HID Mouse Root" + .TypeName = "HID Mouse Root", + .ReadDir = HID_Mouse_Root_ReadDir, + .FindDir = HID_Mouse_Root_FindDir }; tVFS_NodeType gHID_Mouse_DevNodeType = { - .TypeName = "HID Mouse Dev" + .TypeName = "HID Mouse Dev", + .Read = HID_Mouse_Dev_Read, + .IOCtl = HID_Mouse_Dev_IOCtl, + .Reference = HID_Mouse_Dev_Reference, + .Close = HID_Mouse_Dev_Close, }; tDevFS_Driver gHID_Mouse_DevFS = { .Name = "USBMouse", @@ -62,6 +77,7 @@ tHID_ReportCallbacks gHID_Mouse_ReportCBs = { .EndCollection = HID_Mouse_Report_EndCollection, .Input = HID_Mouse_Report_Input, }; +tMutex glHID_MouseListLock; tHID_Mouse *gpHID_FirstMouse; tHID_Mouse *gpHID_LastMouse = (tHID_Mouse*)&gpHID_FirstMouse; @@ -69,6 +85,68 @@ tHID_Mouse *gpHID_LastMouse = (tHID_Mouse*)&gpHID_FirstMouse; // ---------------------------------------------------------------------------- // VFS Interface // ---------------------------------------------------------------------------- +char *HID_Mouse_Root_ReadDir(tVFS_Node *Node, int Pos) +{ + char data[3]; + if(Pos < 0 || Pos >= Node->Size) return NULL; + + snprintf(data, 3, "%i", Pos); + return strdup(data); +} + +tVFS_Node *HID_Mouse_Root_FindDir(tVFS_Node *Node, const char *Name) +{ + int ID; + int ofs; + tHID_Mouse *mouse; + + if( Name[0] == '\0' ) + return NULL; + + ofs = ParseInt(Name, &ID); + if( ofs == 0 || Name[ofs] != '\0' ) + return NULL; + + // Scan list, locate item + Mutex_Acquire(&glHID_MouseListLock); + for( mouse = gpHID_FirstMouse; mouse && ID --; mouse = mouse->Next ) ; + mouse->Node.ReferenceCount ++; + Mutex_Release(&glHID_MouseListLock); + + return &mouse->Node; +} + +Uint64 HID_Mouse_Dev_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) +{ + tHID_Mouse *info = Node->ImplPtr; + + if( Offset > FILE_SIZE ) return 0; + + if( Length > FILE_SIZE ) Length = FILE_SIZE; + if( Offset + Length > FILE_SIZE ) Length = FILE_SIZE - Offset; + + memcpy( Buffer, info->FileData + Offset, Length ); + + return Length; +} + +static const char *csaDevIOCtls[] = {DRV_IOCTLNAMES, DRV_JOY_IOCTLNAMES, NULL}; +int HID_Mouse_Dev_IOCtl(tVFS_Node *Node, int ID, void *Data) +{ + switch(ID) + { + BASE_IOCTLS(DRV_TYPE_JOYSTICK, "USBMouse", 0x050, csaDevIOCtls); + } + return -1; +} +void HID_Mouse_Dev_Reference(tVFS_Node *Node) +{ + Node->ReferenceCount ++; +} +void HID_Mouse_Dev_Close(tVFS_Node *Node) +{ + Node->ReferenceCount --; +} // ---------------------------------------------------------------------------- // Data input / Update @@ -124,7 +202,8 @@ void HID_Mouse_DataAvail(tUSBInterface *Dev, int EndPt, int Length, void *Data) info = USB_GetDeviceDataPtr(Dev); if( !info ) return ; - + + Log_Debug("USBMouse", "info = %p", info); ofs = 0; for( int i = 0; i < info->nMappings; i ++ ) @@ -189,11 +268,14 @@ tHID_ReportCallbacks *HID_Mouse_Report_Collection( // New device! info = calloc( sizeof(tHID_Mouse), 1 ); info->DataAvail = HID_Mouse_DataAvail; + info->Node.ImplPtr = info; info->Node.Type = &gHID_Mouse_DevNodeType; info->FileHeader = (void*)info->FileData; info->Axies = (void*)(info->FileHeader + 1); info->Buttons = (void*)(info->Axies + MAX_AXIES); + + LOG("Initialised new mouse at %p", info); USB_SetDeviceDataPtr(Dev, info); } @@ -217,9 +299,12 @@ void HID_Mouse_Report_EndCollection(tUSBInterface *Dev) if( info->CollectionDepth == 0 ) { - // TODO: Do final cleanup on device + // Perform final initialisation steps + Mutex_Acquire(&glHID_MouseListLock); gpHID_LastMouse->Next = info; gpHID_LastMouse = info; + gHID_Mouse_DevFS.RootNode.Size ++; + Mutex_Release(&glHID_MouseListLock); } else { diff --git a/KernelLand/Modules/USB/UHCI/uhci.c b/KernelLand/Modules/USB/UHCI/uhci.c index 76b0ba4e..b348a45f 100644 --- a/KernelLand/Modules/USB/UHCI/uhci.c +++ b/KernelLand/Modules/USB/UHCI/uhci.c @@ -191,6 +191,12 @@ void UHCI_int_AppendTD(tUHCI_Controller *Cont, tUHCI_TD *TD) link = Cont->FrameList[next_frame]; do { prev_td = UHCI_int_GetTDFromPhys(link); + if(!prev_td) { + Log_Error("UHCI", "ERROR: TD list is bad"); + TD->Link = 1; + LEAVE('-'); + return ; + } link = prev_td->Link; } while( !(link & 1) ); -- 2.20.1