ReactOS 0.4.16-dev-338-g34e76ad
fxpkgpnp.hpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft. All rights reserved.
4
5Module Name:
6
7 FxPkgPnp.hpp
8
9Abstract:
10
11 This module implements the pnp package for the driver frameworks.
12
13Author:
14
15
16
17Environment:
18
19 Both kernel and user mode
20
21Revision History:
22
23--*/
24
25#ifndef _FXPKGPNP_H_
26#define _FXPKGPNP_H_
27
28//
29// These are all magical numbers based on inspection. If the queue overflows,
30// it is OK to increase these numbers without fear of either dependencies or
31// weird side effects.
32//
36
37// @@SMVERIFY_SPLIT_BEGIN
38
39//
40// DEBUGGED_EVENT is a TRUE value rather then a FALSE value (and having the field
41// name be TrapOnEvent) so that the initializer for the entry in the table has
42// to explicitly set this value, otherwise, if left out, the compiler will zero
43// out the field, which would lead to mistakenly saying the event was debugged
44// if DEBUGGED_EVENT is FALSE.
45//
46// Basically, we are catching folks who update the table but forget to specify
47// TRAP_ON_EVENT when they add the new entry.
48//
49#if FX_SUPER_DBG
50 #define DEBUGGED_EVENT , TRUE
51 #define TRAP_ON_EVENT , FALSE
52
53 #define DO_EVENT_TRAP(x) if ((x)->EventDebugged == FALSE) { COVERAGE_TRAP(); }
54
55 #define EVENT_TRAP_FIELD BOOLEAN EventDebugged;
56
57#else // FX_SUPER_DBG
58
59 #define DEBUGGED_EVENT
60 #define TRAP_ON_EVENT
61 #define DO_EVENT_TRAP(x) (0)
62
63 // intentionally blank
64 #define EVENT_TRAP_FIELD
65
66#endif // FX_SUPER_DBG
67
68#if FX_STATE_MACHINE_VERIFY
69enum FxStateMachineDeviceType {
70 FxSmDeviceTypeInvalid = 0,
71 FxSmDeviceTypePnp,
72 FxSmDeviceTypePnpFdo,
73 FxSmDeviceTypePnpPdo,
74};
75#endif // FX_STATE_MACHINE_VERIFY
76
77// @@SMVERIFY_SPLIT_END
78
79#include "fxpnpcallbacks.hpp"
80
81#include "fxeventqueue.hpp"
82
83//
84// Bit-flags for tracking which callback is currently executing.
85//
87 // Prepare hardware callback is running.
89};
90
91typedef
96 );
97
98//
99// workaround overloaded definition (rpc generated headers all define INTERFACE
100// to match the class name).
101//
102#undef INTERFACE
103
105 //
106 // generic interface header
107 //
109
111
113
114//
115// What follows here is a series of structures that define three state
116// machines. The first is the PnP state machine, followed by the
117// Power state machine, followed by the Power Policy state machine.
118// The first two will be instantiated in every driver. The third will
119// be instantiated only in drivers which are the power policy owners
120// for their device stacks, which usually amounts to the being the FDO.
121//
122#include "fxpnpstatemachine.hpp"
125
127
128//
129// Group these here instead of in the individual headers because, for some reason,
130// tracewpp.exe, can't handle such an arrangement.
131//
132// begin_wpp config
133// CUSTOM_TYPE(FxPnpEvent, ItemEnum(FxPnpEvent));
134// CUSTOM_TYPE(FxPowerEvent, ItemEnum(FxPowerEvent));
135// CUSTOM_TYPE(FxPowerPolicyEvent, ItemEnum(FxPowerPolicyEvent));
136// CUSTOM_TYPE(FxPowerIdleFlags, ItemEnum(FxPowerIdleFlags));
137// CUSTOM_TYPE(FxPowerIdleStates, ItemEnum(FxPowerIdleStates));
138// CUSTOM_TYPE(FxPowerIdleEvents, ItemEnum(FxPowerIdleEvents));
139// CUSTOM_TYPE(FxDevicePwrRequirementEvents, ItemEnum(FxDevicePwrRequirementEvents));
140// CUSTOM_TYPE(FxDevicePwrRequirementStates, ItemEnum(FxDevicePwrRequirementStates));
141// CUSTOM_TYPE(FxWakeInterruptEvents, ItemEnum(FxWakeInterruptEvents));
142// CUSTOM_TYPE(FxWakeInterruptStates, ItemEnum(FxWakeInterruptStates));
143
144// CUSTOM_TYPE(FxSelfManagedIoEvents, ItemEnum(FxSelfManagedIoEvents));
145// CUSTOM_TYPE(FxSelfManagedIoStates, ItemEnum(FxSelfManagedIoStates));
146// end_wpp
147
148//
149// These are defined in ntddk.h so its wpp custom type should be
150// added to a common header along with other public enums. Howeever until that
151// is done, define custom type here.
152//
153// begin_wpp config
154// CUSTOM_TYPE(DEVICE_POWER_STATE, ItemEnum(_DEVICE_POWER_STATE));
155// CUSTOM_TYPE(SYSTEM_POWER_STATE, ItemEnum(_SYSTEM_POWER_STATE));
156// CUSTOM_TYPE(BUS_QUERY_ID_TYPE, ItemEnum(BUS_QUERY_ID_TYPE));
157// CUSTOM_TYPE(DEVICE_RELATION_TYPE, ItemEnum(_DEVICE_RELATION_TYPE));
158// CUSTOM_TYPE(pwrmn, ItemListByte(IRP_MN_WAIT_WAKE,IRP_MN_POWER_SEQUENCE,IRP_MN_SET_POWER,IRP_MN_QUERY_POWER));
159// end_wpp
160
161//
162// Information shared between the power and power policy state machines.
163//
165 //
166 // Current wait wake irp in this device object. Access to this field is
167 // determined by m_WaitWakeOwner.
168 //
169 // m_WaitWakeOwner == TRUE, access is guarded by
170 // FxPowerMachine::m_WaitWakeLock
171 //
172 //
173 // m_WaitWakeOwner == FALSE, access is guarded InterlockedExchange operations
174 // and the ability to cancel the request is guarded through
175 // FxPowerPolicyMachine::m_WaitWakeCancelCompletionOwnership
176 //
177 // Any devobj can be both the power policy owner and the wait wake owner,
178 // but usually this dual role would only be for raw PDOs.
179 //
181
182 //
183 // Indication whether this power machine owns wait wake irps (and calls
184 // (dis)arm at bus level callbacks and handles cancellation logic.
185 //
187
188 //
189 // If TRUE the watchdog timer should be extended to a very long period of
190 // time during debugging for a NP power operation.
191 //
192 // NOTE: nowhere in the code do we set this value to TRUE. The debugger
193 // extension !wdfextendwatchdog will set it to TRUE, so the field must
194 // stay. If moved, the extension must obviously be updated as well.
195 //
197};
198
200
204};
205
215};
216
220};
221
222typedef
228 );
229
230//
231// The naming of these values is very important. The following macros rely on
232// it:
233//
234// (state related:)
235// SET_PNP_DEVICE_STATE_BIT
236// SET_TRI_STATE_FROM_STATE_BITS
237// GET_PNP_STATE_BITS_FROM_STRUCT
238//
239// (caps related:)
240// GET_PNP_CAP_BITS_FROM_STRUCT
241// SET_PNP_CAP_IF_TRUE
242// SET_PNP_CAP_IF_FALSE
243// SET_PNP_CAP
244//
245// They using the naming convention to generically map the field name in
246// WDF_DEVICE_PNP_CAPABILITIES and WDF_DEVICE_STATE to the appropriate bit
247// values.
248//
254
259
264
269
274
279
280 FxPnpStateMask = 0x00000FFF,
281
286
291
296
301
306
311
316
321
326
327 FxPnpCapMask = 0x3FFFF000,
328};
329
331 struct {
332 // States
339
340 // Caps
351
352 //
353 // The bottom 3 nibbles (0xFFF) are the pnp state tri state values encoded
354 // down to 2 bits each.
355 //
356 // The remaining portion (0x3FFFF000) are the pnp caps tri state values
357 // encoded down to 2 bits each as well.
358 //
360};
361
362//
363// The naming of these values is very important. The following macros rely on it:
364// GET_POWER_CAP_BITS_FROM_STRUCT
365// SET_POWER_CAP
366//
367// They using the naming convention to generically map the field name in
368// WDF_DEVICE_POWER_CAPABILITIES to the appropriate bit values.
369//
375
380
385
390
395
400};
401
403 //
404 // Encoded with FxPowerCapValues, which encodes the WDF_TRI_STATE values
405 //
407
408 //
409 // Default value PowerDeviceMaximum, PowerSystemMaximum indicates not to
410 // set this value.
411 //
412 BYTE DeviceWake; // DEVICE_POWER_STATE
413 BYTE SystemWake; // SYSTEM_POWER_STATE
414
415 //
416 // Each state is encoded in a nibble in a byte
417 //
419
420 //
421 // Default values of -1 indicate not to set this value
422 //
426};
427
432
433struct FxEnumerationInfo : public FxStump {
434public:
436 __in PFX_DRIVER_GLOBALS FxDriverGlobals
437 ) : m_ChildListList(FxDriverGlobals)
438 {
439 }
440
443 VOID
444 )
445 {
447
449 if (!NT_SUCCESS(status)) {
450 return status;
451 }
452
454 if (!NT_SUCCESS(status)) {
455 return status;
456 }
457
458 return STATUS_SUCCESS;
459 }
460
461 _Acquires_lock_(_Global_critical_region_)
462 VOID
463 AcquireParentPowerStateLock(
464 __in PFX_DRIVER_GLOBALS FxDriverGlobals
465 )
466 {
467 (VOID) m_PowerStateLock.AcquireLock(FxDriverGlobals);
468 }
469
470 _Releases_lock_(_Global_critical_region_)
471 VOID
472 ReleaseParentPowerStateLock(
473 __in PFX_DRIVER_GLOBALS FxDriverGlobals
474 )
475 {
476 m_PowerStateLock.ReleaseLock(FxDriverGlobals);
477 }
478
479public:
481
482 //
483 // List of FxChildList objects which contain enumerated children
484 //
486};
487
488class FxPkgPnp : public FxPackage {
489
495
496protected:
497 FxPkgPnp(
498 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
501 );
502
503 ~FxPkgPnp();
504
505 virtual
506 BOOLEAN
507 Dispose(
508 VOID
509 );
510
512 virtual
514 Dispatch(
516 );
517
518 virtual
521 VOID
522 ) =0;
523
524 virtual
527 VOID
528 ) =0;
529
530 VOID
532 VOID
533 );
534
535 VOID
537 VOID
538 );
539
544 );
545
550 );
551
554 __in PNP_DEVICE_STATE PnpDeviceState
555 );
556
561 );
562
568 );
569
575 );
576
580 VOID
581 );
582
583 VOID
585 VOID
586 );
587
591 VOID
592 );
593
596 PnpPrepareHardware(
597 __out PBOOLEAN ResourcesMatched
598 );
599
603 VOID
604 );
605
609 VOID
610 );
611
615 VOID
616 );
617
619 static
624 );
625
627 static
632 );
633
635 static
640 );
641
643 static
648 );
649
651 static
656 );
657
659 static
664 );
665
667 static
672 );
673
678 );
679
683 );
684
685 virtual
686 VOID
688 BOOLEAN IrpMustBePresent = TRUE
689 ) =0;
690
691 VOID
694 );
695
696 VOID
699 );
700
701 VOID
704 );
705
706 VOID
709 );
710
711 VOID
714 );
715
716 static
717 VOID
721 __in PVOID WorkerContext
722 );
723
724 static
725 VOID
729 __in PVOID WorkerContext
730 );
731
732 static
733 VOID
737 __in PVOID WorkerContext
738 );
739
740 VOID
743 );
744
745 VOID
748 );
749
750 VOID
753 );
754
755 VOID
758 );
759
761 static
766 );
767
772 );
773
774 VOID
775 SaveState(
776 __in BOOLEAN UseCanSaveState
777 );
778
780 static
785 );
786
791 );
792
793
794 LONG
796 VOID
797 );
798
799 LONG
801 VOID
802 );
803
804 static
805 VOID
810 );
811
812 static
817 );
818
819// begin pnp state machine table based callbacks
820 static
824 );
825
826 virtual
827 BOOLEAN
829 VOID
830 ) =0;
831
832 virtual
835 VOID
836 ) = 0;
837
838 static
842 );
843
844 virtual
847 VOID
848 ) = 0;
849
850 static
854 );
855
856 static
860 );
861
862 static
866 );
867
868 static
872 );
873
874 static
878 );
879
880 static
884 );
885
886 static
890 );
891
892 static
896 );
897
898 static
902 );
903
904 static
908 );
909
910 static
914 );
915
916 static
920 );
921
922 static
926 );
927
928 static
932 );
933
934 static
938 );
939
940 static
944 );
945
946 virtual
949 VOID
950 ) =0;
951
952 static
956 );
957
958 static
962 );
963
964 static
968 );
969
970 virtual
973 VOID
974 ) =0;
975
976 virtual
979 VOID
980 ) =0;
981
982 virtual
983 VOID
985 VOID
986 );
987
988 VOID
990 VOID
991 );
992
993 static
997 );
998
999 static
1003 );
1004
1005 static
1009 );
1010
1011 static
1015 );
1016
1017 static
1021 );
1022
1023 static
1027 );
1028
1029 static
1033 );
1034
1035 static
1039 );
1040
1041 static
1045 );
1046
1047 static
1051 );
1052
1053 static
1057 );
1058
1059 static
1063 );
1064
1065 static
1069 );
1070
1071 static
1075 );
1076
1077 static
1081 );
1082
1083 static
1087 );
1088
1089 static
1093 );
1094
1095 static
1099 );
1100
1101 static
1105 );
1106
1107 static
1111 );
1112
1113 static
1117 );
1118
1119 static
1123 );
1124
1125 static
1129 );
1130
1131 static
1135 );
1136
1137 static
1141 );
1142
1143 static
1147 );
1148
1149 static
1153 );
1154
1155 static
1159 );
1160
1161 static
1165 );
1166
1167 static
1171 );
1172
1173 static
1177 );
1178 // end pnp state machine table based callbacks
1179
1180 VOID
1182 VOID
1183 );
1184
1185 VOID
1187 VOID
1188 );
1189
1190 VOID
1192 VOID
1193 );
1194
1195 VOID
1197 VOID
1198 );
1199
1200 VOID
1202 __in BOOLEAN IrpMustBePresent = TRUE
1203 );
1204
1205 VOID
1207 VOID
1208 );
1209
1210 virtual
1211 NTSTATUS
1213 FxIrp* Irp
1214 ) =0;
1215
1216 // begin power state machine table based callbacks
1217 static
1221 );
1222
1223 virtual
1226 VOID
1227 ) =0;
1228
1229 static
1233 );
1234
1235 virtual
1238 VOID
1239 ) =0;
1240
1241 static
1245 );
1246
1247 static
1251 );
1252
1253 static
1257 );
1258
1259 virtual
1260 NTSTATUS
1262 BOOLEAN* ParentOn
1263 ) =0;
1264
1265 static
1269 );
1270
1271 static
1273 PowerDZero(
1275 );
1276
1277 static
1279 PowerD0NP(
1281 );
1282
1283 static
1287 );
1288
1289 static
1293 );
1294
1295 static
1299 );
1300
1301 static
1305 );
1306
1307 static
1311 );
1312
1313 static
1317 );
1318
1319 static
1323 );
1324
1325 static
1329 );
1330
1331 static
1335 );
1336
1337 static
1341 );
1342
1343 static
1347 );
1348
1349 static
1353 );
1354
1355 static
1359 );
1360
1361 static
1365 );
1366
1367 static
1371 );
1372
1373 static
1377 );
1378
1379 static
1383 );
1384
1385 virtual
1386 NTSTATUS
1388 VOID
1389 )
1390 {
1391 return STATUS_SUCCESS;
1392 }
1393
1394 virtual
1395 VOID
1397 VOID
1398 )
1399 {
1400 }
1401
1402 virtual
1403 VOID
1405 VOID
1406 ) =0;
1407
1408 static
1412 );
1413
1414 static
1418 );
1419
1420 static
1424 );
1425
1426 static
1430 );
1431
1432 static
1436 );
1437
1438 static
1442 );
1443
1444 static
1448 );
1449
1450 static
1454 );
1455
1456 static
1460 );
1461
1462 static
1466 );
1467
1468 static
1472 );
1473
1474 static
1478 );
1479
1480 static
1484 );
1485
1486 static
1490 );
1491
1492 static
1496 );
1497
1498 static
1502 );
1503
1504 static
1508 );
1509
1510 static
1514 );
1515
1516 static
1520 );
1521
1522 static
1526 );
1527
1528 static
1532 );
1533
1534 static
1538 );
1539
1540 static
1544 );
1545
1546 static
1550 );
1551
1552 static
1556 );
1557
1558 static
1562 );
1563
1564 static
1568 );
1569
1570 static
1574 );
1575
1576 static
1580 );
1581
1582 static
1586 );
1587
1588 static
1592 );
1593
1594 static
1598 );
1599
1600 static
1604 );
1605
1606 static
1610 );
1611
1612 static
1616 );
1617
1618 static
1622 );
1623
1624 static
1628 );
1629
1630 static
1634 );
1635
1636 static
1640 );
1641
1642 static
1646 );
1647
1648 static
1652 );
1653
1654 static
1658 );
1659
1660 static
1664 );
1665
1666 static
1670 );
1671
1672 static
1676 );
1677
1678 static
1682 );
1683
1684 static
1688 );
1689
1690 static
1694 );
1695
1696 static
1700 );
1701
1702 static
1706 );
1707
1708 static
1712 );
1713
1714 static
1718 );
1719
1720 static
1724 );
1725
1726 static
1730 );
1731
1732 static
1736 );
1737
1738 static
1742 );
1743
1744 static
1748 );
1749
1750 static
1754 );
1755
1756 static
1760 );
1761
1762 static
1766 );
1767
1768 static
1772 );
1773
1774 // end power state machine table based callbacks
1775
1776 // begin power policy state machine table based callbacks
1777 static
1781 );
1782
1783 static
1787 );
1788
1789 static
1793 );
1794
1795 static
1799 );
1800
1801 static
1805 );
1806
1807 static
1811 );
1812
1813 static
1817 );
1818
1819 static
1823 );
1824
1825 static
1829 );
1830
1831 static
1835 );
1836
1837 static
1841 );
1842
1843 static
1847 );
1848
1849 static
1853 );
1854
1855 static
1859 );
1860
1861 static
1865 );
1866
1867 static
1871 );
1872
1873 static
1877 );
1878
1879 static
1883 );
1884
1885 static
1889 );
1890
1891 static
1895 );
1896
1897 static
1901 );
1902
1903 static
1907 );
1908
1909 static
1913 );
1914
1915 static
1919 );
1920
1921 static
1925 );
1926
1927 static
1931 );
1932
1933 static
1937 );
1938
1939 static
1943 );
1944
1945 static
1949 );
1950
1951 static
1955 );
1956
1957 static
1961 );
1962
1963 static
1967 );
1968
1969 static
1973 );
1974
1975 static
1979 );
1980
1981 static
1985 );
1986
1987 static
1991 );
1992
1993 static
1997 );
1998
1999 static
2003 );
2004
2005 static
2009 );
2010
2011 static
2015 );
2016
2017 static
2021 );
2022
2023 static
2027 );
2028
2029 static
2033 );
2034
2035 static
2039 );
2040
2041 static
2045 );
2046
2047 static
2051 );
2052
2053 static
2057 );
2058
2059 static
2063 );
2064
2065 static
2069 );
2070
2071 static
2075 );
2076
2077 static
2081 );
2082
2083 static
2087 );
2088
2089 static
2093 );
2094
2095 static
2099 );
2100
2101 static
2105 );
2106
2107 static
2111 );
2112
2113 static
2117 );
2118
2119 static
2123 );
2124
2125 static
2129 );
2130
2131 static
2135 );
2136
2137 static
2141 );
2142
2143 static
2147 );
2148
2149 static
2153 );
2154
2155 static
2159 );
2160
2161 static
2165 );
2166
2167 static
2171 );
2172
2173 static
2177 );
2178
2179 static
2183 );
2184
2185 static
2189 );
2190
2191 static
2195 );
2196
2197 static
2201 );
2202
2203 static
2207 );
2208
2209 static
2213 );
2214
2215 static
2219 );
2220
2221 static
2225 );
2226
2227 static
2231 );
2232
2233 static
2237 );
2238
2239 static
2243 );
2244
2245 static
2249 );
2250
2251 static
2255 );
2256
2257 static
2261 );
2262
2263 static
2267 );
2268
2269 static
2273 );
2274
2275 static
2279 );
2280
2281 static
2285 );
2286
2287 static
2291 );
2292
2293 static
2297 );
2298
2299 static
2303 );
2304
2305 static
2309 );
2310
2311 static
2315 );
2316
2317 static
2321 );
2322
2323 static
2327 );
2328
2329 static
2333 );
2334
2335 static
2339 );
2340
2341 static
2345 );
2346
2347 static
2351 );
2352
2353 static
2357 );
2358
2359 static
2363 );
2364
2365 static
2369 );
2370
2371 static
2375 );
2376
2377 static
2381 );
2382
2383 static
2387 );
2388
2389 static
2393 );
2394
2395 static
2399 );
2400
2401 static
2405 );
2406
2407 static
2411 );
2412
2413 static
2417 );
2418
2419 static
2423 );
2424
2425 static
2429 );
2430
2431 static
2435 );
2436
2437 static
2441 );
2442
2443 static
2447 );
2448
2449 static
2453 );
2454
2455 static
2459 );
2460
2461 static
2465 );
2466
2467 static
2471 );
2472
2473 static
2477 );
2478
2479 static
2483 );
2484
2485 static
2489 );
2490
2491 static
2495 );
2496
2497 static
2501 );
2502
2503 static
2507 );
2508
2509 static
2513 );
2514
2515 static
2519 );
2520 static
2524 );
2525
2526 static
2530 );
2531
2532 static
2536 );
2537
2538 static
2542 );
2543
2544 static
2548 );
2549
2550 static
2554 );
2555
2556 static
2560 );
2561
2562 static
2566 );
2567
2568 static
2572 );
2573
2574 static
2578 );
2579
2580 static
2584 );
2585
2586 static
2590 );
2591
2592 static
2596 );
2597
2598 static
2602 );
2603
2604 static
2608 );
2609
2610 static
2614 );
2615
2616 static
2620 );
2621
2622 static
2626 );
2627
2628 static
2632 );
2633
2634 // end power policy state machine table based callbacks
2635
2636 VOID
2638 VOID
2639 );
2640
2641 BOOLEAN
2643 VOID
2644 );
2645
2646 BOOLEAN
2648 VOID
2649 );
2650
2651 BOOLEAN
2653 __in BOOLEAN ImplicitPowerUp
2654 );
2655
2656 VOID
2658 VOID
2659 );
2660
2661 VOID
2664 );
2665
2666 BOOLEAN
2669 );
2670
2671 BOOLEAN
2673 VOID
2674 )
2675 {
2676 //
2677 // We don't acquire the spinlock because when we transition to the state
2678 // which will attempt the arming of the device (at bus level), we will
2679 // gracefully handle the absence of the irp.
2680 //
2681 // On the other side if there is no irp and it is set immediately after
2682 // our check, the event posted by the irp's arrival will transition us
2683 // to the state which will attempt the arming.
2684 //
2686 }
2687
2688 VOID
2691 );
2692
2693 VOID
2696 );
2697
2698 VOID
2700 VOID
2701 );
2702
2703 VOID
2706 );
2707
2708 VOID
2710 VOID
2711 );
2712
2713 VOID
2716 );
2717
2719 BOOLEAN
2721 VOID
2722 );
2723
2724 BOOLEAN
2726 VOID
2727 );
2728
2729 VOID
2731 VOID
2732 );
2733
2734 static
2737
2738 VOID
2740 __in FxIrp* Irp
2741 );
2742
2743 static
2744 VOID
2746 __in FxIrp* Irp
2747 );
2748
2749 static
2752
2753 static
2756
2757 static
2760
2762 NTSTATUS
2766 );
2767
2769 NTSTATUS
2771 __in SYSTEM_POWER_STATE SystemState
2772 );
2773
2774 VOID
2776 VOID
2777 );
2778
2779 BOOLEAN
2781 VOID
2782 );
2783
2784 VOID
2786 VOID
2787 );
2788
2789 BOOLEAN
2791 VOID
2792 );
2793
2794 VOID
2796 VOID
2797 );
2798
2799 static
2802
2803 static
2806
2809 VOID
2810 )
2811 {
2813
2814 //
2815 // In a FastS4 situation, Parameters.Power.State.SystemState will be
2816 // PowerSystemHibernate, while TargetSystemState will indicate the
2817 // true Sx state the machine is moving into.
2818 //
2819 return (SYSTEM_POWER_STATE)
2821 TargetSystemState;
2822 }
2823
2825 NTSTATUS
2827 __in SYSTEM_POWER_STATE QueryState
2828 );
2829
2830 BOOLEAN
2832 __in SYSTEM_POWER_STATE SystemState
2833 )
2834 {
2835 return SystemState <= PowerPolicyGetDeviceDeepestSystemWakeState();
2836 }
2837
2840 VOID
2841 )
2842 {
2844 }
2845
2848 __in SYSTEM_POWER_STATE SystemState
2849 );
2850
2851 static
2855 )
2856 {
2858 }
2859
2860 static
2864 )
2865 {
2867 }
2868
2869 static
2873 )
2874 {
2876 }
2877
2878#if FX_STATE_MACHINE_VERIFY
2879 static
2880 CPPNP_STATE_ENTRY_FN_RETURN_STATE_TABLE
2881 GetPnpStateEntryFunctionReturnStatesTableEntry(
2883 )
2884 {
2885 return &m_WdfPnpStateEntryFunctionReturnStates[WdfDevStateNormalize(State) - WdfDevStatePnpObjectCreated];
2886 }
2887
2888 static
2889 CPPOWER_STATE_ENTRY_FN_RETURN_STATE_TABLE
2890 GetPowerStateEntryFunctionReturnStatesTableEntry(
2892 )
2893 {
2894 return &m_WdfPowerStateEntryFunctionReturnStates[WdfDevStateNormalize(State) - WdfDevStatePowerObjectCreated];
2895 }
2896
2897 static
2898 CPPWR_POL_STATE_ENTRY_FN_RETURN_STATE_TABLE
2899 GetPwrPolStateEntryFunctionReturnStatesTableEntry(
2901 )
2902 {
2903 return &m_WdfPwrPolStateEntryFunctionReturnStates[WdfDevStateNormalize(State) - WdfDevStatePwrPolObjectCreated];
2904 }
2905
2906 VOID
2907 ValidatePnpStateEntryFunctionReturnValue(
2909 WDF_DEVICE_PNP_STATE NewState
2910 );
2911
2912 VOID
2913 ValidatePowerStateEntryFunctionReturnValue(
2915 WDF_DEVICE_POWER_STATE NewState
2916 );
2917
2918 VOID
2919 ValidatePwrPolStateEntryFunctionReturnValue(
2922 );
2923#endif //FX_STATE_MACHINE_VERIFY
2924
2926 static
2930 )
2931 {
2932 ULONG i;
2933
2934 for (i = 0;
2936 i++) {
2937 if (m_WdfNotPowerPolicyOwnerStates[i].CurrentTargetState == State) {
2939 }
2940 }
2941
2942 return NULL;
2943 }
2944
2945 static
2946 NTSTATUS
2953 );
2954
2955 static
2956 NTSTATUS
2961 __in PVOID InBuffer
2962 );
2963
2964 static
2965 NTSTATUS
2971 __in PVOID InBuffer
2972 );
2973
2974 static
2975 NTSTATUS
2978 __in FxWmiInstanceInternal* Instaace,
2982 );
2983
2984 static
2985 NTSTATUS
2990 __in PVOID InBuffer
2991 );
2992
2993 static
2994 NTSTATUS
3000 __in PVOID InBuffer
3001 );
3002
3003 BOOLEAN
3005 VOID
3006 )
3007 {
3008 return (m_PendingPnPIrp != NULL) ? TRUE : FALSE;
3009 }
3010
3011 VOID
3013 __inout FxIrp* Irp,
3014 __in BOOLEAN MarkIrpPending = TRUE
3015 );
3016
3017 VOID
3020 )
3021 {
3023
3026 }
3027
3028 MdIrp
3030 VOID
3031 )
3032 {
3033 MdIrp irp;
3034
3037
3038 return irp;
3039 }
3040
3041 MdIrp
3043 VOID
3044 )
3045 {
3046 return m_PendingPnPIrp;
3047 }
3048
3049 VOID
3052 )
3053 {
3055
3056 Irp->MarkIrpPending();
3057 m_PendingDevicePowerIrp = Irp->GetIrp();
3058
3059 if (Irp->GetParameterPowerStateDeviceState() > PowerDeviceD0) {
3060 //
3061 // We are powering down, capture the current power action. We will
3062 // reset it to PowerActionNone once we have powered up.
3063 //
3064 m_SystemPowerAction = (UCHAR) Irp->GetParameterPowerShutdownType();
3065 }
3066 }
3067
3068 MdIrp
3070 VOID
3071 )
3072 {
3073 MdIrp irp;
3074
3077
3078 return irp;
3079 }
3080
3081 VOID
3084 )
3085 {
3087 Irp->MarkIrpPending();
3088 m_PendingSystemPowerIrp = Irp->GetIrp();
3089 }
3090
3091 MdIrp
3093 VOID
3094 )
3095 {
3096 MdIrp irp;
3097
3100
3101 return irp;
3102 }
3103
3104 MdIrp
3106 VOID
3107 )
3108 {
3110 }
3111
3112 BOOLEAN
3114 VOID
3115 )
3116 {
3119
3120 if (irp.GetIrp() == NULL) {
3121 return FALSE;
3122 }
3123
3125
3126 return (state == PowerDeviceD0 ? TRUE : FALSE);
3127 }
3128
3129 BOOLEAN
3132 )
3133 {
3134 return m_SpecialSupport[((ULONG)Usage)-1];
3135 }
3136
3137 VOID
3141 )
3142 {
3144 }
3145
3146 LONG
3149 __in BOOLEAN Add
3150 )
3151 {
3152 if (Add) {
3154 }
3155 else {
3157 }
3158 }
3159
3160 LONG
3162 // __range(WdfSpecialFilePaging, WdfSpecialFileBoot)
3163 __in __range(1, 4) ULONG Usage
3164 )
3165 {
3166 return m_SpecialFileCount[Usage-1];
3167 }
3168
3169 BOOLEAN
3171 VOID
3172 )
3173 {
3178 return FALSE;
3179 }
3180 else {
3181 return TRUE;
3182 }
3183 }
3184
3185 static
3189 )
3190 {
3191 switch (Type) {
3196 default: ASSERT(FALSE);return DeviceUsageTypePaging;
3197 }
3198 }
3199
3200 static
3204 )
3205 {
3206 switch (Type) {
3211 default: ASSERT(FALSE); return WdfSpecialFilePaging;
3212 }
3213 }
3214
3215 ULONG
3218 __in BOOLEAN InPath
3219 );
3220
3221 VOID
3224 __in BOOLEAN InPath,
3226 );
3227
3228 VOID
3232 );
3233
3235 NTSTATUS
3237 VOID
3238 );
3239
3240public:
3241 VOID
3244 __in BOOLEAN ProcessEventOnDifferentThread = FALSE
3245 );
3246
3247 VOID
3250 __in BOOLEAN ProcessEventOnDifferentThread = FALSE
3251 );
3252
3253 VOID
3256 __in BOOLEAN ProcessEventOnDifferentThread = FALSE
3257 );
3258
3259 BOOLEAN
3261 __in KIRQL CurrentIrql,
3262 __in BOOLEAN CallerSpecifiedProcessingOnDifferentThread
3263 );
3264
3265 BOOLEAN
3267 __in KIRQL CurrentIrql,
3268 __in BOOLEAN CallerSpecifiedProcessingOnDifferentThread
3269 );
3270
3271 VOID
3273 __in BOOLEAN ClenaupPnp
3274 );
3275
3276 VOID
3278 __in MxEvent * WaitEvent
3279 );
3280
3282 virtual
3283 NTSTATUS
3284 Initialize(
3286 );
3287
3289 NTSTATUS
3291 VOID
3292 );
3293
3294 virtual
3295 VOID
3298 );
3299
3300 VOID
3304 );
3305
3307 NTSTATUS
3310 );
3311
3312 VOID
3315 );
3316
3317 NTSTATUS
3319 __in const GUID* Guid,
3322 );
3323
3324 NTSTATUS
3327 );
3328
3329 NTSTATUS
3332 );
3333
3334 NTSTATUS
3337 __in BOOLEAN ArmForWakeIfChildrenAreArmedForWake,
3338 __in BOOLEAN IndicateChildWakeOnParentWake
3339 );
3340
3341private:
3342
3343 VOID
3345 VOID
3346 );
3347
3348 NTSTATUS
3351 );
3352
3353 VOID
3357 );
3358
3359 NTSTATUS
3362 );
3363
3364 VOID
3368 );
3369
3370 VOID
3372 __in HANDLE RegKey,
3375 );
3376
3377 NTSTATUS
3381 );
3382
3383 NTSTATUS
3386 _In_ BOOLEAN ForS0Idle
3387 );
3388
3389public:
3390 BOOLEAN
3393 );
3394
3395 BOOLEAN
3397 VOID
3398 );
3399
3400 ULONG
3402 VOID
3403 );
3404
3405 BOOLEAN
3406 __inline
3408 VOID
3409 )
3410 {
3412 }
3413
3414 VOID
3416 VOID
3417 )
3418 {
3419 LONG c;
3420
3421 //
3422 // Called by a child that we are waiting on its removal
3423 //
3425 ASSERT(c >= 0);
3426
3427 if (c == 0) {
3429 }
3430 }
3431
3432 VOID
3435 );
3436
3437 VOID
3440 );
3441
3442 VOID
3445 );
3446
3447 VOID
3448 SetPnpCaps(
3450 );
3451
3452 VOID
3455 );
3456
3457 VOID
3460 );
3461
3462 VOID
3465 );
3466
3467 VOID
3470 )
3471 {
3474 sizeof(PNP_BUS_INFORMATION));
3475 }
3476
3478 NTSTATUS
3481 );
3482
3484 NTSTATUS
3485 __inline
3489 __in_opt LONG Line = 0,
3491 )
3492 {
3494 }
3495
3496 VOID
3497 __inline
3500 __in_opt LONG Line = 0,
3502 )
3503 {
3505 }
3506
3507 BOOLEAN
3509 VOID
3510 )
3511 {
3512 return m_HasPowerThread;
3513 }
3514
3515 VOID
3518 )
3519 {
3522 WorkItem
3523 );
3524 }
3525
3527 NTSTATUS
3530 );
3531
3532 VOID
3535 );
3536
3538 NTSTATUS
3541 );
3542
3543 VOID
3546 );
3547
3548 VOID
3550 VOID
3551 );
3552
3554 NTSTATUS
3556 VOID
3557 );
3558
3559 VOID
3562 );
3563
3564 VOID
3567 );
3568
3569 VOID
3571 __inout PLONG PendingCount
3572 );
3573
3575 NTSTATUS
3577 VOID
3578 );
3579
3580 VOID
3582 __in FxDmaEnabler* Enabler
3583 );
3584
3585 VOID
3587 __in FxDmaEnabler* Enabler
3588 );
3589
3590 VOID
3592 __in FxDmaEnabler* Enabler
3593 );
3594
3595 VOID
3599 );
3600
3601 VOID
3603 VOID
3604 );
3605
3606 VOID
3608 VOID
3609 );
3610
3611 BOOLEAN
3613 VOID
3614 )
3615 {
3617 }
3618
3619 BOOLEAN
3621 VOID
3622 )
3623 {
3624 if (m_WakeInterruptCount > 0) {
3625 return TRUE;
3626 } else {
3627 return FALSE;
3628 }
3629 }
3630
3631 BOOLEAN
3633 VOID
3634 )
3635 {
3636 if (IsPowerPolicyOwner()) {
3638 }
3639 else {
3640 return FALSE;
3641 }
3642 }
3643
3644 BOOLEAN
3646 VOID
3647 )
3648 {
3649 if (IsPowerPolicyOwner()) {
3651 }
3652 else {
3653 return FALSE;
3654 }
3655 }
3656
3657 BOOLEAN
3659 VOID
3660 )
3661 {
3662 if (IsPowerPolicyOwner()) {
3665 }
3666 else {
3667 return FALSE;
3668 }
3669 }
3670
3671 BOOLEAN
3673 VOID
3674 )
3675 {
3676 if (IsPowerPolicyOwner()) {
3678 }
3679 else {
3680 return FALSE;
3681 }
3682 }
3683
3685 NTSTATUS
3687 __out PBOOLEAN PowerUp
3688 )
3689 {
3690 *PowerUp = FALSE;
3691
3692 if (IsPowerPolicyOwner()) {
3694
3695 //
3696 // By referencing the parent (this device) we make sure that if the
3697 // parent is in Dx, we force it back into D0 so that this child can
3698 // be in D0.
3699 //
3701
3702 if (!NT_SUCCESS(status)) {
3703 return status;
3704 }
3705
3706 //
3707 // m_EnumInfo is valid because the child device is calling into the
3708 // parent device and if there is a child, there is a m_EnumInfo.
3709 //
3710 m_EnumInfo->AcquireParentPowerStateLock(GetDriverGlobals());
3711
3712 //
3713 // The caller has added a power reference to this device, so this device
3714 // will remain in D0 until that power reference has been removed. This
3715 // count is separate from the power ref count b/c the power ref count
3716 // only controls when the idle timer will fire. This count handles the
3717 // race that can occur after we decide that the parent is idle and act
3718 // on it and the child powers up before this parent actually powers
3719 // down.
3720 //
3723
3724 m_EnumInfo->ReleaseParentPowerStateLock(GetDriverGlobals());
3725 }
3726 else {
3727 //
3728 // The parent (this device) is not the power policy owner. That
3729 // means we cannot poke the parent to come back to D0 and rely on
3730 // the parent being in D0. Our only recourse is to move into D0 and
3731 // ignore the parent's device power state.
3732 //
3733 // We will only get into this situation if the parent is not the
3734 // power policy owner of the stack. This usually means the parent
3735 // is a filter driver in the parent stack and is creating a virtual
3736 // child. Since the child is assumed virtual, it's D state is not
3737 // tied to real hardware and doesn't really matter.
3738 //
3739 *PowerUp = TRUE;
3740 }
3741
3742 return STATUS_SUCCESS;
3743 }
3744
3745 VOID
3747 VOID
3748 )
3749 {
3750 //
3751 // If this parent is the power policy owner of the child's stack, release
3752 // the requirement this device to be in D0 while the child is in D0.
3753 //
3754 if (IsPowerPolicyOwner()) {
3755 //
3756 // Decrement the number of children who are powered on
3757 //
3758 m_EnumInfo->AcquireParentPowerStateLock(GetDriverGlobals());
3761 m_EnumInfo->ReleaseParentPowerStateLock(GetDriverGlobals());
3762
3764 }
3765 }
3766
3769 VOID
3770 )
3771 {
3773 }
3774
3775 VOID
3777 VOID
3778 );
3779
3780
3781 VOID
3783 VOID
3784 )
3785 {
3787 }
3788
3789 virtual
3790 NTSTATUS
3792 FxIrp* Irp
3793 ) =0;
3794
3795 FxCmResList *
3797 VOID
3798 )
3799 {
3800 return m_Resources;
3801 }
3802
3803 FxCmResList *
3805 VOID
3806 )
3807 {
3808 return m_ResourcesRaw;
3809 }
3810
3811 ULONG
3813 VOID
3814 )
3815 {
3817 }
3818
3819 VOID
3821 __in BOOLEAN ProcessPowerEventOnDifferentThread
3822 );
3823
3824 VOID
3826 __in enum FxWakeInterruptEvents WakeInterruptEvent
3827 );
3828
3829private:
3830 VOID
3832 VOID
3833 );
3834
3835 VOID
3837 VOID
3838 );
3839
3840 VOID
3842 VOID
3843 );
3844
3845 VOID
3847 VOID
3848 );
3849
3851 NTSTATUS
3853 __in ULONG NotifyFlags
3854 );
3855
3856 NTSTATUS
3858 __in ULONG NotifyFlags
3859 );
3860
3861 BOOLEAN
3863 VOID
3864 );
3865
3866 BOOLEAN
3868 _In_ HANDLE RestartKey,
3869 _In_ BOOLEAN CreatedNewKey
3870 );
3871
3872 VOID
3874 __in BOOLEAN GracefulRemove
3875 );
3876
3877 virtual
3878 NTSTATUS
3880 FxIrp* Irp
3881 ) =0;
3882
3883 virtual
3884 VOID
3886 BOOLEAN GracefulRemove
3887 ) =0;
3888
3889 virtual
3890 VOID
3892 VOID
3893 ) =0;
3894
3895 virtual
3896 VOID
3898 VOID
3899 ) =0;
3900
3901 virtual
3902 NTSTATUS
3904 VOID
3905 ) =0;
3906
3908 NTSTATUS
3910 VOID
3911 );
3912
3913 virtual
3914 NTSTATUS
3916 VOID
3917 ) =0;
3918
3919 VOID
3921 VOID
3922 );
3923
3925 NTSTATUS
3927 __inout FxIrp* Irp,
3929 );
3930
3932 NTSTATUS
3934 VOID
3935 );
3936
3937 VOID
3939 VOID
3940 );
3941
3942 static
3943 VOID
3947 )
3948 {
3950
3951 result = ((FxPkgPnp*) Context)->m_PowerThread->QueueWorkItem(WorkItem);
3952#if DBG
3953 ASSERT(result);
3954#else
3956#endif
3957 }
3958
3959 static
3960 VOID
3961 STDCALL
3964 );
3965
3966 static
3967 VOID
3968 STDCALL
3971 );
3972
3973 BOOLEAN
3975 __in DEVICE_POWER_STATE DxState
3976 );
3977
3978 VOID
3980 VOID
3981 );
3982
3983 VOID
3985 VOID
3986 );
3987
3988 VOID
3989 __inline
3991 VOID
3992 );
3993
3995 NTSTATUS
3997 __in DEVICE_POWER_STATE DxState,
3999 )
4000 {
4001 //
4002 // The device is powering down because the system is moving into a lower
4003 // power state.
4004 //
4005 // If we have child devices, setup the guard so that they do not power
4006 // up while the parent is in low power. Note that in this case (an Sx
4007 // transition) we do not look at the count of powered up children
4008 // because the power policy owner for the child's stack should not be
4009 // powering up the device once it has processed the Sx irp for its stack.
4010 //
4012
4014 }
4015
4016 VOID
4018 VOID
4019 )
4020 {
4021 if (m_EnumInfo != NULL) {
4022 m_EnumInfo->AcquireParentPowerStateLock(GetDriverGlobals());
4023 //
4024 // Setup a guard so that no children power up until we return to S0.
4025 //
4027 m_EnumInfo->ReleaseParentPowerStateLock(GetDriverGlobals());
4028 }
4029 }
4030
4032 NTSTATUS
4034 VOID
4035 );
4036
4037public:
4039 NTSTATUS
4043 );
4044
4046 NTSTATUS
4048 __in PCM_PARTIAL_RESOURCE_DESCRIPTOR CmIntResourceRaw,
4051 );
4052
4053 BOOLEAN
4055 VOID
4056 )
4057 {
4058#if FX_IS_KERNEL_MODE
4060#else
4061 return FALSE;
4062#endif
4063 }
4064
4065 BOOLEAN
4067 VOID
4068 )
4069 {
4070 return (m_InterruptObjectCount > 1 ? TRUE : FALSE);
4071 }
4072
4073 VOID
4075 VOID
4076 )
4077 {
4079
4081 }
4082
4083 //
4084 // Start of members
4085 //
4086public:
4087
4089
4092
4094
4096
4097 //
4098 // Track the current device and system power states.
4099 //
4100
4101 // SYSTEM_POWER_STATE
4103
4104 // WDF_POWER_DEVICE_STATE
4106
4107 // WDF_POWER_DEVICE_STATE
4109
4110 //
4111 // List of dependent devices for usage notifications
4112 //
4114
4116
4117 //
4118 // Collection of FxQueryInterface objects
4119 //
4121
4123
4125
4127
4129
4130 //
4131 // Indicate the types of special files which are supported.
4132 //
4134
4135 //
4136 // Track the number of special file notifications
4137 // (ie. paging file, crash dump file, and hibernate file).
4138 //
4140
4141 //
4142 // ULONG and not a BOOLEAN so the driver can match nest calls to
4143 // WdfDeviceSetStaticStopRemove without having to track the count on their
4144 // own.
4145 //
4147
4148 //
4149 // All 3 state machine engines
4150 //
4154
4156
4157 //
4158 // Data shared between the power and power policy machines determining how
4159 // we handle wait wake irps.
4160 //
4162
4163 //
4164 // Interface for managing the difference between D3hot and D3cold.
4165 //
4167
4168protected:
4169 //
4170 // Event that is set when processing a remove device is complete
4171 //
4173
4174 //
4175 // Count of children we need to fully remove when the parent (this package)
4176 // is being removed.
4177 //
4179
4180 //
4181 // DEVICE_WAKE_DEPTH - Indicates the lowest D-state that can successfully
4182 // generate a wake signal from a particular S-state. The array is tightly-
4183 // packed, with index 0 corresponding to PowerSystemWorking.
4184 //
4186
4187 // SYSTEM_POWER_STATE
4189
4190 // WDF_DEVICE_FAILED_ACTION
4192
4193 //
4194 // Set the event which indicates that the pnp state machine is done outside
4195 // of the state machine so that we can drain any remaining state machine
4196 // events in the removing thread before signaling the event.
4197 //
4199
4200 //
4201 // Interface to queue a work item to the devnode's power thread. Any device
4202 // in the stack can export the power thread, but it must be the lowest
4203 // device in the stack capable of doing so. This would always be a WDF
4204 // enumerated PDO, but could theoretically be any PDO. If the PDO does
4205 // support this interface, WDF will try to export the interface in a filter
4206 // or FDO.
4207 //
4208 // This export is not publicly defined because this is an internal WDF
4209 // implementation detail where we want to use as few threads as possible,
4210 // but still guarantee that non power pagable devices can operate a passive
4211 // level and not be blocked by paging I/O (which eliminates using work items).
4212 //
4214
4216
4217 //
4218 // Translated resources
4219 //
4221
4222 //
4223 // Raw resources
4224 //
4226
4228
4229 //
4230 // Bus information for any enumerated children
4231 //
4233
4234 //
4235 // Number of times we have tried to enumerate children but failed
4236 //
4238
4239 //
4240 // The power action corresponding to the system power transition
4241 //
4243
4244 //
4245 // TRUE once the entire stack has been queried for the caps
4246 //
4248
4250
4251 //
4252 // if FALSE, there is no power thread available on the devnode currently
4253 // and a work item should be enqueued. if TRUE, there is a power thread
4254 // and the callback should be enqueued to it.
4255 //
4257
4258 //
4259 // If TRUE, we guarantee that in *all* cases that the ReleaseHardware
4260 // callback for the current device is invoked only after all descendent
4261 // devices have already been removed. We do this by ensuring that
4262 // ReleaseHardware is only ever invoked when there is a PNP IRP such as
4263 // remove, surprise-remove or stop is pending in the device. PNP already
4264 // ensures that it sends us that IRP only after all child devices have
4265 // processed the corresponding IRP in their stacks.
4266 //
4267 // Even if FALSE, in *most* cases, the ReleaseHardware callback of the
4268 // current device should still be invoked only after all descendent devices
4269 // have already been stopped/removed. However, in some failure paths we
4270 // might invoke the ReleaseHardware callback of the current device before
4271 // all descendent devices have been stopped. In these cases, we do not wait
4272 // for the surprise-remove IRP sent as a result of the failure in order to
4273 // invoke ReleaseHardware. Instead, we invoke it proactively.
4274 //
4275 // The default value is FALSE.
4276 //
4278
4279 //
4280 // GUID for querying for a power thread down the stack
4281 //
4283
4284#if (FX_CORE_MODE==FX_CORE_KERNEL_MODE)
4285 //
4286 // Interrupt APIs for Vista and forward
4287 //
4290 //
4291 // Interrupt APIs for Windows 8 and forward
4292 //
4295#endif
4296
4297private:
4298
4299 //
4300 // For user mode we need to preallocate event since its initialization can
4301 // fail
4302 //
4303#if (FX_CORE_MODE==FX_CORE_USER_MODE)
4306#endif
4307
4309
4311
4312 //
4313 // Number of interrupts that are declared to be capable
4314 // of waking from low power
4315 //
4317
4318 //
4319 // Count that keeps track of the number of wake interrupt
4320 // machines that have acknowledged back an event queued
4321 // in to them by the device level PnP/Power code
4322 //
4324
4325 //
4326 // Keeps track of whether the last system wake was due to
4327 // a wake interrupt, so that we can report this device as
4328 // the source of wake to the power manager
4329 //
4331
4332 //
4333 // If TRUE, do not disconnect wake interrupts even if there is no
4334 // pended IRP_MN_WAIT_WAKE. This works around a race condition between
4335 // the wake interrupt firing (and the wake ISR running) and the device
4336 // powering down. This flag is set when we are in a wake-enabled device
4337 // powering down path and is cleared when the device is powered up again.
4338 //
4340
4341 //
4342 // If TRUE, the PNP State has reached PnpEventStarted at least once.
4343 //
4345
4346 //
4347 // Non NULL when this device is exporting the power thread interface. This
4348 // would be the lowest device in the stack that supports this interface.
4349 //
4351
4353
4355
4356 //
4357 // The current pnp state changing irp in the stack that we have pended to
4358 // process in the pnp state machine
4359 //
4361
4362 //
4363 // The current system power irp in the stack that we have pended to process
4364 // in the power state machine
4365 //
4367
4368 //
4369 // The current device power irp in the stack that we have pended to process
4370 // in the power state machine
4371 //
4373
4375
4377
4379
4384
4407
4423
4492
4510
4511#if FX_STATE_MACHINE_VERIFY
4512 //
4513 // Array of possible states that can be returned by state entry functions
4514 //
4515 static const PNP_STATE_ENTRY_FN_RETURN_STATE_TABLE m_WdfPnpStateEntryFunctionReturnStates[];
4516 static const POWER_STATE_ENTRY_FN_RETURN_STATE_TABLE m_WdfPowerStateEntryFunctionReturnStates[];
4517 static const PWR_POL_STATE_ENTRY_FN_RETURN_STATE_TABLE m_WdfPwrPolStateEntryFunctionReturnStates[];
4518#endif // FX_STATE_MACHINE_VERIFY
4519
4520 //
4521 // Names for registry values in which we will store the beginning of the
4522 // restart time period, the number of restart attempts in that period, and
4523 // if the device successfully started.
4524 //
4528
4529 //
4530 // Time between successive restarts in which we will attempt to restart a
4531 // stack again. Expressed in seconds.
4532 //
4534
4535 //
4536 // Number of times in the restart time period in which we will attempt a
4537 // restart.
4538 //
4540
4541 //
4542 // Shove the function pointers to the end of the structure so that when
4543 // we dump the structure while debugging, the less pertinent info is at the
4544 // bottom.
4545 //
4546public:
4550
4555
4558
4562};
4563
4564__inline
4565VOID
4567 __inout FxPkgPnp* PkgPnp
4568 )
4569{
4570 if (m_SetRemovedEvent) {
4572 PkgPnp->SignalDeviceRemovedEvent();
4573 return;
4574 }
4575
4576 //
4577 // Process any irp that should be sent down the stack/forgotten.
4578 //
4579 if (m_FireAndForgetIrp != NULL) {
4581
4583 (void) PkgPnp->FireAndForgetIrp(&irp);
4584 }
4585
4586 if (m_DeleteObject) {
4587 PkgPnp->ProcessDelayedDeletion();
4588 }
4589
4590 if (m_Event != NULL) {
4591 m_Event->Set();
4592 }
4593}
4594
4595#endif // _FXPKGPNP_H_
#define SaveState(State)
unsigned char BOOLEAN
unsigned int UINT32
Type
Definition: Type.h:7
#define VOID
Definition: acefi.h:82
static int state
Definition: maze.c:121
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
LONG NTSTATUS
Definition: precomp.h:26
const struct winhelp_callbacks Callbacks
Definition: callback.c:161
Definition: File.h:16
Definition: fxirp.hpp:28
SYSTEM_POWER_STATE_CONTEXT GetParameterPowerSystemPowerStateContext()
Definition: fxirpum.cpp:671
VOID SetStatus(__in NTSTATUS Status)
Definition: fxirpum.cpp:457
MdIrp GetIrp(VOID)
Definition: fxirpum.cpp:15
DEVICE_POWER_STATE GetParameterPowerStateDeviceState()
Definition: fxirpum.cpp:695
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
static WDF_DEVICE_POWER_STATE PowerStartingChild(__inout FxPkgPnp *This)
static const PNP_EVENT_TARGET_STATE m_PnpInitOtherStates[]
Definition: fxpkgpnp.hpp:4385
static WDF_DEVICE_POWER_POLICY_STATE PowerPolSystemWakeDeviceWakeCompletePowerUp(__inout FxPkgPnp *This)
static WDF_DEVICE_POWER_POLICY_STATE NotPowerPolOwnerStopping(__inout FxPkgPnp *This)
MdIrp m_PendingPnPIrp
Definition: fxpkgpnp.hpp:4360
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolStoppingD0OtherStates[]
Definition: fxpkgpnp.hpp:4450
static WDF_SPECIAL_FILE_TYPE _UsageToSpecialType(__in DEVICE_USAGE_NOTIFICATION_TYPE Type)
Definition: fxpkgpnp.hpp:3202
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSystemWakeDeviceWakeCompletePowerUpOtherStates[]
Definition: fxpkgpnp.hpp:4471
VOID SetInternalFailure(VOID)
Definition: fxpkgpnp.cpp:4856
static WDF_DEVICE_POWER_POLICY_STATE PowerPolDeviceIdleSleeping(__inout FxPkgPnp *This)
static WDF_DEVICE_PNP_STATE PnpEventRestartReleaseHardware(__inout FxPkgPnp *This)
BOOLEAN IsSxWakeEnabled(VOID)
Definition: fxpkgpnp.hpp:3672
FxCmResList * GetTranslatedResourceList(VOID)
Definition: fxpkgpnp.hpp:3796
static WDF_DEVICE_POWER_STATE PowerDxSurpriseRemovedPowerUp(__inout FxPkgPnp *This)
static const PNP_EVENT_TARGET_STATE m_PnpQueriedRemovingOtherStates[]
Definition: fxpkgpnp.hpp:4393
static CPPOWER_POLICY_STATE_TABLE GetPowerPolicyTableEntry(__in WDF_DEVICE_POWER_POLICY_STATE State)
Definition: fxpkgpnp.hpp:2871
static WDF_DEVICE_POWER_STATE PowerReportPowerDownFailed(__inout FxPkgPnp *This)
VOID AddInterruptObject(__in FxInterrupt *Interrupt)
Definition: fxpkgpnp.cpp:5928
static WDF_DEVICE_POWER_POLICY_STATE NotPowerPolOwnerStoppingPoweringDown(__inout FxPkgPnp *This)
static WDF_DEVICE_POWER_STATE PowerWakingDmaEnable(__inout FxPkgPnp *This)
static WDF_DEVICE_PNP_STATE PnpEventHardwareAvailablePowerPolicyFailed(__inout FxPkgPnp *This)
BOOLEAN PowerDmaEnableAndScan(__in BOOLEAN ImplicitPowerUp)
static MdCancelRoutineType _PowerWaitWakeCancelRoutine
Definition: fxpkgpnp.hpp:2736
static WDF_DEVICE_POWER_STATE PowerD0DisarmingWakeAtBusNP(__inout FxPkgPnp *This)
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolCancelingWakeForSystemSleepWakeCanceledOtherStates[]
Definition: fxpkgpnp.hpp:4446
VOID RemoveUsageDevice(__in MdDeviceObject DependentDevice)
Definition: fxpkgpnp.cpp:4742
static WDF_DEVICE_POWER_POLICY_STATE PowerPolTimerExpiredWakeCapablePowerDownNotProcessed(__inout FxPkgPnp *This)
static WDF_DEVICE_POWER_STATE PowerD0ArmedForWake(__inout FxPkgPnp *This)
static WDF_DEVICE_POWER_STATE PowerNotifyingD0ExitToWakeInterruptsNP(__inout FxPkgPnp *This)
VOID QueueToPowerThread(__in PWORK_QUEUE_ITEM WorkItem)
Definition: fxpkgpnp.hpp:3516
FxPnpStateCallback * m_PnpStateCallbacks
Definition: fxpkgpnp.hpp:4374
VOID PnpCheckAssumptions(VOID)
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSystemAsleepWakeArmedOtherStates[]
Definition: fxpkgpnp.hpp:4435
static WDF_DEVICE_POWER_POLICY_STATE NotPowerPolOwnerRemoved(__inout FxPkgPnp *This)
static WDF_DEVICE_POWER_POLICY_STATE PowerPolSleepingWakePowerDownFailedWakeCanceled(__inout FxPkgPnp *This)
ULONG m_PnpCapsUINumber
Definition: fxpkgpnp.hpp:4091
BOOLEAN IsPresentPendingPnpIrp(VOID)
Definition: fxpkgpnp.hpp:3004
FxCmResList * m_Resources
Definition: fxpkgpnp.hpp:4220
VOID ProcessDelayedDeletion(VOID)
Definition: fxpkgpnp.cpp:1293
VOID PowerPolicyPostParentToD0ToChildren(VOID)
static const POWER_EVENT_TARGET_STATE m_PowerD0BusWakeOwnerNPOtherStates[]
Definition: fxpkgpnp.hpp:4411
_Must_inspect_result_ NTSTATUS AllocateEnumInfo(VOID)
Definition: fxpkgpnp.cpp:4920
FxPnpDeviceUsageNotificationEx m_DeviceUsageNotificationEx
Definition: fxpkgpnp.hpp:4548
static WDF_DEVICE_PNP_STATE PnpEventInitSurpriseRemoved(__inout FxPkgPnp *This)
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSystemAsleepWakeArmedNPOtherStates[]
Definition: fxpkgpnp.hpp:4436
static _Must_inspect_result_ NTSTATUS _PnpCancelRemoveDevice(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpnp.cpp:2026
static WDF_DEVICE_POWER_POLICY_STATE PowerPolSystemAsleepNoWake(__inout FxPkgPnp *This)
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolWaitingArmedWakeInterruptFiredOtherStates[]
Definition: fxpkgpnp.hpp:4507
VOID ChildListNotifyRemove(__inout PLONG PendingCount)
Definition: fxpkgpnp.cpp:4999
static const POWER_POLICY_EVENT_TARGET_STATE m_NotPowerPolOwnerGotoD0States[]
Definition: fxpkgpnp.hpp:4500
static const POWER_POLICY_EVENT_TARGET_STATE m_NotPowerPolOwnerRemovedStates[]
Definition: fxpkgpnp.hpp:4506
static const POWER_POLICY_EVENT_TARGET_STATE m_NotPowerPolOwnerStoppingPoweringDownStates[]
Definition: fxpkgpnp.hpp:4505
static WDF_DEVICE_POWER_STATE PowerWakePendingNP(__inout FxPkgPnp *This)
VOID AddQueryInterface(__in FxQueryInterface *QI, __in BOOLEAN Lock)
Definition: fxpkgpnp.cpp:5017
VOID RegisterPowerPolicyCallbacks(__in PWDF_POWER_POLICY_EVENT_CALLBACKS Callbacks)
Definition: fxpkgpnp.cpp:2715
PFN_IO_REPORT_INTERRUPT_INACTIVE m_IoReportInterruptInactive
Definition: fxpkgpnp.hpp:4294
static WDF_DEVICE_POWER_POLICY_STATE PowerPolTimerExpiredWakeCapableWakeCanceled(__inout FxPkgPnp *This)
BOOLEAN HasMultipleInterrupts(VOID)
Definition: fxpkgpnp.hpp:4066
_Must_inspect_result_ NTSTATUS QueryForCapabilities(VOID)
Definition: fxpkgpnp.cpp:1675
static _Must_inspect_result_ NTSTATUS _PnpRemoveDevice(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpnp.cpp:2275
BOOLEAN PowerGotoDxIoStoppedNP(VOID)
static WDF_DEVICE_POWER_STATE PowerStartSelfManagedIoFailed(__inout FxPkgPnp *This)
FxSystemThread * m_PowerThread
Definition: fxpkgpnp.hpp:4350
_Must_inspect_result_ NTSTATUS HandleQueryBusInformation(__inout FxIrp *Irp)
Definition: fxpkgpnp.cpp:947
static WDF_DEVICE_POWER_POLICY_STATE PowerPolTimerExpiredNoWakePowerDownNotProcessed(__inout FxPkgPnp *This)
static WDF_DEVICE_PNP_STATE PnpEventRemovedChildrenRemoved(__inout FxPkgPnp *This)
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSystemWakeDeviceWakeEnabledWakeCanceledNPOtherStates[]
Definition: fxpkgpnp.hpp:4467
VOID PowerCompleteWakeRequestFromWithinMachine(__in NTSTATUS Status)
friend FxPowerPolicyMachine
Definition: fxpkgpnp.hpp:492
static WDF_DEVICE_POWER_POLICY_STATE NotPowerPolOwnerStarting(__inout FxPkgPnp *This)
static VOID STDCALL _PowerThreadInterfaceDereference(__inout PVOID Context)
Definition: fxpkgpnp.cpp:5292
static WDF_DEVICE_POWER_POLICY_STATE PowerPolStarted(__inout FxPkgPnp *This)
BOOLEAN IsS0IdleSystemManaged(VOID)
Definition: fxpkgpnp.hpp:3645
virtual VOID ReleaseReenumerationInterface(VOID)=0
static WDF_DEVICE_POWER_POLICY_STATE PowerPolSleepingWakeRevertArmWakeNP(__inout FxPkgPnp *This)
VOID __inline PowerPolicyDisarmWakeFromSx(VOID)
ULONG m_InterruptObjectCount
Definition: fxpkgpnp.hpp:4308
static const PNP_EVENT_TARGET_STATE m_PnpStartedStoppingOtherStates[]
Definition: fxpkgpnp.hpp:4397
static const PNP_EVENT_TARGET_STATE m_PnpStoppedOtherStates[]
Definition: fxpkgpnp.hpp:4395
_Must_inspect_result_ NTSTATUS CreatePowerThread(VOID)
Definition: fxpkgpnp.cpp:5125
static WDF_DEVICE_PNP_STATE PnpEventQueryCanceled(__inout FxPkgPnp *This)
static WDF_DEVICE_PNP_STATE PnpEventQueryStopStaticCheck(__inout FxPkgPnp *This)
static WDF_DEVICE_POWER_POLICY_STATE PowerPolSleepingNoWakeDxRequestFailed(__inout FxPkgPnp *This)
virtual WDF_DEVICE_POWER_STATE PowerCheckDeviceTypeNPOverload(VOID)=0
UCHAR m_BusEnumRetries
Definition: fxpkgpnp.hpp:4237
static const POWER_POLICY_EVENT_TARGET_STATE m_NotPowerPolOwnerGotoDxStates[]
Definition: fxpkgpnp.hpp:4497
SINGLE_LIST_ENTRY m_DeviceInterfaceHead
Definition: fxpkgpnp.hpp:4126
FxWaitLockInternal m_QueryInterfaceLock
Definition: fxpkgpnp.hpp:4120
virtual WDF_DEVICE_PNP_STATE PnpEventFdoRemovedOverload(VOID)=0
FxSelfManagedIoMachine * m_SelfManagedIoMachine
Definition: fxpkgpnp.hpp:4155
static WDF_DEVICE_POWER_STATE PowerCheckDeviceTypeNP(__inout FxPkgPnp *This)
_Must_inspect_result_ NTSTATUS PnpPowerReferenceDuringQueryPnp(VOID)
Definition: fxpkgpnp.cpp:5351
VOID PowerSendPowerDownFailureEvent(__in FxPowerDownType Type)
VOID SetPendingDevicePowerIrp(__inout FxIrp *Irp)
Definition: fxpkgpnp.hpp:3050
static const POWER_POLICY_EVENT_TARGET_STATE m_NotPowerPolOwnerObjectCreatedStates[]
Definition: fxpkgpnp.hpp:4493
LONG m_SpecialFileCount[WdfSpecialFileMax-1]
Definition: fxpkgpnp.hpp:4139
_Must_inspect_result_ NTSTATUS PnpDeviceUsageNotification(__inout FxIrp *Irp)
Definition: fxpkgpnp.cpp:3867
static WDF_DEVICE_POWER_POLICY_STATE PowerPolStoppingFailed(__inout FxPkgPnp *This)
static WDF_DEVICE_PNP_STATE PnpEventStartedCancelStop(__inout FxPkgPnp *This)
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolS0WakeCompletePowerUpOtherStates[]
Definition: fxpkgpnp.hpp:4455
FxCmResList * m_ResourcesRaw
Definition: fxpkgpnp.hpp:4225
static const PNP_EVENT_TARGET_STATE m_PnpRemovedPdoWaitOtherStates[]
Definition: fxpkgpnp.hpp:4389
PNP_BUS_INFORMATION m_BusInformation
Definition: fxpkgpnp.hpp:4232
BOOLEAN PowerIsWakeRequestPresent(VOID)
Definition: fxpkgpnp.hpp:2672
_Must_inspect_result_ NTSTATUS PnpEnableInterfacesAndRegisterWmi(VOID)
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolWakeCapableDeviceIdleOtherStates[]
Definition: fxpkgpnp.hpp:4440
FxRelatedDeviceList * m_UsageDependentDeviceList
Definition: fxpkgpnp.hpp:4113
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolTimerExpiredWakeCapablePowerDownFailedWakeInterruptArrivedOtherStates[]
Definition: fxpkgpnp.hpp:4490
static WDF_DEVICE_POWER_POLICY_STATE PowerPolSystemSleepNeedWakeCompletePowerUp(__inout FxPkgPnp *This)
static WDF_DEVICE_POWER_POLICY_STATE NotPowerPolOwnerStoppingPoweringUp(__inout FxPkgPnp *This)
static WDF_DEVICE_POWER_POLICY_STATE PowerPolSystemWakeQueryIdle(__inout FxPkgPnp *This)
static WDF_DEVICE_POWER_POLICY_STATE PowerPolTimerExpiredNoWakePoweredDownDisableIdleTimer(__inout FxPkgPnp *This)
VOID DisconnectInterruptNP(VOID)
PFN_IO_DISCONNECT_INTERRUPT_EX m_IoDisconnectInterruptEx
Definition: fxpkgpnp.hpp:4289
static WDF_DEVICE_POWER_STATE PowerD0DisarmingWakeAtBus(__inout FxPkgPnp *This)
static NTSTATUS _SxWakeSetItem(__in CfxDevice *Device, __in FxWmiInstanceInternal *Instance, __in ULONG DataItemId, __in ULONG InBufferSize, __in PVOID InBuffer)
Definition: fxpkgpnp.cpp:3556
static WDF_DEVICE_POWER_POLICY_STATE PowerPolStopping(__inout FxPkgPnp *This)
VOID PnpPowerPolicySurpriseRemove(VOID)
static WDF_DEVICE_POWER_POLICY_STATE PowerPolStartingDecideS0Wake(__inout FxPkgPnp *This)
static WDF_DEVICE_POWER_STATE PowerD0NP(__inout FxPkgPnp *This)
FxPowerStateCallback * m_PowerStateCallbacks
Definition: fxpkgpnp.hpp:4376
static WDF_DEVICE_POWER_POLICY_STATE PowerPolStartedCancelTimer(__inout FxPkgPnp *This)
BOOLEAN m_ReleaseHardwareAfterDescendantsOnFailure
Definition: fxpkgpnp.hpp:4277
static VOID STDCALL _PowerThreadInterfaceReference(__inout PVOID Context)
Definition: fxpkgpnp.cpp:5262
BOOLEAN PowerPolicyCancelWaitWake(VOID)
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolTimerExpiredWakeCapableWakeSucceededOtherStates[]
Definition: fxpkgpnp.hpp:4456
static WDF_DEVICE_POWER_STATE PowerSurpriseRemoved(__inout FxPkgPnp *This)
static const PNP_EVENT_TARGET_STATE m_PnpStartedStoppingFailedOtherStates[]
Definition: fxpkgpnp.hpp:4398
static WDF_DEVICE_PNP_STATE PnpEventQueriedRemoving(__inout FxPkgPnp *This)
static WDF_DEVICE_POWER_POLICY_STATE PowerPolTimerExpiredWakeCapableWakeArrived(__inout FxPkgPnp *This)
static WDF_DEVICE_PNP_STATE PnpEventQueriedSurpriseRemove(__inout FxPkgPnp *This)
static WDF_DEVICE_POWER_STATE PowerReportPowerUpFailedDerefParent(__inout FxPkgPnp *This)
VOID ChildRemoved(VOID)
Definition: fxpkgpnp.hpp:3415
static WDF_DEVICE_POWER_POLICY_STATE PowerPolS0WakeDisarm(__inout FxPkgPnp *This)
static WDF_DEVICE_POWER_POLICY_STATE NotPowerPolOwnerStoppingSendStatus(__inout FxPkgPnp *This)
static WDF_DEVICE_PNP_STATE PnpEventStartedRemoving(__inout FxPkgPnp *This)
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolObjectCreatedOtherStates[]
Definition: fxpkgpnp.hpp:4424
static WDF_DEVICE_POWER_STATE PowerD0SurpriseRemoved(__inout FxPkgPnp *This)
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolTimerExpiredWakeCapablePowerDownFailedCancelWakeOtherStates[]
Definition: fxpkgpnp.hpp:4458
static WDF_DEVICE_POWER_POLICY_STATE PowerPolSystemWakeDeviceWakeTriggeredS0(__inout FxPkgPnp *This)
LONG m_PendingChildCount
Definition: fxpkgpnp.hpp:4178
FxPowerMachine m_PowerMachine
Definition: fxpkgpnp.hpp:4152
static WDF_DEVICE_POWER_POLICY_STATE PowerPolTimerExpiredWakeCompletedPowerDown(__inout FxPkgPnp *This)
LONG m_PowerThreadInterfaceReferenceCount
Definition: fxpkgpnp.hpp:4352
static WDF_DEVICE_POWER_POLICY_STATE PowerPolCancelingUsbSSForSystemSleep(__inout FxPkgPnp *This)
virtual VOID PowerParentPowerDereference(VOID)=0
BOOLEAN ShouldProcessPowerPolicyEventOnDifferentThread(__in KIRQL CurrentIrql, __in BOOLEAN CallerSpecifiedProcessingOnDifferentThread)
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolTimerExpiredWakeCapableCancelWakeOtherStates[]
Definition: fxpkgpnp.hpp:4461
static const PWCHAR m_RestartStartAchievedName
Definition: fxpkgpnp.hpp:4525
FxPnpDeviceD0Exit m_DeviceD0Exit
Definition: fxpkgpnp.hpp:4554
UCHAR m_SystemPowerAction
Definition: fxpkgpnp.hpp:4242