18a978a17SVictor Perevertkin //
28a978a17SVictor Perevertkin // Copyright (C) Microsoft. All rights reserved.
38a978a17SVictor Perevertkin //
4*1f377076SVictor Perevertkin #include "../pnppriv.hpp"
58a978a17SVictor Perevertkin
68a978a17SVictor Perevertkin #include <initguid.h>
78a978a17SVictor Perevertkin #include <wdmguid.h>
88a978a17SVictor Perevertkin
98a978a17SVictor Perevertkin extern "C" {
108a978a17SVictor Perevertkin #if defined(EVENT_TRACING)
118a978a17SVictor Perevertkin #include "FxPkgPnpKM.tmh"
128a978a17SVictor Perevertkin #endif
138a978a17SVictor Perevertkin }
148a978a17SVictor Perevertkin
158a978a17SVictor Perevertkin NTSTATUS
FilterResourceRequirements(__in IO_RESOURCE_REQUIREMENTS_LIST ** IoList)168a978a17SVictor Perevertkin FxPkgPnp::FilterResourceRequirements(
178a978a17SVictor Perevertkin __in IO_RESOURCE_REQUIREMENTS_LIST **IoList
188a978a17SVictor Perevertkin )
198a978a17SVictor Perevertkin /*++
208a978a17SVictor Perevertkin
218a978a17SVictor Perevertkin Routine Description:
228a978a17SVictor Perevertkin
238a978a17SVictor Perevertkin This routine traverses one or more alternate _IO_RESOURCE_LISTs in the input
248a978a17SVictor Perevertkin IO_RESOURCE_REQUIREMENTS_LIST looking for interrupt descriptor and applies
258a978a17SVictor Perevertkin the policy set by driver in the interrupt object to the resource descriptor.
268a978a17SVictor Perevertkin
278a978a17SVictor Perevertkin LBI - Line based interrupt
288a978a17SVictor Perevertkin MSI - Message Signalled interrupt
298a978a17SVictor Perevertkin
308a978a17SVictor Perevertkin Here are the assumptions made about the order of descriptors.
318a978a17SVictor Perevertkin
328a978a17SVictor Perevertkin - An IoRequirementList can have one or more alternate IoResourceList
338a978a17SVictor Perevertkin - Each IoResourceList can have one or more resource descriptors
348a978a17SVictor Perevertkin - A descriptor can be default (unique), preferred, or alternate descriptors
358a978a17SVictor Perevertkin - A preferred descriptor can have zero or more alternate descriptors (P, A, A, A..)
368a978a17SVictor Perevertkin - In an IoResourceList, there can be one or more LBI descriptors
378a978a17SVictor Perevertkin (non-pci devices)(P,A,P,A)
388a978a17SVictor Perevertkin - In an IoResourceList, there can be only one preferred MSI 2.2
398a978a17SVictor Perevertkin (single or multi message) descriptor
408a978a17SVictor Perevertkin - In an IoResourceList, there cannot be MSI2.2 and MSI-X descriptors
418a978a17SVictor Perevertkin - In an IoResourceList, there can be one or more MSI-X descriptor
428a978a17SVictor Perevertkin - An alternate descriptor cannot be a very first descriptor in the list
438a978a17SVictor Perevertkin
448a978a17SVictor Perevertkin
458a978a17SVictor Perevertkin Now with that assumption, this routines parses the list looking for interrupt
468a978a17SVictor Perevertkin descriptor.
478a978a17SVictor Perevertkin
488a978a17SVictor Perevertkin - If it finds a LBI, it starts with the very first interrupt object and applies
498a978a17SVictor Perevertkin the policy set by the driver to the resource descriptor.
508a978a17SVictor Perevertkin - If it's finds an MSI2.2 then it starts with the first interrupt object and applies
518a978a17SVictor Perevertkin the policy. If the MSI2.2 is a multi-message one then it loops thru looking for
528a978a17SVictor Perevertkin as many interrupt object as there are messages. It doesn't fail the IRP, if the
538a978a17SVictor Perevertkin interrupt objects are less than the messages.
548a978a17SVictor Perevertkin - If there is an alternate descriptor then it applies the same policy from the
558a978a17SVictor Perevertkin interrupt object that it used for the preceding preferred descriptor.
568a978a17SVictor Perevertkin - Framework always uses FULLY_SPECIFIED connection type for both LBI and MSI
578a978a17SVictor Perevertkin interrupts including MSI-X
588a978a17SVictor Perevertkin - Framework will apply the policy on the descriptor set by the driver only
598a978a17SVictor Perevertkin if the policy is already not included in the resource descriptor. This is
608a978a17SVictor Perevertkin to allow the policy set in the registry to take precedence over the hard
618a978a17SVictor Perevertkin coded driver policy.
628a978a17SVictor Perevertkin - If the driver registers filter resource requirement and applies the policy
638a978a17SVictor Perevertkin on its own (by escaping to WDM) then framework doesn't override that.
648a978a17SVictor Perevertkin
658a978a17SVictor Perevertkin Arguments:
668a978a17SVictor Perevertkin
678a978a17SVictor Perevertkin IoList - Pointer to the list part of an IRP_MN_FILTER_RESOURCE_REQUIREMENTS.
688a978a17SVictor Perevertkin
698a978a17SVictor Perevertkin Return Value:
708a978a17SVictor Perevertkin
718a978a17SVictor Perevertkin NTSTATUS
728a978a17SVictor Perevertkin
738a978a17SVictor Perevertkin --*/
748a978a17SVictor Perevertkin {
758a978a17SVictor Perevertkin ULONG altResListIndex;
768a978a17SVictor Perevertkin PIO_RESOURCE_REQUIREMENTS_LIST pIoRequirementList;
778a978a17SVictor Perevertkin PIO_RESOURCE_LIST pIoResList;
788a978a17SVictor Perevertkin
798a978a17SVictor Perevertkin pIoRequirementList = *IoList;
808a978a17SVictor Perevertkin
818a978a17SVictor Perevertkin if (pIoRequirementList == NULL) {
828a978a17SVictor Perevertkin return STATUS_SUCCESS;
838a978a17SVictor Perevertkin }
848a978a17SVictor Perevertkin
858a978a17SVictor Perevertkin if (IsListEmpty(&m_InterruptListHead)) {
868a978a17SVictor Perevertkin //
878a978a17SVictor Perevertkin // No interrupt objects created to filter resource requirements.
888a978a17SVictor Perevertkin //
898a978a17SVictor Perevertkin return STATUS_SUCCESS;
908a978a17SVictor Perevertkin }
918a978a17SVictor Perevertkin
928a978a17SVictor Perevertkin pIoResList = pIoRequirementList->List;
938a978a17SVictor Perevertkin
948a978a17SVictor Perevertkin //
958a978a17SVictor Perevertkin // Parse one or more alternative resource lists.
968a978a17SVictor Perevertkin //
978a978a17SVictor Perevertkin for (altResListIndex = 0;
988a978a17SVictor Perevertkin altResListIndex < pIoRequirementList->AlternativeLists;
998a978a17SVictor Perevertkin altResListIndex++) {
1008a978a17SVictor Perevertkin PLIST_ENTRY pIntListEntryForMSI;
1018a978a17SVictor Perevertkin PLIST_ENTRY pIntListEntryForLBI;
1028a978a17SVictor Perevertkin BOOLEAN multiMessageMSI22Found;
1038a978a17SVictor Perevertkin BOOLEAN previousDescMSI;
1048a978a17SVictor Perevertkin ULONG descIndex;
1058a978a17SVictor Perevertkin
1068a978a17SVictor Perevertkin multiMessageMSI22Found = FALSE;
1078a978a17SVictor Perevertkin previousDescMSI = FALSE;
1088a978a17SVictor Perevertkin
1098a978a17SVictor Perevertkin pIntListEntryForMSI = &m_InterruptListHead;
1108a978a17SVictor Perevertkin pIntListEntryForLBI = &m_InterruptListHead;
1118a978a17SVictor Perevertkin
1128a978a17SVictor Perevertkin //
1138a978a17SVictor Perevertkin // Traverse each _IO_RESOURCE_LISTs looking for interrupt descriptors
1148a978a17SVictor Perevertkin // and call FilterResourceRequirements method so that it can apply
1158a978a17SVictor Perevertkin // policy set on the interrupt object into the resource-descriptor.
1168a978a17SVictor Perevertkin //
1178a978a17SVictor Perevertkin
1188a978a17SVictor Perevertkin for (descIndex = 0; descIndex < pIoResList->Count; descIndex++) {
1198a978a17SVictor Perevertkin ULONG messageCount;
1208a978a17SVictor Perevertkin PIO_RESOURCE_DESCRIPTOR pIoDesc;
1218a978a17SVictor Perevertkin FxInterrupt* pInterruptInstance;
1228a978a17SVictor Perevertkin
1238a978a17SVictor Perevertkin pIoDesc = &pIoResList->Descriptors[descIndex];
1248a978a17SVictor Perevertkin
1258a978a17SVictor Perevertkin switch (pIoDesc->Type) {
1268a978a17SVictor Perevertkin case CmResourceTypeInterrupt:
1278a978a17SVictor Perevertkin
1288a978a17SVictor Perevertkin if (FxInterrupt::_IsMessageInterrupt(pIoDesc->Flags)) {
1298a978a17SVictor Perevertkin
1308a978a17SVictor Perevertkin previousDescMSI = TRUE;
1318a978a17SVictor Perevertkin
1328a978a17SVictor Perevertkin //
1338a978a17SVictor Perevertkin // We will advance to the next interrupt object if the resource
1348a978a17SVictor Perevertkin // is not an alternate resource descriptor. A resource list can
1358a978a17SVictor Perevertkin // have a preferred and zero or more alternate resource descriptors
1368a978a17SVictor Perevertkin // for the same resource. We need to apply the same policy on the
1378a978a17SVictor Perevertkin // alternate desc that we applied on the preferred one in case one
1388a978a17SVictor Perevertkin // of the alernate desc is selected for this device. An alternate
1398a978a17SVictor Perevertkin // resource descriptor can't be the first descriptor in a list.
1408a978a17SVictor Perevertkin //
1418a978a17SVictor Perevertkin if ((pIoDesc->Option & IO_RESOURCE_ALTERNATIVE) == 0) {
1428a978a17SVictor Perevertkin pIntListEntryForMSI = pIntListEntryForMSI->Flink;
1438a978a17SVictor Perevertkin }
1448a978a17SVictor Perevertkin
1458a978a17SVictor Perevertkin if (pIntListEntryForMSI == &m_InterruptListHead) {
1468a978a17SVictor Perevertkin DoTraceLevelMessage(
1478a978a17SVictor Perevertkin GetDriverGlobals(), TRACE_LEVEL_WARNING, TRACINGPNP,
1488a978a17SVictor Perevertkin "Not enough interrupt objects created for MSI by WDFDEVICE 0x%p ",
1498a978a17SVictor Perevertkin m_Device->GetHandle());
1508a978a17SVictor Perevertkin break;
1518a978a17SVictor Perevertkin }
1528a978a17SVictor Perevertkin
1538a978a17SVictor Perevertkin pInterruptInstance = CONTAINING_RECORD(pIntListEntryForMSI, FxInterrupt, m_PnpList);
1548a978a17SVictor Perevertkin messageCount = pIoDesc->u.Interrupt.MaximumVector - pIoDesc->u.Interrupt.MinimumVector + 1;
1558a978a17SVictor Perevertkin
1568a978a17SVictor Perevertkin if (messageCount > 1) {
1578a978a17SVictor Perevertkin //
1588a978a17SVictor Perevertkin // PCI spec guarantees that there can be only one preferred/default
1598a978a17SVictor Perevertkin // MSI 2.2 descriptor in a single list.
1608a978a17SVictor Perevertkin //
1618a978a17SVictor Perevertkin if ((pIoDesc->Option & IO_RESOURCE_ALTERNATIVE) == 0) {
1628a978a17SVictor Perevertkin #if DBG
1638a978a17SVictor Perevertkin ASSERT(multiMessageMSI22Found == FALSE);
1648a978a17SVictor Perevertkin #else
1658a978a17SVictor Perevertkin UNREFERENCED_PARAMETER(multiMessageMSI22Found);
1668a978a17SVictor Perevertkin #endif
1678a978a17SVictor Perevertkin multiMessageMSI22Found = TRUE;
1688a978a17SVictor Perevertkin
1698a978a17SVictor Perevertkin }
1708a978a17SVictor Perevertkin }
1718a978a17SVictor Perevertkin else {
1728a978a17SVictor Perevertkin //
1738a978a17SVictor Perevertkin // This is either single message MSI 2.2 or MSI-X interrupts
1748a978a17SVictor Perevertkin //
1758a978a17SVictor Perevertkin DO_NOTHING();
1768a978a17SVictor Perevertkin }
1778a978a17SVictor Perevertkin
1788a978a17SVictor Perevertkin pInterruptInstance->FilterResourceRequirements(pIoDesc);
1798a978a17SVictor Perevertkin }
1808a978a17SVictor Perevertkin else {
1818a978a17SVictor Perevertkin
1828a978a17SVictor Perevertkin //
1838a978a17SVictor Perevertkin // We will advance to next interrupt object if the desc is not an alternate
1848a978a17SVictor Perevertkin // descriptor. For non PCI devices, the first LBI interrupt desc can't be an
1858a978a17SVictor Perevertkin // alternate descriptor.
1868a978a17SVictor Perevertkin //
1878a978a17SVictor Perevertkin if ((pIoDesc->Option & IO_RESOURCE_ALTERNATIVE) == 0) {
1888a978a17SVictor Perevertkin pIntListEntryForLBI = pIntListEntryForLBI->Flink;
1898a978a17SVictor Perevertkin }
1908a978a17SVictor Perevertkin
1918a978a17SVictor Perevertkin //
1928a978a17SVictor Perevertkin // An LBI can be first alternate resource if there are preceding MSI(X) descriptors
1938a978a17SVictor Perevertkin // listed in the list. In that case, this descriptor is the alternate interrupt resource
1948a978a17SVictor Perevertkin // for all of the MSI messages. As a result, we will use the first interrupt object from
1958a978a17SVictor Perevertkin // the list if this ends up being assigned by the system instead of MSI.
1968a978a17SVictor Perevertkin //
1978a978a17SVictor Perevertkin if (previousDescMSI) {
1988a978a17SVictor Perevertkin ASSERT(pIoDesc->Option & IO_RESOURCE_ALTERNATIVE);
1998a978a17SVictor Perevertkin pIntListEntryForLBI = m_InterruptListHead.Flink;
2008a978a17SVictor Perevertkin previousDescMSI = FALSE;
2018a978a17SVictor Perevertkin }
2028a978a17SVictor Perevertkin
2038a978a17SVictor Perevertkin //
2048a978a17SVictor Perevertkin // There can be one or more LBI interrupts and each LBI interrupt
2058a978a17SVictor Perevertkin // could have zero or more alternate descriptors.
2068a978a17SVictor Perevertkin //
2078a978a17SVictor Perevertkin if (pIntListEntryForLBI == &m_InterruptListHead) {
2088a978a17SVictor Perevertkin DoTraceLevelMessage(
2098a978a17SVictor Perevertkin GetDriverGlobals(), TRACE_LEVEL_WARNING, TRACINGPNP,
2108a978a17SVictor Perevertkin "Not enough interrupt objects created for LBI by WDFDEVICE 0x%p ",
2118a978a17SVictor Perevertkin m_Device->GetHandle());
2128a978a17SVictor Perevertkin break;
2138a978a17SVictor Perevertkin }
2148a978a17SVictor Perevertkin
2158a978a17SVictor Perevertkin pInterruptInstance = CONTAINING_RECORD(pIntListEntryForLBI, FxInterrupt, m_PnpList);
2168a978a17SVictor Perevertkin
2178a978a17SVictor Perevertkin pInterruptInstance->FilterResourceRequirements(pIoDesc);
2188a978a17SVictor Perevertkin }
2198a978a17SVictor Perevertkin
2208a978a17SVictor Perevertkin break;
2218a978a17SVictor Perevertkin
2228a978a17SVictor Perevertkin default:
2238a978a17SVictor Perevertkin break;
2248a978a17SVictor Perevertkin }
2258a978a17SVictor Perevertkin }
2268a978a17SVictor Perevertkin
2278a978a17SVictor Perevertkin //
2288a978a17SVictor Perevertkin // Since the Descriptors is a variable length list, you cannot get to the next
2298a978a17SVictor Perevertkin // alternate list by doing pIoRequirementList->List[altResListIndex].
2308a978a17SVictor Perevertkin // Descriptors[descIndex] will now point to the end of the descriptor list.
2318a978a17SVictor Perevertkin // If there is another alternate list, it would be begin there.
2328a978a17SVictor Perevertkin //
2338a978a17SVictor Perevertkin pIoResList = (PIO_RESOURCE_LIST) &pIoResList->Descriptors[descIndex];
2348a978a17SVictor Perevertkin }
2358a978a17SVictor Perevertkin
2368a978a17SVictor Perevertkin return STATUS_SUCCESS;
2378a978a17SVictor Perevertkin }
2388a978a17SVictor Perevertkin
2398a978a17SVictor Perevertkin _Must_inspect_result_
2408a978a17SVictor Perevertkin NTSTATUS
AllocateDmaEnablerList(VOID)2418a978a17SVictor Perevertkin FxPkgPnp::AllocateDmaEnablerList(
2428a978a17SVictor Perevertkin VOID
2438a978a17SVictor Perevertkin )
2448a978a17SVictor Perevertkin {
2458a978a17SVictor Perevertkin FxSpinLockTransactionedList* pList;
2468a978a17SVictor Perevertkin NTSTATUS status;
2478a978a17SVictor Perevertkin KIRQL irql;
2488a978a17SVictor Perevertkin
2498a978a17SVictor Perevertkin if (m_DmaEnablerList != NULL) {
2508a978a17SVictor Perevertkin return STATUS_SUCCESS;
2518a978a17SVictor Perevertkin }
2528a978a17SVictor Perevertkin
2538a978a17SVictor Perevertkin Lock(&irql);
2548a978a17SVictor Perevertkin if (m_DmaEnablerList == NULL) {
2558a978a17SVictor Perevertkin pList = new (GetDriverGlobals()) FxSpinLockTransactionedList();
2568a978a17SVictor Perevertkin
2578a978a17SVictor Perevertkin if (pList != NULL) {
2588a978a17SVictor Perevertkin m_DmaEnablerList = pList;
2598a978a17SVictor Perevertkin status = STATUS_SUCCESS;
2608a978a17SVictor Perevertkin }
2618a978a17SVictor Perevertkin else {
2628a978a17SVictor Perevertkin status = STATUS_INSUFFICIENT_RESOURCES;
2638a978a17SVictor Perevertkin }
2648a978a17SVictor Perevertkin }
2658a978a17SVictor Perevertkin else {
2668a978a17SVictor Perevertkin //
2678a978a17SVictor Perevertkin // Already have a DMA list
2688a978a17SVictor Perevertkin //
2698a978a17SVictor Perevertkin status = STATUS_SUCCESS;
2708a978a17SVictor Perevertkin }
2718a978a17SVictor Perevertkin Unlock(irql);
2728a978a17SVictor Perevertkin
2738a978a17SVictor Perevertkin return status;
2748a978a17SVictor Perevertkin }
2758a978a17SVictor Perevertkin
2768a978a17SVictor Perevertkin VOID
AddDmaEnabler(__in FxDmaEnabler * Enabler)2778a978a17SVictor Perevertkin FxPkgPnp::AddDmaEnabler(
2788a978a17SVictor Perevertkin __in FxDmaEnabler* Enabler
2798a978a17SVictor Perevertkin )
2808a978a17SVictor Perevertkin {
2818a978a17SVictor Perevertkin DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGPNP,
2828a978a17SVictor Perevertkin "Adding DmaEnabler %p, WDFDMAENABLER %p",
2838a978a17SVictor Perevertkin Enabler, Enabler->GetObjectHandle());
2848a978a17SVictor Perevertkin
2858a978a17SVictor Perevertkin m_DmaEnablerList->Add(GetDriverGlobals(), &Enabler->m_TransactionLink);
2868a978a17SVictor Perevertkin }
2878a978a17SVictor Perevertkin
2888a978a17SVictor Perevertkin VOID
RemoveDmaEnabler(__in FxDmaEnabler * Enabler)2898a978a17SVictor Perevertkin FxPkgPnp::RemoveDmaEnabler(
2908a978a17SVictor Perevertkin __in FxDmaEnabler* Enabler
2918a978a17SVictor Perevertkin )
2928a978a17SVictor Perevertkin {
2938a978a17SVictor Perevertkin DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGPNP,
2948a978a17SVictor Perevertkin "Removing DmaEnabler %p, WDFDMAENABLER %p",
2958a978a17SVictor Perevertkin Enabler, Enabler->GetObjectHandle());
2968a978a17SVictor Perevertkin
2978a978a17SVictor Perevertkin m_DmaEnablerList->Remove(GetDriverGlobals(), &Enabler->m_TransactionLink);
2988a978a17SVictor Perevertkin }
2998a978a17SVictor Perevertkin
3008a978a17SVictor Perevertkin VOID
WriteStateToRegistry(__in HANDLE RegKey,__in PUNICODE_STRING ValueName,__in ULONG Value)3018a978a17SVictor Perevertkin FxPkgPnp::WriteStateToRegistry(
3028a978a17SVictor Perevertkin __in HANDLE RegKey,
3038a978a17SVictor Perevertkin __in PUNICODE_STRING ValueName,
3048a978a17SVictor Perevertkin __in ULONG Value
3058a978a17SVictor Perevertkin )
3068a978a17SVictor Perevertkin {
3078a978a17SVictor Perevertkin ZwSetValueKey(RegKey, ValueName, 0, REG_DWORD, &Value, sizeof(Value));
3088a978a17SVictor Perevertkin }
3098a978a17SVictor Perevertkin
310*1f377076SVictor Perevertkin // NTSTATUS __REACTOS__
311*1f377076SVictor Perevertkin // FxPkgPnp::UpdateWmiInstanceForS0Idle(
312*1f377076SVictor Perevertkin // __in FxWmiInstanceAction Action
313*1f377076SVictor Perevertkin // )
314*1f377076SVictor Perevertkin // {
315*1f377076SVictor Perevertkin // FxWmiProvider* pProvider;
316*1f377076SVictor Perevertkin // NTSTATUS status;
3178a978a17SVictor Perevertkin
318*1f377076SVictor Perevertkin // switch(Action) {
319*1f377076SVictor Perevertkin // case AddInstance:
320*1f377076SVictor Perevertkin // if (m_PowerPolicyMachine.m_Owner->m_IdleSettings.WmiInstance == NULL) {
321*1f377076SVictor Perevertkin // FxWmiInstanceInternalCallbacks cb;
3228a978a17SVictor Perevertkin
323*1f377076SVictor Perevertkin // cb.SetInstance = _S0IdleSetInstance;
324*1f377076SVictor Perevertkin // cb.QueryInstance = _S0IdleQueryInstance;
325*1f377076SVictor Perevertkin // cb.SetItem = _S0IdleSetItem;
3268a978a17SVictor Perevertkin
327*1f377076SVictor Perevertkin // status = RegisterPowerPolicyWmiInstance(
328*1f377076SVictor Perevertkin // &GUID_POWER_DEVICE_ENABLE,
329*1f377076SVictor Perevertkin // &cb,
330*1f377076SVictor Perevertkin // &m_PowerPolicyMachine.m_Owner->m_IdleSettings.WmiInstance);
3318a978a17SVictor Perevertkin
332*1f377076SVictor Perevertkin // if (!NT_SUCCESS(status)) {
333*1f377076SVictor Perevertkin // return status;
334*1f377076SVictor Perevertkin // }
335*1f377076SVictor Perevertkin // }
336*1f377076SVictor Perevertkin // else {
337*1f377076SVictor Perevertkin // pProvider = m_PowerPolicyMachine.m_Owner->m_IdleSettings.
338*1f377076SVictor Perevertkin // WmiInstance->GetProvider();
3398a978a17SVictor Perevertkin
340*1f377076SVictor Perevertkin // //
341*1f377076SVictor Perevertkin // // Enable the WMI GUID by adding the instance back to the provider's
342*1f377076SVictor Perevertkin // // list. If there is an error, ignore it. It just means we were
343*1f377076SVictor Perevertkin // // racing with another thread removing or adding the instance.
344*1f377076SVictor Perevertkin // //
345*1f377076SVictor Perevertkin // (void) pProvider->AddInstance(
346*1f377076SVictor Perevertkin // m_PowerPolicyMachine.m_Owner->m_IdleSettings.WmiInstance,
347*1f377076SVictor Perevertkin // TRUE
348*1f377076SVictor Perevertkin // );
349*1f377076SVictor Perevertkin // }
350*1f377076SVictor Perevertkin // break;
3518a978a17SVictor Perevertkin
352*1f377076SVictor Perevertkin // case RemoveInstance:
353*1f377076SVictor Perevertkin // if (m_PowerPolicyMachine.m_Owner->m_IdleSettings.WmiInstance != NULL) {
354*1f377076SVictor Perevertkin // //
355*1f377076SVictor Perevertkin // // Disable the WMI guid by removing it from the provider's list of
356*1f377076SVictor Perevertkin // // instances.
357*1f377076SVictor Perevertkin // //
358*1f377076SVictor Perevertkin // pProvider = m_PowerPolicyMachine.m_Owner->m_IdleSettings.
359*1f377076SVictor Perevertkin // WmiInstance->GetProvider();
3608a978a17SVictor Perevertkin
361*1f377076SVictor Perevertkin // pProvider->RemoveInstance(
362*1f377076SVictor Perevertkin // m_PowerPolicyMachine.m_Owner->m_IdleSettings.WmiInstance
363*1f377076SVictor Perevertkin // );
364*1f377076SVictor Perevertkin // }
365*1f377076SVictor Perevertkin // break;
3668a978a17SVictor Perevertkin
367*1f377076SVictor Perevertkin // default:
368*1f377076SVictor Perevertkin // ASSERT(FALSE);
369*1f377076SVictor Perevertkin // break;
370*1f377076SVictor Perevertkin // }
3718a978a17SVictor Perevertkin
372*1f377076SVictor Perevertkin // return STATUS_SUCCESS;;
373*1f377076SVictor Perevertkin // }
3748a978a17SVictor Perevertkin
3758a978a17SVictor Perevertkin VOID
ReadRegistryS0Idle(__in PCUNICODE_STRING ValueName,__out BOOLEAN * Enabled)3768a978a17SVictor Perevertkin FxPkgPnp::ReadRegistryS0Idle(
3778a978a17SVictor Perevertkin __in PCUNICODE_STRING ValueName,
3788a978a17SVictor Perevertkin __out BOOLEAN *Enabled
3798a978a17SVictor Perevertkin )
3808a978a17SVictor Perevertkin {
3818a978a17SVictor Perevertkin NTSTATUS status;
3828a978a17SVictor Perevertkin FxAutoRegKey hKey;
3838a978a17SVictor Perevertkin
3848a978a17SVictor Perevertkin status = m_Device->OpenSettingsKey(&hKey.m_Key, STANDARD_RIGHTS_READ);
3858a978a17SVictor Perevertkin
3868a978a17SVictor Perevertkin //
3878a978a17SVictor Perevertkin // Modify the value of Enabled only if success
3888a978a17SVictor Perevertkin //
3898a978a17SVictor Perevertkin if (NT_SUCCESS(status)) {
3908a978a17SVictor Perevertkin ULONG value;
3918a978a17SVictor Perevertkin
3928a978a17SVictor Perevertkin status = FxRegKey::_QueryULong(
3938a978a17SVictor Perevertkin hKey.m_Key, ValueName, &value);
3948a978a17SVictor Perevertkin
3958a978a17SVictor Perevertkin if (NT_SUCCESS(status)) {
3968a978a17SVictor Perevertkin //
3978a978a17SVictor Perevertkin // Normalize the ULONG value into a BOOLEAN
3988a978a17SVictor Perevertkin //
3998a978a17SVictor Perevertkin *Enabled = (value == FALSE) ? FALSE : TRUE;
4008a978a17SVictor Perevertkin }
4018a978a17SVictor Perevertkin }
4028a978a17SVictor Perevertkin }
4038a978a17SVictor Perevertkin
404*1f377076SVictor Perevertkin // NTSTATUS __REACTOS__
405*1f377076SVictor Perevertkin // FxPkgPnp::UpdateWmiInstanceForSxWake(
406*1f377076SVictor Perevertkin // __in FxWmiInstanceAction Action
407*1f377076SVictor Perevertkin // )
408*1f377076SVictor Perevertkin // {
409*1f377076SVictor Perevertkin // FxWmiProvider* pProvider;
410*1f377076SVictor Perevertkin // NTSTATUS status;
4118a978a17SVictor Perevertkin
412*1f377076SVictor Perevertkin // switch(Action) {
413*1f377076SVictor Perevertkin // case AddInstance:
414*1f377076SVictor Perevertkin // if (m_PowerPolicyMachine.m_Owner->m_WakeSettings.WmiInstance == NULL) {
415*1f377076SVictor Perevertkin // FxWmiInstanceInternalCallbacks cb;
4168a978a17SVictor Perevertkin
417*1f377076SVictor Perevertkin // cb.SetInstance = _SxWakeSetInstance;
418*1f377076SVictor Perevertkin // cb.QueryInstance = _SxWakeQueryInstance;
419*1f377076SVictor Perevertkin // cb.SetItem = _SxWakeSetItem;
4208a978a17SVictor Perevertkin
421*1f377076SVictor Perevertkin // status = RegisterPowerPolicyWmiInstance(
422*1f377076SVictor Perevertkin // &GUID_POWER_DEVICE_WAKE_ENABLE,
423*1f377076SVictor Perevertkin // &cb,
424*1f377076SVictor Perevertkin // &m_PowerPolicyMachine.m_Owner->m_WakeSettings.WmiInstance);
4258a978a17SVictor Perevertkin
426*1f377076SVictor Perevertkin // if (!NT_SUCCESS(status)) {
427*1f377076SVictor Perevertkin // return status;
428*1f377076SVictor Perevertkin // }
429*1f377076SVictor Perevertkin // } else {
430*1f377076SVictor Perevertkin // pProvider = m_PowerPolicyMachine.m_Owner->m_WakeSettings.
431*1f377076SVictor Perevertkin // WmiInstance->GetProvider();
4328a978a17SVictor Perevertkin
433*1f377076SVictor Perevertkin // //
434*1f377076SVictor Perevertkin // // Enable the WMI GUID by adding the instance back to the provider's
435*1f377076SVictor Perevertkin // // list. If there is an error, ignore it. It just means we were
436*1f377076SVictor Perevertkin // // racing with another thread removing or adding the instance.
437*1f377076SVictor Perevertkin // //
438*1f377076SVictor Perevertkin // (void) pProvider->AddInstance(
439*1f377076SVictor Perevertkin // m_PowerPolicyMachine.m_Owner->m_WakeSettings.WmiInstance,
440*1f377076SVictor Perevertkin // TRUE
441*1f377076SVictor Perevertkin // );
442*1f377076SVictor Perevertkin // }
443*1f377076SVictor Perevertkin // break;
4448a978a17SVictor Perevertkin
445*1f377076SVictor Perevertkin // case RemoveInstance:
446*1f377076SVictor Perevertkin // if (m_PowerPolicyMachine.m_Owner->m_WakeSettings.WmiInstance != NULL) {
447*1f377076SVictor Perevertkin // //
448*1f377076SVictor Perevertkin // // Disable the WMI guid by removing it from the provider's list of
449*1f377076SVictor Perevertkin // // instances.
450*1f377076SVictor Perevertkin // //
451*1f377076SVictor Perevertkin // pProvider = m_PowerPolicyMachine.m_Owner->m_WakeSettings.
452*1f377076SVictor Perevertkin // WmiInstance->GetProvider();
4538a978a17SVictor Perevertkin
454*1f377076SVictor Perevertkin // pProvider->RemoveInstance(
455*1f377076SVictor Perevertkin // m_PowerPolicyMachine.m_Owner->m_WakeSettings.WmiInstance
456*1f377076SVictor Perevertkin // );
457*1f377076SVictor Perevertkin // }
458*1f377076SVictor Perevertkin // break;
4598a978a17SVictor Perevertkin
460*1f377076SVictor Perevertkin // default:
461*1f377076SVictor Perevertkin // ASSERT(FALSE);
462*1f377076SVictor Perevertkin // break;
463*1f377076SVictor Perevertkin // }
4648a978a17SVictor Perevertkin
465*1f377076SVictor Perevertkin // return STATUS_SUCCESS;
466*1f377076SVictor Perevertkin // }
4678a978a17SVictor Perevertkin
4688a978a17SVictor Perevertkin VOID
ReadRegistrySxWake(__in PCUNICODE_STRING ValueName,__out BOOLEAN * Enabled)4698a978a17SVictor Perevertkin FxPkgPnp::ReadRegistrySxWake(
4708a978a17SVictor Perevertkin __in PCUNICODE_STRING ValueName,
4718a978a17SVictor Perevertkin __out BOOLEAN *Enabled
4728a978a17SVictor Perevertkin )
4738a978a17SVictor Perevertkin {
4748a978a17SVictor Perevertkin FxAutoRegKey hKey;
4758a978a17SVictor Perevertkin NTSTATUS status;
4768a978a17SVictor Perevertkin
4778a978a17SVictor Perevertkin status = m_Device->OpenSettingsKey(&hKey.m_Key, STANDARD_RIGHTS_READ);
4788a978a17SVictor Perevertkin
4798a978a17SVictor Perevertkin //
4808a978a17SVictor Perevertkin // Modify the value of Enabled only if success
4818a978a17SVictor Perevertkin //
4828a978a17SVictor Perevertkin if (NT_SUCCESS(status)) {
4838a978a17SVictor Perevertkin ULONG value;
4848a978a17SVictor Perevertkin
4858a978a17SVictor Perevertkin status = FxRegKey::_QueryULong(
4868a978a17SVictor Perevertkin hKey.m_Key, ValueName, &value);
4878a978a17SVictor Perevertkin
4888a978a17SVictor Perevertkin if (NT_SUCCESS(status)) {
4898a978a17SVictor Perevertkin //
4908a978a17SVictor Perevertkin // Normalize the ULONG value into a BOOLEAN
4918a978a17SVictor Perevertkin //
4928a978a17SVictor Perevertkin *Enabled = (value == FALSE) ? FALSE : TRUE;
4938a978a17SVictor Perevertkin }
4948a978a17SVictor Perevertkin }
4958a978a17SVictor Perevertkin }
4968a978a17SVictor Perevertkin
4978a978a17SVictor Perevertkin VOID
PnpPassThroughQIWorker(__in MxDeviceObject * Device,__inout FxIrp * Irp,__inout FxIrp * ForwardIrp)4988a978a17SVictor Perevertkin PnpPassThroughQIWorker(
4998a978a17SVictor Perevertkin __in MxDeviceObject* Device,
5008a978a17SVictor Perevertkin __inout FxIrp* Irp,
5018a978a17SVictor Perevertkin __inout FxIrp* ForwardIrp
5028a978a17SVictor Perevertkin )
5038a978a17SVictor Perevertkin {
5048a978a17SVictor Perevertkin PIO_STACK_LOCATION pFwdStack, pCurStack;
5058a978a17SVictor Perevertkin
5068a978a17SVictor Perevertkin pCurStack = Irp->GetCurrentIrpStackLocation();
5078a978a17SVictor Perevertkin
5088a978a17SVictor Perevertkin ForwardIrp->SetStatus(STATUS_NOT_SUPPORTED);
5098a978a17SVictor Perevertkin
5108a978a17SVictor Perevertkin pFwdStack = ForwardIrp->GetNextIrpStackLocation();
5118a978a17SVictor Perevertkin pFwdStack->MajorFunction = Irp->GetMajorFunction();
5128a978a17SVictor Perevertkin pFwdStack->MinorFunction = Irp->GetMinorFunction();
5138a978a17SVictor Perevertkin
5148a978a17SVictor Perevertkin RtlCopyMemory(&pFwdStack->Parameters.QueryInterface,
5158a978a17SVictor Perevertkin &pCurStack->Parameters.QueryInterface,
5168a978a17SVictor Perevertkin sizeof(pFwdStack->Parameters.QueryInterface));
5178a978a17SVictor Perevertkin
5188a978a17SVictor Perevertkin ForwardIrp->SetInformation(Irp->GetInformation());
5198a978a17SVictor Perevertkin ForwardIrp->SendIrpSynchronously(Device->GetObject());
5208a978a17SVictor Perevertkin
5218a978a17SVictor Perevertkin pFwdStack = ForwardIrp->GetNextIrpStackLocation();
5228a978a17SVictor Perevertkin
5238a978a17SVictor Perevertkin RtlCopyMemory(&pCurStack->Parameters.QueryInterface,
5248a978a17SVictor Perevertkin &pFwdStack->Parameters.QueryInterface,
5258a978a17SVictor Perevertkin sizeof(pCurStack->Parameters.QueryInterface));
5268a978a17SVictor Perevertkin }
5278a978a17SVictor Perevertkin
5288a978a17SVictor Perevertkin VOID
RevokeDmaEnablerResources(__in FxDmaEnabler * DmaEnabler)5298a978a17SVictor Perevertkin FxPkgPnp::RevokeDmaEnablerResources(
5308a978a17SVictor Perevertkin __in FxDmaEnabler *DmaEnabler
5318a978a17SVictor Perevertkin )
5328a978a17SVictor Perevertkin {
533*1f377076SVictor Perevertkin // DmaEnabler->RevokeResources();
534*1f377076SVictor Perevertkin ROSWDFNOTIMPLEMENTED;
5358a978a17SVictor Perevertkin }
5368a978a17SVictor Perevertkin
5378a978a17SVictor Perevertkin VOID
QueryForD3ColdInterface(VOID)5388a978a17SVictor Perevertkin FxPkgPnp::QueryForD3ColdInterface(
5398a978a17SVictor Perevertkin VOID
5408a978a17SVictor Perevertkin )
5418a978a17SVictor Perevertkin {
5428a978a17SVictor Perevertkin MxDeviceObject deviceObject;
5438a978a17SVictor Perevertkin PDEVICE_OBJECT topOfStack;
5448a978a17SVictor Perevertkin PDEVICE_OBJECT pdo;
5458a978a17SVictor Perevertkin FxAutoIrp irp;
5468a978a17SVictor Perevertkin NTSTATUS status;
5478a978a17SVictor Perevertkin
5488a978a17SVictor Perevertkin //
5498a978a17SVictor Perevertkin // This function can be invoked multiple times, particularly if filters
5508a978a17SVictor Perevertkin // send IRP_MN_QUERY_CAPABILITIES. So bail out if the interface has already
5518a978a17SVictor Perevertkin // been acquired.
5528a978a17SVictor Perevertkin //
5538a978a17SVictor Perevertkin
5548a978a17SVictor Perevertkin if ((m_D3ColdInterface.InterfaceDereference != NULL) ||
5558a978a17SVictor Perevertkin (m_D3ColdInterface.GetIdleWakeInfo != NULL) ||
5568a978a17SVictor Perevertkin (m_D3ColdInterface.SetD3ColdSupport != NULL)) {
5578a978a17SVictor Perevertkin return;
5588a978a17SVictor Perevertkin }
5598a978a17SVictor Perevertkin
5608a978a17SVictor Perevertkin pdo = m_Device->GetPhysicalDevice();
5618a978a17SVictor Perevertkin
5628a978a17SVictor Perevertkin if (pdo == NULL) {
5638a978a17SVictor Perevertkin return;
5648a978a17SVictor Perevertkin }
5658a978a17SVictor Perevertkin
5668a978a17SVictor Perevertkin //
5678a978a17SVictor Perevertkin // Get the top of stack device object, even though normal filters and the
5688a978a17SVictor Perevertkin // FDO may not have been added to the stack yet to ensure that this
5698a978a17SVictor Perevertkin // query-interface is seen by bus filters. Specifically, in a PCI device
5708a978a17SVictor Perevertkin // which is soldered to the motherboard, ACPI will be on the stack and it
5718a978a17SVictor Perevertkin // needs to see this IRP.
5728a978a17SVictor Perevertkin //
5738a978a17SVictor Perevertkin topOfStack = IoGetAttachedDeviceReference(pdo);
5748a978a17SVictor Perevertkin deviceObject.SetObject(topOfStack);
5758a978a17SVictor Perevertkin if (deviceObject.GetObject() != NULL) {
5768a978a17SVictor Perevertkin irp.SetIrp(FxIrp::AllocateIrp(deviceObject.GetStackSize()));
5778a978a17SVictor Perevertkin if (irp.GetIrp() == NULL) {
5788a978a17SVictor Perevertkin
5798a978a17SVictor Perevertkin DoTraceLevelMessage(
5808a978a17SVictor Perevertkin GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
5818a978a17SVictor Perevertkin "Failed to allocate IRP to get D3COLD_SUPPORT_INTERFACE from !devobj %p",
5828a978a17SVictor Perevertkin pdo);
5838a978a17SVictor Perevertkin } else {
5848a978a17SVictor Perevertkin
5858a978a17SVictor Perevertkin //
5868a978a17SVictor Perevertkin // Initialize the Irp
5878a978a17SVictor Perevertkin //
5888a978a17SVictor Perevertkin irp.SetStatus(STATUS_NOT_SUPPORTED);
5898a978a17SVictor Perevertkin
5908a978a17SVictor Perevertkin irp.ClearNextStack();
5918a978a17SVictor Perevertkin irp.SetMajorFunction(IRP_MJ_PNP);
5928a978a17SVictor Perevertkin irp.SetMinorFunction(IRP_MN_QUERY_INTERFACE);
5938a978a17SVictor Perevertkin irp.SetParameterQueryInterfaceType(&GUID_D3COLD_SUPPORT_INTERFACE);
5948a978a17SVictor Perevertkin irp.SetParameterQueryInterfaceVersion(D3COLD_SUPPORT_INTERFACE_VERSION);
5958a978a17SVictor Perevertkin irp.SetParameterQueryInterfaceSize(sizeof(m_D3ColdInterface));
5968a978a17SVictor Perevertkin irp.SetParameterQueryInterfaceInterfaceSpecificData(NULL);
5978a978a17SVictor Perevertkin irp.SetParameterQueryInterfaceInterface((PINTERFACE)&m_D3ColdInterface);
5988a978a17SVictor Perevertkin
5998a978a17SVictor Perevertkin status = irp.SendIrpSynchronously(deviceObject.GetObject());
6008a978a17SVictor Perevertkin
6018a978a17SVictor Perevertkin if (!NT_SUCCESS(status)) {
6028a978a17SVictor Perevertkin DoTraceLevelMessage(
6038a978a17SVictor Perevertkin GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGPNP,
6048a978a17SVictor Perevertkin "!devobj %p declined to supply D3COLD_SUPPORT_INTERFACE",
6058a978a17SVictor Perevertkin pdo);
6068a978a17SVictor Perevertkin
6078a978a17SVictor Perevertkin RtlZeroMemory(&m_D3ColdInterface, sizeof(m_D3ColdInterface));
6088a978a17SVictor Perevertkin }
6098a978a17SVictor Perevertkin }
6108a978a17SVictor Perevertkin }
6118a978a17SVictor Perevertkin ObDereferenceObject(topOfStack);
6128a978a17SVictor Perevertkin }
6138a978a17SVictor Perevertkin
6148a978a17SVictor Perevertkin VOID
DropD3ColdInterface(VOID)6158a978a17SVictor Perevertkin FxPkgPnp::DropD3ColdInterface(
6168a978a17SVictor Perevertkin VOID
6178a978a17SVictor Perevertkin )
6188a978a17SVictor Perevertkin {
6198a978a17SVictor Perevertkin if (m_D3ColdInterface.InterfaceDereference != NULL) {
6208a978a17SVictor Perevertkin m_D3ColdInterface.InterfaceDereference(m_D3ColdInterface.Context);
6218a978a17SVictor Perevertkin }
6228a978a17SVictor Perevertkin
6238a978a17SVictor Perevertkin RtlZeroMemory(&m_D3ColdInterface, sizeof(m_D3ColdInterface));
6248a978a17SVictor Perevertkin }
6258a978a17SVictor Perevertkin
626