ReactOS  0.4.15-dev-5452-g3c95c95
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 }
#define SERIAL_MSR_DSR
Definition: ns16550.h:148
#define READ_PORT_UCHAR(p)
Definition: pc98vid.h:22
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
static WCHAR Address[46]
Definition: ping.c:68
#define SERIAL_MCR_OUT1
Definition: ns16550.h:123
#define MODEM_STATUS_REGISTER
Definition: ns16550.h:39
unsigned char UCHAR
Definition: xmlstorage.h:181
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
#define SERIAL_MSR_RI
Definition: ns16550.h:149
#define SERIAL_MSR_DCD
Definition: ns16550.h:150
#define MODEM_CONTROL_REGISTER
Definition: ns16550.h:37
#define SERIAL_MSR_CTS
Definition: ns16550.h:147
#define SERIAL_MCR_LOOP
Definition: ns16550.h:125

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 }
#define SCRATCH_REGISTER
Definition: ns16550.h:40
#define READ_PORT_UCHAR(p)
Definition: pc98vid.h:22
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static WCHAR Address[46]
Definition: ping.c:68
unsigned char UCHAR
Definition: xmlstorage.h:181
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
unsigned char Byte
Definition: zlib.h:37

Referenced by CpDoesPortExist().

◆ CpDoesPortExist()

BOOLEAN NTAPI CpDoesPortExist ( IN PUCHAR  Address)

Definition at line 224 of file cport.c.

225 {
226  return ( ComPortTest1(Address) || ComPortTest2(Address) );
227 }
static BOOLEAN ComPortTest2(IN PUCHAR Address)
Definition: cport.c:201
static BOOLEAN ComPortTest1(IN PUCHAR Address)
Definition: cport.c:127
static WCHAR Address[46]
Definition: ping.c:68

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_DISABLE
Definition: ns16550.h:81
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:140
#define SERIAL_FCR_ENABLE
Definition: ns16550.h:82
static WCHAR Address[46]
Definition: ping.c:68
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
#define SERIAL_FCR_RCVR_RESET
Definition: ns16550.h:83
#define FIFO_CONTROL_REGISTER
Definition: ns16550.h:35
#define SERIAL_FCR_TXMT_RESET
Definition: ns16550.h:84

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 */
268  Lsr = CpReadLsr(Port, SERIAL_LSR_DR);
269  if ((Lsr & SERIAL_LSR_DR) == SERIAL_LSR_DR)
270  {
271  /* If an error happened, clear the byte and fail */
272  if (Lsr & (SERIAL_LSR_FE | SERIAL_LSR_PE | SERIAL_LSR_OE))
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 }
CPPORT Port[4]
Definition: headless.c:35
#define SERIAL_LSR_PE
Definition: ns16550.h:133
#define CP_GET_ERROR
Definition: cportlib.h:20
#define READ_PORT_UCHAR(p)
Definition: pc98vid.h:22
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:167
#define SERIAL_LSR_DR
Definition: ns16550.h:131
#define RECEIVE_BUFFER_REGISTER
Definition: ns16550.h:31
USHORT Flags
Definition: cportlib.h:31
#define TIMEOUT_COUNT
Definition: cport.c:42
UCHAR NTAPI CpReadLsr(IN PCPPORT Port, IN UCHAR ExpectedValue)
Definition: cport.c:231
unsigned char UCHAR
Definition: xmlstorage.h:181
#define SERIAL_LSR_FE
Definition: ns16550.h:134
PUCHAR Address
Definition: cportlib.h:29
#define CPPORT_FLAG_MODEM_CONTROL
Definition: cportlib.h:25
#define CP_GET_SUCCESS
Definition: cportlib.h:18
unsigned char Byte
Definition: zlib.h:37
unsigned int ULONG
Definition: retypes.h:1
#define CP_GET_NODATA
Definition: cportlib.h:19
#define SERIAL_LSR_OE
Definition: ns16550.h:132

◆ 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 */
97  Port->Address = Address;
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 }
CPPORT Port[4]
Definition: headless.c:35
VOID NTAPI CpEnableFifo(IN PUCHAR Address, IN BOOLEAN Enable)
Definition: cport.c:51
#define READ_PORT_UCHAR(p)
Definition: pc98vid.h:22
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define SERIAL_MCR_OUT2
Definition: ns16550.h:124
#define SERIAL_MCR_RTS
Definition: ns16550.h:122
#define SERIAL_1_STOP
Definition: ns16550.h:106
#define INTERRUPT_ENABLE_REGISTER
Definition: ns16550.h:33
#define SERIAL_MCR_DTR
Definition: ns16550.h:121
#define RECEIVE_BUFFER_REGISTER
Definition: ns16550.h:31
USHORT Flags
Definition: cportlib.h:31
#define SERIAL_8_DATA
Definition: ns16550.h:103
static WCHAR Address[46]
Definition: ping.c:68
#define STATUS_NOT_FOUND
Definition: shellext.h:72
VOID NTAPI CpSetBaud(IN PCPPORT Port, IN ULONG BaudRate)
Definition: cport.c:62
#define SERIAL_NONE_PARITY
Definition: ns16550.h:111
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
BOOLEAN NTAPI CpDoesPortExist(IN PUCHAR Address)
Definition: cport.c:224
#define VOID
Definition: acefi.h:82
PUCHAR Address
Definition: cportlib.h:29
ULONG BaudRate
Definition: cportlib.h:30
#define MODEM_CONTROL_REGISTER
Definition: ns16550.h:37
#define NULL
Definition: types.h:112
#define STATUS_SUCCESS
Definition: shellext.h:65
#define LINE_CONTROL_REGISTER
Definition: ns16550.h:36

◆ 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 }
CPPORT Port[4]
Definition: headless.c:35
#define SERIAL_LSR_THRE
Definition: ns16550.h:136
USHORT Flags
Definition: cportlib.h:31
#define TRANSMIT_HOLDING_REGISTER
Definition: ns16550.h:32
UCHAR NTAPI CpReadLsr(IN PCPPORT Port, IN UCHAR ExpectedValue)
Definition: cport.c:231
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
PUCHAR Address
Definition: cportlib.h:29
#define CPPORT_FLAG_MODEM_CONTROL
Definition: cportlib.h:25
unsigned char Byte
Definition: zlib.h:37

◆ 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 }
CPPORT Port[4]
Definition: headless.c:35
#define LINE_STATUS_REGISTER
Definition: ns16550.h:38
#define READ_PORT_UCHAR(p)
Definition: pc98vid.h:22
USHORT Flags
Definition: cportlib.h:31
#define MODEM_STATUS_REGISTER
Definition: ns16550.h:39
unsigned char UCHAR
Definition: xmlstorage.h:181
PUCHAR Address
Definition: cportlib.h:29
#define SERIAL_MSR_RI
Definition: ns16550.h:149
UCHAR RingIndicator
Definition: cport.c:44
#define CPPORT_FLAG_MODEM_CONTROL
Definition: cportlib.h:25

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 }
CPPORT Port[4]
Definition: headless.c:35
#define CLOCK_RATE
Definition: ns16550.h:21
#define DIVISOR_LATCH_LSB
Definition: ns16550.h:42
_In_ ULONG Mode
Definition: hubbusif.h:303
#define READ_PORT_UCHAR(p)
Definition: pc98vid.h:22
#define DIVISOR_LATCH_MSB
Definition: ns16550.h:43
unsigned char UCHAR
Definition: xmlstorage.h:181
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
PUCHAR Address
Definition: cportlib.h:29
#define SERIAL_LCR_DLAB
Definition: ns16550.h:94
ULONG BaudRate
Definition: cportlib.h:30
unsigned int ULONG
Definition: retypes.h:1
#define LINE_CONTROL_REGISTER
Definition: ns16550.h:36

Referenced by CpInitialize().

Variable Documentation

◆ RingIndicator

UCHAR RingIndicator

Definition at line 44 of file cport.c.

Referenced by CpReadLsr().