BOOLEAN NICEvtInterruptIsr( IN WDFINTERRUPT Interrupt, IN ULONG MessageID ) /*++ Routine Description: Interrupt handler for the device. Arguments: Interupt - Address of the framework interrupt object MessageID - Return Value: TRUE if our device is interrupting, FALSE otherwise. --*/ { BOOLEAN InterruptRecognized = FALSE; PFDO_DATA FdoData = NULL; USHORT IntStatus; UNREFERENCED_PARAMETER( MessageID ); TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INTERRUPT, "--> NICEvtInterruptIsr\n"); FdoData = FdoGetData(WdfInterruptGetDevice(Interrupt)); // // We process the interrupt if it's not disabled and it's active // if (!NIC_INTERRUPT_DISABLED(FdoData) && NIC_INTERRUPT_ACTIVE(FdoData)) { InterruptRecognized = TRUE; // // Disable the interrupt (will be re-enabled in NICEvtInterruptDpc // NICDisableInterrupt(FdoData); // // Acknowledge the interrupt(s) and get the interrupt status // NIC_ACK_INTERRUPT(FdoData, IntStatus); WdfInterruptQueueDpcForIsr( Interrupt ); } TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INTERRUPT, "<-- NICEvtInterruptIsr\n"); return InterruptRecognized; }
BOOLEAN MPSetPowerLowPrivate( PVOID Context ) /*++ Routine Description: The section follows the steps mentioned in Section C.2.6.2 of the Reference Manual. Arguments: Adapter Pointer to our adapter Return Value: --*/ { CSR_FILTER_STRUC Filter; USHORT IntStatus; MP_PMCSR PMCSR = {0}; ULONG ulResult; PFDO_DATA FdoData = Context; DebugPrint(TRACE, DBG_POWER, "-->MPSetPowerLowPrivate\n"); RtlZeroMemory (&Filter, sizeof (Filter)); do { // // Before issue the command to low power state, we should disable the // interrup and ack all the pending interrupts, then set the adapter's power to // low state. // NICDisableInterrupt(FdoData); NIC_ACK_INTERRUPT(FdoData, IntStatus); // // If the driver should wake up the machine // if (FdoData->AllowWakeArming) { // // Send the WakeUp Patter to the nic MPIssueScbPoMgmtCommand(FdoData, &Filter, TRUE); // // Section C.2.6.2 - The driver needs to wait for the CU to idle // The above function already waits for the CU to idle // ASSERT ((FdoData->CSRAddress->ScbStatus & SCB_CUS_MASK) == SCB_CUS_IDLE); } else { ulResult = FdoData->BusInterface.GetBusData( FdoData->BusInterface.Context, PCI_WHICHSPACE_CONFIG, (PVOID)&PMCSR, FIELD_OFFSET(MP_PM_PCI_SPACE, PMCSR), sizeof(PMCSR)); if(ulResult != sizeof(PMCSR)){ ASSERT(ulResult == sizeof(PMCSR)); DebugPrint(ERROR, DBG_POWER, "GetBusData for PMCSR failed\n"); return FALSE; } if (PMCSR.PME_En == 1) { // // PME is enabled. Clear the PME_En bit. // So that it is not asserted // MpClearPME_En (FdoData,PMCSR); } // // Set the driver to lower power state by OS // } } while (FALSE); DebugPrint(TRACE, DBG_POWER, "<--MPSetPowerLowPrivate\n"); return TRUE; }