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
This commit is contained in:
Hervé Poussineau 2006-08-25 22:07:10 +00:00
parent 3c97814afe
commit ec5899ca4f
11 changed files with 229 additions and 118 deletions

View file

@ -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)

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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,