MODULES += Display/BochsGA
MODULES += Input/PS2KbMouse
MODULES += x86/ISADMA x86/VGAText
+
MODULES += USB/Core USB/UHCI USB/OHCI
+MODULES += USB/HID
#MODULES += Interfaces/UDI
};
// === 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);
}
#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);
} VendorDev;
} Match;
- void (*Connected)(tUSBInterface *Dev);
+ void (*Connected)(tUSBInterface *Dev, void *Descriptors, size_t Size);
void (*Disconnected)(tUSBInterface *Dev);
int MaxEndpoints;
// --- Drivers ---
void USB_RegisterDriver(tUSBDriver *Driver)
{
- Log_Warning("USB", "TODO: Implement USB_RegisterDriver");
Driver->Next = gpUSB_InterfaceDrivers;
gpUSB_InterfaceDrivers = Driver;
}
* usb_devinit.c
* - USB Device Initialisation
*/
-#define DEBUG 1
+#define DEBUG 0
#include <acess.h>
#include <vfs.h>
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);
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);
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);
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);
);
}
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 );
}
}
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(
--- /dev/null
+#
+# Acess2 HID Driver
+#
+
+OBJ = main.o mouse.o
+CPPFLAGS = -I../Core/include
+NAME = HID
+
+-include ../Makefile.tpl
struct {
Uint8 DescType;
Uint16 DescLen;
- } Descriptors[];
-}
+ } PACKED Descriptors[];
+} PACKED;
#endif
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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",
+};
* 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);
}
--- /dev/null
+/*
+ * 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
+ )
+{
+
+}
+
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);
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;
}
prev_td->Link = MM_GetPhysAddr( (tVAddr)TD );
LOG("next_frame = %i, prev_td = %p", next_frame, prev_td);
+ LEAVE('-');
}
/**
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