ReactOS 0.4.15-dev-8131-g4988de4
readwrite.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/input/i8042prt/readwrite.c
5 * PURPOSE: Read/write port functions
6 * PROGRAMMERS: Copyright Victor Kirhenshtein (sauros@iname.com)
7 Copyright Jason Filby (jasonfilby@yahoo.com)
8 Copyright Martijn Vernooij (o112w8r02@sneakemail.com)
9 Copyright 2006-2007 Hervé Poussineau (hpoussin@reactos.org)
10 */
11
12/* INCLUDES ******************************************************************/
13
14#include "i8042prt.h"
15
16#include <debug.h>
17
18/* FUNCTIONS *****************************************************************/
19
20VOID
22 IN PPORT_DEVICE_EXTENSION DeviceExtension)
23{
24 UCHAR Ignore;
25
26 /* Flush output buffer */
27 while (NT_SUCCESS(i8042ReadData(DeviceExtension, KBD_OBF /* | MOU_OBF*/, &Ignore))) {
29 TRACE_(I8042PRT, "Output data flushed\n");
30 }
31
32 /* Flush input buffer */
33 while (NT_SUCCESS(i8042ReadData(DeviceExtension, KBD_IBF, &Ignore))) {
35 TRACE_(I8042PRT, "Input data flushed\n");
36 }
37}
38
41 IN PPORT_DEVICE_EXTENSION DeviceExtension,
43 IN UCHAR SelectCmd OPTIONAL)
44{
45 if (SelectCmd)
46 if (!i8042Write(DeviceExtension, DeviceExtension->ControlPort, SelectCmd))
47 return FALSE;
48
49 return i8042Write(DeviceExtension, DeviceExtension->DataPort, Value);
50}
51
52/*
53 * FUNCTION: Read data from port 0x60
54 */
57 IN PPORT_DEVICE_EXTENSION DeviceExtension,
58 IN UCHAR StatusFlags,
60{
63
64 Status = i8042ReadStatus(DeviceExtension, &PortStatus);
65 if (!NT_SUCCESS(Status))
66 return Status;
67
68 // If data is available
69 if (PortStatus & StatusFlags)
70 {
71 *Data = READ_PORT_UCHAR(DeviceExtension->DataPort);
72 INFO_(I8042PRT, "Read: 0x%02x (status: 0x%x)\n", Data[0], PortStatus);
73
74 // If the data is valid (not timeout, not parity error)
75 if ((PortStatus & KBD_PERR) == 0)
76 return STATUS_SUCCESS;
77 }
79}
80
83 IN PPORT_DEVICE_EXTENSION DeviceExtension,
85{
86 ASSERT(DeviceExtension->ControlPort != NULL);
87 *Status = READ_PORT_UCHAR(DeviceExtension->ControlPort);
88 return STATUS_SUCCESS;
89}
90
91/*
92 * FUNCTION: Read data from data port
93 */
96 IN PPORT_DEVICE_EXTENSION DeviceExtension,
98{
101
102 Counter = DeviceExtension->Settings.PollingIterations;
103
104 while (Counter--)
105 {
106 Status = i8042ReadKeyboardData(DeviceExtension, Data);
107
108 if (NT_SUCCESS(Status))
109 return Status;
110
112 }
113
114 /* Timed out */
115 return STATUS_IO_TIMEOUT;
116}
117
118/*
119 * This one reads a value from the port; You don't have to specify
120 * which one, it'll always be from the one you talked to, so one function
121 * is enough this time. Note how MSDN specifies the
122 * WaitForAck parameter to be ignored.
123 */
128 IN BOOLEAN WaitForAck)
129{
130 PPORT_DEVICE_EXTENSION DeviceExtension;
131
132 UNREFERENCED_PARAMETER(WaitForAck);
133
134 DeviceExtension = (PPORT_DEVICE_EXTENSION)Context;
135
136 return i8042ReadDataWait(DeviceExtension, Value);
137}
138
139/*
140 * These functions are callbacks for filter driver custom
141 * initialization routines.
142 */
145 IN PPORT_DEVICE_EXTENSION DeviceExtension,
146 IN UCHAR Port,
147 IN UCHAR Value,
148 IN BOOLEAN WaitForAck)
149{
151 UCHAR Ack;
152 ULONG ResendIterations;
153
154 ResendIterations = DeviceExtension->Settings.ResendIterations + 1;
155
156 do
157 {
158 if (Port)
159 if (!i8042Write(DeviceExtension, DeviceExtension->DataPort, Port))
160 {
161 WARN_(I8042PRT, "Failed to write Port\n");
162 return STATUS_IO_TIMEOUT;
163 }
164
165 if (!i8042Write(DeviceExtension, DeviceExtension->DataPort, Value))
166 {
167 WARN_(I8042PRT, "Failed to write Value\n");
168 return STATUS_IO_TIMEOUT;
169 }
170
171 if (WaitForAck)
172 {
173 Status = i8042ReadDataWait(DeviceExtension, &Ack);
174 if (!NT_SUCCESS(Status))
175 {
176 WARN_(I8042PRT, "Failed to read Ack\n");
177 return Status;
178 }
179 if (Ack == KBD_ACK)
180 return STATUS_SUCCESS;
181 else if (Ack == KBD_RESEND)
182 INFO_(I8042PRT, "i8042 asks for a data resend\n");
183 }
184 else
185 {
186 return STATUS_SUCCESS;
187 }
188 TRACE_(I8042PRT, "Reiterating\n");
189 ResendIterations--;
190 } while (ResendIterations);
191
192 return STATUS_IO_TIMEOUT;
193}
194
195/*
196 * FUNCTION: Write data to a port, waiting first for it to become ready
197 */
200 IN PPORT_DEVICE_EXTENSION DeviceExtension,
201 IN PUCHAR addr,
202 IN UCHAR data)
203{
205
206 ASSERT(addr);
207 ASSERT(DeviceExtension->ControlPort != NULL);
208
209 Counter = DeviceExtension->Settings.PollingIterations;
210
211 while ((KBD_IBF & READ_PORT_UCHAR(DeviceExtension->ControlPort)) &&
212 (Counter--))
213 {
215 }
216
217 if (Counter)
218 {
220 INFO_(I8042PRT, "Sent 0x%x to port %p\n", data, addr);
221 return TRUE;
222 }
223 return FALSE;
224}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI KeStallExecutionProcessor(IN ULONG MicroSeconds)
Definition: ntoskrnl.c:81
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define TRACE_(x)
Definition: compat.h:76
NTSTATUS i8042ReadDataWait(IN PPORT_DEVICE_EXTENSION DeviceExtension, OUT PUCHAR Data)
Definition: readwrite.c:95
VOID i8042Flush(IN PPORT_DEVICE_EXTENSION DeviceExtension)
Definition: readwrite.c:21
NTSTATUS i8042ReadData(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR StatusFlags, OUT PUCHAR Data)
Definition: readwrite.c:56
NTSTATUS NTAPI i8042SynchReadPort(IN PVOID Context, OUT PUCHAR Value, IN BOOLEAN WaitForAck)
Definition: readwrite.c:125
BOOLEAN i8042IsrWritePort(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR Value, IN UCHAR SelectCmd OPTIONAL)
Definition: readwrite.c:40
NTSTATUS NTAPI i8042SynchWritePort(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR Port, IN UCHAR Value, IN BOOLEAN WaitForAck)
Definition: readwrite.c:144
NTSTATUS i8042ReadStatus(IN PPORT_DEVICE_EXTENSION DeviceExtension, OUT PUCHAR Status)
Definition: readwrite.c:82
BOOLEAN i8042Write(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN PUCHAR addr, IN UCHAR data)
Definition: readwrite.c:199
Status
Definition: gdiplustypes.h:25
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLenum const GLvoid * addr
Definition: glext.h:9621
CPPORT Port[4]
Definition: headless.c:35
_Outptr_ PUSB_DEVICE_HANDLE _In_ PUSB_DEVICE_HANDLE _In_ USHORT PortStatus
Definition: hubbusif.h:42
struct _PORT_DEVICE_EXTENSION * PPORT_DEVICE_EXTENSION
#define KBD_PERR
Definition: i8042prt.h:253
#define KBD_RESEND
Definition: i8042prt.h:244
#define KBD_IBF
Definition: i8042prt.h:251
#define KBD_OBF
Definition: i8042prt.h:250
#define KBD_ACK
Definition: i8042prt.h:242
#define i8042ReadKeyboardData(DeviceExtension, Data)
Definition: i8042prt.h:403
#define ASSERT(a)
Definition: mode.c:44
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define READ_PORT_UCHAR(p)
Definition: pc98vid.h:22
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
#define INFO_(ch,...)
Definition: debug.h:159
#define WARN_(ch,...)
Definition: debug.h:157
#define STATUS_SUCCESS
Definition: shellext.h:65
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
static LARGE_INTEGER Counter
Definition: clock.c:43
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_IO_TIMEOUT
Definition: udferr_usr.h:163
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
unsigned char UCHAR
Definition: xmlstorage.h:181