ReactOS  0.4.15-dev-4920-g5fa8403
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_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ PIRP Irp
Definition: csq.h:116
#define ASSERT(a)
Definition: mode.c:44
struct _SERIAL_DEVICE_EXTENSION * PSERIAL_DEVICE_EXTENSION
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421

◆ 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  {
140  case SR_IIR_MSR_CHANGE:
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));
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));
220  {
223  }
224  if (LSR & SR_LSR_PARITY_ERROR)
225  {
228  }
230  {
233  }
234  if (LSR & SR_LSR_BREAK_INT)
235  {
238  }
239 
240  ret = TRUE;
241  goto done;
242  }
243  }
244 
245 done:
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 }
#define ULongToPtr(ul)
Definition: basetsd.h:92
#define SERIAL_EV_RING
Definition: serial.c:107
#define INFO_(ch,...)
Definition: debug.h:159
#define READ_PORT_UCHAR(p)
Definition: pc98vid.h:22
#define TRUE
Definition: types.h:120
struct _DEVICE_OBJECT * PDEVICE_OBJECT
#define SR_IER_MSR_CHANGE
Definition: serial.h:116
unsigned char * PUCHAR
Definition: retypes.h:3
BOOLEAN NTAPI KeInsertQueueDpc(IN PKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: dpc.c:725
#define SERIAL_EV_DSR
Definition: serial.c:103
ULONG GetNumberOfElementsInCircularBuffer(IN PCIRCULAR_BUFFER pBuffer)
#define SR_MSR_DCD_CHANGED
Definition: serial.h:165
IO_STATUS_BLOCK IoStatus
#define SERIAL_EV_TXEMPTY
Definition: serial.c:101
#define SERIAL_EV_RX80FULL
Definition: serial.c:109
#define SERIAL_EV_RLSD
Definition: serial.c:104
#define SERIAL_EV_ERR
Definition: serial.c:106
#define SER_MSR(x)
Definition: serial.h:161
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define SR_MSR_DSR_CHANGED
Definition: serial.h:163
#define SR_MSR_RI_CHANGED
Definition: serial.h:164
#define FALSE
Definition: types.h:117
#define SR_LSR_PARITY_ERROR
Definition: serial.h:155
SERIALPERF_STATS SerialPerfStats
Definition: serial.h:71
#define SR_MSR_DCD
Definition: serial.h:169
#define IER
Definition: serial_port.h:62
#define SR_MSR_CTS_CHANGED
Definition: serial.h:162
unsigned char BOOLEAN
#define LSR
Definition: serial_port.h:67
ULONG SerialOverrunErrorCount
Definition: ntddser.h:297
#define SR_IIR_ID_MASK
Definition: serial.h:122
HANDLE Events[3]
Definition: schedsvc.c:40
#define TRACE_(x)
Definition: compat.h:76
ULONG BreakInterruptErrorCount
Definition: serial.h:70
#define SERIAL_EV_CTS
Definition: serial.c:102
#define MSR
Definition: serial_port.h:68
#define SR_LSR_OVERRUN_ERROR
Definition: serial.h:154
#define SER_IIR(x)
Definition: serial.h:120
#define SI_MSR_RI
Definition: serial.h:168
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID ServiceContext
Definition: iofuncs.h:800
ULONG Length
Definition: serial.h:43
unsigned char UCHAR
Definition: xmlstorage.h:181
#define SERIAL_EV_BREAK
Definition: serial.c:105
int ret
#define SR_LSR_FRAMING_ERROR
Definition: serial.h:156
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
#define SR_IIR_MSR_CHANGE
Definition: serial.h:123
#define SR_MSR_CTS
Definition: serial.h:166
#define SER_LSR(x)
Definition: serial.h:152
#define SR_IIR_DATA_RECEIVED
Definition: serial.h:125
#define InterlockedIncrement
Definition: armddk.h:53
#define SR_LSR_BREAK_INT
Definition: serial.h:157
struct _SERIAL_DEVICE_EXTENSION * PSERIAL_DEVICE_EXTENSION
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
#define SER_IER(x)
Definition: serial.h:112
ULONG FrameErrorCount
Definition: ntddser.h:296
#define SR_IIR_THR_EMPTY
Definition: serial.h:124
CIRCULAR_BUFFER InputBuffer
Definition: serial.h:75
unsigned int ULONG
Definition: retypes.h:1
#define SR_IIR_ERROR
Definition: serial.h:126
#define SERIAL_EV_RXCHAR
Definition: serial.c:99
#define STATUS_SUCCESS
Definition: shellext.h:65
ULONG ParityErrorCount
Definition: ntddser.h:299
signed int * PLONG
Definition: retypes.h:5
_In_ LONG _In_ LONG Limit
Definition: kefuncs.h:317
#define SR_MSR_DSR
Definition: serial.h:167
#define SR_IIR_SELF
Definition: serial.h:121

◆ 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
56  DeviceExtension->SerialPerfStats.BufferOverrunErrorCount++;
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 }
#define ULongToPtr(ul)
Definition: basetsd.h:92
#define INFO_(ch,...)
Definition: debug.h:159
#define SER_RBR(x)
Definition: serial.h:109
#define READ_PORT_UCHAR(p)
Definition: pc98vid.h:22
ULONG BufferOverrunErrorCount
Definition: ntddser.h:298
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
KSPIN_LOCK InputBufferLock
Definition: serial.h:76
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
_Out_ PKIRQL Irql
Definition: csq.h:179
KEVENT InputBufferNotEmpty
Definition: serial.h:74
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define SR_LSR_DATA_RECEIVED
Definition: serial.h:153
#define SR_IER_DATA_RECEIVED
Definition: serial.h:113
#define FALSE
Definition: types.h:117
SERIALPERF_STATS SerialPerfStats
Definition: serial.h:71
#define IER
Definition: serial_port.h:62
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS PushCircularBufferEntry(IN PCIRCULAR_BUFFER pBuffer, IN UCHAR Entry)
unsigned char UCHAR
Definition: xmlstorage.h:181
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
#define SER_LSR(x)
Definition: serial.h:152
struct _SERIAL_DEVICE_EXTENSION * PSERIAL_DEVICE_EXTENSION
#define SER_IER(x)
Definition: serial.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
unsigned char Byte
Definition: zlib.h:37
CIRCULAR_BUFFER InputBuffer
Definition: serial.h:75
ULONG ReceivedCount
Definition: ntddser.h:294

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));
100  }
101  KeReleaseSpinLock(&DeviceExtension->OutputBufferLock, Irql);
102 }
#define ULongToPtr(ul)
Definition: basetsd.h:92
CIRCULAR_BUFFER OutputBuffer
Definition: serial.h:77
#define INFO_(ch,...)
Definition: debug.h:159
#define READ_PORT_UCHAR(p)
Definition: pc98vid.h:22
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
#define SR_IER_THR_EMPTY
Definition: serial.h:114
_Out_ PKIRQL Irql
Definition: csq.h:179
UCHAR KIRQL
Definition: env_spec_w32.h:591
KSPIN_LOCK OutputBufferLock
Definition: serial.h:78
SERIALPERF_STATS SerialPerfStats
Definition: serial.h:71
BOOLEAN IsCircularBufferEmpty(IN PCIRCULAR_BUFFER pBuffer)
#define IER
Definition: serial_port.h:62
#define SER_THR(x)
Definition: serial.h:110
Status
Definition: gdiplustypes.h:24
#define SR_LSR_THR_EMPTY
Definition: serial.h:158
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
unsigned char UCHAR
Definition: xmlstorage.h:181
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
#define SER_LSR(x)
Definition: serial.h:152
NTSTATUS PopCircularBufferEntry(IN PCIRCULAR_BUFFER pBuffer, OUT PUCHAR Entry)
struct _SERIAL_DEVICE_EXTENSION * PSERIAL_DEVICE_EXTENSION
ULONG TransmittedCount
Definition: ntddser.h:295
#define SER_IER(x)
Definition: serial.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
unsigned char Byte
Definition: zlib.h:37

Referenced by SerialAddDeviceInternal(), and SerialWrite().