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
;
39 VOID
PS2MouseStartIo(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
41 PDEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
43 if (KeSynchronizeExecution(DeviceExtension
->MouseInterrupt
, MouseSynchronizeRoutine
, Irp
))
45 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
46 Irp
->IoStatus
.Information
= 0;
47 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
48 IoStartNextPacket(DeviceObject
, FALSE
);
52 NTSTATUS
PS2MouseDispatch(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
54 PIO_STACK_LOCATION stk
= IoGetCurrentIrpStackLocation(Irp
);
57 switch (stk
->MajorFunction
)
60 if (AlreadyOpened
== TRUE
)
62 Status
= STATUS_SUCCESS
;
66 Status
= STATUS_SUCCESS
;
72 Status
= STATUS_SUCCESS
;
76 DbgPrint("NOT IMPLEMENTED\n");
77 Status
= STATUS_NOT_IMPLEMENTED
;
81 if (Status
==STATUS_PENDING
)
83 IoMarkIrpPending(Irp
);
87 Irp
->IoStatus
.Status
= Status
;
88 Irp
->IoStatus
.Information
= 0;
89 IoCompleteRequest(Irp
,IO_NO_INCREMENT
);
94 VOID
PS2MouseInitializeDataQueue(PVOID Context
)
97 /* PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeviceExtension;
99 DeviceExtension->InputDataCount = 0;
100 DeviceExtension->MouseInputData = ExAllocatePool(NonPagedPool, sizeof(MOUSE_INPUT_DATA) * MOUSE_BUFFER_SIZE); */
103 NTSTATUS
PS2MouseInternalDeviceControl(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
)
105 PDEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
106 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
109 switch(Stack
->Parameters
.DeviceIoControl
.IoControlCode
)
111 case IOCTL_INTERNAL_MOUSE_CONNECT
:
113 DeviceExtension
->ClassInformation
=
114 *((PCLASS_INFORMATION
)Stack
->Parameters
.DeviceIoControl
.Type3InputBuffer
);
116 // Reinitialize the port input data queue synchronously
117 KeSynchronizeExecution(DeviceExtension
->MouseInterrupt
,
118 (PKSYNCHRONIZE_ROUTINE
)PS2MouseInitializeDataQueue
, DeviceExtension
);
120 status
= STATUS_SUCCESS
;
124 status
= STATUS_INVALID_DEVICE_REQUEST
;
128 Irp
->IoStatus
.Status
= status
;
129 if (status
== STATUS_PENDING
) {
130 IoMarkIrpPending(Irp
);
131 IoStartPacket(DeviceObject
, Irp
, NULL
, NULL
);
133 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
139 VOID
PS2MouseIsrDpc(PKDPC Dpc
, PDEVICE_OBJECT DeviceObject
, PIRP Irp
, PVOID Context
)
141 PDEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
143 (*(PSERVICE_CALLBACK_ROUTINE
)DeviceExtension
->ClassInformation
.CallBack
)(
144 DeviceExtension
->ClassInformation
.DeviceObject
,
145 DeviceExtension
->MouseInputData
,
147 &DeviceExtension
->InputDataCount
);
149 DeviceExtension
->InputDataCount
= 0;
153 DriverEntry(PDRIVER_OBJECT DriverObject
, PUNICODE_STRING RegistryPath
)
155 PDEVICE_OBJECT DeviceObject
;
156 UNICODE_STRING DeviceName
;
157 UNICODE_STRING SymlinkName
;
158 PDEVICE_EXTENSION DeviceExtension
;
160 DbgPrint("PS/2 Keyboard & Mouse Driver 0.0.2\n");
162 if(detect_ps2_port() == TRUE
)
164 DbgPrint("PS/2 Mouse Detected\n");
166 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 RtlInitUnicodeString(&DeviceName
, L
"\\Device\\Mouse"); // FIXME: find correct device name
174 IoCreateDevice(DriverObject
,
175 sizeof(DEVICE_EXTENSION
),
177 FILE_DEVICE_SERIAL_MOUSE_PORT
, // FIXME: this isn't really a serial mouse port driver
181 DeviceObject
->Flags
= DeviceObject
->Flags
| DO_BUFFERED_IO
;
183 RtlInitUnicodeString(&SymlinkName
, L
"\\??\\Mouse"); // FIXME: find correct device name
184 IoCreateSymbolicLink(&SymlinkName
, &DeviceName
);
186 DeviceExtension
= DeviceObject
->DeviceExtension
;
187 KeInitializeDpc(&DeviceExtension
->IsrDpc
, (PKDEFERRED_ROUTINE
)PS2MouseIsrDpc
, DeviceObject
);
188 KeInitializeDpc(&DeviceExtension
->IsrDpcRetry
, (PKDEFERRED_ROUTINE
)PS2MouseIsrDpc
, DeviceObject
);
190 mouse_init(DeviceObject
);
192 return(STATUS_SUCCESS
);