4 ** Written by Jason Filby (jasonfilby@yahoo.com)
5 ** For ReactOS (www.reactos.com)
7 ** Handles the keyboard and mouse on the PS/2 ports
9 ** TODO: Fix detect_ps2_port(void) so that it works under BOCHs
10 Implement mouse button support
14 #include <ddk/ntddk.h>
15 #include "../include/mouse.h"
20 MouseSynchronizeRoutine(PVOID Context
)
22 PIRP Irp
= (PIRP
)Context
;
23 PMOUSE_INPUT_DATA rec
= (PMOUSE_INPUT_DATA
)Irp
->AssociatedIrp
.SystemBuffer
;
24 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation(Irp
);
25 ULONG NrToRead
= stk
->Parameters
.Read
.Length
/sizeof(MOUSE_INPUT_DATA
);
28 if ((stk
->Parameters
.Read
.Length
/sizeof(MOUSE_INPUT_DATA
))==NrToRead
)
33 MouseDataRequired
=stk
->Parameters
.Read
.Length
/sizeof(MOUSE_INPUT_DATA
);
34 MouseDataRead
=NrToRead
;
41 PS2MouseStartIo(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
43 PDEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
45 if (KeSynchronizeExecution(DeviceExtension
->MouseInterrupt
, MouseSynchronizeRoutine
, Irp
))
47 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
48 Irp
->IoStatus
.Information
= 0;
49 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
50 IoStartNextPacket(DeviceObject
, FALSE
);
55 PS2MouseDispatch(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
57 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation(Irp
);
60 switch (stk
->MajorFunction
)
63 if (AlreadyOpened
== TRUE
)
65 Status
= STATUS_SUCCESS
;
69 Status
= STATUS_SUCCESS
;
75 Status
= STATUS_SUCCESS
;
79 DbgPrint("NOT IMPLEMENTED\n");
80 Status
= STATUS_NOT_IMPLEMENTED
;
84 if (Status
==STATUS_PENDING
)
86 IoMarkIrpPending(Irp
);
90 Irp
->IoStatus
.Status
= Status
;
91 Irp
->IoStatus
.Information
= 0;
92 IoCompleteRequest(Irp
,IO_NO_INCREMENT
);
97 VOID
PS2MouseInitializeDataQueue(PVOID Context
)
102 PS2MouseInternalDeviceControl(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
)
104 PDEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
105 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
108 switch(Stack
->Parameters
.DeviceIoControl
.IoControlCode
)
110 case IOCTL_INTERNAL_MOUSE_CONNECT
:
112 DeviceExtension
->ClassInformation
=
113 *((PCLASS_INFORMATION
)Stack
->Parameters
.DeviceIoControl
.Type3InputBuffer
);
115 // Reinitialize the port input data queue synchronously
116 KeSynchronizeExecution(DeviceExtension
->MouseInterrupt
,
117 (PKSYNCHRONIZE_ROUTINE
)PS2MouseInitializeDataQueue
, DeviceExtension
);
119 status
= STATUS_SUCCESS
;
123 status
= STATUS_INVALID_DEVICE_REQUEST
;
127 Irp
->IoStatus
.Status
= status
;
128 if (status
== STATUS_PENDING
) {
129 IoMarkIrpPending(Irp
);
130 IoStartPacket(DeviceObject
, Irp
, NULL
, NULL
);
132 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
138 VOID
PS2MouseIsrDpc(PKDPC Dpc
, PDEVICE_OBJECT DeviceObject
, PIRP Irp
, PVOID Context
)
140 PDEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
143 Queue
= DeviceExtension
->ActiveQueue
% 2;
144 InterlockedIncrement(&DeviceExtension
->ActiveQueue
);
145 (*(PSERVICE_CALLBACK_ROUTINE
)DeviceExtension
->ClassInformation
.CallBack
)(
146 DeviceExtension
->ClassInformation
.DeviceObject
,
147 DeviceExtension
->MouseInputData
[Queue
],
149 &DeviceExtension
->InputDataCount
[Queue
]);
150 DeviceExtension
->InputDataCount
[Queue
] = 0;
154 DriverEntry(PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
)
156 PDEVICE_OBJECT DeviceObject
;
157 UNICODE_STRING DeviceName
;
158 UNICODE_STRING SymlinkName
;
159 PDEVICE_EXTENSION DeviceExtension
;
161 if (detect_ps2_port() == TRUE
) {
162 DbgPrint("PS2 Port Driver version 0.0.1\n");
164 DbgPrint("PS2 port not found.\n");
165 return STATUS_UNSUCCESSFUL
;
168 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = PS2MouseDispatch
;
169 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = PS2MouseDispatch
;
170 DriverObject
->MajorFunction
[IRP_MJ_INTERNAL_DEVICE_CONTROL
] = PS2MouseInternalDeviceControl
;
171 DriverObject
->DriverStartIo
= PS2MouseStartIo
;
173 RtlInitUnicodeStringFromLiteral(&DeviceName
,
174 L
"\\Device\\Mouse"); // FIXME: find correct device name
175 IoCreateDevice(DriverObject
,
176 sizeof(DEVICE_EXTENSION
),
178 FILE_DEVICE_SERIAL_MOUSE_PORT
, // FIXME: this isn't really a serial mouse port driver
182 DeviceObject
->Flags
= DeviceObject
->Flags
| DO_BUFFERED_IO
;
184 RtlInitUnicodeStringFromLiteral(&SymlinkName
,
185 L
"\\??\\Mouse"); // FIXME: find correct device name
186 IoCreateSymbolicLink(&SymlinkName
, &DeviceName
);
188 DeviceExtension
= DeviceObject
->DeviceExtension
;
189 KeInitializeDpc(&DeviceExtension
->IsrDpc
, (PKDEFERRED_ROUTINE
)PS2MouseIsrDpc
, DeviceObject
);
191 mouse_init(DeviceObject
);
193 return(STATUS_SUCCESS
);