ReactOS  0.4.14-dev-1036-g3c5b10f
cport.c File Reference
#include <cportlib/cportlib.h>
#include <drivers/serial/ns16550.h>
#include <intrin.h>
#include <ioaccess.h>
#include <ntstatus.h>
#include <debug.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 NDEBUG
 
#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

◆ NDEBUG

#define NDEBUG

Definition at line 39 of file cport.c.

◆ TIMEOUT_COUNT

#define TIMEOUT_COUNT   1024 * 200

Definition at line 45 of file cport.c.

Function Documentation

◆ ComPortTest1()

static BOOLEAN ComPortTest1 ( IN PUCHAR  Address)
static

Definition at line 130 of file cport.c.

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

Referenced by CpDoesPortExist().

◆ ComPortTest2()

static BOOLEAN ComPortTest2 ( IN PUCHAR  Address)
static

Definition at line 204 of file cport.c.

205 {
206  /*
207  * This test checks whether the 16450/16550 scratch register is available.
208  * If not, the serial port is considered as unexisting.
209  */
210 
211  UCHAR Byte = 0;
212 
213  do
214  {
216 
218  return FALSE;
219 
220  } while (++Byte != 0);
221 
222  return TRUE;
223 }
#define SCRATCH_REGISTER
Definition: ns16550.h:40
#define TRUE
Definition: types.h:120
unsigned char Byte
Definition: zconf.h:391
UCHAR NTAPI READ_PORT_UCHAR(PUCHAR Address)
Definition: mach.c:528
static WCHAR Address[46]
Definition: ping.c:68
unsigned char UCHAR
Definition: xmlstorage.h:181
void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value)
Definition: mach.c:532

Referenced by CpDoesPortExist().

◆ CpDoesPortExist()

BOOLEAN NTAPI CpDoesPortExist ( IN PUCHAR  Address)

Definition at line 227 of file cport.c.

228 {
229  return ( ComPortTest1(Address) || ComPortTest2(Address) );
230 }
static BOOLEAN ComPortTest2(IN PUCHAR Address)
Definition: cport.c:204
static BOOLEAN ComPortTest1(IN PUCHAR Address)
Definition: cport.c:130
static WCHAR Address[46]
Definition: ping.c:68

Referenced by CpInitialize(), DetectSerialPorts(), InbvPortInitialize(), KdDebuggerInitialize0(), KdPortInitializeEx(), and WinLdrPortInitialize().

◆ CpEnableFifo()

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

Definition at line 54 of file cport.c.

56 {
57  /* Set FIFO and clear the receive/transmit buffers */
61 }
#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 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
void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value)
Definition: mach.c:532

Referenced by CpInitialize(), InbvPortEnableFifo(), and WinLdrEnableFifo().

◆ CpGetByte()

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

Definition at line 256 of file cport.c.

260 {
261  UCHAR Lsr;
262  ULONG LimitCount = Wait ? TIMEOUT_COUNT : 1;
263 
264  /* Handle early read-before-init */
265  if (!Port->Address) return CP_GET_NODATA;
266 
267  /* If "wait" mode enabled, spin many times, otherwise attempt just once */
268  while (LimitCount--)
269  {
270  /* Read LSR for data ready */
271  Lsr = CpReadLsr(Port, SERIAL_LSR_DR);
272  if ((Lsr & SERIAL_LSR_DR) == SERIAL_LSR_DR)
273  {
274  /* If an error happened, clear the byte and fail */
275  if (Lsr & (SERIAL_LSR_FE | SERIAL_LSR_PE | SERIAL_LSR_OE))
276  {
277  *Byte = 0;
278  return CP_GET_ERROR;
279  }
280 
281  /* If only polling was requested by caller, return now */
282  if (Poll) return CP_GET_SUCCESS;
283 
284  /* Otherwise read the byte and return it */
286 
287  /* Handle CD if port is in modem control mode */
289  {
290  /* Not implemented yet */
291  // DPRINT1("CP: CPPORT_FLAG_MODEM_CONTROL unexpected\n");
292  }
293 
294  /* Byte was read */
295  return CP_GET_SUCCESS;
296  }
297  }
298 
299  /* Reset LSR, no data was found */
300  CpReadLsr(Port, 0);
301  return CP_GET_NODATA;
302 }
CPPORT Port[4]
Definition: headless.c:34
#define SERIAL_LSR_PE
Definition: ns16550.h:133
#define CP_GET_ERROR
Definition: cportlib.h:20
unsigned char Byte
Definition: zconf.h:391
UCHAR NTAPI READ_PORT_UCHAR(PUCHAR Address)
Definition: mach.c:528
#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:45
UCHAR NTAPI CpReadLsr(IN PCPPORT Port, IN UCHAR ExpectedValue)
Definition: cport.c:234
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 int ULONG
Definition: retypes.h:1
#define CP_GET_NODATA
Definition: cportlib.h:19
#define SERIAL_LSR_OE
Definition: ns16550.h:132
IN BOOLEAN Wait
Definition: fatprocs.h:1529

Referenced by InbvPortGetByte(), InbvPortPollOnly(), KdPortGetByteEx(), KdpPollByte(), KdpReceiveByte(), WinLdrPortGetByte(), and WinLdrPortPollOnly().

◆ CpInitialize()

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

Definition at line 88 of file cport.c.

91 {
92  /* Validity checks */
93  if (Port == NULL || Address == NULL || BaudRate == 0)
95 
97  return STATUS_NOT_FOUND;
98 
99  /* Initialize port data */
100  Port->Address = Address;
101  Port->BaudRate = 0;
102  Port->Flags = 0;
103 
104  /* Disable the interrupts */
107 
108  /* Turn on DTR, RTS and OUT2 */
111 
112  /* Set the baud rate */
113  CpSetBaud(Port, BaudRate);
114 
115  /* Set 8 data bits, 1 stop bit, no parity, no break */
118 
119  /* Turn on FIFO */
120  // TODO: Check whether FIFO exists and turn it on in that case.
121  CpEnableFifo(Address, TRUE); // for 16550
122 
123  /* Read junk out of the RBR */
125 
126  return STATUS_SUCCESS;
127 }
CPPORT Port[4]
Definition: headless.c:34
#define TRUE
Definition: types.h:120
VOID NTAPI CpEnableFifo(IN PUCHAR Address, IN BOOLEAN Enable)
Definition: cport.c:54
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
UCHAR NTAPI READ_PORT_UCHAR(PUCHAR Address)
Definition: mach.c:528
#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
smooth NULL
Definition: ftsmooth.c:416
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:65
#define SERIAL_NONE_PARITY
Definition: ns16550.h:111
BOOLEAN NTAPI CpDoesPortExist(IN PUCHAR Address)
Definition: cport.c:227
#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
void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value)
Definition: mach.c:532
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define LINE_CONTROL_REGISTER
Definition: ns16550.h:36

Referenced by InbvPortInitialize(), KdDebuggerInitialize0(), KdPortInitializeEx(), KdpPortInitialize(), LlbHwOmap3UartInitialize(), and WinLdrPortInitialize().

◆ CpPutByte()

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

Definition at line 306 of file cport.c.

308 {
309  /* Check if port is in modem control to handle CD */
310  // while (Port->Flags & CPPORT_FLAG_MODEM_CONTROL) // Commented for the moment.
311  if (Port->Flags & CPPORT_FLAG_MODEM_CONTROL) // To be removed when this becomes implemented.
312  {
313  /* Not implemented yet */
314  // DPRINT1("CP: CPPORT_FLAG_MODEM_CONTROL unexpected\n");
315  }
316 
317  /* Wait for LSR to say we can go ahead */
318  while ((CpReadLsr(Port, SERIAL_LSR_THRE) & SERIAL_LSR_THRE) == 0x00);
319 
320  /* Send the byte */
322 }
CPPORT Port[4]
Definition: headless.c:34
#define SERIAL_LSR_THRE
Definition: ns16550.h:136
unsigned char Byte
Definition: zconf.h:391
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:234
PUCHAR Address
Definition: cportlib.h:29
#define CPPORT_FLAG_MODEM_CONTROL
Definition: cportlib.h:25
void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value)
Definition: mach.c:532

Referenced by InbvPortPutByte(), KdPortPutByteEx(), KdpSendByte(), LlbHwUartSendChar(), and WinLdrPortPutByte().

◆ CpReadLsr()

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

Definition at line 234 of file cport.c.

236 {
237  UCHAR Lsr, Msr;
238 
239  /* Read the LSR and check if the expected value is present */
241  if (!(Lsr & ExpectedValue))
242  {
243  /* Check the MSR for ring indicator toggle */
245 
246  /* If the indicator reaches 3, we've seen this on/off twice */
247  RingIndicator |= (Msr & SERIAL_MSR_RI) ? 1 : 2;
249  }
250 
251  return Lsr;
252 }
CPPORT Port[4]
Definition: headless.c:34
#define LINE_STATUS_REGISTER
Definition: ns16550.h:38
UCHAR NTAPI READ_PORT_UCHAR(PUCHAR Address)
Definition: mach.c:528
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:47
#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 65 of file cport.c.

67 {
68  UCHAR Lcr;
69  ULONG Mode = CLOCK_RATE / BaudRate;
70 
71  /* Set the DLAB on */
74 
75  /* Set the baud rate */
78 
79  /* Reset DLAB */
81 
82  /* Save baud rate in port */
83  Port->BaudRate = BaudRate;
84 }
CPPORT Port[4]
Definition: headless.c:34
#define CLOCK_RATE
Definition: ns16550.h:21
#define DIVISOR_LATCH_LSB
Definition: ns16550.h:42
_In_ ULONG Mode
Definition: hubbusif.h:303
UCHAR NTAPI READ_PORT_UCHAR(PUCHAR Address)
Definition: mach.c:528
#define DIVISOR_LATCH_MSB
Definition: ns16550.h:43
unsigned char UCHAR
Definition: xmlstorage.h:181
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
void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value)
Definition: mach.c:532
#define LINE_CONTROL_REGISTER
Definition: ns16550.h:36

Referenced by CpInitialize().

Variable Documentation

◆ RingIndicator

UCHAR RingIndicator

Definition at line 47 of file cport.c.

Referenced by CpReadLsr().