165 lines
3.1 KiB
C
165 lines
3.1 KiB
C
/*++
|
||
|
||
Copyright (c) 1991, 1992, 1993 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
flush.c
|
||
|
||
Abstract:
|
||
|
||
This module contains the code that is very specific to flush
|
||
operations in the serial driver
|
||
|
||
Author:
|
||
|
||
Anthony V. Ercolano 26-Sep-1991
|
||
|
||
Environment:
|
||
|
||
Kernel mode
|
||
|
||
Revision History :
|
||
|
||
--*/
|
||
|
||
#include "precomp.h"
|
||
|
||
|
||
NTSTATUS
|
||
SerialStartFlush(
|
||
IN PSERIAL_DEVICE_EXTENSION Extension
|
||
);
|
||
|
||
#ifdef ALLOC_PRAGMA
|
||
#pragma alloc_text(PAGESRP0,SerialFlush)
|
||
#pragma alloc_text(PAGESRP0,SerialStartFlush)
|
||
#endif
|
||
|
||
|
||
NTSTATUS
|
||
SerialFlush(
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN PIRP Irp
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This is the dispatch routine for flush. Flushing works by placing
|
||
this request in the write queue. When this request reaches the
|
||
front of the write queue we simply complete it since this implies
|
||
that all previous writes have completed.
|
||
|
||
Arguments:
|
||
|
||
DeviceObject - Pointer to the device object for this device
|
||
|
||
Irp - Pointer to the IRP for the current request
|
||
|
||
Return Value:
|
||
|
||
Could return status success, cancelled, or pending.
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
PSERIAL_DEVICE_EXTENSION Extension = DeviceObject->DeviceExtension;
|
||
NTSTATUS status;
|
||
PAGED_CODE();
|
||
|
||
SerialDump(
|
||
SERIRPPATH,
|
||
("SERIAL: Dispatch entry for: %x\n",Irp)
|
||
);
|
||
|
||
SerialDump(SERTRACECALLS, ("SERIAL: Entering SerialFlush\n"));
|
||
|
||
|
||
|
||
Irp->IoStatus.Information = 0L;
|
||
|
||
if ((status = SerialIRPPrologue(Irp, Extension)) == STATUS_SUCCESS) {
|
||
|
||
if (SerialCompleteIfError(DeviceObject, Irp) != STATUS_SUCCESS) {
|
||
SerialDump(SERTRACECALLS, ("SERIAL: Leaving SerialFlush (1)\n"));
|
||
|
||
return STATUS_CANCELLED;
|
||
|
||
}
|
||
|
||
SerialDump(SERTRACECALLS, ("SERIAL: Leaving SerialFlush (2)\n"));
|
||
|
||
return SerialStartOrQueue(Extension, Irp, &Extension->WriteQueue,
|
||
&Extension->CurrentWriteIrp, SerialStartFlush);
|
||
|
||
} else {
|
||
Irp->IoStatus.Status = status;
|
||
|
||
if (!NT_SUCCESS(status)) {
|
||
SerialCompleteRequest(Extension, Irp, IO_NO_INCREMENT);
|
||
}
|
||
|
||
SerialDump(SERTRACECALLS, ("SERIAL: Leaving SerialFlush (3)\n"));
|
||
return status;
|
||
}
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
SerialStartFlush(
|
||
IN PSERIAL_DEVICE_EXTENSION Extension
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is called if there were no writes in the queue.
|
||
The flush became the current write because there was nothing
|
||
in the queue. Note however that does not mean there is
|
||
nothing in the queue now! So, we will start off the write
|
||
that might follow us.
|
||
|
||
Arguments:
|
||
|
||
Extension - Points to the serial device extension
|
||
|
||
Return Value:
|
||
|
||
This will always return STATUS_SUCCESS.
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
PIRP NewIrp;
|
||
PAGED_CODE();
|
||
|
||
Extension->CurrentWriteIrp->IoStatus.Status = STATUS_SUCCESS;
|
||
|
||
//
|
||
// The following call will actually complete the flush.
|
||
//
|
||
|
||
SerialGetNextWrite(
|
||
&Extension->CurrentWriteIrp,
|
||
&Extension->WriteQueue,
|
||
&NewIrp,
|
||
TRUE,
|
||
Extension
|
||
);
|
||
|
||
if (NewIrp) {
|
||
|
||
ASSERT(NewIrp == Extension->CurrentWriteIrp);
|
||
SerialStartWrite(Extension);
|
||
|
||
}
|
||
|
||
return STATUS_SUCCESS;
|
||
|
||
}
|