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

📄 usbfx2lk_pnp.cpp

📁 基于vc++6.0环境的cypress USB 驱动源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        // In either case, we pass the IRP all the way down.  When it's
        // done we can then read the list of device resources pointed to 
        // in the IRP Stack Location.
        //
        case (STATE_NEVER_STARTED + IRP_MN_START_DEVICE):

            //
            // If we've never been started, we'll need to
            //  enable our device interface. 
            //
            // Note that we don't disable our interface on
            //  a STOP. It's really only a transient 
            //  state and there's no reason why we shouldn't
            //  let users open up our device and queue I/O
            //  to it while we're in it.
            //
            enableInterface = TRUE;

            //
            // Fall through...
            //

        case (STATE_STOPPED + IRP_MN_START_DEVICE): {

            //
            // This is a BUS FIRST Irp. The bus driver is involved in
            //  the allocation of resources for us, so we must give 
            //  it to him first to fill in our stack location with
            //  our resources. 
            //
            status = OsrForwardIrpSynchronous(devExt,Irp);
            
            //
            // Is the bus driver OK with us starting?
            //
            if (NT_SUCCESS(status)) {
                
                //
                // Excellent...Try starting our device!
                //
                status = OsrStartDevice(devExt);
                
                if (NT_SUCCESS(status)) {

                    //
                    // Indicate the initial power state of the device to the 
                    // power manager by calling PoSetPowerState.
                    //
                    powerState.DeviceState   = PowerDeviceD0;
                    
                    PoSetPowerState(DeviceObject, DevicePowerState, powerState);

                    //
                    // Enable SS if the user wants it. The decision
                    //  about whether or not SS is enabled by the user
                    //  is done under lock within EnableSelectiveSuspend
                    //
                    EnableSelectiveSuspend(devExt);

                    OsrUpdateDeviceState(devExt, STATE_STARTED);

                    //
                    // IF you registered a device interface, using
                    //  IoRegisterDeviceInterface(), and you're coming
                    //  out of the NEVER_STARTED state, you'll also need to
                    //  set the interface state here to ENABLED.  This is
                    //  done with the following call.
                    //
                    if (enableInterface) {

                        status = IoSetDeviceInterfaceState(
                                        &devExt->InterfaceName,
                                        TRUE);

                        if (!NT_SUCCESS(status)) {
                        
                            //
                            // We won't consider this to be fatal. Currently the only reason
                            //  for it happening is if the interface is already enabled, in
                            //  which case it's a bug and this DbgPrint should suffice.
                            //
                            OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_PNP_INFO, 
                                ("OsrPnp: IoSetDeviceInterfaceState failed! Returned status 0x%8.8x (%s)\n",
                                status, OsrNtStatusToString(status)));
                        
                        }

                    }


                    //
                    // Initialize WaitWake Information and queue a wait 
                    //  wake IRP to the host if waking is enabled for the device.
                    //
                    devExt->FlagWWOutstanding = 0;
                    devExt->FlagWWCancel = 0;
                    devExt->WaitWakeIrp = NULL;

                    if(devExt->DeviceCapabilitiesInitialized && devExt->WaitWakeEnable) {
                        IssueWaitWake(devExt);
                    }

                    // 
                    // If we were stopped, our queues were stalled and 
                    // we need to restart them.  We are guaranteed to 
                    // be powered up here.
                    //
                    OsrProcessQueuedRequests(devExt);

                } else {
                    
                    OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_PNP_INFO, 
                        ("OsrPnp: Unable to start device! Status = 0x%8.8x (%s)\n", 
                        status, OsrNtStatusToString(status)));
                    
                }
                
                
            } else {
                
                OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_PNP_INFO, 
                    ("OsrPnp: Request to start failed! Status = 0x%8.8x (%s)\n", 
                    status, OsrNtStatusToString(status)));
                
            }
                
            //
            // Fill in the completion status...
            //
            Irp->IoStatus.Status      = status;
            Irp->IoStatus.Information = 0;
            
            //
            //  We need to call IoCompleteRequest on it
            //  to finish processing. 
            //
            IoCompleteRequest(Irp, IO_NO_INCREMENT);

            //
            // We're done with this request
            //
            OsrDecrementOutstandingIoCount(devExt,__FILE__,__LINE__);

            
            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO, 
                ("OsrPnp: Finished! Leaving with state %s\n",
                OsrPrintState(devExt)));
            
            return status;

        }
           
        //
        // STATE:   STARTED
        // IRP_MN:  _QUERY_STOP_DEVICE
        //
        // We're here if we're running and the PnP Manager sends us
        // a QUERY_STOP_DEVICE request.  He'll do this if he wants to
        // rebalance resources to see if we're willing to give up the
        // anything we setup during our IRP_MN_START_DEVICE.
        //
        // To proess this QUERY_STOP, we check to see if the stop is
        // acceptable to us (in this driver it always is), and then
        // we just transition the device to STOP_PENDING state.  In
        // this state, new requests that arrive are queued.  When a
        // currently in-progress request is completed, a new request
        // is NOT started.  Thus, ON OUR DEVICE, we sort of hope that
        // between the QUERY_STOP IRP arrive and actual STOP IRP arriving
        // that any in-progress I/O will complete of its own accord.
        // We like this scheme, particularly because at least on NT
        // during startup the device seems to get lots of QUERY_STOP
        // IRPs, that are just followed by CANCEL_STOP.  Thus, we think
        // it would be unfortunate to do anything radical with the
        // outstanding requests (like cancel them) when we receive a
        // QUERY_STOP.
        //
        case (STATE_STARTED + IRP_MN_QUERY_STOP_DEVICE): {
        
            //
            // See if we're OK with stopping the device at this point.
            // We do NOT actually RETURN the resources here... we
            // just affirm or deny that we're OK with returning them.
            //
            status = OsrCanStopDevice(devExt, Irp);
            
            if (!NT_SUCCESS(status)) {
                
                //
                // Nope...We can't stop the device
                //  so there's no need to pass it 
                //  down to see if anyone else can stop.
                //  Just complete the Irp and return...
                //
                Irp->IoStatus.Status      = status;
                Irp->IoStatus.Information = 0;
                
                IoCompleteRequest(Irp, IO_NO_INCREMENT);

                //
                // We're done with this request
                //
                OsrDecrementOutstandingIoCount(devExt,__FILE__,__LINE__);
                
                OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO, 
                    ("OsrPnp: Finished! Leaving with state %s\n",
                    OsrPrintState(devExt)));
                
                return status;
            }
            
            //
            // We're cool with being stopped. 
            //

            //
            // Power the device up if it isn't already. 
            //  Do this before changing the device's 
            //  PnP state.
            //
            SSPowerDeviceIfSuspended(devExt);

            //
            // If enabled, disable selective suspend. We'll
            //  enable it again if we get a cancel.
            //
            DisableSelectiveSuspend(devExt);

            //
            // Set new state. This state results in no new
            // requests being started on the device, but incoming
            // requests are still allowed and queued.
            //
            OsrUpdateDeviceState(devExt, STATE_STOP_PENDING);


            //
            // Wait until all active requests on the device have
            // completed so that we can return our resources
            //  in the STOP case. 
            //
            OsrDecrementOutstandingIoCount(devExt,__FILE__,__LINE__);
            OsrWaitForStop(devExt);

            //
            // Replace status code that's in the IRP to indicate our
            // opinion about stopping the device.  If we're
            // OK with being stopped this HAS to be
            // STATUS_SUCCESS.
            //
            Irp->IoStatus.Status = STATUS_SUCCESS;
            

            //
            // Pass this request on down to the next driver
            //
            IoSkipCurrentIrpStackLocation(Irp);
            
            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO, 
                ("OsrPnp: Finished! Leaving with state %s\n",
                OsrPrintState(devExt)));
            
            status = IoCallDriver(devExt->DeviceToSendIrpsTo, Irp);

            return status;
            
        }
        
        //
        // STATE:   STOP_PENDING
        // IRP_MN:  _CANCEL_STOP_DEVICE
        //
        // We're here because we've already received a QUERY_STOP,
        // that we've agreed to.  We've completed any pending I/O
        // requests.  Now we've received a CANCEL_STOP_DEVICE
        // IRP, that says "never mind" about that stop.
        //
        // We (hopefully) restart our queues and return to Started state.
        //
        case (STATE_STOP_PENDING + IRP_MN_CANCEL_STOP_DEVICE): {
            
            //
            // OK, so we're not going to be stopped...
            //
            
            //
            // This is a BUS FIRST Irp. 
            //
            status = OsrForwardIrpSynchronous(devExt,Irp);
                
            if (NT_SUCCESS(status)) {
                
                //
                // We're now back to a STARTED state
                //
                OsrUpdateDeviceState(devExt, STATE_STARTED);

                status = STATUS_SUCCESS;
                
                //
                // Start processing any I/O that may have 
                //  been queued due to the QUERY_STOP...
                //
                OsrProcessQueuedRequests(devExt);

            } else {

                //
                // EEP! This is a fatal error if you're running
                //  verifier. We'll print out and hope the
                //  machine stays standing. If a debugger is attached
                //  we'll break into it...
                //
                OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_PNP_INFO, 
                    ("OsrPnp: A device in the stack has FAILED CANCEL_STOP!! Returned status 0x%8.8x (%s)\n",
                    Irp->IoStatus.Status, OsrNtStatusToString(Irp->IoStatus.Status)));

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

            }

            //
            // Re-enable selective suspend (if enabled)
            //
            EnableSelectiveSuspend(devExt);

            //
            // Put the Completion Status into the Irp.
            //
            Irp->IoStatus.Status      = status;
            Irp->IoStatus.Information = 0;
            
            //
            // OsrForwardIrpSynchronous is just a nice little
            //  wrapper that sets a completion routine, calls
            //  the next lowest driver, waits, and then reclaims the Irp
            //  for us in the completion routine by returning
            //  STATUS_MORE_PROCESSING_REQUIRED (or calls 
            //  IoForwardIrpSynchronously to do all of that if 
            //  we're built for XP and later). Just as if we
            //  had carried these steps out by ourselves, we now
            //  own the Irp and need to call IoCompleteRequest on it
            //  to finish processing. 
            //
            IoCompleteRequest(Irp, IO_NO_INCREMENT);

            //
            // We're done with this request
            //
            OsrDecrementOutstandingIoCount(devExt,__FILE__,__LINE__);
            
            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO, 
                ("OsrPnp: Finished! Leaving with state %s\n",
                OsrPrintState(devExt)));
            
            return status;
        
        }

        //
        // STATE:   STOP_PENDING
        // IRP_MN:  _STOP_DEVICE
        //
        // We're in this state because we previously received a 
        // QUERY_STOP_DEVICE, that we agreed that we could grant.
        // Thus, we're waiting to receive a STOP_DEVICE request.
        // To process this request, we first wait for any in-progress
        // requests to complete (note that no NEW requests have been
        // started since the transition to STOP_PENDING state as a

⌨️ 快捷键说明

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