More cleanups
[reactos.git] / reactos / drivers / input / psaux / psaux.c
1 /*
2
3 ** PS/2 driver 0.0.1
4 ** Written by Jason Filby (jasonfilby@yahoo.com)
5 ** For ReactOS (www.reactos.com)
6
7 ** Handles the keyboard and mouse on the PS/2 ports
8
9 ** TODO: Fix detect_ps2_port(void) so that it works under BOCHs
10 Implement mouse button support
11
12 */
13
14 #include <ddk/ntddk.h>
15 #include "../include/mouse.h"
16 #include "mouse.h"
17 #include "psaux.h"
18
19 BOOLEAN MouseSynchronizeRoutine(PVOID Context)
20 {
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);
25 int i;
26
27 if ((stk->Parameters.Read.Length/sizeof(MOUSE_INPUT_DATA))==NrToRead)
28 {
29 return(TRUE);
30 }
31
32 MouseDataRequired=stk->Parameters.Read.Length/sizeof(MOUSE_INPUT_DATA);
33 MouseDataRead=NrToRead;
34 CurrentIrp=Irp;
35
36 return(FALSE);
37 }
38
39 VOID STDCALL
40 PS2MouseStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
41 {
42 PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
43
44 if (KeSynchronizeExecution(DeviceExtension->MouseInterrupt, MouseSynchronizeRoutine, Irp))
45 {
46 Irp->IoStatus.Status = STATUS_SUCCESS;
47 Irp->IoStatus.Information = 0;
48 IoCompleteRequest(Irp, IO_NO_INCREMENT);
49 IoStartNextPacket(DeviceObject, FALSE);
50 }
51 }
52
53 NTSTATUS STDCALL
54 PS2MouseDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
55 {
56 PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
57 NTSTATUS Status;
58
59 switch (stk->MajorFunction)
60 {
61 case IRP_MJ_CREATE:
62 if (AlreadyOpened == TRUE)
63 {
64 Status = STATUS_SUCCESS;
65 }
66 else
67 {
68 Status = STATUS_SUCCESS;
69 AlreadyOpened = TRUE;
70 }
71 break;
72
73 case IRP_MJ_CLOSE:
74 Status = STATUS_SUCCESS;
75 break;
76
77 default:
78 DbgPrint("NOT IMPLEMENTED\n");
79 Status = STATUS_NOT_IMPLEMENTED;
80 break;
81 }
82
83 if (Status==STATUS_PENDING)
84 {
85 IoMarkIrpPending(Irp);
86 }
87 else
88 {
89 Irp->IoStatus.Status = Status;
90 Irp->IoStatus.Information = 0;
91 IoCompleteRequest(Irp,IO_NO_INCREMENT);
92 }
93 return(Status);
94 }
95
96 VOID PS2MouseInitializeDataQueue(PVOID Context)
97 {
98 ;
99 /* PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeviceExtension;
100
101 DeviceExtension->InputDataCount = 0;
102 DeviceExtension->MouseInputData = ExAllocatePool(NonPagedPool, sizeof(MOUSE_INPUT_DATA) * MOUSE_BUFFER_SIZE); */
103 }
104
105 NTSTATUS STDCALL
106 PS2MouseInternalDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
107 {
108 PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
109 PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
110 NTSTATUS status;
111
112 switch(Stack->Parameters.DeviceIoControl.IoControlCode)
113 {
114 case IOCTL_INTERNAL_MOUSE_CONNECT:
115
116 DeviceExtension->ClassInformation =
117 *((PCLASS_INFORMATION)Stack->Parameters.DeviceIoControl.Type3InputBuffer);
118
119 // Reinitialize the port input data queue synchronously
120 KeSynchronizeExecution(DeviceExtension->MouseInterrupt,
121 (PKSYNCHRONIZE_ROUTINE)PS2MouseInitializeDataQueue, DeviceExtension);
122
123 status = STATUS_SUCCESS;
124 break;
125
126 default:
127 status = STATUS_INVALID_DEVICE_REQUEST;
128 break;
129 }
130
131 Irp->IoStatus.Status = status;
132 if (status == STATUS_PENDING) {
133 IoMarkIrpPending(Irp);
134 IoStartPacket(DeviceObject, Irp, NULL, NULL);
135 } else {
136 IoCompleteRequest(Irp, IO_NO_INCREMENT);
137 }
138
139 return status;
140 }
141
142 VOID PS2MouseIsrDpc(PKDPC Dpc, PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
143 {
144 PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
145
146 (*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->ClassInformation.CallBack)(
147 DeviceExtension->ClassInformation.DeviceObject,
148 DeviceExtension->MouseInputData,
149 NULL,
150 &DeviceExtension->InputDataCount);
151
152 DeviceExtension->InputDataCount = 0;
153 }
154
155 NTSTATUS STDCALL
156 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
157 {
158 PDEVICE_OBJECT DeviceObject;
159 UNICODE_STRING DeviceName;
160 UNICODE_STRING SymlinkName;
161 PDEVICE_EXTENSION DeviceExtension;
162
163 DbgPrint("PS/2 Keyboard & Mouse Driver 0.0.2\n");
164
165 if(detect_ps2_port() == TRUE)
166 {
167 DbgPrint("PS/2 Mouse Detected\n");
168 } else
169 return STATUS_UNSUCCESSFUL;
170
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;
175
176 RtlInitUnicodeString(&DeviceName, L"\\Device\\Mouse"); // FIXME: find correct device name
177 IoCreateDevice(DriverObject,
178 sizeof(DEVICE_EXTENSION),
179 &DeviceName,
180 FILE_DEVICE_SERIAL_MOUSE_PORT, // FIXME: this isn't really a serial mouse port driver
181 0,
182 TRUE,
183 &DeviceObject);
184 DeviceObject->Flags = DeviceObject->Flags | DO_BUFFERED_IO;
185
186 RtlInitUnicodeString(&SymlinkName, L"\\??\\Mouse"); // FIXME: find correct device name
187 IoCreateSymbolicLink(&SymlinkName, &DeviceName);
188
189 DeviceExtension = DeviceObject->DeviceExtension;
190 KeInitializeDpc(&DeviceExtension->IsrDpc, (PKDEFERRED_ROUTINE)PS2MouseIsrDpc, DeviceObject);
191 KeInitializeDpc(&DeviceExtension->IsrDpcRetry, (PKDEFERRED_ROUTINE)PS2MouseIsrDpc, DeviceObject);
192
193 mouse_init(DeviceObject);
194
195 return(STATUS_SUCCESS);
196 }