Author: fireball Date: Tue Mar 3 15:06:57 2009 New Revision: 39856
URL: http://svn.reactos.org/svn/reactos?rev=39856&view=rev Log: - Move part of the 1st stage pnp hacks to kbdclass driver. Previously, the driver (i8042prt) relied on kbdclass's normal reinit routine being called BEFORE a registered boot reinit routine, which is certainly wrong on a real NT system. - Now, the correct order is ensured, and it is not relying on a broken reinit calling order in ReactOS anymore.
Added: trunk/reactos/drivers/input/kbdclass/setup.c - copied, changed from r39836, trunk/reactos/drivers/input/i8042prt/setup.c Modified: trunk/reactos/drivers/input/i8042prt/setup.c trunk/reactos/drivers/input/kbdclass/kbdclass.c trunk/reactos/drivers/input/kbdclass/kbdclass.h trunk/reactos/drivers/input/kbdclass/kbdclass.rbuild
Modified: trunk/reactos/drivers/input/i8042prt/setup.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/i8042prt/setu... ============================================================================== --- trunk/reactos/drivers/input/i8042prt/setup.c [iso-8859-1] (original) +++ trunk/reactos/drivers/input/i8042prt/setup.c [iso-8859-1] Tue Mar 3 15:06:57 2009 @@ -44,123 +44,6 @@ ZwClose(hSetupKey); INFO_(I8042PRT, "IsFirstStageSetup() returns %s\n", ret ? "YES" : "NO"); return ret; -} - -static VOID NTAPI -SendStartDevice( - IN PDRIVER_OBJECT DriverObject, - IN PVOID Context, - IN ULONG Count) -{ - PDEVICE_OBJECT Pdo; - PCM_RESOURCE_LIST AllocatedResources = NULL; - PCM_RESOURCE_LIST AllocatedResourcesTranslated = NULL; - PDEVICE_OBJECT TopDeviceObject = NULL; - KEVENT Event; - IO_STATUS_BLOCK IoStatusBlock; - PIRP Irp; - PIO_STACK_LOCATION Stack; - ULONG ResourceListSize; - NTSTATUS Status; - - Pdo = (PDEVICE_OBJECT)Context; - TRACE_(I8042PRT, "SendStartDevice(%p)\n", Pdo); - - /* Create default resource list */ - ResourceListSize = sizeof(CM_RESOURCE_LIST) + 3 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); - AllocatedResources = ExAllocatePoolWithTag(PagedPool, ResourceListSize, I8042PRT_TAG); - if (!AllocatedResources) - { - WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n"); - Status = STATUS_NO_MEMORY; - goto cleanup; - } - AllocatedResources->Count = 1; - AllocatedResources->List[0].PartialResourceList.Version = 1; - AllocatedResources->List[0].PartialResourceList.Revision = 1; - AllocatedResources->List[0].PartialResourceList.Count = 3; - /* Data port */ - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].Type = CmResourceTypePort; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].ShareDisposition = CmResourceShareDeviceExclusive; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].Flags = 0; /* FIXME */ - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Start.u.HighPart = 0; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Start.u.LowPart = KEYBOARD_DATA_PORT; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Length = 1; - /* Control port */ - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].Type = CmResourceTypePort; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].ShareDisposition = CmResourceShareDeviceExclusive; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].Flags = 0; /* FIXME */ - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].u.Port.Start.u.HighPart = 0; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].u.Port.Start.u.LowPart = KEYBOARD_CONTROL_PORT; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[1].u.Port.Length = 1; - /* Interrupt */ - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].Type = CmResourceTypeInterrupt; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].ShareDisposition = CmResourceShareDeviceExclusive; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].Flags = CM_RESOURCE_INTERRUPT_LATCHED; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Level = KEYBOARD_IRQ; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Vector = 0; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Affinity = (KAFFINITY)-1; - - /* Create default resource list translated */ - AllocatedResourcesTranslated = ExAllocatePoolWithTag(PagedPool, ResourceListSize, I8042PRT_TAG); - if (!AllocatedResourcesTranslated) - { - WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n"); - Status = STATUS_NO_MEMORY; - goto cleanup; - } - RtlCopyMemory(AllocatedResourcesTranslated, AllocatedResources, ResourceListSize); - AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Vector = HalGetInterruptVector( - Internal, 0, - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Level, - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Vector, - (PKIRQL)&AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Level, - &AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Affinity); - - /* Send IRP_MN_START_DEVICE */ - TopDeviceObject = IoGetAttachedDeviceReference(Pdo); - KeInitializeEvent( - &Event, - NotificationEvent, - FALSE); - Irp = IoBuildSynchronousFsdRequest( - IRP_MJ_PNP, - TopDeviceObject, - NULL, - 0, - NULL, - &Event, - &IoStatusBlock); - Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; - Irp->IoStatus.Information = 0; - Stack = IoGetNextIrpStackLocation(Irp); - Stack->MinorFunction = IRP_MN_START_DEVICE; - Stack->Parameters.StartDevice.AllocatedResources = AllocatedResources; - Stack->Parameters.StartDevice.AllocatedResourcesTranslated = AllocatedResourcesTranslated; - Status = IoCallDriver(TopDeviceObject, Irp); - if (Status == STATUS_PENDING) - { - KeWaitForSingleObject( - &Event, - Executive, - KernelMode, - FALSE, - NULL); - Status = IoStatusBlock.Status; - } - if (!NT_SUCCESS(Status)) - { - WARN_(I8042PRT, "IoCallDriver() failed with status 0x%08lx\n", Status); - goto cleanup; - } - -cleanup: - if (TopDeviceObject) - ObDereferenceObject(TopDeviceObject); - if (AllocatedResources) - ExFreePoolWithTag(AllocatedResources, I8042PRT_TAG); - if (AllocatedResourcesTranslated) - ExFreePoolWithTag(AllocatedResourcesTranslated, I8042PRT_TAG); }
static NTSTATUS @@ -251,12 +134,8 @@ goto cleanup; }
- /* We will send the IRP_MN_START_DEVICE later, once kbdclass is loaded */ + /* We will send the IRP_MN_START_DEVICE later when kbdclass looks for legacy drivers */ AddRegistryEntry(L"KeyboardPort", &KeyboardName, RegistryPath->Buffer); - IoRegisterBootDriverReinitialization( - DriverObject, - SendStartDevice, - Pdo);
Status = STATUS_SUCCESS; /* Yes, completly forget the Pdo pointer, as we will never
Modified: trunk/reactos/drivers/input/kbdclass/kbdclass.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/kbdclass/kbdc... ============================================================================== --- trunk/reactos/drivers/input/kbdclass/kbdclass.c [iso-8859-1] (original) +++ trunk/reactos/drivers/input/kbdclass/kbdclass.c [iso-8859-1] Tue Mar 3 15:06:57 2009 @@ -939,6 +939,10 @@ /* FIXME: Log the error */ WARN_(CLASS_NAME, "ClassAddDevice() failed with status 0x%08lx\n", Status); } + + /* A special hack for 1st stage setup: manually send start device to i8042prt */ + if (IsFirstStageSetup()) + Send8042StartDevice(DriverObject, PortDeviceObject); }
cleanup:
Modified: trunk/reactos/drivers/input/kbdclass/kbdclass.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/kbdclass/kbdc... ============================================================================== --- trunk/reactos/drivers/input/kbdclass/kbdclass.h [iso-8859-1] (original) +++ trunk/reactos/drivers/input/kbdclass/kbdclass.h [iso-8859-1] Tue Mar 3 15:06:57 2009 @@ -81,3 +81,13 @@ IN ULONG Flags, IN PCUNICODE_STRING SourceString, OUT PUNICODE_STRING DestinationString); + +/* setup.c */ +BOOLEAN +IsFirstStageSetup( + VOID); + +VOID NTAPI +Send8042StartDevice( + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT Pdo);
Modified: trunk/reactos/drivers/input/kbdclass/kbdclass.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/kbdclass/kbdc... ============================================================================== --- trunk/reactos/drivers/input/kbdclass/kbdclass.rbuild [iso-8859-1] (original) +++ trunk/reactos/drivers/input/kbdclass/kbdclass.rbuild [iso-8859-1] Tue Mar 3 15:06:57 2009 @@ -7,6 +7,7 @@ <library>hal</library> <file>kbdclass.c</file> <file>misc.c</file> + <file>setup.c</file> <file>kbdclass.rc</file> <!-- See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38054#c7 --> <compilerflag>-fno-unit-at-a-time</compilerflag>
Copied: trunk/reactos/drivers/input/kbdclass/setup.c (from r39836, trunk/reactos/drivers/input/i8042prt/setup.c) URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/kbdclass/setu... ============================================================================== --- trunk/reactos/drivers/input/i8042prt/setup.c [iso-8859-1] (original) +++ trunk/reactos/drivers/input/kbdclass/setup.c [iso-8859-1] Tue Mar 3 15:06:57 2009 @@ -1,7 +1,7 @@ /* - * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver + * PROJECT: ReactOS Keyboard class driver * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/input/i8042prt/setup.c + * FILE: drivers/input/kbdclass/setup.c * PURPOSE: Create a legacy PDO during ReactOS installation * PROGRAMMERS: Copyright 2006-2007 Hervé Poussineau (hpoussin@reactos.org) */ @@ -12,7 +12,7 @@
/* INCLUDES ******************************************************************/
-#include "i8042prt.h" +#include "kbdclass.h"
/* GLOBALS *******************************************************************/
@@ -42,17 +42,15 @@
if (hSetupKey != (HANDLE)NULL) ZwClose(hSetupKey); - INFO_(I8042PRT, "IsFirstStageSetup() returns %s\n", ret ? "YES" : "NO"); + INFO_(CLASS_NAME, "IsFirstStageSetup() returns %s\n", ret ? "YES" : "NO"); return ret; }
-static VOID NTAPI -SendStartDevice( +VOID NTAPI +Send8042StartDevice( IN PDRIVER_OBJECT DriverObject, - IN PVOID Context, - IN ULONG Count) + IN PDEVICE_OBJECT Pdo) { - PDEVICE_OBJECT Pdo; PCM_RESOURCE_LIST AllocatedResources = NULL; PCM_RESOURCE_LIST AllocatedResourcesTranslated = NULL; PDEVICE_OBJECT TopDeviceObject = NULL; @@ -63,15 +61,14 @@ ULONG ResourceListSize; NTSTATUS Status;
- Pdo = (PDEVICE_OBJECT)Context; - TRACE_(I8042PRT, "SendStartDevice(%p)\n", Pdo); + TRACE_(CLASS_NAME, "SendStartDevice(%p)\n", Pdo);
/* Create default resource list */ ResourceListSize = sizeof(CM_RESOURCE_LIST) + 3 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); - AllocatedResources = ExAllocatePoolWithTag(PagedPool, ResourceListSize, I8042PRT_TAG); + AllocatedResources = ExAllocatePoolWithTag(PagedPool, ResourceListSize, CLASS_TAG); if (!AllocatedResources) { - WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n"); + WARN_(CLASS_NAME, "ExAllocatePoolWithTag() failed\n"); Status = STATUS_NO_MEMORY; goto cleanup; } @@ -102,10 +99,10 @@ AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Affinity = (KAFFINITY)-1;
/* Create default resource list translated */ - AllocatedResourcesTranslated = ExAllocatePoolWithTag(PagedPool, ResourceListSize, I8042PRT_TAG); + AllocatedResourcesTranslated = ExAllocatePoolWithTag(PagedPool, ResourceListSize, CLASS_TAG); if (!AllocatedResourcesTranslated) { - WARN_(I8042PRT, "ExAllocatePoolWithTag() failed\n"); + WARN_(CLASS_NAME, "ExAllocatePoolWithTag() failed\n"); Status = STATUS_NO_MEMORY; goto cleanup; } @@ -150,7 +147,7 @@ } if (!NT_SUCCESS(Status)) { - WARN_(I8042PRT, "IoCallDriver() failed with status 0x%08lx\n", Status); + WARN_(CLASS_NAME, "IoCallDriver() failed with status 0x%08lx\n", Status); goto cleanup; }
@@ -158,116 +155,7 @@ if (TopDeviceObject) ObDereferenceObject(TopDeviceObject); if (AllocatedResources) - ExFreePoolWithTag(AllocatedResources, I8042PRT_TAG); + ExFreePoolWithTag(AllocatedResources, CLASS_TAG); if (AllocatedResourcesTranslated) - ExFreePoolWithTag(AllocatedResourcesTranslated, I8042PRT_TAG); + ExFreePoolWithTag(AllocatedResourcesTranslated, CLASS_TAG); } - -static NTSTATUS -AddRegistryEntry( - IN PCWSTR PortTypeName, - IN PUNICODE_STRING DeviceName, - IN PCWSTR RegistryPath) -{ - UNICODE_STRING PathU = RTL_CONSTANT_STRING(L"\REGISTRY\MACHINE\HARDWARE\DEVICEMAP"); - OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE hDeviceMapKey = (HANDLE)-1; - HANDLE hPortKey = (HANDLE)-1; - UNICODE_STRING PortTypeNameU; - NTSTATUS Status; - - InitializeObjectAttributes(&ObjectAttributes, &PathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); - Status = ZwOpenKey(&hDeviceMapKey, 0, &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - WARN_(I8042PRT, "ZwOpenKey() failed with status 0x%08lx\n", Status); - goto cleanup; - } - - RtlInitUnicodeString(&PortTypeNameU, PortTypeName); - InitializeObjectAttributes(&ObjectAttributes, &PortTypeNameU, OBJ_KERNEL_HANDLE, hDeviceMapKey, NULL); - Status = ZwCreateKey(&hPortKey, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL); - if (!NT_SUCCESS(Status)) - { - WARN_(I8042PRT, "ZwCreateKey() failed with status 0x%08lx\n", Status); - goto cleanup; - } - - Status = ZwSetValueKey(hPortKey, DeviceName, 0, REG_SZ, (PVOID)RegistryPath, wcslen(RegistryPath) * sizeof(WCHAR) + sizeof(UNICODE_NULL)); - if (!NT_SUCCESS(Status)) - { - WARN_(I8042PRT, "ZwSetValueKey() failed with status 0x%08lx\n", Status); - goto cleanup; - } - - Status = STATUS_SUCCESS; - -cleanup: - if (hDeviceMapKey != (HANDLE)-1) - ZwClose(hDeviceMapKey); - if (hPortKey != (HANDLE)-1) - ZwClose(hPortKey); - return Status; -} - -NTSTATUS -i8042AddLegacyKeyboard( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath) -{ - UNICODE_STRING KeyboardName = RTL_CONSTANT_STRING(L"\Device\KeyboardPort8042"); - PI8042_DEVICE_TYPE DeviceExtension = NULL; - PDEVICE_OBJECT Pdo = NULL; - NTSTATUS Status; - - TRACE_(I8042PRT, "i8042AddLegacyKeyboard()\n"); - - /* Create a named PDO */ - Status = IoCreateDevice( - DriverObject, - sizeof(I8042_DEVICE_TYPE), - &KeyboardName, - FILE_DEVICE_8042_PORT, - FILE_DEVICE_SECURE_OPEN, - TRUE, - &Pdo); - if (!NT_SUCCESS(Status)) - { - WARN_(I8042PRT, "IoCreateDevice() failed with status 0x%08lx\n", Status); - goto cleanup; - } - - /* Initialize device extension */ - DeviceExtension = (PI8042_DEVICE_TYPE)Pdo->DeviceExtension; - RtlZeroMemory(DeviceExtension, sizeof(I8042_DEVICE_TYPE)); - *DeviceExtension = PhysicalDeviceObject; - Pdo->Flags &= ~DO_DEVICE_INITIALIZING; - - /* Add FDO at the top of the PDO */ - Status = i8042AddDevice(DriverObject, Pdo); - if (!NT_SUCCESS(Status)) - { - WARN_(I8042PRT, "i8042AddDevice() failed with status 0x%08lx\n", Status); - goto cleanup; - } - - /* We will send the IRP_MN_START_DEVICE later, once kbdclass is loaded */ - AddRegistryEntry(L"KeyboardPort", &KeyboardName, RegistryPath->Buffer); - IoRegisterBootDriverReinitialization( - DriverObject, - SendStartDevice, - Pdo); - - Status = STATUS_SUCCESS; - /* Yes, completly forget the Pdo pointer, as we will never - * have to unload this driver during first stage setup. - */ - -cleanup: - if (!NT_SUCCESS(Status)) - { - if (Pdo) - IoDeleteDevice(Pdo); - } - return Status; -}