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.
118 lines
4.5 KiB
118 lines
4.5 KiB
/*-------------------------------------------------------------------
|
|
| waitmask.c -
|
|
|
|
3-30-99 - fix cancel event operation(race-condition) to avoid
|
|
potential bug-check on queued eventwait cancel.
|
|
11-24-98 - update event kdprint debug messages - kpb
|
|
Copyright 1993-99 Comtrol Corporation. All rights reserved.
|
|
|--------------------------------------------------------------------*/
|
|
#include "precomp.h"
|
|
|
|
/*------------------------------------------------------------------
|
|
SerialCancelWait - (setup in ioctl.c currently, 3-28-98, kpb)
|
|
This routine is used to cancel a irp that is waiting on a comm event.
|
|
|-------------------------------------------------------------------*/
|
|
VOID SerialCancelWait(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
|
|
|
|
{
|
|
PSERIAL_DEVICE_EXTENSION Extension = DeviceObject->DeviceExtension;
|
|
|
|
MyKdPrint(D_Ioctl,("CancelWait\n"))
|
|
// take out, 3-30-99, kpb... Extension->IrpMaskLocation = NULL;
|
|
if (Extension->CurrentWaitIrp)
|
|
{
|
|
PIRP Irp_tmp;
|
|
|
|
MyKdPrint(D_Ioctl,("Cancel a Wait\n"))
|
|
|
|
//***** add, 3-30-99, kpb, cause crash on read thread in dos box without
|
|
// grab from ISR timer or interrupt routine.
|
|
SyncUp(Driver.InterruptObject,
|
|
&Driver.TimerLock,
|
|
SerialGrabWaitFromIsr,
|
|
Extension);
|
|
//***** end add, 3-30-99
|
|
|
|
// ExtTrace(Extension,D_Ioctl, "Cancel Event");
|
|
Extension->CurrentWaitIrp->IoStatus.Information = 0;
|
|
Extension->CurrentWaitIrp->IoStatus.Status = STATUS_CANCELLED;
|
|
|
|
Irp_tmp = Extension->CurrentWaitIrp;
|
|
IoSetCancelRoutine(Irp_tmp, NULL); // add 9-15-97, kpb
|
|
Extension->CurrentWaitIrp = 0;
|
|
IoReleaseCancelSpinLock(Irp->CancelIrql);
|
|
SerialCompleteRequest(Extension, Irp_tmp, IO_SERIAL_INCREMENT);
|
|
}
|
|
else
|
|
{
|
|
IoReleaseCancelSpinLock(Irp->CancelIrql);
|
|
ExtTrace(Extension,D_Ioctl, "Err Cancel Event!");
|
|
MyKdPrint(D_Ioctl,("No Wait to Cancel\n"))
|
|
}
|
|
}
|
|
|
|
/*------------------------------------------------------------------
|
|
SerialCompleteWait - called by isr.c via CommWaitDpc. It nulls out
|
|
IrpMaskLocation to signal control passed back to us.
|
|
|-------------------------------------------------------------------*/
|
|
VOID SerialCompleteWait(IN PKDPC Dpc,IN PVOID DeferredContext,
|
|
IN PVOID SystemContext1, IN PVOID SystemContext2)
|
|
{
|
|
PSERIAL_DEVICE_EXTENSION Extension = DeferredContext;
|
|
KIRQL OldIrql;
|
|
PIRP Irp_tmp;
|
|
|
|
UNREFERENCED_PARAMETER(Dpc);
|
|
UNREFERENCED_PARAMETER(SystemContext1);
|
|
UNREFERENCED_PARAMETER(SystemContext2);
|
|
|
|
MyKdPrint(D_Ioctl,("Complete Wait\n"))
|
|
IoAcquireCancelSpinLock(&OldIrql);
|
|
|
|
if (Extension->CurrentWaitIrp != 0)
|
|
{
|
|
MyKdPrint(D_Ioctl,("Complete a Wait\n"))
|
|
ExtTrace2(Extension,D_Ioctl, "Event Done Got:%xH Mask:%xH",
|
|
*(ULONG *) Extension->CurrentWaitIrp->AssociatedIrp.SystemBuffer,
|
|
Extension->IsrWaitMask);
|
|
|
|
Extension->WaitIsISRs = 0;
|
|
Extension->IrpMaskLocation = &Extension->DummyIrpMaskLoc;
|
|
|
|
// caller sets the ULONG bit flags indicating event at .SystemBuffer
|
|
//*(ULONG *)Extension->CurrentWaitIrp->AssociatedIrp.SystemBuffer = 0;
|
|
Extension->CurrentWaitIrp->IoStatus.Status = STATUS_SUCCESS;
|
|
Extension->CurrentWaitIrp->IoStatus.Information = sizeof(ULONG);
|
|
Irp_tmp = Extension->CurrentWaitIrp;
|
|
IoSetCancelRoutine(Irp_tmp, NULL); // add 9-15-97, kpb
|
|
Extension->CurrentWaitIrp = 0;
|
|
IoReleaseCancelSpinLock(OldIrql);
|
|
SerialCompleteRequest(Extension, Irp_tmp, IO_SERIAL_INCREMENT);
|
|
}
|
|
else
|
|
{
|
|
MyKdPrint(D_Ioctl,("No wait to complete\n"))
|
|
IoReleaseCancelSpinLock(OldIrql);
|
|
}
|
|
}
|
|
|
|
/*------------------------------------------------------------------
|
|
SerialGrabWaitFromIsr - Take back the wait packet from the ISR by
|
|
reseting IrpMaskLocation in extension. Need to use a sync with
|
|
isr/timer routine to avoid contention in multiprocessor environments.
|
|
|
|
Called from sync routine or with timer spinlock held.
|
|
|
|
App - Can set IrpMaskLocation to give read-irp handling to the ISR without
|
|
syncing to ISR.
|
|
ISR - Can reset ReadPending to give wait-irp handling back to app-time.
|
|
|
|
If App wants to grab control of read-irp handling back from ISR, then
|
|
it must sync-up with the isr/timer routine which has control.
|
|
|-------------------------------------------------------------------*/
|
|
BOOLEAN SerialGrabWaitFromIsr(PSERIAL_DEVICE_EXTENSION Extension)
|
|
{
|
|
Extension->WaitIsISRs = 0;
|
|
Extension->IrpMaskLocation = &Extension->DummyIrpMaskLoc;
|
|
return FALSE;
|
|
}
|