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"
19 BOOLEAN
MouseSynchronizeRoutine(PVOID Context
)
21 PIRP Irp
= (PIRP
)Context
;
22 PMOUSE_INPUT_DATA rec
= (PMOUSE_INPUT_DATA
)Irp
->AssociatedIrp
.SystemBuffer
;
23 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation(Irp
);
24 ULONG NrToRead
= stk
->Parameters
.Read
.Length
/sizeof(MOUSE_INPUT_DATA
);
27 if ((stk
->Parameters
.Read
.Length
/sizeof(MOUSE_INPUT_DATA
))==NrToRead
)
32 MouseDataRequired
=stk
->Parameters
.Read
.Length
/sizeof(MOUSE_INPUT_DATA
);
33 MouseDataRead
=NrToRead
;
40 PS2MouseStartIo(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
42 PDEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
44 if (KeSynchronizeExecution(DeviceExtension
->MouseInterrupt
, MouseSynchronizeRoutine
, Irp
))
46 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
47 Irp
->IoStatus
.Information
= 0;
48 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
49 IoStartNextPacket(DeviceObject
, FALSE
);
54 PS2MouseDispatch(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
56 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation(Irp
);
59 switch (stk
->MajorFunction
)
62 if (AlreadyOpened
== TRUE
)
64 Status
= STATUS_SUCCESS
;
68 Status
= STATUS_SUCCESS
;
74 Status
= STATUS_SUCCESS
;
78 DbgPrint("NOT IMPLEMENTED\n");
79 Status
= STATUS_NOT_IMPLEMENTED
;
83 if (Status
==STATUS_PENDING
)
85 IoMarkIrpPending(Irp
);
89 Irp
->IoStatus
.Status
= Status
;
90 Irp
->IoStatus
.Information
= 0;
91 IoCompleteRequest(Irp
,IO_NO_INCREMENT
);
96 VOID
PS2MouseInitializeDataQueue(PVOID Context
)
99 /* PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeviceExtension;
101 DeviceExtension->InputDataCount = 0;
102 DeviceExtension->MouseInputData = ExAllocatePool(NonPagedPool, sizeof(MOUSE_INPUT_DATA) * MOUSE_BUFFER_SIZE); */
106 PS2MouseInternalDeviceControl(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
)
108 PDEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
109 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
112 switch(Stack
->Parameters
.DeviceIoControl
.IoControlCode
)
114 case IOCTL_INTERNAL_MOUSE_CONNECT
:
116 DeviceExtension
->ClassInformation
=
117 *((PCLASS_INFORMATION
)Stack
->Parameters
.DeviceIoControl
.Type3InputBuffer
);
119 // Reinitialize the port input data queue synchronously
120 KeSynchronizeExecution(DeviceExtension
->MouseInterrupt
,
121 (PKSYNCHRONIZE_ROUTINE
)PS2MouseInitializeDataQueue
, DeviceExtension
);
123 status
= STATUS_SUCCESS
;
127 status
= STATUS_INVALID_DEVICE_REQUEST
;
131 Irp
->IoStatus
.Status
= status
;
132 if (status
== STATUS_PENDING
) {
133 IoMarkIrpPending(Irp
);
134 IoStartPacket(DeviceObject
, Irp
, NULL
, NULL
);
136 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
142 VOID
PS2MouseIsrDpc(PKDPC Dpc
, PDEVICE_OBJECT DeviceObject
, PIRP Irp
, PVOID Context
)
144 PDEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
146 (*(PSERVICE_CALLBACK_ROUTINE
)DeviceExtension
->ClassInformation
.CallBack
)(
147 DeviceExtension
->ClassInformation
.DeviceObject
,
148 DeviceExtension
->MouseInputData
,
150 &DeviceExtension
->InputDataCount
);
152 DeviceExtension
->InputDataCount
= 0;
156 DriverEntry(PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
)
158 PDEVICE_OBJECT DeviceObject
;
159 UNICODE_STRING DeviceName
;
160 UNICODE_STRING SymlinkName
;
161 PDEVICE_EXTENSION DeviceExtension
;
163 DbgPrint("PS/2 Keyboard & Mouse Driver 0.0.2\n");
165 if(detect_ps2_port() == TRUE
)
167 DbgPrint("PS/2 Mouse Detected\n");
169 return STATUS_UNSUCCESSFUL
;
171 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = PS2MouseDispatch
;
172 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = PS2MouseDispatch
;
173 DriverObject
->MajorFunction
[IRP_MJ_INTERNAL_DEVICE_CONTROL
] = PS2MouseInternalDeviceControl
;
174 DriverObject
->DriverStartIo
= PS2MouseStartIo
;
176 RtlInitUnicodeString(&DeviceName
, L
"\\Device\\Mouse"); // FIXME: find correct device name
177 IoCreateDevice(DriverObject
,
178 sizeof(DEVICE_EXTENSION
),
180 FILE_DEVICE_SERIAL_MOUSE_PORT
, // FIXME: this isn't really a serial mouse port driver
184 DeviceObject
->Flags
= DeviceObject
->Flags
| DO_BUFFERED_IO
;
186 RtlInitUnicodeString(&SymlinkName
, L
"\\??\\Mouse"); // FIXME: find correct device name
187 IoCreateSymbolicLink(&SymlinkName
, &DeviceName
);
189 DeviceExtension
= DeviceObject
->DeviceExtension
;
190 KeInitializeDpc(&DeviceExtension
->IsrDpc
, (PKDEFERRED_ROUTINE
)PS2MouseIsrDpc
, DeviceObject
);
191 KeInitializeDpc(&DeviceExtension
->IsrDpcRetry
, (PKDEFERRED_ROUTINE
)PS2MouseIsrDpc
, DeviceObject
);
193 mouse_init(DeviceObject
);
195 return(STATUS_SUCCESS
);