⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 waitmask.c

📁 NXP产品LPC23XX的开发板的源文件
💻 C
📖 第 1 页 / 共 2 页
字号:

}

BOOLEAN
SerialGrabWaitFromIsr(
    IN PVOID Context
    )

/*++

Routine Description:

    This routine will check to see if the ISR still knows about
    a wait irp by checking to see if the IrpMaskLocation is non-null.
    If it is then it will zero the Irpmasklocation (which in effect
    grabs the irp away from the isr).  This routine is only called
    buy the cancel code for the wait.

    NOTE: This is called by KeSynchronizeExecution.

Arguments:

    Context - A pointer to the device extension

Return Value:

    Always FALSE.

--*/

{

    PDEVICE_EXTENSION Extension = Context;
//    SERIAL_LOCKED_PAGED_CODE();

    SerialDump(
        SERDIAG3,
        ("SERIAL: In SerialGrabWaitFromIsr\n")
        );

    if (Extension->IrpMaskLocation) {

        SerialDump(
            SERDIAG4,
            ("SERIAL: The isr still owns the irp %x, mask location is %x\n"
             "------- and system buffer is %x\n",
             Extension->CurrentWaitIrp,Extension->IrpMaskLocation,
             Extension->CurrentWaitIrp->AssociatedIrp.SystemBuffer)
            );

        //
        // The isr still "owns" the irp.
        //

        *Extension->IrpMaskLocation = 0;
        Extension->IrpMaskLocation = NULL;

        Extension->CurrentWaitIrp->IoStatus.Information = sizeof(ULONG);

        //
        // Since the isr no longer references the irp we need to
        // decrement the reference count.
        //

        SERIAL_CLEAR_REFERENCE(
            Extension->CurrentWaitIrp,
            SERIAL_REF_ISR
            );

    }

    return FALSE;
}

BOOLEAN
SerialGiveWaitToIsr(
    IN PVOID Context
    )

/*++

Routine Description:

    This routine simply sets a variable in the device extension
    so that the isr knows that we have a wait irp.

    NOTE: This is called by KeSynchronizeExecution.

    NOTE: This routine assumes that it is called with the
          cancel spinlock held.

Arguments:

    Context - Simply a pointer to the device extension.

Return Value:

    Always FALSE.

--*/

{

    PDEVICE_EXTENSION Extension = Context;
//    SERIAL_LOCKED_PAGED_CODE();

    SerialDump(
        SERDIAG3,
        ("SERIAL: In SerialGiveWaitToIsr\n")
        );
    //
    // There certainly shouldn't be a current mask location at
    // this point since we have a new current wait irp.
    //

    ASSERT(!Extension->IrpMaskLocation);

    //
    // The isr may or may not actually reference this irp.  It
    // won't if the wait can be satisfied immediately.  However,
    // since it will then go through the normal completion sequence,
    // we need to have an incremented reference count anyway.
    //

    SERIAL_SET_REFERENCE(
        Extension->CurrentWaitIrp,
        SERIAL_REF_ISR
        );

    if (!Extension->HistoryMask) {

        SerialDump(
            SERDIAG4,
            ("SERIAL: No events occured prior to the wait call\n")
            );

        //
        // Although this wait might not be for empty transmit
        // queue, it doesn't hurt anything to set it to false.
        //

//        Extension->EmptiedTransmit = FALSE; henry

        //
        // Record where the "completion mask" should be set.
        //

        Extension->IrpMaskLocation =
            Extension->CurrentWaitIrp->AssociatedIrp.SystemBuffer;
        SerialDump(
            SERDIAG4,
            ("SERIAL: The isr owns the irp %x, mask location is %x\n"
             "------- and system buffer is %x\n",
             Extension->CurrentWaitIrp,Extension->IrpMaskLocation,
             Extension->CurrentWaitIrp->AssociatedIrp.SystemBuffer)
            );

    } else {

        SerialDump(
            SERDIAG4,
            ("SERIAL: %x occurred prior to the wait - starting the\n"
             "------- completion code for %x\n",
             Extension->HistoryMask,Extension->CurrentWaitIrp)
            );
        *((ULONG *)Extension->CurrentWaitIrp->AssociatedIrp.SystemBuffer) =
            Extension->HistoryMask;
        Extension->HistoryMask = 0;
        Extension->CurrentWaitIrp->IoStatus.Information = sizeof(ULONG);
        Extension->CurrentWaitIrp->IoStatus.Status = STATUS_SUCCESS;

        SerialInsertQueueDpc(
            &Extension->CommWaitDpc,
            NULL,
            NULL,
            Extension
            );

    }

    return FALSE;
}

BOOLEAN
SerialFinishOldWait(
    IN PVOID Context
    )

/*++

Routine Description:

    This routine will check to see if the ISR still knows about
    a wait irp by checking to see if the Irpmasklocation is non-null.
    If it is then it will zero the Irpmasklocation (which in effect
    grabs the irp away from the isr).  This routine is only called
    by the cancel code for the wait.

    NOTE: This is called by KeSynchronizeExecution.

Arguments:

    Context - A pointer to the device extension

Return Value:

    Always FALSE.

--*/

{

//    PSERIAL_DEVICE_EXTENSION Extension = Context;
//    SERIAL_LOCKED_PAGED_CODE();
    PDEVICE_EXTENSION Extension = Context;
    
    SerialDump(
        SERDIAG3,
        ("SERIAL: In SerialFinishOldWait\n")
        );
    if (Extension->IrpMaskLocation) {

        SerialDump(
            SERDIAG4,
            ("SERIAL: The isr still owns the irp %x, mask location is %x\n"
             "------- and system buffer is %x\n",
             Extension->CurrentWaitIrp,Extension->IrpMaskLocation,
             Extension->CurrentWaitIrp->AssociatedIrp.SystemBuffer)
            );
        //
        // The isr still "owns" the irp.
        //

        *Extension->IrpMaskLocation = 0;
        Extension->IrpMaskLocation = NULL;

        Extension->CurrentWaitIrp->IoStatus.Information = sizeof(ULONG);

        //
        // We don't decrement the reference since the completion routine
        // will do that.
        //

        SerialInsertQueueDpc(
            &Extension->CommWaitDpc,
            NULL,
            NULL,
            Extension
            );

    }

    //
    // Don't wipe out any historical data we are still interested in.
    //

    Extension->HistoryMask &= *((ULONG *)Extension->CurrentMaskIrp->
                                            AssociatedIrp.SystemBuffer);

    Extension->IsrWaitMask = *((ULONG *)Extension->CurrentMaskIrp->
                                            AssociatedIrp.SystemBuffer);
    SerialDump(
        SERDIAG4,
        ("SERIAL: Set mask location of %x, in irp %x, with system buffer of %x\n",
         Extension->IrpMaskLocation,
         Extension->CurrentMaskIrp,Extension->CurrentMaskIrp->AssociatedIrp.SystemBuffer)
        );
    return FALSE;
}

VOID
SerialCancelWait(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This routine is used to cancel a irp that is waiting on
    a comm event.

Arguments:

    DeviceObject - Pointer to the device object for this device

    Irp - Pointer to the IRP for the current request

Return Value:

    None.

--*/

{

    PDEVICE_EXTENSION Extension = DeviceObject->DeviceExtension;
//    SERIAL_LOCKED_PAGED_CODE();

    SerialDump(
        SERDIAG3,
        ("SERIAL: In SerialCancelWait\n")
        );

    SerialDump(
        SERDIAG4,
        ("SERIAL: Canceling wait for irp %x\n",Extension->CurrentWaitIrp)
        );
    SerialTryToCompleteCurrent(
        Extension,
        SerialGrabWaitFromIsr,
        Irp->CancelIrql,
        STATUS_CANCELLED,
        &Extension->CurrentWaitIrp,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        SERIAL_REF_CANCEL
        );

}


VOID
SerialCompleteWait(
    IN PKDPC Dpc,
    IN PVOID DeferredContext,
    IN PVOID SystemContext1,
    IN PVOID SystemContext2
    )

{

    PDEVICE_EXTENSION Extension = DeferredContext;
    KIRQL OldIrql;


    SerialDump(SERTRACECALLS, ("SERIAL: SerialCompleteWait\n"));

    SerialDump(
        SERDIAG3,
        ("SERIAL: In SerialCompleteWait\n")
        );
    UNREFERENCED_PARAMETER(SystemContext1);
    UNREFERENCED_PARAMETER(SystemContext2);

    IoAcquireCancelSpinLock(&OldIrql);

    SerialDump(
        SERDIAG4,
        ("SERIAL: Completing wait for irp %x\n",Extension->CurrentWaitIrp)
        );
    SerialTryToCompleteCurrent(
        Extension,
        NULL,
        OldIrql,
        STATUS_SUCCESS,
        &Extension->CurrentWaitIrp,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        SERIAL_REF_ISR
        );

    SerialDpcEpilogue(Extension, Dpc);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -