NT4/private/ntos/dd/serial/purge.c

191 lines
3.8 KiB
C
Raw Normal View History

2001-01-01 00:00:00 +01:00
/*++
Copyright (c) 1991, 1992, 1993 Microsoft Corporation
Module Name:
purge.c
Abstract:
This module contains the code that is very specific to purge
operations in the serial driver
Author:
Anthony V. Ercolano 26-Sep-1991
Environment:
Kernel mode
Revision History :
--*/
#include "precomp.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGESER,SerialStartPurge)
#pragma alloc_text(PAGESER,SerialPurgeInterruptBuff)
#endif
NTSTATUS
SerialStartPurge(
IN PSERIAL_DEVICE_EXTENSION Extension
)
/*++
Routine Description:
Depending on the mask in the current irp, purge the interrupt
buffer, the read queue, or the write queue, or all of the above.
Arguments:
Extension - Pointer to the device extension.
Return Value:
Will return STATUS_SUCCESS always. This is reasonable
since the DPC completion code that calls this routine doesn't
care and the purge request always goes through to completion
once it's started.
--*/
{
PIRP NewIrp;
do {
ULONG Mask;
Mask = *((ULONG *)
(Extension->CurrentPurgeIrp->AssociatedIrp.SystemBuffer));
if (Mask & SERIAL_PURGE_TXABORT) {
SerialKillAllReadsOrWrites(
Extension->DeviceObject,
&Extension->WriteQueue,
&Extension->CurrentWriteIrp
);
SerialKillAllReadsOrWrites(
Extension->DeviceObject,
&Extension->WriteQueue,
&Extension->CurrentXoffIrp
);
}
if (Mask & SERIAL_PURGE_RXABORT) {
SerialKillAllReadsOrWrites(
Extension->DeviceObject,
&Extension->ReadQueue,
&Extension->CurrentReadIrp
);
}
if (Mask & SERIAL_PURGE_RXCLEAR) {
KIRQL OldIrql;
//
// Clean out the interrupt buffer.
//
// Note that we do this under protection of the
// the drivers control lock so that we don't hose
// the pointers if there is currently a read that
// is reading out of the buffer.
//
KeAcquireSpinLock(
&Extension->ControlLock,
&OldIrql
);
KeSynchronizeExecution(
Extension->Interrupt,
SerialPurgeInterruptBuff,
Extension
);
KeReleaseSpinLock(
&Extension->ControlLock,
OldIrql
);
}
Extension->CurrentPurgeIrp->IoStatus.Status = STATUS_SUCCESS;
Extension->CurrentPurgeIrp->IoStatus.Information = 0;
SerialGetNextIrp(
&Extension->CurrentPurgeIrp,
&Extension->PurgeQueue,
&NewIrp,
TRUE
);
} while (NewIrp);
return STATUS_SUCCESS;
}
BOOLEAN
SerialPurgeInterruptBuff(
IN PVOID Context
)
/*++
Routine Description:
This routine simply resets the interrupt (typeahead) buffer.
NOTE: This routine is being called from KeSynchronizeExecution.
Arguments:
Context - Really a pointer to the device extension.
Return Value:
Always false.
--*/
{
PSERIAL_DEVICE_EXTENSION Extension = Context;
//
// The typeahead buffer is by definition empty if there
// currently is a read owned by the isr.
//
if (Extension->ReadBufferBase == Extension->InterruptReadBuffer) {
Extension->CurrentCharSlot = Extension->InterruptReadBuffer;
Extension->FirstReadableChar = Extension->InterruptReadBuffer;
Extension->LastCharSlot = Extension->InterruptReadBuffer +
(Extension->BufferSize - 1);
Extension->CharsInInterruptBuffer = 0;
SerialHandleReducedIntBuffer(Extension);
}
return FALSE;
}