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

📄 usbfx2lk_power.cpp

📁 基于vc++6.0环境的cypress USB 驱动源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:

    //
    // Which power state are we talking about?
    //
    powerState = ioStack->Parameters.Power.State;

    //
    // For ALL power IRPs, we are REQUIRED to:
    //
    //  1) call PoStartNextPowerIrp()
    //  2) Pass the IRP down to the next lower driver, unless
    //      we complete the request with an error.
    //

    switch(ioStack->MinorFunction)  {
        
            
        case IRP_MN_QUERY_POWER:

            OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_POWER_INFO, 
                ("OsrHandleDevicePowerIrp: Querying Device state transition to %s\n", 
                OsrPrintDevicePowerState(powerState.DeviceState)));
        
            //
            // We will always accept the device QUERY_POWER 
            // for our device.
            //
            // A device may need to start queuing inbound I/O requests  
            // here.  If a device does queue new requests on power down
            // then it must have some method of restarting those requests
            // when the device is returned to full power.  When and where
            // to start queuing requests is device specific and could 
            // possibly be postponed until the SET_POWER IRP arrives.  
            // However, it is typically when a QUERY_POWER IRP for the
            // device is received that a driver starts queuing requests.
            //

            //
            // Enter the POWER_PROCESSING state, all I/O
            //  requests will be queued
            //
            OsrUpdateDeviceState(devExt, STATE_POWER_PROCESSING);

            //
            // Setup our completion routine that just calls PoStartNextPowerIrp.
            //
            // See DevicePowerIoCompletionRoutine for an explanation
            //  of why we wait until the Irp comes back up to 
            //  call PoStartNextPowerIrp...
            //
            IoMarkIrpPending(Irp);
            
            IoCopyCurrentIrpStackLocationToNext(Irp);
            
            IoSetCompletionRoutine(Irp, 
                                   DevicePowerIoCompletionRoutine,
                                   (PVOID)devExt,
                                   TRUE,
                                   TRUE,
                                   TRUE);
        
            //
            // Pass the device power irp down using PoCallDriver! 
            //  It is an error to use IoCallDriver here...Power irps 
            //  must be passed down with PoCallDriver, since it
            //  will do some additional work to ensure proper
            //  synchronization of power Irps
            //
            (VOID)PoCallDriver(devExt->DeviceToSendIrpsTo,
                               Irp);
        
            //
            // We've registered an IO completion routine so we're not 
            //  finished with this Irp...DON'T release our remove lock!
            //
            
            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_POWER_INFO, ("OsrHandleDevicePowerIrp: Exiting!\n"));
            
            //
            // We've marked the Irp pending so we MUST
            //  return STATUS_PENDING
            //
            
            return STATUS_PENDING;
            
       case IRP_MN_SET_POWER:
           
           OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_POWER_INFO, 
                       ("OsrHandleDevicePowerIrp: Setting Device state to %s\n", 
                       OsrPrintDevicePowerState(powerState.DeviceState)));

           
           // 
           // We need to determine if we are powering up, powering down, or if
           // the device's power state is not changing.
           //
           if(devExt->DevicePowerState > powerState.DeviceState) {
               
               //
               // This is a power up, we send the IRP down so the PDO can power up
               // first, then we finish our processing in an I/O completion routine.
               //
               IoMarkIrpPending(Irp);
               
               IoCopyCurrentIrpStackLocationToNext(Irp);
               
               IoSetCompletionRoutine(Irp, 
                                      DevicePowerIoCompletionRoutine,
                                      (PVOID)devExt,
                                      TRUE,
                                      TRUE,
                                      TRUE);
               
               //
               // Pass the irp down using PoCallDriver! It is an
               //  error to use IoCallDriver here...Power irps 
               //  must be passed down with PoCallDriver, since it
               //  will do some additional work to ensure proper
               //  synchronization of power Irps
               //
               (VOID)PoCallDriver(devExt->DeviceToSendIrpsTo, 
                                  Irp);
               
               //
               // We've registered an IO completion routine so we're not 
               //  finished with this Irp...DON'T release our remove lock!
               //
               
               OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_POWER_INFO, ("OsrHandleDevicePowerIrp: Exiting!\n"));
               
               //
               // The IRP is marked pending so we 
               // MUST return STATUS_PENDING here.
               //
               return STATUS_PENDING;
               
               
           } else if (devExt->DevicePowerState < powerState.DeviceState) {

               //
               // Power down case. We handle it first and send the IRP to the bus
               //  with a completion routine that calls PoStartNextPowerIrp
               //
               // See DevicePowerIoCompletionRoutine for an explanation
               //  of why we wait until the Irp comes back up to 
               //  call PoStartNextPowerIrp...
               //
               //


               // 
               //  Notify the power manager of our device power state change
               //
               PoSetPowerState(DeviceObject, 
                               DevicePowerState, 
                               powerState);
               
               
               IoMarkIrpPending(Irp);
               
               IoCopyCurrentIrpStackLocationToNext(Irp);
               
               IoSetCompletionRoutine(
                                      Irp, 
                                      DevicePowerIoCompletionRoutine,
                                      (PVOID)devExt,
                                      TRUE,
                                      TRUE,
                                      TRUE);
               
               //
               // Pass the irp down using PoCallDriver! It is an
               //  error to use IoCallDriver here...Power irps 
               //  must be passed down with PoCallDriver, since it
               //  will do some additional work to ensure proper
               //  synchronization of power Irps
               //
               (VOID)PoCallDriver(devExt->DeviceToSendIrpsTo,   
                                  Irp);
               
               //
               // We've registered an IO completion routine so we're not 
               //  finished with this Irp...DON'T release our remove lock!
               //
               
               OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_POWER_INFO, ("OsrHandleDevicePowerIrp: Exiting!\n"));
               
               //
               // The IRP is marked pending so we 
               // MUST return STATUS_PENDING here.
               //
               return STATUS_PENDING;
               
           } else {
               
               //
               // Else we're staying at the same power state.
               //  There's no reason to touch our hardware, so
               //  we're just going to set our completion routine
               //  and call PoStartNextPowerIrp in the completion routine.
               //  
               // See DevicePowerIoCompletionRoutine for an explanation
               //  of why we wait until the Irp comes back up to 
               //  call PoStartNextPowerIrp...
               //
               
               IoMarkIrpPending(Irp);
               
               IoCopyCurrentIrpStackLocationToNext(Irp);
               
               IoSetCompletionRoutine(
                                      Irp, 
                                      DevicePowerIoCompletionRoutine,
                                      (PVOID)devExt,   
                                      TRUE,
                                      TRUE,
                                      TRUE);
               
               //
               // Pass the irp down using PoCallDriver! It is an
               //  error to use IoCallDriver here...Power irps 
               //  must be passed down with PoCallDriver, since it
               //  will do some additional work to ensure proper
               //  synchronization of power Irps
               //
               (VOID)PoCallDriver(devExt->DeviceToSendIrpsTo, 
                                  Irp);
               
               //
               // We've registered an IO completion routine so we're not 
               //  finished with this Irp...DON'T release our remove lock!
               //
               
               OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_POWER_INFO, ("OsrHandleDevicePowerIrp: Exiting!\n"));
               
               //
               // The IRP is marked pending so we 
               // MUST return STATUS_PENDING here.
               //
               return STATUS_PENDING;
               
           }
           
           //
           // We never get here...
           //
           return STATUS_UNSUCCESSFUL;
           
        case IRP_MN_WAIT_WAKE:

            OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_POWER_INFO, 
                        ("OsrHandleDevicePowerIrp: IRP_MN_WAIT_WAKE received.\n"));
                
            IoMarkIrpPending(Irp);

            IoCopyCurrentIrpStackLocationToNext(Irp);

            IoSetCompletionRoutine(
                            Irp,
                            (PIO_COMPLETION_ROUTINE)WaitWakeCompletionRoutine,
                            devExt, 
                            TRUE, 
                            TRUE, 
                            TRUE);

            PoStartNextPowerIrp(Irp);

            status = PoCallDriver(devExt->DeviceToSendIrpsTo, Irp);

            if(!NT_SUCCESS(status)) {

                OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_POWER_INFO,
                    ("OsrHandleDevicePowerIrp: Lower drivers failed the wait-wake Irp\n"));
            }

            status = STATUS_PENDING;

            //
            // push back the count HERE and NOT in completion routine
            // a pending Wait Wake Irp should not impede stopping the device
            //

            OsrDecrementOutstandingIoCount(devExt,__FILE__,__LINE__);

            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_POWER_INFO, ("OsrHandleDevicePowerIrp: Exit..\n"));

            return STATUS_PENDING;

        case IRP_MN_BOGUS:

            //
            // Driver Verifier bogus minor function code
            //
            
            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_POWER_INFO, 
                    ("OsrHandleDevicePowerIrp: Received IRP_MN_BOGUS: Just pass it along...\n"));

            //
            // Fall through...
            //


        case IRP_MN_POWER_SEQUENCE:

            // 
            // This device does not support wake or power sequence so 
            // we just send the request down to the bus
            //

            //
            // Fall through...
            //

        default:
        
            //
            // Unknown power code...
            //
            
            //
            // No matter what we always must call 
            //  PoStartNextPowerIrp...
            //
            //  We must also always make this call BEFORE calling
            //  IoSkipCurrentIrpStackLocation. Why? Because
            //  PoStartNextPowerIrp lets another power Irp of 
            //  the same kind that we're processing now through
            //  (System or Device). How does it know what kind
            //  of Irp we're handling? Why from the current
            //  stack location of course!
            //
            
            PoStartNextPowerIrp(Irp);
            
            IoSkipCurrentIrpStackLocation(Irp);
            
            //
            // Pass the irp down using PoCallDriver! It is an
            //  error to use IoCallDriver here...Power irps 
            //  must be passed down with PoCallDriver, since it
            //  will do some additional work to ensure proper
            //  synchronization of power Irps
            //
            status = PoCallDriver(devExt->DeviceToSendIrpsTo, Irp);
            
            //
            // We're done with this request
            //
            OsrDecrementOutstandingIoCount(devExt,__FILE__,__LINE__);
            
            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_POWER_INFO, ("OsrHandleDevicePowerIrp: Exiting!\n"));
            
            return status;
            
    }
    
    //
    // We never get here...
    //

    OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_POWER_INFO, 
            ("OsrHandleDevicePowerIrp: Should never reach the end! Breaking into the debugger if attached...\n"));

    //
    // Use KdBreakPoint instead of DbgBreakPoint so that 
    //  we only break in the checked build...
    //
    KdBreakPoint();

    return STATUS_UNSUCCESSFUL;


}


///////////////////////////////////////////////////////////////////////////////
//
// DevicePowerIoCompletionRoutine
//
//      Our I/O completion routine for device power up IRPs.
//
//  INPUTS:
//
//      DeviceObject - Pointer to device object.
//      Irp          - Address of the DEVICE power IRP.
//      Context      - the device extension
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//      NTSTATUS value signalling the I/O manager to continue processing IRP
//      stack locations or not.
//
//  IRQL:
//
//      This routine is called at IRQL <= DISPATCH_LEVEL
//
//  CONTEXT:
//
//      This routine is called in an arbitrary thread context
//
//  NOTES:
//
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS  DevicePowerIoCompletionRoutine(PDEVICE_OBJECT DeviceObject,PIRP Irp,
                                         PVOID Context) 
{

⌨️ 快捷键说明

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