191 lines
3.8 KiB
C
191 lines
3.8 KiB
C
|
/*++
|
|||
|
|
|||
|
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;
|
|||
|
|
|||
|
}
|