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

📄 isopnp.c

📁 传说中的 usb 端口 驱动 源码 啊啊啊啊啊啊啊
💻 C
📖 第 1 页 / 共 5 页
字号:
/*++

Copyright (c) 2004  Microsoft Corporation

Module Name:

    isopnp.c

Abstract:

    Isoch USB device driver for Intel 82930 USB test board
    Plug and Play module

Environment:

    Kernel mode

Notes:

    Copyright (c) 2004 Microsoft Corporation.
    All Rights Reserved.

--*/

#include "isousb.h"
#include "isopnp.h"
#include "isopwr.h"
#include "isodev.h"
#include "isowmi.h"
#include "isousr.h"
#include "isorwr.h"
#include "isostrm.h"

NTSTATUS
IsoUsb_DispatchPnP(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp
    )
/*++

Routine Description:

    The plug and play dispatch routines.
    Most of these requests the driver will completely ignore.
    In all cases it must pass on the IRP to the lower driver.

Arguments:

    DeviceObject - pointer to a device object.

    Irp - pointer to an I/O Request Packet.

Return Value:

    NT status code

--*/
{
    PIO_STACK_LOCATION irpStack;
    PDEVICE_EXTENSION  deviceExtension;
    KEVENT             startDeviceEvent;
    NTSTATUS           ntStatus;

    //
    // initialize variables
    //

    irpStack = IoGetCurrentIrpStackLocation(Irp);
    deviceExtension = DeviceObject->DeviceExtension;

    //
    // since the device is removed, fail the Irp.
    //

    if(Removed == deviceExtension->DeviceState) {

        ntStatus = STATUS_DELETE_PENDING;

        Irp->IoStatus.Status = ntStatus;
        Irp->IoStatus.Information = 0;

        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        return ntStatus;
    }

    IsoUsb_DbgPrint(3, ("///////////////////////////////////////////\n"));
    IsoUsb_DbgPrint(3, ("IsoUsb_DispatchPnP::"));
    IsoUsb_IoIncrement(deviceExtension);

    if(irpStack->MinorFunction == IRP_MN_START_DEVICE) {

        ASSERT(deviceExtension->IdleReqPend == 0);
    }
    else {

        if(deviceExtension->SSEnable) {

            CancelSelectSuspend(deviceExtension);
        }
    }

    IsoUsb_DbgPrint(2, (PnPMinorFunctionString(irpStack->MinorFunction)));

    switch(irpStack->MinorFunction) {

    case IRP_MN_START_DEVICE:

        ntStatus = HandleStartDevice(DeviceObject, Irp);

        break;

    case IRP_MN_QUERY_STOP_DEVICE:

        //
        // if we cannot stop the device, we fail the query stop irp
        //
        ntStatus = CanStopDevice(DeviceObject, Irp);

        if(NT_SUCCESS(ntStatus)) {

            ntStatus = HandleQueryStopDevice(DeviceObject, Irp);

            return ntStatus;
        }
        break;

    case IRP_MN_CANCEL_STOP_DEVICE:

        ntStatus = HandleCancelStopDevice(DeviceObject, Irp);

        break;

    case IRP_MN_STOP_DEVICE:

        ntStatus = HandleStopDevice(DeviceObject, Irp);

        IsoUsb_DbgPrint(3, ("IsoUsb_DispatchPnP::IRP_MN_STOP_DEVICE::"));
        IsoUsb_IoDecrement(deviceExtension);

        return ntStatus;

    case IRP_MN_QUERY_REMOVE_DEVICE:

        //
        // if we cannot remove the device, we fail the query remove irp
        //
        ntStatus = CanRemoveDevice(DeviceObject, Irp);

        if(NT_SUCCESS(ntStatus)) {

            ntStatus = HandleQueryRemoveDevice(DeviceObject, Irp);

            return ntStatus;
        }
        break;

    case IRP_MN_CANCEL_REMOVE_DEVICE:

        ntStatus = HandleCancelRemoveDevice(DeviceObject, Irp);

        break;

    case IRP_MN_SURPRISE_REMOVAL:

        ntStatus = HandleSurpriseRemoval(DeviceObject, Irp);

        IsoUsb_DbgPrint(3, ("IsoUsb_DispatchPnP::IRP_MN_SURPRISE_REMOVAL::"));
        IsoUsb_IoDecrement(deviceExtension);

        return ntStatus;

    case IRP_MN_REMOVE_DEVICE:

        ntStatus = HandleRemoveDevice(DeviceObject, Irp);

        return ntStatus;

    case IRP_MN_QUERY_CAPABILITIES:

        ntStatus = HandleQueryCapabilities(DeviceObject, Irp);

        break;

    default:

        IoSkipCurrentIrpStackLocation(Irp);

        ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);

        IsoUsb_DbgPrint(3, ("IsoUsb_DispatchPnP::default::"));
        IsoUsb_IoDecrement(deviceExtension);

        return ntStatus;

    } // switch

//
// complete request
//

    Irp->IoStatus.Status = ntStatus;
    Irp->IoStatus.Information = 0;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);

//
// decrement count
//
    IsoUsb_DbgPrint(3, ("IsoUsb_DispatchPnP::"));
    IsoUsb_IoDecrement(deviceExtension);

    return ntStatus;
}


NTSTATUS
HandleStartDevice(
    IN PDEVICE_OBJECT   DeviceObject,
    IN PIRP             Irp
    )
/*++

Routine Description:

    This is the dispatch routine for RP_MJ_PNP, IRP_MN_START_DEVICE

    The PnP Manager sends this IRP at IRQL PASSIVE_LEVEL in the context
    of a system thread.

    This IRP must be handled first by the underlying bus driver for a
    device and then by each higher driver in the device stack.

Arguments:

    DeviceObject - pointer to a device object.

    Irp - I/O request packet

Return Value:

    NT status value

--*/
{
    PDEVICE_EXTENSION deviceExtension;
    KIRQL             oldIrql;
    LARGE_INTEGER     dueTime;
    NTSTATUS          ntStatus;

    IsoUsb_DbgPrint(3, ("HandleStartDevice - begins\n"));

    //
    // initialize variables
    //
    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

    // Pass the IRP_MN_START_DEVICE Irp down the stack first before we
    // do anything.
    //
    ntStatus = IsoUsb_SyncPassDownIrp(DeviceObject,
                                      Irp);

    if (!NT_SUCCESS(ntStatus))
    {
        IsoUsb_DbgPrint(1, ("Lower drivers failed IRP_MN_START_DEVICE\n"));
        return ntStatus;
    }

    // If this is the first time the device as been started, retrieve the
    // Device and Configuration Descriptors from the device.
    //
    if (deviceExtension->DeviceDescriptor == NULL)
    {
        ntStatus = IsoUsb_GetDescriptors(DeviceObject);

        if (!NT_SUCCESS(ntStatus))
        {
            return ntStatus;
        }
    }

    // Now configure the device
    //
    ntStatus = IsoUsb_SelectConfiguration(DeviceObject);

    if (!NT_SUCCESS(ntStatus))
    {
        return ntStatus;
    }

    //
    // enable the symbolic links for system components to open
    // handles to the device
    //

    ntStatus = IoSetDeviceInterfaceState(&deviceExtension->InterfaceName,
                                         TRUE);

    if(!NT_SUCCESS(ntStatus)) {

        IsoUsb_DbgPrint(1, ("IoSetDeviceInterfaceState:enable:failed\n"));
        return ntStatus;
    }

    KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql);

    SET_NEW_PNP_STATE(deviceExtension, Working);
    deviceExtension->QueueState = AllowRequests;

    KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql);

    //
    // initialize wait wake outstanding flag to false.
    // and issue a wait wake.

    deviceExtension->FlagWWOutstanding = 0;
    deviceExtension->FlagWWCancel = 0;
    deviceExtension->WaitWakeIrp = NULL;

    if(deviceExtension->WaitWakeEnable) {

        IssueWaitWake(deviceExtension);
    }

    ProcessQueuedRequests(deviceExtension);

    if(WinXpOrBetter == deviceExtension->WdmVersion) {

        deviceExtension->SSEnable = deviceExtension->SSRegistryEnable;

        //
        // set timer for selective suspend requests.
        //

        if(deviceExtension->SSEnable) {

            dueTime.QuadPart = -10000 * IDLE_INTERVAL;               // 5000 ms

            KeSetTimerEx(&deviceExtension->Timer,
                         dueTime,
                         IDLE_INTERVAL,                              // 5000 ms
                         &deviceExtension->DeferredProcCall);

            deviceExtension->FreeIdleIrpCount = 0;
        }
    }

    if((Win2kOrBetter == deviceExtension->WdmVersion) ||
       (WinXpOrBetter == deviceExtension->WdmVersion)) {

        deviceExtension->IsDeviceHighSpeed = 0;
        GetBusInterfaceVersion(DeviceObject);
    }

    IsoUsb_DbgPrint(3, ("HandleStartDevice - ends\n"));

    return ntStatus;
}


NTSTATUS
CanStopDevice(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp
    )
/*++

Routine Description:

    This routine determines whether the device can be safely stopped. In our
    particular case, we'll assume we can always stop the device.
    A device might fail the request if it doesn't have a queue for the
    requests it might come or if it was notified that it is in the paging
    path.

Arguments:

    DeviceObject - pointer to the device object.

    Irp - pointer to the current IRP.

Return Value:

    STATUS_SUCCESS if the device can be safely stopped, an appropriate
    NT Status if not.

--*/
{
   //
   // We assume we can stop the device
   //

   UNREFERENCED_PARAMETER(DeviceObject);
   UNREFERENCED_PARAMETER(Irp);

   return STATUS_SUCCESS;
}


NTSTATUS
HandleQueryStopDevice(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp
    )
/*++

Routine Description:

    This routine services the Irps of minor type IRP_MN_QUERY_STOP_DEVICE

Arguments:

    DeviceObject - pointer to device object
    Irp - I/O request packet sent by the pnp manager.

Return Value:

    NT status value

--*/
{
    KIRQL             oldIrql;
    NTSTATUS          ntStatus;
    PDEVICE_EXTENSION deviceExtension;

    IsoUsb_DbgPrint(3, ("HandleQueryStopDevice - begins\n"));

    //
    // initialize variables
    //

    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

    //
    // If we can stop the device, we need to set the QueueState to
    // HoldRequests so further requests will be queued.
    //

    KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql);

    SET_NEW_PNP_STATE(deviceExtension, PendingStop);
    deviceExtension->QueueState = HoldRequests;

    KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql);

    //
    // wait for the existing ones to be finished.
    // first, decrement this operation
    //

    IsoUsb_DbgPrint(3, ("HandleQueryStopDevice::"));
    IsoUsb_IoDecrement(deviceExtension);

    KeWaitForSingleObject(&deviceExtension->StopEvent,
                          Executive,
                          KernelMode,
                          FALSE,
                          NULL);

    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

⌨️ 快捷键说明

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