1*8a978a17SVictor Perevertkin // 2*8a978a17SVictor Perevertkin // Copyright (C) Microsoft. All rights reserved. 3*8a978a17SVictor Perevertkin // 4*8a978a17SVictor Perevertkin #ifndef _FXPNPSTATEMACHINE_H_ 5*8a978a17SVictor Perevertkin #define _FXPNPSTATEMACHINE_H_ 6*8a978a17SVictor Perevertkin 7*8a978a17SVictor Perevertkin // @@SMVERIFY_SPLIT_BEGIN 8*8a978a17SVictor Perevertkin 9*8a978a17SVictor Perevertkin typedef 10*8a978a17SVictor Perevertkin WDF_DEVICE_PNP_STATE 11*8a978a17SVictor Perevertkin (*PFN_PNP_STATE_ENTRY_FUNCTION)( 12*8a978a17SVictor Perevertkin FxPkgPnp* This 13*8a978a17SVictor Perevertkin ); 14*8a978a17SVictor Perevertkin 15*8a978a17SVictor Perevertkin // 16*8a978a17SVictor Perevertkin // Treat these values as a bit field when comparing for known dropped events in 17*8a978a17SVictor Perevertkin // the current state and treat them as values when they known transition events 18*8a978a17SVictor Perevertkin // from state to the next. 19*8a978a17SVictor Perevertkin // 20*8a978a17SVictor Perevertkin enum FxPnpEvent { 21*8a978a17SVictor Perevertkin PnpEventInvalid = 0x000000, 22*8a978a17SVictor Perevertkin PnpEventAddDevice = 0x000001, 23*8a978a17SVictor Perevertkin PnpEventStartDevice = 0x000002, 24*8a978a17SVictor Perevertkin PnpEventStartDeviceComplete = 0x000004, 25*8a978a17SVictor Perevertkin PnpEventStartDeviceFailed = 0x000008, 26*8a978a17SVictor Perevertkin PnpEventQueryRemove = 0x000010, 27*8a978a17SVictor Perevertkin PnpEventQueryStop = 0x000020, 28*8a978a17SVictor Perevertkin PnpEventCancelRemove = 0x000040, 29*8a978a17SVictor Perevertkin PnpEventCancelStop = 0x000080, 30*8a978a17SVictor Perevertkin PnpEventStop = 0x000100, 31*8a978a17SVictor Perevertkin PnpEventRemove = 0x000200, 32*8a978a17SVictor Perevertkin PnpEventSurpriseRemove = 0x000400, 33*8a978a17SVictor Perevertkin PnpEventEject = 0x000800, 34*8a978a17SVictor Perevertkin PnpEventPwrPolStopped = 0x001000, 35*8a978a17SVictor Perevertkin PnpEventPwrPolStopFailed = 0x002000, 36*8a978a17SVictor Perevertkin PnpEventPowerUpFailed = 0x004000, 37*8a978a17SVictor Perevertkin PnpEventPowerDownFailed = 0x008000, 38*8a978a17SVictor Perevertkin PnpEventParentRemoved = 0x010000, 39*8a978a17SVictor Perevertkin PnpEventChildrenRemovalComplete = 0x020000, 40*8a978a17SVictor Perevertkin PnpEventPwrPolStarted = 0x040000, 41*8a978a17SVictor Perevertkin PnpEventPwrPolStartFailed = 0x080000, 42*8a978a17SVictor Perevertkin PnpEventDeviceInD0 = 0x100000, 43*8a978a17SVictor Perevertkin PnpEventPwrPolRemoved = 0x200000, 44*8a978a17SVictor Perevertkin 45*8a978a17SVictor Perevertkin // 46*8a978a17SVictor Perevertkin // Not a real event, just a value that shows all of the events which have 47*8a978a17SVictor Perevertkin // queued the pnp irp. If we drop one of these events, we *must* complete 48*8a978a17SVictor Perevertkin // the pended pnp irp. See PnpProcessEventInner. 49*8a978a17SVictor Perevertkin // 50*8a978a17SVictor Perevertkin PnpEventPending = PnpEventStartDeviceComplete | 51*8a978a17SVictor Perevertkin PnpEventQueryRemove | 52*8a978a17SVictor Perevertkin PnpEventQueryStop | 53*8a978a17SVictor Perevertkin PnpEventCancelRemove | 54*8a978a17SVictor Perevertkin PnpEventCancelStop | 55*8a978a17SVictor Perevertkin PnpEventStop | 56*8a978a17SVictor Perevertkin PnpEventSurpriseRemove | 57*8a978a17SVictor Perevertkin PnpEventEject, 58*8a978a17SVictor Perevertkin 59*8a978a17SVictor Perevertkin // 60*8a978a17SVictor Perevertkin // Not a real event, just a value that indicates all of the events which 61*8a978a17SVictor Perevertkin // goto the head of the queue and are always processed, even if the state is 62*8a978a17SVictor Perevertkin // locked. 63*8a978a17SVictor Perevertkin // 64*8a978a17SVictor Perevertkin PnpPriorityEventsMask = PnpEventPwrPolStarted | 65*8a978a17SVictor Perevertkin PnpEventPwrPolStartFailed | 66*8a978a17SVictor Perevertkin PnpEventPwrPolStopped | 67*8a978a17SVictor Perevertkin PnpEventPwrPolStopFailed | 68*8a978a17SVictor Perevertkin PnpEventDeviceInD0 | 69*8a978a17SVictor Perevertkin PnpEventPwrPolRemoved, 70*8a978a17SVictor Perevertkin 71*8a978a17SVictor Perevertkin PnpEventNull = 0xFFFFFFFF, 72*8a978a17SVictor Perevertkin }; 73*8a978a17SVictor Perevertkin 74*8a978a17SVictor Perevertkin // 75*8a978a17SVictor Perevertkin // Bit packed ULONG. 76*8a978a17SVictor Perevertkin // 77*8a978a17SVictor Perevertkin union FxPnpStateInfo { 78*8a978a17SVictor Perevertkin struct { 79*8a978a17SVictor Perevertkin // 80*8a978a17SVictor Perevertkin // Indicates whether the state is open to all events 81*8a978a17SVictor Perevertkin // 82*8a978a17SVictor Perevertkin ULONG QueueOpen : 1; 83*8a978a17SVictor Perevertkin 84*8a978a17SVictor Perevertkin // 85*8a978a17SVictor Perevertkin // Bit of events we know we can drop in this state 86*8a978a17SVictor Perevertkin // 87*8a978a17SVictor Perevertkin ULONG KnownDroppedEvents : 31; 88*8a978a17SVictor Perevertkin } Bits; 89*8a978a17SVictor Perevertkin 90*8a978a17SVictor Perevertkin struct { 91*8a978a17SVictor Perevertkin // 92*8a978a17SVictor Perevertkin // Maps to the same bit location as QueueOpen. Since we start 93*8a978a17SVictor Perevertkin // KnownDroppedEvents at the next bit, start our bits by at the next 94*8a978a17SVictor Perevertkin // bit as well. 95*8a978a17SVictor Perevertkin // 96*8a978a17SVictor Perevertkin ULONG Reserved : 1; 97*8a978a17SVictor Perevertkin 98*8a978a17SVictor Perevertkin // 99*8a978a17SVictor Perevertkin // These are defined so that we can easily tell in the debugger what 100*8a978a17SVictor Perevertkin // each set bit in KnownDroppedEvents maps to in the FxPnpEvent enum 101*8a978a17SVictor Perevertkin // 102*8a978a17SVictor Perevertkin ULONG PnpEventAddDeviceKnown : 1; 103*8a978a17SVictor Perevertkin ULONG PnpEventStartDeviceKnown : 1; 104*8a978a17SVictor Perevertkin ULONG PnpEventStartDeviceCompleteKnown : 1; 105*8a978a17SVictor Perevertkin ULONG PnpEventStartDeviceFailedKnown : 1; 106*8a978a17SVictor Perevertkin ULONG PnpEventQueryRemoveKnown : 1; 107*8a978a17SVictor Perevertkin ULONG PnpEventQueryStopKnown : 1; 108*8a978a17SVictor Perevertkin ULONG PnpEventCancelRemoveKnown : 1; 109*8a978a17SVictor Perevertkin ULONG PnpEventCancelStopKnown : 1; 110*8a978a17SVictor Perevertkin ULONG PnpEventStopKnown : 1; 111*8a978a17SVictor Perevertkin ULONG PnpEventRemoveKnown : 1; 112*8a978a17SVictor Perevertkin ULONG PnpEventSurpriseRemoveKnown : 1; 113*8a978a17SVictor Perevertkin ULONG PnpEventEjectKnown : 1; 114*8a978a17SVictor Perevertkin ULONG PnpEventPwrPolStopped : 1; 115*8a978a17SVictor Perevertkin ULONG PnpEventPwrPolStopFailed : 1; 116*8a978a17SVictor Perevertkin ULONG PnpEventPowerUpFailedKnown : 1; 117*8a978a17SVictor Perevertkin ULONG PnpEventPowerDownFailedKnown : 1; 118*8a978a17SVictor Perevertkin ULONG PnpEventParentRemovedKnown : 1; 119*8a978a17SVictor Perevertkin ULONG PnpEventChildrenRemovalCompleteKnown : 1; 120*8a978a17SVictor Perevertkin ULONG PnpEventPwrPolStarted : 1; 121*8a978a17SVictor Perevertkin ULONG PnpEventPwrPolStartFailed : 1; 122*8a978a17SVictor Perevertkin } BitsByName; 123*8a978a17SVictor Perevertkin }; 124*8a978a17SVictor Perevertkin 125*8a978a17SVictor Perevertkin struct PNP_EVENT_TARGET_STATE { 126*8a978a17SVictor Perevertkin FxPnpEvent PnpEvent; 127*8a978a17SVictor Perevertkin 128*8a978a17SVictor Perevertkin WDF_DEVICE_PNP_STATE TargetState; 129*8a978a17SVictor Perevertkin 130*8a978a17SVictor Perevertkin EVENT_TRAP_FIELD 131*8a978a17SVictor Perevertkin }; 132*8a978a17SVictor Perevertkin 133*8a978a17SVictor Perevertkin typedef const PNP_EVENT_TARGET_STATE* CPPNP_EVENT_TARGET_STATE; 134*8a978a17SVictor Perevertkin 135*8a978a17SVictor Perevertkin struct PNP_STATE_TABLE { 136*8a978a17SVictor Perevertkin // 137*8a978a17SVictor Perevertkin // Framework internal function 138*8a978a17SVictor Perevertkin // 139*8a978a17SVictor Perevertkin PFN_PNP_STATE_ENTRY_FUNCTION StateFunc; 140*8a978a17SVictor Perevertkin 141*8a978a17SVictor Perevertkin PNP_EVENT_TARGET_STATE FirstTargetState; 142*8a978a17SVictor Perevertkin 143*8a978a17SVictor Perevertkin CPPNP_EVENT_TARGET_STATE OtherTargetStates; 144*8a978a17SVictor Perevertkin 145*8a978a17SVictor Perevertkin FxPnpStateInfo StateInfo; 146*8a978a17SVictor Perevertkin 147*8a978a17SVictor Perevertkin }; 148*8a978a17SVictor Perevertkin 149*8a978a17SVictor Perevertkin typedef const PNP_STATE_TABLE* CPPNP_STATE_TABLE; 150*8a978a17SVictor Perevertkin 151*8a978a17SVictor Perevertkin #if FX_STATE_MACHINE_VERIFY 152*8a978a17SVictor Perevertkin #define MAX_PNP_STATE_ENTRY_FN_RETURN_STATES (5) 153*8a978a17SVictor Perevertkin 154*8a978a17SVictor Perevertkin struct PNP_STATE_ENTRY_FUNCTION_TARGET_STATE { 155*8a978a17SVictor Perevertkin // 156*8a978a17SVictor Perevertkin // Return value from state entry function 157*8a978a17SVictor Perevertkin // 158*8a978a17SVictor Perevertkin WDF_DEVICE_PNP_STATE State; 159*8a978a17SVictor Perevertkin 160*8a978a17SVictor Perevertkin // 161*8a978a17SVictor Perevertkin // type of device the returning state applies to 162*8a978a17SVictor Perevertkin // 163*8a978a17SVictor Perevertkin FxStateMachineDeviceType DeviceType; 164*8a978a17SVictor Perevertkin 165*8a978a17SVictor Perevertkin // 166*8a978a17SVictor Perevertkin // Info about the state transition 167*8a978a17SVictor Perevertkin // 168*8a978a17SVictor Perevertkin PSTR Comment; 169*8a978a17SVictor Perevertkin }; 170*8a978a17SVictor Perevertkin 171*8a978a17SVictor Perevertkin typedef const PNP_STATE_ENTRY_FUNCTION_TARGET_STATE* CPPNP_STATE_ENTRY_FUNCTION_TARGET_STATE; 172*8a978a17SVictor Perevertkin 173*8a978a17SVictor Perevertkin struct PNP_STATE_ENTRY_FN_RETURN_STATE_TABLE { 174*8a978a17SVictor Perevertkin // 175*8a978a17SVictor Perevertkin // array of state transitions caused by state entry function 176*8a978a17SVictor Perevertkin // 177*8a978a17SVictor Perevertkin PNP_STATE_ENTRY_FUNCTION_TARGET_STATE TargetStates[MAX_PNP_STATE_ENTRY_FN_RETURN_STATES]; 178*8a978a17SVictor Perevertkin }; 179*8a978a17SVictor Perevertkin 180*8a978a17SVictor Perevertkin typedef const PNP_STATE_ENTRY_FN_RETURN_STATE_TABLE* CPPNP_STATE_ENTRY_FN_RETURN_STATE_TABLE; 181*8a978a17SVictor Perevertkin #endif //FX_STATE_MACHINE_VERIFY 182*8a978a17SVictor Perevertkin 183*8a978a17SVictor Perevertkin // @@SMVERIFY_SPLIT_END 184*8a978a17SVictor Perevertkin 185*8a978a17SVictor Perevertkin // 186*8a978a17SVictor Perevertkin // This type of union is done so that we can 187*8a978a17SVictor Perevertkin // 1) shrink the array element to the smallest size possible 188*8a978a17SVictor Perevertkin // 2) keep types within the structure so we can dump it in the debugger 189*8a978a17SVictor Perevertkin // 190*8a978a17SVictor Perevertkin union FxPnpMachineStateHistory { 191*8a978a17SVictor Perevertkin struct { 192*8a978a17SVictor Perevertkin WDF_DEVICE_PNP_STATE State1 : 16; 193*8a978a17SVictor Perevertkin WDF_DEVICE_PNP_STATE State2 : 16; 194*8a978a17SVictor Perevertkin WDF_DEVICE_PNP_STATE State3 : 16; 195*8a978a17SVictor Perevertkin WDF_DEVICE_PNP_STATE State4 : 16; 196*8a978a17SVictor Perevertkin WDF_DEVICE_PNP_STATE State5 : 16; 197*8a978a17SVictor Perevertkin WDF_DEVICE_PNP_STATE State6 : 16; 198*8a978a17SVictor Perevertkin WDF_DEVICE_PNP_STATE State7 : 16; 199*8a978a17SVictor Perevertkin WDF_DEVICE_PNP_STATE State8 : 16; 200*8a978a17SVictor Perevertkin } S; 201*8a978a17SVictor Perevertkin 202*8a978a17SVictor Perevertkin USHORT History[PnpEventQueueDepth]; 203*8a978a17SVictor Perevertkin }; 204*8a978a17SVictor Perevertkin 205*8a978a17SVictor Perevertkin 206*8a978a17SVictor Perevertkin struct FxPnpMachine : public FxWorkItemEventQueue { FxPnpMachineFxPnpMachine207*8a978a17SVictor Perevertkin FxPnpMachine( 208*8a978a17SVictor Perevertkin VOID 209*8a978a17SVictor Perevertkin ) : FxWorkItemEventQueue(PnpEventQueueDepth) 210*8a978a17SVictor Perevertkin { 211*8a978a17SVictor Perevertkin RtlZeroMemory(&m_Queue[0], sizeof(m_Queue)); 212*8a978a17SVictor Perevertkin RtlZeroMemory(&m_States, sizeof(m_States)); 213*8a978a17SVictor Perevertkin 214*8a978a17SVictor Perevertkin m_States.History[IncrementHistoryIndex()] = WdfDevStatePnpObjectCreated; 215*8a978a17SVictor Perevertkin m_FireAndForget = FALSE; 216*8a978a17SVictor Perevertkin } 217*8a978a17SVictor Perevertkin 218*8a978a17SVictor Perevertkin FxPnpEvent m_Queue[PnpEventQueueDepth]; 219*8a978a17SVictor Perevertkin 220*8a978a17SVictor Perevertkin FxPnpMachineStateHistory m_States; 221*8a978a17SVictor Perevertkin 222*8a978a17SVictor Perevertkin BOOLEAN m_FireAndForget; 223*8a978a17SVictor Perevertkin }; 224*8a978a17SVictor Perevertkin 225*8a978a17SVictor Perevertkin #endif // _FXPNPSTATEMACHINE_H_ 226