[I8042PRT]

Implement parsing of SMBIOS tables to be able to apply hardware specific hacks. First hack fix attempt is on Microsoft VirtualMachine.

svn path=/trunk/; revision=66823
This commit is contained in:
Timo Kreuzer 2015-03-19 21:50:53 +00:00
parent 0ca08e8f25
commit 77ef72e473
6 changed files with 296 additions and 9 deletions

View file

@ -1,6 +1,7 @@
list(APPEND SOURCE
createclose.c
hwhacks.c
i8042prt.c
keyboard.c
misc.c

View file

@ -0,0 +1,268 @@
/*
* PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver
* LICENSE: GPL - See COPYING in the top level directory
* FILE: drivers/input/i8042prt/hwhacks.c
* PURPOSE: Mouse specific functions
* PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
* REFERENCES: - http://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.0.0.pdf
* -
*/
#include "i8042prt.h"
#include <wmiguid.h>
#include <wmidata.h>
#include <wmistr.h>
#include "dmi.h"
#define NDEBUG
#include <debug.h>
const GUID MSSmBios_RawSMBiosTables_GUID = SMBIOS_DATA_GUID;
PVOID i8042SMBiosTables;
ULONG i8042HwFlags;
enum _ID_STRINGS
{
ID_NONE = 0,
BIOS_VENDOR,
BIOS_VERSION,
BIOS_DATE,
SYS_VENDOR,
SYS_PRODUCT,
SYS_VERSION,
SYS_SERIAL,
BOARD_VENDOR,
BOARD_NAME,
BOARD_VERSION,
BOARD_SERIAL,
BOARD_ASSET_TAG,
ID_STRINGS_MAX,
};
typedef struct _MATCHENTRY
{
ULONG Type;
PCHAR String;
} MATCHENTRY;
#define MAX_MATCH_ENTRIES 3
typedef struct _HARDWARE_TABLE
{
MATCHENTRY MatchEntries[MAX_MATCH_ENTRIES];
ULONG Flags;
} HARDWARE_TABLE;
const HARDWARE_TABLE i8042HardwareTable[] =
{
// { {{BOARD_VENDOR, "RIOWORKS"}, {BOARD_NAME, "HDAMB"}, {BOARD_VERSION, "Rev E"}}, FL_NOLOOP },
// { {{BOARD_VENDOR, "ASUSTeK Computer Inc."}, {BOARD_NAME, "G1S"}, {BOARD_VERSION, "1.0"}}, FL_NOLOOP },
{ {{SYS_VENDOR, "Microsoft Corporation"}, {SYS_PRODUCT, "Virtual Machine"}, /*{SYS_VERSION, "VS2005R2"} */}, FL_INITHACK },
{ {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Latitude D530"}}, FL_INITHACK },
{ {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Latitude D600"}}, FL_INITHACK },
};
static
PCHAR
GetDmiString(
_In_ PDMI_HEADER Header,
_In_ ULONG FieldOffset)
{
ULONG StringIndex;
PCHAR String;
StringIndex = ((PUCHAR)Header)[FieldOffset];
String = (PCHAR)Header + Header->Length;
while (StringIndex != 0)
{
while (*String != 0)
String++;
String++;
StringIndex--;
}
return String;
}
static
VOID
i8042ParseSMBiosTables(
_In_reads_bytes_(TableSize) PVOID SMBiosTables,
_In_ ULONG TableSize)
{
PMSSmBios_RawSMBiosTables BiosTablesHeader = SMBiosTables;
PDMI_HEADER Header;
ULONG Remaining, i, j;
PCHAR Data;
PCHAR Strings[ID_STRINGS_MAX] = { 0 };
Header = (PDMI_HEADER)(&BiosTablesHeader->SMBiosData);
Remaining = BiosTablesHeader->Size;
while (Remaining >= sizeof(*Header))
{
if (Header->Type == DMI_ENTRY_END_OF_TABLE)
break;
switch (Header->Type)
{
case DMI_ENTRY_BIOS:
if (Remaining < DMI_BIOS_SIZE)
return;
Strings[BIOS_VENDOR] = GetDmiString(Header, DMI_BIOS_VENDOR);
Strings[BIOS_VERSION] = GetDmiString(Header, DMI_BIOS_VERSION);
Strings[BIOS_DATE] = GetDmiString(Header, DMI_BIOS_DATE);
break;
case DMI_ENTRY_SYSTEM:
if (Remaining < DMI_SYS_SIZE)
return;
Strings[SYS_VENDOR] = GetDmiString(Header, DMI_SYS_VENDOR);
Strings[SYS_PRODUCT] = GetDmiString(Header, DMI_SYS_PRODUCT);
Strings[SYS_VERSION] = GetDmiString(Header, DMI_SYS_VERSION);
Strings[SYS_SERIAL] = GetDmiString(Header, DMI_SYS_SERIAL);
break;
case DMI_ENTRY_BASEBOARD:
if (Remaining < DMI_BOARD_SIZE)
return;
Strings[BOARD_VENDOR] = GetDmiString(Header, DMI_BOARD_VENDOR);
Strings[BOARD_NAME] = GetDmiString(Header, DMI_BOARD_NAME);
Strings[BOARD_VERSION] = GetDmiString(Header, DMI_BOARD_VERSION);
Strings[BOARD_SERIAL] = GetDmiString(Header, DMI_BOARD_SERIAL);
Strings[BOARD_ASSET_TAG] = GetDmiString(Header, DMI_BOARD_ASSET_TAG);
break;
case DMI_ENTRY_CHASSIS:
case DMI_ENTRY_ONBOARD_DEVICE:
case DMI_ENTRY_OEMSTRINGS:
// DMI_ENTRY_IPMI_DEV?
// DMI_ENTRY_ONBOARD_DEV_EXT?
break;
}
Remaining -= Header->Length;
Data = (PCHAR)Header + Header->Length;
/* Now loop until we find 2 zeroes */
while ((Remaining >= 2) && ((Data[0] != 0) || (Data[1] != 0)))
{
Data++;
Remaining--;
}
if (Remaining < 2)
break;
/* Go to the next header */
Remaining -= 2;
Header = (PDMI_HEADER)((PUCHAR)Data + 2);
}
#if DBG
DbgPrint("i8042prt: Dumping DMI data:\n");
DbgPrint("BIOS_VENDOR: %s\n", Strings[BIOS_VENDOR]);
DbgPrint("BIOS_VERSION: %s\n", Strings[BIOS_VERSION]);
DbgPrint("BIOS_DATE: %s\n", Strings[BIOS_DATE]);
DbgPrint("SYS_VENDOR: %s\n", Strings[SYS_VENDOR]);
DbgPrint("SYS_PRODUCT: %s\n", Strings[SYS_PRODUCT]);
DbgPrint("SYS_VERSION: %s\n", Strings[SYS_VERSION]);
DbgPrint("SYS_SERIAL: %s\n", Strings[SYS_SERIAL]);
DbgPrint("BOARD_VENDOR: %s\n", Strings[BOARD_VENDOR]);
DbgPrint("BOARD_NAME: %s\n", Strings[BOARD_NAME]);
DbgPrint("BOARD_VERSION: %s\n", Strings[BOARD_VERSION]);
DbgPrint("BOARD_SERIAL: %s\n", Strings[BOARD_SERIAL]);
DbgPrint("BOARD_ASSET_TAG: %s\n", Strings[BOARD_ASSET_TAG]);
#endif
/* Now loop the hardware table to find a match */
for (i = 0; i < ARRAYSIZE(i8042HardwareTable); i++)
{
for (j = 0; j < MAX_MATCH_ENTRIES; j++)
{
ULONG Type = i8042HardwareTable[i].MatchEntries[j].Type;
if (Type != ID_NONE)
{
/* Check for a match */
if ((Strings[Type] == NULL) ||
strcmp(i8042HardwareTable[i].MatchEntries[j].String,
Strings[i8042HardwareTable[i].MatchEntries[j].Type]))
{
/* Does not match, try next entry */
break;
}
}
}
if (j == MAX_MATCH_ENTRIES)
{
/* All items matched! */
i8042HwFlags = i8042HardwareTable[i].Flags;
DPRINT("Found match for hw table index %u\n", i);
break;
}
}
}
VOID
NTAPI
i8042InitializeHwHacks(
VOID)
{
NTSTATUS Status;
PVOID DataBlockObject;
PWNODE_ALL_DATA AllData;
ULONG BufferSize;
/* Open the data block object for the SMBIOS table */
Status = IoWMIOpenBlock(&MSSmBios_RawSMBiosTables_GUID,
WMIGUID_QUERY,
&DataBlockObject);
if (!NT_SUCCESS(Status))
{
DPRINT1("IoWMIOpenBlock failed: 0x%08lx\n", Status);
return;
}
/* Query the required buffer size */
BufferSize = 0;
Status = IoWMIQueryAllData(DataBlockObject, &BufferSize, NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("IoWMIOpenBlock failed: 0x%08lx\n", Status);
return;
}
AllData = ExAllocatePoolWithTag(PagedPool, BufferSize, 'BTMS');
if (AllData == NULL)
{
DPRINT1("Failed to allocate %lu bytes for SMBIOS tables\n", BufferSize);
return;
}
/* Query the buffer data */
Status = IoWMIQueryAllData(DataBlockObject, &BufferSize, AllData);
if (!NT_SUCCESS(Status))
{
DPRINT1("IoWMIOpenBlock failed: 0x%08lx\n", Status);
return;
}
/* Parse the table */
i8042ParseSMBiosTables(AllData + 1,
AllData->WnodeHeader.BufferSize);
/* Free the buffer */
ExFreePoolWithTag(AllData, 'BTMS');
}

View file

@ -560,5 +560,7 @@ DriverEntry(
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = i8042SystemControl;
DriverObject->MajorFunction[IRP_MJ_PNP] = i8042Pnp;
i8042InitializeHwHacks();
return STATUS_SUCCESS;
}

View file

@ -441,4 +441,19 @@ ReadRegistryEntries(
IN PUNICODE_STRING RegistryPath,
OUT PI8042_SETTINGS Settings);
/* hwhacks.c */
VOID
NTAPI
i8042InitializeHwHacks(
VOID);
enum _FLAGS
{
FL_NOLOOP = 0x01,
FL_INITHACK = 0x02,
};
extern ULONG i8042HwFlags;
#endif /* _I8042PRT_PCH_ */

View file

@ -482,9 +482,10 @@ StartProcedure(
/* HACK: the mouse has already been reset in i8042DetectMouse. This second
reset prevents some touchpads/mice from working (Dell D531, D600).
See CORE-6901 */
#ifndef __I8042PRT_HACK_FOR_NOTEBOOK__
i8042IsrWritePort(DeviceExtension, MOU_CMD_RESET, CTRL_WRITE_MOUSE);
#endif
if (!(i8042HwFlags & FL_INITHACK))
{
i8042IsrWritePort(DeviceExtension, MOU_CMD_RESET, CTRL_WRITE_MOUSE);
}
KeReleaseInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt, Irql);
}

View file

@ -25,22 +25,22 @@
#include <guiddef.h>
#define DATA_PROVIDER_INFO_GUID \
{0x5494dfdc, 0xa98a, 0x11d1, 0xbf, 0x43, 0x00, 0xa0, 0xc9, 0x06, 0x29, 0x10}
{0x5494dfdc, 0xa98a, 0x11d1, {0xbf, 0x43, 0x00, 0xa0, 0xc9, 0x06, 0x29, 0x10}}
#define SMBIOS_DATA_GUID \
{0x8f680850, 0xa584, 0x11d1, 0xbf, 0x38, 0x00, 0xa0, 0xc9, 0x06, 0x29, 0x10}
{0x8f680850, 0xa584, 0x11d1, {0xbf, 0x38, 0x00, 0xa0, 0xc9, 0x06, 0x29, 0x10}}
#define INSTANCE_INFO_GUID \
{0xc7bf35d0, 0xaadb, 0x11d1, 0xbf, 0x4a, 0x00, 0xa0, 0xc9, 0x6, 0x29, 0x10}
{0xc7bf35d0, 0xaadb, 0x11d1, {0xbf, 0x4a, 0x00, 0xa0, 0xc9, 0x06, 0x29, 0x10}}
#define BINARY_MOF_GUID \
{0x05901221, 0xD566, 0x11d1, 0xB2, 0xF0, 0x00, 0xA0, 0xC9, 0x06, 0x29, 0x10}
{0x05901221, 0xD566, 0x11d1, {0xB2, 0xF0, 0x00, 0xA0, 0xC9, 0x06, 0x29, 0x10}}
#define ENUMERATE_GUIDS_GUID \
{0xe3dff7bd, 0x3915, 0x11d2, 0x91, 0x03, 0x00, 0xc0, 0x4f, 0xb9, 0x98, 0xa2}
{0xe3dff7bd, 0x3915, 0x11d2, {0x91, 0x03, 0x00, 0xc0, 0x4f, 0xb9, 0x98, 0xa2}}
#define MS_SYSTEM_INFORMATIONGUID \
{0x98a2b9d7, 0x94dd, 0x496a, {0x84, 0x7e, 0x67, 0xa5, 0x55, 0x7a, 0x59, 0xf2}}
{0x98a2b9d7, 0x94dd, 0x496a, {0x84, 0x7e, 0x67, 0xa5, 0x55, 0x7a, 0x59, 0xf2}}
DEFINE_GUID(MS_SYSTEM_INFORMATION_GUID, \
0x98a2b9d7, 0x94dd, 0x496a, 0x84, 0x7e, 0x67, 0xa5, 0x55, 0x7a, 0x59, 0xf2);