2 * PROJECT: ReactOS Serial mouse driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/input/sermouse/detect.c
5 * PURPOSE: Detect serial mouse type
6 * PROGRAMMERS: Copyright Jason Filby (jasonfilby@yahoo.com)
7 Copyright Filip Navara (xnavara@volny.cz)
8 Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org)
13 /* Most of this file is ripped from reactos/drivers/bus/serenum/detect.c */
17 IN PDEVICE_OBJECT DeviceObject
,
19 IN PVOID InputBuffer OPTIONAL
,
20 IN SIZE_T InputBufferSize
,
21 IN OUT PVOID OutputBuffer OPTIONAL
,
22 IN OUT PSIZE_T OutputBufferSize
)
26 IO_STATUS_BLOCK IoStatus
;
29 KeInitializeEvent (&Event
, NotificationEvent
, FALSE
);
31 Irp
= IoBuildDeviceIoControlRequest(CtlCode
,
34 (ULONG
)InputBufferSize
,
36 (OutputBufferSize
) ? (ULONG
)*OutputBufferSize
: 0,
42 WARN_(SERMOUSE
, "IoBuildDeviceIoControlRequest() failed\n");
43 return STATUS_INSUFFICIENT_RESOURCES
;
46 Status
= IoCallDriver(DeviceObject
, Irp
);
48 if (Status
== STATUS_PENDING
)
50 INFO_(SERMOUSE
, "Operation pending\n");
51 KeWaitForSingleObject(&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
52 Status
= IoStatus
.Status
;
57 *OutputBufferSize
= (SIZE_T
)IoStatus
.Information
;
65 IN PDEVICE_OBJECT LowerDevice
,
68 OUT PULONG_PTR FilledBytes
)
71 IO_STATUS_BLOCK ioStatus
;
76 KeInitializeEvent(&event
, NotificationEvent
, FALSE
);
78 Irp
= IoBuildSynchronousFsdRequest(
88 Status
= IoCallDriver(LowerDevice
, Irp
);
89 if (Status
== STATUS_PENDING
)
91 KeWaitForSingleObject(&event
, Suspended
, KernelMode
, FALSE
, NULL
);
92 Status
= ioStatus
.Status
;
94 INFO_(SERMOUSE
, "Bytes received: %lu/%lu\n",
95 ioStatus
.Information
, BufferSize
);
96 *FilledBytes
= ioStatus
.Information
;
102 IN ULONG milliseconds
)
105 LARGE_INTEGER DueTime
;
107 DueTime
.QuadPart
= milliseconds
* -10;
108 KeInitializeTimer(&Timer
);
109 KeSetTimer(&Timer
, DueTime
, NULL
);
110 return KeWaitForSingleObject(&Timer
, Executive
, KernelMode
, FALSE
, NULL
);
114 SermouseDetectLegacyDevice(
115 IN PDEVICE_OBJECT LowerDevice
)
121 SERIAL_TIMEOUTS Timeouts
;
122 SERIAL_LINE_CONTROL LCR
;
123 ULONG_PTR i
, Count
= 0;
125 SERMOUSE_MOUSE_TYPE MouseType
= mtNone
;
128 TRACE_(SERMOUSE
, "SermouseDetectLegacyDevice(LowerDevice %p)\n", LowerDevice
);
130 RtlZeroMemory(Buffer
, sizeof(Buffer
));
133 Status
= ObOpenObjectByPointer(
141 if (!NT_SUCCESS(Status
)) return mtNone
;
144 TRACE_(SERMOUSE
, "Reset UART\n");
145 Mcr
= 0; /* MCR: DTR/RTS/OUT2 off */
146 Status
= DeviceIoControl(LowerDevice
, IOCTL_SERIAL_SET_MODEM_CONTROL
,
147 &Mcr
, sizeof(Mcr
), NULL
, NULL
);
148 if (!NT_SUCCESS(Status
)) goto ByeBye
;
150 /* Set communications parameters */
151 TRACE_(SERMOUSE
, "Set communications parameters\n");
154 Status
= DeviceIoControl(LowerDevice
, IOCTL_SERIAL_SET_FIFO_CONTROL
,
155 &Fcr
, sizeof(Fcr
), NULL
, NULL
);
156 if (!NT_SUCCESS(Status
)) goto ByeBye
;
157 /* Set serial port speed */
159 Status
= DeviceIoControl(LowerDevice
, IOCTL_SERIAL_SET_BAUD_RATE
,
160 &BaudRate
, sizeof(BaudRate
), NULL
, NULL
);
161 if (!NT_SUCCESS(Status
)) goto ByeBye
;
164 LCR
.Parity
= NO_PARITY
;
165 LCR
.StopBits
= STOP_BITS_2
;
166 Status
= DeviceIoControl(LowerDevice
, IOCTL_SERIAL_SET_LINE_CONTROL
,
167 &LCR
, sizeof(LCR
), NULL
, NULL
);
168 if (!NT_SUCCESS(Status
)) goto ByeBye
;
170 /* Flush receive buffer */
171 TRACE_(SERMOUSE
, "Flush receive buffer\n");
172 Command
= SERIAL_PURGE_RXCLEAR
;
173 Status
= DeviceIoControl(LowerDevice
, IOCTL_SERIAL_SET_MODEM_CONTROL
,
174 &Command
, sizeof(Command
), NULL
, NULL
);
175 if (!NT_SUCCESS(Status
)) goto ByeBye
;
180 TRACE_(SERMOUSE
, "Enable DTR/RTS\n");
181 Status
= DeviceIoControl(LowerDevice
, IOCTL_SERIAL_SET_DTR
,
182 NULL
, 0, NULL
, NULL
);
183 if (!NT_SUCCESS(Status
)) goto ByeBye
;
184 Status
= DeviceIoControl(LowerDevice
, IOCTL_SERIAL_SET_RTS
,
185 NULL
, 0, NULL
, NULL
);
186 if (!NT_SUCCESS(Status
)) goto ByeBye
;
188 /* Set timeout to 500 microseconds */
189 TRACE_(SERMOUSE
, "Set timeout to 500 microseconds\n");
190 Timeouts
.ReadIntervalTimeout
= 100;
191 Timeouts
.ReadTotalTimeoutMultiplier
= 0;
192 Timeouts
.ReadTotalTimeoutConstant
= 500;
193 Timeouts
.WriteTotalTimeoutMultiplier
= Timeouts
.WriteTotalTimeoutConstant
= 0;
194 Status
= DeviceIoControl(LowerDevice
, IOCTL_SERIAL_SET_TIMEOUTS
,
195 &Timeouts
, sizeof(Timeouts
), NULL
, NULL
);
196 if (!NT_SUCCESS(Status
)) goto ByeBye
;
198 /* Fill the read buffer */
199 TRACE_(SERMOUSE
, "Fill the read buffer\n");
200 Status
= ReadBytes(LowerDevice
, Buffer
, sizeof(Buffer
)/sizeof(Buffer
[0]), &Count
);
201 if (!NT_SUCCESS(Status
)) goto ByeBye
;
203 for (i
= 0; i
< Count
; i
++)
205 if (Buffer
[i
] == 'B')
207 /* Sign for Microsoft Ballpoint */
208 ERR_(SERMOUSE
, "Microsoft Ballpoint device detected. THIS DEVICE IS NOT YET SUPPORTED");
212 else if (Buffer
[i
] == 'M')
214 /* Sign for Microsoft Mouse protocol followed by button specifier */
215 if (i
== sizeof(Buffer
) - 1)
220 switch (Buffer
[i
+ 1])
223 INFO_(SERMOUSE
, "Microsoft Mouse with 3-buttons detected\n");
224 MouseType
= mtLogitech
;
227 INFO_(SERMOUSE
, "Microsoft Wheel Mouse detected\n");
228 MouseType
= mtWheelZ
;
231 INFO_(SERMOUSE
, "Microsoft Mouse with 2-buttons detected\n");
232 MouseType
= mtMicrosoft
;