ReactOS  0.4.15-dev-1184-g23e04ae
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

static NTSTATUS NTAPI ForwardIrpAndWaitCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
NTSTATUS ForwardIrpAndWait (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
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)
 

Variables

static IO_COMPLETION_ROUTINE ForwardIrpAndWaitCompletion
 

Function Documentation

◆ ForwardIrpAndForget()

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

Definition at line 57 of file misc.c.

60 {
61  PDEVICE_OBJECT LowerDevice = ((PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
62 
63  ASSERT(LowerDevice);
64 
66  return IoCallDriver(LowerDevice, Irp);
67 }
_In_ PIRP Irp
Definition: csq.h:116
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
struct _SERIAL_DEVICE_EXTENSION * PSERIAL_DEVICE_EXTENSION
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421

◆ ForwardIrpAndWait()

NTSTATUS ForwardIrpAndWait ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 29 of file misc.c.

32 {
33  PDEVICE_OBJECT LowerDevice = ((PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
34  KEVENT Event;
36 
37  ASSERT(LowerDevice);
38 
41 
42  TRACE_(SERIAL, "Calling lower device %p\n", LowerDevice);
44 
45  Status = IoCallDriver(LowerDevice, Irp);
46  if (Status == STATUS_PENDING)
47  {
49  if (NT_SUCCESS(Status))
50  Status = Irp->IoStatus.Status;
51  }
52 
53  return Status;
54 }
static IO_COMPLETION_ROUTINE ForwardIrpAndWaitCompletion
Definition: misc.c:15
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2864
#define FALSE
Definition: types.h:117
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:450
smooth NULL
Definition: ftsmooth.c:416
#define TRACE_(x)
Definition: compat.h:76
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Status
Definition: gdiplustypes.h:24
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
struct _SERIAL_DEVICE_EXTENSION * PSERIAL_DEVICE_EXTENSION
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218

◆ ForwardIrpAndWaitCompletion()

static NTSTATUS NTAPI ForwardIrpAndWaitCompletion ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PVOID  Context 
)
static

Definition at line 18 of file misc.c.

22 {
23  if (Irp->PendingReturned)
26 }
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
#define FALSE
Definition: types.h:117
#define IO_NO_INCREMENT
Definition: iotypes.h:581

◆ SerialCompleteIrp()

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

Definition at line 145 of file misc.c.

150 {
152 }
#define IoCompleteRequest
Definition: irp.c:1240
#define IO_NO_INCREMENT
Definition: iotypes.h:581

Referenced by SerialAddDeviceInternal().

◆ SerialInterruptService()

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

Definition at line 155 of file misc.c.

158 {
160  PSERIAL_DEVICE_EXTENSION DeviceExtension;
161  PUCHAR ComPortBase;
162  UCHAR Iir;
163  ULONG Events = 0;
164  BOOLEAN ret = FALSE;
165 
166  /* FIXME: sometimes, produce SERIAL_EV_RXFLAG event */
167 
169  DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
170  ComPortBase = ULongToPtr(DeviceExtension->BaseAddress);
171 
172  Iir = READ_PORT_UCHAR(SER_IIR(ComPortBase));
173  if (Iir == 0xff)
174  return TRUE;
175  Iir &= SR_IIR_ID_MASK;
176  if ((Iir & SR_IIR_SELF) != 0) { return FALSE; }
177 
178  switch (Iir)
179  {
180  case SR_IIR_MSR_CHANGE:
181  {
182  UCHAR MSR, IER;
183  TRACE_(SERIAL, "SR_IIR_MSR_CHANGE\n");
184 
185  MSR = READ_PORT_UCHAR(SER_MSR(ComPortBase));
186  if (MSR & SR_MSR_CTS_CHANGED)
187  {
188  if (MSR & SR_MSR_CTS)
189  KeInsertQueueDpc(&DeviceExtension->SendByteDpc, NULL, NULL);
190  else
191  {
192  ; /* FIXME: stop transmission */
193  }
195  }
196  if (MSR & SR_MSR_DSR_CHANGED)
197  {
198  if (MSR & SR_MSR_DSR)
199  KeInsertQueueDpc(&DeviceExtension->ReceivedByteDpc, NULL, NULL);
200  else
201  {
202  ; /* FIXME: stop reception */
203  }
205  }
206  if (MSR & SR_MSR_RI_CHANGED)
207  {
208  INFO_(SERIAL, "SR_MSR_RI_CHANGED changed: now %d\n", MSR & SI_MSR_RI);
210  }
211  if (MSR & SR_MSR_DCD_CHANGED)
212  {
213  INFO_(SERIAL, "SR_MSR_DCD_CHANGED changed: now %d\n", MSR & SR_MSR_DCD);
215  }
216  IER = READ_PORT_UCHAR(SER_IER(ComPortBase));
218 
219  ret = TRUE;
220  goto done;
221  }
222  case SR_IIR_THR_EMPTY:
223  {
224  TRACE_(SERIAL, "SR_IIR_THR_EMPTY\n");
225 
226  KeInsertQueueDpc(&DeviceExtension->SendByteDpc, NULL, NULL);
228 
229  ret = TRUE;
230  goto done;
231  }
233  {
234  ULONG AlreadyReceivedBytes, Limit;
235  TRACE_(SERIAL, "SR_IIR_DATA_RECEIVED\n");
236 
237  KeInsertQueueDpc(&DeviceExtension->ReceivedByteDpc, NULL, NULL);
239 
240  /* Check if buffer will be 80% full */
241  AlreadyReceivedBytes = GetNumberOfElementsInCircularBuffer(
242  &DeviceExtension->InputBuffer) * 5;
243  Limit = DeviceExtension->InputBuffer.Length * 4;
244  if (AlreadyReceivedBytes < Limit && AlreadyReceivedBytes + 1 >= Limit)
245  {
246  /* Buffer is full at 80% */
248  }
249 
250  ret = TRUE;
251  goto done;
252  }
253  case SR_IIR_ERROR:
254  {
255  UCHAR LSR;
256  TRACE_(SERIAL, "SR_IIR_ERROR\n");
257 
258  LSR = READ_PORT_UCHAR(SER_LSR(ComPortBase));
260  {
263  }
264  if (LSR & SR_LSR_PARITY_ERROR)
265  {
268  }
270  {
273  }
274  if (LSR & SR_LSR_BREAK_INT)
275  {
278  }
279 
280  ret = TRUE;
281  goto done;
282  }
283  }
284 
285 done:
286  if (!ret)
287  return FALSE;
288  if (DeviceExtension->WaitOnMaskIrp && (Events & DeviceExtension->WaitMask))
289  {
290  /* Finish pending IRP */
291  PULONG pEvents = (PULONG)DeviceExtension->WaitOnMaskIrp->AssociatedIrp.SystemBuffer;
292 
293  DeviceExtension->WaitOnMaskIrp->IoStatus.Status = STATUS_SUCCESS;
294  DeviceExtension->WaitOnMaskIrp->IoStatus.Information = sizeof(ULONG);
295  *pEvents = Events;
296  KeInsertQueueDpc(&DeviceExtension->CompleteIrpDpc, DeviceExtension->WaitOnMaskIrp, NULL);
297 
298  /* We are now ready to handle another IRP, even if this one is not completed */
299  DeviceExtension->WaitOnMaskIrp = NULL;
300  return TRUE;
301  }
302  return TRUE;
303 }
#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:21
#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:724
#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
#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
smooth NULL
Definition: ftsmooth.c:416
#define LSR
Definition: serial_port.h:67
ULONG SerialOverrunErrorCount
Definition: ntddser.h:297
#define SR_IIR_ID_MASK
Definition: serial.h:122
#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:798
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:20
#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
HANDLE Events[2]
Definition: schedsvc.c:40
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
unsigned int * PULONG
Definition: retypes.h:1
#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
ULONG ParityErrorCount
Definition: ntddser.h:299
return STATUS_SUCCESS
Definition: btrfs.c:3014
signed int * PLONG
Definition: retypes.h:5
_In_ LONG _In_ LONG Limit
Definition: kefuncs.h:315
#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 70 of file misc.c.

75 {
76  PSERIAL_DEVICE_EXTENSION DeviceExtension;
77  PUCHAR ComPortBase;
78  UCHAR Byte;
79  KIRQL Irql;
80  UCHAR IER;
82 
83  DeviceExtension = (PSERIAL_DEVICE_EXTENSION)pDeviceExtension;
84  ComPortBase = ULongToPtr(DeviceExtension->BaseAddress);
85 
86  KeAcquireSpinLock(&DeviceExtension->InputBufferLock, &Irql);
87  while (READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_DATA_RECEIVED)
88  {
89  Byte = READ_PORT_UCHAR(SER_RBR(ComPortBase));
90  INFO_(SERIAL, "Byte received on COM%lu: 0x%02x\n",
91  DeviceExtension->ComPort, Byte);
92  Status = PushCircularBufferEntry(&DeviceExtension->InputBuffer, Byte);
93  if (NT_SUCCESS(Status))
94  DeviceExtension->SerialPerfStats.ReceivedCount++;
95  else
96  DeviceExtension->SerialPerfStats.BufferOverrunErrorCount++;
97  }
98  KeSetEvent(&DeviceExtension->InputBufferNotEmpty, 0, FALSE);
99  KeReleaseSpinLock(&DeviceExtension->InputBufferLock, Irql);
100 
101  /* allow new interrupts */
102  IER = READ_PORT_UCHAR(SER_IER(ComPortBase));
104 }
#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:21
ULONG BufferOverrunErrorCount
Definition: ntddser.h:298
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
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
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
NTSTATUS PushCircularBufferEntry(IN PCIRCULAR_BUFFER pBuffer, IN UCHAR Entry)
unsigned char UCHAR
Definition: xmlstorage.h:181
Status
Definition: gdiplustypes.h:24
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:20
#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 107 of file misc.c.

112 {
113  PSERIAL_DEVICE_EXTENSION DeviceExtension;
114  PUCHAR ComPortBase;
115  UCHAR Byte;
116  KIRQL Irql;
117  UCHAR IER;
119 
120  DeviceExtension = (PSERIAL_DEVICE_EXTENSION)pDeviceExtension;
121  ComPortBase = ULongToPtr(DeviceExtension->BaseAddress);
122 
123  KeAcquireSpinLock(&DeviceExtension->OutputBufferLock, &Irql);
124  while (!IsCircularBufferEmpty(&DeviceExtension->OutputBuffer)
125  && READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_THR_EMPTY)
126  {
127  Status = PopCircularBufferEntry(&DeviceExtension->OutputBuffer, &Byte);
128  if (!NT_SUCCESS(Status))
129  break;
130  WRITE_PORT_UCHAR(SER_THR(ComPortBase), Byte);
131  INFO_(SERIAL, "Byte sent to COM%lu: 0x%02x\n",
132  DeviceExtension->ComPort, Byte);
133  DeviceExtension->SerialPerfStats.TransmittedCount++;
134  }
135  if (!IsCircularBufferEmpty(&DeviceExtension->OutputBuffer))
136  {
137  /* allow new interrupts */
138  IER = READ_PORT_UCHAR(SER_IER(ComPortBase));
139  WRITE_PORT_UCHAR(SER_IER(ComPortBase), IER | SR_IER_THR_EMPTY);
140  }
141  KeReleaseSpinLock(&DeviceExtension->OutputBufferLock, Irql);
142 }
#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:21
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
#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
#define SR_LSR_THR_EMPTY
Definition: serial.h:158
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
unsigned char UCHAR
Definition: xmlstorage.h:181
Status
Definition: gdiplustypes.h:24
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:20
#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().

Variable Documentation

◆ ForwardIrpAndWaitCompletion

IO_COMPLETION_ROUTINE ForwardIrpAndWaitCompletion
static

Definition at line 15 of file misc.c.

Referenced by ForwardIrpAndWait().