ReactOS 0.4.16-dev-303-g11d5cb8
cport.c File Reference
#include <intrin.h>
#include <ioaccess.h>
#include <ntstatus.h>
#include <cportlib/cportlib.h>
#include <drivers/serial/ns16550.h>
Include dependency graph for cport.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define TIMEOUT_COUNT   1024 * 200
 

Functions

VOID NTAPI CpEnableFifo (IN PUCHAR Address, IN BOOLEAN Enable)
 
VOID NTAPI CpSetBaud (IN PCPPORT Port, IN ULONG BaudRate)
 
NTSTATUS NTAPI CpInitialize (IN PCPPORT Port, IN PUCHAR Address, IN ULONG BaudRate)
 
static BOOLEAN ComPortTest1 (IN PUCHAR Address)
 
static BOOLEAN ComPortTest2 (IN PUCHAR Address)
 
BOOLEAN NTAPI CpDoesPortExist (IN PUCHAR Address)
 
UCHAR NTAPI CpReadLsr (IN PCPPORT Port, IN UCHAR ExpectedValue)
 
USHORT NTAPI CpGetByte (IN PCPPORT Port, OUT PUCHAR Byte, IN BOOLEAN Wait, IN BOOLEAN Poll)
 
VOID NTAPI CpPutByte (IN PCPPORT Port, IN UCHAR Byte)
 

Variables

UCHAR RingIndicator
 

Macro Definition Documentation

◆ TIMEOUT_COUNT

#define TIMEOUT_COUNT   1024 * 200

Definition at line 42 of file cport.c.

Function Documentation

◆ ComPortTest1()

static BOOLEAN ComPortTest1 ( IN PUCHAR  Address)
static

Definition at line 127 of file cport.c.

128{
129 /*
130 * See "Building Hardware and Firmware to Complement Microsoft Windows Headless Operation"
131 * Out-of-Band Management Port Device Requirements:
132 * The device must act as a 16550 or 16450 UART.
133 * Windows Server 2003 will test this device using the following process:
134 * 1. Save off the current modem status register.
135 * 2. Place the UART into diagnostic mode (The UART is placed into loopback mode
136 * by writing SERIAL_MCR_LOOP to the modem control register).
137 * 3. The modem status register is read and the high bits are checked. This means
138 * SERIAL_MSR_CTS, SERIAL_MSR_DSR, SERIAL_MSR_RI and SERIAL_MSR_DCD should
139 * all be clear.
140 * 4. Place the UART in diagnostic mode and turn on OUTPUT (Loopback Mode and
141 * OUTPUT are both turned on by writing (SERIAL_MCR_LOOP | SERIAL_MCR_OUT1)
142 * to the modem control register).
143 * 5. The modem status register is read and the ring indicator is checked.
144 * This means SERIAL_MSR_RI should be set.
145 * 6. Restore original modem status register.
146 *
147 * REMARK: Strangely enough, the Virtual PC 2007 virtual machine
148 * doesn't pass this test.
149 */
150
151 BOOLEAN RetVal = FALSE;
152 UCHAR Mcr, Msr;
153
154 /* Save the Modem Control Register */
156
157 /* Enable loop (diagnostic) mode (set Bit 4 of the MCR) */
159
160 /* Clear all modem output bits */
162
163 /* Read the Modem Status Register */
165
166 /*
167 * The upper nibble of the MSR (modem output bits) must be
168 * equal to the lower nibble of the MCR (modem input bits).
169 */
170 if ((Msr & (SERIAL_MSR_CTS | SERIAL_MSR_DSR | SERIAL_MSR_RI | SERIAL_MSR_DCD)) == 0x00)
171 {
172 /* Set all modem output bits */
174 SERIAL_MCR_OUT1 | SERIAL_MCR_LOOP); // Windows
175/* ReactOS
176 WRITE_PORT_UCHAR(Address + MODEM_CONTROL_REGISTER,
177 SERIAL_MCR_DTR | SERIAL_MCR_RTS | SERIAL_MCR_OUT1 | SERIAL_MCR_OUT2 | SERIAL_MCR_LOOP);
178*/
179
180 /* Read the Modem Status Register */
182
183 /*
184 * The upper nibble of the MSR (modem output bits) must be
185 * equal to the lower nibble of the MCR (modem input bits).
186 */
187 if (Msr & SERIAL_MSR_RI) // Windows
188 // if (Msr & (SERIAL_MSR_CTS | SERIAL_MSR_DSR | SERIAL_MSR_RI | SERIAL_MSR_DCD) == 0xF0) // ReactOS
189 {
190 RetVal = TRUE;
191 }
192 }
193
194 /* Restore the MCR */
196
197 return RetVal;
198}
unsigned char BOOLEAN
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define SERIAL_MCR_OUT1
Definition: ns16550.h:123
#define SERIAL_MSR_CTS
Definition: ns16550.h:147
#define SERIAL_MCR_LOOP
Definition: ns16550.h:125
#define SERIAL_MSR_DSR
Definition: ns16550.h:148
#define SERIAL_MSR_DCD
Definition: ns16550.h:150
#define MODEM_CONTROL_REGISTER
Definition: ns16550.h:37
#define SERIAL_MSR_RI
Definition: ns16550.h:149
#define MODEM_STATUS_REGISTER
Definition: ns16550.h:39
#define READ_PORT_UCHAR(p)
Definition: pc98vid.h:22
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
static WCHAR Address[46]
Definition: ping.c:68
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by CpDoesPortExist().

◆ ComPortTest2()

static BOOLEAN ComPortTest2 ( IN PUCHAR  Address)
static

Definition at line 201 of file cport.c.

202{
203 /*
204 * This test checks whether the 16450/16550 scratch register is available.
205 * If not, the serial port is considered as unexisting.
206 */
207
208 UCHAR Byte = 0;
209
210 do
211 {
213
215 return FALSE;
216
217 } while (++Byte != 0);
218
219 return TRUE;
220}
unsigned char Byte
Definition: zlib.h:37
#define SCRATCH_REGISTER
Definition: ns16550.h:40

Referenced by CpDoesPortExist().

◆ CpDoesPortExist()

BOOLEAN NTAPI CpDoesPortExist ( IN PUCHAR  Address)

Definition at line 224 of file cport.c.

225{
227}
static BOOLEAN ComPortTest2(IN PUCHAR Address)
Definition: cport.c:201
static BOOLEAN ComPortTest1(IN PUCHAR Address)
Definition: cport.c:127

Referenced by CpInitialize().

◆ CpEnableFifo()

VOID NTAPI CpEnableFifo ( IN PUCHAR  Address,
IN BOOLEAN  Enable 
)

Definition at line 51 of file cport.c.

53{
54 /* Set FIFO and clear the receive/transmit buffers */
58}
#define SERIAL_FCR_ENABLE
Definition: ns16550.h:82
#define SERIAL_FCR_DISABLE
Definition: ns16550.h:81
#define FIFO_CONTROL_REGISTER
Definition: ns16550.h:35
#define SERIAL_FCR_RCVR_RESET
Definition: ns16550.h:83
#define SERIAL_FCR_TXMT_RESET
Definition: ns16550.h:84
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:142

Referenced by CpInitialize().

◆ CpGetByte()

USHORT NTAPI CpGetByte ( IN PCPPORT  Port,
OUT PUCHAR  Byte,
IN BOOLEAN  Wait,
IN BOOLEAN  Poll 
)

Definition at line 253 of file cport.c.

257{
258 UCHAR Lsr;
259 ULONG LimitCount = Wait ? TIMEOUT_COUNT : 1;
260
261 /* Handle early read-before-init */
262 if (!Port->Address) return CP_GET_NODATA;
263
264 /* If "wait" mode enabled, spin many times, otherwise attempt just once */
265 while (LimitCount--)
266 {
267 /* Read LSR for data ready */
269 if ((Lsr & SERIAL_LSR_DR) == SERIAL_LSR_DR)
270 {
271 /* If an error happened, clear the byte and fail */
273 {
274 *Byte = 0;
275 return CP_GET_ERROR;
276 }
277
278 /* If only polling was requested by caller, return now */
279 if (Poll) return CP_GET_SUCCESS;
280
281 /* Otherwise read the byte and return it */
283
284 /* Handle CD if port is in modem control mode */
286 {
287 /* Not implemented yet */
288 // DPRINT1("CP: CPPORT_FLAG_MODEM_CONTROL unexpected\n");
289 }
290
291 /* Byte was read */
292 return CP_GET_SUCCESS;
293 }
294 }
295
296 /* Reset LSR, no data was found */
297 CpReadLsr(Port, 0);
298 return CP_GET_NODATA;
299}
#define TIMEOUT_COUNT
Definition: cport.c:42
UCHAR NTAPI CpReadLsr(IN PCPPORT Port, IN UCHAR ExpectedValue)
Definition: cport.c:231
#define CP_GET_SUCCESS
Definition: cportlib.h:18
#define CP_GET_NODATA
Definition: cportlib.h:19
#define CPPORT_FLAG_MODEM_CONTROL
Definition: cportlib.h:25
#define CP_GET_ERROR
Definition: cportlib.h:20
CPPORT Port[4]
Definition: headless.c:35
#define SERIAL_LSR_PE
Definition: ns16550.h:133
#define SERIAL_LSR_OE
Definition: ns16550.h:132
#define RECEIVE_BUFFER_REGISTER
Definition: ns16550.h:31
#define SERIAL_LSR_DR
Definition: ns16550.h:131
#define SERIAL_LSR_FE
Definition: ns16550.h:134
PUCHAR Address
Definition: cportlib.h:29
USHORT Flags
Definition: cportlib.h:31
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170

◆ CpInitialize()

NTSTATUS NTAPI CpInitialize ( IN PCPPORT  Port,
IN PUCHAR  Address,
IN ULONG  BaudRate 
)

Definition at line 85 of file cport.c.

88{
89 /* Validity checks */
90 if (Port == NULL || Address == NULL || BaudRate == 0)
92
94 return STATUS_NOT_FOUND;
95
96 /* Initialize port data */
98 Port->BaudRate = 0;
99 Port->Flags = 0;
100
101 /* Disable the interrupts */
104
105 /* Turn on DTR, RTS and OUT2 */
108
109 /* Set the baud rate */
110 CpSetBaud(Port, BaudRate);
111
112 /* Set 8 data bits, 1 stop bit, no parity, no break */
115
116 /* Turn on FIFO */
117 // TODO: Check whether FIFO exists and turn it on in that case.
118 CpEnableFifo(Address, TRUE); // for 16550
119
120 /* Read junk out of the RBR */
122
123 return STATUS_SUCCESS;
124}
#define VOID
Definition: acefi.h:82
VOID NTAPI CpEnableFifo(IN PUCHAR Address, IN BOOLEAN Enable)
Definition: cport.c:51
VOID NTAPI CpSetBaud(IN PCPPORT Port, IN ULONG BaudRate)
Definition: cport.c:62
BOOLEAN NTAPI CpDoesPortExist(IN PUCHAR Address)
Definition: cport.c:224
#define NULL
Definition: types.h:112
#define SERIAL_MCR_RTS
Definition: ns16550.h:122
#define INTERRUPT_ENABLE_REGISTER
Definition: ns16550.h:33
#define SERIAL_MCR_OUT2
Definition: ns16550.h:124
#define SERIAL_8_DATA
Definition: ns16550.h:103
#define SERIAL_NONE_PARITY
Definition: ns16550.h:111
#define SERIAL_MCR_DTR
Definition: ns16550.h:121
#define LINE_CONTROL_REGISTER
Definition: ns16550.h:36
#define SERIAL_1_STOP
Definition: ns16550.h:106
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
ULONG BaudRate
Definition: cportlib.h:30
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135

◆ CpPutByte()

VOID NTAPI CpPutByte ( IN PCPPORT  Port,
IN UCHAR  Byte 
)

Definition at line 303 of file cport.c.

305{
306 /* Check if port is in modem control to handle CD */
307 // while (Port->Flags & CPPORT_FLAG_MODEM_CONTROL) // Commented for the moment.
308 if (Port->Flags & CPPORT_FLAG_MODEM_CONTROL) // To be removed when this becomes implemented.
309 {
310 /* Not implemented yet */
311 // DPRINT1("CP: CPPORT_FLAG_MODEM_CONTROL unexpected\n");
312 }
313
314 /* Wait for LSR to say we can go ahead */
315 while ((CpReadLsr(Port, SERIAL_LSR_THRE) & SERIAL_LSR_THRE) == 0x00);
316
317 /* Send the byte */
319}
#define TRANSMIT_HOLDING_REGISTER
Definition: ns16550.h:32
#define SERIAL_LSR_THRE
Definition: ns16550.h:136

◆ CpReadLsr()

UCHAR NTAPI CpReadLsr ( IN PCPPORT  Port,
IN UCHAR  ExpectedValue 
)

Definition at line 231 of file cport.c.

233{
234 UCHAR Lsr, Msr;
235
236 /* Read the LSR and check if the expected value is present */
238 if (!(Lsr & ExpectedValue))
239 {
240 /* Check the MSR for ring indicator toggle */
242
243 /* If the indicator reaches 3, we've seen this on/off twice */
244 RingIndicator |= (Msr & SERIAL_MSR_RI) ? 1 : 2;
246 }
247
248 return Lsr;
249}
UCHAR RingIndicator
Definition: cport.c:44
#define LINE_STATUS_REGISTER
Definition: ns16550.h:38

Referenced by CpGetByte(), and CpPutByte().

◆ CpSetBaud()

VOID NTAPI CpSetBaud ( IN PCPPORT  Port,
IN ULONG  BaudRate 
)

Definition at line 62 of file cport.c.

64{
65 UCHAR Lcr;
66 ULONG Mode = CLOCK_RATE / BaudRate;
67
68 /* Set the DLAB on */
71
72 /* Set the baud rate */
75
76 /* Reset DLAB */
78
79 /* Save baud rate in port */
80 Port->BaudRate = BaudRate;
81}
_In_ ULONG Mode
Definition: hubbusif.h:303
#define DIVISOR_LATCH_MSB
Definition: ns16550.h:43
#define CLOCK_RATE
Definition: ns16550.h:21
#define DIVISOR_LATCH_LSB
Definition: ns16550.h:42
#define SERIAL_LCR_DLAB
Definition: ns16550.h:94

Referenced by CpInitialize().

Variable Documentation

◆ RingIndicator

UCHAR RingIndicator

Definition at line 44 of file cport.c.

Referenced by CpReadLsr().