From ec5899ca4fafffef9f2b945a277a79ee061f795e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Fri, 25 Aug 2006 22:07:10 +0000 Subject: [PATCH] Implement IOCTL_SERIAL_WAIT_ON_MASK Better implementation of IOCTL_SERIAL_SET_WAIT_MASK Remove "Serial:" prefix on debug output svn path=/trunk/; revision=23712 --- reactos/drivers/base/serial/circularbuffer.c | 21 ++- reactos/drivers/base/serial/cleanup.c | 2 +- reactos/drivers/base/serial/close.c | 2 +- reactos/drivers/base/serial/create.c | 6 +- reactos/drivers/base/serial/devctrl.c | 148 +++++++++++-------- reactos/drivers/base/serial/info.c | 6 +- reactos/drivers/base/serial/misc.c | 92 ++++++++++-- reactos/drivers/base/serial/pnp.c | 33 +++-- reactos/drivers/base/serial/power.c | 2 +- reactos/drivers/base/serial/rw.c | 18 +-- reactos/drivers/base/serial/serial.h | 17 ++- 11 files changed, 229 insertions(+), 118 deletions(-) diff --git a/reactos/drivers/base/serial/circularbuffer.c b/reactos/drivers/base/serial/circularbuffer.c index a17f2951726..67189c23357 100644 --- a/reactos/drivers/base/serial/circularbuffer.c +++ b/reactos/drivers/base/serial/circularbuffer.c @@ -15,7 +15,7 @@ InitializeCircularBuffer( IN PCIRCULAR_BUFFER pBuffer, IN ULONG BufferSize) { - DPRINT("Serial: InitializeCircularBuffer(pBuffer %p, BufferSize %lu)\n", pBuffer, BufferSize); + DPRINT("InitializeCircularBuffer(pBuffer %p, BufferSize %lu)\n", pBuffer, BufferSize); ASSERT(pBuffer); pBuffer->Buffer = (PUCHAR)ExAllocatePoolWithTag(NonPagedPool, BufferSize * sizeof(UCHAR), SERIAL_TAG); if (!pBuffer->Buffer) @@ -29,7 +29,7 @@ NTSTATUS FreeCircularBuffer( IN PCIRCULAR_BUFFER pBuffer) { - DPRINT("Serial: FreeCircularBuffer(pBuffer %p)\n", pBuffer); + DPRINT("FreeCircularBuffer(pBuffer %p)\n", pBuffer); ASSERT(pBuffer); if (pBuffer->Buffer != NULL) ExFreePoolWithTag(pBuffer->Buffer, SERIAL_TAG); @@ -40,18 +40,27 @@ BOOLEAN IsCircularBufferEmpty( IN PCIRCULAR_BUFFER pBuffer) { - DPRINT("Serial: IsCircularBufferEmpty(pBuffer %p)\n", pBuffer); + DPRINT("IsCircularBufferEmpty(pBuffer %p)\n", pBuffer); ASSERT(pBuffer); return (pBuffer->ReadPosition == pBuffer->WritePosition); } +ULONG +GetNumberOfElementsInCircularBuffer( + IN PCIRCULAR_BUFFER pBuffer) +{ + DPRINT("GetNumberOfElementsInCircularBuffer(pBuffer %p)\n", pBuffer); + ASSERT(pBuffer); + return (pBuffer->WritePosition + pBuffer->Length - pBuffer->ReadPosition) % pBuffer->Length; +} + NTSTATUS PushCircularBufferEntry( IN PCIRCULAR_BUFFER pBuffer, IN UCHAR Entry) { ULONG NextPosition; - DPRINT("Serial: PushCircularBufferEntry(pBuffer %p, Entry 0x%x)\n", pBuffer, Entry); + DPRINT("PushCircularBufferEntry(pBuffer %p, Entry 0x%x)\n", pBuffer, Entry); ASSERT(pBuffer); ASSERT(pBuffer->Length); NextPosition = (pBuffer->WritePosition + 1) % pBuffer->Length; @@ -67,7 +76,7 @@ PopCircularBufferEntry( IN PCIRCULAR_BUFFER pBuffer, OUT PUCHAR Entry) { - DPRINT("Serial: PopCircularBufferEntry(pBuffer %p)\n", pBuffer); + DPRINT("PopCircularBufferEntry(pBuffer %p)\n", pBuffer); ASSERT(pBuffer); ASSERT(pBuffer->Length); if (IsCircularBufferEmpty(pBuffer)) @@ -84,7 +93,7 @@ IncreaseCircularBufferSize( { PUCHAR NewBuffer; - DPRINT("Serial: IncreaseCircularBufferSize(pBuffer %p, NewBufferSize %lu)\n", pBuffer, NewBufferSize); + DPRINT("IncreaseCircularBufferSize(pBuffer %p, NewBufferSize %lu)\n", pBuffer, NewBufferSize); ASSERT(pBuffer); ASSERT(pBuffer->Length); if (pBuffer->Length > NewBufferSize) diff --git a/reactos/drivers/base/serial/cleanup.c b/reactos/drivers/base/serial/cleanup.c index 4c9c95b1dd1..760c20c5260 100644 --- a/reactos/drivers/base/serial/cleanup.c +++ b/reactos/drivers/base/serial/cleanup.c @@ -15,7 +15,7 @@ SerialCleanup( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - DPRINT("Serial: IRP_MJ_CLEANUP\n"); + DPRINT("IRP_MJ_CLEANUP\n"); Irp->IoStatus.Information = 0; Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); diff --git a/reactos/drivers/base/serial/close.c b/reactos/drivers/base/serial/close.c index 1c336beab70..5ff9234355e 100644 --- a/reactos/drivers/base/serial/close.c +++ b/reactos/drivers/base/serial/close.c @@ -17,7 +17,7 @@ SerialClose( { PSERIAL_DEVICE_EXTENSION pDeviceExtension; - DPRINT("Serial: IRP_MJ_CLOSE\n"); + DPRINT("IRP_MJ_CLOSE\n"); pDeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension; pDeviceExtension->IsOpened = FALSE; diff --git a/reactos/drivers/base/serial/create.c b/reactos/drivers/base/serial/create.c index f6cf90a83bd..33ab2b09dbc 100644 --- a/reactos/drivers/base/serial/create.c +++ b/reactos/drivers/base/serial/create.c @@ -19,7 +19,7 @@ SerialCreate( PSERIAL_DEVICE_EXTENSION DeviceExtension; NTSTATUS Status; - DPRINT("Serial: IRP_MJ_CREATE\n"); + DPRINT("IRP_MJ_CREATE\n"); Stack = IoGetCurrentIrpStackLocation(Irp); DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension; @@ -32,12 +32,12 @@ SerialCreate( if(DeviceExtension->IsOpened) { - DPRINT("Serial: COM%lu is already opened\n", DeviceExtension->ComPort); + DPRINT("COM%lu is already opened\n", DeviceExtension->ComPort); Status = STATUS_ACCESS_DENIED; goto ByeBye; } - DPRINT("Serial: open COM%lu: successfull\n", DeviceExtension->ComPort); + DPRINT("Open COM%lu: successfull\n", DeviceExtension->ComPort); DeviceExtension->IsOpened = TRUE; Status = STATUS_SUCCESS; diff --git a/reactos/drivers/base/serial/devctrl.c b/reactos/drivers/base/serial/devctrl.c index 0cbf6027310..f1a4193ffb7 100644 --- a/reactos/drivers/base/serial/devctrl.c +++ b/reactos/drivers/base/serial/devctrl.c @@ -65,7 +65,7 @@ SerialSetBaudRate( if (NT_SUCCESS(Status)) { UCHAR Lcr; - DPRINT("Serial: SerialSetBaudRate(COM%lu, %lu Bauds)\n", DeviceExtension->ComPort, BaudRate); + DPRINT("SerialSetBaudRate(COM%lu, %lu Bauds)\n", DeviceExtension->ComPort, BaudRate); /* Set Bit 7 of LCR to expose baud registers */ Lcr = READ_PORT_UCHAR(SER_LCR(ComPortBase)); WRITE_PORT_UCHAR(SER_LCR(ComPortBase), Lcr | SR_LCR_DLAB); @@ -95,7 +95,7 @@ SerialSetLineControl( ASSERT(DeviceExtension); ASSERT(NewSettings); - DPRINT("Serial: SerialSetLineControl(COM%lu, Settings { %lu %lu %lu })\n", + DPRINT("SerialSetLineControl(COM%lu, Settings { %lu %lu %lu })\n", DeviceExtension->ComPort, NewSettings->StopBits, NewSettings->Parity, NewSettings->WordLength); /* Verify parameters */ @@ -289,7 +289,7 @@ SerialDeviceControl( PUCHAR ComPortBase; NTSTATUS Status; - DPRINT("Serial: IRP_MJ_DEVICE_CONTROL dispatch\n"); + DPRINT("IRP_MJ_DEVICE_CONTROL dispatch\n"); Stack = IoGetCurrentIrpStackLocation(Irp); LengthIn = Stack->Parameters.DeviceIoControl.InputBufferLength; @@ -305,7 +305,7 @@ SerialDeviceControl( { case IOCTL_SERIAL_CLEAR_STATS: { - DPRINT("Serial: IOCTL_SERIAL_CLEAR_STATS\n"); + DPRINT("IOCTL_SERIAL_CLEAR_STATS\n"); KeSynchronizeExecution( DeviceExtension->Interrupt, (PKSYNCHRONIZE_ROUTINE)SerialClearPerfStats, @@ -315,7 +315,7 @@ SerialDeviceControl( } case IOCTL_SERIAL_CLR_DTR: { - DPRINT("Serial: IOCTL_SERIAL_CLR_DTR\n"); + DPRINT("IOCTL_SERIAL_CLR_DTR\n"); /* FIXME: If the handshake flow control of the device is configured to * automatically use DTR, return STATUS_INVALID_PARAMETER */ Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort); @@ -329,7 +329,7 @@ SerialDeviceControl( } case IOCTL_SERIAL_CLR_RTS: { - DPRINT("Serial: IOCTL_SERIAL_CLR_RTS\n"); + DPRINT("IOCTL_SERIAL_CLR_RTS\n"); /* FIXME: If the handshake flow control of the device is configured to * automatically use RTS, return STATUS_INVALID_PARAMETER */ Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort); @@ -345,7 +345,7 @@ SerialDeviceControl( { /* Obsolete on Microsoft Windows 2000+ */ PULONG pConfigSize; - DPRINT("Serial: IOCTL_SERIAL_CONFIG_SIZE\n"); + DPRINT("IOCTL_SERIAL_CONFIG_SIZE\n"); if (LengthOut != sizeof(ULONG) || BufferOut == NULL) Status = STATUS_INVALID_PARAMETER; else @@ -359,7 +359,7 @@ SerialDeviceControl( } case IOCTL_SERIAL_GET_BAUD_RATE: { - DPRINT("Serial: IOCTL_SERIAL_GET_BAUD_RATE\n"); + DPRINT("IOCTL_SERIAL_GET_BAUD_RATE\n"); if (LengthOut < sizeof(SERIAL_BAUD_RATE)) Status = STATUS_BUFFER_TOO_SMALL; else if (BufferOut == NULL) @@ -375,23 +375,17 @@ SerialDeviceControl( case IOCTL_SERIAL_GET_CHARS: { /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_GET_CHARS not implemented.\n"); + DPRINT1("IOCTL_SERIAL_GET_CHARS not implemented.\n"); Status = STATUS_NOT_IMPLEMENTED; break; } case IOCTL_SERIAL_GET_COMMSTATUS: { - DPRINT("Serial: IOCTL_SERIAL_GET_COMMSTATUS\n"); + DPRINT("IOCTL_SERIAL_GET_COMMSTATUS\n"); if (LengthOut < sizeof(SERIAL_STATUS)) - { - DPRINT("Serial: return STATUS_BUFFER_TOO_SMALL\n"); Status = STATUS_BUFFER_TOO_SMALL; - } else if (BufferOut == NULL) - { - DPRINT("Serial: return STATUS_INVALID_PARAMETER\n"); Status = STATUS_INVALID_PARAMETER; - } else { Status = SerialGetCommStatus((PSERIAL_STATUS)BufferOut, DeviceExtension); @@ -402,7 +396,7 @@ SerialDeviceControl( case IOCTL_SERIAL_GET_DTRRTS: { PULONG pDtrRts; - DPRINT("Serial: IOCTL_SERIAL_GET_DTRRTS\n"); + DPRINT("IOCTL_SERIAL_GET_DTRRTS\n"); if (LengthOut != sizeof(ULONG) || BufferOut == NULL) Status = STATUS_INVALID_PARAMETER; else @@ -421,13 +415,13 @@ SerialDeviceControl( case IOCTL_SERIAL_GET_HANDFLOW: { /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_GET_HANDFLOW not implemented.\n"); + DPRINT1("IOCTL_SERIAL_GET_HANDFLOW not implemented.\n"); Status = STATUS_NOT_IMPLEMENTED; break; } case IOCTL_SERIAL_GET_LINE_CONTROL: { - DPRINT("Serial: IOCTL_SERIAL_GET_LINE_CONTROL\n"); + DPRINT("IOCTL_SERIAL_GET_LINE_CONTROL\n"); if (LengthOut < sizeof(SERIAL_LINE_CONTROL)) Status = STATUS_BUFFER_TOO_SMALL; else if (BufferOut == NULL) @@ -443,7 +437,7 @@ SerialDeviceControl( case IOCTL_SERIAL_GET_MODEM_CONTROL: { PULONG pMCR; - DPRINT("Serial: IOCTL_SERIAL_GET_MODEM_CONTROL\n"); + DPRINT("IOCTL_SERIAL_GET_MODEM_CONTROL\n"); if (LengthOut != sizeof(ULONG) || BufferOut == NULL) Status = STATUS_INVALID_PARAMETER; else @@ -458,7 +452,7 @@ SerialDeviceControl( case IOCTL_SERIAL_GET_MODEMSTATUS: { PULONG pMSR; - DPRINT("Serial: IOCTL_SERIAL_GET_MODEMSTATUS\n"); + DPRINT("IOCTL_SERIAL_GET_MODEMSTATUS\n"); if (LengthOut != sizeof(ULONG) || BufferOut == NULL) Status = STATUS_INVALID_PARAMETER; else @@ -472,17 +466,11 @@ SerialDeviceControl( } case IOCTL_SERIAL_GET_PROPERTIES: { - DPRINT("Serial: IOCTL_SERIAL_GET_PROPERTIES\n"); + DPRINT("IOCTL_SERIAL_GET_PROPERTIES\n"); if (LengthOut < sizeof(SERIAL_COMMPROP)) - { - DPRINT("Serial: return STATUS_BUFFER_TOO_SMALL\n"); Status = STATUS_BUFFER_TOO_SMALL; - } else if (BufferOut == NULL) - { - DPRINT("Serial: return STATUS_INVALID_PARAMETER\n"); Status = STATUS_INVALID_PARAMETER; - } else { Status = SerialGetCommProp((PSERIAL_COMMPROP)BufferOut, DeviceExtension); @@ -492,17 +480,11 @@ SerialDeviceControl( } case IOCTL_SERIAL_GET_STATS: { - DPRINT("Serial: IOCTL_SERIAL_GET_STATS\n"); + DPRINT("IOCTL_SERIAL_GET_STATS\n"); if (LengthOut < sizeof(SERIALPERF_STATS)) - { - DPRINT("Serial: return STATUS_BUFFER_TOO_SMALL\n"); Status = STATUS_BUFFER_TOO_SMALL; - } else if (BufferOut == NULL) - { - DPRINT("Serial: return STATUS_INVALID_PARAMETER\n"); Status = STATUS_INVALID_PARAMETER; - } else { KeSynchronizeExecution(DeviceExtension->Interrupt, @@ -514,7 +496,7 @@ SerialDeviceControl( } case IOCTL_SERIAL_GET_TIMEOUTS: { - DPRINT("Serial: IOCTL_SERIAL_GET_TIMEOUTS\n"); + DPRINT("IOCTL_SERIAL_GET_TIMEOUTS\n"); if (LengthOut != sizeof(SERIAL_TIMEOUTS) || BufferOut == NULL) Status = STATUS_INVALID_PARAMETER; else @@ -528,7 +510,7 @@ SerialDeviceControl( case IOCTL_SERIAL_GET_WAIT_MASK: { PULONG pWaitMask; - DPRINT("Serial: IOCTL_SERIAL_GET_WAIT_MASK\n"); + DPRINT("IOCTL_SERIAL_GET_WAIT_MASK\n"); if (LengthOut != sizeof(ULONG) || BufferOut == NULL) Status = STATUS_INVALID_PARAMETER; else @@ -543,21 +525,21 @@ SerialDeviceControl( case IOCTL_SERIAL_IMMEDIATE_CHAR: { /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_IMMEDIATE_CHAR not implemented.\n"); + DPRINT1("IOCTL_SERIAL_IMMEDIATE_CHAR not implemented.\n"); Status = STATUS_NOT_IMPLEMENTED; break; } case IOCTL_SERIAL_LSRMST_INSERT: { /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_LSRMST_INSERT not implemented.\n"); + DPRINT1("IOCTL_SERIAL_LSRMST_INSERT not implemented.\n"); Status = STATUS_NOT_IMPLEMENTED; break; } case IOCTL_SERIAL_PURGE: { KIRQL Irql; - DPRINT("Serial: IOCTL_SERIAL_PURGE\n"); + DPRINT("IOCTL_SERIAL_PURGE\n"); /* FIXME: SERIAL_PURGE_RXABORT and SERIAL_PURGE_TXABORT * should stop current request */ if (LengthIn != sizeof(ULONG) || BufferIn == NULL) @@ -607,14 +589,14 @@ SerialDeviceControl( case IOCTL_SERIAL_RESET_DEVICE: { /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_RESET_DEVICE not implemented.\n"); + DPRINT1("IOCTL_SERIAL_RESET_DEVICE not implemented.\n"); Status = STATUS_NOT_IMPLEMENTED; break; } case IOCTL_SERIAL_SET_BAUD_RATE: { PULONG pNewBaudRate; - DPRINT("Serial: IOCTL_SERIAL_SET_BAUD_RATE\n"); + DPRINT("IOCTL_SERIAL_SET_BAUD_RATE\n"); if (LengthIn != sizeof(ULONG) || BufferIn == NULL) Status = STATUS_INVALID_PARAMETER; else @@ -627,21 +609,21 @@ SerialDeviceControl( case IOCTL_SERIAL_SET_BREAK_OFF: { /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_SET_BREAK_OFF not implemented.\n"); + DPRINT1("IOCTL_SERIAL_SET_BREAK_OFF not implemented.\n"); Status = STATUS_NOT_IMPLEMENTED; break; } case IOCTL_SERIAL_SET_BREAK_ON: { /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_SET_BREAK_ON not implemented.\n"); + DPRINT1("IOCTL_SERIAL_SET_BREAK_ON not implemented.\n"); Status = STATUS_NOT_IMPLEMENTED; break; } case IOCTL_SERIAL_SET_CHARS: { /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_SET_CHARS not implemented.\n"); + DPRINT1("IOCTL_SERIAL_SET_CHARS not implemented.\n"); Status = STATUS_NOT_IMPLEMENTED; break; } @@ -649,7 +631,7 @@ SerialDeviceControl( { /* FIXME: If the handshake flow control of the device is configured to * automatically use DTR, return STATUS_INVALID_PARAMETER */ - DPRINT("Serial: IOCTL_SERIAL_SET_DTR\n"); + DPRINT("IOCTL_SERIAL_SET_DTR\n"); if (!(DeviceExtension->MCR & SR_MCR_DTR)) { Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort); @@ -666,7 +648,7 @@ SerialDeviceControl( } case IOCTL_SERIAL_SET_FIFO_CONTROL: { - DPRINT("Serial: IOCTL_SERIAL_SET_FIFO_CONTROL\n"); + DPRINT("IOCTL_SERIAL_SET_FIFO_CONTROL\n"); if (LengthIn != sizeof(ULONG) || BufferIn == NULL) Status = STATUS_INVALID_PARAMETER; else @@ -683,13 +665,13 @@ SerialDeviceControl( case IOCTL_SERIAL_SET_HANDFLOW: { /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_SET_HANDFLOW not implemented.\n"); + DPRINT1("IOCTL_SERIAL_SET_HANDFLOW not implemented.\n"); Status = STATUS_NOT_IMPLEMENTED; break; } case IOCTL_SERIAL_SET_LINE_CONTROL: { - DPRINT("Serial: IOCTL_SERIAL_SET_LINE_CONTROL\n"); + DPRINT("IOCTL_SERIAL_SET_LINE_CONTROL\n"); if (LengthIn < sizeof(SERIAL_LINE_CONTROL)) Status = STATUS_BUFFER_TOO_SMALL; else if (BufferIn == NULL) @@ -701,7 +683,7 @@ SerialDeviceControl( case IOCTL_SERIAL_SET_MODEM_CONTROL: { PULONG pMCR; - DPRINT("Serial: IOCTL_SERIAL_SET_MODEM_CONTROL\n"); + DPRINT("IOCTL_SERIAL_SET_MODEM_CONTROL\n"); if (LengthIn != sizeof(ULONG) || BufferIn == NULL) Status = STATUS_INVALID_PARAMETER; else @@ -747,7 +729,7 @@ SerialDeviceControl( { /* FIXME: If the handshake flow control of the device is configured to * automatically use DTR, return STATUS_INVALID_PARAMETER */ - DPRINT("Serial: IOCTL_SERIAL_SET_RTS\n"); + DPRINT("IOCTL_SERIAL_SET_RTS\n"); if (!(DeviceExtension->MCR & SR_MCR_RTS)) { Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort); @@ -764,7 +746,7 @@ SerialDeviceControl( } case IOCTL_SERIAL_SET_TIMEOUTS: { - DPRINT("Serial: IOCTL_SERIAL_SET_TIMEOUTS\n"); + DPRINT("IOCTL_SERIAL_SET_TIMEOUTS\n"); if (LengthIn != sizeof(SERIAL_TIMEOUTS) || BufferIn == NULL) Status = STATUS_INVALID_PARAMETER; else @@ -776,13 +758,18 @@ SerialDeviceControl( } case IOCTL_SERIAL_SET_WAIT_MASK: { - PULONG pWaitMask; - DPRINT("Serial: IOCTL_SERIAL_SET_WAIT_MASK\n"); + PULONG pWaitMask = (PULONG)BufferIn; + DPRINT("IOCTL_SERIAL_SET_WAIT_MASK\n"); + if (LengthIn != sizeof(ULONG) || BufferIn == NULL) Status = STATUS_INVALID_PARAMETER; + else if (DeviceExtension->WaitOnMaskIrp) /* FIXME: Race condition ; field may be currently in modification */ + { + DPRINT("An IRP is already currently processed\n"); + Status = STATUS_INVALID_PARAMETER; + } else { - pWaitMask = (PULONG)BufferIn; DeviceExtension->WaitMask = *pWaitMask; Status = STATUS_SUCCESS; } @@ -791,42 +778,75 @@ SerialDeviceControl( case IOCTL_SERIAL_SET_XOFF: { /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_SET_XOFF not implemented.\n"); + DPRINT1("IOCTL_SERIAL_SET_XOFF not implemented.\n"); Status = STATUS_NOT_IMPLEMENTED; break; } case IOCTL_SERIAL_SET_XON: { /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_SET_XON not implemented.\n"); + DPRINT1("IOCTL_SERIAL_SET_XON not implemented.\n"); Status = STATUS_NOT_IMPLEMENTED; break; } case IOCTL_SERIAL_WAIT_ON_MASK: { - /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_WAIT_ON_MASK not implemented.\n"); - Status = STATUS_NOT_IMPLEMENTED; + PIRP WaitingIrp; + DPRINT("IOCTL_SERIAL_WAIT_ON_MASK\n"); + + if (LengthOut != sizeof(ULONG) || BufferOut == NULL) + Status = STATUS_INVALID_PARAMETER; + else + { + /* FIXME: Race condition here: + * If an interrupt comes before we can mark the Irp + * as pending, it might be possible to complete the + * Irp before pending it, leading to a crash! */ + WaitingIrp = InterlockedCompareExchangePointer( + &DeviceExtension->WaitOnMaskIrp, + Irp, + NULL); + + /* Check if an Irp is already pending */ + if (WaitingIrp != NULL) + { + /* Unable to have a 2nd pending IRP for this IOCTL */ + DPRINT("Unable to pend a second IRP for IOCTL_SERIAL_WAIT_ON_MASK\n"); + Status = STATUS_INVALID_PARAMETER; + } + else + { + Status = STATUS_PENDING; + /* FIXME: immediately return if a wait event already occurred */ + } + } break; } case IOCTL_SERIAL_XOFF_COUNTER: { /* FIXME */ - DPRINT1("Serial: IOCTL_SERIAL_XOFF_COUNTER not implemented.\n"); + DPRINT1("IOCTL_SERIAL_XOFF_COUNTER not implemented.\n"); Status = STATUS_NOT_IMPLEMENTED; break; } default: { /* Pass Irp to lower driver */ - DPRINT("Serial: Unknown IOCTL code 0x%x\n", Stack->Parameters.DeviceIoControl.IoControlCode); + DPRINT("Unknown IOCTL code 0x%x\n", Stack->Parameters.DeviceIoControl.IoControlCode); IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(DeviceExtension->LowerDevice, Irp); } } - Irp->IoStatus.Information = Information; Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); + if (Status == STATUS_PENDING) + { + IoMarkIrpPending(Irp); + } + else + { + Irp->IoStatus.Information = Information; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } return Status; } diff --git a/reactos/drivers/base/serial/info.c b/reactos/drivers/base/serial/info.c index efec45941fb..8a86bf67dd0 100644 --- a/reactos/drivers/base/serial/info.c +++ b/reactos/drivers/base/serial/info.c @@ -33,7 +33,7 @@ SerialQueryInformation( { PFILE_STANDARD_INFORMATION StandardInfo = (PFILE_STANDARD_INFORMATION)SystemBuffer; - DPRINT("Serial: IRP_MJ_QUERY_INFORMATION / FileStandardInformation\n"); + DPRINT("IRP_MJ_QUERY_INFORMATION / FileStandardInformation\n"); if (BufferLength < sizeof(FILE_STANDARD_INFORMATION)) Status = STATUS_BUFFER_OVERFLOW; else if (!StandardInfo) @@ -55,7 +55,7 @@ SerialQueryInformation( ASSERT(PositionInfo); - DPRINT("Serial: IRP_MJ_QUERY_INFORMATION / FilePositionInformation\n"); + DPRINT("IRP_MJ_QUERY_INFORMATION / FilePositionInformation\n"); if (BufferLength < sizeof(PFILE_POSITION_INFORMATION)) Status = STATUS_BUFFER_OVERFLOW; else if (!PositionInfo) @@ -69,7 +69,7 @@ SerialQueryInformation( } default: { - DPRINT("Serial: IRP_MJ_QUERY_INFORMATION: Unexpected file information class 0x%02x\n", Stack->Parameters.QueryFile.FileInformationClass); + DPRINT("IRP_MJ_QUERY_INFORMATION: Unexpected file information class 0x%02x\n", Stack->Parameters.QueryFile.FileInformationClass); return ForwardIrpAndForget(DeviceObject, Irp); } } diff --git a/reactos/drivers/base/serial/misc.c b/reactos/drivers/base/serial/misc.c index 60490eacaf2..69c28d537b1 100644 --- a/reactos/drivers/base/serial/misc.c +++ b/reactos/drivers/base/serial/misc.c @@ -36,7 +36,7 @@ ForwardIrpAndWait( KeInitializeEvent(&Event, NotificationEvent, FALSE); IoCopyCurrentIrpStackLocationToNext(Irp); - DPRINT("Serial: Calling lower device %p [%wZ]\n", LowerDevice, &LowerDevice->DriverObject->DriverName); + DPRINT("Calling lower device %p [%wZ]\n", LowerDevice, &LowerDevice->DriverObject->DriverName); IoSetCompletionRoutine(Irp, ForwardIrpAndWaitCompletion, &Event, TRUE, TRUE, TRUE); Status = IoCallDriver(LowerDevice, Irp); @@ -84,7 +84,7 @@ SerialReceiveByte( while (READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_DATA_RECEIVED) { Byte = READ_PORT_UCHAR(SER_RBR(ComPortBase)); - DPRINT("Serial: Byte received on COM%lu: 0x%02x\n", + DPRINT("Byte received on COM%lu: 0x%02x\n", DeviceExtension->ComPort, Byte); Status = PushCircularBufferEntry(&DeviceExtension->InputBuffer, Byte); if (NT_SUCCESS(Status)) @@ -125,7 +125,7 @@ SerialSendByte( if (!NT_SUCCESS(Status)) break; WRITE_PORT_UCHAR(SER_THR(ComPortBase), Byte); - DPRINT("Serial: Byte sent to COM%lu: 0x%02x\n", + DPRINT("Byte sent to COM%lu: 0x%02x\n", DeviceExtension->ComPort, Byte); DeviceExtension->SerialPerfStats.TransmittedCount++; } @@ -138,6 +138,16 @@ SerialSendByte( KeReleaseSpinLock(&DeviceExtension->OutputBufferLock, Irql); } +VOID NTAPI +SerialCompleteIrp( + IN PKDPC Dpc, + IN PVOID pDeviceExtension, // real type PSERIAL_DEVICE_EXTENSION + IN PVOID pIrp, // real type PIRP + IN PVOID Unused) +{ + IoCompleteRequest((PIRP)pIrp, IO_NO_INCREMENT); +} + BOOLEAN NTAPI SerialInterruptService( IN PKINTERRUPT Interrupt, @@ -147,6 +157,10 @@ SerialInterruptService( PSERIAL_DEVICE_EXTENSION DeviceExtension; PUCHAR ComPortBase; UCHAR Iir; + ULONG Events = 0; + BOOLEAN ret = FALSE; + + /* FIXME: sometimes, produce SERIAL_EV_RXFLAG event */ DeviceObject = (PDEVICE_OBJECT)ServiceContext; DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension; @@ -163,7 +177,7 @@ SerialInterruptService( case SR_IIR_MSR_CHANGE: { UCHAR MSR, IER; - DPRINT("Serial: SR_IIR_MSR_CHANGE\n"); + DPRINT("SR_IIR_MSR_CHANGE\n"); MSR = READ_PORT_UCHAR(SER_MSR(ComPortBase)); if (MSR & SR_MSR_CTS_CHANGED) @@ -172,6 +186,7 @@ SerialInterruptService( KeInsertQueueDpc(&DeviceExtension->SendByteDpc, NULL, NULL); else ; /* FIXME: stop transmission */ + Events |= SERIAL_EV_CTS; } if (MSR & SR_MSR_DSR_CHANGED) { @@ -179,50 +194,103 @@ SerialInterruptService( KeInsertQueueDpc(&DeviceExtension->ReceivedByteDpc, NULL, NULL); else ; /* FIXME: stop reception */ + Events |= SERIAL_EV_DSR; } if (MSR & SR_MSR_RI_CHANGED) { DPRINT("SR_MSR_RI_CHANGED changed: now %d\n", MSR & SI_MSR_RI); + Events |= SERIAL_EV_RING; } if (MSR & SR_MSR_DCD_CHANGED) { DPRINT("SR_MSR_DCD_CHANGED changed: now %d\n", MSR & SR_MSR_DCD); + Events |= SERIAL_EV_RLSD; } IER = READ_PORT_UCHAR(SER_IER(ComPortBase)); WRITE_PORT_UCHAR(SER_IER(ComPortBase), IER | SR_IER_MSR_CHANGE); - return TRUE; + + ret = TRUE; + goto done; } case SR_IIR_THR_EMPTY: { - DPRINT("Serial: SR_IIR_THR_EMPTY\n"); + DPRINT("SR_IIR_THR_EMPTY\n"); KeInsertQueueDpc(&DeviceExtension->SendByteDpc, NULL, NULL); - return TRUE; + Events |= SERIAL_EV_TXEMPTY; + + ret = TRUE; + goto done; } case SR_IIR_DATA_RECEIVED: { - DPRINT("Serial: SR_IIR_DATA_RECEIVED\n"); + ULONG AlreadyReceivedBytes, Limit; + DPRINT("SR_IIR_DATA_RECEIVED\n"); KeInsertQueueDpc(&DeviceExtension->ReceivedByteDpc, NULL, NULL); - return TRUE; + Events |= SERIAL_EV_RXCHAR; + + /* Check if buffer will be 80% full */ + AlreadyReceivedBytes = GetNumberOfElementsInCircularBuffer( + &DeviceExtension->InputBuffer) * 5; + Limit = DeviceExtension->InputBuffer.Length * 4; + if (AlreadyReceivedBytes < Limit && AlreadyReceivedBytes + 1 >= Limit) + { + /* Buffer is full at 80% */ + Events |= SERIAL_EV_RX80FULL; + } + + ret = TRUE; + goto done; } case SR_IIR_ERROR: { UCHAR LSR; - DPRINT("Serial: SR_IIR_ERROR\n"); + DPRINT("SR_IIR_ERROR\n"); LSR = READ_PORT_UCHAR(SER_LSR(ComPortBase)); if (LSR & SR_LSR_OVERRUN_ERROR) + { InterlockedIncrement((PLONG)&DeviceExtension->SerialPerfStats.SerialOverrunErrorCount); + Events |= SERIAL_EV_ERR; + } if (LSR & SR_LSR_PARITY_ERROR) + { InterlockedIncrement((PLONG)&DeviceExtension->SerialPerfStats.ParityErrorCount); + Events |= SERIAL_EV_ERR; + } if (LSR & SR_LSR_FRAMING_ERROR) + { InterlockedIncrement((PLONG)&DeviceExtension->SerialPerfStats.FrameErrorCount); + Events |= SERIAL_EV_ERR; + } if (LSR & SR_LSR_BREAK_INT) + { InterlockedIncrement((PLONG)&DeviceExtension->BreakInterruptErrorCount); + Events |= SERIAL_EV_BREAK; + } - return TRUE; + ret = TRUE; + goto done; } } - return FALSE; + +done: + if (!ret) + return FALSE; + if (DeviceExtension->WaitOnMaskIrp && (Events & DeviceExtension->WaitMask)) + { + /* Finish pending IRP */ + PULONG pEvents = (PULONG)DeviceExtension->WaitOnMaskIrp->AssociatedIrp.SystemBuffer; + + DeviceExtension->WaitOnMaskIrp->IoStatus.Status = STATUS_SUCCESS; + DeviceExtension->WaitOnMaskIrp->IoStatus.Information = sizeof(ULONG); + *pEvents = Events; + KeInsertQueueDpc(&DeviceExtension->CompleteIrpDpc, DeviceExtension->WaitOnMaskIrp, NULL); + + /* We are now ready to handle another IRP, even if this one is not completed */ + DeviceExtension->WaitOnMaskIrp = NULL; + return STATUS_SUCCESS; + } + return TRUE; } diff --git a/reactos/drivers/base/serial/pnp.c b/reactos/drivers/base/serial/pnp.c index 41b6ac49677..feffdaf0bf7 100644 --- a/reactos/drivers/base/serial/pnp.c +++ b/reactos/drivers/base/serial/pnp.c @@ -28,7 +28,7 @@ SerialAddDeviceInternal( static ULONG DeviceNumber = 0; static ULONG ComPortNumber = 1; - DPRINT("Serial: SerialAddDeviceInternal called\n"); + DPRINT("SerialAddDeviceInternal()\n"); ASSERT(DriverObject); ASSERT(Pdo); @@ -45,7 +45,7 @@ SerialAddDeviceInternal( &Fdo); if (!NT_SUCCESS(Status)) { - DPRINT("Serial: IoCreateDevice() failed with status 0x%08x\n", Status); + DPRINT("IoCreateDevice() failed with status 0x%08x\n", Status); Fdo = NULL; goto ByeBye; } @@ -56,7 +56,7 @@ SerialAddDeviceInternal( Status = IoRegisterDeviceInterface(Pdo, &GUID_DEVINTERFACE_COMPORT, NULL, &DeviceExtension->SerialInterfaceName); if (!NT_SUCCESS(Status)) { - DPRINT("Serial: IoRegisterDeviceInterface() failed with status 0x%08x\n", Status); + DPRINT("IoRegisterDeviceInterface() failed with status 0x%08x\n", Status); goto ByeBye; } @@ -78,11 +78,12 @@ SerialAddDeviceInternal( KeInitializeEvent(&DeviceExtension->InputBufferNotEmpty, NotificationEvent, FALSE); KeInitializeDpc(&DeviceExtension->ReceivedByteDpc, SerialReceiveByte, DeviceExtension); KeInitializeDpc(&DeviceExtension->SendByteDpc, SerialSendByte, DeviceExtension); + KeInitializeDpc(&DeviceExtension->CompleteIrpDpc, SerialCompleteIrp, DeviceExtension); Fdo->Flags |= DO_POWER_PAGABLE; Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice); if (!NT_SUCCESS(Status)) { - DPRINT("Serial: IoAttachDeviceToDeviceStackSafe() failed with status 0x%08x\n", Status); + DPRINT("IoAttachDeviceToDeviceStackSafe() failed with status 0x%08x\n", Status); goto ByeBye; } Fdo->Flags |= DO_BUFFERED_IO; @@ -185,7 +186,7 @@ SerialPnpStartDevice( } } } - DPRINT("Serial: New COM port. Base = 0x%lx, Irql = %u\n", + DPRINT("New COM port. Base = 0x%lx, Irql = %u\n", DeviceExtension->BaseAddress, Dirql); if (!DeviceExtension->BaseAddress) return STATUS_INSUFFICIENT_RESOURCES; @@ -212,7 +213,7 @@ SerialPnpStartDevice( Status = SerialSetBaudRate(DeviceExtension, DeviceExtension->BaudRate); if (!NT_SUCCESS(Status)) { - DPRINT("Serial: SerialSetBaudRate() failed with status 0x%08x\n", Status); + DPRINT("SerialSetBaudRate() failed with status 0x%08x\n", Status); return Status; } @@ -223,7 +224,7 @@ SerialPnpStartDevice( Status = SerialSetLineControl(DeviceExtension, &DeviceExtension->SerialLineControl); if (!NT_SUCCESS(Status)) { - DPRINT("Serial: SerialSetLineControl() failed with status 0x%08x\n", Status); + DPRINT("SerialSetLineControl() failed with status 0x%08x\n", Status); return Status; } @@ -245,7 +246,7 @@ SerialPnpStartDevice( Status = IoCreateSymbolicLink(&LinkName, &DeviceName); if (!NT_SUCCESS(Status)) { - DPRINT("Serial: IoCreateSymbolicLink() failed with status 0x%08x\n", Status); + DPRINT("IoCreateSymbolicLink() failed with status 0x%08x\n", Status); return Status; } @@ -258,7 +259,7 @@ SerialPnpStartDevice( Affinity, FALSE); if (!NT_SUCCESS(Status)) { - DPRINT("Serial: IoConnectInterrupt() failed with status 0x%08x\n", Status); + DPRINT("IoConnectInterrupt() failed with status 0x%08x\n", Status); IoSetDeviceInterfaceState(&DeviceExtension->SerialInterfaceName, FALSE); IoDeleteSymbolicLink(&LinkName); return Status; @@ -313,7 +314,7 @@ SerialPnp( IRP_MN_QUERY_REMOVE_DEVICE 0x1 IRP_MN_REMOVE_DEVICE 0x2 { - DPRINT("Serial: IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n"); + DPRINT("IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n"); IoAcquireRemoveLock IoReleaseRemoveLockAndWait pass request to DeviceExtension-LowerDriver @@ -336,7 +337,7 @@ SerialPnp( */ case IRP_MN_START_DEVICE: /* 0x0 */ { - DPRINT("Serial: IRP_MJ_PNP / IRP_MN_START_DEVICE\n"); + DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n"); ASSERT(((PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->PnpState == dsStopped); @@ -345,7 +346,7 @@ SerialPnp( */ if (Stack->Parameters.StartDevice.AllocatedResources == NULL) { - DPRINT1("Serial: no allocated resources. Can't start COM%lu\n", + DPRINT1("No allocated resources. Can't start COM%lu\n", ((PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->ComPort); Status = STATUS_INSUFFICIENT_RESOURCES; break; @@ -366,16 +367,16 @@ SerialPnp( { case BusRelations: { - DPRINT("Serial: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n"); + DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n"); return ForwardIrpAndForget(DeviceObject, Irp); } case RemovalRelations: { - DPRINT("Serial: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n"); + DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n"); return ForwardIrpAndForget(DeviceObject, Irp); } default: - DPRINT1("Serial: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n", + DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n", Stack->Parameters.QueryDeviceRelations.Type); return ForwardIrpAndForget(DeviceObject, Irp); } @@ -383,7 +384,7 @@ SerialPnp( } default: { - DPRINT1("Serial: unknown minor function 0x%x\n", MinorFunction); + DPRINT1("Unknown minor function 0x%x\n", MinorFunction); return ForwardIrpAndForget(DeviceObject, Irp); } } diff --git a/reactos/drivers/base/serial/power.c b/reactos/drivers/base/serial/power.c index 717606791de..fcfac0b83a1 100644 --- a/reactos/drivers/base/serial/power.c +++ b/reactos/drivers/base/serial/power.c @@ -15,7 +15,7 @@ SerialPower( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - DPRINT("Serial: IRP_MJ_POWER dispatch\n"); + DPRINT("IRP_MJ_POWER dispatch\n"); Irp->IoStatus.Information = 0; Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); diff --git a/reactos/drivers/base/serial/rw.c b/reactos/drivers/base/serial/rw.c index 4d14b74f89c..dedce38c3e8 100644 --- a/reactos/drivers/base/serial/rw.c +++ b/reactos/drivers/base/serial/rw.c @@ -44,10 +44,10 @@ ReadBytes( Length = IoGetCurrentIrpStackLocation(Irp)->Parameters.Read.Length; Buffer = SerialGetUserBuffer(Irp); - DPRINT("Serial: UseIntervalTimeout = %s, IntervalTimeout = %lu\n", + DPRINT("UseIntervalTimeout = %s, IntervalTimeout = %lu\n", WorkItemData->UseIntervalTimeout ? "YES" : "NO", WorkItemData->UseIntervalTimeout ? WorkItemData->IntervalTimeout.QuadPart : 0); - DPRINT("Serial: UseTotalTimeout = %s\n", + DPRINT("UseTotalTimeout = %s\n", WorkItemData->UseTotalTimeout ? "YES" : "NO"); ObjectCount = 1; @@ -69,7 +69,7 @@ ReadBytes( && Length > 0) { PopCircularBufferEntry(&DeviceExtension->InputBuffer, &ReceivedByte); - DPRINT("Serial: reading byte from buffer: 0x%02x\n", ReceivedByte); + DPRINT("Reading byte from buffer: 0x%02x\n", ReceivedByte); Buffer[Information++] = ReceivedByte; Length--; @@ -80,7 +80,7 @@ ReadBytes( if (WorkItemData->DontWait && !(WorkItemData->ReadAtLeastOneByte && Information == 0)) { - DPRINT("Serial: buffer empty. Don't wait more bytes\n"); + DPRINT("Buffer empty. Don't wait more bytes\n"); break; } @@ -97,7 +97,7 @@ ReadBytes( if (Status == STATUS_TIMEOUT /* interval timeout */ || Status == STATUS_WAIT_1) /* total timeout */ { - DPRINT("Serial: timeout when reading bytes. Status = 0x%08lx\n", Status); + DPRINT("Timeout when reading bytes. Status = 0x%08lx\n", Status); break; } } @@ -121,7 +121,7 @@ SerialReadWorkItem( PWORKITEM_DATA WorkItemData; PIRP Irp; - DPRINT("Serial: SerialReadWorkItem() called\n"); + DPRINT("SerialReadWorkItem() called\n"); WorkItemData = (PWORKITEM_DATA)pWorkItemData; Irp = WorkItemData->Irp; @@ -147,7 +147,7 @@ SerialRead( PIO_WORKITEM WorkItem; NTSTATUS Status; - DPRINT("Serial: IRP_MJ_READ\n"); + DPRINT("IRP_MJ_READ\n"); Stack = IoGetCurrentIrpStackLocation(Irp); Length = Stack->Parameters.Read.Length; @@ -259,7 +259,7 @@ SerialWrite( KIRQL Irql; NTSTATUS Status = STATUS_SUCCESS; - DPRINT("Serial: IRP_MJ_WRITE\n"); + DPRINT("IRP_MJ_WRITE\n"); /* FIXME: pend operation if possible */ /* FIXME: use write timeouts */ @@ -296,7 +296,7 @@ SerialWrite( } else { - DPRINT("Serial: buffer overrun on COM%lu\n", DeviceExtension->ComPort); + DPRINT("Buffer overrun on COM%lu\n", DeviceExtension->ComPort); DeviceExtension->SerialPerfStats.BufferOverrunErrorCount++; break; } diff --git a/reactos/drivers/base/serial/serial.h b/reactos/drivers/base/serial/serial.h index 9a7c2f42677..c1386ed391f 100644 --- a/reactos/drivers/base/serial/serial.h +++ b/reactos/drivers/base/serial/serial.h @@ -81,10 +81,12 @@ typedef struct _SERIAL_DEVICE_EXTENSION PKINTERRUPT Interrupt; KDPC ReceivedByteDpc; KDPC SendByteDpc; + KDPC CompleteIrpDpc; SERIAL_LINE_CONTROL SerialLineControl; UART_TYPE UartType; ULONG WaitMask; + PIRP WaitOnMaskIrp; ULONG BreakInterruptErrorCount; SERIALPERF_STATS SerialPerfStats; @@ -204,6 +206,10 @@ BOOLEAN IsCircularBufferEmpty( IN PCIRCULAR_BUFFER pBuffer); +ULONG +GetNumberOfElementsInCircularBuffer( + IN PCIRCULAR_BUFFER pBuffer); + NTSTATUS PushCircularBufferEntry( IN PCIRCULAR_BUFFER pBuffer, @@ -286,8 +292,8 @@ VOID NTAPI SerialReceiveByte( IN PKDPC Dpc, IN PVOID pDeviceExtension, // real type PSERIAL_DEVICE_EXTENSION - IN PVOID pByte, // real type UCHAR - IN PVOID Unused); + IN PVOID Unused1, + IN PVOID Unused2); VOID NTAPI SerialSendByte( @@ -296,6 +302,13 @@ SerialSendByte( IN PVOID Unused1, IN PVOID Unused2); +VOID NTAPI +SerialCompleteIrp( + IN PKDPC Dpc, + IN PVOID pDeviceExtension, // real type PSERIAL_DEVICE_EXTENSION + IN PVOID pIrp, // real type PIRP + IN PVOID Unused); + BOOLEAN NTAPI SerialInterruptService( IN PKINTERRUPT Interrupt,