ReactOS 0.4.16-dev-258-g81860b4
misc.c File Reference
#include "serial.h"
#include <debug.h>
Include dependency graph for misc.c:

Go to the source code of this file.

Functions

NTSTATUS NTAPI ForwardIrpAndForget (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
VOID NTAPI SerialReceiveByte (IN PKDPC Dpc, IN PVOID pDeviceExtension, IN PVOID Unused1, IN PVOID Unused2)
 
VOID NTAPI SerialSendByte (IN PKDPC Dpc, IN PVOID pDeviceExtension, IN PVOID Unused1, IN PVOID Unused2)
 
VOID NTAPI SerialCompleteIrp (IN PKDPC Dpc, IN PVOID pDeviceExtension, IN PVOID pIrp, IN PVOID Unused)
 
BOOLEAN NTAPI SerialInterruptService (IN PKINTERRUPT Interrupt, IN OUT PVOID ServiceContext)
 

Function Documentation

◆ ForwardIrpAndForget()

NTSTATUS NTAPI ForwardIrpAndForget ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 17 of file misc.c.

20{
21 PDEVICE_OBJECT LowerDevice = ((PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
22
23 ASSERT(LowerDevice);
24
26 return IoCallDriver(LowerDevice, Irp);
27}
_In_ PIRP Irp
Definition: csq.h:116
struct _SERIAL_DEVICE_EXTENSION * PSERIAL_DEVICE_EXTENSION
#define ASSERT(a)
Definition: mode.c:44
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define IoCallDriver
Definition: irp.c:1225
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055

◆ SerialCompleteIrp()

VOID NTAPI SerialCompleteIrp ( IN PKDPC  Dpc,
IN PVOID  pDeviceExtension,
IN PVOID  pIrp,
IN PVOID  Unused 
)

Definition at line 105 of file misc.c.

110{
112}
FxIrp * pIrp
#define IoCompleteRequest
Definition: irp.c:1240
#define IO_NO_INCREMENT
Definition: iotypes.h:598

Referenced by SerialAddDeviceInternal().

◆ SerialInterruptService()

BOOLEAN NTAPI SerialInterruptService ( IN PKINTERRUPT  Interrupt,
IN OUT PVOID  ServiceContext 
)

Definition at line 115 of file misc.c.

118{
120 PSERIAL_DEVICE_EXTENSION DeviceExtension;
121 PUCHAR ComPortBase;
122 UCHAR Iir;
123 ULONG Events = 0;
124 BOOLEAN ret = FALSE;
125
126 /* FIXME: sometimes, produce SERIAL_EV_RXFLAG event */
127
129 DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
130 ComPortBase = ULongToPtr(DeviceExtension->BaseAddress);
131
132 Iir = READ_PORT_UCHAR(SER_IIR(ComPortBase));
133 if (Iir == 0xff)
134 return TRUE;
135 Iir &= SR_IIR_ID_MASK;
136 if ((Iir & SR_IIR_SELF) != 0) { return FALSE; }
137
138 switch (Iir)
139 {
141 {
142 UCHAR MSR, IER;
143 TRACE_(SERIAL, "SR_IIR_MSR_CHANGE\n");
144
145 MSR = READ_PORT_UCHAR(SER_MSR(ComPortBase));
146 if (MSR & SR_MSR_CTS_CHANGED)
147 {
148 if (MSR & SR_MSR_CTS)
149 KeInsertQueueDpc(&DeviceExtension->SendByteDpc, NULL, NULL);
150 else
151 {
152 ; /* FIXME: stop transmission */
153 }
155 }
156 if (MSR & SR_MSR_DSR_CHANGED)
157 {
158 if (MSR & SR_MSR_DSR)
159 KeInsertQueueDpc(&DeviceExtension->ReceivedByteDpc, NULL, NULL);
160 else
161 {
162 ; /* FIXME: stop reception */
163 }
165 }
166 if (MSR & SR_MSR_RI_CHANGED)
167 {
168 INFO_(SERIAL, "SR_MSR_RI_CHANGED changed: now %d\n", MSR & SI_MSR_RI);
170 }
171 if (MSR & SR_MSR_DCD_CHANGED)
172 {
173 INFO_(SERIAL, "SR_MSR_DCD_CHANGED changed: now %d\n", MSR & SR_MSR_DCD);
175 }
176 IER = READ_PORT_UCHAR(SER_IER(ComPortBase));
177 WRITE_PORT_UCHAR(SER_IER(ComPortBase), IER | SR_IER_MSR_CHANGE);
178
179 ret = TRUE;
180 goto done;
181 }
182 case SR_IIR_THR_EMPTY:
183 {
184 TRACE_(SERIAL, "SR_IIR_THR_EMPTY\n");
185
186 KeInsertQueueDpc(&DeviceExtension->SendByteDpc, NULL, NULL);
188
189 ret = TRUE;
190 goto done;
191 }
193 {
194 ULONG AlreadyReceivedBytes, Limit;
195 TRACE_(SERIAL, "SR_IIR_DATA_RECEIVED\n");
196
197 KeInsertQueueDpc(&DeviceExtension->ReceivedByteDpc, NULL, NULL);
199
200 /* Check if buffer will be 80% full */
201 AlreadyReceivedBytes = GetNumberOfElementsInCircularBuffer(
202 &DeviceExtension->InputBuffer) * 5;
203 Limit = DeviceExtension->InputBuffer.Length * 4;
204 if (AlreadyReceivedBytes < Limit && AlreadyReceivedBytes + 1 >= Limit)
205 {
206 /* Buffer is full at 80% */
208 }
209
210 ret = TRUE;
211 goto done;
212 }
213 case SR_IIR_ERROR:
214 {
215 UCHAR LSR;
216 TRACE_(SERIAL, "SR_IIR_ERROR\n");
217
218 LSR = READ_PORT_UCHAR(SER_LSR(ComPortBase));
219 if (LSR & SR_LSR_OVERRUN_ERROR)
220 {
223 }
224 if (LSR & SR_LSR_PARITY_ERROR)
225 {
228 }
229 if (LSR & SR_LSR_FRAMING_ERROR)
230 {
233 }
234 if (LSR & SR_LSR_BREAK_INT)
235 {
238 }
239
240 ret = TRUE;
241 goto done;
242 }
243 }
244
245done:
246 if (!ret)
247 return FALSE;
248 if (DeviceExtension->WaitOnMaskIrp && (Events & DeviceExtension->WaitMask))
249 {
250 /* Finish pending IRP */
251 PULONG pEvents = (PULONG)DeviceExtension->WaitOnMaskIrp->AssociatedIrp.SystemBuffer;
252
253 DeviceExtension->WaitOnMaskIrp->IoStatus.Status = STATUS_SUCCESS;
254 DeviceExtension->WaitOnMaskIrp->IoStatus.Information = sizeof(ULONG);
255 *pEvents = Events;
256 KeInsertQueueDpc(&DeviceExtension->CompleteIrpDpc, DeviceExtension->WaitOnMaskIrp, NULL);
257
258 /* We are now ready to handle another IRP, even if this one is not completed */
259 DeviceExtension->WaitOnMaskIrp = NULL;
260 return TRUE;
261 }
262 return TRUE;
263}
unsigned char BOOLEAN
#define InterlockedIncrement
Definition: armddk.h:53
HANDLE Events[3]
Definition: schedsvc.c:40
#define ULongToPtr(ul)
Definition: basetsd.h:92
ULONG GetNumberOfElementsInCircularBuffer(IN PCIRCULAR_BUFFER pBuffer)
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define TRACE_(x)
Definition: compat.h:76
BOOLEAN NTAPI KeInsertQueueDpc(IN PKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: dpc.c:725
#define SR_MSR_RI_CHANGED
Definition: serial.h:164
#define SR_IIR_DATA_RECEIVED
Definition: serial.h:125
#define SER_MSR(x)
Definition: serial.h:161
#define SI_MSR_RI
Definition: serial.h:168
#define SR_MSR_DCD
Definition: serial.h:169
#define SR_IIR_MSR_CHANGE
Definition: serial.h:123
#define SR_MSR_DCD_CHANGED
Definition: serial.h:165
#define SR_LSR_OVERRUN_ERROR
Definition: serial.h:154
#define SR_LSR_BREAK_INT
Definition: serial.h:157
#define SR_MSR_DSR
Definition: serial.h:167
#define SR_LSR_PARITY_ERROR
Definition: serial.h:155
#define SR_MSR_DSR_CHANGED
Definition: serial.h:163
#define SER_IIR(x)
Definition: serial.h:120
#define SR_MSR_CTS_CHANGED
Definition: serial.h:162
#define SER_IER(x)
Definition: serial.h:112
#define SR_MSR_CTS
Definition: serial.h:166
#define SR_LSR_FRAMING_ERROR
Definition: serial.h:156
#define SR_IIR_SELF
Definition: serial.h:121
#define SER_LSR(x)
Definition: serial.h:152
#define SR_IIR_ERROR
Definition: serial.h:126
#define SR_IIR_ID_MASK
Definition: serial.h:122
#define SR_IIR_THR_EMPTY
Definition: serial.h:124
#define SR_IER_MSR_CHANGE
Definition: serial.h:116
struct _DEVICE_OBJECT * PDEVICE_OBJECT
#define SERIAL_EV_TXEMPTY
Definition: serial.c:101
#define SERIAL_EV_RING
Definition: serial.c:107
#define SERIAL_EV_RX80FULL
Definition: serial.c:109
#define SERIAL_EV_BREAK
Definition: serial.c:105
#define SERIAL_EV_RXCHAR
Definition: serial.c:99
#define SERIAL_EV_DSR
Definition: serial.c:103
#define SERIAL_EV_RLSD
Definition: serial.c:104
#define SERIAL_EV_ERR
Definition: serial.c:106
#define SERIAL_EV_CTS
Definition: serial.c:102
#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 STATUS_SUCCESS
Definition: shellext.h:65
ULONG Length
Definition: serial.h:43
PVOID SystemBuffer
union _IRP::@1581 AssociatedIrp
IO_STATUS_BLOCK IoStatus
ULONG ParityErrorCount
Definition: ntddser.h:299
ULONG FrameErrorCount
Definition: ntddser.h:296
ULONG SerialOverrunErrorCount
Definition: ntddser.h:297
ULONG BreakInterruptErrorCount
Definition: serial.h:70
CIRCULAR_BUFFER InputBuffer
Definition: serial.h:75
SERIALPERF_STATS SerialPerfStats
Definition: serial.h:71
uint32_t * PULONG
Definition: typedefs.h:59
int32_t * PLONG
Definition: typedefs.h:58
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
int ret
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID ServiceContext
Definition: iofuncs.h:801
_In_ LONG _In_ LONG Limit
Definition: kefuncs.h:304
unsigned char UCHAR
Definition: xmlstorage.h:181

◆ SerialReceiveByte()

VOID NTAPI SerialReceiveByte ( IN PKDPC  Dpc,
IN PVOID  pDeviceExtension,
IN PVOID  Unused1,
IN PVOID  Unused2 
)

Definition at line 30 of file misc.c.

35{
36 PSERIAL_DEVICE_EXTENSION DeviceExtension;
37 PUCHAR ComPortBase;
38 UCHAR Byte;
39 KIRQL Irql;
40 UCHAR IER;
42
43 DeviceExtension = (PSERIAL_DEVICE_EXTENSION)pDeviceExtension;
44 ComPortBase = ULongToPtr(DeviceExtension->BaseAddress);
45
46 KeAcquireSpinLock(&DeviceExtension->InputBufferLock, &Irql);
47 while (READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_DATA_RECEIVED)
48 {
49 Byte = READ_PORT_UCHAR(SER_RBR(ComPortBase));
50 INFO_(SERIAL, "Byte received on COM%lu: 0x%02x\n",
51 DeviceExtension->ComPort, Byte);
52 Status = PushCircularBufferEntry(&DeviceExtension->InputBuffer, Byte);
53 if (NT_SUCCESS(Status))
54 DeviceExtension->SerialPerfStats.ReceivedCount++;
55 else
57 }
58 KeSetEvent(&DeviceExtension->InputBufferNotEmpty, 0, FALSE);
59 KeReleaseSpinLock(&DeviceExtension->InputBufferLock, Irql);
60
61 /* allow new interrupts */
62 IER = READ_PORT_UCHAR(SER_IER(ComPortBase));
64}
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS PushCircularBufferEntry(IN PCIRCULAR_BUFFER pBuffer, IN UCHAR Entry)
_Out_ PKIRQL Irql
Definition: csq.h:179
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
unsigned char Byte
Definition: zlib.h:37
#define SER_RBR(x)
Definition: serial.h:109
#define SR_IER_DATA_RECEIVED
Definition: serial.h:113
#define SR_LSR_DATA_RECEIVED
Definition: serial.h:153
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
Status
Definition: gdiplustypes.h:25
ULONG ReceivedCount
Definition: ntddser.h:294
ULONG BufferOverrunErrorCount
Definition: ntddser.h:298
KSPIN_LOCK InputBufferLock
Definition: serial.h:76
KEVENT InputBufferNotEmpty
Definition: serial.h:74

Referenced by SerialAddDeviceInternal().

◆ SerialSendByte()

VOID NTAPI SerialSendByte ( IN PKDPC  Dpc,
IN PVOID  pDeviceExtension,
IN PVOID  Unused1,
IN PVOID  Unused2 
)

Definition at line 67 of file misc.c.

72{
73 PSERIAL_DEVICE_EXTENSION DeviceExtension;
74 PUCHAR ComPortBase;
75 UCHAR Byte;
76 KIRQL Irql;
77 UCHAR IER;
79
80 DeviceExtension = (PSERIAL_DEVICE_EXTENSION)pDeviceExtension;
81 ComPortBase = ULongToPtr(DeviceExtension->BaseAddress);
82
83 KeAcquireSpinLock(&DeviceExtension->OutputBufferLock, &Irql);
84 while (!IsCircularBufferEmpty(&DeviceExtension->OutputBuffer)
85 && READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_THR_EMPTY)
86 {
87 Status = PopCircularBufferEntry(&DeviceExtension->OutputBuffer, &Byte);
88 if (!NT_SUCCESS(Status))
89 break;
90 WRITE_PORT_UCHAR(SER_THR(ComPortBase), Byte);
91 INFO_(SERIAL, "Byte sent to COM%lu: 0x%02x\n",
92 DeviceExtension->ComPort, Byte);
93 DeviceExtension->SerialPerfStats.TransmittedCount++;
94 }
95 if (!IsCircularBufferEmpty(&DeviceExtension->OutputBuffer))
96 {
97 /* allow new interrupts */
98 IER = READ_PORT_UCHAR(SER_IER(ComPortBase));
99 WRITE_PORT_UCHAR(SER_IER(ComPortBase), IER | SR_IER_THR_EMPTY);
100 }
101 KeReleaseSpinLock(&DeviceExtension->OutputBufferLock, Irql);
102}
BOOLEAN IsCircularBufferEmpty(IN PCIRCULAR_BUFFER pBuffer)
NTSTATUS PopCircularBufferEntry(IN PCIRCULAR_BUFFER pBuffer, OUT PUCHAR Entry)
#define SR_IER_THR_EMPTY
Definition: serial.h:114
#define SR_LSR_THR_EMPTY
Definition: serial.h:158
#define SER_THR(x)
Definition: serial.h:110
ULONG TransmittedCount
Definition: ntddser.h:295
KSPIN_LOCK OutputBufferLock
Definition: serial.h:78
CIRCULAR_BUFFER OutputBuffer
Definition: serial.h:77

Referenced by SerialAddDeviceInternal(), and SerialWrite().