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

📄 waitmask.c

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

Copyright (c) 1991, 1992, 1993 Microsoft Corporation

Module Name:

    waitmask.c

Abstract:

    This module contains the code that is very specific to get/set/wait
    on event mask operations in the serial driver

Author:

    Anthony V. Ercolano 26-Sep-1991
	Henry Tan			31-Jul-2000

Environment:

    Kernel mode

Revision History :

--*/

//#include "precomp.h"
#include "wdm.h"
#include "stdarg.h"
#include "stdio.h"
#include "usbdi.h"
#include "usbdlib.h"
#include "usbcom.h"


BOOLEAN
SerialGrabWaitFromIsr(
    IN PVOID Context
    );

BOOLEAN
SerialGiveWaitToIsr(
    IN PVOID Context
    );

BOOLEAN
SerialFinishOldWait(
    IN PVOID Context
    );

NTSTATUS
SerialStartMask(
    IN PDEVICE_EXTENSION Extension
    )

/*++

Routine Description:

    This routine is used to process the set mask and wait
    mask ioctls.  Calls to this routine are serialized by
    placing irps in the list under the protection of the
    cancel spin lock.

Arguments:

    Extension - A pointer to the serial device extension.

Return Value:

    Will return pending for everything put the first
    request that we actually process.  Even in that
    case it will return pending unless it can complete
    it right away.


--*/

{

    //
    // The current stack location.  This contains much of the
    // information we need to process this particular request.
    //
    PIO_STACK_LOCATION IrpSp;

    PIRP NewIrp;

    BOOLEAN SetFirstStatus = FALSE;
    NTSTATUS FirstStatus;

//    SERIAL_LOCKED_PAGED_CODE();

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

    ASSERT(Extension->CurrentMaskIrp);

    do {

        SerialDump(
            SERDIAG4,
            ("SERIAL: STARTMASK - CurrentMaskIrp: %x\n",Extension->CurrentMaskIrp)
            );
        IrpSp = IoGetCurrentIrpStackLocation(Extension->CurrentMaskIrp);

        ASSERT((IrpSp->Parameters.DeviceIoControl.IoControlCode ==
                IOCTL_SERIAL_WAIT_ON_MASK) ||
               (IrpSp->Parameters.DeviceIoControl.IoControlCode ==
                IOCTL_SERIAL_SET_WAIT_MASK));

        if (IrpSp->Parameters.DeviceIoControl.IoControlCode ==
            IOCTL_SERIAL_SET_WAIT_MASK) {

            SerialDump(
                SERDIAG4,
                ("SERIAL - %x is a SETMASK irp\n",Extension->CurrentMaskIrp)
                );

            //
            // Complete the old wait if there is one.
            //
/*
			KeSynchronizeExecution(
              Extension->Interrupt,
                SerialFinishOldWait,
                Extension
                );
*/
			SerialFinishOldWait(Extension);

            //
            // Any current waits should be on its way to completion
            // at this point.  There certainly shouldn't be any
            // irp mask location.
            //

            ASSERT(!Extension->IrpMaskLocation);

            Extension->CurrentMaskIrp->IoStatus.Status = STATUS_SUCCESS;

            if (!SetFirstStatus) {

                SerialDump(
                    SERDIAG4,
                    ("SERIAL: %x was the first irp processed by this\n"
                     "------- invocation of startmask\n",Extension->CurrentMaskIrp)
                    );
                FirstStatus = STATUS_SUCCESS;
                SetFirstStatus = TRUE;

            }

            //
            // The following call will also cause the current
            // call to be completed.
            //

            SerialGetNextIrp(
                &Extension->CurrentMaskIrp,
                &Extension->MaskQueue,
                &NewIrp,
                TRUE,
                Extension
                );
            SerialDump(
                SERDIAG4,
                ("SERIAL: Perhaps another mask irp was found in the queue\n"
                 "------- %x/%x <- values should be the same\n",
                 Extension->CurrentMaskIrp,NewIrp)
                );


        } else {

            //
            // First make sure that we have a non-zero mask.
            // If the app queues a wait on a zero mask it can't
            // be statisfied so it makes no sense to start it.
            //

            if ((!Extension->IsrWaitMask) || (Extension->CurrentWaitIrp)) {

                SerialDump(
                    SERDIAG4,
                    ("SERIAL: WaitIrp is invalid\n"
                     "------- IsrWaitMask: %x\n"
                     "------- CurrentWaitIrp: %x\n",
                     Extension->IsrWaitMask,
                     Extension->CurrentWaitIrp)
                    );

                Extension->CurrentMaskIrp->IoStatus.Status = STATUS_INVALID_PARAMETER;

                if (!SetFirstStatus) {

                    SerialDump(
                        SERDIAG4,
                        ("SERIAL: %x was the first irp processed by this\n"
                         "------- invocation of startmask\n",Extension->CurrentMaskIrp)
                        );
                    FirstStatus = STATUS_INVALID_PARAMETER;
                    SetFirstStatus = TRUE;

                }

                SerialGetNextIrp(
                    &Extension->CurrentMaskIrp,
                    &Extension->MaskQueue,
                    &NewIrp,
                    TRUE,
                    Extension
                    );
                SerialDump(
                    SERDIAG4,
                    ("SERIAL: Perhaps another mask irp was found in the queue\n"
                     "------- %x/%x <- values should be the same\n",
                     Extension->CurrentMaskIrp,NewIrp)
                    );

            } else {

                KIRQL OldIrql;

                //
                // Make the current mask irp the current wait irp and
                // get a new current mask irp.  Note that when we get
                // the new current mask irp we DO NOT complete the
                // old current mask irp (which is now the current wait
                // irp.
                //
                // Then under the protection of the cancel spin lock
                // we check to see if the current wait irp needs to
                // be canceled
                //

                IoAcquireCancelSpinLock(&OldIrql);

                if (Extension->CurrentMaskIrp->Cancel) {

                    SerialDump(
                        SERDIAG4,
                        ("SERIAL: %x irp was already marked as cancelled\n",
                         Extension->CurrentMaskIrp)
                        );
                    IoReleaseCancelSpinLock(OldIrql);
                    Extension->CurrentMaskIrp->IoStatus.Status = STATUS_CANCELLED;

                    if (!SetFirstStatus) {

                        SerialDump(
                            SERDIAG4,
                            ("SERIAL: %x was the first irp processed by this\n"
                             "------- invocation of startmask\n",Extension->CurrentMaskIrp)
                            );
                        FirstStatus = STATUS_CANCELLED;
                        SetFirstStatus = TRUE;

                    }

                    SerialGetNextIrp(
                        &Extension->CurrentMaskIrp,
                        &Extension->MaskQueue,
                        &NewIrp,
                        TRUE,
                        Extension
                        );
                    SerialDump(
                        SERDIAG4,
                        ("SERIAL: Perhaps another mask irp was found in the queue\n"
                         "------- %x/%x <- values should be the same\n",
                         Extension->CurrentMaskIrp,NewIrp)
                        );

                } else {

                    SerialDump(
                        SERDIAG4,
                        ("SERIAL: %x will become the current wait irp\n",
                         Extension->CurrentMaskIrp)
                        );
                    if (!SetFirstStatus) {

                        SerialDump(
                            SERDIAG4,
                            ("SERIAL: %x was the first irp processed by this\n"
                             "------- invocation of startmask\n",Extension->CurrentMaskIrp)
                            );
                        FirstStatus = STATUS_PENDING;
                        SetFirstStatus = TRUE;

                        //
                        // If we haven't already set a first status
                        // then there is a chance that this packet
                        // was never on the queue.  We should mark
                        // it as pending.
                        //

                        IoMarkIrpPending(Extension->CurrentMaskIrp);

                    }

                    //
                    // There should never be a mask location when
                    // there isn't a current wait irp.  At this point
                    // there shouldn't be a current wait irp also.
                    //

                    ASSERT(!Extension->IrpMaskLocation);
                    ASSERT(!Extension->CurrentWaitIrp);

                    Extension->CurrentWaitIrp = Extension->CurrentMaskIrp;
                    SERIAL_INIT_REFERENCE(Extension->CurrentWaitIrp);
                    IoSetCancelRoutine(
                        Extension->CurrentWaitIrp,
                        SerialCancelWait
                        );

                    //
                    // Since the cancel routine has a reference to
                    // the irp we need to update the reference
                    // count.
                    //

                    SERIAL_SET_REFERENCE(
                        Extension->CurrentWaitIrp,
                        SERIAL_REF_CANCEL
                        );
/*
                    KeSynchronizeExecution(
                        Extension->Interrupt,
                        SerialGiveWaitToIsr,
                        Extension
                        );
*/
					SerialGiveWaitToIsr(Extension);

                    //
                    // Since it isn't really the mask irp anymore,
                    // null out that pointer.
                    //

                    Extension->CurrentMaskIrp = NULL;

                    //
                    // This will release the cancel spinlock for us
                    //

                    SerialGetNextIrpLocked(
                        &Extension->CurrentMaskIrp,
                        &Extension->MaskQueue,
                        &NewIrp,
                        FALSE,
                        Extension,
                        OldIrql
                        );
                    SerialDump(
                        SERDIAG4,
                        ("SERIAL: Perhaps another mask irp was found in the queue\n"
                         "------- %x/%x <- values should be the same\n",
                         Extension->CurrentMaskIrp,NewIrp)
                        );

                }

            }

        }

    } while (NewIrp);

    return FirstStatus;

⌨️ 快捷键说明

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