diff --git a/reactos/drivers/input/i8042prt/README.txt b/reactos/drivers/input/i8042prt/README.txt deleted file mode 100644 index 16bb6c791fb..00000000000 --- a/reactos/drivers/input/i8042prt/README.txt +++ /dev/null @@ -1,80 +0,0 @@ -Intel 8042 port driver - -This directory contains a driver for Intels 8042 and compatible controllers. -It is based on the information in the DDK documentation on MSDN. It is intended -to be compatible with keyboard and mouse drivers written for Windows. It is -not based on the i8042prt example driver that's included with the DDK. - -The directory contains these files: - -createclose.c: open/close devices functionnality - -i8042prt.c: Main controller functionality, things shared by keyboards and mice - -keyboard.c: keyboard functionality: detection, interrupt handling - -misc.c: misc things, mostly related to Irp passing - -mouse.c: mouse functionality: detection, interrupt handling, packet parsing for - standard ps2 and microsoft mice - -pnp.c: Plug&Play functionnality - -ps2pp.c: logitech ps2++ mouse packat parsing (basic) - -readwrite.c: read/write to the i8042 controller - -registry.c: registry reading - -setup.c: add keyboard support during the 1st stage setup - -i8042prt.rc: obvious - - -Some parts of the driver make little sense. This is because it implements -an interface that has evolved over a long time, and because the ps/2 -'standard' is really awful. - -Things to add: - -- Better AT (before ps2) keyboard handling -- SiS keyboard controller detection -- Mouse identification -- General robustness: reset mouse if things go wrong -- Handling all registry settings -- ACPI - -Things not to add: - -- Other mouse protocols, touchpad handling etc. : Write a filter driver instead -- Keyboard lights handling: Should be in win32k -- Keyboard scancode translation: Should be in win32k - -Things requiring work elsewhere: - -- Debugger interface (TAB + key): - Currently this interface wants translated keycodes, which are not - implemented by this driver. As it just uses a giant switch with - hardcoded cases, this should not be hard to fix. - -- Class drivers: - The class drivers should be able to handle reads for more than one packet - at a time (kbdclass should, mouclass does not). Win32k should send such - requests. - - -I put a lot of work in making it work like Microsofts driver does, so third party drivers can work. Please keep it that way. - - -Links: - -Here's a link describing most of the registry settings: - -http://www.microsoft.com/resources/documentation/Windows/2000/server/reskit/en-us/Default.asp?url=/resources/documentation/Windows/2000/server/reskit/en-us/regentry/31493.asp - -PS/2 protocol documentation: - -http://www.win.tue.nl/~aeb/linux/kbd/scancodes.html - -It also contains a link to a description of the ps2++ protocol, which has -since disappeared. Archive.org still has it. diff --git a/reactos/drivers/input/i8042prt/createclose.c b/reactos/drivers/input/i8042prt/createclose.c deleted file mode 100644 index e895dbee3cc..00000000000 --- a/reactos/drivers/input/i8042prt/createclose.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/input/i8042prt/createclose.c - * PURPOSE: IRP_MJ_CREATE, IRP_MJ_CLEANUP and IRP_MJ_CLOSE operations - * PROGRAMMERS: Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) - */ - -/* INCLUDES ******************************************************************/ - -#include "i8042prt.h" - -#define NDEBUG -#include - -/* FUNCTIONS *****************************************************************/ - -NTSTATUS NTAPI -i8042Create( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - DPRINT("IRP_MJ_CREATE\n"); - - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_SUCCESS; -} - -NTSTATUS NTAPI -i8042Cleanup( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - DPRINT("IRP_MJ_CLEANUP\n"); - - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_SUCCESS; -} - -NTSTATUS NTAPI -i8042Close( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - DPRINT("IRP_MJ_CLOSE\n"); - - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_SUCCESS; -} diff --git a/reactos/drivers/input/i8042prt/i8042prt.c b/reactos/drivers/input/i8042prt/i8042prt.c deleted file mode 100644 index ebffde03621..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt.c +++ /dev/null @@ -1,524 +0,0 @@ -/* - * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/input/i8042prt/i8042prt.c - * PURPOSE: Driver entry function - * PROGRAMMERS: Copyright Victor Kirhenshtein (sauros@iname.com) - Copyright Jason Filby (jasonfilby@yahoo.com) - Copyright Martijn Vernooij (o112w8r02@sneakemail.com) - Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) - */ - -/* INCLUDES ******************************************************************/ - -#define INITGUID -#include "i8042prt.h" - -#define NDEBUG -#include - -/* FUNCTIONS *****************************************************************/ - -NTSTATUS NTAPI -i8042AddDevice( - IN PDRIVER_OBJECT DriverObject, - IN PDEVICE_OBJECT Pdo) -{ - PI8042_DRIVER_EXTENSION DriverExtension; - PFDO_DEVICE_EXTENSION DeviceExtension = NULL; - PDEVICE_OBJECT Fdo = NULL; - ULONG DeviceExtensionSize; - NTSTATUS Status; - - DPRINT("i8042AddDevice(%p %p)\n", DriverObject, Pdo); - - DriverExtension = (PI8042_DRIVER_EXTENSION)IoGetDriverObjectExtension(DriverObject, DriverObject); - - if (Pdo == NULL) - { - /* We're getting a NULL Pdo at the first call as - * we are a legacy driver. Ignore it */ - return STATUS_SUCCESS; - } - - /* Create new device object. As we don't know if the device would be a keyboard - * or a mouse, we have to allocate the biggest device extension. */ - DeviceExtensionSize = MAX(sizeof(I8042_KEYBOARD_EXTENSION), sizeof(I8042_MOUSE_EXTENSION)); - Status = IoCreateDevice( - DriverObject, - DeviceExtensionSize, - NULL, - Pdo->DeviceType, - FILE_DEVICE_SECURE_OPEN, - TRUE, - &Fdo); - if (!NT_SUCCESS(Status)) - { - DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status); - goto cleanup; - } - - DeviceExtension = (PFDO_DEVICE_EXTENSION)Fdo->DeviceExtension; - RtlZeroMemory(DeviceExtension, DeviceExtensionSize); - DeviceExtension->Type = Unknown; - DeviceExtension->Fdo = Fdo; - DeviceExtension->Pdo = Pdo; - DeviceExtension->PortDeviceExtension = &DriverExtension->Port; - Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice); - - Fdo->Flags &= ~DO_DEVICE_INITIALIZING; - return STATUS_SUCCESS; - -cleanup: - if (DeviceExtension && DeviceExtension->LowerDevice) - IoDetachDevice(DeviceExtension->LowerDevice); - if (Fdo) - IoDeleteDevice(Fdo); - return Status; -} - -VOID NTAPI -i8042SendHookWorkItem( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Context) -{ - PI8042_HOOK_WORKITEM WorkItemData; - PFDO_DEVICE_EXTENSION FdoDeviceExtension; - PPORT_DEVICE_EXTENSION PortDeviceExtension; - PDEVICE_OBJECT TopOfStack = NULL; - ULONG IoControlCode; - PVOID InputBuffer; - ULONG InputBufferLength; - IO_STATUS_BLOCK IoStatus; - KEVENT Event; - PIRP NewIrp; - NTSTATUS Status; - - DPRINT("i8042SendHookWorkItem(%p %p)\n", DeviceObject, Context); - - WorkItemData = (PI8042_HOOK_WORKITEM)Context; - FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - PortDeviceExtension = FdoDeviceExtension->PortDeviceExtension; - - switch (FdoDeviceExtension->Type) - { - case Keyboard: - { - PI8042_KEYBOARD_EXTENSION DeviceExtension; - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)FdoDeviceExtension; - IoControlCode = IOCTL_INTERNAL_I8042_HOOK_KEYBOARD; - InputBuffer = &DeviceExtension->KeyboardHook; - InputBufferLength = sizeof(INTERNAL_I8042_HOOK_KEYBOARD); - break; - } - case Mouse: - { - PI8042_MOUSE_EXTENSION DeviceExtension; - DeviceExtension = (PI8042_MOUSE_EXTENSION)FdoDeviceExtension; - IoControlCode = IOCTL_INTERNAL_I8042_HOOK_MOUSE; - InputBuffer = &DeviceExtension->MouseHook; - InputBufferLength = sizeof(INTERNAL_I8042_HOOK_MOUSE); - break; - } - default: - { - DPRINT1("Unknown FDO type %u\n", FdoDeviceExtension->Type); - ASSERT(FALSE); - WorkItemData->Irp->IoStatus.Status = STATUS_INTERNAL_ERROR; - goto cleanup; - } - } - - KeInitializeEvent(&Event, NotificationEvent, FALSE); - TopOfStack = IoGetAttachedDeviceReference(DeviceObject); - - NewIrp = IoBuildDeviceIoControlRequest( - IoControlCode, - TopOfStack, - InputBuffer, - InputBufferLength, - NULL, - 0, - TRUE, - &Event, - &IoStatus); - - if (!NewIrp) - { - DPRINT("IoBuildDeviceIoControlRequest() failed\n"); - WorkItemData->Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - - Status = IoCallDriver(TopOfStack, NewIrp); - if (Status == STATUS_PENDING) - { - KeWaitForSingleObject( - &Event, - Executive, - KernelMode, - FALSE, - NULL); - Status = IoStatus.Status; - } - if (!NT_SUCCESS(Status)) - { - DPRINT("IoCallDriver() failed with status 0x%08lx\n", Status); - goto cleanup; - } - - if (FdoDeviceExtension->Type == Keyboard) - { - PI8042_KEYBOARD_EXTENSION DeviceExtension; - - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)FdoDeviceExtension; - /* Call the hooked initialization if it exists */ - if (DeviceExtension->KeyboardHook.InitializationRoutine) - { - Status = DeviceExtension->KeyboardHook.InitializationRoutine( - DeviceExtension->KeyboardHook.Context, - PortDeviceExtension, - i8042SynchReadPort, - i8042SynchWritePortKbd, - FALSE); - if (!NT_SUCCESS(Status)) - { - DPRINT("KeyboardHook.InitializationRoutine() failed with status 0x%08lx\n", Status); - WorkItemData->Irp->IoStatus.Status = Status; - goto cleanup; - } - } - } -#if 0 - else - { - /* Mouse doesn't have this, but we need to send a - * reset to start the detection. - */ - KIRQL Irql; - - Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt); - - i8042Write(PortDeviceExtension, PortDeviceExtension->ControlPort, CTRL_WRITE_MOUSE); - i8042Write(PortDeviceExtension, PortDeviceExtension->DataPort, MOU_CMD_RESET); - - KeReleaseInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt, Irql); - } -#endif - - WorkItemData->Irp->IoStatus.Status = STATUS_SUCCESS; - -cleanup: - if (TopOfStack != NULL) - ObDereferenceObject(TopOfStack); - WorkItemData->Irp->IoStatus.Information = 0; - IoCompleteRequest(WorkItemData->Irp, IO_NO_INCREMENT); - - IoFreeWorkItem(WorkItemData->WorkItem); - ExFreePool(WorkItemData); -} - -static VOID NTAPI -i8042StartIo( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PFDO_DEVICE_EXTENSION DeviceExtension; - - DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - switch (DeviceExtension->Type) - { - case Keyboard: - i8042KbdStartIo(DeviceObject, Irp); - break; - default: - DPRINT1("Unknown FDO type %u\n", DeviceExtension->Type); - ASSERT(FALSE); - break; - } -} - -/* Write the current byte of the packet. Returns FALSE in case - * of problems. - */ -static BOOLEAN -i8042PacketWrite( - IN PPORT_DEVICE_EXTENSION DeviceExtension) -{ - UCHAR Port = DeviceExtension->PacketPort; - - if (Port) - { - if (!i8042Write(DeviceExtension, - DeviceExtension->ControlPort, - Port)) - { - /* something is really wrong! */ - DPRINT1("Failed to send packet byte!\n"); - return FALSE; - } - } - - return i8042Write(DeviceExtension, - DeviceExtension->DataPort, - DeviceExtension->Packet.Bytes[DeviceExtension->Packet.CurrentByte]); -} - -BOOLEAN -i8042PacketIsr( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN UCHAR Output) -{ - if (DeviceExtension->Packet.State == Idle) - return FALSE; - - switch (Output) - { - case KBD_RESEND: - DeviceExtension->PacketResends++; - if (DeviceExtension->PacketResends > DeviceExtension->Settings.ResendIterations) - { - DeviceExtension->Packet.State = Idle; - DeviceExtension->PacketComplete = TRUE; - DeviceExtension->PacketResult = STATUS_IO_TIMEOUT; - DeviceExtension->PacketResends = 0; - return TRUE; - } - DeviceExtension->Packet.CurrentByte--; - break; - - case KBD_NACK: - DeviceExtension->Packet.State = Idle; - DeviceExtension->PacketComplete = TRUE; - DeviceExtension->PacketResult = STATUS_UNEXPECTED_IO_ERROR; - DeviceExtension->PacketResends = 0; - return TRUE; - - default: - DeviceExtension->PacketResends = 0; - } - - if (DeviceExtension->Packet.CurrentByte >= DeviceExtension->Packet.ByteCount) - { - DeviceExtension->Packet.State = Idle; - DeviceExtension->PacketComplete = TRUE; - DeviceExtension->PacketResult = STATUS_SUCCESS; - return TRUE; - } - - if (!i8042PacketWrite(DeviceExtension)) - { - DeviceExtension->Packet.State = Idle; - DeviceExtension->PacketComplete = TRUE; - DeviceExtension->PacketResult = STATUS_IO_TIMEOUT; - return TRUE; - } - DeviceExtension->Packet.CurrentByte++; - - return TRUE; -} - -/* - * This function starts a packet. It must be called with the - * correct DIRQL. - */ -NTSTATUS -i8042StartPacket( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN PFDO_DEVICE_EXTENSION FdoDeviceExtension, - IN PUCHAR Bytes, - IN ULONG ByteCount, - IN PIRP Irp) -{ - KIRQL Irql; - NTSTATUS Status; - - Irql = KeAcquireInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt); - - if (DeviceExtension->Packet.State != Idle) - { - Status = STATUS_DEVICE_BUSY; - goto done; - } - - switch (FdoDeviceExtension->Type) - { - case Keyboard: DeviceExtension->PacketPort = 0; break; - case Mouse: DeviceExtension->PacketPort = CTRL_WRITE_MOUSE; break; - default: - DPRINT1("Unknown FDO type %u\n", FdoDeviceExtension->Type); - ASSERT(FALSE); - Status = STATUS_INTERNAL_ERROR; - goto done; - } - - DeviceExtension->Packet.Bytes = Bytes; - DeviceExtension->Packet.CurrentByte = 0; - DeviceExtension->Packet.ByteCount = ByteCount; - DeviceExtension->Packet.State = SendingBytes; - DeviceExtension->PacketResult = Status = STATUS_PENDING; - DeviceExtension->CurrentIrp = Irp; - DeviceExtension->CurrentIrpDevice = FdoDeviceExtension->Fdo; - - if (!i8042PacketWrite(DeviceExtension)) - { - Status = STATUS_IO_TIMEOUT; - DeviceExtension->Packet.State = Idle; - DeviceExtension->PacketResult = STATUS_ABANDONED; - goto done; - } - - DeviceExtension->Packet.CurrentByte++; - -done: - KeReleaseInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt, Irql); - - if (Status != STATUS_PENDING) - { - DeviceExtension->CurrentIrp = NULL; - DeviceExtension->CurrentIrpDevice = NULL; - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } - return Status; -} - -static NTSTATUS NTAPI -IrpStub( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - KEBUGCHECK(0); - return STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS NTAPI -i8042DeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PFDO_DEVICE_EXTENSION DeviceExtension; - NTSTATUS Status; - - DPRINT("i8042DeviceControl(%p %p)\n", DeviceObject, Irp); - DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - - switch (DeviceExtension->Type) - { - case Keyboard: - return i8042KbdDeviceControl(DeviceObject, Irp); - break; - default: - return IrpStub(DeviceObject, Irp); - } - - return Status; -} - -static NTSTATUS NTAPI -i8042InternalDeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PFDO_DEVICE_EXTENSION DeviceExtension; - ULONG ControlCode; - NTSTATUS Status; - - DPRINT("i8042InternalDeviceControl(%p %p)\n", DeviceObject, Irp); - DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - - switch (DeviceExtension->Type) - { - case Unknown: - { - ControlCode = IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode; - switch (ControlCode) - { - case IOCTL_INTERNAL_KEYBOARD_CONNECT: - Status = i8042KbdInternalDeviceControl(DeviceObject, Irp); - break; - case IOCTL_INTERNAL_MOUSE_CONNECT: - Status = i8042MouInternalDeviceControl(DeviceObject, Irp); - break; - default: - DPRINT1("Unknown IO control code 0x%lx\n", ControlCode); - ASSERT(FALSE); - Status = STATUS_INVALID_DEVICE_REQUEST; - break; - } - break; - } - case Keyboard: - Status = i8042KbdInternalDeviceControl(DeviceObject, Irp); - break; - case Mouse: - Status = i8042MouInternalDeviceControl(DeviceObject, Irp); - break; - default: - DPRINT1("Unknown FDO type %u\n", DeviceExtension->Type); - ASSERT(FALSE); - Status = STATUS_INTERNAL_ERROR; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - break; - } - - return Status; -} - -NTSTATUS NTAPI -DriverEntry( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath) -{ - PI8042_DRIVER_EXTENSION DriverExtension; - ULONG i; - NTSTATUS Status; - - Status = IoAllocateDriverObjectExtension( - DriverObject, - DriverObject, - sizeof(I8042_DRIVER_EXTENSION), - (PVOID*)&DriverExtension); - if (!NT_SUCCESS(Status)) - { - DPRINT("IoAllocateDriverObjectExtension() failed with status 0x%08lx\n", Status); - return Status; - } - RtlZeroMemory(DriverExtension, sizeof(I8042_DRIVER_EXTENSION)); - KeInitializeSpinLock(&DriverExtension->Port.SpinLock); - - Status = RtlDuplicateUnicodeString( - RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, - RegistryPath, - &DriverExtension->RegistryPath); - if (!NT_SUCCESS(Status)) - { - DPRINT("RtlDuplicateUnicodeString() failed with status 0x%08lx\n", Status); - return Status; - } - - Status = ReadRegistryEntries(RegistryPath, &DriverExtension->Port.Settings); - if (!NT_SUCCESS(Status)) - { - DPRINT("ReadRegistryEntries() failed with status 0x%08lx\n", Status); - return Status; - } - - DriverObject->DriverExtension->AddDevice = i8042AddDevice; - DriverObject->DriverStartIo = i8042StartIo; - - for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) - DriverObject->MajorFunction[i] = IrpStub; - - DriverObject->MajorFunction[IRP_MJ_CREATE] = i8042Create; - DriverObject->MajorFunction[IRP_MJ_CLEANUP] = i8042Cleanup; - DriverObject->MajorFunction[IRP_MJ_CLOSE] = i8042Close; - DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = i8042DeviceControl; - DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = i8042InternalDeviceControl; - DriverObject->MajorFunction[IRP_MJ_PNP] = i8042Pnp; - - if (IsFirstStageSetup()) - return i8042AddLegacyKeyboard(DriverObject, RegistryPath); - - return STATUS_SUCCESS; -} diff --git a/reactos/drivers/input/i8042prt/i8042prt.h b/reactos/drivers/input/i8042prt/i8042prt.h deleted file mode 100644 index 9df68e61f2b..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt.h +++ /dev/null @@ -1,488 +0,0 @@ -#ifndef _I8042PRT_H_ -#define _I8042PRT_H_ - -#include -#include -#include -#include -#include -#include - -/*----------------------------------------------------- - * Structures - * --------------------------------------------------*/ - -typedef enum -{ - dsStopped, - dsStarted, - dsPaused, - dsRemoved, - dsSurpriseRemoved -} DEVICE_STATE; - -typedef struct _I8042_SETTINGS -{ - /* Registry settings */ - ULONG KeyboardDataQueueSize; /* done */ - UNICODE_STRING KeyboardDeviceBaseName; - ULONG MouseDataQueueSize; /* done */ - ULONG MouseResolution; - ULONG MouseSynchIn100ns; - ULONG NumberOfButtons; - UNICODE_STRING PointerDeviceBaseName; - ULONG PollStatusIterations; /* done */ - ULONG OverrideKeyboardType; - ULONG OverrideKeyboardSubtype; - ULONG PollingIterations; /* done */ - ULONG PollingIterationsMaximum; - ULONG ResendIterations; /* done */ - ULONG SampleRate; - ULONG CrashOnCtrlScroll; /* done */ -} I8042_SETTINGS, *PI8042_SETTINGS; - -typedef enum _MOUSE_TIMEOUT_STATE -{ - NoChange, - TimeoutStart, - TimeoutCancel -} MOUSE_TIMEOUT_STATE, *PMOUSE_TIMEOUT_STATE; - -typedef struct _INTERRUPT_DATA -{ - PKINTERRUPT Object; - ULONG Vector; - KIRQL Dirql; - KINTERRUPT_MODE InterruptMode; - BOOLEAN ShareInterrupt; - KAFFINITY Affinity; -} INTERRUPT_DATA, *PINTERRUPT_DATA; - -#define WHEEL_DELTA 120 - -struct _I8042_KEYBOARD_EXTENSION; -typedef struct _I8042_KEYBOARD_EXTENSION *PI8042_KEYBOARD_EXTENSION; -struct _I8042_MOUSE_EXTENSION; -typedef struct _I8042_MOUSE_EXTENSION *PI8042_MOUSE_EXTENSION; - -/* PORT_DEVICE_EXTENSION.Flags */ -#define KEYBOARD_PRESENT 0x01 /* A keyboard is attached */ -#define MOUSE_PRESENT 0x02 /* A mouse is attached */ -#define KEYBOARD_CONNECTED 0x04 /* Keyboard received IOCTL_INTERNAL_KEYBOARD_CONNECT */ -#define MOUSE_CONNECTED 0x08 /* Mouse received IOCTL_INTERNAL_MOUSE_CONNECT */ -#define KEYBOARD_STARTED 0x04 /* Keyboard FDO received IRP_MN_START_DEVICE */ -#define MOUSE_STARTED 0x08 /* Mouse FDO received IRP_MN_START_DEVICE */ -#define KEYBOARD_INITIALIZED 0x10 /* Keyboard interrupt is connected */ -#define MOUSE_INITIALIZED 0x20 /* Mouse interrupt is connected */ - -typedef struct _PORT_DEVICE_EXTENSION -{ - PUCHAR DataPort; /* Usually 0x60 */ - PUCHAR ControlPort; /* Usually 0x64 */ - I8042_SETTINGS Settings; - ULONG Flags; - - PI8042_KEYBOARD_EXTENSION KeyboardExtension; - INTERRUPT_DATA KeyboardInterrupt; - PI8042_MOUSE_EXTENSION MouseExtension; - INTERRUPT_DATA MouseInterrupt; - PKINTERRUPT HighestDIRQLInterrupt; - KSPIN_LOCK SpinLock; - KIRQL HighestDirql; - - OUTPUT_PACKET Packet; - ULONG PacketResends; - BOOLEAN PacketComplete; - NTSTATUS PacketResult; - UCHAR PacketBuffer[16]; - UCHAR PacketPort; - - PIRP CurrentIrp; - PDEVICE_OBJECT CurrentIrpDevice; -} PORT_DEVICE_EXTENSION, *PPORT_DEVICE_EXTENSION; - -typedef struct _I8042_DRIVER_EXTENSION -{ - UNICODE_STRING RegistryPath; - - PORT_DEVICE_EXTENSION Port; -} I8042_DRIVER_EXTENSION, *PI8042_DRIVER_EXTENSION; - -typedef enum _I8042_DEVICE_TYPE -{ - Unknown, - Keyboard, - Mouse, - PhysicalDeviceObject -} I8042_DEVICE_TYPE, *PI8042_DEVICE_TYPE; - -typedef struct _FDO_DEVICE_EXTENSION -{ - I8042_DEVICE_TYPE Type; - // Associated device object (FDO) - PDEVICE_OBJECT Fdo; - // Associated device object (PDO) - PDEVICE_OBJECT Pdo; - // Lower device object - PDEVICE_OBJECT LowerDevice; - // Current state of the driver - DEVICE_STATE PnpState; - - PPORT_DEVICE_EXTENSION PortDeviceExtension; -} FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION; - -typedef struct _I8042_KEYBOARD_EXTENSION -{ - FDO_DEVICE_EXTENSION Common; - CONNECT_DATA KeyboardData; - INTERNAL_I8042_HOOK_KEYBOARD KeyboardHook; - KDPC DpcKeyboard; - - KEYBOARD_INDICATOR_PARAMETERS KeyboardIndicators; - - KEYBOARD_SCAN_STATE KeyboardScanState; - BOOLEAN KeyComplete; - PKEYBOARD_INPUT_DATA KeyboardBuffer; - ULONG KeysInBuffer; - - /* Power keys items */ - ULONG ReportedCaps; - ULONG NewCaps; - ULONG LastPowerKey; - UNICODE_STRING PowerInterfaceName; - PIO_WORKITEM PowerWorkItem; - PIRP PowerIrp; - - /* Debug items */ - ULONG ComboPosition; - PIO_WORKITEM DebugWorkItem; -#ifdef __REACTOS__ - ULONG DebugKey; - BOOLEAN TabPressed; -#endif -} I8042_KEYBOARD_EXTENSION; - -typedef enum _I8042_MOUSE_TYPE -{ - GenericPS2, - Intellimouse, - IntellimouseExplorer, - Ps2pp -} I8042_MOUSE_TYPE, *PI8042_MOUSE_TYPE; - -typedef struct _I8042_MOUSE_EXTENSION -{ - FDO_DEVICE_EXTENSION Common; - CONNECT_DATA MouseData; - INTERNAL_I8042_HOOK_MOUSE MouseHook; - KDPC DpcMouse; - - MOUSE_ATTRIBUTES MouseAttributes; - - MOUSE_STATE MouseState; - BOOLEAN MouseComplete; - MOUSE_RESET_SUBSTATE MouseResetState; - PMOUSE_INPUT_DATA MouseBuffer; - ULONG MouseInBuffer; - USHORT MouseButtonState; - ULARGE_INTEGER MousePacketStartTime; - - KTIMER TimerMouseTimeout; - KDPC DpcMouseTimeout; - MOUSE_TIMEOUT_STATE MouseTimeoutState; - BOOLEAN MouseTimeoutActive; - - UCHAR MouseLogiBuffer[3]; - I8042_MOUSE_TYPE MouseType; -} I8042_MOUSE_EXTENSION; - -typedef struct _I8042_HOOK_WORKITEM -{ - PIO_WORKITEM WorkItem; - PIRP Irp; -} I8042_HOOK_WORKITEM, *PI8042_HOOK_WORKITEM; - -/*----------------------------------------------------- - * Some defines - * --------------------------------------------------*/ - -#define MAX(a, b) ((a) >= (b) ? (a) : (b)) - -#define KEYBOARD_POWER_CODE 0x5E -#define KEYBOARD_SLEEP_CODE 0x5F -#define KEYBOARD_WAKE_CODE 0x63 - -/*----------------------------------------------------- - * Controller commands - * --------------------------------------------------*/ - -#define KBD_READ_MODE 0x20 -#define KBD_WRITE_MODE 0x60 -#define KBD_LINE_TEST 0xAB -#define MOUSE_LINE_TEST 0xA9 -#define CTRL_SELF_TEST 0xAA -#define CTRL_WRITE_MOUSE 0xD4 - -/*----------------------------------------------------- - * Keyboard commands - * --------------------------------------------------*/ - -#define KBD_CMD_SET_LEDS 0xED -#define KBD_CMD_GET_ID 0xF2 - -/*----------------------------------------------------- - * Keyboard responses - * --------------------------------------------------*/ - -#define KBD_ACK 0xFA -#define KBD_NACK 0xFC -#define KBD_RESEND 0xFE - -/*----------------------------------------------------- - * Controller status register bits - * --------------------------------------------------*/ - -#define KBD_OBF 0x01 -#define KBD_IBF 0x02 -#define MOU_OBF 0x20 -#define KBD_PERR 0x80 - -/*----------------------------------------------------- - * Controller command byte bits - * --------------------------------------------------*/ - -#define CCB_KBD_INT_ENAB 0x01 -#define CCB_MOUSE_INT_ENAB 0x02 -#define CCB_SYSTEM_FLAG 0x04 -#define CCB_KBD_DISAB 0x10 -#define CCB_MOUSE_DISAB 0x20 -#define CCB_TRANSLATE 0x40 - -/*----------------------------------------------------- - * LED bits - * --------------------------------------------------*/ - -#define KBD_LED_SCROLL 0x01 -#define KBD_LED_NUM 0x02 -#define KBD_LED_CAPS 0x04 - -/*----------------------------------------------------- - * Mouse commands - * --------------------------------------------------*/ - -#define MOU_CMD_GET_ID 0xF2 -#define MOU_CMD_RESET 0xFF - -/*----------------------------------------------------- - * Mouse responses - * --------------------------------------------------*/ - -#define MOUSE_ACK 0xFA -#define MOUSE_ERROR 0xFC -#define MOUSE_NACK 0xFE - -/*----------------------------------------------------- - * Prototypes - * --------------------------------------------------*/ - -/* createclose.c */ - -VOID NTAPI -i8042SendHookWorkItem( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Context); - -NTSTATUS NTAPI -i8042Create( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp); - -NTSTATUS NTAPI -i8042Cleanup( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp); - -NTSTATUS NTAPI -i8042Close( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp); - -/* keyboard.c */ - -NTSTATUS NTAPI -i8042SynchWritePortKbd( - IN PVOID Context, - IN UCHAR Value, - IN BOOLEAN WaitForAck); - -BOOLEAN -i8042KbdStartIo( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp); - -NTSTATUS -i8042KbdDeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp); - -NTSTATUS -i8042KbdInternalDeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp); - -BOOLEAN NTAPI -i8042KbdInterruptService( - IN PKINTERRUPT Interrupt, - PVOID Context); - -/* i8042prt.c */ - -NTSTATUS NTAPI -i8042AddDevice( - IN PDRIVER_OBJECT DriverObject, - IN PDEVICE_OBJECT Pdo); - -BOOLEAN -i8042PacketIsr( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN UCHAR Output); - -NTSTATUS -i8042StartPacket( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN PFDO_DEVICE_EXTENSION FdoDeviceExtension, - IN PUCHAR Bytes, - IN ULONG ByteCount, - IN PIRP Irp); - -/* misc.c */ - -NTSTATUS NTAPI -ForwardIrpAndForget( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp); - -NTSTATUS -ForwardIrpAndWait( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp); - -/* mouse.c */ - -VOID -i8042MouHandle( - IN PI8042_MOUSE_EXTENSION DeviceExtension, - IN UCHAR Output); - -VOID -i8042MouHandleButtons( - IN PI8042_MOUSE_EXTENSION DeviceExtension, - IN USHORT Mask); - -NTSTATUS -i8042MouInitialize( - IN PI8042_MOUSE_EXTENSION DeviceExtension); - -NTSTATUS -i8042MouInternalDeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp); - -BOOLEAN NTAPI -i8042MouInterruptService( - IN PKINTERRUPT Interrupt, - PVOID Context); - -VOID NTAPI -i8042MouQueuePacket( - IN PVOID Context); - -/* pnp.c */ - -BOOLEAN -i8042ChangeMode( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN UCHAR FlagsToDisable, - IN UCHAR FlagsToEnable); - -NTSTATUS NTAPI -i8042Pnp( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp); - -/* ps2pp.c */ -VOID -i8042MouHandlePs2pp( - IN PI8042_MOUSE_EXTENSION DeviceExtension, - IN UCHAR Input); - -/* readwrite.c */ - -VOID -i8042Flush( - IN PPORT_DEVICE_EXTENSION DeviceExtension); - -VOID -i8042IsrWritePort( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN UCHAR Value, - IN UCHAR SelectCmd OPTIONAL); - -NTSTATUS -i8042ReadData( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN UCHAR StatusFlags, - OUT PUCHAR Data); -#define i8042ReadKeyboardData(DeviceExtension, Data) \ - i8042ReadData(DeviceExtension, KBD_OBF, Data) -#define i8042ReadMouseData(DeviceExtension, Data) \ - i8042ReadData(DeviceExtension, MOU_OBF, Data) - -NTSTATUS -i8042ReadDataWait( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - OUT PUCHAR Data); - -NTSTATUS -i8042ReadStatus( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - OUT PUCHAR Status); - -NTSTATUS NTAPI -i8042SynchReadPort( - IN PVOID Context, - IN PUCHAR Value, - IN BOOLEAN WaitForAck); - -NTSTATUS NTAPI -i8042SynchWritePort( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN UCHAR Port, - IN UCHAR Value, - IN BOOLEAN WaitForAck); - -BOOLEAN -i8042Write( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN PUCHAR addr, - IN UCHAR data); - -/* registry.c */ - -NTSTATUS -ReadRegistryEntries( - IN PUNICODE_STRING RegistryPath, - OUT PI8042_SETTINGS Settings); - -/* setup.c */ - -BOOLEAN -IsFirstStageSetup( - VOID); - -NTSTATUS -i8042AddLegacyKeyboard( - IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath); - -#endif // _I8042PRT_H_ diff --git a/reactos/drivers/input/i8042prt/i8042prt.rbuild b/reactos/drivers/input/i8042prt/i8042prt.rbuild deleted file mode 100644 index 1c4a264012b..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt.rbuild +++ /dev/null @@ -1,18 +0,0 @@ - - - - - ntoskrnl - hal - createclose.c - i8042prt.c - keyboard.c - misc.c - mouse.c - pnp.c - ps2pp.c - readwrite.c - registry.c - setup.c - i8042prt.rc - diff --git a/reactos/drivers/input/i8042prt/i8042prt.rc b/reactos/drivers/input/i8042prt/i8042prt.rc deleted file mode 100644 index eaed77a9427..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt.rc +++ /dev/null @@ -1,5 +0,0 @@ -#define REACTOS_VERSION_DLL -#define REACTOS_STR_FILE_DESCRIPTION "i8042 Port Device Driver\0" -#define REACTOS_STR_INTERNAL_NAME "i8042prt\0" -#define REACTOS_STR_ORIGINAL_FILENAME "i8042prt.sys\0" -#include diff --git a/reactos/drivers/input/i8042prt/i8042prt/README.txt b/reactos/drivers/input/i8042prt/i8042prt/README.txt deleted file mode 100644 index a8f09ff5f59..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt/README.txt +++ /dev/null @@ -1,83 +0,0 @@ -Intel 8042 port driver - -This directory contains a driver for Intels 8042 and compatible controllers. -It is based on the information in the DDK documentation on MSDN. It is intended -to be compatible with keyboard and mouse drivers written for Windows. It is -not based on the i8042prt example driver that's included with the DDK. - -The directory contains these files: - -i8042prt.c: Main controller functionality, things shared by keyboards and mice - -keyboard.c: keyboard functionality: detection, interrupt handling - -mouse.c: mouse functionality: detection, interrupt handling, packet parsing for - standard ps2 and microsoft mice - -ps2pp.c: logitech ps2++ mouse packat parsing (basic) - -registry.c: registry reading - -makefile, i8042prt.rc: obvious - - -Some parts of the driver make little sense. This is because it implements -an interface that has evolved over a long time, and because the ps/2 -'standard' is really awful. - -Things to add: - -- Better AT (before ps2) keyboard handling -- SiS keyboard controller detection -- Mouse identification -- General robustness: reset mouse if things go wrong -- Handling all registry settings -- ACPI -- Make it work more like a WDM driver - -Things not to add: - -- Other mouse protocols, touchpad handling etc. : Write a filter driver instead -- Keyboard lights handling: Should be in win32k -- Keyboard scancode translation: Should be in win32k - -Things requiring work elsewhere: - -- Debugger interface (TAB + key): - Currently this interface wants translated keycodes, which are not - implemented by this driver. As it just uses a giant switch with - hardcoded cases, this should not be hard to fix. - -- Class drivers: - I wrote a keyboard class driver, which does keycode translations. It - should not do this, win32k should get untranslated keycodes and do - the translation itself. - - I changed the mouse class driver (mouclass) to work like Microsofts mouclass. - Unfortunately this means that the original psaux driver doesn't work - anymore (the same holds for the other mice drivers, probably). - - The keyboard class driver passes on ioctls from win32k, so it can change - keyboard settings. As far as I could see, the mouse class driver does not - do this yet. - - The class drivers should be able to handle reads for more than one packet - at a time (kbdclass should, mouclass does not). Win32k should send such - requests. - - -I put a lot of work in making it work like Microsofts driver does, so third party drivers can work. Please keep it that way. - - -Links: - -Here's a link describing most of the registry settings: - -http://www.microsoft.com/resources/documentation/Windows/2000/server/reskit/en-us/Default.asp?url=/resources/documentation/Windows/2000/server/reskit/en-us/regentry/31493.asp - -PS/2 protocol documentation: - -http://www.win.tue.nl/~aeb/linux/kbd/scancodes.html - -It also contains a link to a description of the ps2++ protocol, which has -since disappeared. Archive.org still has it. diff --git a/reactos/drivers/input/i8042prt/i8042prt/i8042prt.c b/reactos/drivers/input/i8042prt/i8042prt/i8042prt.c deleted file mode 100644 index 04625caa859..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt/i8042prt.c +++ /dev/null @@ -1,927 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: drivers/input/i8042prt/i8042prt.c - * PURPOSE: i8042 (ps/2 keyboard-mouse controller) driver - * PROGRAMMER: Victor Kirhenshtein (sauros@iname.com) - * Jason Filby (jasonfilby@yahoo.com) - * Tinus - */ - -/* INCLUDES ****************************************************************/ - -#define NDEBUG -#include - -#include "i8042prt.h" - -/* GLOBALS *******************************************************************/ - -/* - * Driver data - */ -#define I8042_TIMEOUT 500000 - -#define I8042_MAX_COMMAND_LENGTH 16 -#define I8042_MAX_UPWARDS_STACK 5 - -UNICODE_STRING I8042RegistryPath; - -/* FUNCTIONS *****************************************************************/ - -/* - * FUNCTION: Write data to a port, waiting first for it to become ready - */ -BOOLEAN I8042Write(PDEVICE_EXTENSION DevExt, PUCHAR addr, UCHAR data) -{ - ULONG ResendIterations = DevExt->Settings.PollingIterations; - - while ((KBD_IBF & READ_PORT_UCHAR(I8042_CTRL_PORT)) && - (ResendIterations--)) - { - KeStallExecutionProcessor(50); - } - - if (ResendIterations) { - WRITE_PORT_UCHAR(addr,data); - DPRINT("Sent %x to %x\n", data, addr); - return TRUE; - } - return FALSE; -} - -#if 0 /* function is not needed */ -/* - * FUNCTION: Write data to a port, without waiting first - */ -static BOOLEAN I8042WriteNoWait(PDEVICE_EXTENSION DevExt, int addr, UCHAR data) -{ - WRITE_PORT_UCHAR((PUCHAR)addr,data); - DPRINT("Sent %x to %x\n", data, addr); - return TRUE; -} -#endif - -/* - * FUNCTION: Read data from port 0x60 - */ -NTSTATUS I8042ReadData(UCHAR *Data) -{ - UCHAR Status; - Status=READ_PORT_UCHAR(I8042_CTRL_PORT); - - // If data is available - if ((Status & KBD_OBF)) { - Data[0]=READ_PORT_UCHAR((PUCHAR)I8042_DATA_PORT); - DPRINT("Read: %x (status: %x)\n", Data[0], Status); - - // If the data is valid (not timeout, not parity error) - if (0 == (Status & KBD_PERR)) - return STATUS_SUCCESS; - } - return STATUS_UNSUCCESSFUL; -} - -NTSTATUS I8042ReadStatus(UCHAR *Status) -{ - Status[0]=READ_PORT_UCHAR(I8042_CTRL_PORT); - return STATUS_SUCCESS; -} - -/* - * FUNCTION: Read data from port 0x60 - */ -NTSTATUS I8042ReadDataWait(PDEVICE_EXTENSION DevExt, UCHAR *Data) -{ - ULONG Counter = DevExt->Settings.PollingIterations; - NTSTATUS Status; - - while (Counter--) { - Status = I8042ReadData(Data); - - if (STATUS_SUCCESS == Status) - return Status; - - KeStallExecutionProcessor(50); - } - // Timed out - return STATUS_IO_TIMEOUT; -} - -VOID I8042Flush() -{ - UCHAR Ignore; - - while (STATUS_SUCCESS == I8042ReadData(&Ignore)) { - DPRINT("Data flushed\n"); /* drop */ - } -} - -VOID STDCALL I8042IsrWritePort(PDEVICE_EXTENSION DevExt, - UCHAR Value, - UCHAR SelectCmd) -{ - if (SelectCmd) - if (!I8042Write(DevExt, I8042_CTRL_PORT, SelectCmd)) - return; - - I8042Write(DevExt, I8042_DATA_PORT, Value); -} - -/* - * These functions are callbacks for filter driver custom - * initialization routines. - */ -NTSTATUS STDCALL I8042SynchWritePort(PDEVICE_EXTENSION DevExt, - UCHAR Port, - UCHAR Value, - BOOLEAN WaitForAck) -{ - NTSTATUS Status; - UCHAR Ack; - ULONG ResendIterations = DevExt->Settings.ResendIterations + 1; - - do { - if (Port) - if (!I8042Write(DevExt, I8042_DATA_PORT, Port)) - { - DPRINT1("Failed to write Port\n"); - return STATUS_IO_TIMEOUT; - } - - if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) - { - DPRINT1("Failed to write Value\n"); - return STATUS_IO_TIMEOUT; - } - - if (WaitForAck) { - Status = I8042ReadDataWait(DevExt, &Ack); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to read Ack\n"); - return Status; - } - if (Ack == KBD_ACK) - return STATUS_SUCCESS; - if (Ack != KBD_RESEND) - { - DPRINT1("Unexpected Ack 0x%x\n", Ack); - return STATUS_UNEXPECTED_IO_ERROR; - } - } else { - return STATUS_SUCCESS; - } - DPRINT("Reiterating\n"); - ResendIterations--; - } while (ResendIterations); - return STATUS_IO_TIMEOUT; -} - -/* - * This one reads a value from the port; You don't have to specify - * which one, it'll always be from the one you talked to, so one function - * is enough this time. Note how MSDN specifies the - * WaitForAck parameter to be ignored. - */ -static NTSTATUS STDCALL I8042SynchReadPort(PVOID Context, - PUCHAR Value, - BOOLEAN WaitForAck) -{ - PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION)Context; - - return I8042ReadDataWait(DevExt, Value); -} - -/* Write the current byte of the packet. Returns FALSE in case - * of problems. - */ -static BOOLEAN STDCALL I8042PacketWrite(PDEVICE_EXTENSION DevExt) -{ - UCHAR Port = DevExt->PacketPort; - - if (Port) { - if (!I8042Write(DevExt, - I8042_CTRL_PORT, - Port)) { - /* something is really wrong! */ - DPRINT1("Failed to send packet byte!\n"); - return FALSE; - } - } - - return I8042Write(DevExt, - I8042_DATA_PORT, - DevExt->Packet.Bytes[DevExt->Packet.CurrentByte]); -} - - -/* - * This function starts a packet. It must be called with the - * correct DIRQL. - */ -NTSTATUS STDCALL I8042StartPacket(PDEVICE_EXTENSION DevExt, - PDEVICE_OBJECT Device, - PUCHAR Bytes, - ULONG ByteCount, - PIRP Irp) -{ - KIRQL Irql; - NTSTATUS Status; - PFDO_DEVICE_EXTENSION FdoDevExt = Device->DeviceExtension; - - Irql = KeAcquireInterruptSpinLock(DevExt->HighestDIRQLInterrupt); - - DevExt->CurrentIrp = Irp; - DevExt->CurrentIrpDevice = Device; - - if (Idle != DevExt->Packet.State) { - Status = STATUS_DEVICE_BUSY; - goto startpacketdone; - } - - DevExt->Packet.Bytes = Bytes; - DevExt->Packet.CurrentByte = 0; - DevExt->Packet.ByteCount = ByteCount; - DevExt->Packet.State = SendingBytes; - DevExt->PacketResult = Status = STATUS_PENDING; - - if (Mouse == FdoDevExt->Type) - DevExt->PacketPort = 0xD4; - else - DevExt->PacketPort = 0; - - if (!I8042PacketWrite(DevExt)) { - Status = STATUS_IO_TIMEOUT; - DevExt->Packet.State = Idle; - DevExt->PacketResult = STATUS_ABANDONED; - goto startpacketdone; - } - - DevExt->Packet.CurrentByte++; - -startpacketdone: - KeReleaseInterruptSpinLock(DevExt->HighestDIRQLInterrupt, Irql); - - if (STATUS_PENDING != Status) { - DevExt->CurrentIrp = NULL; - DevExt->CurrentIrpDevice = NULL; - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } - return Status; -} - -BOOLEAN STDCALL I8042PacketIsr(PDEVICE_EXTENSION DevExt, - UCHAR Output) -{ - if (Idle == DevExt->Packet.State) - return FALSE; - - switch (Output) { - case KBD_RESEND: - DevExt->PacketResends++; - if (DevExt->PacketResends > DevExt->Settings.ResendIterations) { - DevExt->Packet.State = Idle; - DevExt->PacketComplete = TRUE; - DevExt->PacketResult = STATUS_IO_TIMEOUT; - DevExt->PacketResends = 0; - return TRUE; - } - DevExt->Packet.CurrentByte--; - break; - - case KBD_NACK: - DevExt->Packet.State = Idle; - DevExt->PacketComplete = TRUE; - DevExt->PacketResult = STATUS_UNEXPECTED_IO_ERROR; - DevExt->PacketResends = 0; - return TRUE; - - default: - DevExt->PacketResends = 0; - } - - if (DevExt->Packet.CurrentByte >= DevExt->Packet.ByteCount) { - DevExt->Packet.State = Idle; - DevExt->PacketComplete = TRUE; - DevExt->PacketResult = STATUS_SUCCESS; - return TRUE; - } - - if (!I8042PacketWrite(DevExt)) { - DevExt->Packet.State = Idle; - DevExt->PacketComplete = TRUE; - DevExt->PacketResult = STATUS_IO_TIMEOUT; - return TRUE; - } - DevExt->Packet.CurrentByte++; - - return TRUE; -} - -VOID I8042PacketDpc(PDEVICE_EXTENSION DevExt) -{ - BOOLEAN FinishIrp = FALSE; - NTSTATUS Result = STATUS_INTERNAL_ERROR; /* Shouldn't happen */ - KIRQL Irql; - - /* If the interrupt happens before this is setup, the key - * was already in the buffer. Too bad! */ - if (!DevExt->HighestDIRQLInterrupt) - return; - - Irql = KeAcquireInterruptSpinLock(DevExt->HighestDIRQLInterrupt); - - if (Idle == DevExt->Packet.State && - DevExt->PacketComplete) { - FinishIrp = TRUE; - Result = DevExt->PacketResult; - DevExt->PacketComplete = FALSE; - } - - KeReleaseInterruptSpinLock(DevExt->HighestDIRQLInterrupt, - Irql); - - if (!FinishIrp) - return; - - if (DevExt->CurrentIrp) { - DevExt->CurrentIrp->IoStatus.Status = Result; - IoCompleteRequest(DevExt->CurrentIrp, IO_NO_INCREMENT); - IoStartNextPacket(DevExt->CurrentIrpDevice, FALSE); - DevExt->CurrentIrp = NULL; - DevExt->CurrentIrpDevice = NULL; - } -} - -VOID STDCALL I8042SendHookWorkItem(PDEVICE_OBJECT DeviceObject, - PVOID Context) -{ - KEVENT Event; - IO_STATUS_BLOCK IoStatus; - NTSTATUS Status; - PDEVICE_EXTENSION DevExt; - PFDO_DEVICE_EXTENSION FdoDevExt; - PIRP NewIrp; - PI8042_HOOK_WORKITEM WorkItemData = (PI8042_HOOK_WORKITEM)Context; - - ULONG IoControlCode; - PVOID InputBuffer; - ULONG InputBufferLength; - BOOLEAN IsKbd; - - DPRINT("HookWorkItem\n"); - - FdoDevExt = (PFDO_DEVICE_EXTENSION) - DeviceObject->DeviceExtension; - - DevExt = FdoDevExt->PortDevExt; - - if (WorkItemData->Target == DevExt->KeyboardData.ClassDeviceObject) { - IoControlCode = IOCTL_INTERNAL_I8042_HOOK_KEYBOARD; - InputBuffer = &DevExt->KeyboardHook; - InputBufferLength = sizeof(INTERNAL_I8042_HOOK_KEYBOARD); - IsKbd = TRUE; - DPRINT ("is for keyboard.\n"); - } else if (WorkItemData->Target == DevExt->MouseData.ClassDeviceObject){ - IoControlCode = IOCTL_INTERNAL_I8042_HOOK_MOUSE; - InputBuffer = &DevExt->MouseHook; - InputBufferLength = sizeof(INTERNAL_I8042_HOOK_MOUSE); - IsKbd = FALSE; - DPRINT ("is for mouse.\n"); - } else { - DPRINT1("I8042SendHookWorkItem: Can't find DeviceObject\n"); - WorkItemData->Irp->IoStatus.Status = STATUS_INTERNAL_ERROR; - goto hookworkitemdone; - } - - KeInitializeEvent(&Event, NotificationEvent, FALSE); - - NewIrp = IoBuildDeviceIoControlRequest( - IoControlCode, - WorkItemData->Target, - InputBuffer, - InputBufferLength, - NULL, - 0, - TRUE, - &Event, - &IoStatus); - - if (!NewIrp) { - DPRINT("IOCTL_INTERNAL_(device)_CONNECT: " - "Can't allocate IRP\n"); - WorkItemData->Irp->IoStatus.Status = - STATUS_INSUFFICIENT_RESOURCES; - goto hookworkitemdone; - } - -#if 0 - Status = IoCallDriver( - WorkItemData->Target, - NewIrp); - - if (STATUS_PENDING == Status) - KeWaitForSingleObject(&Event, - Executive, - KernelMode, - FALSE, - NULL); -#endif - - if (IsKbd) { - /* Call the hooked initialization if it exists */ - if (DevExt->KeyboardHook.InitializationRoutine) { - Status = DevExt->KeyboardHook.InitializationRoutine( - DevExt->KeyboardHook.Context, - DevExt, - I8042SynchReadPort, - I8042SynchWritePortKbd, - FALSE); - if (!NT_SUCCESS(Status)) { - WorkItemData->Irp->IoStatus.Status = Status; - goto hookworkitemdone; - } - } - /* TODO: Now would be the right time to enable the interrupt */ - - DevExt->KeyboardClaimed = TRUE; - } else { - /* Mouse doesn't have this, but we need to send a - * reset to start the detection. - */ - KIRQL Irql; - - Irql = KeAcquireInterruptSpinLock( - DevExt->HighestDIRQLInterrupt); - - I8042Write(DevExt, I8042_CTRL_PORT, 0xD4); - I8042Write(DevExt, I8042_DATA_PORT, 0xFF); - - KeReleaseInterruptSpinLock(DevExt->HighestDIRQLInterrupt, Irql); - } - - WorkItemData->Irp->IoStatus.Status = STATUS_SUCCESS; - -hookworkitemdone: - WorkItemData->Irp->IoStatus.Information = 0; - IoCompleteRequest(WorkItemData->Irp, IO_NO_INCREMENT); - - IoFreeWorkItem(WorkItemData->WorkItem); - ExFreePool(WorkItemData); - DPRINT("HookWorkItem done\n"); -} - -static VOID STDCALL I8042StartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - if (!I8042StartIoKbd(DeviceObject, Irp)) { - DPRINT1("Unhandled StartIo!\n"); - } -} - -static NTSTATUS STDCALL I8042InternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST; - PFDO_DEVICE_EXTENSION FdoDevExt = DeviceObject->DeviceExtension; - - DPRINT("InternalDeviceControl\n"); - - switch (FdoDevExt->Type) { - case Keyboard: - Status = I8042InternalDeviceControlKbd(DeviceObject, Irp); - break; - case Mouse: - Status = I8042InternalDeviceControlMouse(DeviceObject, Irp); - break; - } - - if (Status == STATUS_INVALID_DEVICE_REQUEST) { - DPRINT1("Invalid internal device request!\n"); - } - - if (Status != STATUS_PENDING) - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return Status; -} - -static NTSTATUS STDCALL I8042CreateDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - NTSTATUS Status; - - DPRINT ("I8042CreateDispatch\n"); - - Status = STATUS_SUCCESS; - - Irp->IoStatus.Status = Status; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return Status; -} - -static NTSTATUS STDCALL I8042BasicDetect(PDEVICE_EXTENSION DevExt) -{ - NTSTATUS Status; - UCHAR Value = 0; - ULONG Counter; - - DevExt->MouseExists = FALSE; - DevExt->KeyboardExists = FALSE; - - I8042Flush(); - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_SELF_TEST)) { - DPRINT1("Writing KBD_SELF_TEST command failed\n"); - return STATUS_IO_TIMEOUT; - } - - // Wait longer? - Counter = 10; - do { - Status = I8042ReadDataWait(DevExt, &Value); - } while ((Counter--) && (STATUS_IO_TIMEOUT == Status)); - - if (!NT_SUCCESS(Status)) { - DPRINT1("Failed to read KBD_SELF_TEST response, status 0x%x\n", - Status); - return Status; - } - - if (Value != 0x55) { - DPRINT1("Got %x instead of 55\n", Value); - return STATUS_IO_DEVICE_ERROR; - } - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_READ_MODE)) { - DPRINT1("Can't read i8042 mode\n"); - return FALSE; - } - - Status = I8042ReadDataWait(DevExt, &Value); - if (!NT_SUCCESS(Status)) { - DPRINT1("No response after read i8042 mode\n"); - return FALSE; - } - - Value |= CCB_KBD_DISAB | CCB_MOUSE_DISAB; /* disable keyboard/mouse */ - Value &= ~(CCB_KBD_INT_ENAB | CCB_MOUSE_INT_ENAB); - /* don't enable keyboard and mouse interrupts */ - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_WRITE_MODE)) { - DPRINT1("Can't set i8042 mode\n"); - return FALSE; - } - - if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) { - DPRINT1("Can't send i8042 mode\n"); - return FALSE; - } - - /* - * We used to send a KBD_LINE_TEST command here, but on at least HP - * Pavilion notebooks the response to that command was incorrect. - * So now we just assume that a keyboard is attached. - */ - DevExt->KeyboardExists = TRUE; - - if (I8042Write(DevExt, I8042_CTRL_PORT, MOUSE_LINE_TEST)) - { - Status = I8042ReadDataWait(DevExt, &Value); - if (NT_SUCCESS(Status) && Value == 0) - DevExt->MouseExists = TRUE; - } - - return STATUS_SUCCESS; -} - -static NTSTATUS STDCALL I8042Initialize(PDEVICE_EXTENSION DevExt) -{ - NTSTATUS Status; - - Status = I8042BasicDetect(DevExt); - if (!NT_SUCCESS(Status)) { - DPRINT1("Basic keyboard detection failed: %x\n", Status); - return Status; - } - - if (DevExt->MouseExists) { - DPRINT("Aux port detected\n"); - DevExt->MouseExists = I8042DetectMouse(DevExt); - } - - if (!DevExt->KeyboardExists) { - DPRINT("Keyboard port not detected\n"); - if (DevExt->Settings.Headless) - /* Act as if it exists regardless */ - DevExt->KeyboardExists = TRUE; - } else { - DPRINT("Keyboard port detected\n"); - DevExt->KeyboardExists = I8042DetectKeyboard(DevExt); - } - - if (DevExt->KeyboardExists) { - DPRINT("Keyboard detected\n"); - I8042KeyboardEnable(DevExt); - I8042KeyboardEnableInterrupt(DevExt); - } - - if (DevExt->MouseExists) { - DPRINT("Mouse detected\n"); - I8042MouseEnable(DevExt); - } - - return STATUS_SUCCESS; -} - -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)) - { - DPRINT("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)) - { - DPRINT("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)) - { - DPRINT("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; -} - -static NTSTATUS STDCALL I8042AddDevice(PDRIVER_OBJECT DriverObject, - PDEVICE_OBJECT Pdo) -{ - UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardPort8042"); - UNICODE_STRING MouseName = RTL_CONSTANT_STRING(L"\\Device\\PointerPort8042"); - ULONG MappedIrqKeyboard = 0, MappedIrqMouse = 0; - KIRQL DirqlKeyboard = 0; - KIRQL DirqlMouse = 0; - KIRQL DirqlMax; - KAFFINITY Affinity; - NTSTATUS Status; - PDEVICE_EXTENSION DevExt; - PFDO_DEVICE_EXTENSION FdoDevExt; - PDEVICE_OBJECT Fdo; - - DPRINT("I8042AddDevice\n"); - - if (Pdo != NULL) - { - /* Device detected by pnpmgr. Ignore it, as we already have - * detected the keyboard and mouse at first call */ - return STATUS_UNSUCCESSFUL; - } - - Status = IoCreateDevice(DriverObject, - sizeof(DEVICE_EXTENSION), - NULL, - FILE_DEVICE_8042_PORT, - FILE_DEVICE_SECURE_OPEN, - TRUE, - &Fdo); - - if (!NT_SUCCESS(Status)) - return Status; - - DevExt = Fdo->DeviceExtension; - - RtlZeroMemory(DevExt, sizeof(DEVICE_EXTENSION)); - - I8042ReadRegistry(DriverObject, DevExt); - - KeInitializeSpinLock(&DevExt->SpinLock); - InitializeListHead(&DevExt->BusDevices); - - KeInitializeDpc(&DevExt->DpcKbd, - I8042DpcRoutineKbd, - DevExt); - - KeInitializeDpc(&DevExt->DpcMouse, - I8042DpcRoutineMouse, - DevExt); - - KeInitializeDpc(&DevExt->DpcMouseTimeout, - I8042DpcRoutineMouseTimeout, - DevExt); - - KeInitializeTimer(&DevExt->TimerMouseTimeout); - - Status = I8042Initialize(DevExt); - Fdo->Flags &= ~DO_DEVICE_INITIALIZING; - if (!NT_SUCCESS(STATUS_SUCCESS)) { - DPRINT1("Initialization failure: %x\n", Status); - return Status; - } - - if (DevExt->KeyboardExists) { - MappedIrqKeyboard = HalGetInterruptVector(Internal, - 0, - 0, - KEYBOARD_IRQ, - &DirqlKeyboard, - &Affinity); - - Status = IoCreateDevice(DriverObject, - sizeof(FDO_DEVICE_EXTENSION), - &DeviceName, - FILE_DEVICE_8042_PORT, - FILE_DEVICE_SECURE_OPEN, - TRUE, - &Fdo); - - if (NT_SUCCESS(Status)) - { - AddRegistryEntry(L"KeyboardPort", &DeviceName, L"REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\i8042prt"); - FdoDevExt = Fdo->DeviceExtension; - - RtlZeroMemory(FdoDevExt, sizeof(FDO_DEVICE_EXTENSION)); - - FdoDevExt->PortDevExt = DevExt; - FdoDevExt->Type = Keyboard; - FdoDevExt->DeviceObject = Fdo; - - Fdo->Flags |= DO_BUFFERED_IO; - - DevExt->DebugWorkItem = IoAllocateWorkItem(Fdo); - DevExt->KeyboardObject = Fdo; - - DevExt->KeyboardBuffer = ExAllocatePoolWithTag( - NonPagedPool, - DevExt->KeyboardAttributes.InputDataQueueLength * - sizeof(KEYBOARD_INPUT_DATA), - TAG_I8042); - - if (!DevExt->KeyboardBuffer) { - DPRINT1("No memory for keyboardbuffer\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - - InsertTailList(&DevExt->BusDevices, &FdoDevExt->BusDevices); - Fdo->Flags &= ~DO_DEVICE_INITIALIZING; - } - else - DevExt->KeyboardExists = FALSE; - } - - if (DevExt->MouseExists) { - MappedIrqMouse = HalGetInterruptVector(Internal, - 0, - 0, - MOUSE_IRQ, - &DirqlMouse, - &Affinity); - - Status = IoCreateDevice(DriverObject, - sizeof(FDO_DEVICE_EXTENSION), - &MouseName, - FILE_DEVICE_8042_PORT, - FILE_DEVICE_SECURE_OPEN, - TRUE, - &Fdo); - - if (NT_SUCCESS(Status)) - { - AddRegistryEntry(L"PointerPort", &MouseName, L"REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\i8042prt"); - FdoDevExt = Fdo->DeviceExtension; - - RtlZeroMemory(FdoDevExt, sizeof(FDO_DEVICE_EXTENSION)); - - FdoDevExt->PortDevExt = DevExt; - FdoDevExt->Type = Mouse; - FdoDevExt->DeviceObject = Fdo; - - Fdo->Flags |= DO_BUFFERED_IO; - DevExt->MouseObject = Fdo; - - DevExt->MouseBuffer = ExAllocatePoolWithTag( - NonPagedPool, - DevExt->MouseAttributes.InputDataQueueLength * - sizeof(MOUSE_INPUT_DATA), - TAG_I8042); - - if (!DevExt->MouseBuffer) { - ExFreePoolWithTag(DevExt->KeyboardBuffer, TAG_I8042); - DPRINT1("No memory for mouse buffer\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - - InsertTailList(&DevExt->BusDevices, &FdoDevExt->BusDevices); - Fdo->Flags &= ~DO_DEVICE_INITIALIZING; - } - else - DevExt->MouseExists = FALSE; - } - - if (DirqlKeyboard > DirqlMouse) - DirqlMax = DirqlKeyboard; - else - DirqlMax = DirqlMouse; - - if (DevExt->KeyboardExists) { - Status = IoConnectInterrupt(&DevExt->KeyboardInterruptObject, - I8042InterruptServiceKbd, - (PVOID)DevExt, - &DevExt->SpinLock, - MappedIrqKeyboard, - DirqlKeyboard, - DirqlMax, - LevelSensitive, - FALSE, - Affinity, - FALSE); - - DPRINT("Keyboard Irq Status: %x\n", Status); - } - - if (DevExt->MouseExists) { - Status = IoConnectInterrupt(&DevExt->MouseInterruptObject, - I8042InterruptServiceMouse, - (PVOID)DevExt, - &DevExt->SpinLock, - MappedIrqMouse, - DirqlMouse, - DirqlMax, - LevelSensitive, - FALSE, - Affinity, - FALSE); - - DPRINT("Mouse Irq Status: %x\n", Status); - } - - if (DirqlKeyboard > DirqlMouse) - DevExt->HighestDIRQLInterrupt = DevExt->KeyboardInterruptObject; - else - DevExt->HighestDIRQLInterrupt = DevExt->MouseInterruptObject; - - DPRINT("I8042AddDevice done\n"); - - return(STATUS_SUCCESS); -} - -NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT DriverObject, - PUNICODE_STRING RegistryPath) -/* - * FUNCTION: Module entry point - */ -{ - DPRINT("I8042 Driver 0.0.1\n"); - - I8042RegistryPath.MaximumLength = RegistryPath->Length + sizeof(L"\\Parameters"); - I8042RegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool, - I8042RegistryPath.MaximumLength, - TAG_I8042); - if (I8042RegistryPath.Buffer == NULL) { - - return STATUS_INSUFFICIENT_RESOURCES; - } - - RtlCopyUnicodeString(&I8042RegistryPath, RegistryPath); - RtlAppendUnicodeToString(&I8042RegistryPath, L"\\Parameters"); - I8042RegistryPath.Buffer[I8042RegistryPath.Length / sizeof(WCHAR)] = 0; - - - - DriverObject->MajorFunction[IRP_MJ_CREATE] = I8042CreateDispatch; - DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = - I8042InternalDeviceControl; - - DriverObject->DriverStartIo = I8042StartIo; - DriverObject->DriverExtension->AddDevice = I8042AddDevice; - - return(STATUS_SUCCESS); -} diff --git a/reactos/drivers/input/i8042prt/i8042prt/i8042prt.h b/reactos/drivers/input/i8042prt/i8042prt/i8042prt.h deleted file mode 100644 index 9abf7a91883..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt/i8042prt.h +++ /dev/null @@ -1,378 +0,0 @@ -#ifndef _I8042DRV_H -#define _I8042DRV_H - -#include -#include -#include - -#ifdef _MSC_VER - #define STDCALL - #define DDKAPI -#endif - -#define KEYBOARD_IRQ 1 -#define MOUSE_IRQ 12 -#define KBD_BUFFER_SIZE 32 - -#define WHEEL_DELTA 120 - -/*----------------------------------------------------- - * DeviceExtension - * --------------------------------------------------*/ -typedef struct _COMMAND_CONTEXT -{ - int NumInput; - int CurInput; - UCHAR * Input; - int NumOutput; - int CurOutput; - UCHAR * Output; - NTSTATUS Status; - - BOOLEAN GotAck; - KEVENT Event; - - PVOID DevExt; -} COMMAND_CONTEXT, *PCOMMAND_CONTEXT; - -typedef enum _MOUSE_TIMEOUT_STATE -{ - NoChange, - TimeoutStart, - TimeoutCancel -} MOUSE_TIMEOUT_STATE, *PMOUSE_TIMEOUT_STATE; - -/* TODO: part of this should be in the _ATTRIBUTES structs instead */ -typedef struct _I8042_SETTINGS -{ - ULONG Headless; /* done */ - ULONG CrashScroll; - ULONG CrashSysRq; /* done */ - ULONG ReportResetErrors; - ULONG PollStatusIterations; /* done */ - ULONG ResendIterations; /* done */ - ULONG PollingIterations; - ULONG PollingIterationsMaximum; - ULONG OverrideKeyboardType; - ULONG OverrideKeyboardSubtype; - ULONG MouseResendStallTime; - ULONG MouseSynchIn100ns; /* done */ - ULONG MouseResolution; /* done */ - ULONG NumberOfButtons; - ULONG EnableWheelDetection; -} I8042_SETTINGS, *PI8042_SETTINGS; - -typedef enum _I8042_MOUSE_TYPE -{ - GenericPS2, - Intellimouse, - IntellimouseExplorer, - Ps2pp -} I8042_MOUSE_TYPE, *PI8042_MOUSE_TYPE; - -typedef enum _I8042_DEVICE_TYPE -{ - Keyboard, - Mouse -} I8042_DEVICE_TYPE, *PI8042_DEVICE_TYPE; - -typedef struct _I8042_DEVICE -{ - LIST_ENTRY ListEntry; - PDEVICE_OBJECT Pdo; -} I8042_DEVICE, *PI8042_DEVICE; - -typedef struct _DEVICE_EXTENSION -{ - PDEVICE_OBJECT KeyboardObject; - PDEVICE_OBJECT MouseObject; - - CONNECT_DATA KeyboardData; - CONNECT_DATA MouseData; - - BOOLEAN KeyboardExists; - BOOLEAN KeyboardIsAT; - BOOLEAN MouseExists; - - BOOLEAN KeyboardClaimed; - BOOLEAN MouseClaimed; - - ULONG BusNumber; - LIST_ENTRY BusDevices; - - INTERNAL_I8042_START_INFORMATION KeyboardStartInformation; - INTERNAL_I8042_START_INFORMATION MouseStartInformation; - - INTERNAL_I8042_HOOK_KEYBOARD KeyboardHook; - INTERNAL_I8042_HOOK_MOUSE MouseHook; - - PKINTERRUPT KeyboardInterruptObject; - PKINTERRUPT MouseInterruptObject; - PKINTERRUPT HighestDIRQLInterrupt; - KSPIN_LOCK SpinLock; - KDPC DpcKbd; - KDPC DpcMouse; - - KTIMER TimerMouseTimeout; - KDPC DpcMouseTimeout; - MOUSE_TIMEOUT_STATE MouseTimeoutState; - BOOLEAN MouseTimeoutActive; - - KEYBOARD_ATTRIBUTES KeyboardAttributes; - KEYBOARD_INDICATOR_PARAMETERS KeyboardIndicators; - KEYBOARD_TYPEMATIC_PARAMETERS KeyboardTypematic; - - BOOLEAN WantAck; - BOOLEAN WantOutput; - BOOLEAN SignalEvent; - - KEYBOARD_SCAN_STATE KeyboardScanState; - BOOLEAN KeyComplete; - KEYBOARD_INPUT_DATA *KeyboardBuffer; - ULONG KeysInBuffer; - - MOUSE_ATTRIBUTES MouseAttributes; - - MOUSE_STATE MouseState; - BOOLEAN MouseComplete; - MOUSE_RESET_SUBSTATE MouseResetState; - MOUSE_INPUT_DATA *MouseBuffer; - ULONG MouseInBuffer; - USHORT MouseButtonState; - ULARGE_INTEGER MousePacketStartTime; - - UCHAR MouseLogiBuffer[3]; - UCHAR MouseLogitechID; - I8042_MOUSE_TYPE MouseType; - - OUTPUT_PACKET Packet; - ULONG PacketResends; - BOOLEAN PacketComplete; - NTSTATUS PacketResult; - UCHAR PacketBuffer[16]; - UCHAR PacketPort; - - PIRP CurrentIrp; - PDEVICE_OBJECT CurrentIrpDevice; - - /* registry config values */ - I8042_SETTINGS Settings; - - /* Debugger stuff */ - BOOLEAN TabPressed; - ULONG DebugKey; - PIO_WORKITEM DebugWorkItem; -} DEVICE_EXTENSION, *PDEVICE_EXTENSION; - -typedef struct _FDO_DEVICE_EXTENSION -{ - PDEVICE_EXTENSION PortDevExt; - I8042_DEVICE_TYPE Type; - PDEVICE_OBJECT DeviceObject; - - LIST_ENTRY BusDevices; -} FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION; - -typedef struct _I8042_HOOK_WORKITEM -{ - PIO_WORKITEM WorkItem; - PDEVICE_OBJECT Target; - PIRP Irp; -} I8042_HOOK_WORKITEM, *PI8042_HOOK_WORKITEM; - -/* - * Some defines - */ -#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24)) -#define TAG_I8042 TAG('8', '0', '4', '2') - -#define KBD_WRAP_MASK 0x1F - -#define ALT_PRESSED (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED) -#define CTRL_PRESSED (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) - - -/* - * Keyboard controller ports - */ - -#define I8042_DATA_PORT ((PUCHAR)0x60) -#define I8042_CTRL_PORT ((PUCHAR)0x64) - - -/* - * Controller commands - */ - -#define KBD_READ_MODE 0x20 -#define KBD_WRITE_MODE 0x60 -#define KBD_SELF_TEST 0xAA -#define KBD_LINE_TEST 0xAB -#define KBD_CTRL_ENABLE 0xAE - -#define MOUSE_LINE_TEST 0xA9 -#define MOUSE_CTRL_ENABLE 0xA8 - -#define KBD_READ_OUTPUT_PORT 0xD0 -#define KBD_WRITE_OUTPUT_PORT 0xD1 - -/* - * Keyboard commands - */ - -#define KBD_SET_LEDS 0xED -#define KBD_GET_ID 0xF2 -#define KBD_ENABLE 0xF4 -#define KBD_DISABLE 0xF5 -#define KBD_RESET 0xFF - - -/* - * Keyboard responces - */ - -#define KBD_BATCC 0xAA -#define KBD_ACK 0xFA -#define KBD_NACK 0xFC -#define KBD_RESEND 0xFE - -/* - * Controller status register bits - */ - -#define KBD_OBF 0x01 -#define KBD_IBF 0x02 -#define KBD_AUX 0x10 -#define KBD_GTO 0x40 -#define KBD_PERR 0x80 - -/* - * Controller command byte bits - */ -#define CCB_KBD_INT_ENAB 0x01 -#define CCB_MOUSE_INT_ENAB 0x02 -#define CCB_SYSTEM_FLAG 0x04 -#define CCB_IGN_KEY_LOCK 0x08 -#define CCB_KBD_DISAB 0x10 -#define CCB_MOUSE_DISAB 0x20 -#define CCB_TRANSLATE 0x40 - - -/* - * LED bits - */ - -#define KBD_LED_SCROLL 0x01 -#define KBD_LED_NUM 0x02 -#define KBD_LED_CAPS 0x04 - -/* - * Mouse responses - */ -#define MOUSE_ACK 0xFA -#define MOUSE_ERROR 0xFC -#define MOUSE_NACK 0xFE - -/* i8042prt.c */ -extern UNICODE_STRING I8042RegistryPath; - -NTSTATUS I8042ReadData(UCHAR *Data); - -NTSTATUS I8042ReadStatus(UCHAR *Status); - -NTSTATUS I8042ReadDataWait(PDEVICE_EXTENSION DevExt, UCHAR *Data); - -VOID I8042Flush(); - -VOID STDCALL I8042IsrWritePort(PDEVICE_EXTENSION DevExt, - UCHAR Value, - UCHAR SelectCmd); - -NTSTATUS STDCALL I8042SynchWritePort(PDEVICE_EXTENSION DevExt, - UCHAR Port, - UCHAR Value, - BOOLEAN WaitForAck); - -NTSTATUS STDCALL I8042StartPacket(PDEVICE_EXTENSION DevExt, - PDEVICE_OBJECT Device, - PUCHAR Bytes, - ULONG ByteCount, - PIRP Irp); - -BOOLEAN STDCALL I8042PacketIsr(PDEVICE_EXTENSION DevExt, - UCHAR Output); - -VOID I8042PacketDpc(PDEVICE_EXTENSION DevExt); - -VOID STDCALL I8042SendHookWorkItem(PDEVICE_OBJECT DeviceObject, - PVOID Context); - -BOOLEAN I8042Write(PDEVICE_EXTENSION DevExt, PUCHAR addr, UCHAR data); - -NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT DriverObject, - PUNICODE_STRING RegistryPath); - -/* keyboard.c */ -VOID STDCALL I8042IsrWritePortKbd(PVOID Context, - UCHAR Value); - -NTSTATUS STDCALL I8042SynchWritePortKbd(PVOID Context, - UCHAR Value, - BOOLEAN WaitForAck); - -BOOLEAN STDCALL I8042InterruptServiceKbd(struct _KINTERRUPT *Interrupt, - VOID * Context); - -VOID STDCALL I8042DpcRoutineKbd(PKDPC Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2); - -BOOLEAN STDCALL I8042StartIoKbd(PDEVICE_OBJECT DeviceObject, PIRP Irp); - -NTSTATUS STDCALL I8042InternalDeviceControlKbd(PDEVICE_OBJECT DeviceObject, - PIRP Irp); - -BOOLEAN STDCALL I8042KeyboardEnable(PDEVICE_EXTENSION DevExt); - -BOOLEAN STDCALL I8042KeyboardEnableInterrupt(PDEVICE_EXTENSION DevExt); - -BOOLEAN STDCALL I8042DetectKeyboard(PDEVICE_EXTENSION DevExt); - -/* registry.c */ -VOID STDCALL I8042ReadRegistry(PDRIVER_OBJECT DriverObject, - PDEVICE_EXTENSION DevExt); - -/* mouse.c */ -VOID STDCALL I8042DpcRoutineMouse(PKDPC Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2); - -VOID STDCALL I8042DpcRoutineMouseTimeout(PKDPC Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2); - -BOOLEAN STDCALL I8042InterruptServiceMouse(struct _KINTERRUPT *Interrupt, - VOID *Context); - -NTSTATUS STDCALL I8042InternalDeviceControlMouse(PDEVICE_OBJECT DeviceObject, - PIRP Irp); - -VOID STDCALL I8042QueueMousePacket(PVOID Context); - -VOID STDCALL I8042MouseHandleButtons(PDEVICE_EXTENSION DevExt, - USHORT Mask); - -VOID STDCALL I8042MouseHandle(PDEVICE_EXTENSION DevExt, - UCHAR Output); - -BOOLEAN STDCALL I8042MouseEnable(PDEVICE_EXTENSION DevExt); -BOOLEAN STDCALL I8042MouseDisable(PDEVICE_EXTENSION DevExt); -BOOLEAN STDCALL I8042DetectMouse(PDEVICE_EXTENSION DevExt); - -/* ps2pp.c */ -VOID I8042MouseHandlePs2pp(PDEVICE_EXTENSION DevExt, UCHAR Input); - -#endif // _KEYBOARD_H_ diff --git a/reactos/drivers/input/i8042prt/i8042prt/i8042prt.rbuild b/reactos/drivers/input/i8042prt/i8042prt/i8042prt.rbuild deleted file mode 100644 index ca4085c16de..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt/i8042prt.rbuild +++ /dev/null @@ -1,14 +0,0 @@ - - - . - - - ntoskrnl - hal - i8042prt.c - keyboard.c - mouse.c - ps2pp.c - registry.c - i8042prt.rc - diff --git a/reactos/drivers/input/i8042prt/i8042prt/i8042prt.rc b/reactos/drivers/input/i8042prt/i8042prt/i8042prt.rc deleted file mode 100644 index 6c44176265e..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt/i8042prt.rc +++ /dev/null @@ -1,5 +0,0 @@ -#define REACTOS_VERSION_DLL -#define REACTOS_STR_FILE_DESCRIPTION "I8042 Port Device Driver\0" -#define REACTOS_STR_INTERNAL_NAME "i8042prt\0" -#define REACTOS_STR_ORIGINAL_FILENAME "i8042prt.sys\0" -#include diff --git a/reactos/drivers/input/i8042prt/i8042prt/keyboard.c b/reactos/drivers/input/i8042prt/i8042prt/keyboard.c deleted file mode 100644 index a301d2ee129..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt/keyboard.c +++ /dev/null @@ -1,776 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: drivers/input/i8042prt/keyboard.c - * PURPOSE: i8042 (ps/2 keyboard-mouse controller) driver - * keyboard specifics - * PROGRAMMER: Victor Kirhenshtein (sauros@iname.com) - * Jason Filby (jasonfilby@yahoo.com) - * Tinus - */ - -/* INCLUDES ****************************************************************/ - -#include "i8042prt.h" - -#define NDEBUG -#include - -/* GLOBALS *******************************************************************/ - -static UCHAR TypematicTable[] = { - 0x00, 0x00, 0x00, 0x05, 0x08, 0x0B, 0x0D, 0x0F, 0x10, 0x12, /* 0-9 */ - 0x13, 0x14, 0x15, 0x16, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1A, /* 10-19 */ - 0x1B, 0x1C, 0x1C, 0x1C, 0x1D, 0x1D, 0x1E }; - -typedef struct _LOCAL_KEYBOARD_INDICATOR_TRANSLATION { - USHORT NumberOfIndicatorKeys; - INDICATOR_LIST IndicatorList[3]; -} LOCAL_KEYBOARD_INDICATOR_TRANSLATION, *PLOCAL_KEYBOARD_INDICATOR_TRANSLATION; - -static LOCAL_KEYBOARD_INDICATOR_TRANSLATION IndicatorTranslation = { 3, { - {0x3A, KEYBOARD_CAPS_LOCK_ON}, - {0x45, KEYBOARD_NUM_LOCK_ON}, - {0x46, KEYBOARD_SCROLL_LOCK_ON}}}; - -static VOID STDCALL I8042DebugWorkItem(PDEVICE_OBJECT DeviceObject, - PVOID Context); - -/* FUNCTIONS *****************************************************************/ - -/* - * These functions are callbacks for filter driver custom interrupt - * service routines. - */ -VOID STDCALL I8042IsrWritePortKbd(PVOID Context, - UCHAR Value) -{ - I8042IsrWritePort(Context, Value, 0); -} - -static VOID STDCALL I8042QueueKeyboardPacket(PVOID Context) -{ - PDEVICE_OBJECT DeviceObject = Context; - PFDO_DEVICE_EXTENSION FdoDevExt = DeviceObject->DeviceExtension; - PDEVICE_EXTENSION DevExt = FdoDevExt->PortDevExt; - - DevExt->KeyComplete = TRUE; - DevExt->KeysInBuffer++; - if (DevExt->KeysInBuffer > - DevExt->KeyboardAttributes.InputDataQueueLength) { - DPRINT1("Keyboard buffer overflow\n"); - DevExt->KeysInBuffer--; - } - - DPRINT("Irq completes key\n"); - KeInsertQueueDpc(&DevExt->DpcKbd, DevExt, NULL); -} - -/* - * These functions are callbacks for filter driver custom - * initialization routines. - */ -NTSTATUS STDCALL I8042SynchWritePortKbd(PVOID Context, - UCHAR Value, - BOOLEAN WaitForAck) -{ - return I8042SynchWritePort((PDEVICE_EXTENSION)Context, - 0, - Value, - WaitForAck); -} - -BOOLEAN STDCALL I8042InterruptServiceKbd(struct _KINTERRUPT *Interrupt, - VOID * Context) -{ - UCHAR Output; - UCHAR PortStatus; - NTSTATUS Status; - PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION) Context; - BOOLEAN HookContinue = FALSE, HookReturn; - ULONG Iterations = 0; - - KEYBOARD_INPUT_DATA *InputData = - DevExt->KeyboardBuffer + DevExt->KeysInBuffer; - - do { - Status = I8042ReadStatus(&PortStatus); - DPRINT("PortStatus: %x\n", PortStatus); - Status = I8042ReadData(&Output); - Iterations++; - if (STATUS_SUCCESS == Status) - break; - KeStallExecutionProcessor(1); - } while (Iterations < DevExt->Settings.PollStatusIterations); - - if (STATUS_SUCCESS != Status) { - DPRINT("Spurious I8042 interrupt\n"); - return FALSE; - } - - DPRINT("Got: %x\n", Output); - - if (DevExt->KeyboardHook.IsrRoutine) { - HookReturn = DevExt->KeyboardHook.IsrRoutine( - DevExt->KeyboardHook.Context, - InputData, - &DevExt->Packet, - PortStatus, - &Output, - &HookContinue, - &DevExt->KeyboardScanState); - - if (!HookContinue) - return HookReturn; - } - - if (I8042PacketIsr(DevExt, Output)) { - if (DevExt->PacketComplete) { - DPRINT("Packet complete\n"); - KeInsertQueueDpc(&DevExt->DpcKbd, DevExt, NULL); - } - DPRINT("Irq eaten by packet\n"); - return TRUE; - } - - DPRINT("Irq is keyboard input\n"); - - if (Normal == DevExt->KeyboardScanState) { - switch (Output) { - case 0xe0: - DevExt->KeyboardScanState = GotE0; - return TRUE; - case 0xe1: - DevExt->KeyboardScanState = GotE1; - return TRUE; - default: - ;/* continue */ - } - } - - InputData->Flags = 0; - - switch (DevExt->KeyboardScanState) { - case GotE0: - InputData->Flags |= KEY_E0; - break; - case GotE1: - InputData->Flags |= KEY_E1; - break; - default: - ; - } - DevExt->KeyboardScanState = Normal; - - if (Output & 0x80) - InputData->Flags |= KEY_BREAK; - else - InputData->Flags |= KEY_MAKE; - - InputData->MakeCode = Output & 0x7f; - - I8042QueueKeyboardPacket(DevExt->KeyboardObject); - - return TRUE; -} - -VOID STDCALL I8042DpcRoutineKbd(PKDPC Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2) -{ - PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION)SystemArgument1; - ULONG KeysTransferred = 0; - ULONG KeysInBufferCopy; - KIRQL Irql; - - I8042PacketDpc(DevExt); - - if (!DevExt->KeyComplete) - return; - - /* We got the interrupt as it was being enabled, too bad */ - if (!DevExt->HighestDIRQLInterrupt) - return; - - Irql = KeAcquireInterruptSpinLock(DevExt->HighestDIRQLInterrupt); - - DevExt->KeyComplete = FALSE; - KeysInBufferCopy = DevExt->KeysInBuffer; - - KeReleaseInterruptSpinLock(DevExt->HighestDIRQLInterrupt, Irql); - - /* Test for TAB (debugging) */ - if (DevExt->Settings.CrashSysRq) { - PKEYBOARD_INPUT_DATA InputData = DevExt->KeyboardBuffer + - KeysInBufferCopy - 1; - if (InputData->MakeCode == 0x0F) { - DPRINT("Tab!\n"); - DevExt->TabPressed = !(InputData->Flags & KEY_BREAK); - } else if (DevExt->TabPressed) { - DPRINT ("Queueing work item %x\n", DevExt->DebugWorkItem); - DevExt->DebugKey = InputData->MakeCode; - DevExt->TabPressed = FALSE; - - IoQueueWorkItem(DevExt->DebugWorkItem, - &(I8042DebugWorkItem), - DelayedWorkQueue, - DevExt); - } - } - - DPRINT ("Send a key\n"); - - if (!DevExt->KeyboardData.ClassService) - return; - - ((PSERVICE_CALLBACK_ROUTINE) DevExt->KeyboardData.ClassService)( - DevExt->KeyboardData.ClassDeviceObject, - DevExt->KeyboardBuffer, - DevExt->KeyboardBuffer + KeysInBufferCopy, - &KeysTransferred); - - Irql = KeAcquireInterruptSpinLock(DevExt->HighestDIRQLInterrupt); - DevExt->KeysInBuffer -= KeysTransferred; - KeReleaseInterruptSpinLock(DevExt->HighestDIRQLInterrupt, Irql); -} - -/* You have to send the rate/delay in a somewhat awkward format */ -static UCHAR I8042GetTypematicByte(USHORT Rate, USHORT Delay) -{ - UCHAR ret; - - if (Rate < 3) { - ret = 0x0; - } else if (Rate > 26) { - ret = 0x1F; - } else { - ret = TypematicTable[Rate]; - } - - if (Delay < 375) { - ; - } else if (Delay < 625) { - ret |= 0x20; - } else if (Delay < 875) { - ret |= 0x40; - } else { - ret |= 0x60; - } - return ret; -} -/* - * Process the keyboard internal device requests - * returns FALSE if it doesn't understand the - * call so someone else can handle it. - */ -BOOLEAN STDCALL I8042StartIoKbd(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - PIO_STACK_LOCATION Stk; - PFDO_DEVICE_EXTENSION FdoDevExt = DeviceObject->DeviceExtension; - PDEVICE_EXTENSION DevExt = FdoDevExt->PortDevExt; - - Stk = IoGetCurrentIrpStackLocation(Irp); - - switch (Stk->Parameters.DeviceIoControl.IoControlCode) { - case IOCTL_INTERNAL_I8042_KEYBOARD_WRITE_BUFFER: - I8042StartPacket( - DevExt, - DeviceObject, - Stk->Parameters.DeviceIoControl.Type3InputBuffer, - Stk->Parameters.DeviceIoControl.InputBufferLength, - Irp); - break; - - case IOCTL_KEYBOARD_SET_INDICATORS: - DevExt->PacketBuffer[0] = 0xED; - DevExt->PacketBuffer[1] = 0; - if (DevExt->KeyboardIndicators.LedFlags & KEYBOARD_CAPS_LOCK_ON) - DevExt->PacketBuffer[1] |= 0x04; - - if (DevExt->KeyboardIndicators.LedFlags & KEYBOARD_NUM_LOCK_ON) - DevExt->PacketBuffer[1] |= 0x02; - - if (DevExt->KeyboardIndicators.LedFlags & KEYBOARD_SCROLL_LOCK_ON) - DevExt->PacketBuffer[1] |= 0x01; - - I8042StartPacket(DevExt, - DeviceObject, - DevExt->PacketBuffer, - 2, - Irp); - break; - case IOCTL_KEYBOARD_SET_TYPEMATIC: - DevExt->PacketBuffer[0] = 0xF3; - DevExt->PacketBuffer[1] = I8042GetTypematicByte( - DevExt->KeyboardTypematic.Rate, - DevExt->KeyboardTypematic.Delay); - - I8042StartPacket(DevExt, - DeviceObject, - DevExt->PacketBuffer, - 2, - Irp); - break; - default: - return FALSE; - } - - return TRUE; -} - -/* - * Runs the keyboard IOCTL_INTERNAL dispatch. - * Returns NTSTATUS_INVALID_DEVICE_REQUEST if it doesn't handle this request - * so someone else can have a try at it. - */ -NTSTATUS STDCALL I8042InternalDeviceControlKbd(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - PIO_STACK_LOCATION Stk; - PFDO_DEVICE_EXTENSION FdoDevExt = DeviceObject->DeviceExtension; - PDEVICE_EXTENSION DevExt = FdoDevExt->PortDevExt; - - DPRINT("InternalDeviceControl\n"); - - Irp->IoStatus.Information = 0; - Stk = IoGetCurrentIrpStackLocation(Irp); - - switch (Stk->Parameters.DeviceIoControl.IoControlCode) { - - case IOCTL_INTERNAL_KEYBOARD_CONNECT: - DPRINT("IOCTL_INTERNAL_KEYBOARD_CONNECT\n"); - if (Stk->Parameters.DeviceIoControl.InputBufferLength < - sizeof(CONNECT_DATA)) { - DPRINT1("Keyboard IOCTL_INTERNAL_KEYBOARD_CONNECT " - "invalid buffer size\n"); - Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; - goto intcontfailure; - } - - if (!DevExt->KeyboardExists) { - Irp->IoStatus.Status = STATUS_DEVICE_NOT_CONNECTED; - goto intcontfailure; - } - - if (DevExt->KeyboardClaimed) { - DPRINT1("IOCTL_INTERNAL_KEYBOARD_CONNECT: " - "Keyboard is already claimed\n"); - Irp->IoStatus.Status = STATUS_SHARING_VIOLATION; - goto intcontfailure; - } - - memcpy(&DevExt->KeyboardData, - Stk->Parameters.DeviceIoControl.Type3InputBuffer, - sizeof(CONNECT_DATA)); - DevExt->KeyboardHook.IsrWritePort = I8042IsrWritePortKbd; - DevExt->KeyboardHook.QueueKeyboardPacket = - I8042QueueKeyboardPacket; - DevExt->KeyboardHook.CallContext = DevExt; - - { - PIO_WORKITEM WorkItem; - PI8042_HOOK_WORKITEM WorkItemData; - - WorkItem = IoAllocateWorkItem(DeviceObject); - if (!WorkItem) { - DPRINT ("IOCTL_INTERNAL_KEYBOARD_CONNECT: " - "Can't allocate work item\n"); - Irp->IoStatus.Status = - STATUS_INSUFFICIENT_RESOURCES; - goto intcontfailure; - } - - WorkItemData = ExAllocatePoolWithTag( - NonPagedPool, - sizeof(I8042_HOOK_WORKITEM), - TAG_I8042); - if (!WorkItemData) { - DPRINT ("IOCTL_INTERNAL_KEYBOARD_CONNECT: " - "Can't allocate work item data\n"); - Irp->IoStatus.Status = - STATUS_INSUFFICIENT_RESOURCES; - IoFreeWorkItem(WorkItem); - goto intcontfailure; - } - WorkItemData->WorkItem = WorkItem; - WorkItemData->Target = - DevExt->KeyboardData.ClassDeviceObject; - WorkItemData->Irp = Irp; - - IoMarkIrpPending(Irp); - IoQueueWorkItem(WorkItem, - I8042SendHookWorkItem, - DelayedWorkQueue, - WorkItemData); - - Irp->IoStatus.Status = STATUS_PENDING; - } - - break; - case IOCTL_INTERNAL_I8042_KEYBOARD_WRITE_BUFFER: - DPRINT("IOCTL_INTERNAL_I8042_KEYBOARD_WRITE_BUFFER\n"); - if (Stk->Parameters.DeviceIoControl.InputBufferLength < 1) { - Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; - goto intcontfailure; - } - if (!DevExt->KeyboardInterruptObject) { - Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY; - goto intcontfailure; - } - - IoMarkIrpPending(Irp); - IoStartPacket(DeviceObject, Irp, NULL, NULL); - Irp->IoStatus.Status = STATUS_PENDING; - - break; - case IOCTL_KEYBOARD_QUERY_ATTRIBUTES: - DPRINT("IOCTL_KEYBOARD_QUERY_ATTRIBUTES\n"); - if (Stk->Parameters.DeviceIoControl.OutputBufferLength < - sizeof(KEYBOARD_ATTRIBUTES)) { - DPRINT("Keyboard IOCTL_KEYBOARD_QUERY_ATTRIBUTES " - "invalid buffer size\n"); - Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; - goto intcontfailure; - } - memcpy(Irp->AssociatedIrp.SystemBuffer, - &DevExt->KeyboardAttributes, - sizeof(KEYBOARD_ATTRIBUTES)); - - Irp->IoStatus.Status = STATUS_SUCCESS; - break; - case IOCTL_KEYBOARD_QUERY_INDICATORS: - DPRINT("IOCTL_KEYBOARD_QUERY_INDICATORS\n"); - if (Stk->Parameters.DeviceIoControl.OutputBufferLength < - sizeof(KEYBOARD_INDICATOR_PARAMETERS)) { - DPRINT("Keyboard IOCTL_KEYBOARD_QUERY_INDICATORS " - "invalid buffer size\n"); - Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; - goto intcontfailure; - } - memcpy(Irp->AssociatedIrp.SystemBuffer, - &DevExt->KeyboardIndicators, - sizeof(KEYBOARD_INDICATOR_PARAMETERS)); - - Irp->IoStatus.Status = STATUS_SUCCESS; - break; - case IOCTL_KEYBOARD_QUERY_TYPEMATIC: - DPRINT("IOCTL_KEYBOARD_QUERY_TYPEMATIC\n"); - if (Stk->Parameters.DeviceIoControl.OutputBufferLength < - sizeof(KEYBOARD_TYPEMATIC_PARAMETERS)) { - DPRINT("Keyboard IOCTL_KEYBOARD_QUERY_TYPEMATIC " - "invalid buffer size\n"); - Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; - goto intcontfailure; - } - memcpy(Irp->AssociatedIrp.SystemBuffer, - &DevExt->KeyboardTypematic, - sizeof(KEYBOARD_TYPEMATIC_PARAMETERS)); - - Irp->IoStatus.Status = STATUS_SUCCESS; - break; - case IOCTL_KEYBOARD_SET_INDICATORS: - DPRINT("IOCTL_KEYBOARD_SET_INDICATORS\n"); - if (Stk->Parameters.DeviceIoControl.InputBufferLength < - sizeof(KEYBOARD_INDICATOR_PARAMETERS)) { - DPRINT("Keyboard IOCTL_KEYBOARD_SET_INDICTATORS " - "invalid buffer size\n"); - Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; - goto intcontfailure; - } - - memcpy(&DevExt->KeyboardIndicators, - Irp->AssociatedIrp.SystemBuffer, - sizeof(KEYBOARD_INDICATOR_PARAMETERS)); - - DPRINT("%x\n", DevExt->KeyboardIndicators.LedFlags); - - IoMarkIrpPending(Irp); - IoStartPacket(DeviceObject, Irp, NULL, NULL); - Irp->IoStatus.Status = STATUS_PENDING; - - break; - case IOCTL_KEYBOARD_SET_TYPEMATIC: - DPRINT("IOCTL_KEYBOARD_SET_TYPEMATIC\n"); - if (Stk->Parameters.DeviceIoControl.InputBufferLength < - sizeof(KEYBOARD_TYPEMATIC_PARAMETERS)) { - DPRINT("Keyboard IOCTL_KEYBOARD_SET_TYPEMATIC " - "invalid buffer size\n"); - Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; - goto intcontfailure; - } - - memcpy(&DevExt->KeyboardTypematic, - Irp->AssociatedIrp.SystemBuffer, - sizeof(KEYBOARD_TYPEMATIC_PARAMETERS)); - - IoMarkIrpPending(Irp); - IoStartPacket(DeviceObject, Irp, NULL, NULL); - Irp->IoStatus.Status = STATUS_PENDING; - - break; - case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION: - /* We should check the UnitID, but it's kind of pointless as - * all keyboards are supposed to have the same one - */ - if (Stk->Parameters.DeviceIoControl.OutputBufferLength < - sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION)) { - DPRINT("IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION: " - "invalid buffer size (expected)\n"); - /* It's to query the buffer size */ - Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; - goto intcontfailure; - } - Irp->IoStatus.Information = - sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION); - - memcpy(Irp->AssociatedIrp.SystemBuffer, - &IndicatorTranslation, - sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION)); - - Irp->IoStatus.Status = STATUS_SUCCESS; - break; - case IOCTL_INTERNAL_I8042_HOOK_KEYBOARD: - /* Nothing to do here */ - Irp->IoStatus.Status = STATUS_SUCCESS; - break; - default: - Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; - break; - } - -intcontfailure: - return Irp->IoStatus.Status; -} - -/* This is all pretty confusing. There's more than one way to - * disable/enable the keyboard. You can send KBD_ENABLE to the - * keyboard, and it will start scanning keys. Sending KBD_DISABLE - * will disable the key scanning but also reset the parameters to - * defaults. - * - * You can also send 0xAE to the controller for enabling the - * keyboard clock line and 0xAD for disabling it. Then it'll - * automatically get turned on at the next command. The last - * way is by modifying the bit that drives the clock line in the - * 'command byte' of the controller. This is almost, but not quite, - * the same as the AE/AD thing. The difference can be used to detect - * some really old broken keyboard controllers which I hope won't be - * necessary. - * - * We change the command byte, sending KBD_ENABLE/DISABLE seems to confuse - * some kvm switches. - */ - -BOOLEAN STDCALL I8042KeyboardEnable(PDEVICE_EXTENSION DevExt) -{ - UCHAR Value; - NTSTATUS Status; - - DPRINT("Enable keyboard\n"); - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_READ_MODE)) { - DPRINT1("Can't read i8042 mode\n"); - return FALSE; - } - - Status = I8042ReadDataWait(DevExt, &Value); - if (!NT_SUCCESS(Status)) { - DPRINT1("No response after read i8042 mode\n"); - return FALSE; - } - - Value &= ~CCB_KBD_DISAB; // don't disable keyboard - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_WRITE_MODE)) { - DPRINT1("Can't set i8042 mode\n"); - return FALSE; - } - - if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) { - DPRINT1("Can't send i8042 mode\n"); - return FALSE; - } - - return TRUE; -} - -static BOOLEAN STDCALL I8042KeyboardDefaultsAndDisable(PDEVICE_EXTENSION DevExt) -{ - UCHAR Value; - NTSTATUS Status; - - DPRINT("Disabling keyboard\n"); - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_READ_MODE)) { - DPRINT1("Can't read i8042 mode\n"); - return FALSE; - } - - Status = I8042ReadDataWait(DevExt, &Value); - if (!NT_SUCCESS(Status)) { - DPRINT1("No response after read i8042 mode\n"); - return FALSE; - } - - Value |= CCB_KBD_DISAB; // disable keyboard - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_WRITE_MODE)) { - DPRINT1("Can't set i8042 mode\n"); - return FALSE; - } - - if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) { - DPRINT1("Can't send i8042 mode\n"); - return FALSE; - } - - return TRUE; -} - -BOOLEAN STDCALL I8042KeyboardEnableInterrupt(PDEVICE_EXTENSION DevExt) -{ - UCHAR Value; - NTSTATUS Status; - - DPRINT("Enabling keyboard interrupt\n"); - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_READ_MODE)) { - DPRINT1("Can't read i8042 mode\n"); - return FALSE; - } - - Status = I8042ReadDataWait(DevExt, &Value); - if (!NT_SUCCESS(Status)) { - DPRINT1("No response after read i8042 mode\n"); - return FALSE; - } - - Value &= ~CCB_KBD_DISAB; // don't disable keyboard - Value |= CCB_KBD_INT_ENAB; // enable keyboard interrupts - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_WRITE_MODE)) { - DPRINT1("Can't set i8042 mode\n"); - return FALSE; - } - - if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) { - DPRINT1("Can't send i8042 mode\n"); - return FALSE; - } - - return TRUE; -} - -BOOLEAN STDCALL I8042DetectKeyboard(PDEVICE_EXTENSION DevExt) -{ - NTSTATUS Status; - UCHAR Value; - UCHAR Value2; - ULONG RetryCount = 10; - - DPRINT("Detecting keyboard\n"); - - I8042KeyboardDefaultsAndDisable(DevExt); - - do { - I8042Flush(); - Status = I8042SynchWritePort(DevExt, 0, KBD_GET_ID, TRUE); - } while (STATUS_IO_TIMEOUT == Status && RetryCount--); - - if (!NT_SUCCESS(Status)) { - DPRINT1("Can't write GET_ID (%x)\n", Status); - /* Could be an AT keyboard */ - DevExt->KeyboardIsAT = TRUE; - goto detectsetleds; - } - - Status = I8042ReadDataWait(DevExt, &Value); - if (!NT_SUCCESS(Status)) { - DPRINT1("No response after GET_ID\n"); - /* Could be an AT keyboard */ - DevExt->KeyboardIsAT = TRUE; - goto detectsetleds; - } - DevExt->KeyboardIsAT = FALSE; - - if (Value != 0xAB && Value != 0xAC) { - DPRINT("Bad ID: %x\n", Value); - /* This is certainly not a keyboard */ - return FALSE; - } - - Status = I8042ReadDataWait(DevExt, &Value2); - if (!NT_SUCCESS(Status)) { - DPRINT("Partial ID\n"); - return FALSE; - } - - DPRINT("Keyboard ID: 0x%x 0x%x\n", Value, Value2); - -detectsetleds: - I8042Flush(); /* Flush any bytes left over from GET_ID */ - - Status = I8042SynchWritePort(DevExt, 0, KBD_SET_LEDS, TRUE); - if (!NT_SUCCESS(Status)) { - DPRINT("Can't write SET_LEDS (%x)\n", Status); - return FALSE; - } - Status = I8042SynchWritePort(DevExt, 0, 0, TRUE); - if (!NT_SUCCESS(Status)) { - DPRINT("Can't finish SET_LEDS (%x)\n", Status); - return FALSE; - } - - // Turn on translation - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_READ_MODE)) { - DPRINT1("Can't read i8042 mode\n"); - return FALSE; - } - - Status = I8042ReadDataWait(DevExt, &Value); - if (!NT_SUCCESS(Status)) { - DPRINT1("No response after read i8042 mode\n"); - return FALSE; - } - - Value |= 0x40; // enable keyboard translation - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_WRITE_MODE)) { - DPRINT1("Can't set i8042 mode\n"); - return FALSE; - } - - if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) { - DPRINT1("Can't send i8042 mode\n"); - return FALSE; - } - - return TRUE; -} - -/* debug stuff */ -VOID STDCALL -KdpServiceDispatcher(ULONG Code, PVOID Context1, PVOID Context2); -#define EnterDebugger ((PVOID)0x25) - -static VOID STDCALL I8042DebugWorkItem(PDEVICE_OBJECT DeviceObject, - PVOID Context) -{ - ULONG Key; - PFDO_DEVICE_EXTENSION FdoDevExt = DeviceObject->DeviceExtension; - PDEVICE_EXTENSION DevExt = FdoDevExt->PortDevExt; - - Key = InterlockedExchange((PLONG)&DevExt->DebugKey, 0); - DPRINT("Debug key: %x\n", Key); - - if (!Key) - return; - -#ifdef __REACTOS__ - /* We hope kernel would understand this. If - * that's not the case, nothing would happen. - */ - KdpServiceDispatcher(TAG('R', 'o', 's', ' '), (PVOID)Key, NULL); -#endif /* __REACTOS__ */ -} diff --git a/reactos/drivers/input/i8042prt/i8042prt/mouse.c b/reactos/drivers/input/i8042prt/i8042prt/mouse.c deleted file mode 100644 index 5a8afb5ebf3..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt/mouse.c +++ /dev/null @@ -1,948 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: drivers/input/i8042prt/mouse.c - * PURPOSE: i8042 (ps/2 keyboard-mouse controller) driver - * mouse specifics - * PROGRAMMER: Victor Kirhenshtein (sauros@iname.com) - * Jason Filby (jasonfilby@yahoo.com) - * Tinus - */ - -/* INCLUDES ****************************************************************/ - -#include "i8042prt.h" - -#define NDEBUG -#include - -/* - * These functions are callbacks for filter driver custom interrupt - * service routines. - */ -static VOID STDCALL I8042IsrWritePortMouse(PVOID Context, - UCHAR Value) -{ - I8042IsrWritePort(Context, Value, 0xD4); -} - -#if 0 -static NTSTATUS STDCALL I8042SynchWritePortMouse(PVOID Context, - UCHAR Value, - BOOLEAN WaitForAck) -{ - return I8042SynchWritePort((PDEVICE_EXTENSION)Context, - 0xD4, - Value, - WaitForAck); -} -#endif - -/* Test if packets are taking too long to come in. If they do, we - * might have gotten out of sync and should just drop what we have. - * - * If we want to be totally right, we'd also have to keep a count of - * errors, and totally reset the mouse after too much of them (can - * happen if the user is using a KVM switch and an OS on another port - * resets the mouse, or if the user hotplugs the mouse, or if we're just - * generally unlucky). Also note the input parsing routine where we - * drop invalid input packets. - */ -static VOID STDCALL I8042MouseInputTestTimeout(PDEVICE_EXTENSION DevExt) -{ - ULARGE_INTEGER Now; - - if (DevExt->MouseState == MouseExpectingACK || - DevExt->MouseState == MouseResetting) - return; - - Now.QuadPart = KeQueryInterruptTime(); - - if (DevExt->MouseState != MouseIdle) { - /* Check if the last byte came too long ago */ - if (Now.QuadPart - DevExt->MousePacketStartTime.QuadPart > - DevExt->Settings.MouseSynchIn100ns) { - DPRINT("Mouse input packet timeout\n"); - DevExt->MouseState = MouseIdle; - } - } - - if (DevExt->MouseState == MouseIdle) - DevExt->MousePacketStartTime.QuadPart = Now.QuadPart; -} - -/* - * Call the customization hook. The Ret2 parameter is about wether - * we should go on with the interrupt. The return value is what - * we should return (indicating to the system wether someone else - * should try to handle the interrupt) - */ -static BOOLEAN STDCALL I8042MouseCallIsrHook(PDEVICE_EXTENSION DevExt, - UCHAR Status, - PUCHAR Input, - PBOOLEAN ToReturn) -{ - BOOLEAN HookReturn, HookContinue; - - HookContinue = FALSE; - - if (DevExt->MouseHook.IsrRoutine) { - HookReturn = DevExt->MouseHook.IsrRoutine( - DevExt->MouseHook.Context, - DevExt->MouseBuffer + DevExt->MouseInBuffer, - &DevExt->Packet, - Status, - Input, - &HookContinue, - &DevExt->MouseState, - &DevExt->MouseResetState); - - if (!HookContinue) { - *ToReturn = HookReturn; - return TRUE; - } - } - return FALSE; -} - -static BOOLEAN STDCALL I8042MouseResetIsr(PDEVICE_EXTENSION DevExt, - UCHAR Status, - PUCHAR Value) -{ - BOOLEAN ToReturn = FALSE; - - if (I8042MouseCallIsrHook(DevExt, Status, Value, &ToReturn)) - return ToReturn; - - if (MouseResetting != DevExt->MouseState) { - return FALSE; - } - DevExt->MouseTimeoutState = TimeoutStart; - - switch (DevExt->MouseResetState) { - case 1100: /* the first ack, drop it. */ - DevExt->MouseResetState = ExpectingReset; - return TRUE; - /* First, 0xFF is sent. The mouse is supposed to say AA00 if ok, - * FC00 if not. - */ - case ExpectingReset: - if (0xAA == *Value) { - DevExt->MouseResetState++; - } else { - DevExt->MouseExists = FALSE; - DevExt->MouseState = MouseIdle; - DPRINT("Mouse returned bad reset reply: " - "%x (expected aa)\n", *Value); - } - return TRUE; - case ExpectingResetId: - if (0x00 == *Value) { - DevExt->MouseResetState++; - DevExt->MouseType = GenericPS2; - I8042IsrWritePortMouse(DevExt, 0xF2); - } else { - DevExt->MouseExists = FALSE; - DevExt->MouseState = MouseIdle; - DPRINT1("Mouse returned bad reset reply part two: " - "%x (expected 0)\n", *Value); - } - return TRUE; - case ExpectingGetDeviceIdACK: - if (MOUSE_ACK == *Value) { - DevExt->MouseResetState++; - } else if (MOUSE_NACK == *Value || - MOUSE_ERROR == *Value) { - DevExt->MouseResetState++; - /* Act as if 00 (normal mouse) was received */ - DPRINT("Mouse doesn't support 0xd2, " - "(returns %x, expected %x), faking.\n", - *Value, MOUSE_ACK); - *Value = 0; - I8042MouseResetIsr(DevExt, Status, Value); - } - return TRUE; - case ExpectingGetDeviceIdValue: - switch (*Value) { - case 0x02: - DevExt->MouseAttributes.MouseIdentifier = - BALLPOINT_I8042_HARDWARE; - break; - case 0x03: - case 0x04: - DevExt->MouseAttributes.MouseIdentifier = - WHEELMOUSE_I8042_HARDWARE; - break; - default: - DevExt->MouseAttributes.MouseIdentifier = - MOUSE_I8042_HARDWARE; - } - DevExt->MouseResetState++; - I8042IsrWritePortMouse(DevExt, 0xE8); - return TRUE; - case ExpectingSetResolutionDefaultACK: - DevExt->MouseResetState++; - I8042IsrWritePortMouse(DevExt, 0x00); - return TRUE; - case ExpectingSetResolutionDefaultValueACK: - DevExt->MouseResetState = ExpectingSetScaling1to1ACK; - I8042IsrWritePortMouse(DevExt, 0xE6); - return TRUE; - case ExpectingSetScaling1to1ACK: - case ExpectingSetScaling1to1ACK2: - DevExt->MouseResetState++; - I8042IsrWritePortMouse(DevExt, 0xE6); - return TRUE; - case ExpectingSetScaling1to1ACK3: - DevExt->MouseResetState++; - I8042IsrWritePortMouse(DevExt, 0xE9); - return TRUE; - case ExpectingReadMouseStatusACK: - DevExt->MouseResetState++; - return TRUE; - case ExpectingReadMouseStatusByte1: - DevExt->MouseLogiBuffer[0] = *Value; - DevExt->MouseResetState++; - return TRUE; - case ExpectingReadMouseStatusByte2: - DevExt->MouseLogiBuffer[1] = *Value; - DevExt->MouseResetState++; - return TRUE; - case ExpectingReadMouseStatusByte3: - DevExt->MouseLogiBuffer[2] = *Value; - /* Now MouseLogiBuffer is a set of info. If the second - * byte is 0, the mouse didn't understand the magic - * code. Otherwise, it it a Logitech and the second byte - * is the number of buttons, bit 7 of the first byte tells - * if it understands special E7 commands, the rest is an ID. - */ - if (DevExt->MouseLogiBuffer[1]) { - DevExt->MouseAttributes.NumberOfButtons = - DevExt->MouseLogiBuffer[1]; - /* For some reason the ID is the wrong way around */ - DevExt->MouseLogitechID = - ((DevExt->MouseLogiBuffer[0] >> 4) & 0x07) | - ((DevExt->MouseLogiBuffer[0] << 3) & 0x78); - DevExt->MouseType = Ps2pp; - I8042IsrWritePortMouse(DevExt, 0xf3); - DevExt->MouseResetState = ExpectingSetSamplingRateACK; - return TRUE; - /* TODO: Go through EnableWheel and Enable5Buttons */ - } - DevExt->MouseResetState = EnableWheel; - I8042MouseResetIsr(DevExt, Status, Value); - return TRUE; - case EnableWheel: - I8042IsrWritePortMouse(DevExt, 0xf3); - DevExt->MouseResetState = 1001; - return TRUE; - case 1001: - I8042IsrWritePortMouse(DevExt, 0xc8); - DevExt->MouseResetState++; - return TRUE; - case 1002: - case 1004: - I8042IsrWritePortMouse(DevExt, 0xf3); - DevExt->MouseResetState++; - return TRUE; - case 1003: - I8042IsrWritePortMouse(DevExt, 0x64); - DevExt->MouseResetState++; - return TRUE; - case 1005: - I8042IsrWritePortMouse(DevExt, 0x50); - DevExt->MouseResetState++; - return TRUE; - case 1006: - I8042IsrWritePortMouse(DevExt, 0xf2); - DevExt->MouseResetState++; - return TRUE; - case 1007: - /* Ignore ACK */ - DevExt->MouseResetState++; - return TRUE; - case 1008: - /* Now if the value == 3, it's either an Intellimouse - * or Intellimouse Explorer. */ - if (0x03 == *Value) { - DevExt->MouseAttributes.NumberOfButtons = 3; - DevExt->MouseAttributes.MouseIdentifier = - WHEELMOUSE_I8042_HARDWARE; - DevExt->MouseType = Intellimouse; - DevExt->MouseResetState = Enable5Buttons; - I8042MouseResetIsr(DevExt, Status, Value); - return TRUE; - } /* Else, just set the default settings and be done */ - I8042IsrWritePortMouse(DevExt, 0xf3); - DevExt->MouseResetState = ExpectingSetSamplingRateACK; - return TRUE; - case Enable5Buttons: - I8042IsrWritePortMouse(DevExt, 0xf3); - DevExt->MouseResetState = 1021; - return TRUE; - case 1022: - case 1024: - I8042IsrWritePortMouse(DevExt, 0xf3); - DevExt->MouseResetState++; - return TRUE; - case 1021: - case 1023: - I8042IsrWritePortMouse(DevExt, 0xc8); - DevExt->MouseResetState++; - return TRUE; - case 1025: - I8042IsrWritePortMouse(DevExt, 0x50); - DevExt->MouseResetState++; - return TRUE; - case 1026: - I8042IsrWritePortMouse(DevExt, 0xf2); - DevExt->MouseResetState++; - return TRUE; - case 1027: - if (0x04 == *Value) { - DevExt->MouseAttributes.NumberOfButtons = 5; - DevExt->MouseAttributes.MouseIdentifier = - WHEELMOUSE_I8042_HARDWARE; - DevExt->MouseType = IntellimouseExplorer; - } - I8042IsrWritePortMouse(DevExt, 0xf3); - DevExt->MouseResetState = ExpectingSetSamplingRateACK; - return TRUE; - case ExpectingSetSamplingRateACK: - I8042IsrWritePortMouse(DevExt, - (UCHAR)DevExt->MouseAttributes.SampleRate); - DevExt->MouseResetState++; - return TRUE; - case ExpectingSetSamplingRateValueACK: - if (MOUSE_NACK == *Value) { - I8042IsrWritePortMouse(DevExt, 0x3c); - DevExt->MouseAttributes.SampleRate = 60; - DevExt->MouseResetState = 1040; - return TRUE; - } - case 1040: /* Fallthrough */ - I8042IsrWritePortMouse(DevExt, 0xe8); - DevExt->MouseResetState = ExpectingFinalResolutionACK; - return TRUE; - case ExpectingFinalResolutionACK: - I8042IsrWritePortMouse(DevExt, - (UCHAR)(DevExt->Settings.MouseResolution & 0xff)); - DPRINT("%x\n", DevExt->Settings.MouseResolution); - DevExt->MouseResetState = ExpectingFinalResolutionValueACK; - return TRUE; - case ExpectingFinalResolutionValueACK: - I8042IsrWritePortMouse(DevExt, 0xf4); - DevExt->MouseResetState = ExpectingEnableACK; - return TRUE; - case ExpectingEnableACK: - DevExt->MouseState = MouseIdle; - DevExt->MouseTimeoutState = TimeoutCancel; - DPRINT("Mouse type = %d\n", DevExt->MouseType); - return TRUE; - default: - if (DevExt->MouseResetState < 100 || - DevExt->MouseResetState > 999) - DPRINT1("MouseResetState went out of range: %d\n", - DevExt->MouseResetState); - return FALSE; - } -} - -/* - * Prepare for reading the next packet and queue the dpc for handling - * this one. - * - * Context is the device object. - */ -VOID STDCALL I8042QueueMousePacket(PVOID Context) -{ - PDEVICE_OBJECT DeviceObject = Context; - PFDO_DEVICE_EXTENSION FdoDevExt = DeviceObject->DeviceExtension; - PDEVICE_EXTENSION DevExt = FdoDevExt->PortDevExt; - - DevExt->MouseComplete = TRUE; - DevExt->MouseInBuffer++; - if (DevExt->MouseInBuffer > - DevExt->MouseAttributes.InputDataQueueLength) { - DPRINT1("Mouse buffer overflow\n"); - DevExt->MouseInBuffer--; - } - - DPRINT("Irq completes mouse packet\n"); - KeInsertQueueDpc(&DevExt->DpcMouse, DevExt, NULL); -} - -/* - * Updates ButtonFlags according to RawButtons and a saved state; - * Only takes in account the bits that are set in Mask - */ -VOID STDCALL I8042MouseHandleButtons(PDEVICE_EXTENSION DevExt, - USHORT Mask) -{ - PMOUSE_INPUT_DATA MouseInput = DevExt->MouseBuffer + - DevExt->MouseInBuffer; - USHORT NewButtonData = (USHORT)(MouseInput->RawButtons & Mask); - USHORT ButtonDiff = (NewButtonData ^ DevExt->MouseButtonState) & Mask; - - /* Note that the defines are such: - * MOUSE_LEFT_BUTTON_DOWN 1 - * MOUSE_LEFT_BUTTON_UP 2 - */ - MouseInput->ButtonFlags |= (NewButtonData & ButtonDiff) | - (((~(NewButtonData)) << 1) & - (ButtonDiff << 1)) | - (MouseInput->RawButtons & 0xfc00); - - DPRINT("Left raw/up/down: %d/%d/%d\n", MouseInput->RawButtons & MOUSE_LEFT_BUTTON_DOWN, - MouseInput->ButtonFlags & MOUSE_LEFT_BUTTON_DOWN, - MouseInput->ButtonFlags & MOUSE_LEFT_BUTTON_UP); - - DevExt->MouseButtonState = (DevExt->MouseButtonState & ~Mask) | - (NewButtonData & Mask); -} - -VOID STDCALL I8042MouseHandle(PDEVICE_EXTENSION DevExt, - UCHAR Output) -{ - PMOUSE_INPUT_DATA MouseInput = DevExt->MouseBuffer + - DevExt->MouseInBuffer; - CHAR Scroll; - - switch (DevExt->MouseState) { - case MouseIdle: - /* This bit should be 1, if not drop the packet, we - * might be lucky and get in sync again - */ - if (!(Output & 8)) { - DPRINT1("Bad input, dropping..\n"); - return; - } - - MouseInput->Buttons = 0; - MouseInput->RawButtons = 0; - MouseInput->Flags = MOUSE_MOVE_RELATIVE; - - /* Note how we ignore the overflow bits, like Windows - * is said to do. There's no reasonable thing to do - * anyway. - */ - - if (Output & 16) - MouseInput->LastX = 1; - else - MouseInput->LastX = 0; - - if (Output & 32) - MouseInput->LastY = 1; - else - MouseInput->LastY = 0; - - if (Output & 1) { - MouseInput->RawButtons |= MOUSE_LEFT_BUTTON_DOWN; - } - - if (Output & 2) { - MouseInput->RawButtons |= MOUSE_RIGHT_BUTTON_DOWN; - } - - if (Output & 4) { - MouseInput->RawButtons |= MOUSE_MIDDLE_BUTTON_DOWN; - } - DevExt->MouseState = XMovement; - break; - case XMovement: - if (MouseInput->LastX) - MouseInput->LastX = (LONG) Output - 256; - else - MouseInput->LastX = Output; - - DevExt->MouseState = YMovement; - break; - case YMovement: - if (MouseInput->LastY) - MouseInput->LastY = (LONG)Output - 256; - else - MouseInput->LastY = (LONG)Output; - - /* Windows wants it the other way around */ - MouseInput->LastY = -MouseInput->LastY; - - if (DevExt->MouseType == GenericPS2 || - DevExt->MouseType == Ps2pp) { - I8042MouseHandleButtons(DevExt, - MOUSE_LEFT_BUTTON_DOWN | - MOUSE_RIGHT_BUTTON_DOWN | - MOUSE_MIDDLE_BUTTON_DOWN); - I8042QueueMousePacket( - DevExt->MouseObject); - DevExt->MouseState = MouseIdle; - } else { - DevExt->MouseState = ZMovement; - } - break; - case ZMovement: - Scroll = Output & 0x0f; - if (Scroll & 8) - Scroll |= 0xf0; - - if (Scroll) { - MouseInput->RawButtons |= MOUSE_WHEEL; - MouseInput->ButtonData = (USHORT)(Scroll * -WHEEL_DELTA); - } - - if (DevExt->MouseType == IntellimouseExplorer) { - if (Output & 16) - MouseInput->RawButtons |= MOUSE_BUTTON_4_DOWN; - - if (Output & 32) - MouseInput->RawButtons |= MOUSE_BUTTON_5_DOWN; - } - I8042MouseHandleButtons(DevExt, MOUSE_LEFT_BUTTON_DOWN | - MOUSE_RIGHT_BUTTON_DOWN | - MOUSE_MIDDLE_BUTTON_DOWN | - MOUSE_BUTTON_4_DOWN | - MOUSE_BUTTON_5_DOWN); - I8042QueueMousePacket(DevExt->MouseObject); - DevExt->MouseState = MouseIdle; - break; - default: - DPRINT1("Unexpected state!\n"); - } -} - -BOOLEAN STDCALL I8042InterruptServiceMouse(struct _KINTERRUPT *Interrupt, - VOID *Context) -{ - UCHAR Output, PortStatus; - NTSTATUS Status; - PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION) Context; - ULONG Iterations = 0; - - do { - Status = I8042ReadStatus(&PortStatus); - Status = I8042ReadData(&Output); - Iterations++; - if (STATUS_SUCCESS == Status) - break; - KeStallExecutionProcessor(1); - } while (Iterations < DevExt->Settings.PollStatusIterations); - - if (STATUS_SUCCESS != Status) { - DPRINT1("Spurious I8042 mouse interrupt\n"); - return FALSE; - } - - DPRINT("Got: %x\n", Output); - - if (I8042PacketIsr(DevExt, Output)) { - if (DevExt->PacketComplete) { - DPRINT("Packet complete\n"); - KeInsertQueueDpc(&DevExt->DpcKbd, DevExt, NULL); - } - DPRINT("Irq eaten by packet\n"); - return TRUE; - } - - I8042MouseInputTestTimeout(DevExt); - - if (I8042MouseResetIsr(DevExt, PortStatus, &Output)) { - DPRINT("Handled by ResetIsr or hooked Isr\n"); - if (NoChange != DevExt->MouseTimeoutState) { - KeInsertQueueDpc(&DevExt->DpcMouse, DevExt, NULL); - } - return TRUE; - } - - if (DevExt->MouseType == Ps2pp) - I8042MouseHandlePs2pp(DevExt, Output); - else - I8042MouseHandle(DevExt, Output); - - return TRUE; -} - -VOID STDCALL I8042DpcRoutineMouse(PKDPC Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2) -{ - PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION)SystemArgument1; - ULONG MouseTransferred = 0; - ULONG MouseInBufferCopy; - KIRQL Irql; - LARGE_INTEGER Timeout; - - switch (DevExt->MouseTimeoutState) { - case TimeoutStart: - DevExt->MouseTimeoutState = NoChange; - if (DevExt->MouseTimeoutActive && - !KeCancelTimer(&DevExt->TimerMouseTimeout)) { - /* The timer fired already, give up */ - DevExt->MouseTimeoutActive = FALSE; - return; - } - - Timeout.QuadPart = -15000000; - /* 1.5 seconds, should be enough */ - - KeSetTimer(&DevExt->TimerMouseTimeout, - Timeout, - &DevExt->DpcMouseTimeout); - DevExt->MouseTimeoutActive = TRUE; - return; - case TimeoutCancel: - DevExt->MouseTimeoutState = NoChange; - KeCancelTimer(&DevExt->TimerMouseTimeout); - DevExt->MouseTimeoutActive = FALSE; - default: - /* nothing, don't want a warning */ ; - } - - /* Should be unlikely */ - if (!DevExt->MouseComplete) - return; - - Irql = KeAcquireInterruptSpinLock(DevExt->HighestDIRQLInterrupt); - - DevExt->MouseComplete = FALSE; - MouseInBufferCopy = DevExt->MouseInBuffer; - - KeReleaseInterruptSpinLock(DevExt->HighestDIRQLInterrupt, Irql); - - DPRINT ("Send a mouse packet\n"); - - if (!DevExt->MouseData.ClassService) - return; - - ((PSERVICE_CALLBACK_ROUTINE) DevExt->MouseData.ClassService)( - DevExt->MouseData.ClassDeviceObject, - DevExt->MouseBuffer, - DevExt->MouseBuffer + MouseInBufferCopy, - &MouseTransferred); - - Irql = KeAcquireInterruptSpinLock(DevExt->HighestDIRQLInterrupt); - - DevExt->MouseInBuffer -= MouseTransferred; - if (DevExt->MouseInBuffer) - RtlMoveMemory(DevExt->MouseBuffer, - DevExt->MouseBuffer+MouseTransferred, - DevExt->MouseInBuffer * sizeof(MOUSE_INPUT_DATA)); - - KeReleaseInterruptSpinLock(DevExt->HighestDIRQLInterrupt, Irql); -} - -/* This timer DPC will be called when the mouse reset times out. - * I'll just send the 'disable mouse port' command to the controller - * and say the mouse doesn't exist. - */ -VOID STDCALL I8042DpcRoutineMouseTimeout(PKDPC Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2) -{ - PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION)DeferredContext; - KIRQL Irql; - - Irql = KeAcquireInterruptSpinLock(DevExt->HighestDIRQLInterrupt); - - DPRINT1("Mouse initialization timeout! (substate %x) " - "Disabling mouse.\n", - DevExt->MouseResetState); - - if (!I8042MouseDisable(DevExt)) { - DPRINT1("Failed to disable mouse.\n"); - } - - DevExt->MouseExists = FALSE; - - KeReleaseInterruptSpinLock(DevExt->HighestDIRQLInterrupt, Irql); -} - -/* - * Process the mouse internal device requests - * returns FALSE if it doesn't understand the - * call so someone else can handle it. - */ -#if 0 -static BOOLEAN STDCALL I8042StartIoMouse(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - PIO_STACK_LOCATION Stk; - PFDO_DEVICE_EXTENSION FdoDevExt = DeviceObject->DeviceExtension; - PDEVICE_EXTENSION DevExt = FdoDevExt->PortDevExt; - - Stk = IoGetCurrentIrpStackLocation(Irp); - - switch (Stk->Parameters.DeviceIoControl.IoControlCode) { - case IOCTL_INTERNAL_I8042_MOUSE_WRITE_BUFFER: - I8042StartPacket( - DevExt, - DeviceObject, - Stk->Parameters.DeviceIoControl.Type3InputBuffer, - Stk->Parameters.DeviceIoControl.InputBufferLength, - Irp); - break; - - default: - return FALSE; - } - - return TRUE; -} -#endif - -/* - * Runs the mouse IOCTL_INTERNAL dispatch. - * Returns NTSTATUS_INVALID_DEVICE_REQUEST if it doesn't handle this request - * so someone else can have a try at it. - */ -NTSTATUS STDCALL I8042InternalDeviceControlMouse(PDEVICE_OBJECT DeviceObject, PIRP Irp) -{ - PIO_STACK_LOCATION Stk; - PFDO_DEVICE_EXTENSION FdoDevExt = DeviceObject->DeviceExtension; - PDEVICE_EXTENSION DevExt = FdoDevExt->PortDevExt; - - DPRINT("InternalDeviceControl\n"); - - Irp->IoStatus.Information = 0; - Stk = IoGetCurrentIrpStackLocation(Irp); - - switch (Stk->Parameters.DeviceIoControl.IoControlCode) { - - case IOCTL_INTERNAL_MOUSE_CONNECT: - DPRINT("IOCTL_INTERNAL_MOUSE_CONNECT\n"); - if (Stk->Parameters.DeviceIoControl.InputBufferLength < - sizeof(CONNECT_DATA)) { - DPRINT1("Mouse IOCTL_INTERNAL_MOUSE_CONNECT " - "invalid buffer size\n"); - Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; - goto intcontfailure; - } - - if (!DevExt->MouseExists) { - Irp->IoStatus.Status = STATUS_DEVICE_NOT_CONNECTED; - goto intcontfailure; - } - - if (DevExt->MouseClaimed) { - DPRINT1("IOCTL_INTERNAL_MOUSE_CONNECT: " - "Mouse is already claimed\n"); - Irp->IoStatus.Status = STATUS_SHARING_VIOLATION; - goto intcontfailure; - } - - memcpy(&DevExt->MouseData, - Stk->Parameters.DeviceIoControl.Type3InputBuffer, - sizeof(CONNECT_DATA)); - DevExt->MouseHook.IsrWritePort = I8042IsrWritePortMouse; - DevExt->MouseHook.QueueMousePacket = - I8042QueueMousePacket; - DevExt->MouseHook.CallContext = DevExt; - - { - PIO_WORKITEM WorkItem; - PI8042_HOOK_WORKITEM WorkItemData; - - WorkItem = IoAllocateWorkItem(DeviceObject); - if (!WorkItem) { - DPRINT ("IOCTL_INTERNAL_MOUSE_CONNECT: " - "Can't allocate work item\n"); - Irp->IoStatus.Status = - STATUS_INSUFFICIENT_RESOURCES; - goto intcontfailure; - } - - WorkItemData = ExAllocatePoolWithTag( - NonPagedPool, - sizeof(I8042_HOOK_WORKITEM), - TAG_I8042); - if (!WorkItemData) { - DPRINT ("IOCTL_INTERNAL_MOUSE_CONNECT: " - "Can't allocate work item data\n"); - Irp->IoStatus.Status = - STATUS_INSUFFICIENT_RESOURCES; - IoFreeWorkItem(WorkItem); - goto intcontfailure; - } - WorkItemData->WorkItem = WorkItem; - WorkItemData->Target = - DevExt->MouseData.ClassDeviceObject; - WorkItemData->Irp = Irp; - - IoMarkIrpPending(Irp); - DevExt->MouseState = MouseResetting; - DevExt->MouseResetState = 1100; - IoQueueWorkItem(WorkItem, - I8042SendHookWorkItem, - DelayedWorkQueue, - WorkItemData); - - Irp->IoStatus.Status = STATUS_PENDING; - } - - break; - case IOCTL_INTERNAL_I8042_MOUSE_WRITE_BUFFER: - DPRINT("IOCTL_INTERNAL_I8042_MOUSE_WRITE_BUFFER\n"); - if (Stk->Parameters.DeviceIoControl.InputBufferLength < 1) { - Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; - goto intcontfailure; - } - if (!DevExt->MouseInterruptObject) { - Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY; - goto intcontfailure; - } - - IoMarkIrpPending(Irp); - IoStartPacket(DeviceObject, Irp, NULL, NULL); - Irp->IoStatus.Status = STATUS_PENDING; - - break; - case IOCTL_MOUSE_QUERY_ATTRIBUTES: - DPRINT("IOCTL_MOUSE_QUERY_ATTRIBUTES\n"); - if (Stk->Parameters.DeviceIoControl.InputBufferLength < - sizeof(MOUSE_ATTRIBUTES)) { - DPRINT("Mouse IOCTL_MOUSE_QUERY_ATTRIBUTES " - "invalid buffer size\n"); - Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; - goto intcontfailure; - } - memcpy(Irp->AssociatedIrp.SystemBuffer, - &DevExt->MouseAttributes, - sizeof(MOUSE_ATTRIBUTES)); - - Irp->IoStatus.Status = STATUS_SUCCESS; - break; - default: - Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; - break; - } - -intcontfailure: - return Irp->IoStatus.Status; -} - -BOOLEAN STDCALL I8042MouseEnable(PDEVICE_EXTENSION DevExt) -{ - UCHAR Value; - NTSTATUS Status; - - DPRINT("Enabling mouse\n"); - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_READ_MODE)) { - DPRINT1("Can't read i8042 mode\n"); - return FALSE; - } - - Status = I8042ReadDataWait(DevExt, &Value); - if (!NT_SUCCESS(Status)) { - DPRINT1("No response after read i8042 mode\n"); - return FALSE; - } - - Value &= ~(0x20); // don't disable mouse - Value |= 0x02; // enable mouse interrupts - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_WRITE_MODE)) { - DPRINT1("Can't set i8042 mode\n"); - return FALSE; - } - - if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) { - DPRINT1("Can't send i8042 mode\n"); - return FALSE; - } - - return TRUE; -} - -BOOLEAN STDCALL I8042MouseDisable(PDEVICE_EXTENSION DevExt) -{ - UCHAR Value; - NTSTATUS Status; - - DPRINT("Disabling mouse\n"); - - I8042Flush(); /* Just to be (kind of) sure */ - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_READ_MODE)) { - DPRINT1("Can't read i8042 mode\n"); - return FALSE; - } - - Status = I8042ReadDataWait(DevExt, &Value); - if (!NT_SUCCESS(Status)) { - DPRINT1("No response after read i8042 mode\n"); - return FALSE; - } - - Value |= 0x20; // don't disable mouse - Value &= ~(0x02); // enable mouse interrupts - - if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_WRITE_MODE)) { - DPRINT1("Can't set i8042 mode\n"); - return FALSE; - } - - if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) { - DPRINT1("Can't send i8042 mode\n"); - return FALSE; - } - - I8042Flush(); - /* Just to be (kind of) sure; if the mouse would - * say something while we are disabling it, these bytes would - * block the keyboard. - */ - - return TRUE; -} - -BOOLEAN STDCALL I8042DetectMouse(PDEVICE_EXTENSION DevExt) -{ - BOOLEAN Ok = TRUE; - NTSTATUS Status; - UCHAR Value; - UCHAR ExpectedReply[] = { 0xFA, 0xAA, 0x00 }; - unsigned ReplyByte; - - if (! I8042Write(DevExt, I8042_CTRL_PORT, 0xD4) || - ! I8042Write(DevExt, I8042_DATA_PORT, 0xFF)) - { - DPRINT1("Failed to write reset command to mouse\n"); - Ok = FALSE; - } - - for (ReplyByte = 0; - ReplyByte < sizeof(ExpectedReply) / sizeof(ExpectedReply[0]) && Ok; - ReplyByte++) - { - Status = I8042ReadDataWait(DevExt, &Value); - if (! NT_SUCCESS(Status)) - { - DPRINT1("No ACK after mouse reset, status 0x%08x\n", - Status); - Ok = FALSE; - } - else if (Value != ExpectedReply[ReplyByte]) - { - DPRINT1("Unexpected reply: 0x%02x (expected 0x%02x)\n", - Value, ExpectedReply[ReplyByte]); - Ok = FALSE; - } - } - - if (! Ok) - { - /* There is probably no mouse present. On some systems, - the probe locks the entire keyboard controller. Let's - try to get access to the keyboard again by sending a - reset */ - I8042Flush(); - I8042Write(DevExt, I8042_CTRL_PORT, KBD_SELF_TEST); - I8042ReadDataWait(DevExt, &Value); - I8042Flush(); - } - - DPRINT("Mouse %sdetected\n", Ok ? "" : "not "); - - return Ok; -} diff --git a/reactos/drivers/input/i8042prt/i8042prt/ps2pp.c b/reactos/drivers/input/i8042prt/i8042prt/ps2pp.c deleted file mode 100644 index 3b183ec8617..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt/ps2pp.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: drivers/input/i8042prt/ps2pp.c - * PURPOSE: i8042prt driver - * ps2pp protocol handling - * PROGRAMMER: Tinus - */ - -/* INCLUDES ****************************************************************/ - -#ifndef NDEBUG -#define NDEBUG -#endif -#include - -#include "i8042prt.h" - - -VOID I8042MouseHandlePs2pp(PDEVICE_EXTENSION DevExt, UCHAR Input) -{ - UCHAR PktType; - PMOUSE_INPUT_DATA MouseInput = DevExt->MouseBuffer + - DevExt->MouseInBuffer; - -/* First, collect 3 bytes for a packet - * We can detect out-of-sync only by checking - * the whole packet anyway. - * - * If bit 7 and 8 of the first byte are 0, its - * a normal packet. - * - * Otherwise, the packet is different, like this: - * 1: E 1 b3 b2 x x x x - * 2: x x b1 b0 x1 x0 1 0 - * 3: x x x x x x x1 x0 - * - * b3-0 form a code that specifies the packet type: - * - * 0 Device Type - * 1 Rollers and buttons - * 2 Reserved - * 3 Reserved - * 4 Device ID - * 5 Channel & Battery - * 6 Wireless notifications - * 7 Reserved - * 8 ShortID LSB (ShortID is a number that is supposed to differentiate - * 9 ShortID MSB between your mouse and your neighbours') - * 10 Reserved - * 11 Mouse capabilities - * 12 Remote control LSB - * 13 Remote control MSB - * 14 Reserved - * 15 Extended packet - */ - - switch (DevExt->MouseState) { - case MouseIdle: - case XMovement: - DevExt->MouseLogiBuffer[DevExt->MouseState] = Input; - DevExt->MouseState++; - break; - - case YMovement: - DevExt->MouseLogiBuffer[2] = Input; - DevExt->MouseState = MouseIdle; - - /* first check if it's a normal packet */ - - if (!(DevExt->MouseLogiBuffer[0] & 0xC0)) { - DevExt->MouseState = MouseIdle; - I8042MouseHandle(DevExt, DevExt->MouseLogiBuffer[0]); - I8042MouseHandle(DevExt, DevExt->MouseLogiBuffer[1]); - I8042MouseHandle(DevExt, DevExt->MouseLogiBuffer[2]); - /* We could care about wether MouseState really - * advances, but we don't need to because we're - * only doing three bytes anyway, so the packet - * will never complete if it's broken. - */ - return; - } - - /* sanity check */ - - if (((DevExt->MouseLogiBuffer[0] & 0x48) != 0x48) || - (((DevExt->MouseLogiBuffer[1] & 0x0C) >> 2) != - (DevExt->MouseLogiBuffer[2] & 0x03))) { - DPRINT1("Ps2pp packet fails sanity checks\n"); - return; - } - - /* Now get the packet type */ - - PktType = ((DevExt->MouseLogiBuffer[0] & 0x30) >> 4) & - ((DevExt->MouseLogiBuffer[1] & 0x30) >> 6); - - switch (PktType) { - case 0: - /* The packet contains the device ID, but we - * already read that in the initialization - * sequence. Ignore it. - */ - return; - case 1: - RtlZeroMemory(MouseInput, sizeof(MOUSE_INPUT_DATA)); - if (DevExt->MouseLogiBuffer[2] & 0x10) - MouseInput->RawButtons |= MOUSE_BUTTON_4_DOWN; - - if (DevExt->MouseLogiBuffer[2] & 0x20) - MouseInput->RawButtons |= MOUSE_BUTTON_5_DOWN; - - if (DevExt->MouseLogiBuffer[2] & 0x0F) { - MouseInput->ButtonFlags |= MOUSE_WHEEL; - if (DevExt->MouseLogiBuffer[2] & 0x08) - MouseInput->ButtonData = - (DevExt->MouseLogiBuffer[2] & 0x07) - - 8; - else - MouseInput->ButtonData = - DevExt->MouseLogiBuffer[2] & 0x07; - } - I8042MouseHandleButtons(DevExt, MOUSE_BUTTON_4_DOWN | - MOUSE_BUTTON_5_DOWN); - I8042QueueMousePacket( - DevExt->MouseObject); - return; - default: - /* These are for things that would probably - * be handled by logitechs own driver. - */ - return; - } - default: - DPRINT1("Unexpected input state for ps2pp!\n"); - } -} diff --git a/reactos/drivers/input/i8042prt/i8042prt/registry.c b/reactos/drivers/input/i8042prt/i8042prt/registry.c deleted file mode 100644 index 8c25872cd31..00000000000 --- a/reactos/drivers/input/i8042prt/i8042prt/registry.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: drivers/input/i8042prt/registry.c - * PURPOSE: i8042 (ps/2 keyboard-mouse controller) driver - * Reading the registry - * PROGRAMMER: Victor Kirhenshtein (sauros@iname.com) - * Jason Filby (jasonfilby@yahoo.com) - * Tinus - */ - -/* INCLUDES ****************************************************************/ - -#ifndef NDEBUG -#define NDEBUG -#endif -#include - -#include "i8042prt.h" - -/* FUNCTIONS *****************************************************************/ - -/* - * Read the registry keys associated with this device. The RegistryPath - * var is a hack. This should be more like what microsoft does, but I - * don't know exactly what they do except that it's a hack too... - */ -VOID STDCALL I8042ReadRegistry(PDRIVER_OBJECT DriverObject, - PDEVICE_EXTENSION DevExt) - -{ - RTL_QUERY_REGISTRY_TABLE Parameters[19]; - - NTSTATUS Status; - - ULONG DefaultHeadless = 0; - ULONG DefaultCrashScroll = 0; - ULONG DefaultCrashSysRq = 0; - ULONG DefaultReportResetErrors = 0; - ULONG DefaultPollStatusIterations = 1; - ULONG DefaultResendIterations = 3; - ULONG DefaultPollingIterations = 12000; - ULONG DefaultPollingIterationsMaximum = 12000; - ULONG DefaultKeyboardDataQueueSize = 100; - ULONG DefaultOverrideKeyboardType = 0; - ULONG DefaultOverrideKeyboardSubtype = 0; - ULONG DefaultMouseDataQueueSize = 100; - ULONG DefaultMouseResendStallTime = 1000; - ULONG DefaultMouseSynchIn100ns = 20000000; - ULONG DefaultMouseResolution = 3; - ULONG DefaultSampleRate = 60; - ULONG DefaultNumberOfButtons = 2; - ULONG DefaultEnableWheelDetection = 1; - - RtlZeroMemory(Parameters, sizeof(Parameters)); - - Parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[0].Name = L"Headless"; - Parameters[0].EntryContext = &DevExt->Settings.Headless; - Parameters[0].DefaultType = REG_DWORD; - Parameters[0].DefaultData = &DefaultHeadless; - Parameters[0].DefaultLength = sizeof(ULONG); - - Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[1].Name = L"CrashOnCtrlScroll"; - Parameters[1].EntryContext = &DevExt->Settings.CrashScroll; - Parameters[1].DefaultType = REG_DWORD; - Parameters[1].DefaultData = &DefaultCrashScroll; - Parameters[1].DefaultLength = sizeof(ULONG); - - Parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[2].Name = L"BreakOnSysRq"; - Parameters[2].EntryContext = &DevExt->Settings.CrashSysRq; - Parameters[2].DefaultType = REG_DWORD; - Parameters[2].DefaultData = &DefaultCrashSysRq; - Parameters[2].DefaultLength = sizeof(ULONG); - - Parameters[3].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[3].Name = L"ReportResetErrors"; - Parameters[3].EntryContext = &DevExt->Settings.ReportResetErrors; - Parameters[3].DefaultType = REG_DWORD; - Parameters[3].DefaultData = &DefaultReportResetErrors; - Parameters[3].DefaultLength = sizeof(ULONG); - - Parameters[4].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[4].Name = L"PollStatusIterations"; - Parameters[4].EntryContext = &DevExt->Settings.PollStatusIterations; - Parameters[4].DefaultType = REG_DWORD; - Parameters[4].DefaultData = &DefaultPollStatusIterations; - Parameters[4].DefaultLength = sizeof(ULONG); - - Parameters[5].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[5].Name = L"ResendIterations"; - Parameters[5].EntryContext = &DevExt->Settings.ResendIterations; - Parameters[5].DefaultType = REG_DWORD; - Parameters[5].DefaultData = &DefaultResendIterations; - Parameters[5].DefaultLength = sizeof(ULONG); - - Parameters[6].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[6].Name = L"PollingIterations"; - Parameters[6].EntryContext = &DevExt->Settings.PollingIterations; - Parameters[6].DefaultType = REG_DWORD; - Parameters[6].DefaultData = &DefaultPollingIterations; - Parameters[6].DefaultLength = sizeof(ULONG); - - Parameters[7].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[7].Name = L"PollingIterationsMaximum"; - Parameters[7].EntryContext = &DevExt->Settings.PollingIterationsMaximum; - Parameters[7].DefaultType = REG_DWORD; - Parameters[7].DefaultData = &DefaultPollingIterationsMaximum; - Parameters[7].DefaultLength = sizeof(ULONG); - - Parameters[8].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[8].Name = L"KeyboardDataQueueSize"; - Parameters[8].EntryContext = - &DevExt->KeyboardAttributes.InputDataQueueLength; - Parameters[8].DefaultType = REG_DWORD; - Parameters[8].DefaultData = &DefaultKeyboardDataQueueSize; - Parameters[8].DefaultLength = sizeof(ULONG); - - Parameters[9].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[9].Name = L"OverrideKeyboardType"; - Parameters[9].EntryContext = &DevExt->Settings.OverrideKeyboardType; - Parameters[9].DefaultType = REG_DWORD; - Parameters[9].DefaultData = &DefaultOverrideKeyboardType; - Parameters[9].DefaultLength = sizeof(ULONG); - - Parameters[10].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[10].Name = L"OverrideKeyboardSubtype"; - Parameters[10].EntryContext = &DevExt->Settings.OverrideKeyboardSubtype; - Parameters[10].DefaultType = REG_DWORD; - Parameters[10].DefaultData = &DefaultOverrideKeyboardSubtype; - Parameters[10].DefaultLength = sizeof(ULONG); - - Parameters[11].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[11].Name = L"MouseDataQueueSize"; - Parameters[11].EntryContext = - &DevExt->MouseAttributes.InputDataQueueLength; - Parameters[11].DefaultType = REG_DWORD; - Parameters[11].DefaultData = &DefaultMouseDataQueueSize; - Parameters[11].DefaultLength = sizeof(ULONG); - - Parameters[12].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[12].Name = L"MouseResendStallTime"; - Parameters[12].EntryContext = &DevExt->Settings.MouseResendStallTime; - Parameters[12].DefaultType = REG_DWORD; - Parameters[12].DefaultData = &DefaultMouseResendStallTime; - Parameters[12].DefaultLength = sizeof(ULONG); - - Parameters[13].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[13].Name = L"MouseSynchIn100ns"; - Parameters[13].EntryContext = &DevExt->Settings.MouseSynchIn100ns; - Parameters[13].DefaultType = REG_DWORD; - Parameters[13].DefaultData = &DefaultMouseSynchIn100ns; - Parameters[13].DefaultLength = sizeof(ULONG); - - Parameters[14].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[14].Name = L"MouseResolution"; - Parameters[14].EntryContext = &DevExt->Settings.MouseResolution; - Parameters[14].DefaultType = REG_DWORD; - Parameters[14].DefaultData = &DefaultMouseResolution; - Parameters[14].DefaultLength = sizeof(ULONG); - - Parameters[15].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[15].Name = L"SampleRate"; - Parameters[15].EntryContext = &DevExt->MouseAttributes.SampleRate; - Parameters[15].DefaultType = REG_DWORD; - Parameters[15].DefaultData = &DefaultSampleRate; - Parameters[15].DefaultLength = sizeof(ULONG); - - Parameters[16].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[16].Name = L"NumberOfButtons"; - Parameters[16].EntryContext = &DevExt->Settings.NumberOfButtons; - Parameters[16].DefaultType = REG_DWORD; - Parameters[16].DefaultData = &DefaultNumberOfButtons; - Parameters[16].DefaultLength = sizeof(ULONG); - - Parameters[17].Flags = RTL_QUERY_REGISTRY_DIRECT; - Parameters[17].Name = L"EnableWheelDetection"; - Parameters[17].EntryContext = &DevExt->Settings.EnableWheelDetection; - Parameters[17].DefaultType = REG_DWORD; - Parameters[17].DefaultData = &DefaultEnableWheelDetection; - Parameters[17].DefaultLength = sizeof(ULONG); - - Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, - I8042RegistryPath.Buffer, - Parameters, - NULL, - NULL); - - if (!NT_SUCCESS(Status)) { - /* Actually, the defaults are not set when the function - * fails, as would happen during setup, so you have to - * set them manually anyway... - */ - RTL_QUERY_REGISTRY_TABLE *Current = Parameters; - DPRINT1 ("Can't read registry: %x\n", Status); - while (Current->Name) { - *((PULONG)Current->EntryContext) = - *((PULONG)Current->DefaultData); - Current++; - } - DPRINT1 ("Manually set defaults\n"); - - } - - if (DevExt->Settings.MouseResolution > 3) - DevExt->Settings.MouseResolution = 3; - - DPRINT("Done reading registry\n"); -} diff --git a/reactos/drivers/input/i8042prt/keyboard.c b/reactos/drivers/input/i8042prt/keyboard.c deleted file mode 100644 index 132ef7bd1ae..00000000000 --- a/reactos/drivers/input/i8042prt/keyboard.c +++ /dev/null @@ -1,875 +0,0 @@ -/* - * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/input/i8042prt/keyboard.c - * PURPOSE: Keyboard specific functions - * PROGRAMMERS: Copyright Victor Kirhenshtein (sauros@iname.com) - Copyright Jason Filby (jasonfilby@yahoo.com) - Copyright Martijn Vernooij (o112w8r02@sneakemail.com) - Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) - */ - -/* INCLUDES ****************************************************************/ - -#include "i8042prt.h" - -#define NDEBUG -#include - -/* GLOBALS *******************************************************************/ - -/* This structure starts with the same layout as KEYBOARD_INDICATOR_TRANSLATION */ -typedef struct _LOCAL_KEYBOARD_INDICATOR_TRANSLATION { - USHORT NumberOfIndicatorKeys; - INDICATOR_LIST IndicatorList[3]; -} LOCAL_KEYBOARD_INDICATOR_TRANSLATION, *PLOCAL_KEYBOARD_INDICATOR_TRANSLATION; - -static LOCAL_KEYBOARD_INDICATOR_TRANSLATION IndicatorTranslation = { 3, { - {0x3A, KEYBOARD_CAPS_LOCK_ON}, - {0x45, KEYBOARD_NUM_LOCK_ON}, - {0x46, KEYBOARD_SCROLL_LOCK_ON}}}; - -/* FUNCTIONS *****************************************************************/ - -#ifdef __REACTOS__ -/* Debug stuff */ -VOID NTAPI -KdpServiceDispatcher(IN ULONG Code, IN PVOID Context1, IN PVOID Context2); -#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24)) - -static VOID NTAPI -i8042DebugWorkItem( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Context) -{ - PI8042_KEYBOARD_EXTENSION DeviceExtension; - ULONG Key; - - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context; - Key = InterlockedExchange((PLONG)&DeviceExtension->DebugKey, 0); - - DPRINT("Debug key: 0x%02x\n", Key); - - if (!Key) - return; - - /* We hope kernel would understand this. If - * that's not the case, nothing would happen. - */ - KdpServiceDispatcher(TAG('R', 'o', 's', ' '), (PVOID)Key, NULL); -} -#endif - -/* - * These functions are callbacks for filter driver custom interrupt - * service routines. - */ -/*static VOID NTAPI -i8042KbdIsrWritePort( - IN PVOID Context, - IN UCHAR Value) -{ - PI8042_KEYBOARD_EXTENSION DeviceExtension; - - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context; - - if (DeviceExtension->KeyboardHook.IsrWritePort) - { - DeviceExtension->KeyboardHook.IsrWritePort( - DeviceExtension->KeyboardHook.CallContext, - Value); - } - else - i8042IsrWritePort(Context, Value, 0); -}*/ - -static VOID NTAPI -i8042KbdQueuePacket( - IN PVOID Context) -{ - PI8042_KEYBOARD_EXTENSION DeviceExtension; - - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context; - - if (DeviceExtension->KeyboardHook.QueueKeyboardPacket) - { - DeviceExtension->KeyboardHook.QueueKeyboardPacket( - DeviceExtension->KeyboardHook.CallContext); - return; - } - - DeviceExtension->KeyComplete = TRUE; - DeviceExtension->KeysInBuffer++; - if (DeviceExtension->KeysInBuffer > DeviceExtension->Common.PortDeviceExtension->Settings.KeyboardDataQueueSize) - { - DPRINT1("Keyboard buffer overflow\n"); - DeviceExtension->KeysInBuffer--; - } - - DPRINT("Irq completes key\n"); - KeInsertQueueDpc(&DeviceExtension->DpcKeyboard, NULL, NULL); -} - -/* - * These functions are callbacks for filter driver custom - * initialization routines. - */ -NTSTATUS NTAPI -i8042SynchWritePortKbd( - IN PVOID Context, - IN UCHAR Value, - IN BOOLEAN WaitForAck) -{ - return i8042SynchWritePort( - (PPORT_DEVICE_EXTENSION)Context, - 0, - Value, - WaitForAck); -} - -/* - * Process the keyboard internal device requests - * returns FALSE if it doesn't understand the - * call so someone else can handle it. - */ -BOOLEAN -i8042KbdStartIo( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION Stack; - PI8042_KEYBOARD_EXTENSION DeviceExtension; - PPORT_DEVICE_EXTENSION PortDeviceExtension; - BOOLEAN Result = FALSE; - - Stack = IoGetCurrentIrpStackLocation(Irp); - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)DeviceObject->DeviceExtension; - PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; - - switch (Stack->Parameters.DeviceIoControl.IoControlCode) - { - case IOCTL_KEYBOARD_SET_INDICATORS: - { - DPRINT("IOCTL_KEYBOARD_SET_INDICATORS\n"); - - PortDeviceExtension->PacketBuffer[0] = KBD_CMD_SET_LEDS; - PortDeviceExtension->PacketBuffer[1] = 0; - if (DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_CAPS_LOCK_ON) - PortDeviceExtension->PacketBuffer[1] |= KBD_LED_CAPS; - - if (DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_NUM_LOCK_ON) - PortDeviceExtension->PacketBuffer[1] |= KBD_LED_NUM; - - if (DeviceExtension->KeyboardIndicators.LedFlags & KEYBOARD_SCROLL_LOCK_ON) - PortDeviceExtension->PacketBuffer[1] |= KBD_LED_SCROLL; - - i8042StartPacket( - PortDeviceExtension, - &DeviceExtension->Common, - PortDeviceExtension->PacketBuffer, - 2, - Irp); - break; - } - default: - { - DPRINT("Unknown ioctl code 0x%lx\n", - Stack->Parameters.DeviceIoControl.IoControlCode); - ASSERT(FALSE); - } - } - - return Result; -} - -static VOID -i8042PacketDpc( - IN PPORT_DEVICE_EXTENSION DeviceExtension) -{ - BOOLEAN FinishIrp = FALSE; - KIRQL Irql; - NTSTATUS Result = STATUS_INTERNAL_ERROR; /* Shouldn't happen */ - - /* If the interrupt happens before this is setup, the key - * was already in the buffer. Too bad! */ - if (!DeviceExtension->HighestDIRQLInterrupt) - return; - - Irql = KeAcquireInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt); - - if (DeviceExtension->Packet.State == Idle - && DeviceExtension->PacketComplete) - { - FinishIrp = TRUE; - Result = DeviceExtension->PacketResult; - DeviceExtension->PacketComplete = FALSE; - } - - KeReleaseInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt, Irql); - - if (!FinishIrp) - return; - - if (DeviceExtension->CurrentIrp) - { - DeviceExtension->CurrentIrp->IoStatus.Status = Result; - IoCompleteRequest(DeviceExtension->CurrentIrp, IO_NO_INCREMENT); - IoStartNextPacket(DeviceExtension->CurrentIrpDevice, FALSE); - DeviceExtension->CurrentIrp = NULL; - DeviceExtension->CurrentIrpDevice = NULL; - } -} - -static VOID NTAPI -i8042PowerWorkItem( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID Context) -{ - PI8042_KEYBOARD_EXTENSION DeviceExtension; - NTSTATUS Status; - - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context; - - /* See http://blogs.msdn.com/doronh/archive/2006/09/08/746961.aspx */ - - /* Register GUID_DEVICE_SYS_BUTTON interface and report capability */ - if (DeviceExtension->NewCaps != DeviceExtension->ReportedCaps) - { - if (DeviceExtension->PowerInterfaceName.MaximumLength == 0) - { - /* We have never registred this interface ; do it */ - Status = IoRegisterDeviceInterface( - DeviceExtension->Common.Pdo, - &GUID_DEVICE_SYS_BUTTON, - NULL, - &DeviceExtension->PowerInterfaceName); - if (!NT_SUCCESS(Status)) - { - /* We can't do more yet, ignore the keypress... */ - DPRINT("IoRegisterDeviceInterface(GUID_DEVICE_SYS_BUTTON) failed with status 0x%08lx\n", - Status); - DeviceExtension->PowerInterfaceName.MaximumLength = 0; - return; - } - } - else - { - /* Disable the interface. Once activated again, capabilities would be asked again */ - Status = IoSetDeviceInterfaceState( - &DeviceExtension->PowerInterfaceName, - FALSE); - if (!NT_SUCCESS(Status)) - { - /* Ignore the key press... */ - DPRINT("Disabling interface %wZ failed with status 0x%08lx\n", - &DeviceExtension->PowerInterfaceName, Status); - return; - } - } - /* Enable the interface. This leads to receving a IOCTL_GET_SYS_BUTTON_CAPS, - * so we can report new capability */ - Status = IoSetDeviceInterfaceState( - &DeviceExtension->PowerInterfaceName, - TRUE); - if (!NT_SUCCESS(Status)) - { - /* Ignore the key press... */ - DPRINT("Enabling interface %wZ failed with status 0x%08lx\n", - &DeviceExtension->PowerInterfaceName, Status); - return; - } - } - - /* Directly complete the IOCTL_GET_SYS_BUTTON_EVENT Irp (if any) */ - if (DeviceExtension->PowerIrp) - { - PULONG pEvent = (PULONG)DeviceExtension->PowerIrp->AssociatedIrp.SystemBuffer; - - DeviceExtension->PowerIrp->IoStatus.Status = STATUS_SUCCESS; - DeviceExtension->PowerIrp->IoStatus.Information = sizeof(ULONG); - *pEvent = DeviceExtension->LastPowerKey; - - IoCompleteRequest(DeviceExtension->PowerIrp, IO_NO_INCREMENT); - DeviceExtension->PowerIrp = NULL; - } -} - -/* Return TRUE if it was a power key */ -static BOOLEAN -HandlePowerKeys( - IN PI8042_KEYBOARD_EXTENSION DeviceExtension) -{ - PKEYBOARD_INPUT_DATA InputData; - ULONG KeyPress; - - InputData = DeviceExtension->KeyboardBuffer + DeviceExtension->KeysInBuffer - 1; - if (!(InputData->Flags & KEY_E0)) - return FALSE; - - if (InputData->Flags & KEY_BREAK) - /* We already took care of the key press */ - return TRUE; - - switch (InputData->MakeCode) - { - case 0x52: /* VK_INSERT */ - DPRINT1("FIXME: Remove debug code\n"); - case KEYBOARD_POWER_CODE: - KeyPress = SYS_BUTTON_POWER; - break; - case KEYBOARD_SLEEP_CODE: - KeyPress = SYS_BUTTON_SLEEP; - break; - - case KEYBOARD_WAKE_CODE: - KeyPress = SYS_BUTTON_WAKE; - break; - default: - return FALSE; - } - - /* Our work can only be done at passive level, so use a workitem */ - DeviceExtension->NewCaps |= KeyPress; - DeviceExtension->LastPowerKey = KeyPress; - IoQueueWorkItem( - DeviceExtension->PowerWorkItem, - &i8042PowerWorkItem, - DelayedWorkQueue, - DeviceExtension); - return TRUE; -} - -static VOID NTAPI -i8042KbdDpcRoutine( - IN PKDPC Dpc, - IN PVOID DeferredContext, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2) -{ - PI8042_KEYBOARD_EXTENSION DeviceExtension; - PPORT_DEVICE_EXTENSION PortDeviceExtension; - ULONG KeysTransferred = 0; - ULONG KeysInBufferCopy; - KIRQL Irql; - - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)DeferredContext; - PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; - - if (HandlePowerKeys(DeviceExtension)) - { - DeviceExtension->KeyComplete = FALSE; - return; - } - - i8042PacketDpc(PortDeviceExtension); - if (!DeviceExtension->KeyComplete) - return; - /* We got the interrupt as it was being enabled, too bad */ - if (!PortDeviceExtension->HighestDIRQLInterrupt) - return; - - Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt); - - DeviceExtension->KeyComplete = FALSE; - KeysInBufferCopy = DeviceExtension->KeysInBuffer; - - KeReleaseInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt, Irql); - -#ifdef __REACTOS__ - if (PortDeviceExtension->Settings.CrashOnCtrlScroll) - { - PKEYBOARD_INPUT_DATA InputData; - InputData = DeviceExtension->KeyboardBuffer + KeysInBufferCopy - 1; - - /* Test for TAB + key combination */ - if (InputData->MakeCode == 0x0F) - DeviceExtension->TabPressed = !(InputData->Flags & KEY_BREAK); - else if (DeviceExtension->TabPressed) - { - DeviceExtension->DebugKey = InputData->MakeCode; - DeviceExtension->TabPressed = FALSE; - - IoQueueWorkItem( - DeviceExtension->DebugWorkItem, - &i8042DebugWorkItem, - DelayedWorkQueue, - DeviceExtension); - } - } -#endif - - DPRINT("Send a key\n"); - - if (!DeviceExtension->KeyboardData.ClassService) - return; - - DPRINT("Sending %lu key(s)\n", KeysInBufferCopy); - (*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->KeyboardData.ClassService)( - DeviceExtension->KeyboardData.ClassDeviceObject, - DeviceExtension->KeyboardBuffer, - DeviceExtension->KeyboardBuffer + KeysInBufferCopy, - &KeysTransferred); - - Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt); - DeviceExtension->KeysInBuffer -= KeysTransferred; - KeReleaseInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt, Irql); -} - -#define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003) - -/* - * Runs the keyboard IOCTL dispatch. - */ -NTSTATUS -i8042KbdDeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION Stack; - PI8042_KEYBOARD_EXTENSION DeviceExtension; - NTSTATUS Status; - - Stack = IoGetCurrentIrpStackLocation(Irp); - Irp->IoStatus.Information = 0; - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)DeviceObject->DeviceExtension; - - switch (Stack->Parameters.DeviceIoControl.IoControlCode) - { - case IOCTL_GET_SYS_BUTTON_CAPS: - { - /* Part of GUID_DEVICE_SYS_BUTTON interface */ - PULONG pCaps; - DPRINT("IOCTL_GET_SYS_BUTTON_CAPS\n"); - - if (Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(ULONG)) - Status = STATUS_INVALID_PARAMETER; - else - { - pCaps = (PULONG)Irp->AssociatedIrp.SystemBuffer; - *pCaps = DeviceExtension->NewCaps; - DeviceExtension->ReportedCaps = DeviceExtension->NewCaps; - Irp->IoStatus.Information = sizeof(ULONG); - Status = STATUS_SUCCESS; - } - break; - } - case IOCTL_GET_SYS_BUTTON_EVENT: - { - /* Part of GUID_DEVICE_SYS_BUTTON interface */ - PIRP WaitingIrp; - DPRINT("IOCTL_GET_SYS_BUTTON_EVENT\n"); - - if (Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(ULONG)) - Status = STATUS_INVALID_PARAMETER; - else - { - /* FIXME: Race condition here: - * If an interrupt comes before we can mark the Irp - * as pending, it might be possible to complete the - * Irp before pending it, leading to a crash! */ - WaitingIrp = InterlockedCompareExchangePointer( - &DeviceExtension->PowerIrp, - Irp, - NULL); - /* Check if an Irp is already pending */ - if (WaitingIrp != NULL) - { - /* Unable to have a 2nd pending IRP for this IOCTL */ - DPRINT("Unable to pend a second IRP for IOCTL_GET_SYS_BUTTON_EVENT\n"); - Status = STATUS_INVALID_PARAMETER; - } - else - { - Status = STATUS_PENDING; - } - } - break; - } - default: - { - DPRINT("IRP_MJ_DEVICE_CONTROL / unknown ioctl code 0x%lx\n", - Stack->Parameters.DeviceIoControl.IoControlCode); - ASSERT(FALSE); - return ForwardIrpAndForget(DeviceObject, Irp); - } - } - - Irp->IoStatus.Status = Status; - if (Status == STATUS_PENDING) - IoMarkIrpPending(Irp); - else - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - /* Special case for IOCTL_GET_SYS_BUTTON_CAPS */ - if (Stack->Parameters.DeviceIoControl.IoControlCode == IOCTL_GET_SYS_BUTTON_CAPS - && DeviceExtension->PowerIrp) - { - /* Also complete the pending IOCTL_GET_SYS_BUTTON_EVENT Irp */ - PULONG pEvent = (PULONG)DeviceExtension->PowerIrp->AssociatedIrp.SystemBuffer; - - DeviceExtension->PowerIrp->IoStatus.Status = STATUS_SUCCESS; - DeviceExtension->PowerIrp->IoStatus.Information = sizeof(ULONG); - *pEvent = DeviceExtension->LastPowerKey; - DeviceExtension->LastPowerKey = 0; - - IoCompleteRequest(DeviceExtension->PowerIrp, IO_NO_INCREMENT); - DeviceExtension->PowerIrp = NULL; - } - return Status; -} - -/* - * Runs the keyboard IOCTL_INTERNAL dispatch. - */ -NTSTATUS -i8042KbdInternalDeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION Stack; - PI8042_KEYBOARD_EXTENSION DeviceExtension; - NTSTATUS Status; - - Stack = IoGetCurrentIrpStackLocation(Irp); - Irp->IoStatus.Information = 0; - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)DeviceObject->DeviceExtension; - - switch (Stack->Parameters.DeviceIoControl.IoControlCode) - { - case IOCTL_INTERNAL_KEYBOARD_CONNECT: - { - SIZE_T Size; - PIO_WORKITEM WorkItem = NULL; - PI8042_HOOK_WORKITEM WorkItemData = NULL; - - DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_KEYBOARD_CONNECT\n"); - if (Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(CONNECT_DATA)) - { - Status = STATUS_INVALID_PARAMETER; - goto cleanup; - } - - DeviceExtension->KeyboardData = - *((PCONNECT_DATA)Stack->Parameters.DeviceIoControl.Type3InputBuffer); - - /* Send IOCTL_INTERNAL_I8042_HOOK_KEYBOARD to device stack */ - WorkItem = IoAllocateWorkItem(DeviceObject); - if (!WorkItem) - { - DPRINT("IoAllocateWorkItem() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - WorkItemData = ExAllocatePool( - NonPagedPool, - sizeof(I8042_HOOK_WORKITEM)); - if (!WorkItemData) - { - DPRINT("ExAllocatePool() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - WorkItemData->WorkItem = WorkItem; - WorkItemData->Irp = Irp; - - /* Initialize extension */ - DeviceExtension->Common.Type = Keyboard; - Size = DeviceExtension->Common.PortDeviceExtension->Settings.KeyboardDataQueueSize * sizeof(KEYBOARD_INPUT_DATA); - DeviceExtension->KeyboardBuffer = ExAllocatePool( - NonPagedPool, - Size); - if (!DeviceExtension->KeyboardBuffer) - { - DPRINT("ExAllocatePool() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - RtlZeroMemory(DeviceExtension->KeyboardBuffer, Size); - KeInitializeDpc( - &DeviceExtension->DpcKeyboard, - i8042KbdDpcRoutine, - DeviceExtension); - DeviceExtension->PowerWorkItem = IoAllocateWorkItem(DeviceObject); - if (!DeviceExtension->PowerWorkItem) - { - DPRINT("IoAllocateWorkItem() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - DeviceExtension->DebugWorkItem = IoAllocateWorkItem(DeviceObject); - if (!DeviceExtension->DebugWorkItem) - { - DPRINT("IoAllocateWorkItem() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - DeviceExtension->Common.PortDeviceExtension->KeyboardExtension = DeviceExtension; - DeviceExtension->Common.PortDeviceExtension->Flags |= KEYBOARD_CONNECTED; - - IoMarkIrpPending(Irp); - IoQueueWorkItem(WorkItem, - i8042SendHookWorkItem, - DelayedWorkQueue, - WorkItemData); - Status = STATUS_PENDING; - break; - -cleanup: - if (DeviceExtension->KeyboardBuffer) - ExFreePool(DeviceExtension->KeyboardBuffer); - if (DeviceExtension->PowerWorkItem) - IoFreeWorkItem(DeviceExtension->PowerWorkItem); - if (DeviceExtension->DebugWorkItem) - IoFreeWorkItem(DeviceExtension->DebugWorkItem); - if (WorkItem) - IoFreeWorkItem(WorkItem); - if (WorkItemData) - ExFreePool(WorkItemData); - break; - } - case IOCTL_INTERNAL_KEYBOARD_DISCONNECT: - { - DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_KEYBOARD_DISCONNECT\n"); - /* MSDN says that operation is to implemented. - * To implement it, we just have to do: - * DeviceExtension->KeyboardData.ClassService = NULL; - */ - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_INTERNAL_I8042_HOOK_KEYBOARD: - { - DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_I8042_HOOK_KEYBOARD\n"); - /* Nothing to do here */ - Status = STATUS_SUCCESS; - break; - } - case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION: - { - DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION\n"); - - /* We should check the UnitID, but it's kind of pointless as - * all keyboards are supposed to have the same one - */ - if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION)) - { - Status = STATUS_BUFFER_TOO_SMALL; - } - else - { - RtlCopyMemory( - Irp->AssociatedIrp.SystemBuffer, - &IndicatorTranslation, - sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION)); - Irp->IoStatus.Information = sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION); - Status = STATUS_SUCCESS; - } - break; - } - case IOCTL_KEYBOARD_QUERY_INDICATORS: - { - DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_QUERY_INDICATORS\n"); - - if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS)) - { - Status = STATUS_BUFFER_TOO_SMALL; - } - else - { - RtlCopyMemory( - Irp->AssociatedIrp.SystemBuffer, - &DeviceExtension->KeyboardIndicators, - sizeof(KEYBOARD_INDICATOR_PARAMETERS)); - Irp->IoStatus.Information = sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION); - Status = STATUS_SUCCESS; - } - break; - } - case IOCTL_KEYBOARD_SET_INDICATORS: - { - DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_KEYBOARD_SET_INDICATORS\n"); - - if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS)) - { - Status = STATUS_BUFFER_TOO_SMALL; - } - else - { - RtlCopyMemory( - &DeviceExtension->KeyboardIndicators, - Irp->AssociatedIrp.SystemBuffer, - sizeof(KEYBOARD_INDICATOR_PARAMETERS)); - Status = STATUS_PENDING; - IoMarkIrpPending(Irp); - IoStartPacket(DeviceObject, Irp, NULL, NULL); - } - break; - } - default: - { - DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / unknown ioctl code 0x%lx\n", - Stack->Parameters.DeviceIoControl.IoControlCode); - ASSERT(FALSE); - return ForwardIrpAndForget(DeviceObject, Irp); - } - } - - Irp->IoStatus.Status = Status; - if (Status != STATUS_PENDING) - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return Status; -} - -/* - * Call the customization hook. The ToReturn parameter is about wether - * we should go on with the interrupt. The return value is what - * we should return (indicating to the system wether someone else - * should try to handle the interrupt) - */ -static BOOLEAN -i8042KbdCallIsrHook( - IN PI8042_KEYBOARD_EXTENSION DeviceExtension, - IN UCHAR Status, - IN UCHAR Input, - OUT PBOOLEAN ToReturn) -{ - BOOLEAN HookReturn, HookContinue; - - HookContinue = FALSE; - - if (DeviceExtension->KeyboardHook.IsrRoutine) - { - HookReturn = DeviceExtension->KeyboardHook.IsrRoutine( - DeviceExtension->KeyboardHook.Context, - DeviceExtension->KeyboardBuffer + DeviceExtension->KeysInBuffer, - &DeviceExtension->Common.PortDeviceExtension->Packet, - Status, - &Input, - &HookContinue, - &DeviceExtension->KeyboardScanState); - - if (!HookContinue) - { - *ToReturn = HookReturn; - return TRUE; - } - } - return FALSE; -} - -BOOLEAN NTAPI -i8042KbdInterruptService( - IN PKINTERRUPT Interrupt, - PVOID Context) -{ - PI8042_KEYBOARD_EXTENSION DeviceExtension; - PPORT_DEVICE_EXTENSION PortDeviceExtension; - PKEYBOARD_INPUT_DATA InputData; - ULONG Counter; - UCHAR PortStatus, Output; - BOOLEAN ToReturn = FALSE; - NTSTATUS Status; - - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context; - PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; - InputData = DeviceExtension->KeyboardBuffer + DeviceExtension->KeysInBuffer; - Counter = PortDeviceExtension->Settings.PollStatusIterations; - - while (Counter) - { - Status = i8042ReadStatus(PortDeviceExtension, &PortStatus); - if (!NT_SUCCESS(Status)) - { - DPRINT("i8042ReadStatus() failed with status 0x%08lx\n", Status); - return FALSE; - } - Status = i8042ReadKeyboardData(PortDeviceExtension, &Output); - if (NT_SUCCESS(Status)) - break; - KeStallExecutionProcessor(1); - Counter--; - } - if (Counter == 0) - { - DPRINT("Spurious i8042 keyboard interrupt\n"); - return FALSE; - } - - DPRINT("Got: 0x%02x\n", Output); - - if (PortDeviceExtension->Settings.CrashOnCtrlScroll) - { - /* Test for CTRL + SCROLL LOCK twice */ - static UCHAR ScanCodes[] = { 0x1d, 0x46, 0x46, 0 }; - - if (!(Output & 0x80)) - { - if ((Output & 0x7f) == ScanCodes[DeviceExtension->ComboPosition]) - { - DeviceExtension->ComboPosition++; - if (ScanCodes[DeviceExtension->ComboPosition] == 0) - KeBugCheck(MANUALLY_INITIATED_CRASH); - } - else if ((Output & 0x7f) == ScanCodes[0]) - DeviceExtension->ComboPosition = 1; - else - DeviceExtension->ComboPosition = 0; - } - } - - if (i8042KbdCallIsrHook(DeviceExtension, PortStatus, Output, &ToReturn)) - return ToReturn; - - if (i8042PacketIsr(PortDeviceExtension, Output)) - { - if (PortDeviceExtension->PacketComplete) - { - DPRINT("Packet complete\n"); - KeInsertQueueDpc(&DeviceExtension->DpcKeyboard, NULL, NULL); - } - DPRINT("Irq eaten by packet\n"); - return TRUE; - } - - DPRINT("Irq is keyboard input\n"); - - if (DeviceExtension->KeyboardScanState == Normal) - { - switch (Output) - { - case 0xe0: - DeviceExtension->KeyboardScanState = GotE0; - return TRUE; - case 0xe1: - DeviceExtension->KeyboardScanState = GotE1; - return TRUE; - default: - break; - } - } - - /* Update InputData */ - InputData->Flags = 0; - switch (DeviceExtension->KeyboardScanState) - { - case GotE0: - InputData->Flags |= KEY_E0; - break; - case GotE1: - InputData->Flags |= KEY_E1; - break; - default: - break; - } - DeviceExtension->KeyboardScanState = Normal; - if (Output & 0x80) - InputData->Flags |= KEY_BREAK; - else - InputData->Flags |= KEY_MAKE; - InputData->MakeCode = Output & 0x7f; - InputData->Reserved = 0; - - i8042KbdQueuePacket(DeviceExtension); - - return TRUE; -} diff --git a/reactos/drivers/input/i8042prt/misc.c b/reactos/drivers/input/i8042prt/misc.c deleted file mode 100644 index 82200c72d02..00000000000 --- a/reactos/drivers/input/i8042prt/misc.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/input/i8042prt/misc.c - * PURPOSE: Misceallenous operations - * PROGRAMMERS: Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) - */ - -/* INCLUDES ******************************************************************/ - -#include "i8042prt.h" - -#define NDEBUG -#include - -/* FUNCTIONS *****************************************************************/ - -static NTSTATUS NTAPI -ForwardIrpAndWaitCompletion( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PVOID Context) -{ - if (Irp->PendingReturned) - KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE); - return STATUS_MORE_PROCESSING_REQUIRED; -} - -NTSTATUS -ForwardIrpAndWait( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PDEVICE_OBJECT LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice; - KEVENT Event; - NTSTATUS Status; - - ASSERT(LowerDevice); - - KeInitializeEvent(&Event, NotificationEvent, FALSE); - IoCopyCurrentIrpStackLocationToNext(Irp); - - DPRINT("Calling lower device %p [%wZ]\n", LowerDevice, &LowerDevice->DriverObject->DriverName); - IoSetCompletionRoutine(Irp, ForwardIrpAndWaitCompletion, &Event, TRUE, TRUE, TRUE); - - Status = IoCallDriver(LowerDevice, Irp); - if (Status == STATUS_PENDING) - { - Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL); - if (NT_SUCCESS(Status)) - Status = Irp->IoStatus.Status; - } - - return Status; -} - -NTSTATUS NTAPI -ForwardIrpAndForget( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PDEVICE_OBJECT LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice; - - ASSERT(LowerDevice); - - IoSkipCurrentIrpStackLocation(Irp); - return IoCallDriver(LowerDevice, Irp); -} diff --git a/reactos/drivers/input/i8042prt/mouse.c b/reactos/drivers/input/i8042prt/mouse.c deleted file mode 100644 index 1d7d65070d1..00000000000 --- a/reactos/drivers/input/i8042prt/mouse.c +++ /dev/null @@ -1,1070 +0,0 @@ -/* - * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/input/i8042prt/mouse.c - * PURPOSE: Mouse specific functions - * PROGRAMMERS: Copyright Victor Kirhenshtein (sauros@iname.com) - Copyright Jason Filby (jasonfilby@yahoo.com) - Copyright Martijn Vernooij (o112w8r02@sneakemail.com) - Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) - */ - -/* INCLUDES ****************************************************************/ - -#include "i8042prt.h" - -#define NDEBUG -#include - -/* FUNCTIONS *****************************************************************/ - -/* - * These functions are callbacks for filter driver custom interrupt - * service routines. - */ -static VOID NTAPI -i8042MouIsrWritePort( - IN PVOID Context, - IN UCHAR Value) -{ - PI8042_MOUSE_EXTENSION DeviceExtension; - - DeviceExtension = (PI8042_MOUSE_EXTENSION)Context; - - if (DeviceExtension->MouseHook.IsrWritePort) - { - DeviceExtension->MouseHook.IsrWritePort( - DeviceExtension->MouseHook.CallContext, - Value); - } - else - i8042IsrWritePort(Context, Value, 0xD4); -} - -VOID NTAPI -i8042MouQueuePacket( - IN PVOID Context) -{ - PI8042_MOUSE_EXTENSION DeviceExtension; - - DeviceExtension = (PI8042_MOUSE_EXTENSION)Context; - - if (DeviceExtension->MouseHook.QueueMousePacket) - { - DeviceExtension->MouseHook.QueueMousePacket( - DeviceExtension->MouseHook.CallContext); - return; - } - - DeviceExtension->MouseComplete = TRUE; - DeviceExtension->MouseInBuffer++; - if (DeviceExtension->MouseInBuffer > DeviceExtension->Common.PortDeviceExtension->Settings.MouseDataQueueSize) - { - DPRINT1("Mouse buffer overflow\n"); - DeviceExtension->MouseInBuffer--; - } - - DPRINT("Irq completes mouse packet\n"); - KeInsertQueueDpc(&DeviceExtension->DpcMouse, NULL, NULL); -} - -VOID -i8042MouHandle( - IN PI8042_MOUSE_EXTENSION DeviceExtension, - IN UCHAR Output) -{ - PMOUSE_INPUT_DATA MouseInput; - CHAR Scroll; - - MouseInput = DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer; - - switch (DeviceExtension->MouseState) - { - case MouseIdle: - /* This bit should be 1, if not drop the packet, we - * might be lucky and get in sync again - */ - if (!(Output & 8)) { - DPRINT1("Bad input, dropping..\n"); - return; - } - - MouseInput->Buttons = 0; - MouseInput->RawButtons = 0; - MouseInput->Flags = MOUSE_MOVE_RELATIVE; - - /* Note how we ignore the overflow bits, like Windows - * is said to do. There's no reasonable thing to do - * anyway. - */ - - if (Output & 16) - MouseInput->LastX = 1; - else - MouseInput->LastX = 0; - if (Output & 32) - MouseInput->LastY = 1; - else - MouseInput->LastY = 0; - - if (Output & 1) - MouseInput->RawButtons |= MOUSE_LEFT_BUTTON_DOWN; - if (Output & 2) - MouseInput->RawButtons |= MOUSE_RIGHT_BUTTON_DOWN; - if (Output & 4) - MouseInput->RawButtons |= MOUSE_MIDDLE_BUTTON_DOWN; - - DeviceExtension->MouseState = XMovement; - break; - - case XMovement: - if (MouseInput->LastX) - MouseInput->LastX = (LONG) Output - 256; - else - MouseInput->LastX = Output; - - DeviceExtension->MouseState = YMovement; - break; - - case YMovement: - if (MouseInput->LastY) - MouseInput->LastY = (LONG)Output - 256; - else - MouseInput->LastY = (LONG)Output; - - /* Windows wants it the other way around */ - MouseInput->LastY = -MouseInput->LastY; - - if (DeviceExtension->MouseType == GenericPS2 || - DeviceExtension->MouseType == Ps2pp) - { - i8042MouHandleButtons( - DeviceExtension, - MOUSE_LEFT_BUTTON_DOWN | - MOUSE_RIGHT_BUTTON_DOWN | - MOUSE_MIDDLE_BUTTON_DOWN); - i8042MouQueuePacket(DeviceExtension); - DeviceExtension->MouseState = MouseIdle; - } - else - { - DeviceExtension->MouseState = ZMovement; - } - break; - - case ZMovement: - Scroll = Output & 0x0f; - if (Scroll & 8) - Scroll |= 0xf0; - - if (Scroll) - { - MouseInput->RawButtons |= MOUSE_WHEEL; - MouseInput->ButtonData = (USHORT)(Scroll * -WHEEL_DELTA); - } - - if (DeviceExtension->MouseType == IntellimouseExplorer) - { - if (Output & 16) - MouseInput->RawButtons |= MOUSE_BUTTON_4_DOWN; - if (Output & 32) - MouseInput->RawButtons |= MOUSE_BUTTON_5_DOWN; - } - i8042MouHandleButtons( - DeviceExtension, - MOUSE_LEFT_BUTTON_DOWN | - MOUSE_RIGHT_BUTTON_DOWN | - MOUSE_MIDDLE_BUTTON_DOWN | - MOUSE_BUTTON_4_DOWN | - MOUSE_BUTTON_5_DOWN); - i8042MouQueuePacket(DeviceExtension); - DeviceExtension->MouseState = MouseIdle; - break; - - default: - DPRINT1("Unexpected state 0x%u!\n", DeviceExtension->MouseState); - ASSERT(FALSE); - } -} - -/* - * Updates ButtonFlags according to RawButtons and a saved state; - * Only takes in account the bits that are set in Mask - */ -VOID -i8042MouHandleButtons( - IN PI8042_MOUSE_EXTENSION DeviceExtension, - IN USHORT Mask) -{ - PMOUSE_INPUT_DATA MouseInput; - USHORT NewButtonData; - USHORT ButtonDiff; - - MouseInput = DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer; - NewButtonData = (USHORT)(MouseInput->RawButtons & Mask); - ButtonDiff = (NewButtonData ^ DeviceExtension->MouseButtonState) & Mask; - - /* Note that the defines are such: - * MOUSE_LEFT_BUTTON_DOWN 1 - * MOUSE_LEFT_BUTTON_UP 2 - */ - MouseInput->ButtonFlags |= (NewButtonData & ButtonDiff) | - (((~(NewButtonData)) << 1) & (ButtonDiff << 1)) | - (MouseInput->RawButtons & 0xfc00); - - DPRINT("Left raw/up/down: %u/%u/%u\n", - MouseInput->RawButtons & MOUSE_LEFT_BUTTON_DOWN, - MouseInput->ButtonFlags & MOUSE_LEFT_BUTTON_DOWN, - MouseInput->ButtonFlags & MOUSE_LEFT_BUTTON_UP); - - DeviceExtension->MouseButtonState = - (DeviceExtension->MouseButtonState & ~Mask) | (NewButtonData & Mask); -} - -static NTSTATUS OldInitialization(PPORT_DEVICE_EXTENSION); /* FIXME */ - -/* Does lastest initializations for the mouse. This method - * is called just before connecting the interrupt. - */ -NTSTATUS -i8042MouInitialize( - IN PI8042_MOUSE_EXTENSION DeviceExtension) -{ - PPORT_DEVICE_EXTENSION PortDeviceExtension; - - PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; - -/* FIXME */ OldInitialization(PortDeviceExtension); - - return STATUS_SUCCESS; -} - -static VOID NTAPI -i8042MouDpcRoutine( - IN PKDPC Dpc, - IN PVOID DeferredContext, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2) -{ - PI8042_MOUSE_EXTENSION DeviceExtension; - PPORT_DEVICE_EXTENSION PortDeviceExtension; - ULONG MouseTransferred = 0; - ULONG MouseInBufferCopy; - KIRQL Irql; - LARGE_INTEGER Timeout; - - DeviceExtension = (PI8042_MOUSE_EXTENSION)DeferredContext; - PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; - - switch (DeviceExtension->MouseTimeoutState) - { - case TimeoutStart: - { - DeviceExtension->MouseTimeoutState = NoChange; - if (DeviceExtension->MouseTimeoutActive && - !KeCancelTimer(&DeviceExtension->TimerMouseTimeout)) - { - /* The timer fired already, give up */ - DeviceExtension->MouseTimeoutActive = FALSE; - return; - } - - Timeout.QuadPart = -15000000; /* 1.5 seconds, should be enough */ - - KeSetTimer( - &DeviceExtension->TimerMouseTimeout, - Timeout, - &DeviceExtension->DpcMouseTimeout); - DeviceExtension->MouseTimeoutActive = TRUE; - return; - } - - case TimeoutCancel: - { - DeviceExtension->MouseTimeoutState = NoChange; - KeCancelTimer(&DeviceExtension->TimerMouseTimeout); - DeviceExtension->MouseTimeoutActive = FALSE; - } - - default: - ;/* nothing, don't want a warning */ - } - - /* Should be unlikely */ - if (!DeviceExtension->MouseComplete) - return; - - Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt); - - DeviceExtension->MouseComplete = FALSE; - MouseInBufferCopy = DeviceExtension->MouseInBuffer; - - KeReleaseInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt, Irql); - - DPRINT("Send a mouse packet\n"); - - if (!DeviceExtension->MouseData.ClassService) - return; - - DPRINT("Sending %lu mouse move(s)\n", MouseInBufferCopy); - (*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->MouseData.ClassService)( - DeviceExtension->MouseData.ClassDeviceObject, - DeviceExtension->MouseBuffer, - DeviceExtension->MouseBuffer + MouseInBufferCopy, - &MouseTransferred); - - Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt); - DeviceExtension->MouseInBuffer -= MouseTransferred; - if (DeviceExtension->MouseInBuffer) - RtlMoveMemory( - DeviceExtension->MouseBuffer, - DeviceExtension->MouseBuffer + MouseTransferred, - DeviceExtension->MouseInBuffer * sizeof(MOUSE_INPUT_DATA)); - KeReleaseInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt, Irql); -} - -/* This timer DPC will be called when the mouse reset times out. - * I'll just send the 'disable mouse port' command to the controller - * and say the mouse doesn't exist. - */ -static VOID NTAPI -i8042DpcRoutineMouseTimeout( - IN PKDPC Dpc, - IN PVOID DeferredContext, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2) -{ - PI8042_MOUSE_EXTENSION DeviceExtension; - PPORT_DEVICE_EXTENSION PortDeviceExtension; - KIRQL Irql; - - DeviceExtension = (PI8042_MOUSE_EXTENSION)DeferredContext; - PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; - - Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt); - - DPRINT1("Mouse initialization timeout! (substate %x). Disabling mouse.\n", - DeviceExtension->MouseResetState); - - i8042Flush(PortDeviceExtension); - i8042ChangeMode(PortDeviceExtension, CCB_MOUSE_INT_ENAB, CCB_MOUSE_DISAB); - i8042Flush(PortDeviceExtension); - - PortDeviceExtension->Flags &= ~MOUSE_PRESENT; - - KeReleaseInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt, Irql); -} - -/* - * Runs the mouse IOCTL_INTERNAL dispatch. - */ -NTSTATUS -i8042MouInternalDeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION Stack; - PI8042_MOUSE_EXTENSION DeviceExtension; - NTSTATUS Status; - - Stack = IoGetCurrentIrpStackLocation(Irp); - Irp->IoStatus.Information = 0; - DeviceExtension = (PI8042_MOUSE_EXTENSION)DeviceObject->DeviceExtension; - - switch (Stack->Parameters.DeviceIoControl.IoControlCode) - { - case IOCTL_INTERNAL_MOUSE_CONNECT: - { - SIZE_T Size; - PIO_WORKITEM WorkItem = NULL; - PI8042_HOOK_WORKITEM WorkItemData = NULL; - - DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_MOUSE_CONNECT\n"); - if (Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(CONNECT_DATA)) - { - Status = STATUS_INVALID_PARAMETER; - goto cleanup; - } - - DeviceExtension->MouseData = - *((PCONNECT_DATA)Stack->Parameters.DeviceIoControl.Type3InputBuffer); - - /* Send IOCTL_INTERNAL_I8042_HOOK_MOUSE to device stack */ - WorkItem = IoAllocateWorkItem(DeviceObject); - if (!WorkItem) - { - DPRINT("IoAllocateWorkItem() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - WorkItemData = ExAllocatePool( - NonPagedPool, - sizeof(I8042_HOOK_WORKITEM)); - if (!WorkItemData) - { - DPRINT("ExAllocatePool() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - WorkItemData->WorkItem = WorkItem; - WorkItemData->Irp = Irp; - - /* Initialize extension */ - DeviceExtension->Common.Type = Mouse; - Size = DeviceExtension->Common.PortDeviceExtension->Settings.MouseDataQueueSize * sizeof(MOUSE_INPUT_DATA); - DeviceExtension->MouseBuffer = ExAllocatePool( - NonPagedPool, - Size); - if (!DeviceExtension->MouseBuffer) - { - DPRINT("ExAllocatePool() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - RtlZeroMemory(DeviceExtension->MouseBuffer, Size); - DeviceExtension->MouseAttributes.InputDataQueueLength = - DeviceExtension->Common.PortDeviceExtension->Settings.MouseDataQueueSize; - KeInitializeDpc( - &DeviceExtension->DpcMouse, - i8042MouDpcRoutine, - DeviceExtension); - KeInitializeDpc( - &DeviceExtension->DpcMouseTimeout, - i8042DpcRoutineMouseTimeout, - DeviceExtension); - KeInitializeTimer(&DeviceExtension->TimerMouseTimeout); - DeviceExtension->Common.PortDeviceExtension->MouseExtension = DeviceExtension; - DeviceExtension->Common.PortDeviceExtension->Flags |= MOUSE_CONNECTED; - - IoMarkIrpPending(Irp); - IoQueueWorkItem(WorkItem, - i8042SendHookWorkItem, - DelayedWorkQueue, - WorkItemData); - Status = STATUS_PENDING; - break; - -cleanup: - if (DeviceExtension->MouseBuffer) - ExFreePool(DeviceExtension->MouseBuffer); - if (WorkItem) - IoFreeWorkItem(WorkItem); - if (WorkItemData) - ExFreePool(WorkItemData); - break; - } - case IOCTL_INTERNAL_MOUSE_DISCONNECT: - { - DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_MOUSE_DISCONNECT\n"); - /* MSDN says that operation is to implemented. - * To implement it, we just have to do: - * DeviceExtension->MouseData.ClassService = NULL; - */ - Status = STATUS_NOT_IMPLEMENTED; - break; - } - case IOCTL_INTERNAL_I8042_HOOK_MOUSE: - { - DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_I8042_HOOK_MOUSE\n"); - /* Nothing to do here */ - Status = STATUS_SUCCESS; - break; - } - default: - { - DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / unknown ioctl code 0x%lx\n", - Stack->Parameters.DeviceIoControl.IoControlCode); - ASSERT(FALSE); - return ForwardIrpAndForget(DeviceObject, Irp); - } - } - - Irp->IoStatus.Status = Status; - if (Status != STATUS_PENDING) - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return Status; -} - -/* Test if packets are taking too long to come in. If they do, we - * might have gotten out of sync and should just drop what we have. - * - * If we want to be totally right, we'd also have to keep a count of - * errors, and totally reset the mouse after too much of them (can - * happen if the user is using a KVM switch and an OS on another port - * resets the mouse, or if the user hotplugs the mouse, or if we're just - * generally unlucky). Also note the input parsing routine where we - * drop invalid input packets. - */ -static VOID -i8042MouInputTestTimeout( - IN PI8042_MOUSE_EXTENSION DeviceExtension) -{ - ULARGE_INTEGER Now; - - if (DeviceExtension->MouseState == MouseExpectingACK || - DeviceExtension->MouseState == MouseResetting) - return; - - Now.QuadPart = KeQueryInterruptTime(); - - if (DeviceExtension->MouseState != MouseIdle) { - /* Check if the last byte came too long ago */ - if (Now.QuadPart - DeviceExtension->MousePacketStartTime.QuadPart > - DeviceExtension->Common.PortDeviceExtension->Settings.MouseSynchIn100ns) - { - DPRINT("Mouse input packet timeout\n"); - DeviceExtension->MouseState = MouseIdle; - } - } - - if (DeviceExtension->MouseState == MouseIdle) - DeviceExtension->MousePacketStartTime.QuadPart = Now.QuadPart; -} - -/* - * Call the customization hook. The ToReturn parameter is about wether - * we should go on with the interrupt. The return value is what - * we should return (indicating to the system wether someone else - * should try to handle the interrupt) - */ -static BOOLEAN -i8042MouCallIsrHook( - IN PI8042_MOUSE_EXTENSION DeviceExtension, - IN UCHAR Status, - IN UCHAR Input, - OUT PBOOLEAN ToReturn) -{ - BOOLEAN HookReturn, HookContinue; - - HookContinue = FALSE; - - if (DeviceExtension->MouseHook.IsrRoutine) - { - DPRINT1("IsrRoutine(%p %p %p 0x%x 0x%x %p %lu %lu)\n", - DeviceExtension->MouseHook.Context, DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer, - &DeviceExtension->Common.PortDeviceExtension->Packet, Status, &Input, &HookContinue, - DeviceExtension->MouseState, DeviceExtension->MouseResetState); - HookReturn = DeviceExtension->MouseHook.IsrRoutine( - DeviceExtension->MouseHook.Context, - DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer, - &DeviceExtension->Common.PortDeviceExtension->Packet, - Status, - &Input, - &HookContinue, - &DeviceExtension->MouseState, - &DeviceExtension->MouseResetState); - DPRINT1("IsrRoutine(%p %p %p 0x%x 0x%x %p %lu %lu)\n", - DeviceExtension->MouseHook.Context, DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer, - &DeviceExtension->Common.PortDeviceExtension->Packet, Status, &Input, &HookContinue, - DeviceExtension->MouseState, DeviceExtension->MouseResetState); - - if (!HookContinue) - { - *ToReturn = HookReturn; - return TRUE; - } - } - return FALSE; -} - -static BOOLEAN -i8042MouResetIsr( - IN PI8042_MOUSE_EXTENSION DeviceExtension, - IN UCHAR Status, - IN UCHAR Value) -{ - PPORT_DEVICE_EXTENSION PortDeviceExtension; - BOOLEAN ToReturn = FALSE; - - if (i8042MouCallIsrHook(DeviceExtension, Status, Value, &ToReturn)) - return ToReturn; - - if (MouseResetting != DeviceExtension->MouseState) - return FALSE; - DeviceExtension->MouseTimeoutState = TimeoutStart; - PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; - - switch (DeviceExtension->MouseResetState) - { - case 1100: /* the first ack, drop it. */ - DeviceExtension->MouseResetState = ExpectingReset; - return TRUE; - case ExpectingReset: - /* First, 0xFF is sent. The mouse is supposed to say AA00 if ok, FC00 if not. */ - if (0xAA == Value) - { - DeviceExtension->MouseResetState++; - } - else - { - PortDeviceExtension->Flags &= ~MOUSE_PRESENT; - DeviceExtension->MouseState = MouseIdle; - DPRINT("Mouse returned bad reset reply: %x (expected aa)\n", Value); - } - return TRUE; - case ExpectingResetId: - if (0x00 == Value) - { - DeviceExtension->MouseResetState++; - DeviceExtension->MouseType = GenericPS2; - i8042MouIsrWritePort(PortDeviceExtension, 0xF2); - } - else - { - PortDeviceExtension->Flags &= ~MOUSE_PRESENT; - DeviceExtension->MouseState = MouseIdle; - DPRINT1("Mouse returned bad reset reply part two: %x (expected 0)\n", Value); - } - return TRUE; - case ExpectingGetDeviceIdACK: - if (MOUSE_ACK == Value) - { - DeviceExtension->MouseResetState++; - } - else if (MOUSE_NACK == Value || MOUSE_ERROR == Value) - { - DeviceExtension->MouseResetState++; - /* Act as if 00 (normal mouse) was received */ - DPRINT("Mouse doesn't support 0xd2, (returns %x, expected %x), faking\n", Value, MOUSE_ACK); - i8042MouResetIsr(DeviceExtension, Status, 0); - } - return TRUE; - case ExpectingGetDeviceIdValue: - switch (Value) - { - case 0x02: - DeviceExtension->MouseAttributes.MouseIdentifier = - BALLPOINT_I8042_HARDWARE; - break; - case 0x03: - case 0x04: - DeviceExtension->MouseAttributes.MouseIdentifier = - WHEELMOUSE_I8042_HARDWARE; - break; - default: - DeviceExtension->MouseAttributes.MouseIdentifier = - MOUSE_I8042_HARDWARE; - } - DeviceExtension->MouseResetState++; - i8042MouIsrWritePort(PortDeviceExtension, 0xE8); - return TRUE; - case ExpectingSetResolutionDefaultACK: - DeviceExtension->MouseResetState++; - i8042MouIsrWritePort(PortDeviceExtension, 0x00); - return TRUE; - case ExpectingSetResolutionDefaultValueACK: - DeviceExtension->MouseResetState = ExpectingSetScaling1to1ACK; - i8042MouIsrWritePort(PortDeviceExtension, 0xE6); - return TRUE; - case ExpectingSetScaling1to1ACK: - case ExpectingSetScaling1to1ACK2: - DeviceExtension->MouseResetState++; - i8042MouIsrWritePort(PortDeviceExtension, 0xE6); - return TRUE; - case ExpectingSetScaling1to1ACK3: - DeviceExtension->MouseResetState++; - i8042MouIsrWritePort(PortDeviceExtension, 0xE9); - return TRUE; - case ExpectingReadMouseStatusACK: - DeviceExtension->MouseResetState++; - return TRUE; - case ExpectingReadMouseStatusByte1: - DeviceExtension->MouseLogiBuffer[0] = Value; - DeviceExtension->MouseResetState++; - return TRUE; - case ExpectingReadMouseStatusByte2: - DeviceExtension->MouseLogiBuffer[1] = Value; - DeviceExtension->MouseResetState++; - return TRUE; - case ExpectingReadMouseStatusByte3: - DeviceExtension->MouseLogiBuffer[2] = Value; - /* Now MouseLogiBuffer is a set of info. If the second - * byte is 0, the mouse didn't understand the magic - * code. Otherwise, it it a Logitech and the second byte - * is the number of buttons, bit 7 of the first byte tells - * if it understands special E7 commands, the rest is an ID. - */ - if (DeviceExtension->MouseLogiBuffer[1]) - { - DeviceExtension->MouseAttributes.NumberOfButtons = - DeviceExtension->MouseLogiBuffer[1]; - DeviceExtension->MouseType = Ps2pp; - i8042MouIsrWritePort(PortDeviceExtension, 0xF3); - DeviceExtension->MouseResetState = ExpectingSetSamplingRateACK; - /* TODO: Go through EnableWheel and Enable5Buttons */ - return TRUE; - } - DeviceExtension->MouseResetState = EnableWheel; - i8042MouResetIsr(DeviceExtension, Status, Value); - return TRUE; - case EnableWheel: - i8042MouIsrWritePort(PortDeviceExtension, 0xF3); - DeviceExtension->MouseResetState = 1001; - return TRUE; - case 1001: - i8042MouIsrWritePort(PortDeviceExtension, 0xC8); - DeviceExtension->MouseResetState++; - return TRUE; - case 1002: - case 1004: - i8042MouIsrWritePort(PortDeviceExtension, 0xF3); - DeviceExtension->MouseResetState++; - return TRUE; - case 1003: - i8042MouIsrWritePort(PortDeviceExtension, 0x64); - DeviceExtension->MouseResetState++; - return TRUE; - case 1005: - i8042MouIsrWritePort(PortDeviceExtension, 0x50); - DeviceExtension->MouseResetState++; - return TRUE; - case 1006: - i8042MouIsrWritePort(PortDeviceExtension, 0xF2); - DeviceExtension->MouseResetState++; - return TRUE; - case 1007: - /* Ignore ACK */ - DeviceExtension->MouseResetState++; - return TRUE; - case 1008: - if (0x03 == Value) { - /* It's either an Intellimouse or Intellimouse Explorer. */ - DeviceExtension->MouseAttributes.NumberOfButtons = 3; - DeviceExtension->MouseAttributes.MouseIdentifier = - WHEELMOUSE_I8042_HARDWARE; - DeviceExtension->MouseType = Intellimouse; - DeviceExtension->MouseResetState = Enable5Buttons; - i8042MouResetIsr(DeviceExtension, Status, Value); - } - else - { - /* Just set the default settings and be done */ - i8042MouIsrWritePort(PortDeviceExtension, 0xF3); - DeviceExtension->MouseResetState = ExpectingSetSamplingRateACK; - } - return TRUE; - case Enable5Buttons: - i8042MouIsrWritePort(PortDeviceExtension, 0xF3); - DeviceExtension->MouseResetState = 1021; - return TRUE; - case 1022: - case 1024: - i8042MouIsrWritePort(PortDeviceExtension, 0xF3); - DeviceExtension->MouseResetState++; - return TRUE; - case 1021: - case 1023: - i8042MouIsrWritePort(PortDeviceExtension, 0xC8); - DeviceExtension->MouseResetState++; - return TRUE; - case 1025: - i8042MouIsrWritePort(PortDeviceExtension, 0x50); - DeviceExtension->MouseResetState++; - return TRUE; - case 1026: - i8042MouIsrWritePort(PortDeviceExtension, 0xF2); - DeviceExtension->MouseResetState++; - return TRUE; - case 1027: - if (0x04 == Value) - { - DeviceExtension->MouseAttributes.NumberOfButtons = 5; - DeviceExtension->MouseAttributes.MouseIdentifier = - WHEELMOUSE_I8042_HARDWARE; - DeviceExtension->MouseType = IntellimouseExplorer; - } - i8042MouIsrWritePort(PortDeviceExtension, 0xF3); - DeviceExtension->MouseResetState = ExpectingSetSamplingRateACK; - return TRUE; - case ExpectingSetSamplingRateACK: - i8042MouIsrWritePort(PortDeviceExtension, - (UCHAR)DeviceExtension->MouseAttributes.SampleRate); - DeviceExtension->MouseResetState++; - return TRUE; - case ExpectingSetSamplingRateValueACK: - if (MOUSE_NACK == Value) - { - i8042MouIsrWritePort(PortDeviceExtension, 0x3C); - DeviceExtension->MouseAttributes.SampleRate = PortDeviceExtension->Settings.SampleRate; - DeviceExtension->MouseResetState = 1040; - return TRUE; - } - case 1040: /* Fallthrough */ - i8042MouIsrWritePort(PortDeviceExtension, 0xE8); - DeviceExtension->MouseResetState = ExpectingFinalResolutionACK; - return TRUE; - case ExpectingFinalResolutionACK: - i8042MouIsrWritePort(PortDeviceExtension, - (UCHAR)(PortDeviceExtension->Settings.MouseResolution & 0xff)); - DPRINT("Mouse resolution %lu\n", - PortDeviceExtension->Settings.MouseResolution); - DeviceExtension->MouseResetState = ExpectingFinalResolutionValueACK; - return TRUE; - case ExpectingFinalResolutionValueACK: - i8042MouIsrWritePort(PortDeviceExtension, 0xF4); - DeviceExtension->MouseResetState = ExpectingEnableACK; - return TRUE; - case ExpectingEnableACK: - DeviceExtension->MouseState = MouseIdle; - DeviceExtension->MouseTimeoutState = TimeoutCancel; - DPRINT("Mouse type = %u\n", DeviceExtension->MouseType); - return TRUE; - default: - if (DeviceExtension->MouseResetState < 100 || DeviceExtension->MouseResetState > 999) - DPRINT1("MouseResetState went out of range: %lu\n", DeviceExtension->MouseResetState); - return FALSE; - } -} - -BOOLEAN NTAPI -i8042MouInterruptService( - IN PKINTERRUPT Interrupt, - PVOID Context) -{ - PI8042_MOUSE_EXTENSION DeviceExtension; - PPORT_DEVICE_EXTENSION PortDeviceExtension; - ULONG Counter; - UCHAR Output, PortStatus; - NTSTATUS Status; - - DeviceExtension = (PI8042_MOUSE_EXTENSION)Context; - PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; - Counter = PortDeviceExtension->Settings.PollStatusIterations; - - while (Counter) - { - Status = i8042ReadStatus(PortDeviceExtension, &PortStatus); - if (!NT_SUCCESS(Status)) - { - DPRINT("i8042ReadStatus() failed with status 0x%08lx\n", Status); - return FALSE; - } - Status = i8042ReadMouseData(PortDeviceExtension, &Output); - if (NT_SUCCESS(Status)) - break; - KeStallExecutionProcessor(1); - Counter--; - } - if (Counter == 0) - { - DPRINT("Spurious i8042 mouse interrupt\n"); - return FALSE; - } - - DPRINT("Got: 0x%02x\n", Output); - - if (i8042PacketIsr(PortDeviceExtension, Output)) - { - if (PortDeviceExtension->PacketComplete) - { - DPRINT("Packet complete\n"); - KeInsertQueueDpc(&DeviceExtension->DpcMouse, NULL, NULL); - } - DPRINT("Irq eaten by packet\n"); - return TRUE; - } - - DPRINT("Irq is mouse input\n"); - - i8042MouInputTestTimeout(DeviceExtension); - - if (i8042MouResetIsr(DeviceExtension, PortStatus, Output)) - { - DPRINT("Handled by ResetIsr or hooked Isr\n"); - if (NoChange != DeviceExtension->MouseTimeoutState) { - KeInsertQueueDpc(&DeviceExtension->DpcMouse, NULL, NULL); - } - return TRUE; - } - - if (DeviceExtension->MouseType == Ps2pp) - i8042MouHandlePs2pp(DeviceExtension, Output); - else - i8042MouHandle(DeviceExtension, Output); - - return TRUE; -} - -/* ================================================ - * FIXME: this part is taken from psaux.sys driver, - * and doesn't follow the coding style of this file - * ===============================================*/ - -#define CONTROLLER_COMMAND_MOUSE_ENABLE 0xA8 -#define PSMOUSE_CMD_ENABLE 0x00f4 -#define PSMOUSE_CMD_GETID (0x0200 | MOU_CMD_GET_ID) -#define PSMOUSE_CMD_RESET_BAT (0x0200 | MOU_CMD_RESET) -#define PSMOUSE_RET_ACK MOUSE_ACK -#define PSMOUSE_RET_NAK MOUSE_NACK -#define MOUSE_INTERRUPTS_ON (CCB_TRANSLATE | \ - CCB_SYSTEM_FLAG | \ - CCB_MOUSE_INT_ENAB) - -typedef struct _I8042_MOUSE_EXTENSION_OLD -{ - PPORT_DEVICE_EXTENSION PortDeviceExtension; - UCHAR pkt[8]; - UCHAR ack; - UINT RepliesExpected; -} I8042_MOUSE_EXTENSION_OLD, *PI8042_MOUSE_EXTENSION_OLD; - -/* Sends a byte to the mouse */ -static INT SendByte( - IN PI8042_MOUSE_EXTENSION_OLD DeviceExtension, - IN UCHAR byte) -{ - INT timeout = 100; /* 100 msec */ - UCHAR scancode; - LARGE_INTEGER Millisecond_Timeout; - - Millisecond_Timeout.QuadPart = -10000L; - - DeviceExtension->ack = 0; - - i8042IsrWritePort(DeviceExtension->PortDeviceExtension, byte, CTRL_WRITE_MOUSE); - while ((DeviceExtension->ack == 0) && timeout--) - { - if (i8042ReadKeyboardData(DeviceExtension->PortDeviceExtension, &scancode)) - { - switch(scancode) - { - case PSMOUSE_RET_ACK: - DeviceExtension->ack = 1; - break; - case PSMOUSE_RET_NAK: - DeviceExtension->ack = -1; - break; - default: - DeviceExtension->ack = 1; /* Workaround for mice which don't ACK the Get ID command */ - if (DeviceExtension->RepliesExpected) - DeviceExtension->pkt[--DeviceExtension->RepliesExpected] = scancode; - break; - } - return (INT)(-(DeviceExtension->ack <= 0)); - } - KeDelayExecutionThread(KernelMode, FALSE, &Millisecond_Timeout); - } - return (INT)(-(DeviceExtension->ack <= 0)); -} - -/* Send a PS/2 command to the mouse. */ -static INT SendCommand( - IN PI8042_MOUSE_EXTENSION_OLD DeviceExtension, - IN PUCHAR param, - IN INT command) -{ - LARGE_INTEGER Millisecond_Timeout; - UCHAR scancode; - INT timeout = 500; /* 500 msec */ - UCHAR send = (command >> 12) & 0xf; - UCHAR receive = (command >> 8) & 0xf; - UCHAR i; - - Millisecond_Timeout.QuadPart = -10000L; - - DeviceExtension->RepliesExpected = receive; - if (command == PSMOUSE_CMD_RESET_BAT) - timeout = 2000; /* 2 sec */ - - if (command & 0xff) - if (SendByte(DeviceExtension, command & 0xff)) - return (INT)(DeviceExtension->RepliesExpected = 0) - 1; - - for (i = 0; i < send; i++) - if (SendByte(DeviceExtension, param[i])) - return (INT)(DeviceExtension->RepliesExpected = 0) - 1; - - while (DeviceExtension->RepliesExpected && timeout--) - { - if (DeviceExtension->RepliesExpected == 1 && command == PSMOUSE_CMD_RESET_BAT) - timeout = 100; - - if (DeviceExtension->RepliesExpected == 1 && command == PSMOUSE_CMD_GETID && - DeviceExtension->pkt[1] != 0xab && DeviceExtension->pkt[1] != 0xac) - { - DeviceExtension->RepliesExpected = 0; - break; - } - - if (i8042ReadKeyboardData(DeviceExtension->PortDeviceExtension, &scancode)) - { - DeviceExtension->pkt[--DeviceExtension->RepliesExpected] = scancode; - } - - KeDelayExecutionThread (KernelMode, FALSE, &Millisecond_Timeout); - } - - for (i = 0; i < receive; i++) - param[i] = DeviceExtension->pkt[(receive - 1) - i]; - - if (DeviceExtension->RepliesExpected) - return (int)(DeviceExtension->RepliesExpected = 0) - 1; - - return 0; -} - -/* Detect if mouse is just a standard ps/2 mouse */ -static BOOLEAN TestMouse( - IN PI8042_MOUSE_EXTENSION_OLD DeviceExtension) -{ - UCHAR param[4]; - - param[0] = param[1] = 0xa5; - - /* - * First, we check if it's a mouse. It should send 0x00 or 0x03 - * in case of an IntelliMouse in 4-byte mode or 0x04 for IM Explorer. - */ - if(SendCommand(DeviceExtension, param, PSMOUSE_CMD_GETID)) - return -1; - - if(param[0] != 0x00 && param[0] != 0x03 && param[0] != 0x04) - return -1; - - /* - * Then we reset and disable the mouse so that it doesn't generate events. - */ - - return TRUE; -} - -/* Initialize the PS/2 mouse support */ -static BOOLEAN SetupMouse( - IN PI8042_MOUSE_EXTENSION_OLD DeviceExtension) -{ - LARGE_INTEGER Millisecond_Timeout; - - Millisecond_Timeout.QuadPart = -10000L; - - /* setup */ - DeviceExtension->RepliesExpected = 0; - DeviceExtension->ack = 0; - - /* Enable the PS/2 mouse port */ - i8042Write(DeviceExtension->PortDeviceExtension, DeviceExtension->PortDeviceExtension->ControlPort, CONTROLLER_COMMAND_MOUSE_ENABLE); - - if(TestMouse(DeviceExtension)) - { - DPRINT("Detected Mouse\n"); - - if(SendCommand(DeviceExtension, NULL, PSMOUSE_CMD_ENABLE)) - DPRINT1("Failed to enable mouse!\n"); - - /* Enable controller interrupts */ - i8042Write(DeviceExtension->PortDeviceExtension, DeviceExtension->PortDeviceExtension->ControlPort, KBD_WRITE_MODE); - i8042Write(DeviceExtension->PortDeviceExtension, DeviceExtension->PortDeviceExtension->DataPort, MOUSE_INTERRUPTS_ON); - } - - return TRUE; -} - -static NTSTATUS OldInitialization( - IN PPORT_DEVICE_EXTENSION PortDeviceExtension) -{ - I8042_MOUSE_EXTENSION_OLD DeviceExtension; - - RtlZeroMemory(&DeviceExtension, sizeof(I8042_MOUSE_EXTENSION_OLD)); - DeviceExtension.PortDeviceExtension = PortDeviceExtension; - SetupMouse(&DeviceExtension); - return STATUS_SUCCESS; -} diff --git a/reactos/drivers/input/i8042prt/pnp.c b/reactos/drivers/input/i8042prt/pnp.c deleted file mode 100644 index a7e086a182d..00000000000 --- a/reactos/drivers/input/i8042prt/pnp.c +++ /dev/null @@ -1,663 +0,0 @@ -/* - * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/input/i8042prt/pnp.c - * PURPOSE: IRP_MJ_PNP operations - * PROGRAMMERS: Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) - */ - -/* INCLUDES ******************************************************************/ - -#include "i8042prt.h" - -#define NDEBUG -#include - -/* FUNCTIONS *****************************************************************/ - -/* This is all pretty confusing. There's more than one way to - * disable/enable the keyboard. You can send KBD_ENABLE to the - * keyboard, and it will start scanning keys. Sending KBD_DISABLE - * will disable the key scanning but also reset the parameters to - * defaults. - * - * You can also send 0xAE to the controller for enabling the - * keyboard clock line and 0xAD for disabling it. Then it'll - * automatically get turned on at the next command. The last - * way is by modifying the bit that drives the clock line in the - * 'command byte' of the controller. This is almost, but not quite, - * the same as the AE/AD thing. The difference can be used to detect - * some really old broken keyboard controllers which I hope won't be - * necessary. - * - * We change the command byte, sending KBD_ENABLE/DISABLE seems to confuse - * some kvm switches. - */ -BOOLEAN -i8042ChangeMode( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN UCHAR FlagsToDisable, - IN UCHAR FlagsToEnable) -{ - UCHAR Value; - NTSTATUS Status; - - if (!i8042Write(DeviceExtension, DeviceExtension->ControlPort, KBD_READ_MODE)) - { - DPRINT1("Can't read i8042 mode\n"); - return FALSE; - } - - Status = i8042ReadDataWait(DeviceExtension, &Value); - if (!NT_SUCCESS(Status)) - { - DPRINT1("No response after read i8042 mode\n"); - return FALSE; - } - - Value &= ~FlagsToDisable; - Value |= FlagsToEnable; - - if (!i8042Write(DeviceExtension, DeviceExtension->ControlPort, KBD_WRITE_MODE)) - { - DPRINT1("Can't set i8042 mode\n"); - return FALSE; - } - - if (!i8042Write(DeviceExtension, DeviceExtension->DataPort, Value)) - { - DPRINT1("Can't send i8042 mode\n"); - return FALSE; - } - - return TRUE; -} - -static NTSTATUS -i8042BasicDetect( - IN PPORT_DEVICE_EXTENSION DeviceExtension) -{ - NTSTATUS Status; - UCHAR Value = 0; - - /* Don't enable keyboard and mouse interrupts, disable keyboard/mouse */ - if (!i8042ChangeMode(DeviceExtension, CCB_KBD_INT_ENAB | CCB_MOUSE_INT_ENAB, CCB_KBD_DISAB | CCB_MOUSE_DISAB)) - return STATUS_IO_DEVICE_ERROR; - - i8042Flush(DeviceExtension); - - if (!i8042Write(DeviceExtension, DeviceExtension->ControlPort, CTRL_SELF_TEST)) - { - DPRINT1("Writing CTRL_SELF_TEST command failed\n"); - return STATUS_IO_TIMEOUT; - } - - Status = i8042ReadDataWait(DeviceExtension, &Value); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to read CTRL_SELF_TEST response, status 0x%08lx\n", Status); - return Status; - } - - if (Value != 0x55) - { - DPRINT1("Got 0x%02x instead of 0x55\n", Value); - return STATUS_IO_DEVICE_ERROR; - } - - /* - * We used to send a KBD_LINE_TEST (0xAB) command here, but on at least HP - * Pavilion notebooks the response to that command was incorrect. - * So now we just assume that a keyboard is attached. - */ - DeviceExtension->Flags |= KEYBOARD_PRESENT; - - if (i8042Write(DeviceExtension, DeviceExtension->ControlPort, MOUSE_LINE_TEST)) - { - Status = i8042ReadDataWait(DeviceExtension, &Value); - if (NT_SUCCESS(Status) && Value == 0) - DeviceExtension->Flags |= MOUSE_PRESENT; - } - - if (IsFirstStageSetup()) - /* Ignore the mouse */ - DeviceExtension->Flags &= ~MOUSE_PRESENT; - - return STATUS_SUCCESS; -} - -static BOOLEAN -i8042DetectKeyboard( - IN PPORT_DEVICE_EXTENSION DeviceExtension) -{ - NTSTATUS Status; - - /* Set LEDs (that is not fatal if some error occurs) */ - Status = i8042SynchWritePort(DeviceExtension, 0, KBD_CMD_SET_LEDS, TRUE); - if (NT_SUCCESS(Status)) - { - Status = i8042SynchWritePort(DeviceExtension, 0, 0, TRUE); - if (!NT_SUCCESS(Status)) - { - DPRINT("Can't finish SET_LEDS (0x%08lx)\n", Status); - return FALSE; - } - } - else - { - DPRINT("Warning: can't write SET_LEDS (0x%08lx)\n", Status); - } - - /* Turn on translation */ - if (!i8042ChangeMode(DeviceExtension, 0, CCB_TRANSLATE)) - return FALSE; - - return TRUE; -} - -static BOOLEAN -i8042DetectMouse( - IN PPORT_DEVICE_EXTENSION DeviceExtension) -{ - BOOLEAN Ok = FALSE; - NTSTATUS Status; - UCHAR Value; - UCHAR ExpectedReply[] = { MOUSE_ACK, 0xAA, 0x00 }; - UCHAR ReplyByte; - - i8042Flush(DeviceExtension); - - if (!i8042Write(DeviceExtension, DeviceExtension->ControlPort, CTRL_WRITE_MOUSE) - ||!i8042Write(DeviceExtension, DeviceExtension->DataPort, MOU_CMD_RESET)) - { - DPRINT1("Failed to write reset command to mouse\n"); - goto cleanup; - } - - for (ReplyByte = 0; - ReplyByte < sizeof(ExpectedReply) / sizeof(ExpectedReply[0]); - ReplyByte++) - { - Status = i8042ReadDataWait(DeviceExtension, &Value); - if (!NT_SUCCESS(Status)) - { - DPRINT1("No ACK after mouse reset, status 0x%08lx\n", Status); - goto cleanup; - } - else if (Value != ExpectedReply[ReplyByte]) - { - DPRINT1("Unexpected reply: 0x%02x (expected 0x%02x)\n", - Value, ExpectedReply[ReplyByte]); - goto cleanup; - } - } - - Ok = TRUE; - -cleanup: - if (!Ok) - { - /* There is probably no mouse present. On some systems, - the probe locks the entire keyboard controller. Let's - try to get access to the keyboard again by sending a - reset */ - i8042Flush(DeviceExtension); - i8042Write(DeviceExtension, DeviceExtension->ControlPort, CTRL_SELF_TEST); - i8042ReadDataWait(DeviceExtension, &Value); - i8042Flush(DeviceExtension); - } - - DPRINT("Mouse %sdetected\n", Ok ? "" : "not "); - - return Ok; -} - -static NTSTATUS -i8042ConnectKeyboardInterrupt( - IN PI8042_KEYBOARD_EXTENSION DeviceExtension) -{ - PPORT_DEVICE_EXTENSION PortDeviceExtension; - KIRQL DirqlMax; - NTSTATUS Status; - - DPRINT("i8042ConnectKeyboardInterrupt()\n"); - - PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; - DirqlMax = MAX( - PortDeviceExtension->KeyboardInterrupt.Dirql, - PortDeviceExtension->MouseInterrupt.Dirql); - - DPRINT("KeyboardInterrupt.Vector %lu\n", - PortDeviceExtension->KeyboardInterrupt.Vector); - DPRINT("KeyboardInterrupt.Dirql %lu\n", - PortDeviceExtension->KeyboardInterrupt.Dirql); - DPRINT("KeyboardInterrupt.DirqlMax %lu\n", - DirqlMax); - DPRINT("KeyboardInterrupt.InterruptMode %s\n", - PortDeviceExtension->KeyboardInterrupt.InterruptMode == LevelSensitive ? "LevelSensitive" : "Latched"); - DPRINT("KeyboardInterrupt.ShareInterrupt %s\n", - PortDeviceExtension->KeyboardInterrupt.ShareInterrupt ? "yes" : "no"); - DPRINT("KeyboardInterrupt.Affinity 0x%lx\n", - PortDeviceExtension->KeyboardInterrupt.Affinity); - Status = IoConnectInterrupt( - &PortDeviceExtension->KeyboardInterrupt.Object, - i8042KbdInterruptService, - DeviceExtension, &PortDeviceExtension->SpinLock, - PortDeviceExtension->KeyboardInterrupt.Vector, PortDeviceExtension->KeyboardInterrupt.Dirql, DirqlMax, - PortDeviceExtension->KeyboardInterrupt.InterruptMode, PortDeviceExtension->KeyboardInterrupt.ShareInterrupt, - PortDeviceExtension->KeyboardInterrupt.Affinity, FALSE); - if (!NT_SUCCESS(Status)) - { - DPRINT("IoConnectInterrupt() failed with status 0x%08x\n", Status); - return Status; - } - - if (DirqlMax == PortDeviceExtension->KeyboardInterrupt.Dirql) - PortDeviceExtension->HighestDIRQLInterrupt = PortDeviceExtension->KeyboardInterrupt.Object; - PortDeviceExtension->Flags |= KEYBOARD_INITIALIZED; - return STATUS_SUCCESS; -} - -static NTSTATUS -i8042ConnectMouseInterrupt( - IN PI8042_MOUSE_EXTENSION DeviceExtension) -{ - PPORT_DEVICE_EXTENSION PortDeviceExtension; - KIRQL DirqlMax; - NTSTATUS Status; - - DPRINT("i8042ConnectMouseInterrupt()\n"); - - Status = i8042MouInitialize(DeviceExtension); - if (!NT_SUCCESS(Status)) - return Status; - - PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; - DirqlMax = MAX( - PortDeviceExtension->KeyboardInterrupt.Dirql, - PortDeviceExtension->MouseInterrupt.Dirql); - - DPRINT("MouseInterrupt.Vector %lu\n", - PortDeviceExtension->MouseInterrupt.Vector); - DPRINT("MouseInterrupt.Dirql %lu\n", - PortDeviceExtension->MouseInterrupt.Dirql); - DPRINT("MouseInterrupt.DirqlMax %lu\n", - DirqlMax); - DPRINT("MouseInterrupt.InterruptMode %s\n", - PortDeviceExtension->MouseInterrupt.InterruptMode == LevelSensitive ? "LevelSensitive" : "Latched"); - DPRINT("MouseInterrupt.ShareInterrupt %s\n", - PortDeviceExtension->MouseInterrupt.ShareInterrupt ? "yes" : "no"); - DPRINT("MouseInterrupt.Affinity 0x%lx\n", - PortDeviceExtension->MouseInterrupt.Affinity); - Status = IoConnectInterrupt( - &PortDeviceExtension->MouseInterrupt.Object, - i8042MouInterruptService, - DeviceExtension, &PortDeviceExtension->SpinLock, - PortDeviceExtension->MouseInterrupt.Vector, PortDeviceExtension->MouseInterrupt.Dirql, DirqlMax, - PortDeviceExtension->MouseInterrupt.InterruptMode, PortDeviceExtension->MouseInterrupt.ShareInterrupt, - PortDeviceExtension->MouseInterrupt.Affinity, FALSE); - if (!NT_SUCCESS(Status)) - { - DPRINT("IoConnectInterrupt() failed with status 0x%08x\n", Status); - goto cleanup; - } - - if (DirqlMax == PortDeviceExtension->MouseInterrupt.Dirql) - PortDeviceExtension->HighestDIRQLInterrupt = PortDeviceExtension->MouseInterrupt.Object; - - PortDeviceExtension->Flags |= MOUSE_INITIALIZED; - Status = STATUS_SUCCESS; - -cleanup: - if (!NT_SUCCESS(Status)) - { - PortDeviceExtension->Flags &= ~MOUSE_INITIALIZED; - if (PortDeviceExtension->MouseInterrupt.Object) - { - IoDisconnectInterrupt(PortDeviceExtension->MouseInterrupt.Object); - PortDeviceExtension->HighestDIRQLInterrupt = PortDeviceExtension->KeyboardInterrupt.Object; - } - } - return Status; -} - -static NTSTATUS -EnableInterrupts( - IN PPORT_DEVICE_EXTENSION DeviceExtension) -{ - UCHAR FlagsToDisable = 0; - UCHAR FlagsToEnable = 0; - - i8042Flush(DeviceExtension); - - /* Select the devices we have */ - if (DeviceExtension->Flags & KEYBOARD_PRESENT) - { - FlagsToDisable |= CCB_KBD_DISAB; - FlagsToEnable |= CCB_KBD_INT_ENAB; - } - if (DeviceExtension->Flags & MOUSE_PRESENT) - { - FlagsToDisable |= CCB_MOUSE_DISAB; - FlagsToEnable |= CCB_MOUSE_INT_ENAB; - } - if (!i8042ChangeMode(DeviceExtension, FlagsToDisable, FlagsToEnable)) - return STATUS_UNSUCCESSFUL; - - return STATUS_SUCCESS; -} - -static NTSTATUS -StartProcedure( - IN PPORT_DEVICE_EXTENSION DeviceExtension) -{ - NTSTATUS Status; - - if (DeviceExtension->DataPort == 0) - { - /* Unable to do something at the moment */ - return STATUS_SUCCESS; - } - - if (!(DeviceExtension->Flags & (KEYBOARD_PRESENT | MOUSE_PRESENT))) - { - /* Try to detect them */ - DPRINT("Check if the controller is really a i8042\n"); - Status = i8042BasicDetect(DeviceExtension); - if (!NT_SUCCESS(Status)) - { - DPRINT("i8042BasicDetect() failed with status 0x%08lx\n", Status); - return STATUS_UNSUCCESSFUL; - } - DPRINT("Detecting keyboard\n"); - if (!i8042DetectKeyboard(DeviceExtension)) - return STATUS_UNSUCCESSFUL; - DPRINT("Detecting mouse\n"); - if (!i8042DetectMouse(DeviceExtension)) - return STATUS_UNSUCCESSFUL; - DPRINT("Keyboard present: %s\n", DeviceExtension->Flags & KEYBOARD_PRESENT ? "YES" : "NO"); - DPRINT("Mouse present : %s\n", DeviceExtension->Flags & MOUSE_PRESENT ? "YES" : "NO"); - } - - /* Connect interrupts */ - if (DeviceExtension->Flags & KEYBOARD_PRESENT && - DeviceExtension->Flags & KEYBOARD_CONNECTED && - DeviceExtension->Flags & KEYBOARD_STARTED && - !(DeviceExtension->Flags & (MOUSE_PRESENT | KEYBOARD_INITIALIZED))) - { - /* No mouse, and the keyboard is ready */ - Status = i8042ConnectKeyboardInterrupt(DeviceExtension->KeyboardExtension); - if (NT_SUCCESS(Status)) - { - DeviceExtension->Flags |= KEYBOARD_INITIALIZED; - Status = EnableInterrupts(DeviceExtension); - } - } - else if (DeviceExtension->Flags & MOUSE_PRESENT && - DeviceExtension->Flags & MOUSE_CONNECTED && - DeviceExtension->Flags & MOUSE_STARTED && - !(DeviceExtension->Flags & (KEYBOARD_PRESENT | MOUSE_INITIALIZED))) - { - /* No keyboard, and the mouse is ready */ - Status = i8042ConnectMouseInterrupt(DeviceExtension->MouseExtension); - if (NT_SUCCESS(Status)) - { - DeviceExtension->Flags |= MOUSE_INITIALIZED; - Status = EnableInterrupts(DeviceExtension); - } - } - else if (DeviceExtension->Flags & KEYBOARD_PRESENT && - DeviceExtension->Flags & KEYBOARD_CONNECTED && - DeviceExtension->Flags & KEYBOARD_STARTED && - DeviceExtension->Flags & MOUSE_PRESENT && - DeviceExtension->Flags & MOUSE_CONNECTED && - DeviceExtension->Flags & MOUSE_STARTED && - !(DeviceExtension->Flags & (KEYBOARD_INITIALIZED | MOUSE_INITIALIZED))) - { - /* The keyboard and mouse are ready */ - Status = i8042ConnectKeyboardInterrupt(DeviceExtension->KeyboardExtension); - if (NT_SUCCESS(Status)) - { - DeviceExtension->Flags |= KEYBOARD_INITIALIZED; - Status = i8042ConnectMouseInterrupt(DeviceExtension->MouseExtension); - if (NT_SUCCESS(Status)) - { - DeviceExtension->Flags |= MOUSE_INITIALIZED; - Status = EnableInterrupts(DeviceExtension); - } - } - } - else - { - /* Nothing to do */ - Status = STATUS_SUCCESS; - } - - return Status; -} - -static NTSTATUS -i8042PnpStartDevice( - IN PDEVICE_OBJECT DeviceObject, - IN PCM_RESOURCE_LIST AllocatedResources, - IN PCM_RESOURCE_LIST AllocatedResourcesTranslated) -{ - PFDO_DEVICE_EXTENSION DeviceExtension; - PPORT_DEVICE_EXTENSION PortDeviceExtension; - PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor, ResourceDescriptorTranslated; - INTERRUPT_DATA InterruptData; - BOOLEAN FoundDataPort = FALSE; - BOOLEAN FoundControlPort = FALSE; - BOOLEAN FoundIrq = FALSE; - ULONG i; - NTSTATUS Status; - - DPRINT("i8042PnpStartDevice(%p)\n", DeviceObject); - DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - PortDeviceExtension = DeviceExtension->PortDeviceExtension; - - ASSERT(DeviceExtension->PnpState == dsStopped); - - if (!AllocatedResources) - { - DPRINT("No allocated resources sent to driver\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - if (AllocatedResources->Count != 1) - { - DPRINT("Wrong number of allocated resources sent to driver\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - if (AllocatedResources->List[0].PartialResourceList.Version != 1 - || AllocatedResources->List[0].PartialResourceList.Revision != 1 - || AllocatedResourcesTranslated->List[0].PartialResourceList.Version != 1 - || AllocatedResourcesTranslated->List[0].PartialResourceList.Revision != 1) - { - DPRINT("Revision mismatch: %u.%u != 1.1 or %u.%u != 1.1\n", - AllocatedResources->List[0].PartialResourceList.Version, - AllocatedResources->List[0].PartialResourceList.Revision, - AllocatedResourcesTranslated->List[0].PartialResourceList.Version, - AllocatedResourcesTranslated->List[0].PartialResourceList.Revision); - return STATUS_REVISION_MISMATCH; - } - - /* Get Irq and optionally control port and data port */ - for (i = 0; i < AllocatedResources->List[0].PartialResourceList.Count; i++) - { - ResourceDescriptor = &AllocatedResources->List[0].PartialResourceList.PartialDescriptors[i]; - ResourceDescriptorTranslated = &AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[i]; - switch (ResourceDescriptor->Type) - { - case CmResourceTypePort: - { - if (ResourceDescriptor->u.Port.Length == 1) - { - /* We assume that the first ressource will - * be the control port and the second one - * will be the data port... - */ - if (!FoundDataPort) - { - PortDeviceExtension->DataPort = (PUCHAR)ResourceDescriptor->u.Port.Start.u.LowPart; - DPRINT("Found data port: 0x%lx\n", PortDeviceExtension->DataPort); - FoundDataPort = TRUE; - } - else if (!FoundControlPort) - { - PortDeviceExtension->ControlPort = (PUCHAR)ResourceDescriptor->u.Port.Start.u.LowPart; - DPRINT("Found control port: 0x%lx\n", PortDeviceExtension->ControlPort); - FoundControlPort = TRUE; - } - else - { - DPRINT("Too much I/O ranges provided\n", ResourceDescriptor->u.Port.Length); - return STATUS_INVALID_PARAMETER; - } - } - else - DPRINT1("Invalid I/O range length: 0x%lx\n", ResourceDescriptor->u.Port.Length); - break; - } - case CmResourceTypeInterrupt: - { - if (FoundIrq) - return STATUS_INVALID_PARAMETER; - InterruptData.Dirql = (KIRQL)ResourceDescriptorTranslated->u.Interrupt.Level; - InterruptData.Vector = ResourceDescriptorTranslated->u.Interrupt.Vector; - InterruptData.Affinity = ResourceDescriptorTranslated->u.Interrupt.Affinity; - if (ResourceDescriptorTranslated->Flags & CM_RESOURCE_INTERRUPT_LATCHED) - InterruptData.InterruptMode = Latched; - else - InterruptData.InterruptMode = LevelSensitive; - InterruptData.ShareInterrupt = (ResourceDescriptorTranslated->ShareDisposition == CmResourceShareShared); - DPRINT("Found irq resource: %lu\n", ResourceDescriptor->u.Interrupt.Vector); - FoundIrq = TRUE; - break; - } - default: - DPRINT("Unknown resource descriptor type 0x%x\n", ResourceDescriptor->Type); - } - } - - if (!FoundIrq) - { - DPRINT("Interrupt resource was not found in allocated resources list\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - else if (DeviceExtension->Type == Keyboard && (!FoundDataPort || !FoundControlPort)) - { - DPRINT("Some required resources were not found in allocated resources list\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - else if (DeviceExtension->Type == Mouse && (FoundDataPort || FoundControlPort)) - { - DPRINT("Too much resources were provided in allocated resources list\n"); - return STATUS_INVALID_PARAMETER; - } - - switch (DeviceExtension->Type) - { - case Keyboard: - { - RtlCopyMemory( - &PortDeviceExtension->KeyboardInterrupt, - &InterruptData, - sizeof(INTERRUPT_DATA)); - PortDeviceExtension->Flags |= KEYBOARD_STARTED; - Status = StartProcedure(PortDeviceExtension); - break; - } - case Mouse: - { - RtlCopyMemory( - &PortDeviceExtension->MouseInterrupt, - &InterruptData, - sizeof(INTERRUPT_DATA)); - PortDeviceExtension->Flags |= MOUSE_STARTED; - Status = StartProcedure(PortDeviceExtension); - break; - } - default: - { - DPRINT1("Unknown FDO type %u\n", DeviceExtension->Type); - ASSERT(FALSE); - Status = STATUS_INVALID_DEVICE_REQUEST; - } - } - - if (NT_SUCCESS(Status)) - DeviceExtension->PnpState = dsStarted; - - return Status; -} - -NTSTATUS NTAPI -i8042Pnp( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION Stack; - ULONG MinorFunction; - I8042_DEVICE_TYPE DeviceType; - ULONG_PTR Information = 0; - NTSTATUS Status; - - Stack = IoGetCurrentIrpStackLocation(Irp); - MinorFunction = Stack->MinorFunction; - DeviceType = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Type; - - switch (MinorFunction) - { - case IRP_MN_START_DEVICE: /* 0x0 */ - { - DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n"); - - /* Call lower driver (if any) */ - if (DeviceType != PhysicalDeviceObject) - { - Status = ForwardIrpAndWait(DeviceObject, Irp); - if (NT_SUCCESS(Status)) - Status = i8042PnpStartDevice( - DeviceObject, - Stack->Parameters.StartDevice.AllocatedResources, - Stack->Parameters.StartDevice.AllocatedResourcesTranslated); - } - else - Status = STATUS_SUCCESS; - break; - } - case IRP_MN_QUERY_DEVICE_RELATIONS: /* (optional) 0x7 */ - { - switch (Stack->Parameters.QueryDeviceRelations.Type) - { - case BusRelations: - { - DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n"); - return ForwardIrpAndForget(DeviceObject, Irp); - } - case RemovalRelations: - { - DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n"); - return ForwardIrpAndForget(DeviceObject, Irp); - } - default: - DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n", - Stack->Parameters.QueryDeviceRelations.Type); - ASSERT(FALSE); - return ForwardIrpAndForget(DeviceObject, Irp); - } - break; - } - default: - { - DPRINT1("IRP_MJ_PNP / unknown minor function 0x%x\n", MinorFunction); - ASSERT(FALSE); - return ForwardIrpAndForget(DeviceObject, Irp); - } - } - - Irp->IoStatus.Information = Information; - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return Status; -} diff --git a/reactos/drivers/input/i8042prt/ps2pp.c b/reactos/drivers/input/i8042prt/ps2pp.c deleted file mode 100644 index c9746d70f43..00000000000 --- a/reactos/drivers/input/i8042prt/ps2pp.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/input/i8042prt/ps2pp.c - * PURPOSE: ps2pp protocol handling - * PROGRAMMERS: Copyright Martijn Vernooij (o112w8r02@sneakemail.com) - * Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) - */ - -/* INCLUDES ****************************************************************/ - -#include "i8042prt.h" - -#define NDEBUG -#include - -/* FUNCTIONS *****************************************************************/ - -VOID -i8042MouHandlePs2pp( - IN PI8042_MOUSE_EXTENSION DeviceExtension, - IN UCHAR Input) -{ - UCHAR PktType; - PMOUSE_INPUT_DATA MouseInput; - - MouseInput = DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer; - - /* First, collect 3 bytes for a packet - * We can detect out-of-sync only by checking - * the whole packet anyway. - * - * If bit 7 and 8 of the first byte are 0, its - * a normal packet. - * - * Otherwise, the packet is different, like this: - * 1: E 1 b3 b2 x x x x - * 2: x x b1 b0 x1 x0 1 0 - * 3: x x x x x x x1 x0 - * - * b3-0 form a code that specifies the packet type: - * - * 0 Device Type - * 1 Rollers and buttons - * 2 Reserved - * 3 Reserved - * 4 Device ID - * 5 Channel & Battery - * 6 Wireless notifications - * 7 Reserved - * 8 ShortID LSB (ShortID is a number that is supposed to differentiate - * 9 ShortID MSB between your mouse and your neighbours') - * 10 Reserved - * 11 Mouse capabilities - * 12 Remote control LSB - * 13 Remote control MSB - * 14 Reserved - * 15 Extended packet - */ - - switch (DeviceExtension->MouseState) - { - case MouseIdle: - case XMovement: - DeviceExtension->MouseLogiBuffer[DeviceExtension->MouseState] = Input; - DeviceExtension->MouseState++; - break; - - case YMovement: - DeviceExtension->MouseLogiBuffer[2] = Input; - DeviceExtension->MouseState = MouseIdle; - - /* first check if it's a normal packet */ - - if (!(DeviceExtension->MouseLogiBuffer[0] & 0xC0)) - { - DeviceExtension->MouseState = MouseIdle; - i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[0]); - i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[1]); - i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[2]); - /* We could care about wether MouseState really - * advances, but we don't need to because we're - * only doing three bytes anyway, so the packet - * will never complete if it's broken. - */ - return; - } - - /* sanity check */ - if (((DeviceExtension->MouseLogiBuffer[0] & 0x48) != 0x48) || - (((DeviceExtension->MouseLogiBuffer[1] & 0x0C) >> 2) != - (DeviceExtension->MouseLogiBuffer[2] & 0x03))) - { - DPRINT1("Ps2pp packet fails sanity checks\n"); - return; - } - - /* Now get the packet type */ - PktType = ((DeviceExtension->MouseLogiBuffer[0] & 0x30) >> 4) & - ((DeviceExtension->MouseLogiBuffer[1] & 0x30) >> 6); - - switch (PktType) - { - case 0: - /* The packet contains the device ID, but we - * already read that in the initialization - * sequence. Ignore it. - */ - return; - case 1: - RtlZeroMemory(MouseInput, sizeof(MOUSE_INPUT_DATA)); - if (DeviceExtension->MouseLogiBuffer[2] & 0x10) - MouseInput->RawButtons |= MOUSE_BUTTON_4_DOWN; - - if (DeviceExtension->MouseLogiBuffer[2] & 0x20) - MouseInput->RawButtons |= MOUSE_BUTTON_5_DOWN; - - if (DeviceExtension->MouseLogiBuffer[2] & 0x0F) - { - MouseInput->ButtonFlags |= MOUSE_WHEEL; - if (DeviceExtension->MouseLogiBuffer[2] & 0x08) - MouseInput->ButtonData = (DeviceExtension->MouseLogiBuffer[2] & 0x07) - 8; - else - MouseInput->ButtonData = DeviceExtension->MouseLogiBuffer[2] & 0x07; - } - i8042MouHandleButtons( - DeviceExtension, - MOUSE_BUTTON_4_DOWN | MOUSE_BUTTON_5_DOWN); - i8042MouQueuePacket(DeviceExtension); - return; - default: - /* These are for things that would probably - * be handled by logitechs own driver. - */ - return; - } - - default: - DPRINT1("Unexpected input state for ps2pp!\n"); - } -} diff --git a/reactos/drivers/input/i8042prt/readwrite.c b/reactos/drivers/input/i8042prt/readwrite.c deleted file mode 100644 index 6ebf68e850c..00000000000 --- a/reactos/drivers/input/i8042prt/readwrite.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/input/i8042prt/readwrite.c - * PURPOSE: Read/write port functions - * PROGRAMMERS: Copyright Victor Kirhenshtein (sauros@iname.com) - Copyright Jason Filby (jasonfilby@yahoo.com) - Copyright Martijn Vernooij (o112w8r02@sneakemail.com) - Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) - */ - -/* INCLUDES ******************************************************************/ - -#include "i8042prt.h" - -#define NDEBUG -#include - -/* FUNCTIONS *****************************************************************/ - -VOID -i8042Flush( - IN PPORT_DEVICE_EXTENSION DeviceExtension) -{ - UCHAR Ignore; - - while (NT_SUCCESS(i8042ReadData(DeviceExtension, KBD_OBF | MOU_OBF, &Ignore))) { - DPRINT("Data flushed\n"); /* drop */ - } -} - -VOID -i8042IsrWritePort( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN UCHAR Value, - IN UCHAR SelectCmd OPTIONAL) -{ - if (SelectCmd) - if (!i8042Write(DeviceExtension, DeviceExtension->ControlPort, SelectCmd)) - return; - - i8042Write(DeviceExtension, DeviceExtension->DataPort, Value); -} - -/* - * FUNCTION: Read data from port 0x60 - */ -NTSTATUS -i8042ReadData( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN UCHAR StatusFlags, - OUT PUCHAR Data) -{ - UCHAR PortStatus; - NTSTATUS Status; - - Status = i8042ReadStatus(DeviceExtension, &PortStatus); - if (!NT_SUCCESS(Status)) - return Status; - - // If data is available - if (PortStatus & StatusFlags) - { - *Data = READ_PORT_UCHAR(DeviceExtension->DataPort); - DPRINT("Read: 0x%02x (status: 0x%x)\n", Data[0], PortStatus); - - // If the data is valid (not timeout, not parity error) - if ((PortStatus & KBD_PERR) == 0) - return STATUS_SUCCESS; - } - return STATUS_UNSUCCESSFUL; -} - -NTSTATUS -i8042ReadStatus( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - OUT PUCHAR Status) -{ - ASSERT(DeviceExtension->ControlPort != NULL); - *Status = READ_PORT_UCHAR(DeviceExtension->ControlPort); - return STATUS_SUCCESS; -} - -/* - * FUNCTION: Read data from data port - */ -NTSTATUS -i8042ReadDataWait( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - OUT PUCHAR Data) -{ - ULONG Counter; - NTSTATUS Status; - - Counter = DeviceExtension->Settings.PollingIterations; - - while (Counter--) - { - Status = i8042ReadKeyboardData(DeviceExtension, Data); - - if (NT_SUCCESS(Status)) - return Status; - - KeStallExecutionProcessor(50); - } - - /* Timed out */ - return STATUS_IO_TIMEOUT; -} - -/* - * This one reads a value from the port; You don't have to specify - * which one, it'll always be from the one you talked to, so one function - * is enough this time. Note how MSDN specifies the - * WaitForAck parameter to be ignored. - */ -NTSTATUS NTAPI -i8042SynchReadPort( - IN PVOID Context, - OUT PUCHAR Value, - IN BOOLEAN WaitForAck) -{ - PPORT_DEVICE_EXTENSION DeviceExtension; - - DeviceExtension = (PPORT_DEVICE_EXTENSION)Context; - - return i8042ReadDataWait(DeviceExtension, Value); -} - -/* - * These functions are callbacks for filter driver custom - * initialization routines. - */ -NTSTATUS NTAPI -i8042SynchWritePort( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN UCHAR Port, - IN UCHAR Value, - IN BOOLEAN WaitForAck) -{ - NTSTATUS Status; - UCHAR Ack; - ULONG ResendIterations; - - ResendIterations = DeviceExtension->Settings.ResendIterations + 1; - - do - { - if (Port) - if (!i8042Write(DeviceExtension, DeviceExtension->DataPort, Port)) - { - DPRINT1("Failed to write Port\n"); - return STATUS_IO_TIMEOUT; - } - - if (!i8042Write(DeviceExtension, DeviceExtension->DataPort, Value)) - { - DPRINT1("Failed to write Value\n"); - return STATUS_IO_TIMEOUT; - } - - if (WaitForAck) - { - Status = i8042ReadDataWait(DeviceExtension, &Ack); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to read Ack\n"); - return Status; - } - if (Ack == KBD_ACK) - return STATUS_SUCCESS; - if (Ack != KBD_RESEND) - { - DPRINT1("Unexpected Ack 0x%02x\n", Ack); - return STATUS_UNEXPECTED_IO_ERROR; - } - } - else - { - return STATUS_SUCCESS; - } - DPRINT("Reiterating\n"); - ResendIterations--; - } while (ResendIterations); - - return STATUS_IO_TIMEOUT; -} - -/* - * FUNCTION: Write data to a port, waiting first for it to become ready - */ -BOOLEAN -i8042Write( - IN PPORT_DEVICE_EXTENSION DeviceExtension, - IN PUCHAR addr, - IN UCHAR data) -{ - ULONG ResendIterations; - - ASSERT(addr); - ASSERT(DeviceExtension->ControlPort != NULL); - - ResendIterations = DeviceExtension->Settings.ResendIterations; - - while ((KBD_IBF & READ_PORT_UCHAR(DeviceExtension->ControlPort)) && - (ResendIterations--)) - { - KeStallExecutionProcessor(50); - } - - if (ResendIterations) - { - WRITE_PORT_UCHAR(addr, data); - DPRINT("Sent 0x%x to port 0x%x\n", data, addr); - return TRUE; - } - return FALSE; -} diff --git a/reactos/drivers/input/i8042prt/registry.c b/reactos/drivers/input/i8042prt/registry.c deleted file mode 100644 index 41e9a857c21..00000000000 --- a/reactos/drivers/input/i8042prt/registry.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/input/i8042prt/i8042prt.c - * PURPOSE: Reading the registry - * PROGRAMMERS: Copyright Victor Kirhenshtein (sauros@iname.com) - Copyright Jason Filby (jasonfilby@yahoo.com) - Copyright Martijn Vernooij (o112w8r02@sneakemail.com) - Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) - */ - -/* INCLUDES ******************************************************************/ - -#include "i8042prt.h" - -#define NDEBUG -#include - -/* FUNCTIONS *****************************************************************/ - -NTSTATUS -ReadRegistryEntries( - IN PUNICODE_STRING RegistryPath, - OUT PI8042_SETTINGS Settings) -{ - UNICODE_STRING ParametersRegistryKey; - RTL_QUERY_REGISTRY_TABLE Parameters[16]; - NTSTATUS Status; - - ULONG DefaultKeyboardDataQueueSize = 0x64; - UNICODE_STRING DefaultKeyboardDeviceBaseName = RTL_CONSTANT_STRING(L"KeyboardPort"); - ULONG DefaultMouseDataQueueSize = 0x64; - ULONG DefaultMouseResolution = 3; - ULONG DefaultMouseSynchIn100ns = 20000000; - ULONG DefaultNumberOfButtons = 2; - UNICODE_STRING DefaultPointerDeviceBaseName = RTL_CONSTANT_STRING(L"PointerPort"); - ULONG DefaultPollStatusIterations = 1; - ULONG DefaultOverrideKeyboardType = 4; - ULONG DefaultOverrideKeyboardSubtype = 0; - ULONG DefaultPollingIterations = 12000; - ULONG DefaultPollingIterationsMaximum = 12000; - ULONG DefaultResendIterations = 0x3; - ULONG DefaultSampleRate = 60; - ULONG DefaultCrashOnCtrlScroll; - - /* Default value for CrashOnCtrlScroll depends if we're - * running a debug build or a normal build. - */ -#ifdef DBG - DefaultCrashOnCtrlScroll = 1; -#else - DefaultCrashOnCtrlScroll = 0; -#endif - - ParametersRegistryKey.Length = 0; - ParametersRegistryKey.MaximumLength = RegistryPath->Length + sizeof(L"\\Parameters") + sizeof(UNICODE_NULL); - ParametersRegistryKey.Buffer = ExAllocatePool(PagedPool, ParametersRegistryKey.MaximumLength); - if (!ParametersRegistryKey.Buffer) - { - DPRINT("ExAllocatePool() failed\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - RtlCopyUnicodeString(&ParametersRegistryKey, RegistryPath); - RtlAppendUnicodeToString(&ParametersRegistryKey, L"\\Parameters"); - ParametersRegistryKey.Buffer[ParametersRegistryKey.Length / sizeof(WCHAR)] = UNICODE_NULL; - - RtlZeroMemory(Parameters, sizeof(Parameters)); - - Parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[0].Name = L"KeyboardDataQueueSize"; - Parameters[0].EntryContext = &Settings->KeyboardDataQueueSize; - Parameters[0].DefaultType = REG_DWORD; - Parameters[0].DefaultData = &DefaultKeyboardDataQueueSize; - Parameters[0].DefaultLength = sizeof(ULONG); - - Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[1].Name = L"KeyboardDeviceBaseName"; - Parameters[1].EntryContext = &Settings->KeyboardDeviceBaseName; - Parameters[1].DefaultType = REG_SZ; - Parameters[1].DefaultData = &DefaultKeyboardDeviceBaseName; - Parameters[1].DefaultLength = 0; - - Parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[2].Name = L"MouseDataQueueSize"; - Parameters[2].EntryContext = &Settings->MouseDataQueueSize; - Parameters[2].DefaultType = REG_DWORD; - Parameters[2].DefaultData = &DefaultMouseDataQueueSize; - Parameters[2].DefaultLength = sizeof(ULONG); - - Parameters[3].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[3].Name = L"MouseResolution"; - Parameters[3].EntryContext = &Settings->MouseResolution; - Parameters[3].DefaultType = REG_DWORD; - Parameters[3].DefaultData = &DefaultMouseResolution; - Parameters[3].DefaultLength = sizeof(ULONG); - - Parameters[4].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[4].Name = L"MouseSynchIn100ns"; - Parameters[4].EntryContext = &Settings->MouseSynchIn100ns; - Parameters[4].DefaultType = REG_DWORD; - Parameters[4].DefaultData = &DefaultMouseSynchIn100ns; - Parameters[4].DefaultLength = sizeof(ULONG); - - Parameters[5].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[5].Name = L"NumberOfButtons"; - Parameters[5].EntryContext = &Settings->NumberOfButtons; - Parameters[5].DefaultType = REG_DWORD; - Parameters[5].DefaultData = &DefaultNumberOfButtons; - Parameters[5].DefaultLength = sizeof(ULONG); - - Parameters[6].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[6].Name = L"PointerDeviceBaseName"; - Parameters[6].EntryContext = &Settings->PointerDeviceBaseName; - Parameters[6].DefaultType = REG_SZ; - Parameters[6].DefaultData = &DefaultPointerDeviceBaseName; - Parameters[6].DefaultLength = 0; - - Parameters[7].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[7].Name = L"PollStatusIterations"; - Parameters[7].EntryContext = &Settings->PollStatusIterations; - Parameters[7].DefaultType = REG_DWORD; - Parameters[7].DefaultData = &DefaultPollStatusIterations; - Parameters[7].DefaultLength = sizeof(ULONG); - - Parameters[8].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[8].Name = L"OverrideKeyboardType"; - Parameters[8].EntryContext = &Settings->OverrideKeyboardType; - Parameters[8].DefaultType = REG_DWORD; - Parameters[8].DefaultData = &DefaultOverrideKeyboardType; - Parameters[8].DefaultLength = sizeof(ULONG); - - Parameters[9].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[9].Name = L"OverrideKeyboardSubtype"; - Parameters[9].EntryContext = &Settings->OverrideKeyboardSubtype; - Parameters[9].DefaultType = REG_DWORD; - Parameters[9].DefaultData = &DefaultOverrideKeyboardSubtype; - Parameters[9].DefaultLength = sizeof(ULONG); - - Parameters[10].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[10].Name = L"PollingIterations"; - Parameters[10].EntryContext = &Settings->PollingIterations; - Parameters[10].DefaultType = REG_DWORD; - Parameters[10].DefaultData = &DefaultPollingIterations; - Parameters[10].DefaultLength = sizeof(ULONG); - - Parameters[11].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[11].Name = L"PollingIterationsMaximum"; - Parameters[11].EntryContext = &Settings->PollingIterationsMaximum; - Parameters[11].DefaultType = REG_DWORD; - Parameters[11].DefaultData = &DefaultPollingIterationsMaximum; - Parameters[11].DefaultLength = sizeof(ULONG); - - Parameters[12].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[12].Name = L"ResendIterations"; - Parameters[12].EntryContext = &Settings->ResendIterations; - Parameters[12].DefaultType = REG_DWORD; - Parameters[12].DefaultData = &DefaultResendIterations; - Parameters[12].DefaultLength = sizeof(ULONG); - - Parameters[13].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[13].Name = L"SampleRate"; - Parameters[13].EntryContext = &Settings->SampleRate; - Parameters[13].DefaultType = REG_DWORD; - Parameters[13].DefaultData = &DefaultSampleRate; - Parameters[13].DefaultLength = sizeof(ULONG); - - Parameters[14].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; - Parameters[14].Name = L"CrashOnCtrlScroll"; - Parameters[14].EntryContext = &Settings->CrashOnCtrlScroll; - Parameters[14].DefaultType = REG_DWORD; - Parameters[14].DefaultData = &DefaultCrashOnCtrlScroll; - Parameters[14].DefaultLength = sizeof(ULONG); - - Status = RtlQueryRegistryValues( - RTL_REGISTRY_ABSOLUTE, - ParametersRegistryKey.Buffer, - Parameters, - NULL, - NULL); - - if (NT_SUCCESS(Status)) - { - /* Check values */ - if (Settings->KeyboardDataQueueSize < 1) - Settings->KeyboardDataQueueSize = DefaultKeyboardDataQueueSize; - if (Settings->MouseDataQueueSize < 1) - Settings->MouseDataQueueSize = DefaultMouseDataQueueSize; - if (Settings->NumberOfButtons < 1) - Settings->NumberOfButtons = DefaultNumberOfButtons; - if (Settings->PollingIterations < 0x400) - Settings->PollingIterations = DefaultPollingIterations; - if (Settings->PollingIterationsMaximum < 0x400) - Settings->PollingIterationsMaximum = DefaultPollingIterationsMaximum; - if (Settings->ResendIterations < 1) - Settings->ResendIterations = DefaultResendIterations; - } - else if (Status == STATUS_OBJECT_NAME_NOT_FOUND) - { - /* Registry path doesn't exist. Set defaults */ - Settings->KeyboardDataQueueSize = DefaultKeyboardDataQueueSize; - Settings->MouseDataQueueSize = DefaultMouseDataQueueSize; - Settings->MouseResolution = DefaultMouseResolution; - Settings->MouseSynchIn100ns = DefaultMouseSynchIn100ns; - Settings->NumberOfButtons = DefaultNumberOfButtons; - Settings->PollStatusIterations = DefaultPollStatusIterations; - Settings->OverrideKeyboardType = DefaultOverrideKeyboardType; - Settings->OverrideKeyboardSubtype = DefaultOverrideKeyboardSubtype; - Settings->PollingIterations = DefaultPollingIterations; - Settings->PollingIterationsMaximum = DefaultPollingIterationsMaximum; - Settings->ResendIterations = DefaultResendIterations; - Settings->SampleRate = DefaultSampleRate; - Settings->CrashOnCtrlScroll = DefaultCrashOnCtrlScroll; - Status = RtlDuplicateUnicodeString( - RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, - &DefaultKeyboardDeviceBaseName, - &Settings->KeyboardDeviceBaseName); - if (!NT_SUCCESS(Status)) - { - DPRINT("RtlDuplicateUnicodeString() failed with status 0x%08lx\n", Status); - } - else - { - Status = RtlDuplicateUnicodeString( - RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, - &DefaultPointerDeviceBaseName, - &Settings->PointerDeviceBaseName); - if (!NT_SUCCESS(Status)) - DPRINT("RtlDuplicateUnicodeString() failed with status 0x%08lx\n", Status); - } - } - - if (NT_SUCCESS(Status)) - { - DPRINT("KeyboardDataQueueSize : 0x%lx\n", Settings->KeyboardDataQueueSize); - DPRINT("KeyboardDeviceBaseName : %wZ\n", &Settings->KeyboardDeviceBaseName); - DPRINT("MouseDataQueueSize : 0x%lx\n", Settings->MouseDataQueueSize); - DPRINT("MouseResolution : 0x%lx\n", Settings->MouseResolution); - DPRINT("MouseSynchIn100ns : %lu\n", Settings->MouseSynchIn100ns); - DPRINT("NumberOfButtons : 0x%lx\n", Settings->NumberOfButtons); - DPRINT("PointerDeviceBaseName : %wZ\n", &Settings->PointerDeviceBaseName); - DPRINT("PollStatusIterations : 0x%lx\n", Settings->PollStatusIterations); - DPRINT("OverrideKeyboardType : 0x%lx\n", Settings->OverrideKeyboardType); - DPRINT("OverrideKeyboardSubtype : 0x%lx\n", Settings->OverrideKeyboardSubtype); - DPRINT("PollingIterations : 0x%lx\n", Settings->PollingIterations); - DPRINT("PollingIterationsMaximum : %lu\n", Settings->PollingIterationsMaximum); - DPRINT("ResendIterations : 0x%lx\n", Settings->ResendIterations); - DPRINT("SampleRate : %lu\n", Settings->SampleRate); - } - - return Status; -} diff --git a/reactos/drivers/input/i8042prt/setup.c b/reactos/drivers/input/i8042prt/setup.c deleted file mode 100644 index b33181c3f89..00000000000 --- a/reactos/drivers/input/i8042prt/setup.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver - * LICENSE: GPL - See COPYING in the top level directory - * FILE: drivers/input/i8042prt/setup.c - * PURPOSE: Create a legacy PDO during ReactOS installation - * PROGRAMMERS: Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) - */ - -/* NOTE: - * All this file is a big hack and should be removed one day... - */ - -/* INCLUDES ******************************************************************/ - -#include "i8042prt.h" - -#define NDEBUG -#include - -/* GLOBALS *******************************************************************/ - -#define KEYBOARD_DATA_PORT 0x60 -#define KEYBOARD_CONTROL_PORT 0x64 -#define KEYBOARD_IRQ 1 - -/* FUNCTIONS *****************************************************************/ - -BOOLEAN -IsFirstStageSetup( - VOID) -{ - UNICODE_STRING PathU = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\Setup"); - OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE hSetupKey = (HANDLE)NULL; - NTSTATUS Status; - BOOLEAN ret = TRUE; - - InitializeObjectAttributes(&ObjectAttributes, &PathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); - Status = ZwOpenKey(&hSetupKey, KEY_QUERY_VALUE, &ObjectAttributes); - - if (Status == STATUS_OBJECT_NAME_NOT_FOUND) - ret = TRUE; - else - ret = FALSE; - - if (hSetupKey != (HANDLE)NULL) - ZwClose(hSetupKey); - DPRINT("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; - DPRINT("SendStartDevice(%p)\n", Pdo); - - /* Create default resource list */ - ResourceListSize = sizeof(CM_RESOURCE_LIST) + 3 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); - AllocatedResources = ExAllocatePool(PagedPool, ResourceListSize); - if (!AllocatedResources) - { - DPRINT("ExAllocatePool() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - 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_LEVEL_SENSITIVE; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Level = 0; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Vector = KEYBOARD_IRQ; - AllocatedResources->List[0].PartialResourceList.PartialDescriptors[2].u.Interrupt.Affinity = (KAFFINITY)-1; - - /* Create default resource list translated */ - AllocatedResourcesTranslated = ExAllocatePool(PagedPool, ResourceListSize); - if (!AllocatedResources) - { - DPRINT("ExAllocatePool() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - 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)) - { - DPRINT("IoCallDriver() failed with status 0x%08lx\n", Status); - goto cleanup; - } - -cleanup: - if (TopDeviceObject) - ObDereferenceObject(TopDeviceObject); - if (AllocatedResources) - ExFreePool(AllocatedResources); - if (AllocatedResourcesTranslated) - ExFreePool(AllocatedResourcesTranslated); -} - -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)) - { - DPRINT("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)) - { - DPRINT("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)) - { - DPRINT("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; - - DPRINT("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)) - { - DPRINT("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)) - { - DPRINT("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; - -cleanup: - if (!NT_SUCCESS(Status)) - { - if (Pdo) - IoDeleteDevice(Pdo); - } - return Status; -}