mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 10:35:28 +00:00
[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:
parent
0ca08e8f25
commit
77ef72e473
6 changed files with 296 additions and 9 deletions
|
@ -1,6 +1,7 @@
|
|||
|
||||
list(APPEND SOURCE
|
||||
createclose.c
|
||||
hwhacks.c
|
||||
i8042prt.c
|
||||
keyboard.c
|
||||
misc.c
|
||||
|
|
268
reactos/drivers/input/i8042prt/hwhacks.c
Normal file
268
reactos/drivers/input/i8042prt/hwhacks.c
Normal 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');
|
||||
}
|
||||
|
|
@ -560,5 +560,7 @@ DriverEntry(
|
|||
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = i8042SystemControl;
|
||||
DriverObject->MajorFunction[IRP_MJ_PNP] = i8042Pnp;
|
||||
|
||||
i8042InitializeHwHacks();
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue