ReactOS  0.4.14-dev-98-gb0d4763
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 
20 VOID
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 
39 BOOLEAN
41  IN PPORT_DEVICE_EXTENSION DeviceExtension,
42  IN UCHAR Value,
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,
59  OUT PUCHAR Data)
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  }
78  return STATUS_UNSUCCESSFUL;
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,
97  OUT PUCHAR Data)
98 {
99  ULONG Counter;
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  */
126  IN PVOID Context,
127  OUT PUCHAR Value,
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  */
198 BOOLEAN
200  IN PPORT_DEVICE_EXTENSION DeviceExtension,
201  IN PUCHAR addr,
202  IN UCHAR data)
203 {
204  ULONG Counter;
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 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
CPPORT Port[4]
Definition: headless.c:34
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
#define KBD_OBF
Definition: i8042prt.h:250
#define INFO_(ch,...)
Definition: debug.h:159
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
BOOLEAN i8042IsrWritePort(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR Value, IN UCHAR SelectCmd OPTIONAL)
Definition: readwrite.c:40
unsigned char * PUCHAR
Definition: retypes.h:3
UCHAR NTAPI READ_PORT_UCHAR(PUCHAR Address)
Definition: mach.c:528
LONG NTSTATUS
Definition: precomp.h:26
#define KBD_IBF
Definition: i8042prt.h:251
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
BOOLEAN i8042Write(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN PUCHAR addr, IN UCHAR data)
Definition: readwrite.c:199
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define TRACE_(x)
Definition: compat.h:66
#define KBD_PERR
Definition: i8042prt.h:253
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI i8042SynchWritePort(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR Port, IN UCHAR Value, IN BOOLEAN WaitForAck)
Definition: readwrite.c:144
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define KBD_ACK
Definition: i8042prt.h:242
unsigned char UCHAR
Definition: xmlstorage.h:181
struct _PORT_DEVICE_EXTENSION * PPORT_DEVICE_EXTENSION
GLenum const GLvoid * addr
Definition: glext.h:9621
#define i8042ReadKeyboardData(DeviceExtension, Data)
Definition: i8042prt.h:405
_Outptr_ PUSB_DEVICE_HANDLE _In_ PUSB_DEVICE_HANDLE _In_ USHORT PortStatus
Definition: hubbusif.h:40
Status
Definition: gdiplustypes.h:24
NTSTATUS i8042ReadStatus(IN PPORT_DEVICE_EXTENSION DeviceExtension, OUT PUCHAR Status)
Definition: readwrite.c:82
NTSTATUS i8042ReadDataWait(IN PPORT_DEVICE_EXTENSION DeviceExtension, OUT PUCHAR Data)
Definition: readwrite.c:95
#define KBD_RESEND
Definition: i8042prt.h:244
#define STATUS_IO_TIMEOUT
Definition: udferr_usr.h:163
static LARGE_INTEGER Counter
Definition: clock.c:43
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS NTAPI i8042SynchReadPort(IN PVOID Context, OUT PUCHAR Value, IN BOOLEAN WaitForAck)
Definition: readwrite.c:125
void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value)
Definition: mach.c:532
return STATUS_SUCCESS
Definition: btrfs.c:2966
NTSTATUS i8042ReadData(IN PPORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR StatusFlags, OUT PUCHAR Data)
Definition: readwrite.c:56
#define WARN_(ch,...)
Definition: debug.h:157
VOID NTAPI KeStallExecutionProcessor(IN ULONG MicroSeconds)
Definition: ntoskrnl.c:99
VOID i8042Flush(IN PPORT_DEVICE_EXTENSION DeviceExtension)
Definition: readwrite.c:21
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68