You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
194 lines
4.7 KiB
194 lines
4.7 KiB
/*++
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
chkcomm.c
|
|
|
|
Abstract:
|
|
|
|
|
|
Author:
|
|
|
|
Thomas J. Dimitri (TommyD) 08-May-1992
|
|
|
|
Environment:
|
|
|
|
Kernel Mode - Or whatever is the equivalent on OS/2 and DOS.
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
#if DBG
|
|
|
|
#define __FILE_SIG__ 'ckhC'
|
|
|
|
#endif
|
|
|
|
#include "asyncall.h"
|
|
|
|
NTSTATUS
|
|
AsyncCheckCommStatusCompletionRoutine(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp,
|
|
IN PVOID Context)
|
|
|
|
/*++
|
|
|
|
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS status;
|
|
PSERIAL_STATUS pSerialStatus;
|
|
PASYNC_IO_CTX AsyncIoCtx = (PASYNC_IO_CTX)Context;
|
|
PASYNC_INFO pInfo=AsyncIoCtx->Context;
|
|
|
|
DeviceObject; // prevent compiler warnings
|
|
|
|
status = Irp->IoStatus.Status;
|
|
pSerialStatus=(PSERIAL_STATUS)(Irp->AssociatedIrp.SystemBuffer);
|
|
|
|
DbgTracef(0,("ACCSCR: s=$%x\n",status));
|
|
|
|
switch (status) {
|
|
case STATUS_SUCCESS:
|
|
|
|
if (pSerialStatus->Errors & SERIAL_ERROR_FRAMING) {
|
|
DbgTracef(-1,("ACCSCR: Framing error\n"));
|
|
pInfo->SerialStats.FramingErrors++;
|
|
}
|
|
|
|
if (pSerialStatus->Errors & SERIAL_ERROR_OVERRUN) {
|
|
DbgTracef(-1,("ACCSCR: Overrun error \n"));
|
|
pInfo->SerialStats.SerialOverrunErrors++;
|
|
}
|
|
|
|
if (pSerialStatus->Errors & SERIAL_ERROR_QUEUEOVERRUN) {
|
|
DbgTracef(-1,("ACCSCR: Q-Overrun error\n"));
|
|
pInfo->SerialStats.BufferOverrunErrors++;
|
|
}
|
|
|
|
//
|
|
// Keep proper count of errors
|
|
//
|
|
AsyncIndicateFragment(
|
|
pInfo,
|
|
pSerialStatus->Errors);
|
|
|
|
// Fall through...
|
|
|
|
default:
|
|
//
|
|
// Free up memory we used to make this call
|
|
//
|
|
IoFreeIrp(Irp);
|
|
AsyncFreeIoCtx(AsyncIoCtx);
|
|
}
|
|
|
|
//
|
|
// Deref the ref applied in AsyncCheckCommStatus
|
|
//
|
|
pInfo->Flags &= ~(ASYNC_FLAG_CHECK_COMM_STATUS);
|
|
DEREF_ASYNCINFO(pInfo, Irp);
|
|
|
|
|
|
//
|
|
// We return STATUS_MORE_PROCESSING_REQUIRED so that the
|
|
// IoCompletionRoutine will stop working on the IRP.
|
|
//
|
|
|
|
return(STATUS_MORE_PROCESSING_REQUIRED);
|
|
}
|
|
|
|
VOID
|
|
AsyncCheckCommStatus(
|
|
IN PASYNC_INFO pInfo)
|
|
/*++
|
|
|
|
This is the Worker Thread entry for reading comm status errors
|
|
|
|
--*/
|
|
{
|
|
PIRP irp;
|
|
PIO_STACK_LOCATION irpSp;
|
|
PDEVICE_OBJECT deviceObject=pInfo->DeviceObject;
|
|
PFILE_OBJECT fileObject=pInfo->FileObject;
|
|
PASYNC_IO_CTX AsyncIoCtx;
|
|
NTSTATUS status;
|
|
|
|
irp=IoAllocateIrp(deviceObject->StackSize, (BOOLEAN)FALSE);
|
|
|
|
//
|
|
// Are we out of irps? Oh no!
|
|
//
|
|
if (irp==NULL) {
|
|
return;
|
|
}
|
|
|
|
AsyncIoCtx = AsyncAllocateIoCtx(FALSE, pInfo);
|
|
|
|
if (AsyncIoCtx == NULL) {
|
|
IoFreeIrp(irp);
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Set the file object to the Not-Signaled state.
|
|
//
|
|
|
|
irp->Tail.Overlay.OriginalFileObject = fileObject;
|
|
irp->RequestorMode = KernelMode;
|
|
irp->PendingReturned = FALSE;
|
|
//
|
|
// Fill in the service independent parameters in the IRP.
|
|
//
|
|
|
|
irp->UserEvent = NULL;
|
|
irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
|
|
irp->Overlay.AsynchronousParameters.UserApcContext = NULL;
|
|
|
|
irp->Flags = IRP_BUFFERED_IO;
|
|
irp->AssociatedIrp.SystemBuffer=&AsyncIoCtx->SerialStatus;
|
|
|
|
irpSp = IoGetNextIrpStackLocation(irp);
|
|
|
|
|
|
irpSp->FileObject = fileObject;
|
|
if (fileObject->Flags & FO_WRITE_THROUGH) {
|
|
irpSp->Flags = SL_WRITE_THROUGH;
|
|
}
|
|
|
|
|
|
irpSp->MajorFunction = IRP_MJ_DEVICE_CONTROL;
|
|
irpSp->Parameters.DeviceIoControl.IoControlCode=IOCTL_SERIAL_GET_COMMSTATUS;
|
|
irpSp->Parameters.DeviceIoControl.InputBufferLength = 0;
|
|
irpSp->Parameters.DeviceIoControl.OutputBufferLength = sizeof(SERIAL_STATUS);
|
|
|
|
IoSetCompletionRoutine(
|
|
irp, // irp to use
|
|
AsyncCheckCommStatusCompletionRoutine, // routine to call when irp is done
|
|
AsyncIoCtx, // context to pass routine
|
|
TRUE, // call on success
|
|
TRUE, // call on error
|
|
TRUE); // call on cancel
|
|
|
|
|
|
pInfo->Flags |= ASYNC_FLAG_CHECK_COMM_STATUS;
|
|
//
|
|
// Reference the asyncinfo block so that its still around when
|
|
// the completion routine is called
|
|
//
|
|
REF_ASYNCINFO(pInfo, irp);
|
|
|
|
//
|
|
// Now simply invoke the driver at its dispatch entry with the IRP.
|
|
//
|
|
|
|
status = IoCallDriver(deviceObject, irp);
|
|
|
|
DbgTracef(0,("ACCS: IoctlGetCommStatus returned with 0x%.8x\n", status));
|
|
}
|