/*++ 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)); }