Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

pnpres.c File Reference

#include "iop.h"

Go to the source code of this file.

Classes

struct  _REQ_DESC
struct  _REQ_ALTERNATIVE
struct  _REQ_LIST
struct  _Counter
struct  _DUPLICATE_DETECTION_CONTEXT
struct  _IOP_POOL
struct  PNPRESDEBUGTRANSLATIONFAILURE

Defines

#define MYDBG   0
#define ExAllocatePoolAT(a, b)   ExAllocatePool(a,b)
#define ExAllocatePoolRD(a, b)   ExAllocatePool(a,b)
#define ExAllocatePoolCMRL(a, b)   ExAllocatePool(a,b)
#define ExAllocatePoolCMRR(a, b)   ExAllocatePool(a,b)
#define ExAllocatePoolAE(a, b)   ExAllocatePool(a,b)
#define ExAllocatePoolTE(a, b)   ExAllocatePool(a,b)
#define ExAllocatePoolPRD(a, b)   ExAllocatePool(a,b)
#define ExAllocatePoolIORD(a, b)   ExAllocatePool(a,b)
#define ExAllocatePool1RD(a, b)   ExAllocatePool(a,b)
#define ExAllocatePoolPDO(a, b)   ExAllocatePool(a,b)
#define ExAllocatePoolIORR(a, b)   ExAllocatePool(a,b)
#define ExAllocatePoolIORL(a, b)   ExAllocatePool(a,b)
#define ExAllocatePoolIORRR(a, b)   ExAllocatePool(a,b)
#define IS_TRANSLATED_REQ_DESC(r)   ((r)->ReqAlternative ? FALSE : TRUE)
#define IopReleaseBootResources(DeviceNode)
#define NextDeviceNode   Sibling
#define PreviousDeviceNode   Child
#define STRUCTURE_ALIGNMENT   1
#define IopInitPool(Pool,Start,Size)
#define IopAllocPoolAligned(Memory,Pool,Size)
#define IopAllocPool(Memory,Pool,Size)
#define FIND_BEST_ASSIGNMENT_TIMEOUT   5000
#define DUMP_ERROR   0x0001
#define DUMP_INFO   0x0002
#define DUMP_DETAIL   0x0004
#define STOP_ERROR   0x1000
#define DebugMessage(Level, Message)

Typedefs

typedef _REQ_DESC REQ_DESC * PREQ_DESC
typedef _REQ_ALTERNATIVE REQ_ALTERNATIVE * PREQ_ALTERNATIVE
typedef _REQ_LIST REQ_LIST * PREQ_LIST
typedef _Counter COUNTER
typedef _CounterPCOUNTER
typedef _DUPLICATE_DETECTION_CONTEXT DUPLICATE_DETECTION_CONTEXT
typedef _DUPLICATE_DETECTION_CONTEXTPDUPLICATE_DETECTION_CONTEXT
typedef _IOP_POOL IOP_POOL
typedef _IOP_POOLPIOP_POOL

Functions

PCM_RESOURCE_LIST IopCreateCmResourceList (IN PCM_RESOURCE_LIST ResourceList, IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber, OUT PCM_RESOURCE_LIST *RemainingList)
PCM_RESOURCE_LIST IopCombineCmResourceList (IN PCM_RESOURCE_LIST ResourceListA, IN PCM_RESOURCE_LIST ResourceListB)
VOID IopRemoveLegacyDeviceNode (IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PDEVICE_NODE LegacyDeviceNode)
NTSTATUS IopFindLegacyDeviceNode (IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT DeviceObject OPTIONAL, OUT PDEVICE_NODE *LegacyDeviceNode, OUT PDEVICE_OBJECT *LegacyPDO)
PDEVICE_NODE IopFindBusDeviceNodeInternal (IN PDEVICE_NODE DeviceNode, IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber)
NTSTATUS IopGetResourceRequirementsForAssignTable (IN PIOP_RESOURCE_REQUEST AssignTable, IN PIOP_RESOURCE_REQUEST AssignTableEnd, OUT PULONG DeviceCount)
NTSTATUS IopResourceRequirementsListToReqList (IN ARBITER_REQUEST_SOURCE AllocationType, IN PIO_RESOURCE_REQUIREMENTS_LIST IoResources, IN PDEVICE_OBJECT PhysicalDevice, OUT PVOID *ResReqList)
VOID IopRearrangeReqList (IN PREQ_LIST ReqList)
VOID IopRearrangeAssignTable (IN PIOP_RESOURCE_REQUEST AssignTable, IN ULONG Count)
int __cdecl IopComparePriority (const void *arg1, const void *arg2)
VOID IopFreeResourceRequirementsForAssignTable (IN PIOP_RESOURCE_REQUEST AssignTable, IN PIOP_RESOURCE_REQUEST AssignTableEnd)
VOID IopFreeReqAlternative (IN PREQ_ALTERNATIVE ReqAlternative)
VOID IopFreeReqList (IN PREQ_LIST ReqList)
NTSTATUS IopAssign (IN ULONG AssignTableCount, IN PIOP_RESOURCE_REQUEST AssignTable, IN BOOLEAN Rebalance)
VOID IopBuildCmResourceLists (IN PIOP_RESOURCE_REQUEST AssignTable, IN PIOP_RESOURCE_REQUEST AssignTableEnd)
VOID IopBuildCmResourceList (IN PIOP_RESOURCE_REQUEST AssignEntry)
NTSTATUS IopAssignInner (IN ULONG AssignTableCount, IN PIOP_RESOURCE_REQUEST AssignTable, IN BOOLEAN Rebalance)
NTSTATUS IopPlacement (IN ARBITER_ACTION ArbiterAction, IN BOOLEAN Rebalance)
VOID IopAddReqDescsToArbiters (IN ULONG ReqDescCount, IN PREQ_DESC *ReqDescTable)
VOID IopRemoveReqDescsFromArbiters (ULONG ReqDescCount, PREQ_DESC *ReqDescTable)
BOOLEAN IopIsBestConfiguration (IN VOID)
VOID IopSaveCurrentConfiguration (IN VOID)
VOID IopRestoreBestConfiguration (IN VOID)
BOOLEAN IopFindResourceHandlerInfo (IN RESOURCE_HANDLER_TYPE HandlerType, IN PDEVICE_NODE DeviceNode, IN UCHAR ResourceType, OUT PVOID *HandlerEntry)
NTSTATUS IopSetupArbiterAndTranslators (IN PREQ_DESC ReqDesc)
NTSTATUS IopParentToRawTranslation (IN OUT PREQ_DESC ReqDesc)
NTSTATUS IopChildToRootTranslation (IN PDEVICE_NODE DeviceNode, OPTIONAL IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber, IN ARBITER_REQUEST_SOURCE ArbiterRequestSource, IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source, OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR *Target)
NTSTATUS IopTranslateAndAdjustReqDesc (IN PREQ_DESC ReqDesc, IN PPI_RESOURCE_TRANSLATOR_ENTRY TranslatorEntry, OUT PREQ_DESC *TranslatedReqDesc)
NTSTATUS IopCallArbiter (PPI_RESOURCE_ARBITER_ENTRY ArbiterEntry, ARBITER_ACTION Command, PVOID Input1, PVOID Input2, PVOID Input3)
VOID IopQueryRebalance (IN PDEVICE_NODE DeviceNode, IN ULONG Phase, IN PULONG RebalanceCount, IN PDEVICE_OBJECT **DeviceTable)
VOID IopQueryRebalanceWorker (IN PDEVICE_NODE DeviceNode, IN ULONG RebalancePhase, IN PULONG RebalanceCount, IN PDEVICE_OBJECT **DeviceTable)
VOID IopTestForReconfiguration (IN PDEVICE_NODE DeviceNode, IN ULONG RebalancePhase, IN PULONG RebalanceCount, IN PDEVICE_OBJECT **DeviceTable)
NTSTATUS IopPlacementForRebalance (IN PDEVICE_NODE DeviceNode, IN ARBITER_ACTION ArbiterAction)
NTSTATUS IopArbitrateDeviceResources (IN PDEVICE_NODE DeviceNode, IN ARBITER_ACTION ArbiterAction)
NTSTATUS IopRebalance (IN ULONG AssignTableCont, IN PIOP_RESOURCE_REQUEST AssignTable)
NTSTATUS IopFindResourcesForArbiter (IN PDEVICE_NODE DeviceNode, IN UCHAR ResourceType, OUT ULONG *Count, OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR *CmDesc)
VOID IopReleaseResourcesInternal (IN PDEVICE_NODE DeviceNode)
VOID IopReleaseResources (IN PDEVICE_NODE DeviceNode)
NTSTATUS IopRestoreResourcesInternal (IN PDEVICE_NODE DeviceNode)
VOID IopSetLegacyDeviceInstance (IN PDRIVER_OBJECT DriverObject, IN PDEVICE_NODE DeviceNode)
PCM_RESOURCE_LIST IopCombineLegacyResources (IN PDEVICE_NODE DeviceNode)
NTSTATUS IopPlacementForReservation (VOID)
NTSTATUS IopReserve (IN PREQ_LIST ReqList)
NTSTATUS IopReserveBootResourcesInternal (IN ARBITER_REQUEST_SOURCE ArbiterRequestSource, IN PDEVICE_OBJECT DeviceObject, IN PCM_RESOURCE_LIST BootResources)
BOOLEAN IopNeedToReleaseBootResources (IN PDEVICE_NODE DeviceNode, IN PCM_RESOURCE_LIST AllocatedResources)
VOID IopReleaseFilteredBootResources (IN PIOP_RESOURCE_REQUEST AssignTable, IN PIOP_RESOURCE_REQUEST AssignTableEnd)
VOID IopDumpResourceRequirementsList (IN PIO_RESOURCE_REQUIREMENTS_LIST IoResources)
VOID IopDumpResourceDescriptor (IN PUCHAR Indent, IN PIO_RESOURCE_DESCRIPTOR Desc)
VOID IopCheckDataStructures (IN PDEVICE_NODE DeviceNode)
VOID IopCheckDataStructuresWorker (IN PDEVICE_NODE Device)
NTSTATUS IopQueryConflictListInternal (PDEVICE_OBJECT PhysicalDeviceObject, IN PCM_RESOURCE_LIST ResourceList, IN ULONG ResourceListSize, OUT PPLUGPLAY_CONTROL_CONFLICT_LIST ConflictList, IN ULONG ConflictListSize, IN ULONG Flags)
NTSTATUS IopQueryConflictFillConflicts (PDEVICE_OBJECT PhysicalDeviceObject, IN ULONG ConflictCount, IN PARBITER_CONFLICT_INFO ConflictInfoList, OUT PPLUGPLAY_CONTROL_CONFLICT_LIST ConflictList, IN ULONG ConflictListSize, IN ULONG Flags)
NTSTATUS IopQueryConflictFillString (IN PDEVICE_OBJECT DeviceObject, IN PWSTR Buffer, IN OUT PULONG Length, IN OUT PULONG Flags)
BOOLEAN IopEliminateBogusConflict (IN PDEVICE_OBJECT PhysicalDeviceObject, IN PDEVICE_OBJECT ConflictDeviceObject)
NTSTATUS IopAllocateResources (IN PULONG DeviceCountP, IN OUT PIOP_RESOURCE_REQUEST *AssignTablePP, IN BOOLEAN Locked, IN BOOLEAN BootConfigsOK)
int __cdecl IopCompareAlternativeCount (const void *arg1, const void *arg2)
NTSTATUS IopLegacyResourceAllocation (IN ARBITER_REQUEST_SOURCE AllocationType, IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements, IN OUT PCM_RESOURCE_LIST *AllocatedResources OPTIONAL)
PDEVICE_NODE IopFindBusDeviceNode (IN PDEVICE_NODE DeviceNode, IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber, IN ULONG SlotNumber)
NTSTATUS IopDuplicateDetection (IN INTERFACE_TYPE LegacyBusType, IN ULONG BusNumber, IN ULONG SlotNumber, OUT PDEVICE_NODE *DeviceNode)
NTSTATUS IopReserveLegacyBootResources (IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber)
NTSTATUS IopAllocateBootResources (IN ARBITER_REQUEST_SOURCE ArbiterRequestSource, IN PDEVICE_OBJECT DeviceObject, IN PCM_RESOURCE_LIST BootResources)
NTSTATUS IopReserveBootResources (IN ARBITER_REQUEST_SOURCE ArbiterRequestSource, IN PDEVICE_OBJECT DeviceObject, IN PCM_RESOURCE_LIST BootResources)
VOID IopReallocateResources (IN PDEVICE_OBJECT DeviceObject)
NTSTATUS IopQueryConflictList (PDEVICE_OBJECT PhysicalDeviceObject, IN PCM_RESOURCE_LIST ResourceList, IN ULONG ResourceListSize, OUT PPLUGPLAY_CONTROL_CONFLICT_LIST ConflictList, IN ULONG ConflictListSize, IN ULONG Flags)

Variables

LIST_ENTRY PiActiveArbiterList
LIST_ENTRY PiBestArbiterList
ULONG PiBestPriority
PIOP_RESOURCE_REQUEST PiAssignTable
ULONG PiAssignTableCount
PDEVICE_NODE IopLegacyDeviceNode
BOOLEAN PiNoRetest
BOOLEAN PiUseTimeout = TRUE
WCHAR IopWstrTranslated []
WCHAR IopWstrRaw []
ULONG PnpResDebugLevel = 0
ULONG PnpResDebugTranslationFailureCount = 32
PNPRESDEBUGTRANSLATIONFAILURE PnpResDebugTranslationFailureArray [32]
PNPRESDEBUGTRANSLATIONFAILUREPnpResDebugTranslationFailure = PnpResDebugTranslationFailureArray


Define Documentation

#define DebugMessage Level,
Message   ) 
 

Value:

if (PnpResDebugLevel & (Level)) { \ DbgPrint Message; \ }

Definition at line 275 of file pnpres.c.

Referenced by DrivesupDebugPrint(), IopAllocateBootResources(), IopAllocateResources(), IopArbitrateDeviceResources(), IopAssign(), IopAssignInner(), IopBuildCmResourceList(), IopBuildCmResourceLists(), IopFindBusDeviceNode(), IopFindLegacyDeviceNode(), IopFindResourcesForArbiter(), IopGetResourceRequirementsForAssignTable(), IopLegacyResourceAllocation(), IopParentToRawTranslation(), IopQueryConflictFillConflicts(), IopQueryConflictList(), IopQueryRebalanceWorker(), IopReallocateResources(), IopRearrangeReqList(), IopRebalance(), IopRemoveLegacyDeviceNode(), IopReserveLegacyBootResources(), IopResourceRequirementsListToReqList(), IopRestoreResourcesInternal(), IopSetupArbiterAndTranslators(), IopTestForReconfiguration(), and IopTranslateAndAdjustReqDesc().

#define DUMP_DETAIL   0x0004
 

Definition at line 269 of file pnpres.c.

Referenced by IopAssign(), IopAssignInner(), IopFindBusDeviceNode(), IopGetResourceRequirementsForAssignTable(), IopQueryConflictFillConflicts(), and IopRebalance().

#define DUMP_ERROR   0x0001
 

Definition at line 267 of file pnpres.c.

Referenced by IopAllocateBootResources(), IopAllocateResources(), IopArbitrateDeviceResources(), IopAssign(), IopBuildCmResourceList(), IopFindLegacyDeviceNode(), IopFindResourcesForArbiter(), IopLegacyResourceAllocation(), IopParentToRawTranslation(), IopQueryConflictList(), IopQueryRebalanceWorker(), IopReallocateResources(), IopRearrangeReqList(), IopRebalance(), IopRemoveLegacyDeviceNode(), IopResourceRequirementsListToReqList(), IopRestoreResourcesInternal(), IopSetupArbiterAndTranslators(), and IopTranslateAndAdjustReqDesc().

#define DUMP_INFO   0x0002
 

Definition at line 268 of file pnpres.c.

Referenced by IopAllocateResources(), IopBuildCmResourceLists(), IopFindLegacyDeviceNode(), IopGetResourceRequirementsForAssignTable(), IopRebalance(), IopReserveLegacyBootResources(), IopResourceRequirementsListToReqList(), IopSetupArbiterAndTranslators(), and IopTestForReconfiguration().

#define ExAllocatePool1RD a,
 )     ExAllocatePool(a,b)
 

Definition at line 68 of file pnpres.c.

Referenced by IopTranslateAndAdjustReqDesc().

#define ExAllocatePoolAE a,
 )     ExAllocatePool(a,b)
 

Definition at line 64 of file pnpres.c.

Referenced by IopSetupArbiterAndTranslators().

#define ExAllocatePoolAT a,
 )     ExAllocatePool(a,b)
 

Definition at line 60 of file pnpres.c.

Referenced by IopAllocateResources().

#define ExAllocatePoolCMRL a,
 )     ExAllocatePool(a,b)
 

Definition at line 62 of file pnpres.c.

Referenced by IopBuildCmResourceList(), and IopCombineLegacyResources().

#define ExAllocatePoolCMRR a,
 )     ExAllocatePool(a,b)
 

Definition at line 63 of file pnpres.c.

Referenced by IopBuildCmResourceList().

#define ExAllocatePoolIORD a,
 )     ExAllocatePool(a,b)
 

Definition at line 67 of file pnpres.c.

Referenced by IopTranslateAndAdjustReqDesc().

#define ExAllocatePoolIORL a,
 )     ExAllocatePool(a,b)
 

Definition at line 71 of file pnpres.c.

Referenced by IopLegacyResourceAllocation(), IopReserveBootResources(), and IopReserveBootResourcesInternal().

#define ExAllocatePoolIORR a,
 )     ExAllocatePool(a,b)
 

Definition at line 70 of file pnpres.c.

Referenced by IopRebalance().

#define ExAllocatePoolIORRR a,
 )     ExAllocatePool(a,b)
 

Definition at line 72 of file pnpres.c.

Referenced by IopCombineCmResourceList(), IopCreateCmResourceList(), and IopReserveBootResources().

#define ExAllocatePoolPDO a,
 )     ExAllocatePool(a,b)
 

Definition at line 69 of file pnpres.c.

Referenced by IopQueryRebalance(), and IopRebalance().

#define ExAllocatePoolPRD a,
 )     ExAllocatePool(a,b)
 

Definition at line 66 of file pnpres.c.

Referenced by IopChildToRootTranslation(), and IopFindResourcesForArbiter().

#define ExAllocatePoolRD a,
 )     ExAllocatePool(a,b)
 

Definition at line 61 of file pnpres.c.

Referenced by IopResourceRequirementsListToReqList().

#define ExAllocatePoolTE a,
 )     ExAllocatePool(a,b)
 

Definition at line 65 of file pnpres.c.

Referenced by IopSetupArbiterAndTranslators().

#define FIND_BEST_ASSIGNMENT_TIMEOUT   5000
 

Definition at line 252 of file pnpres.c.

Referenced by IopAssign().

#define IopAllocPool Memory,
Pool,
Size   ) 
 

Value:

*(Memory) = (PVOID) (Pool)->PoolStart; \ (Pool)->PoolStart += (Size); \ ASSERT((Pool)->PoolStart <= (Pool)->PoolEnd);

Definition at line 225 of file pnpres.c.

Referenced by IopResourceRequirementsListToReqList().

#define IopAllocPoolAligned Memory,
Pool,
Size   ) 
 

Value:

(Pool)->PoolStart = (PUCHAR) \ (((ULONG_PTR) (Pool)->PoolStart + STRUCTURE_ALIGNMENT - 1) \ & ~(STRUCTURE_ALIGNMENT - 1)); \ IopAllocPool(Memory, Pool, Size);

Definition at line 215 of file pnpres.c.

Referenced by IopResourceRequirementsListToReqList().

#define IopInitPool Pool,
Start,
Size   ) 
 

Value:

{ \ (Pool)->PoolStart = (Start); \ (Pool)->PoolEnd = (Start) + (Size); \ (Pool)->PoolSize = (Size); \ RtlZeroMemory(Start, Size); \ }

Definition at line 203 of file pnpres.c.

Referenced by IopResourceRequirementsListToReqList().

#define IopReleaseBootResources DeviceNode   ) 
 

Value:

ASSERT(((DeviceNode)->Flags & DNF_MADEUP) == 0); \ IopReleaseResourcesInternal(DeviceNode); \ (DeviceNode)->Flags &= ~DNF_HAS_BOOT_CONFIG; \ (DeviceNode)->Flags &= ~DNF_BOOT_CONFIG_RESERVED; \ if ((DeviceNode)->BootResources) { \ ExFreePool((DeviceNode)->BootResources); \ (DeviceNode)->BootResources = NULL; \ }

Definition at line 157 of file pnpres.c.

Referenced by IopTestForReconfiguration().

#define IS_TRANSLATED_REQ_DESC  )     ((r)->ReqAlternative ? FALSE : TRUE)
 

Definition at line 151 of file pnpres.c.

Referenced by IopFreeReqAlternative(), and IopParentToRawTranslation().

#define MYDBG   0
 

Definition at line 38 of file pnpres.c.

#define NextDeviceNode   Sibling
 

Definition at line 180 of file pnpres.c.

#define PreviousDeviceNode   Child
 

Definition at line 181 of file pnpres.c.

#define STOP_ERROR   0x1000
 

Definition at line 270 of file pnpres.c.

Referenced by IopAssignInner(), IopChildToRootTranslation(), IopQueryConflictListInternal(), IopRebalance(), and IopReserve().

#define STRUCTURE_ALIGNMENT   1
 

Definition at line 187 of file pnpres.c.

Referenced by IopResourceRequirementsListToReqList().


Typedef Documentation

typedef struct _Counter COUNTER
 

typedef struct _DUPLICATE_DETECTION_CONTEXT DUPLICATE_DETECTION_CONTEXT
 

typedef struct _IOP_POOL IOP_POOL
 

typedef struct _Counter * PCOUNTER
 

typedef struct _DUPLICATE_DETECTION_CONTEXT * PDUPLICATE_DETECTION_CONTEXT
 

typedef struct _IOP_POOL * PIOP_POOL
 

typedef struct _REQ_ALTERNATIVE REQ_ALTERNATIVE* PREQ_ALTERNATIVE
 

Definition at line 81 of file pnpres.c.

Referenced by IopAssign(), IopBuildCmResourceList(), IopComparePriority(), IopFindResourcesForArbiter(), IopIsBestConfiguration(), IopQueryConflictListInternal(), IopRearrangeReqList(), IopReserve(), IopResourceRequirementsListToReqList(), IopRestoreBestConfiguration(), and IopSaveCurrentConfiguration().

typedef struct _REQ_DESC REQ_DESC* PREQ_DESC
 

Definition at line 79 of file pnpres.c.

Referenced by IopAddReqDescsToArbiters(), IopBuildCmResourceList(), IopCallArbiter(), IopFindResourcesForArbiter(), IopFreeReqAlternative(), IopParentToRawTranslation(), IopQueryConflictListInternal(), IopRemoveReqDescsFromArbiters(), IopResourceRequirementsListToReqList(), IopRestoreBestConfiguration(), IopSaveCurrentConfiguration(), IopSetupArbiterAndTranslators(), and IopTranslateAndAdjustReqDesc().

typedef struct _REQ_LIST REQ_LIST* PREQ_LIST
 

Definition at line 83 of file pnpres.c.

Referenced by IopAssign(), IopBuildCmResourceList(), IopFindResourcesForArbiter(), IopGetResourceRequirementsForAssignTable(), IopIsBestConfiguration(), IopQueryConflictListInternal(), IopReserveBootResourcesInternal(), IopResourceRequirementsListToReqList(), IopRestoreBestConfiguration(), IopRestoreResourcesInternal(), and IopSaveCurrentConfiguration().


Function Documentation

VOID IopAddReqDescsToArbiters IN ULONG  ReqDescCount,
IN PREQ_DESC ReqDescTable
 

Definition at line 2716 of file pnpres.c.

References _PI_RESOURCE_ARBITER_ENTRY::ActiveArbiterList, ArbiterActionRollbackAllocation, ASSERT, IopCallArbiter(), NULL, PI_ARBITER_HAS_SOMETHING, PiActiveArbiterList, PREQ_DESC, _PI_RESOURCE_ARBITER_ENTRY::ResourceList, _PI_RESOURCE_ARBITER_ENTRY::ResourcesChanged, _PI_RESOURCE_ARBITER_ENTRY::State, _REQ_DESC::TranslatedReqDesc, and TRUE.

Referenced by IopAssign(), and IopReserve().

02723 : 02724 02725 This routine adds a list of a req descriptors to their arbiters. 02726 02727 Parameters: 02728 02729 P1 - 02730 02731 Return Value: 02732 02733 None. 02734 02735 --*/ 02736 { 02737 PREQ_DESC reqDesc; 02738 PREQ_DESC reqDescTranslated; 02739 PLIST_ENTRY listHead; 02740 PPI_RESOURCE_ARBITER_ENTRY arbiterEntry; 02741 PREQ_DESC *reqDescTableEnd; 02742 02743 for (reqDescTableEnd = ReqDescTable + ReqDescCount; ReqDescTable < reqDescTableEnd; ReqDescTable++) { 02744 02745 // 02746 // For each req desc, find its arbiter, link the translated req desc to its arbiter. 02747 // 02748 02749 reqDesc = *ReqDescTable; 02750 if (reqDesc->ArbitrationRequired) { 02751 02752 reqDescTranslated = reqDesc->TranslatedReqDesc; // Could be reqDesc itself 02753 02754 InitializeListHead(&reqDescTranslated->AlternativeTable.ListEntry); 02755 arbiterEntry = reqDesc->u.Arbiter; 02756 ASSERT(arbiterEntry); 02757 listHead = &arbiterEntry->ResourceList; 02758 InsertTailList(listHead, &reqDescTranslated->AlternativeTable.ListEntry); 02759 02760 arbiterEntry->ResourcesChanged = TRUE; 02761 if (arbiterEntry->State & PI_ARBITER_HAS_SOMETHING) { 02762 02763 IopCallArbiter(arbiterEntry, ArbiterActionRollbackAllocation, NULL, NULL, NULL); 02764 arbiterEntry->State &= ~PI_ARBITER_HAS_SOMETHING; 02765 } 02766 02767 // 02768 // Link the arbiter entry to our active arbiter list if it has not been 02769 // 02770 02771 if (IsListEmpty(&arbiterEntry->ActiveArbiterList)) { 02772 02773 InsertTailList(&PiActiveArbiterList, &arbiterEntry->ActiveArbiterList); 02774 } 02775 } 02776 } 02777 }

NTSTATUS IopAllocateBootResources IN ARBITER_REQUEST_SOURCE  ArbiterRequestSource,
IN PDEVICE_OBJECT  DeviceObject,
IN PCM_RESOURCE_LIST  BootResources
 

Definition at line 7141 of file pnpres.c.

References DebugMessage, DelayExecution, DUMP_ERROR, FALSE, IopRegistrySemaphore, IopReserveBootResourcesInternal(), KeEnterCriticalRegion, KeLeaveCriticalRegion, KeReleaseSemaphore(), KernelMode, KeWaitForSingleObject(), NT_SUCCESS, NTSTATUS(), NULL, and PAGED_CODE.

Referenced by IopInitializeBootDrivers(), IopReserveBootResources(), and IopReserveLegacyBootResources().

07149 : 07150 07151 This routine reports boot resources for the specified device to 07152 arbiters. 07153 07154 Arguments: 07155 07156 DeviceObject - Supplies a pointer to the device object, could be NULL 07157 if DeviceObject is NULL, the BootResources are reserved and will not be given 07158 to a device unless there is no other choice. The caller must release the 07159 pool for BootResources. 07160 if DeviceObject is NON_NULL, BootResources are BOOT reserved (preallocated.) 07161 07162 BootResources - Supplies a pointer to the Boot resources. 07163 07164 Return Value: 07165 07166 None. 07167 07168 --*/ 07169 { 07170 NTSTATUS status; 07171 07172 PAGED_CODE(); 07173 07174 KeEnterCriticalRegion( ); 07175 07176 status = KeWaitForSingleObject( &IopRegistrySemaphore, 07177 DelayExecution, 07178 KernelMode, 07179 FALSE, 07180 NULL ); 07181 07182 if (NT_SUCCESS(status)) { 07183 07184 status = IopReserveBootResourcesInternal(ArbiterRequestSource, DeviceObject, BootResources); 07185 KeReleaseSemaphore(&IopRegistrySemaphore, 0, 1, FALSE); 07186 07187 } else { 07188 07189 DebugMessage(DUMP_ERROR, ("IopReserveBootResources: Get RegustrySemaphore failed. Status %x\n", status)); 07190 } 07191 07192 KeLeaveCriticalRegion(); 07193 07194 return status; 07195 }

NTSTATUS IopAllocateResources IN PULONG  DeviceCountP,
IN OUT PIOP_RESOURCE_REQUEST AssignTablePP,
IN BOOLEAN  Locked,
IN BOOLEAN  BootConfigsOK
 

Definition at line 720 of file pnpres.c.

References _IOP_RESOURCE_REQUEST::AllocationType, ArbiterRequestPnpDetected, ArbiterRequestPnpEnumerated, ASSERT, DebugMessage, DelayExecution, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, DNF_HAS_BOOT_CONFIG, DNF_NEEDS_REBALANCE, DUMP_ERROR, DUMP_INFO, ExAllocatePoolAT, ExFreePool(), FALSE, _DEVICE_NODE::Flags, _IOP_RESOURCE_REQUEST::Flags, _DEVICE_NODE::InstancePath, IOP_ASSIGN_EXCLUDE, IOP_ASSIGN_IGNORE, IOP_ASSIGN_NO_REBALANCE, IOP_ASSIGN_RETRY, IopAssignInner(), IopBootConfigsReserved, IopBuildCmResourceLists(), IopFreeResourceRequirementsForAssignTable(), IopGetResourceRequirementsForAssignTable(), IopRearrangeAssignTable(), IopRebalance(), IopRegistrySemaphore, IopReleaseFilteredBootResources(), KeEnterCriticalRegion, KeLeaveCriticalRegion, KeReleaseSemaphore(), KernelMode, KeWaitForSingleObject(), NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, _IOP_RESOURCE_REQUEST::PhysicalDevice, _IOP_RESOURCE_REQUEST::ResourceAssignment, _IOP_RESOURCE_REQUEST::ResourceRequirements, _IOP_RESOURCE_REQUEST::Status, Status, and TRUE.

Referenced by IopAssignResourcesToDevices(), and IopLegacyResourceAllocation().

00729 : 00730 00731 For each AssignTable entry, this routine queries device's IO resource requirements 00732 list and converts it to our internal REQ_LIST format; calls worker routine to perform 00733 the resources assignment. 00734 00735 Parameters: 00736 00737 AssignTable - supplies a pointer to the first entry of a IOP_RESOURCE_REQUEST table. 00738 00739 AssignTableEnd - supplies a pointer to the end of IOP_RESOURCE_REQUEST table. 00740 00741 Locked - Indicates whether the IopRegistrySemaphore is acquired by the caller. 00742 00743 BootConfigsOK - Indicates whether we should assign BOOT configs. 00744 00745 Return Value: 00746 00747 Status code that indicates whether or not the function was successful. 00748 00749 --*/ 00750 00751 { 00752 PIOP_RESOURCE_REQUEST AssignTable; 00753 PIOP_RESOURCE_REQUEST AssignTableEnd; 00754 PIOP_RESOURCE_REQUEST AssignTableTail; 00755 PIOP_RESOURCE_REQUEST AssignEntry; 00756 PIOP_RESOURCE_REQUEST AssignEntryOriginal; 00757 ULONG AssignTableCount; 00758 ULONG DeviceCount; 00759 NTSTATUS Status; 00760 BOOLEAN FreeAssignTable; 00761 BOOLEAN tryRebalance; 00762 00763 PAGED_CODE(); 00764 00765 DeviceCount = *DeviceCountP; 00766 FreeAssignTable = FALSE; 00767 tryRebalance = TRUE; 00768 AssignTable = *AssignTablePP; 00769 AssignTableEnd = AssignTable + DeviceCount; 00770 00771 // 00772 // If legacy device resource allocation, don't rebalance on failure, 00773 // if the resource they want is already assigned, what they are looking 00774 // for isn't there. 00775 // 00776 00777 if ((DeviceCount == 1) && (AssignTable->Flags & IOP_ASSIGN_NO_REBALANCE)) { 00778 00779 tryRebalance = FALSE; 00780 00781 } 00782 00783 // 00784 // Grab the IO registry semaphore to make sure no other device is 00785 // reporting it's resource usage while we are searching for conflicts. 00786 // 00787 00788 if (!Locked) { 00789 00790 KeEnterCriticalRegion(); 00791 00792 Status = KeWaitForSingleObject( &IopRegistrySemaphore, 00793 DelayExecution, 00794 KernelMode, 00795 FALSE, 00796 NULL ); 00797 00798 if (!NT_SUCCESS(Status)) { 00799 00800 DebugMessage(DUMP_ERROR, ("IopAllocateResources: Get RegistrySemaphore failed. Status %x\n", Status)); 00801 KeLeaveCriticalRegion(); 00802 return Status; 00803 00804 } 00805 } 00806 00807 // 00808 // Get the resource requirements. 00809 // 00810 00811 Status = IopGetResourceRequirementsForAssignTable(AssignTable, AssignTableEnd, &DeviceCount); 00812 if (DeviceCount == 0) { 00813 00814 DebugMessage(DUMP_INFO, ("IopAllocateResources: Get Requirements for Assign Table found nothing. status %x\n", Status)); 00815 00816 if (!Locked) { 00817 00818 KeReleaseSemaphore(&IopRegistrySemaphore, 0, 1, FALSE); 00819 KeLeaveCriticalRegion(); 00820 00821 } 00822 00823 return Status; 00824 00825 } 00826 00827 // 00828 // Check if it is OK to assign resources to devices with BOOT configs. 00829 // 00830 00831 if (BootConfigsOK) { 00832 00833 if (!IopBootConfigsReserved) { 00834 00835 // 00836 // Process devices with BOOT configs or no requirements first. 00837 // 00838 00839 for (AssignEntry = AssignTable; AssignEntry < AssignTableEnd; AssignEntry++) { 00840 00841 PDEVICE_NODE deviceNode = (PDEVICE_NODE)AssignEntry->PhysicalDevice->DeviceObjectExtension->DeviceNode; 00842 00843 if (deviceNode->Flags & DNF_HAS_BOOT_CONFIG) { 00844 00845 break; 00846 } 00847 } 00848 00849 if (AssignEntry != AssignTableEnd) { 00850 00851 // 00852 // There are devices with BOOT config. 00853 // 00854 00855 for (AssignEntry = AssignTable; AssignEntry < AssignTableEnd; AssignEntry++) { 00856 00857 PDEVICE_NODE deviceNode = (PDEVICE_NODE)AssignEntry->PhysicalDevice->DeviceObjectExtension->DeviceNode; 00858 00859 if ( !(AssignEntry->Flags & IOP_ASSIGN_IGNORE) && 00860 !(deviceNode->Flags & DNF_HAS_BOOT_CONFIG) && 00861 AssignEntry->ResourceRequirements && 00862 AssignEntry->AllocationType != ArbiterRequestPnpDetected) { 00863 00864 DeviceCount--; 00865 DebugMessage(DUMP_INFO, ("Delaying non BOOT config device %ws...\n", deviceNode->InstancePath.Buffer)); 00866 AssignEntry->Status = STATUS_RETRY; 00867 AssignEntry->Flags |= IOP_ASSIGN_IGNORE; 00868 IopFreeResourceRequirementsForAssignTable(AssignEntry, AssignEntry + 1); 00869 00870 } 00871 } 00872 } 00873 00874 if (DeviceCount == 0) { 00875 00876 if (!Locked) { 00877 00878 KeReleaseSemaphore(&IopRegistrySemaphore, 0, 1, FALSE); 00879 KeLeaveCriticalRegion(); 00880 00881 } 00882 00883 return Status; 00884 } 00885 } 00886 00887 // 00888 // Check if we need to allocate a new table. 00889 // 00890 00891 if (DeviceCount != *DeviceCountP) { 00892 00893 // 00894 // Allocate a new table. 00895 // 00896 00897 AssignTable = (PIOP_RESOURCE_REQUEST) ExAllocatePoolAT( PagedPool, 00898 sizeof(IOP_RESOURCE_REQUEST) * DeviceCount); 00899 if (AssignTable == NULL) { 00900 00901 IopFreeResourceRequirementsForAssignTable(*AssignTablePP, AssignTableEnd); 00902 00903 if (!Locked) { 00904 00905 KeReleaseSemaphore(&IopRegistrySemaphore, 0, 1, FALSE); 00906 KeLeaveCriticalRegion(); 00907 00908 } 00909 00910 return STATUS_INSUFFICIENT_RESOURCES; 00911 } 00912 00913 FreeAssignTable = TRUE; 00914 00915 // 00916 // Process the AssignTable to remove any entry which is marked as IOP_ASSIGN_IGNORE. 00917 // 00918 00919 AssignEntryOriginal = *AssignTablePP; 00920 AssignTableEnd = AssignTable + DeviceCount; 00921 for (AssignEntry = AssignTable; AssignEntry < AssignTableEnd;) { 00922 00923 if (!(AssignEntryOriginal->Flags & IOP_ASSIGN_IGNORE)) { 00924 00925 *AssignEntry = *AssignEntryOriginal; 00926 AssignEntry++; 00927 00928 } 00929 AssignEntryOriginal++; 00930 } 00931 } 00932 00933 } else { 00934 00935 // 00936 // Only process devices with no resource requirements. Rest get STATUS_RETRY. 00937 // 00938 00939 for (AssignEntry = AssignTable; AssignEntry < AssignTableEnd; AssignEntry++) { 00940 00941 if ( !(AssignEntry->Flags & IOP_ASSIGN_IGNORE) && 00942 AssignEntry->ResourceRequirements) { 00943 00944 PDEVICE_NODE deviceNode = (PDEVICE_NODE)AssignEntry->PhysicalDevice->DeviceObjectExtension->DeviceNode; 00945 00946 DebugMessage(DUMP_INFO, ("Delaying resources requiring device %ws...\n", deviceNode->InstancePath.Buffer)); 00947 IopFreeResourceRequirementsForAssignTable(AssignEntry, AssignEntry + 1); 00948 AssignEntry->Status = STATUS_RETRY; 00949 00950 } 00951 } 00952 00953 // 00954 // Release the I/O Registry Semaphore 00955 // 00956 00957 if (!Locked) { 00958 00959 KeReleaseSemaphore(&IopRegistrySemaphore, 0, 1, FALSE); 00960 KeLeaveCriticalRegion(); 00961 00962 } 00963 00964 return Status; 00965 } 00966 AssignTableCount = (ULONG)(AssignTableEnd - AssignTable); 00967 ASSERT(AssignTableCount == DeviceCount); 00968 00969 // 00970 // Sort the AssignTable 00971 // 00972 00973 IopRearrangeAssignTable(AssignTable, DeviceCount); 00974 00975 for (AssignEntry = AssignTable; AssignEntry < AssignTableEnd; AssignEntry++) { 00976 00977 PDEVICE_NODE deviceNode = (PDEVICE_NODE)AssignEntry->PhysicalDevice->DeviceObjectExtension->DeviceNode; 00978 00979 DebugMessage(DUMP_INFO, ("Pnpres: Trying to allocate resources for %ws.\n", deviceNode->InstancePath.Buffer)); 00980 00981 Status = IopAssignInner(1, AssignEntry, FALSE); 00982 if (NT_SUCCESS(Status)) { 00983 00984 IopBuildCmResourceLists(AssignEntry, AssignEntry + 1); 00985 if (AssignEntry->AllocationType == ArbiterRequestPnpEnumerated) { 00986 00987 IopReleaseFilteredBootResources(AssignEntry, AssignEntry + 1); 00988 } 00989 } else if (Status == STATUS_INSUFFICIENT_RESOURCES) { 00990 00991 DebugMessage(DUMP_ERROR, ("IopAllocateResource: Failed to allocate Pool.\n")); 00992 break; 00993 00994 } else if (tryRebalance) { 00995 00996 DebugMessage(DUMP_INFO, ("IopAllocateResources: Initiating REBALANCE...\n")); 00997 00998 deviceNode->Flags |= DNF_NEEDS_REBALANCE; 00999 Status = IopRebalance(1, AssignEntry); 01000 deviceNode->Flags &= ~DNF_NEEDS_REBALANCE; 01001 if (!NT_SUCCESS(Status)) { 01002 AssignEntry->Status = STATUS_CONFLICTING_ADDRESSES; 01003 } 01004 } else { 01005 AssignEntry->Status = STATUS_CONFLICTING_ADDRESSES; 01006 } 01007 } 01008 01009 // 01010 // IF we did not go through the entire table without any error, 01011 // mark remaining entries as RETRY. 01012 // 01013 01014 for (; AssignEntry < AssignTableEnd; AssignEntry++) { 01015 01016 AssignEntry->Status = STATUS_RETRY; 01017 } 01018 01019 IopFreeResourceRequirementsForAssignTable(AssignTable, AssignTableEnd); 01020 01021 // 01022 // Release the I/O Registry Semaphore 01023 // 01024 01025 if (!Locked) { 01026 KeReleaseSemaphore( &IopRegistrySemaphore, 0, 1, FALSE ); 01027 KeLeaveCriticalRegion( ); 01028 } 01029 01030 // 01031 // Copy the information in our own AssignTable to caller's AssignTable 01032 // 01033 01034 if (FreeAssignTable) { 01035 AssignEntryOriginal = *AssignTablePP; 01036 for (AssignEntry = AssignTable; AssignEntry < AssignTableEnd;) { 01037 if (AssignEntryOriginal->Flags & (IOP_ASSIGN_IGNORE | IOP_ASSIGN_RETRY)) { 01038 AssignEntryOriginal++; 01039 continue; 01040 } 01041 *AssignEntryOriginal = *AssignEntry; 01042 AssignEntry++; 01043 AssignEntryOriginal++; 01044 } 01045 ASSERT(AssignEntryOriginal <= *AssignTablePP + *DeviceCountP); 01046 ExFreePool(AssignTable); 01047 } 01048 01049 AssignEntry = *AssignTablePP; 01050 while (AssignEntry < *AssignTablePP + *DeviceCountP) { 01051 if (AssignEntry->Flags & (IOP_ASSIGN_IGNORE | IOP_ASSIGN_RETRY)) { 01052 AssignEntry++; 01053 continue; 01054 } 01055 if ((AssignEntry->Flags & IOP_ASSIGN_EXCLUDE) || AssignEntry->ResourceAssignment == NULL) { 01056 01057 AssignEntry->Status = STATUS_CONFLICTING_ADDRESSES; 01058 } 01059 AssignEntry++; 01060 } 01061 01062 return Status; 01063 }

NTSTATUS IopArbitrateDeviceResources IN PDEVICE_NODE  DeviceNode,
IN ARBITER_ACTION  ArbiterAction
 

Definition at line 5016 of file pnpres.c.

References _PI_RESOURCE_ARBITER_ENTRY::ActiveArbiterList, ArbiterActionCommitAllocation, ArbiterActionRetestAllocation, ArbiterActionTestAllocation, ASSERT, _PI_RESOURCE_ARBITER_ENTRY::BestConfig, _PI_RESOURCE_ARBITER_ENTRY::BestResourceList, DebugMessage, DUMP_ERROR, ExFreePool(), FALSE, IopCallArbiter(), IopFindResourcesForArbiter(), NT_SUCCESS, NTSTATUS(), NULL, PI_ARBITER_HAS_SOMETHING, PI_ARBITER_TEST_FAILED, _PI_RESOURCE_ARBITER_ENTRY::ResourceList, _PI_RESOURCE_ARBITER_ENTRY::ResourcesChanged, _PI_RESOURCE_ARBITER_ENTRY::ResourceType, and _PI_RESOURCE_ARBITER_ENTRY::State.

Referenced by IopPlacementForRebalance().

05023 : 05024 05025 This routine 05026 05027 Parameters: 05028 05029 P1 - 05030 05031 Return Value: 05032 05033 Status code that indicates whether or not the function was successful. 05034 05035 --*/ 05036 05037 { 05038 PLIST_ENTRY listEntry, listHead; 05039 PPI_RESOURCE_ARBITER_ENTRY arbiterEntry; 05040 ULONG count = 0; 05041 PCM_PARTIAL_RESOURCE_DESCRIPTOR cmDesc = NULL; 05042 NTSTATUS status; 05043 05044 ASSERT((ArbiterAction == ArbiterActionTestAllocation) || 05045 (ArbiterAction == ArbiterActionRetestAllocation) || 05046 (ArbiterAction == ArbiterActionCommitAllocation)); 05047 05048 05049 listHead = &DeviceNode->DeviceArbiterList; 05050 listEntry = listHead->Flink; 05051 while (listEntry != listHead) { 05052 arbiterEntry = CONTAINING_RECORD(listEntry, PI_RESOURCE_ARBITER_ENTRY, DeviceArbiterList); 05053 listEntry = listEntry->Flink; 05054 if (IsListEmpty(&arbiterEntry->ResourceList) == FALSE) { 05055 05056 if (ArbiterAction == ArbiterActionCommitAllocation) { 05057 05058 status = IopCallArbiter(arbiterEntry, ArbiterActionCommitAllocation, NULL, NULL, NULL); 05059 ASSERT(status == STATUS_SUCCESS); 05060 arbiterEntry->State = 0; 05061 InitializeListHead(&arbiterEntry->ActiveArbiterList); 05062 InitializeListHead(&arbiterEntry->BestConfig); 05063 InitializeListHead(&arbiterEntry->ResourceList); 05064 InitializeListHead(&arbiterEntry->BestResourceList); 05065 05066 } else if (arbiterEntry->ResourcesChanged == FALSE) { 05067 05068 // 05069 // If the resource requirements are the same and it failed before, we know it 05070 // won't be able to succeed. So, return failure. 05071 // 05072 05073 if (arbiterEntry->State & PI_ARBITER_TEST_FAILED) { 05074 return STATUS_UNSUCCESSFUL; 05075 } 05076 } else { 05077 05078 05079 // 05080 // If the resource requirements are changed, we need to call arbiter to test it. 05081 // First find out what resources *could* be owned by the arbiter. 05082 // And then call the Arbiter to try to satisfy the request from the resources 05083 // it *could* have. 05084 05085 status = IopFindResourcesForArbiter( 05086 DeviceNode, 05087 arbiterEntry->ResourceType, 05088 &count, 05089 &cmDesc 05090 ); 05091 if (!NT_SUCCESS(status)) { 05092 DebugMessage(DUMP_ERROR, ("Rebalance: Failed to find required resources for Arbiter\n")); 05093 return status; 05094 } 05095 status = IopCallArbiter(arbiterEntry, 05096 ArbiterAction, 05097 &arbiterEntry->ResourceList, 05098 (PVOID)ULongToPtr(count), 05099 cmDesc 05100 ); 05101 if (cmDesc) { 05102 ExFreePool(cmDesc); 05103 } 05104 if (!NT_SUCCESS(status)) { 05105 arbiterEntry->State |= PI_ARBITER_TEST_FAILED; 05106 return status; 05107 } else { 05108 arbiterEntry->State &= ~PI_ARBITER_TEST_FAILED; 05109 arbiterEntry->ResourcesChanged = FALSE; 05110 if (ArbiterAction == ArbiterActionTestAllocation) { 05111 arbiterEntry->State |= PI_ARBITER_HAS_SOMETHING; 05112 } 05113 } 05114 } 05115 } 05116 } 05117 return STATUS_SUCCESS; 05118 }

NTSTATUS IopAssign IN ULONG  AssignTableCount,
IN PIOP_RESOURCE_REQUEST  AssignTable,
IN BOOLEAN  Rebalance
 

Definition at line 3084 of file pnpres.c.

References ArbiterActionTestAllocation, DbgPrint, DebugMessage, DUMP_DETAIL, DUMP_ERROR, FALSE, FIND_BEST_ASSIGNMENT_TIMEOUT, _DEVICE_NODE::InstancePath, IOP_ASSIGN_EXCLUDE, IopAddReqDescsToArbiters(), IopIsBestConfiguration(), IopPlacement(), IopRemoveReqDescsFromArbiters(), IopSaveCurrentConfiguration(), KeQuerySystemTime(), NT_SUCCESS, NTSTATUS(), PAGED_CODE, PiNoRetest, PiUseTimeout, PREQ_ALTERNATIVE, PREQ_LIST, and TRUE.

Referenced by IopAssignInner().

03092 : 03093 03094 This routine performs the resource allocation for the passed in AssignTables. 03095 03096 Parameters: 03097 03098 AssignTableCount - supplies the number of AssignTable 03099 03100 AssignTable - supplies a pointer to the first AssignTable. 03101 03102 Return Value: 03103 03104 Status code that indicates whether or not the function was successful. 03105 03106 --*/ 03107 03108 { 03109 NTSTATUS status = STATUS_INSUFFICIENT_RESOURCES; 03110 LONG tableIndex; 03111 PREQ_LIST reqList; 03112 PREQ_ALTERNATIVE reqAlternative; 03113 PDEVICE_NODE deviceNode; 03114 LARGE_INTEGER startTime; 03115 BOOLEAN timeoutExpired; 03116 ULONG spewCount = 0; 03117 03118 PAGED_CODE(); 03119 03120 timeoutExpired = FALSE; 03121 03122 // 03123 // Initialize our starting time. 03124 // 03125 03126 KeQuerySystemTime(&startTime); 03127 03128 // 03129 // Initialize the selected alternative for each entry to the first 03130 // possible alternative. 03131 // 03132 03133 for (tableIndex = 0; tableIndex < (LONG)AssignTableCount; tableIndex++) { 03134 03135 if (!(AssignTable[tableIndex].Flags & IOP_ASSIGN_EXCLUDE)) { 03136 03137 reqList = AssignTable[tableIndex].ReqList; 03138 reqList->SelectedAlternative = &reqList->ReqAlternativeTable[0]; 03139 } 03140 } 03141 03142 // 03143 // Go through all possible combinations of req alternatives for all devices. 03144 // 03145 03146 while (tableIndex >= 0) { 03147 03148 // 03149 // Add the currently selected alternative to the arbiters iff 03150 // it has changed since the last time. 03151 // 03152 03153 for (tableIndex = AssignTableCount - 1; tableIndex >= 0;) { 03154 03155 if (AssignTable[tableIndex].Flags & IOP_ASSIGN_EXCLUDE) { 03156 03157 tableIndex--; 03158 } else { 03159 03160 reqList = AssignTable[tableIndex].ReqList; 03161 reqAlternative = *reqList->SelectedAlternative; 03162 deviceNode = (PDEVICE_NODE)AssignTable[tableIndex].PhysicalDevice->DeviceObjectExtension->DeviceNode; 03163 DebugMessage(DUMP_DETAIL, ("PnpRes: Adding %d/%d req alt to the arbiters for %ws.\n", reqAlternative->ReqAlternativeIndex + 1, reqList->ReqAlternativeCount, deviceNode->InstancePath.Buffer)); 03164 IopAddReqDescsToArbiters( reqAlternative->ReqDescCount, 03165 reqAlternative->ReqDescTable); 03166 if (reqList->SelectedAlternative == &reqList->ReqAlternativeTable[0]) { 03167 03168 tableIndex--; 03169 } else { 03170 03171 break; 03172 } 03173 } 03174 } 03175 03176 // 03177 // Test this configuration. 03178 // 03179 03180 status = IopPlacement(ArbiterActionTestAllocation, Rebalance); 03181 if (NT_SUCCESS(status)) { 03182 // 03183 // Compute priority and update best configuration if needed. 03184 // 03185 03186 if (IopIsBestConfiguration()) { 03187 03188 // 03189 // This assignment gets the best score. Update its ReqBestAlternative 03190 // and return. 03191 // 03192 03193 DebugMessage(DUMP_DETAIL, ("PnpRes: Found a best assignment. Save it\n")); 03194 IopSaveCurrentConfiguration(); 03195 03196 // 03197 // The reqList->ReqBestAlternative will be set to reqAlternative, i.e. 03198 // reqList->ReqBestAlternative = reqAlternative; 03199 // in IopSaveCurrentConfiguration(). 03200 // This will cause the control to exit the for-loop. 03201 // 03202 03203 } 03204 03205 // 03206 // Do we need to stop? 03207 // 03208 03209 if (PiNoRetest) { 03210 03211 break; 03212 } 03213 } 03214 03215 // 03216 // Algorithm to select the next alternative. 03217 // 03218 // We go through the table in the reverse direction. 03219 // We first remove the currently selected alternative. 03220 // We update the selected alternative to the next possible 03221 // alternative. If we roll over, we go to the next entry in 03222 // the table. 03223 // 03224 03225 for (tableIndex = AssignTableCount - 1; tableIndex >= 0; ) { 03226 03227 if (AssignTable[tableIndex].Flags & IOP_ASSIGN_EXCLUDE) { 03228 03229 tableIndex--; 03230 } else { 03231 03232 reqList = AssignTable[tableIndex].ReqList; 03233 reqAlternative = *reqList->SelectedAlternative; 03234 deviceNode = (PDEVICE_NODE)AssignTable[tableIndex].PhysicalDevice->DeviceObjectExtension->DeviceNode; 03235 DebugMessage(DUMP_DETAIL, ("PnpRes: Removing %d/%d req alt from the arbiters for %ws.\n", reqAlternative->ReqAlternativeIndex + 1, reqList->ReqAlternativeCount, deviceNode->InstancePath.Buffer)); 03236 IopRemoveReqDescsFromArbiters( reqAlternative->ReqDescCount, 03237 reqAlternative->ReqDescTable); 03238 if (++reqList->SelectedAlternative < reqList->ReqBestAlternative && !timeoutExpired) { 03239 03240 break; 03241 } else { 03242 03243 reqList->SelectedAlternative = &reqList->ReqAlternativeTable[0]; 03244 tableIndex--; 03245 } 03246 } 03247 03248 } 03249 03250 // 03251 // Check if timeout has expired. 03252 // 03253 03254 if (tableIndex >= 0) { 03255 03256 LARGE_INTEGER currentTime; 03257 ULONG timeDiff; 03258 03259 // 03260 // Compute time difference in milliseconds. 03261 // 03262 03263 KeQuerySystemTime(&currentTime); 03264 timeDiff = (ULONG)((currentTime.QuadPart - startTime.QuadPart) / 10000); 03265 03266 // 03267 // We are done if timeout has expired. 03268 // 03269 03270 if (timeDiff >= FIND_BEST_ASSIGNMENT_TIMEOUT) 03271 { 03272 if (PiUseTimeout) { 03273 03274 DebugMessage(DUMP_ERROR, ("PnpRes: Timeout expired, bailing out!\n")); 03275 timeoutExpired = TRUE; 03276 03277 } else { 03278 03279 spewCount = (spewCount + 1) % 50; 03280 if (spewCount == 0) { 03281 DbgPrint("PnpRes: Timeout expired.\n"); 03282 } 03283 } 03284 } 03285 } 03286 } 03287 03288 return (status); 03289 }

NTSTATUS IopAssignInner IN ULONG  AssignTableCount,
IN PIOP_RESOURCE_REQUEST  AssignTable,
IN BOOLEAN  Rebalance
 

Definition at line 3292 of file pnpres.c.

References ARBITER_ACTION, ArbiterActionCommitAllocation, ArbiterActionRetestAllocation, ASSERT, DebugMessage, DUMP_DETAIL, FALSE, IopAssign(), IopCheckDataStructures(), IopPlacement(), IopRestoreBestConfiguration(), IopRootDeviceNode, NTSTATUS(), PiActiveArbiterList, PiAssignTable, PiAssignTableCount, PiBestArbiterList, PiBestPriority, PiNoRetest, PnpResDebugLevel, STOP_ERROR, and TRUE.

Referenced by IopAllocateResources(), IopReallocateResources(), IopRebalance(), and IopRestoreResourcesInternal().

03300 : 03301 03302 This routine sets up static variables and invokes the real resource allocation 03303 routine. 03304 03305 Parameters: 03306 03307 AssignTableCount - supplies the number of AssignTable 03308 03309 AssignTable - supplies a pointer to the first AssignTable. 03310 03311 Return Value: 03312 03313 Status code that indicates whether or not the function was successful. 03314 03315 --*/ 03316 03317 { 03318 NTSTATUS status; 03319 ARBITER_ACTION arbiterAction; 03320 03321 // 03322 // Initialize static variable 03323 // 03324 03325 InitializeListHead(&PiBestArbiterList); 03326 InitializeListHead(&PiActiveArbiterList); 03327 PiAssignTableCount = AssignTableCount; 03328 PiAssignTable = AssignTable; 03329 PiBestPriority = (ULONG) -1; 03330 if (AssignTableCount == 1) { 03331 PiNoRetest = TRUE; 03332 arbiterAction = ArbiterActionCommitAllocation; 03333 } else { 03334 PiNoRetest = FALSE; 03335 arbiterAction = ArbiterActionRetestAllocation; 03336 } 03337 03338 // 03339 // Try to solve the inner NP-complete problem. 03340 // 03341 03342 IopAssign(AssignTableCount, AssignTable, Rebalance); 03343 #if DBG_SCOPE 03344 if ((PnpResDebugLevel & STOP_ERROR) && PiNoRetest == FALSE) { 03345 IopCheckDataStructures(IopRootDeviceNode); 03346 } 03347 #endif 03348 if (IsListEmpty(&PiBestArbiterList)) { 03349 DebugMessage(DUMP_DETAIL, ("PnpRes: IoAssignInner failed to find an assignment.\n")); 03350 status = STATUS_UNSUCCESSFUL; 03351 } else { 03352 03353 if (Rebalance) { 03354 DebugMessage(DUMP_DETAIL, ("PnpRes: Restore the best assignment.\n")); 03355 } else { 03356 DebugMessage(DUMP_DETAIL, ("PnpRes: Restore the best assignment and commit it.\n")); 03357 } 03358 03359 IopRestoreBestConfiguration(); 03360 status = IopPlacement(arbiterAction, Rebalance); 03361 #if DBG_SCOPE 03362 if (!Rebalance) { 03363 if (PnpResDebugLevel & STOP_ERROR) { 03364 IopCheckDataStructures(IopRootDeviceNode); 03365 } 03366 } 03367 #endif 03368 ASSERT(status == STATUS_SUCCESS); 03369 } 03370 PiNoRetest = FALSE; 03371 return status; 03372 }

VOID IopBuildCmResourceList IN PIOP_RESOURCE_REQUEST  AssignEntry  ) 
 

Definition at line 2034 of file pnpres.c.

References ArbiterResultNullRequest, ASSERT, CmRegistryMachineHardwareResourceMapName, DebugMessage, DUMP_ERROR, ExAllocatePoolCMRL, ExAllocatePoolCMRR, ExFreePool(), IopChildToRootTranslation(), IopCreateRegistryKeyEx(), IopParentToRawTranslation(), IopWriteResourceList(), IopWstrRaw, IopWstrTranslated, NT_SUCCESS, NTSTATUS(), NULL, ObQueryNameString(), PAGED_CODE, PagedPool, PREQ_ALTERNATIVE, PREQ_DESC, PREQ_LIST, RtlAppendUnicodeToString(), and RtlInitUnicodeString().

Referenced by IopBuildCmResourceLists().

02039 : 02040 02041 This routine walks REQ_LIST of the AssignEntry to build a corresponding 02042 Cm Resource lists. It also reports the resources to ResourceMap. 02043 02044 Parameters: 02045 02046 AssignEntry - Supplies a pointer to an IOP_ASSIGN_REQUEST structure 02047 02048 Return Value: 02049 02050 None. The ResourceAssignment in AssignEntry is initialized. 02051 02052 --*/ 02053 02054 { 02055 NTSTATUS status; 02056 HANDLE resourceMapKey; 02057 PDEVICE_OBJECT physicalDevice; 02058 PREQ_LIST reqList = AssignEntry->ReqList; 02059 PREQ_ALTERNATIVE reqAlternative; 02060 PREQ_DESC reqDesc, reqDescx; 02061 PIO_RESOURCE_DESCRIPTOR privateData; 02062 ULONG count = 0, size, i; 02063 PCM_RESOURCE_LIST cmResources, cmResourcesRaw; 02064 PCM_FULL_RESOURCE_DESCRIPTOR cmFullResource, cmFullResourceRaw; 02065 PCM_PARTIAL_RESOURCE_LIST cmPartialList, cmPartialListRaw; 02066 PCM_PARTIAL_RESOURCE_DESCRIPTOR cmDescriptor, cmDescriptorRaw, assignment, tAssignment; 02067 #if DBG 02068 PCM_PARTIAL_RESOURCE_DESCRIPTOR cmDescriptorEnd, cmDescriptorEndRaw; 02069 #endif 02070 02071 PAGED_CODE(); 02072 02073 // 02074 // Determine the size of the CmResourceList 02075 // 02076 02077 // 02078 // Determine the size of the CmResourceList 02079 // 02080 02081 reqAlternative = *reqList->SelectedAlternative; 02082 for (i = 0; i < reqAlternative->ReqDescCount; i++) { 02083 reqDesc = reqAlternative->ReqDescTable[i]; 02084 count += reqDesc->DevicePrivateCount + 1; 02085 } 02086 02087 size = sizeof(CM_RESOURCE_LIST) + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * (count - 1); 02088 cmResources = (PCM_RESOURCE_LIST) ExAllocatePoolCMRL(PagedPool, size); 02089 if (!cmResources) { 02090 02091 // 02092 // If we can not find memory, the resources will not be committed by arbiter. 02093 // 02094 02095 DebugMessage(DUMP_ERROR, ("PnpRes: Not enough memory to build Translated CmResourceList\n")); 02096 AssignEntry->Status = STATUS_INSUFFICIENT_RESOURCES; 02097 AssignEntry->ResourceAssignment = NULL; 02098 AssignEntry->TranslatedResourceAssignment = NULL; 02099 return; 02100 } 02101 cmResourcesRaw = (PCM_RESOURCE_LIST) ExAllocatePoolCMRR(PagedPool, size); 02102 if (!cmResourcesRaw) { 02103 DebugMessage(DUMP_ERROR, ("PnpRes: Not enough memory to build Raw CmResourceList\n")); 02104 ExFreePool(cmResources); 02105 AssignEntry->Status = STATUS_INSUFFICIENT_RESOURCES; 02106 AssignEntry->ResourceAssignment = NULL; 02107 AssignEntry->TranslatedResourceAssignment = NULL; 02108 return; 02109 } 02110 cmResources->Count = 1; 02111 cmFullResource = cmResources->List; 02112 02113 // 02114 // The CmResourceList we build here does not distinguish the 02115 // Interface Type on descriptor level. This should be fine because 02116 // for IoReportResourceUsage we ignore the CmResourceList we build 02117 // here. 02118 // 02119 02120 cmFullResource->InterfaceType = reqList->InterfaceType; 02121 cmFullResource->BusNumber = reqList->BusNumber; 02122 cmPartialList = &cmFullResource->PartialResourceList; 02123 cmPartialList->Version = 0; 02124 cmPartialList->Revision = 0; 02125 cmPartialList->Count = count; 02126 cmDescriptor = cmPartialList->PartialDescriptors; 02127 #if DBG 02128 cmDescriptorEnd = cmDescriptor + count; 02129 #endif 02130 cmResourcesRaw->Count = 1; 02131 cmFullResourceRaw = cmResourcesRaw->List; 02132 cmFullResourceRaw->InterfaceType = reqList->InterfaceType; 02133 cmFullResourceRaw->BusNumber = reqList->BusNumber; 02134 cmPartialListRaw = &cmFullResourceRaw->PartialResourceList; 02135 cmPartialListRaw->Version = 0; 02136 cmPartialListRaw->Revision = 0; 02137 cmPartialListRaw->Count = count; 02138 cmDescriptorRaw = cmPartialListRaw->PartialDescriptors; 02139 #if DBG 02140 cmDescriptorEndRaw = cmDescriptorRaw + count; 02141 #endif 02142 02143 for (i = 0; i < reqAlternative->ReqDescCount; i++) { 02144 reqDesc = reqAlternative->ReqDescTable[i]; 02145 02146 if (reqDesc->ArbitrationRequired) { 02147 02148 // 02149 // Get raw assignment and copy it to our raw resource list 02150 // 02151 02152 reqDescx = reqDesc->TranslatedReqDesc; 02153 if (reqDescx->AlternativeTable.Result != ArbiterResultNullRequest) { 02154 status = IopParentToRawTranslation(reqDescx); 02155 if (!NT_SUCCESS(status)) { 02156 DebugMessage(DUMP_ERROR, ("PnpRes: Parent To Raw translation failed\n")); 02157 ExFreePool(cmResources); 02158 ExFreePool(cmResourcesRaw); 02159 AssignEntry->Status = STATUS_INSUFFICIENT_RESOURCES; 02160 AssignEntry->ResourceAssignment = NULL; 02161 return; 02162 } 02163 assignment = reqDesc->AlternativeTable.Assignment; 02164 } else { 02165 assignment = reqDescx->AlternativeTable.Assignment; 02166 } 02167 *cmDescriptorRaw = *assignment; 02168 cmDescriptorRaw++; 02169 02170 // 02171 // Translate assignment and copy it to our translated resource list 02172 // 02173 if (reqDescx->AlternativeTable.Result != ArbiterResultNullRequest) { 02174 status = IopChildToRootTranslation( 02175 (PDEVICE_NODE)reqDesc->AlternativeTable.PhysicalDeviceObject->DeviceObjectExtension->DeviceNode, 02176 reqDesc->InterfaceType, 02177 reqDesc->BusNumber, 02178 reqDesc->AlternativeTable.RequestSource, 02179 &reqDesc->Allocation, 02180 &tAssignment 02181 ); 02182 if (!NT_SUCCESS(status)) { 02183 DebugMessage(DUMP_ERROR, ("PnpRes: Child to Root translation failed\n")); 02184 ExFreePool(cmResources); 02185 ExFreePool(cmResourcesRaw); 02186 AssignEntry->Status = STATUS_INSUFFICIENT_RESOURCES; 02187 AssignEntry->ResourceAssignment = NULL; 02188 return; 02189 } 02190 *cmDescriptor = *tAssignment; 02191 ExFreePool(tAssignment); 02192 } else { 02193 *cmDescriptor = *(reqDescx->AlternativeTable.Assignment); 02194 } 02195 cmDescriptor++; 02196 02197 } else { 02198 *cmDescriptorRaw = reqDesc->Allocation; 02199 *cmDescriptor = reqDesc->Allocation; 02200 cmDescriptorRaw++; 02201 cmDescriptor++; 02202 } 02203 02204 // 02205 // Next copy the device private descriptors to CmResourceLists 02206 // 02207 02208 count = reqDesc->DevicePrivateCount; 02209 privateData = reqDesc->DevicePrivate; 02210 while (count != 0) { 02211 02212 cmDescriptor->Type = cmDescriptorRaw->Type = CmResourceTypeDevicePrivate; 02213 cmDescriptor->ShareDisposition = cmDescriptorRaw->ShareDisposition = 02214 CmResourceShareDeviceExclusive; 02215 cmDescriptor->Flags = cmDescriptorRaw->Flags = privateData->Flags; 02216 RtlMoveMemory(&cmDescriptorRaw->u.DevicePrivate, 02217 &privateData->u.DevicePrivate, 02218 sizeof(cmDescriptorRaw->u.DevicePrivate.Data) 02219 ); 02220 RtlMoveMemory(&cmDescriptor->u.DevicePrivate, 02221 &privateData->u.DevicePrivate, 02222 sizeof(cmDescriptor->u.DevicePrivate.Data) 02223 ); 02224 privateData++; 02225 cmDescriptorRaw++; 02226 cmDescriptor++; 02227 count--; 02228 ASSERT(cmDescriptorRaw <= cmDescriptorEndRaw); 02229 ASSERT(cmDescriptor <= cmDescriptorEnd); 02230 } 02231 ASSERT(cmDescriptor <= cmDescriptorEnd); 02232 ASSERT(cmDescriptorRaw <= cmDescriptorEndRaw); 02233 02234 } 02235 02236 // 02237 // report assigned resources to ResourceMap 02238 // 02239 02240 physicalDevice = AssignEntry->PhysicalDevice; 02241 02242 // 02243 // Open ResourceMap key 02244 // 02245 02246 status = IopCreateRegistryKeyEx( &resourceMapKey, 02247 (HANDLE) NULL, 02248 &CmRegistryMachineHardwareResourceMapName, 02249 KEY_READ | KEY_WRITE, 02250 REG_OPTION_VOLATILE, 02251 NULL 02252 ); 02253 if (NT_SUCCESS(status )) { 02254 WCHAR DeviceBuffer[256]; 02255 POBJECT_NAME_INFORMATION NameInformation; 02256 ULONG NameLength; 02257 UNICODE_STRING UnicodeClassName; 02258 UNICODE_STRING UnicodeDriverName; 02259 UNICODE_STRING UnicodeDeviceName; 02260 02261 RtlInitUnicodeString(&UnicodeClassName, PNPMGR_STR_PNP_MANAGER); 02262 02263 RtlInitUnicodeString(&UnicodeDriverName, REGSTR_KEY_PNP_DRIVER); 02264 02265 NameInformation = (POBJECT_NAME_INFORMATION) DeviceBuffer; 02266 status = ObQueryNameString( physicalDevice, 02267 NameInformation, 02268 sizeof( DeviceBuffer ), 02269 &NameLength ); 02270 if (NT_SUCCESS(status)) { 02271 NameInformation->Name.MaximumLength = sizeof(DeviceBuffer) - sizeof(OBJECT_NAME_INFORMATION); 02272 if (NameInformation->Name.Length == 0) { 02273 NameInformation->Name.Buffer = (PVOID)((ULONG_PTR)DeviceBuffer + sizeof(OBJECT_NAME_INFORMATION)); 02274 } 02275 02276 UnicodeDeviceName = NameInformation->Name; 02277 RtlAppendUnicodeToString(&UnicodeDeviceName, IopWstrRaw); 02278 02279 // 02280 // IopWriteResourceList should remove all the device private and device 02281 // specifiec descriptors. 02282 // 02283 02284 status = IopWriteResourceList( 02285 resourceMapKey, 02286 &UnicodeClassName, 02287 &UnicodeDriverName, 02288 &UnicodeDeviceName, 02289 cmResourcesRaw, 02290 size 02291 ); 02292 if (NT_SUCCESS(status)) { 02293 UnicodeDeviceName = NameInformation->Name; 02294 RtlAppendUnicodeToString (&UnicodeDeviceName, IopWstrTranslated); 02295 status = IopWriteResourceList( 02296 resourceMapKey, 02297 &UnicodeClassName, 02298 &UnicodeDriverName, 02299 &UnicodeDeviceName, 02300 cmResources, 02301 size 02302 ); 02303 } 02304 } 02305 ZwClose(resourceMapKey); 02306 } 02307 #if 0 // Ignore the registry writing status. 02308 if (!NT_SUCCESS(status)) { 02309 ExFreePool(cmResources); 02310 ExFreePool(cmResourcesRaw); 02311 cmResources = NULL; 02312 cmResourcesRaw = NULL; 02313 } 02314 #endif 02315 AssignEntry->ResourceAssignment = cmResourcesRaw; 02316 AssignEntry->TranslatedResourceAssignment = cmResources; 02317 }

VOID IopBuildCmResourceLists IN PIOP_RESOURCE_REQUEST  AssignTable,
IN PIOP_RESOURCE_REQUEST  AssignTableEnd
 

Definition at line 2320 of file pnpres.c.

References DbgPrint, DebugMessage, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, DUMP_INFO, _IOP_RESOURCE_REQUEST::Flags, _DEVICE_NODE::InstancePath, IOP_ASSIGN_EXCLUDE, IOP_ASSIGN_IGNORE, IOP_ASSIGN_RETRY, IopBuildCmResourceList(), IopDetermineResourceListSize(), IopDumpCmResourceList(), IopWriteAllocatedResourcesToRegistry(), NTSTATUS(), NULL, PAGED_CODE, _IOP_RESOURCE_REQUEST::PhysicalDevice, PnpResDebugLevel, _IOP_RESOURCE_REQUEST::ResourceAssignment, _IOP_RESOURCE_REQUEST::Status, and _IOP_RESOURCE_REQUEST::TranslatedResourceAssignment.

Referenced by IopAllocateResources(), IopReallocateResources(), and IopRebalance().

02327 : 02328 02329 For each AssignTable entry, this routine queries device's IO resource requirements 02330 list and converts it to our internal REQ_LIST format. 02331 02332 Parameters: 02333 02334 AssignTable - supplies a pointer to the first entry of a IOP_RESOURCE_REQUEST table. 02335 02336 AssignTableEnd - supplies a pointer to the end of IOP_RESOURCE_REQUEST table. 02337 02338 Return Value: 02339 02340 Status code that indicates whether or not the function was successful. 02341 02342 --*/ 02343 02344 { 02345 NTSTATUS status; 02346 PIOP_RESOURCE_REQUEST assignEntry; 02347 PDEVICE_OBJECT physicalDevice; 02348 PDEVICE_NODE deviceNode; 02349 02350 PAGED_CODE(); 02351 02352 // 02353 // Go thru each entry, for each Physical device object, we build a CmResourceList 02354 // from its ListOfAssignedResources. 02355 // 02356 02357 for (assignEntry = AssignTable; assignEntry < AssignTableEnd; ++assignEntry) { 02358 02359 assignEntry->ResourceAssignment = NULL; 02360 if (assignEntry->Flags & IOP_ASSIGN_IGNORE || assignEntry->Flags & IOP_ASSIGN_RETRY) { 02361 continue; 02362 } 02363 if (assignEntry->Flags & IOP_ASSIGN_EXCLUDE) { 02364 assignEntry->Status = STATUS_UNSUCCESSFUL; 02365 continue; 02366 } 02367 assignEntry->Status = STATUS_SUCCESS; 02368 IopBuildCmResourceList (assignEntry); 02369 if (assignEntry->ResourceAssignment) { 02370 physicalDevice = assignEntry->PhysicalDevice; 02371 deviceNode = (PDEVICE_NODE)physicalDevice->DeviceObjectExtension->DeviceNode; 02372 IopWriteAllocatedResourcesToRegistry( 02373 deviceNode, 02374 assignEntry->ResourceAssignment, 02375 IopDetermineResourceListSize(assignEntry->ResourceAssignment) 02376 ); 02377 #if DBG_SCOPE 02378 DebugMessage(DUMP_INFO,("Pnpres: Building CM resource lists for %ws...\n", deviceNode->InstancePath.Buffer)); 02379 if (PnpResDebugLevel & DUMP_INFO) { 02380 DbgPrint("Raw resources "); 02381 IopDumpCmResourceList(assignEntry->ResourceAssignment); 02382 DbgPrint("Translated resources "); 02383 IopDumpCmResourceList(assignEntry->TranslatedResourceAssignment); 02384 } 02385 #endif 02386 } 02387 } 02388 }

NTSTATUS IopCallArbiter PPI_RESOURCE_ARBITER_ENTRY  ArbiterEntry,
ARBITER_ACTION  Command,
PVOID  Input1,
PVOID  Input2,
PVOID  Input3
 

Definition at line 4339 of file pnpres.c.

References ArbiterActionBootAllocation, ArbiterActionCommitAllocation, ArbiterActionQueryAllocatedResources, ArbiterActionQueryArbitrate, ArbiterActionQueryConflict, ArbiterActionRetestAllocation, ArbiterActionRollbackAllocation, ArbiterActionTestAllocation, ArbiterActionWriteReservedResources, _ARBITER_INTERFACE::ArbiterHandler, _PI_RESOURCE_ARBITER_ENTRY::ArbiterInterface, ASSERT, _ARBITER_INTERFACE::Context, _ARBITER_LIST_ENTRY::ListEntry, NTSTATUS(), NULL, _ARBITER_PARAMETERS::Parameters, and PREQ_DESC.

Referenced by IopAddReqDescsToArbiters(), IopArbitrateDeviceResources(), IopPlacement(), IopPlacementForReservation(), IopQueryConflictListInternal(), IopReleaseResourcesInternal(), IopRemoveReqDescsFromArbiters(), and IopSetupArbiterAndTranslators().

04349 : 04350 04351 This routine builds a Parameter block from Input structure and calls specified 04352 arbiter to carry out the Command. 04353 04354 Parameters: 04355 04356 ArbiterEntry - Supplies a pointer to our PI_RESOURCE_ARBITER_ENTRY such that 04357 we know everything about the arbiter. 04358 04359 Command - Supplies the Action code for the arbiter. 04360 04361 Input - Supplies a PVOID pointer to a structure. 04362 04363 Return Value: 04364 04365 Status code that indicates whether or not the function was successful. 04366 04367 --*/ 04368 { 04369 ARBITER_PARAMETERS parameters; 04370 PARBITER_INTERFACE arbiterInterface = ArbiterEntry->ArbiterInterface; 04371 NTSTATUS status; 04372 PARBITER_LIST_ENTRY arbiterListEntry; 04373 LIST_ENTRY listHead; 04374 PVOID *ExtParams; 04375 04376 switch (Command) { 04377 case ArbiterActionTestAllocation: 04378 case ArbiterActionRetestAllocation: 04379 04380 // 04381 // For ArbiterActionTestAllocation, the Input is a pointer to the doubly 04382 // linked list of ARBITER_LIST_ENTRY's. 04383 // 04384 04385 parameters.Parameters.TestAllocation.ArbitrationList = (PLIST_ENTRY)Input1; 04386 parameters.Parameters.TestAllocation.AllocateFromCount = (ULONG)((ULONG_PTR)Input2); 04387 parameters.Parameters.TestAllocation.AllocateFrom = 04388 (PCM_PARTIAL_RESOURCE_DESCRIPTOR)Input3; 04389 status = (arbiterInterface->ArbiterHandler)( 04390 arbiterInterface->Context, 04391 Command, 04392 &parameters 04393 ); 04394 break; 04395 04396 case ArbiterActionBootAllocation: 04397 04398 // 04399 // For ArbiterActionBootAllocation, the input is a pointer to the doubly 04400 // linked list of ARBITER_LIST_ENTRY'S. 04401 // 04402 04403 parameters.Parameters.BootAllocation.ArbitrationList = (PLIST_ENTRY)Input1; 04404 04405 status = (arbiterInterface->ArbiterHandler)( 04406 arbiterInterface->Context, 04407 Command, 04408 &parameters 04409 ); 04410 break; 04411 04412 case ArbiterActionQueryArbitrate: 04413 04414 // 04415 // For QueryArbiter, the input is a pointer to REQ_DESC 04416 // 04417 04418 arbiterListEntry = &((PREQ_DESC)Input1)->AlternativeTable; 04419 ASSERT(IsListEmpty(&arbiterListEntry->ListEntry)); 04420 listHead = arbiterListEntry->ListEntry; 04421 arbiterListEntry->ListEntry.Flink = arbiterListEntry->ListEntry.Blink = &listHead; 04422 parameters.Parameters.QueryArbitrate.ArbitrationList = &listHead; 04423 status = (arbiterInterface->ArbiterHandler)( 04424 arbiterInterface->Context, 04425 Command, 04426 &parameters 04427 ); 04428 arbiterListEntry->ListEntry = listHead; 04429 break; 04430 04431 case ArbiterActionCommitAllocation: 04432 case ArbiterActionRollbackAllocation: 04433 case ArbiterActionWriteReservedResources: 04434 04435 // 04436 // Commit, Rollback and WriteReserved do not have parmater. 04437 // 04438 04439 status = (arbiterInterface->ArbiterHandler)( 04440 arbiterInterface->Context, 04441 Command, 04442 NULL 04443 ); 04444 break; 04445 04446 case ArbiterActionQueryAllocatedResources: 04447 status = STATUS_NOT_IMPLEMENTED; 04448 break; 04449 04450 case ArbiterActionQueryConflict: 04451 // 04452 // For QueryConflict 04453 // Ex0 is PDO 04454 // Ex1 is PIO_RESOURCE_DESCRIPTOR 04455 // Ex2 is PULONG 04456 // Ex3 is PARBITER_CONFLICT_INFO * 04457 ExtParams = (PVOID*)Input1; 04458 04459 parameters.Parameters.QueryConflict.PhysicalDeviceObject = (PDEVICE_OBJECT)ExtParams[0]; 04460 parameters.Parameters.QueryConflict.ConflictingResource = (PIO_RESOURCE_DESCRIPTOR)ExtParams[1]; 04461 parameters.Parameters.QueryConflict.ConflictCount = (PULONG)ExtParams[2]; 04462 parameters.Parameters.QueryConflict.Conflicts = (PARBITER_CONFLICT_INFO *)ExtParams[3]; 04463 status = (arbiterInterface->ArbiterHandler)( 04464 arbiterInterface->Context, 04465 Command, 04466 &parameters 04467 ); 04468 break; 04469 04470 default: 04471 status = STATUS_INVALID_PARAMETER; 04472 break; 04473 } 04474 04475 return status; 04476 }

VOID IopCheckDataStructures IN PDEVICE_NODE  DeviceNode  ) 
 

Definition at line 7662 of file pnpres.c.

References IopCheckDataStructuresWorker().

Referenced by IopAssignInner(), IopQueryConflictListInternal(), IopRebalance(), and IopReserve().

07666 { 07667 if (DeviceNode) { 07668 IopCheckDataStructuresWorker (DeviceNode); 07669 IopCheckDataStructures (DeviceNode->Sibling); 07670 IopCheckDataStructures (DeviceNode->Child); 07671 } 07672 }

VOID IopCheckDataStructuresWorker IN PDEVICE_NODE  Device  ) 
 

Definition at line 7674 of file pnpres.c.

References _PI_RESOURCE_ARBITER_ENTRY::ActiveArbiterList, _PI_RESOURCE_ARBITER_ENTRY::ArbiterInterface, ASSERT, NULL, and _PI_RESOURCE_ARBITER_ENTRY::ResourceList.

Referenced by IopCheckDataStructures().

07680 : 07681 07682 This routine releases the assigned resources for device specified by DeviceNode. 07683 Note, this routine does not reset the resource related fields in DeviceNode structure. 07684 07685 Parameters: 07686 07687 DeviceNode - specifies the device node whose resources are goint to be released. 07688 07689 Return Value: 07690 07691 Status code that indicates whether or not the function was successful. 07692 07693 --*/ 07694 07695 { 07696 PLIST_ENTRY listHead, listEntry; 07697 PPI_RESOURCE_ARBITER_ENTRY arbiterEntry; 07698 07699 listHead = &Device->DeviceArbiterList; 07700 listEntry = listHead->Flink; 07701 while (listEntry != listHead) { 07702 arbiterEntry = CONTAINING_RECORD(listEntry, PI_RESOURCE_ARBITER_ENTRY, DeviceArbiterList); 07703 if (arbiterEntry->ArbiterInterface != NULL) { 07704 ASSERT(IsListEmpty(&arbiterEntry->ResourceList)); 07705 ASSERT(IsListEmpty(&arbiterEntry->ActiveArbiterList)); 07706 InitializeListHead(&arbiterEntry->ActiveArbiterList); 07707 InitializeListHead(&arbiterEntry->ResourceList); 07708 } 07709 listEntry = listEntry->Flink; 07710 } 07711 }

NTSTATUS IopChildToRootTranslation IN PDEVICE_NODE  DeviceNode,
OPTIONAL IN INTERFACE_TYPE  InterfaceType,
IN ULONG  BusNumber,
IN ARBITER_REQUEST_SOURCE  ArbiterRequestSource,
IN PCM_PARTIAL_RESOURCE_DESCRIPTOR  Source,
OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR *  Target
 

Definition at line 3933 of file pnpres.c.

References ArbiterRequestHalReported, BusNumber, _TRANSLATOR_INTERFACE::Context, DbgPrint, _DEVICE_NODE::DeviceTranslatorList, PNPRESDEBUGTRANSLATIONFAILURE::devnode, ExAllocatePoolPRD, ExFreePool(), exit, FALSE, InterfaceType, IopFindBusDeviceNode(), IopRootDeviceNode, NT_SUCCESS, NTSTATUS(), NULL, PagedPool, _DEVICE_NODE::Parent, PnpResDebugLevel, PnpResDebugTranslationFailure, PnpResDebugTranslationFailureCount, PNPRESDEBUGTRANSLATIONFAILURE::resource, _PI_RESOURCE_TRANSLATOR_ENTRY::ResourceType, STOP_ERROR, TranslateChildToParent, _TRANSLATOR_INTERFACE::TranslateResources, _PI_RESOURCE_TRANSLATOR_ENTRY::TranslatorInterface, and TRUE.

Referenced by IopBuildCmResourceList().

03944 : 03945 03946 This routine translates a CmPartialResourceDescriptors from 03947 their intermediate translated form to their final translated form. 03948 The translated CM_PARTIAL_RESOURCE_DESCRIPTOR is returned via Target variable. 03949 03950 The caller is responsible to release the translated descriptor. 03951 03952 Parameters: 03953 03954 DeviceNode - Specified the device object. If The DeviceNode is specified, 03955 the InterfaceType and BusNumber are ignored and we will 03956 use DeviceNode as a starting point to find various translators to 03957 translate the Source descriptor. If DeviceNode is not specified, 03958 the InterfaceType and BusNumber must be specified. 03959 03960 InterfaceType, BusNumber - must be supplied if DeviceNode is not specified. 03961 03962 Source - A pointer to the resource descriptor to be translated. 03963 03964 Target - Supplies an address to receive the translated resource descriptor. 03965 03966 Return Value: 03967 03968 Status code that indicates whether or not the function was successful. 03969 03970 --*/ 03971 { 03972 PDEVICE_NODE deviceNode; 03973 PLIST_ENTRY listHead, nextEntry; 03974 PCM_PARTIAL_RESOURCE_DESCRIPTOR target, source, tmp; 03975 PPI_RESOURCE_TRANSLATOR_ENTRY translatorEntry; 03976 PTRANSLATOR_INTERFACE translator; 03977 NTSTATUS status = STATUS_SUCCESS; 03978 BOOLEAN done = FALSE, foundTranslator = FALSE, restartedAlready; 03979 03980 if (ArbiterRequestSource == ArbiterRequestHalReported) { 03981 restartedAlready = TRUE; 03982 } else { 03983 restartedAlready = FALSE; 03984 } 03985 03986 source = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ExAllocatePoolPRD( 03987 PagedPool, 03988 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) 03989 ); 03990 if (source == NULL) { 03991 return STATUS_INSUFFICIENT_RESOURCES; 03992 } 03993 target = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ExAllocatePoolPRD( 03994 PagedPool, 03995 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) 03996 ); 03997 if (target == NULL) { 03998 ExFreePool(source); 03999 return STATUS_INSUFFICIENT_RESOURCES; 04000 } 04001 *source = *Source; 04002 04003 // 04004 // Move up to current device node's parent to start translation 04005 // 04006 04007 if (!ARGUMENT_PRESENT(DeviceNode)) { 04008 deviceNode = IopFindBusDeviceNode (IopRootDeviceNode, InterfaceType, BusNumber, 0); 04009 } else { 04010 // We want to start with the deviceNode instead of its parent. Because the 04011 // deviceNode may provide a translator interface. 04012 deviceNode = DeviceNode; 04013 } 04014 while (deviceNode && !done) { 04015 04016 if ((deviceNode == IopRootDeviceNode) && (foundTranslator == FALSE)) { 04017 if (restartedAlready == FALSE) { 04018 restartedAlready = TRUE; 04019 deviceNode = IopFindBusDeviceNode (IopRootDeviceNode, InterfaceType, BusNumber, 0); 04020 04021 // 04022 // If we did not find a PDO, try again with InterfaceType == Isa. This allows 04023 // drivers that request Internal to get resources even if there is no PDO 04024 // that is Internal. (but if there is an Internal PDO, they get that one) 04025 // 04026 04027 if ((deviceNode == IopRootDeviceNode) && (InterfaceType == Internal)) { 04028 deviceNode = IopFindBusDeviceNode(IopRootDeviceNode, Isa, 0, 0); 04029 } 04030 04031 continue; 04032 } 04033 } 04034 // 04035 // First, check if there is a translator for the device node? 04036 // If yes, translate the req desc and link it to the front of ReqDesc->TranslatedReqDesc 04037 // else do nothing. 04038 // 04039 04040 listHead = &deviceNode->DeviceTranslatorList; 04041 nextEntry = listHead->Flink; 04042 for (; nextEntry != listHead; nextEntry = nextEntry->Flink) { 04043 translatorEntry = CONTAINING_RECORD(nextEntry, PI_RESOURCE_TRANSLATOR_ENTRY, DeviceTranslatorList); 04044 if (translatorEntry->ResourceType == Source->Type) { 04045 if (translator = translatorEntry->TranslatorInterface) { 04046 04047 // 04048 // Find a translator to translate the req desc ... Translate it and link it to 04049 // the front of ReqDesc->TranslatedReqDesc. 04050 // 04051 04052 doitagain: 04053 status = (translator->TranslateResources) ( 04054 translator->Context, 04055 source, 04056 TranslateChildToParent, 04057 0, 04058 NULL, 04059 DeviceNode ? DeviceNode->PhysicalDeviceObject : NULL, 04060 target 04061 ); 04062 if (NT_SUCCESS(status)) { 04063 tmp = source; 04064 source = target; 04065 target = tmp; 04066 04067 // 04068 // If the translator is non-hierarchial and performs a complete 04069 // translation to root (eg ISA interrups for PCI devices) then 04070 // don't pass translations to parent. 04071 // 04072 04073 if (status == STATUS_TRANSLATION_COMPLETE) { 04074 done = TRUE; 04075 } 04076 04077 } else { 04078 #if DBG_SCOPE 04079 // DebugMessage(DUMP_ERROR, ("PnpRes: Child to Root Translation failed\n")); 04080 DbgPrint("PnpRes: Child to Root Translation failed\n"); 04081 if (DeviceNode) { 04082 DbgPrint( 04083 " DeviceNode %08x (PDO %08x)\n", 04084 DeviceNode, 04085 DeviceNode->PhysicalDeviceObject 04086 ); 04087 } 04088 DbgPrint( 04089 " Resource Type %02x Data %08x %08x %08x\n", 04090 source->Type, 04091 source->u.DevicePrivate.Data[0], 04092 source->u.DevicePrivate.Data[1], 04093 source->u.DevicePrivate.Data[2] 04094 ); 04095 if (PnpResDebugTranslationFailureCount) { 04096 PnpResDebugTranslationFailureCount--; 04097 PnpResDebugTranslationFailure->devnode = DeviceNode; 04098 PnpResDebugTranslationFailure->resource = *source; 04099 PnpResDebugTranslationFailure++; 04100 } 04101 if (PnpResDebugLevel & STOP_ERROR) { 04102 DbgBreakPoint(); 04103 goto doitagain; 04104 } 04105 #endif 04106 goto exit; 04107 } 04108 } 04109 break; 04110 } 04111 } 04112 04113 // 04114 // Move up to current device node's parent 04115 // 04116 04117 deviceNode = deviceNode->Parent; 04118 } 04119 *Target = source; 04120 ExFreePool(target); 04121 return status; 04122 exit: 04123 ExFreePool(source); 04124 ExFreePool(target); 04125 return status; 04126 }

PCM_RESOURCE_LIST IopCombineCmResourceList IN PCM_RESOURCE_LIST  ResourceListA,
IN PCM_RESOURCE_LIST  ResourceListB
 

Definition at line 6955 of file pnpres.c.

References ExAllocatePoolIORRR, IopDetermineResourceListSize(), NULL, and PagedPool.

Referenced by IopReserveLegacyBootResources().

06959 { 06960 PCM_RESOURCE_LIST newList = NULL; 06961 ULONG sizeA, sizeB, size; 06962 06963 if (ResourceListA == NULL) { 06964 06965 return ResourceListB; 06966 06967 } 06968 06969 if (ResourceListB == NULL) { 06970 06971 return ResourceListA; 06972 06973 } 06974 06975 sizeA = IopDetermineResourceListSize(ResourceListA); 06976 sizeB = IopDetermineResourceListSize(ResourceListB); 06977 06978 if (sizeA && sizeB) { 06979 06980 size = sizeA + sizeB - (sizeof(CM_RESOURCE_LIST) - sizeof(CM_FULL_RESOURCE_DESCRIPTOR)); 06981 newList = (PCM_RESOURCE_LIST)ExAllocatePoolIORRR(PagedPool, size); 06982 if (newList) { 06983 06984 RtlMoveMemory(newList, ResourceListA, sizeA); 06985 RtlMoveMemory( (PUCHAR)newList + sizeA, 06986 (PUCHAR)ResourceListB + (sizeof(CM_RESOURCE_LIST) - sizeof(CM_FULL_RESOURCE_DESCRIPTOR)), 06987 sizeB - (sizeof(CM_RESOURCE_LIST) - sizeof(CM_FULL_RESOURCE_DESCRIPTOR))); 06988 newList->Count += ResourceListB->Count; 06989 } 06990 } 06991 06992 return newList; 06993 }

PCM_RESOURCE_LIST IopCombineLegacyResources IN PDEVICE_NODE  DeviceNode  ) 
 

Definition at line 6726 of file pnpres.c.

References ExAllocatePoolCMRL, IopDetermineResourceListSize(), NTSTATUS(), NULL, _DEVICE_NODE::OverUsed2, PAGED_CODE, PagedPool, and _DEVICE_NODE::ResourceList.

Referenced by IopLegacyResourceAllocation().

06732 : 06733 06734 This routine sets the Root\Legacy_xxxx\0000 device instance path to the 06735 madeup PDO (i.e. DeviceNode) which is created only for legacy resource allocation. 06736 This routine also links the madeup PDO to the Root\Legacy_xxxx\0000 device node 06737 to keep track what resources are assigned to the driver which services the 06738 root\legacy_xxxx\0000 device. 06739 06740 Parameters: 06741 06742 DeviceNode - The legacy device node whose resources need to be combined. 06743 06744 Return Value: 06745 06746 Return the combined resource list. 06747 06748 --*/ 06749 06750 { 06751 NTSTATUS status; 06752 PCM_RESOURCE_LIST combinedList = NULL; 06753 PDEVICE_NODE devNode = DeviceNode; 06754 ULONG size = 0; 06755 PUCHAR p; 06756 06757 PAGED_CODE(); 06758 06759 if (DeviceNode) { 06760 06761 // 06762 // First determine how much memory is needed for the new combined list. 06763 // 06764 06765 while (devNode) { 06766 if (devNode->ResourceList) { 06767 size += IopDetermineResourceListSize(devNode->ResourceList); 06768 } 06769 devNode = (PDEVICE_NODE)devNode->OverUsed2.NextResourceDeviceNode; 06770 } 06771 if (size != 0) { 06772 combinedList = (PCM_RESOURCE_LIST) ExAllocatePoolCMRL(PagedPool, size); 06773 devNode = DeviceNode; 06774 if (combinedList) { 06775 combinedList->Count = 0; 06776 p = (PUCHAR)combinedList; 06777 p += sizeof(ULONG); // Skip Count 06778 while (devNode) { 06779 if (devNode->ResourceList) { 06780 size = IopDetermineResourceListSize(devNode->ResourceList); 06781 if (size != 0) { 06782 size -= sizeof(ULONG); 06783 RtlMoveMemory( 06784 p, 06785 devNode->ResourceList->List, 06786 size 06787 ); 06788 p += size; 06789 combinedList->Count += devNode->ResourceList->Count; 06790 } 06791 } 06792 devNode = (PDEVICE_NODE)devNode->OverUsed2.NextResourceDeviceNode; 06793 } 06794 } 06795 } 06796 } 06797 return combinedList; 06798 }

int __cdecl IopCompareAlternativeCount const void *  arg1,
const void *  arg2
 

Definition at line 1767 of file pnpres.c.

References PAGED_CODE, and _IOP_RESOURCE_REQUEST::Priority.

Referenced by IopRearrangeAssignTable().

01774 : 01775 01776 This routine compares the priority of arg1 and arg1. It is used in C run time sort. 01777 01778 Parameters: 01779 01780 Arg1, arg2 - a pointer to PREQ_ALTERNATIVE 01781 01782 Return Value: 01783 01784 < 0 if arg1 < arg2 01785 = 0 if arg1 = arg2 01786 > 0 if arg1 > arg2 01787 01788 --*/ 01789 01790 { 01791 PIOP_RESOURCE_REQUEST RR1 = (PIOP_RESOURCE_REQUEST)arg1; 01792 PIOP_RESOURCE_REQUEST RR2 = (PIOP_RESOURCE_REQUEST)arg2; 01793 01794 PAGED_CODE(); 01795 01796 if (RR1->Priority == RR2->Priority) { 01797 if ((ULONG_PTR)RR1 < (ULONG_PTR)RR2) { 01798 return -1; 01799 } else { 01800 return 1; 01801 } 01802 } 01803 if (RR1->Priority > RR2->Priority) { 01804 return 1; 01805 } else { 01806 return -1; 01807 } 01808 }

int __cdecl IopComparePriority const void *  arg1,
const void *  arg2
 

Definition at line 1723 of file pnpres.c.

References PAGED_CODE, and PREQ_ALTERNATIVE.

Referenced by IopRearrangeReqList().

01730 : 01731 01732 This routine compares the priority of arg1 and arg1. It is used in C run time sort. 01733 01734 Parameters: 01735 01736 Arg1, arg2 - a pointer to PREQ_ALTERNATIVE 01737 01738 Return Value: 01739 01740 < 0 if arg1 < arg2 01741 = 0 if arg1 = arg2 01742 > 0 if arg1 > arg2 01743 01744 --*/ 01745 01746 { 01747 PREQ_ALTERNATIVE RA1 = *(PREQ_ALTERNATIVE *)arg1; 01748 PREQ_ALTERNATIVE RA2 = *(PREQ_ALTERNATIVE *)arg2; 01749 01750 PAGED_CODE(); 01751 01752 if (RA1->Priority == RA2->Priority) { 01753 if ((ULONG_PTR)RA1 < (ULONG_PTR)RA2) { 01754 return -1; 01755 } else { 01756 return 1; 01757 } 01758 } 01759 if (RA1->Priority > RA2->Priority) { 01760 return 1; 01761 } else { 01762 return -1; 01763 } 01764 } int

PCM_RESOURCE_LIST IopCreateCmResourceList IN PCM_RESOURCE_LIST  ResourceList,
IN INTERFACE_TYPE  InterfaceType,
IN ULONG  BusNumber,
OUT PCM_RESOURCE_LIST *  RemainingList
 

Definition at line 6801 of file pnpres.c.

References BusNumber, ExAllocatePoolIORRR, ExFreePool(), InterfaceType, List, NULL, and PagedPool.

Referenced by IopReserveLegacyBootResources().

06807 { 06808 PCM_RESOURCE_LIST newList = NULL; 06809 ULONG i, j; 06810 ULONG totalSize, matchSize, remainingSize, listSize; 06811 PCM_FULL_RESOURCE_DESCRIPTOR fullResourceDesc, newFullResourceDesc, remainingFullResourceDesc; 06812 PCM_PARTIAL_RESOURCE_DESCRIPTOR partialDescriptor; 06813 06814 06815 // 06816 // Determine the size of memory to be allocated for the matching resource list. 06817 // 06818 06819 fullResourceDesc = &ResourceList->List[0]; 06820 totalSize = FIELD_OFFSET(CM_RESOURCE_LIST, List); 06821 matchSize = 0; 06822 for (i = 0; i < ResourceList->Count; i++) { 06823 06824 // 06825 // Add the size of this descriptor. 06826 // 06827 06828 listSize = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, 06829 PartialResourceList) + 06830 FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, 06831 PartialDescriptors); 06832 06833 partialDescriptor = &fullResourceDesc->PartialResourceList.PartialDescriptors[0]; 06834 for (j = 0; j < fullResourceDesc->PartialResourceList.Count; j++) { 06835 06836 ULONG descriptorSize = sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); 06837 06838 if (partialDescriptor->Type == CmResourceTypeDeviceSpecific) { 06839 06840 descriptorSize += partialDescriptor->u.DeviceSpecificData.DataSize; 06841 } 06842 06843 listSize += descriptorSize; 06844 partialDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) 06845 ((PUCHAR)partialDescriptor + descriptorSize); 06846 06847 } 06848 06849 if ( fullResourceDesc->InterfaceType == InterfaceType && 06850 fullResourceDesc->BusNumber == BusNumber) { 06851 06852 06853 matchSize += listSize; 06854 } 06855 06856 totalSize += listSize; 06857 fullResourceDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) 06858 ((PUCHAR)fullResourceDesc + listSize); 06859 } 06860 06861 if (totalSize) { 06862 06863 if (matchSize) { 06864 06865 matchSize += FIELD_OFFSET(CM_RESOURCE_LIST, List); 06866 06867 } 06868 if (matchSize == totalSize) { 06869 06870 *RemainingList = NULL; 06871 newList = ResourceList; 06872 06873 } else if (matchSize == 0) { 06874 06875 *RemainingList = ResourceList; 06876 06877 } else { 06878 06879 // 06880 // Allocate memory for both lists. 06881 // 06882 06883 newList = (PCM_RESOURCE_LIST)ExAllocatePoolIORRR(PagedPool, matchSize); 06884 06885 if (newList) { 06886 06887 *RemainingList = (PCM_RESOURCE_LIST)ExAllocatePoolIORRR(PagedPool, totalSize - matchSize + FIELD_OFFSET(CM_RESOURCE_LIST, List)); 06888 06889 if (*RemainingList) { 06890 06891 newList->Count = 0; 06892 (*RemainingList)->Count = 0; 06893 newFullResourceDesc = &newList->List[0]; 06894 remainingFullResourceDesc = &(*RemainingList)->List[0]; 06895 fullResourceDesc = &ResourceList->List[0]; 06896 for (i = 0; i < ResourceList->Count; i++) { 06897 06898 listSize = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, 06899 PartialResourceList) + 06900 FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, 06901 PartialDescriptors); 06902 06903 partialDescriptor = &fullResourceDesc->PartialResourceList.PartialDescriptors[0]; 06904 for (j = 0; j < fullResourceDesc->PartialResourceList.Count; j++) { 06905 06906 ULONG descriptorSize = sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); 06907 06908 if (partialDescriptor->Type == CmResourceTypeDeviceSpecific) { 06909 06910 descriptorSize += partialDescriptor->u.DeviceSpecificData.DataSize; 06911 } 06912 06913 listSize += descriptorSize; 06914 partialDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) 06915 ((PUCHAR)partialDescriptor + descriptorSize); 06916 06917 } 06918 06919 if ( fullResourceDesc->InterfaceType == InterfaceType && 06920 fullResourceDesc->BusNumber == BusNumber) { 06921 06922 newList->Count++; 06923 RtlMoveMemory(newFullResourceDesc, fullResourceDesc, listSize); 06924 newFullResourceDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) 06925 ((PUCHAR)newFullResourceDesc + listSize); 06926 } else { 06927 06928 (*RemainingList)->Count++; 06929 RtlMoveMemory(remainingFullResourceDesc, fullResourceDesc, listSize); 06930 remainingFullResourceDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) 06931 ((PUCHAR)remainingFullResourceDesc + listSize); 06932 } 06933 06934 fullResourceDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) 06935 ((PUCHAR)fullResourceDesc + listSize); 06936 } 06937 06938 } else { 06939 06940 ExFreePool(newList); 06941 newList = NULL; 06942 06943 } 06944 06945 } else { 06946 06947 *RemainingList = NULL; 06948 } 06949 } 06950 } 06951 return newList; 06952 }

VOID IopDumpResourceDescriptor IN PUCHAR  Indent,
IN PIO_RESOURCE_DESCRIPTOR  Desc
 

Definition at line 4533 of file pnpres.c.

References DbgPrint.

Referenced by IopDumpResourceRequirementsList(), and IopPlacementForReservation().

04537 { 04538 DbgPrint("%sOpt: %x, Share: %x\t", Indent, Desc->Option, Desc->ShareDisposition); 04539 switch (Desc->Type) { 04540 case CmResourceTypePort: 04541 DbgPrint ("IO Min: %x:%08x, Max: %x:%08x, Algn: %x, Len %x\n", 04542 Desc->u.Port.MinimumAddress.HighPart, Desc->u.Port.MinimumAddress.LowPart, 04543 Desc->u.Port.MaximumAddress.HighPart, Desc->u.Port.MaximumAddress.LowPart, 04544 Desc->u.Port.Alignment, 04545 Desc->u.Port.Length 04546 ); 04547 break; 04548 04549 case CmResourceTypeMemory: 04550 DbgPrint ("MEM Min: %x:%08x, Max: %x:%08x, Algn: %x, Len %x\n", 04551 Desc->u.Memory.MinimumAddress.HighPart, Desc->u.Memory.MinimumAddress.LowPart, 04552 Desc->u.Memory.MaximumAddress.HighPart, Desc->u.Memory.MaximumAddress.LowPart, 04553 Desc->u.Memory.Alignment, 04554 Desc->u.Memory.Length 04555 ); 04556 break; 04557 04558 case CmResourceTypeInterrupt: 04559 DbgPrint ("INT Min: %x, Max: %x\n", 04560 Desc->u.Interrupt.MinimumVector, 04561 Desc->u.Interrupt.MaximumVector 04562 ); 04563 break; 04564 04565 case CmResourceTypeDma: 04566 DbgPrint ("DMA Min: %x, Max: %x\n", 04567 Desc->u.Dma.MinimumChannel, 04568 Desc->u.Dma.MaximumChannel 04569 ); 04570 break; 04571 04572 case CmResourceTypeDevicePrivate: 04573 DbgPrint ("DevicePrivate Data: %x, %x, %x\n", 04574 Desc->u.DevicePrivate.Data[0], 04575 Desc->u.DevicePrivate.Data[1], 04576 Desc->u.DevicePrivate.Data[2] 04577 ); 04578 break; 04579 04580 default: 04581 DbgPrint ("Unknown Descriptor type %x\n", 04582 Desc->Type 04583 ); 04584 break; 04585 } 04586 }

VOID IopDumpResourceRequirementsList IN PIO_RESOURCE_REQUIREMENTS_LIST  IoResources  ) 
 

Definition at line 4480 of file pnpres.c.

References DbgPrint, IopDumpResourceDescriptor(), and NULL.

Referenced by IopGetResourceRequirementsForAssignTable(), and IopReserveBootResourcesInternal().

04486 : 04487 04488 This routine dumps IoResources 04489 04490 Parameters: 04491 04492 IoResources - supplies a pointer to the IO resource requirements list 04493 04494 Return Value: 04495 04496 None. 04497 04498 --*/ 04499 04500 { 04501 PIO_RESOURCE_LIST IoResourceList; 04502 PIO_RESOURCE_DESCRIPTOR IoResourceDescriptor; 04503 PIO_RESOURCE_DESCRIPTOR IoResourceDescriptorEnd; 04504 LONG IoResourceListCount; 04505 04506 if (IoResources == NULL) { 04507 return; 04508 } 04509 IoResourceList = IoResources->List; 04510 IoResourceListCount = (LONG) IoResources->AlternativeLists; 04511 // 04512 // For old IO resource requirements list there is no assigned resources associated with 04513 // it. We simply free the memory. 04514 // 04515 04516 DbgPrint("** ResReqList: Interface: %x, Bus: %x, Slot: %x, AlternativeLists: %x\n", 04517 IoResources->InterfaceType, 04518 IoResources->BusNumber, 04519 IoResources->SlotNumber, 04520 IoResources->AlternativeLists); 04521 while (--IoResourceListCount >= 0) { 04522 DbgPrint (" Alternative List: DescCount: %x\n", IoResourceList->Count); 04523 IoResourceDescriptor = IoResourceList->Descriptors; 04524 IoResourceDescriptorEnd = IoResourceDescriptor + IoResourceList->Count; 04525 for (; IoResourceDescriptor < IoResourceDescriptorEnd; ++IoResourceDescriptor) { 04526 IopDumpResourceDescriptor(" ", IoResourceDescriptor); 04527 } 04528 IoResourceList = (PIO_RESOURCE_LIST) IoResourceDescriptorEnd; 04529 } 04530 DbgPrint("\n"); 04531 } VOID

NTSTATUS IopDuplicateDetection IN INTERFACE_TYPE  LegacyBusType,
IN ULONG  BusNumber,
IN ULONG  SlotNumber,
OUT PDEVICE_NODE DeviceNode
 

Definition at line 6528 of file pnpres.c.

References BusNumber, _INTERFACE::Context, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, ExFreePool(), _INTERFACE::InterfaceDereference, IopFindBusDeviceNode(), IopQueryResourceHandlerInterface(), IopRootDeviceNode, NT_SUCCESS, NTSTATUS(), NULL, _DEVICE_NODE::PhysicalDeviceObject, and ResourceLegacyDeviceDetection.

Referenced by IoReportDetectedDevice().

06537 : 06538 06539 This routine searches for the bus device driver for a given legacy device, 06540 sends a query interface IRP for legacy device detection, and if the driver 06541 implements this interface, requests the PDO for the given legacy device. 06542 06543 Parameters: 06544 06545 LegacyBusType - The legacy device's interface type. 06546 06547 BusNumber - The legacy device's bus number. 06548 06549 SlotNumber - The legacy device's slot number. 06550 06551 DeviceNode - specifies a pointer to a variable to receive the duplicated device node 06552 06553 Return Value: 06554 06555 NTSTATUS code. 06556 06557 --*/ 06558 06559 { 06560 PDEVICE_NODE deviceNode; 06561 PDEVICE_OBJECT busDeviceObject; 06562 PLEGACY_DEVICE_DETECTION_INTERFACE interface; 06563 NTSTATUS status; 06564 PDEVICE_OBJECT deviceObject; 06565 06566 // 06567 // Initialize return parameter to "not found". 06568 // 06569 06570 *DeviceNode = NULL; 06571 06572 // 06573 // Search the device tree for the bus of the legacy device. 06574 // 06575 06576 deviceNode = IopFindBusDeviceNode( 06577 IopRootDeviceNode, 06578 LegacyBusType, 06579 BusNumber, 06580 SlotNumber 06581 ); 06582 06583 // 06584 // Either a bus driver does not exist (or more likely, the legacy bus 06585 // type and bus number were unspecified). Either way, we can't make 06586 // any further progress. 06587 // 06588 06589 if (deviceNode == NULL) { 06590 06591 return STATUS_INVALID_DEVICE_REQUEST; 06592 06593 } 06594 06595 // 06596 // We found the legacy device's bus driver. Query it to determine 06597 // whether it implements the LEGACY_DEVICE_DETECTION interface. 06598 // 06599 06600 busDeviceObject = deviceNode->PhysicalDeviceObject; 06601 06602 status = IopQueryResourceHandlerInterface( 06603 ResourceLegacyDeviceDetection, 06604 busDeviceObject, 06605 0, 06606 (PINTERFACE *)&interface 06607 ); 06608 06609 // 06610 // If it doesn't, we're stuck. 06611 // 06612 06613 if (!NT_SUCCESS(status) || interface == NULL) { 06614 06615 return STATUS_INVALID_DEVICE_REQUEST; 06616 06617 } 06618 06619 // 06620 // Invoke the bus driver's legacy device detection method. 06621 // 06622 06623 status = (*interface->LegacyDeviceDetection)( 06624 interface->Context, 06625 LegacyBusType, 06626 BusNumber, 06627 SlotNumber, 06628 &deviceObject 06629 ); 06630 06631 // 06632 // If it found a legacy device, update the return parameter. 06633 // 06634 06635 if (NT_SUCCESS(status) && deviceObject != NULL) { 06636 06637 *DeviceNode = 06638 (PDEVICE_NODE)deviceObject->DeviceObjectExtension->DeviceNode; 06639 06640 status = STATUS_SUCCESS; 06641 06642 } else { 06643 06644 status = STATUS_INVALID_DEVICE_REQUEST; 06645 06646 } 06647 06648 // 06649 // Free the interface. 06650 // 06651 06652 (*interface->InterfaceDereference)(interface->Context); 06653 06654 ExFreePool(interface); 06655 06656 return status; 06657 }

BOOLEAN IopEliminateBogusConflict IN PDEVICE_OBJECT  PhysicalDeviceObject,
IN PDEVICE_OBJECT  ConflictDeviceObject
 

Definition at line 7775 of file pnpres.c.

References ASSERT, _DEVICE_OBJECT::AttachedDevice, DNF_LEGACY_DRIVER, DO_BUS_ENUMERATED_DEVICE, _DRIVER_OBJECT::DriverExtension, FALSE, _DEVICE_NODE::Flags, IopDatabaseLock, NTSTATUS(), NULL, PAGED_CODE, RtlCompareUnicodeString(), _DRIVER_EXTENSION::ServiceKeyName, _DEVICE_NODE::ServiceName, and TRUE.

Referenced by IopQueryConflictFillConflicts().

07781 : 07782 07783 Determine if we're really conflicting with ourselves 07784 if this is the case, we ignore it 07785 07786 Arguments: 07787 07788 PhysicalDeviceObject PDO we're performing the test for 07789 ConflictDeviceObject The object we've determined is conflicting 07790 07791 Return Value: 07792 07793 TRUE to eliminate the conflict 07794 07795 --*/ 07796 { 07797 NTSTATUS status = STATUS_SUCCESS; 07798 PDEVICE_NODE deviceNode; 07799 PDRIVER_OBJECT driverObject; 07800 KIRQL irql; 07801 PDEVICE_OBJECT attachedDevice; 07802 07803 PAGED_CODE(); 07804 07805 // 07806 // simple cases 07807 // 07808 if (PhysicalDeviceObject == NULL || ConflictDeviceObject == NULL) { 07809 return FALSE; 07810 } 07811 // 07812 // if ConflictDeviceObject is on PDO's stack, this is a non-conflict 07813 // nb at least PDO has to be checked 07814 // 07815 ExAcquireFastLock( &IopDatabaseLock, &irql ); 07816 07817 for (attachedDevice = PhysicalDeviceObject; 07818 attachedDevice; 07819 attachedDevice = attachedDevice->AttachedDevice) { 07820 07821 if (attachedDevice == ConflictDeviceObject) { 07822 ExReleaseFastLock( &IopDatabaseLock, irql ); 07823 return TRUE; 07824 } 07825 } 07826 07827 ExReleaseFastLock( &IopDatabaseLock, irql ); 07828 07829 // 07830 // legacy case 07831 // 07832 deviceNode = PhysicalDeviceObject->DeviceObjectExtension->DeviceNode; 07833 ASSERT(deviceNode); 07834 if (deviceNode->Flags & DNF_LEGACY_DRIVER) { 07835 // 07836 // hmmm, let's see if our ConflictDeviceObject is resources associated with a legacy device 07837 // 07838 if (ConflictDeviceObject->Flags & DO_BUS_ENUMERATED_DEVICE) { 07839 // 07840 // if not, we have a legacy conflicting with non-legacy, we're interested! 07841 // 07842 return FALSE; 07843 } 07844 // 07845 // FDO, report driver name 07846 // 07847 driverObject = ConflictDeviceObject->DriverObject; 07848 if(driverObject == NULL) { 07849 // 07850 // should not be NULL 07851 // 07852 ASSERT(driverObject); 07853 return FALSE; 07854 } 07855 // 07856 // compare deviceNode->Service with driverObject->Service 07857 // 07858 if (deviceNode->ServiceName.Length != 0 && 07859 deviceNode->ServiceName.Length == driverObject->DriverExtension->ServiceKeyName.Length && 07860 RtlCompareUnicodeString(&deviceNode->ServiceName,&driverObject->DriverExtension->ServiceKeyName,TRUE)==0) { 07861 // 07862 // the driver's service name is the same that this PDO is associated with 07863 // by ignoring it we could end up ignoring conflicts of simular types of legacy devices 07864 // but since these have to be hand-config'd anyhow, it's prob better than having false conflicts 07865 // (jamiehun) 07866 // 07867 return TRUE; 07868 } 07869 07870 } 07871 return FALSE; 07872 }

PDEVICE_NODE IopFindBusDeviceNode IN PDEVICE_NODE  DeviceNode,
IN INTERFACE_TYPE  InterfaceType,
IN ULONG  BusNumber,
IN ULONG  SlotNumber
 

Definition at line 6408 of file pnpres.c.

References BusNumber, DebugMessage, DUMP_DETAIL, _DEVICE_NODE::InstancePath, InterfaceType, IopFindBusDeviceNodeInternal(), IopRootDeviceNode, and NULL.

Referenced by IopChildToRootTranslation(), IopDuplicateDetection(), IopReleaseResourcesInternal(), and IopSetupArbiterAndTranslators().

06417 : 06418 06419 This routine finds the bus PDO which performs translation and arbitration for the 06420 specified InterfaceType, BusNumber and SlotNumber. 06421 06422 Parameters: 06423 06424 DeviceNode - the root of the PDO to start our search 06425 06426 InterfaceType - Specifies the PDO's interface type. 06427 06428 BusNumber - specifies the PDO's bus number. 06429 06430 SlotNumber - specified the PDO's slot number (UNUSED). 06431 06432 Return Value: 06433 06434 A pointer to the BUS PDO. 06435 06436 --*/ 06437 06438 { 06439 PDEVICE_NODE busDeviceNode = NULL; 06440 06441 UNREFERENCED_PARAMETER(SlotNumber); 06442 06443 if (DeviceNode && InterfaceType != InterfaceTypeUndefined) { 06444 06445 if (InterfaceType == PNPBus) { 06446 // 06447 // if we specified PnpBus as InterfaceType, we know nobody specifies such a bus 06448 // don't waste time looking for BusNumber because it doesn't exist 06449 // 06450 busDeviceNode = NULL; 06451 } else { 06452 // 06453 // search for bus (recursive) 06454 // 06455 busDeviceNode = IopFindBusDeviceNodeInternal(DeviceNode, (InterfaceType == Eisa) ? Isa : InterfaceType, BusNumber); 06456 } 06457 06458 if (busDeviceNode == NULL && DeviceNode == IopRootDeviceNode) { 06459 06460 DebugMessage(DUMP_DETAIL, ("IopFindBusDeviceNode: Found %ws with interface=%08X & bus=%08X\n", DeviceNode->InstancePath.Buffer, InterfaceType, BusNumber)); 06461 return DeviceNode; 06462 } 06463 06464 if (busDeviceNode) { 06465 06466 DebugMessage(DUMP_DETAIL, ("IopFindBusDeviceNode: Found %ws with interface=%08X & bus=%08X\n", busDeviceNode->InstancePath.Buffer, InterfaceType, BusNumber)); 06467 } 06468 } 06469 06470 return busDeviceNode; 06471 }

PDEVICE_NODE IopFindBusDeviceNodeInternal IN PDEVICE_NODE  DeviceNode,
IN INTERFACE_TYPE  InterfaceType,
IN ULONG  BusNumber
 

Definition at line 6474 of file pnpres.c.

References _DEVICE_NODE::BusNumber, BusNumber, _DEVICE_NODE::Child, _DEVICE_NODE::InterfaceType, InterfaceType, NULL, and _DEVICE_NODE::Sibling.

Referenced by IopFindBusDeviceNode().

06482 : 06483 06484 This worker routine finds the bus PDO which performs translation and arbitration for the 06485 specified InterfaceType and BusNumber. 06486 06487 Parameters: 06488 06489 DeviceNode - the root of the PDO to start our search 06490 06491 InterfaceType - Specifies the PDO's interface type. 06492 06493 BusNumber - specifies the PDO's bus number. 06494 06495 Return Value: 06496 06497 A pointer to the BUS PDO. 06498 06499 --*/ 06500 06501 { 06502 PDEVICE_NODE current; 06503 06504 for (current = DeviceNode; current; current = current->Sibling) { 06505 06506 if ( BusNumber == current->BusNumber && 06507 (InterfaceType == current->InterfaceType || 06508 (InterfaceType == Isa && current->InterfaceType == Eisa))) { 06509 06510 return current; 06511 } 06512 06513 if (current->Child) { 06514 06515 PDEVICE_NODE busDeviceNode = IopFindBusDeviceNodeInternal(current->Child, InterfaceType, BusNumber); 06516 06517 if (busDeviceNode) { 06518 06519 return busDeviceNode; 06520 } 06521 } 06522 } 06523 06524 return NULL; 06525 }

NTSTATUS IopFindLegacyDeviceNode IN PDRIVER_OBJECT  DriverObject,
IN PDEVICE_OBJECT DeviceObject  OPTIONAL,
OUT PDEVICE_NODE LegacyDeviceNode,
OUT PDEVICE_OBJECT LegacyPDO
 

Definition at line 5911 of file pnpres.c.

References ASSERT, DebugMessage, DNF_LEGACY_RESOURCE_DEVICENODE, DNF_MADEUP, DNF_PROCESSED, DO_BUS_ENUMERATED_DEVICE, _DEVICE_OBJECT::DriverObject, DUMP_ERROR, DUMP_INFO, _DEVICE_NODE::DuplicatePDO, FALSE, _DEVICE_OBJECT::Flags, _DEVICE_NODE::Flags, IoCreateDevice(), IoDeleteDevice(), IopAllocateDeviceNode(), IopLegacyDeviceNode, IoPnpDriverObject, IopNumberDeviceNodes, IopSetLegacyDeviceInstance(), KeQueryTickCount(), L, NT_SUCCESS, NTSTATUS(), _DEVICE_NODE::PhysicalDeviceObject, and USHORT.

Referenced by IopLegacyResourceAllocation().

05920 : 05921 05922 This routine searches for the device node and device object created for legacy resource 05923 allocation for the DriverObject and DeviceObject. 05924 05925 Parameters: 05926 05927 DriverObject - specifies the driver object doing the legacy allocation. 05928 05929 DeviceObject - specifies the device object. 05930 05931 LegacyDeviceNode - receives the pointer to the legacy device node if found. 05932 05933 LegacyDeviceObject - receives the pointer to the legacy device object if found. 05934 05935 05936 Return Value: 05937 05938 Status code that indicates whether or not the function was successful. 05939 05940 --*/ 05941 05942 { 05943 NTSTATUS status = STATUS_UNSUCCESSFUL; 05944 PDEVICE_NODE deviceNode; 05945 05946 ASSERT(LegacyDeviceNode && LegacyPDO); 05947 05948 05949 // 05950 // Use the device object if it exists. 05951 // 05952 05953 if (DeviceObject) { 05954 05955 deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode; 05956 if (deviceNode) { 05957 05958 *LegacyPDO = DeviceObject; 05959 *LegacyDeviceNode = deviceNode; 05960 status = STATUS_SUCCESS; 05961 05962 } else if (!(DeviceObject->Flags & DO_BUS_ENUMERATED_DEVICE)) { 05963 05964 deviceNode = IopAllocateDeviceNode(DeviceObject); 05965 if (deviceNode) { 05966 05967 deviceNode->Flags |= DNF_LEGACY_RESOURCE_DEVICENODE; 05968 IopSetLegacyDeviceInstance (DriverObject, deviceNode); 05969 *LegacyPDO = DeviceObject; 05970 *LegacyDeviceNode = deviceNode; 05971 status = STATUS_SUCCESS; 05972 05973 } else { 05974 05975 DebugMessage(DUMP_ERROR, ("PNPRES: Failed to allocate device node for PDO %08X\n", DeviceObject)); 05976 status = STATUS_INSUFFICIENT_RESOURCES; 05977 05978 } 05979 05980 } else { 05981 05982 DebugMessage(DUMP_ERROR, ("PNPRES: %08X PDO without a device node!\n", DeviceObject)); 05983 ASSERT(DeviceObject->DeviceObjectExtension->DeviceNode); 05984 05985 } 05986 05987 } else { 05988 05989 // 05990 // Search our list of legacy device nodes. 05991 // 05992 05993 for ( deviceNode = IopLegacyDeviceNode; 05994 deviceNode && deviceNode->DuplicatePDO != (PDEVICE_OBJECT)DriverObject; 05995 deviceNode = deviceNode->NextDeviceNode); 05996 05997 if (deviceNode) { 05998 05999 *LegacyPDO = deviceNode->PhysicalDeviceObject; 06000 *LegacyDeviceNode = deviceNode; 06001 status = STATUS_SUCCESS; 06002 06003 } else { 06004 06005 WCHAR buffer[60]; 06006 UNICODE_STRING deviceName; 06007 LARGE_INTEGER tickCount; 06008 ULONG length; 06009 PDEVICE_OBJECT pdo; 06010 06011 // 06012 // We are seeing this for the first time. 06013 // Create a madeup device node. 06014 // 06015 06016 KeQueryTickCount(&tickCount); 06017 length = _snwprintf(buffer, sizeof(buffer) / sizeof(WCHAR), L"\\Device\\Resource%04u%x", IopNumberDeviceNodes, tickCount.LowPart); 06018 deviceName.MaximumLength = sizeof(buffer); 06019 deviceName.Length = (USHORT)(length * sizeof(WCHAR)); 06020 deviceName.Buffer = buffer; 06021 06022 DebugMessage(DUMP_INFO, ("PNPRES: Creating dummy PDO %ws\n", deviceName.Buffer)); 06023 06024 status = IoCreateDevice( IoPnpDriverObject, 06025 sizeof(IOPNP_DEVICE_EXTENSION), 06026 &deviceName, 06027 FILE_DEVICE_CONTROLLER, 06028 0, 06029 FALSE, 06030 &pdo); 06031 06032 if (NT_SUCCESS(status)) { 06033 06034 pdo->Flags |= DO_BUS_ENUMERATED_DEVICE; 06035 deviceNode = IopAllocateDeviceNode(pdo); 06036 if (deviceNode) { 06037 06038 // 06039 // Change driver object to the caller even though the owner 06040 // of the pdo is IoPnpDriverObject. This is to support 06041 // DriverExclusive for legacy interface. 06042 // 06043 06044 pdo->DriverObject = DriverObject; 06045 deviceNode->Flags = DNF_MADEUP | DNF_PROCESSED | DNF_LEGACY_RESOURCE_DEVICENODE; 06046 deviceNode->DuplicatePDO = (PDEVICE_OBJECT)DriverObject; 06047 IopSetLegacyDeviceInstance (DriverObject, deviceNode); 06048 06049 // 06050 // Add it to our list of legacy device nodes rather than adding it to the HW tree. 06051 // 06052 06053 deviceNode->NextDeviceNode = IopLegacyDeviceNode; 06054 if (IopLegacyDeviceNode) { 06055 06056 IopLegacyDeviceNode->PreviousDeviceNode = deviceNode; 06057 06058 } 06059 IopLegacyDeviceNode = deviceNode; 06060 *LegacyPDO = pdo; 06061 *LegacyDeviceNode = deviceNode; 06062 06063 } else { 06064 06065 DebugMessage(DUMP_ERROR, ("PNPRES: Failed to allocate device node for PDO %08X\n", pdo)); 06066 IoDeleteDevice(pdo); 06067 status = STATUS_INSUFFICIENT_RESOURCES; 06068 06069 } 06070 06071 } else { 06072 06073 DebugMessage(DUMP_ERROR, ("PNPRES: IoCreateDevice failed for %ws with status %08X\n", deviceName.Buffer, status)); 06074 06075 } 06076 } 06077 } 06078 06079 return status; 06080 }

BOOLEAN IopFindResourceHandlerInfo IN RESOURCE_HANDLER_TYPE  HandlerType,
IN PDEVICE_NODE  DeviceNode,
IN UCHAR  ResourceType,
OUT PVOID *  HandlerEntry
 

Definition at line 3424 of file pnpres.c.

References _PI_RESOURCE_ARBITER_ENTRY::ArbiterInterface, ASSERT, FALSE, NULL, PI_MAXIMUM_RESOURCE_TYPE_TRACKED, ResourceArbiter, ResourceTranslator, _PI_RESOURCE_ARBITER_ENTRY::ResourceType, TRUE, and USHORT.

Referenced by IopSetupArbiterAndTranslators().

03433 : 03434 03435 This routine finds the desired resource handler interface for the specified 03436 resource type in the specified Device node. 03437 03438 Parameters: 03439 03440 HandlerType - Specifies the type of handler needed. 03441 03442 DeviceNode - specifies the device node from where to search for handler 03443 03444 ResourceTYpe - specifies the type of resource. 03445 03446 HandlerEntry - supplies a pointer to a variable to receive the handler. 03447 03448 Return Value: 03449 03450 TRUE + non-null HandlerEntry : Find handler info and there is a handler 03451 TRUE + NULL HandlerEntry : Find handler info and there is NO handler 03452 FALSE + NULL HandlerEntry : No handler info found. 03453 03454 --*/ 03455 { 03456 USHORT resourceMask; 03457 USHORT noHandlerMask, queryHandlerMask; 03458 PLIST_ENTRY listHead, nextEntry; 03459 PPI_RESOURCE_ARBITER_ENTRY arbiterEntry; 03460 03461 *HandlerEntry = NULL; 03462 03463 switch (HandlerType) { 03464 case ResourceArbiter: 03465 noHandlerMask = DeviceNode->NoArbiterMask; 03466 queryHandlerMask = DeviceNode->QueryArbiterMask; 03467 listHead = &DeviceNode->DeviceArbiterList; 03468 break; 03469 03470 case ResourceTranslator: 03471 noHandlerMask = DeviceNode->NoTranslatorMask; 03472 queryHandlerMask = DeviceNode->QueryTranslatorMask; 03473 listHead = &DeviceNode->DeviceTranslatorList; 03474 break; 03475 03476 default: 03477 return FALSE; 03478 } 03479 03480 resourceMask = 1 << ResourceType; 03481 if (noHandlerMask & resourceMask) { 03482 03483 // 03484 // There is no desired handler for the resource type in this device node 03485 // 03486 03487 return TRUE; 03488 } 03489 03490 if (queryHandlerMask & resourceMask) { 03491 03492 // 03493 // Has handler for the resource type in this device node. 03494 // look for it ... 03495 // 03496 03497 nextEntry = listHead->Flink; 03498 for (; nextEntry != listHead; nextEntry = nextEntry->Flink) { 03499 arbiterEntry = CONTAINING_RECORD(nextEntry, PI_RESOURCE_ARBITER_ENTRY, DeviceArbiterList); 03500 if (arbiterEntry->ResourceType == ResourceType) { 03501 break; 03502 } 03503 } 03504 ASSERT(nextEntry != listHead); // There must be one ... 03505 *HandlerEntry = arbiterEntry; 03506 return TRUE; 03507 03508 } else { 03509 03510 // 03511 // If we are here there are two cases: 03512 // We have not query the desired interface yet or 03513 // the resource type is out of the range we are tracking using masks. 03514 // In this case, we need to go thru the link list. 03515 // 03516 03517 if (ResourceType > PI_MAXIMUM_RESOURCE_TYPE_TRACKED) { 03518 nextEntry = listHead->Flink; 03519 for (; nextEntry != listHead; nextEntry = nextEntry->Flink) { 03520 arbiterEntry = CONTAINING_RECORD(nextEntry, PI_RESOURCE_ARBITER_ENTRY, DeviceArbiterList); 03521 if (arbiterEntry->ResourceType == ResourceType) { 03522 if (arbiterEntry->ArbiterInterface) { 03523 *HandlerEntry = arbiterEntry; 03524 } 03525 return TRUE; 03526 } 03527 } 03528 } 03529 return FALSE; 03530 } 03531 }

NTSTATUS IopFindResourcesForArbiter IN PDEVICE_NODE  DeviceNode,
IN UCHAR  ResourceType,
OUT ULONG *  Count,
OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR *  CmDesc
 

Definition at line 5121 of file pnpres.c.

References Count, DebugMessage, DNF_STARTED, DUMP_ERROR, ExAllocatePoolPRD, NULL, PagedPool, _IOP_RESOURCE_REQUEST::PhysicalDevice, PiAssignTable, PiAssignTableCount, PREQ_ALTERNATIVE, PREQ_DESC, PREQ_LIST, and _IOP_RESOURCE_REQUEST::ReqList.

Referenced by IopArbitrateDeviceResources().

05130 : 05131 05132 This routine returns the resources required by the ResourceType arbiter in DeviceNode. 05133 05134 Parameters: 05135 05136 DeviceNode -specifies the device node whose ResourceType arbiter is requesting for resources 05137 05138 ResourceType - specifies the resource type 05139 05140 Count - specifies a pointer to a varaible to receive the count of Cm descriptors returned 05141 05142 CmDesc - specifies a pointer to a varibble to receive the returned cm descriptor. 05143 05144 Return Value: 05145 05146 Status code that indicates whether or not the function was successful. 05147 05148 --*/ 05149 05150 { 05151 PIOP_RESOURCE_REQUEST assignEntry; 05152 PREQ_ALTERNATIVE reqAlternative; 05153 PREQ_DESC reqDesc; 05154 ULONG i, count = 0; 05155 PCM_PARTIAL_RESOURCE_DESCRIPTOR cmDescriptor; 05156 05157 *Count = 0; 05158 *CmDesc = NULL; 05159 if (DeviceNode->Flags & DNF_STARTED) { 05160 return STATUS_SUCCESS; 05161 } 05162 05163 // 05164 // Find this device node's IOP_RESOURCE_REQUEST structure first 05165 // 05166 05167 for (assignEntry = PiAssignTable + PiAssignTableCount - 1; 05168 assignEntry >= PiAssignTable; 05169 assignEntry--) { 05170 if (assignEntry->PhysicalDevice == DeviceNode->PhysicalDeviceObject) { 05171 break; 05172 } 05173 } 05174 if (assignEntry < PiAssignTable) { 05175 DebugMessage(DUMP_ERROR, ("Rebalance: No resreqlist for Arbiter? Can not find Arbiter assign table entry\n")); 05176 return STATUS_UNSUCCESSFUL; 05177 } 05178 05179 reqAlternative = *((PREQ_LIST)assignEntry->ReqList)->SelectedAlternative; 05180 for (i = 0; i < reqAlternative->ReqDescCount; i++) { 05181 reqDesc = reqAlternative->ReqDescTable[i]->TranslatedReqDesc; 05182 if (reqDesc->Allocation.Type == ResourceType) { 05183 count++; 05184 } 05185 } 05186 05187 cmDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ExAllocatePoolPRD( 05188 PagedPool, 05189 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * count 05190 ); 05191 if (!cmDescriptor) { 05192 05193 // 05194 // If we can not find memory, the resources will not be committed by arbiter. 05195 // 05196 05197 DebugMessage(DUMP_ERROR, ("Rebalance: Not enough memory to perform rebalance\n")); 05198 return STATUS_INSUFFICIENT_RESOURCES; 05199 } 05200 05201 *Count = count; 05202 *CmDesc = cmDescriptor; 05203 05204 for (i = 0; i < reqAlternative->ReqDescCount; i++) { 05205 reqDesc = reqAlternative->ReqDescTable[i]->TranslatedReqDesc; 05206 if (reqDesc->Allocation.Type == ResourceType) { 05207 *cmDescriptor = reqDesc->Allocation; 05208 cmDescriptor++; 05209 } 05210 } 05211 return STATUS_SUCCESS; 05212 }

VOID IopFreeReqAlternative IN PREQ_ALTERNATIVE  ReqAlternative  ) 
 

Definition at line 1922 of file pnpres.c.

References ExFreePool(), IS_TRANSLATED_REQ_DESC, PAGED_CODE, and PREQ_DESC.

Referenced by IopFreeReqList(), and IopResourceRequirementsListToReqList().

01925 { 01926 PREQ_DESC reqDesc, reqDescx; 01927 ULONG i; 01928 01929 PAGED_CODE(); 01930 01931 if (ReqAlternative) { 01932 for (i = 0; i < ReqAlternative->ReqDescCount; i++) { 01933 reqDesc = ReqAlternative->ReqDescTable[i]; 01934 reqDescx = reqDesc->TranslatedReqDesc; 01935 while (reqDescx && IS_TRANSLATED_REQ_DESC(reqDescx)) { 01936 reqDesc = reqDescx; 01937 if (reqDescx->AlternativeTable.Alternatives) { 01938 ExFreePool(reqDescx->AlternativeTable.Alternatives); 01939 } 01940 reqDescx = reqDescx->TranslatedReqDesc; 01941 ExFreePool(reqDesc); 01942 } 01943 } 01944 } 01945 }

VOID IopFreeReqList IN PREQ_LIST  ReqList  ) 
 

Definition at line 1948 of file pnpres.c.

References ExFreePool(), IopFreeReqAlternative(), and PAGED_CODE.

Referenced by IopFreeResourceRequirementsForAssignTable(), IopQueryConflictListInternal(), IopReserveBootResourcesInternal(), and IopResourceRequirementsListToReqList().

01954 : 01955 01956 This routine release the ReqList associated with a resource requirements list 01957 01958 Parameters: 01959 01960 ReqList - supplies a pointer to the REQ_LIST. 01961 01962 Return Value: 01963 01964 None. 01965 01966 --*/ 01967 01968 { 01969 ULONG i; 01970 01971 PAGED_CODE(); 01972 01973 if (ReqList) { 01974 01975 // 01976 // First we need to free all the *extra* req descs for translators. 01977 // The default Req Desc will be freed when the ReqList is freed. 01978 // 01979 01980 for (i = 0; i < ReqList->ReqAlternativeCount; i++) { 01981 IopFreeReqAlternative(ReqList->ReqAlternativeTable[i]); 01982 } 01983 ExFreePool(ReqList); 01984 } 01985 }

VOID IopFreeResourceRequirementsForAssignTable IN PIOP_RESOURCE_REQUEST  AssignTable,
IN PIOP_RESOURCE_REQUEST  AssignTableEnd
 

Definition at line 1988 of file pnpres.c.

References ExFreePool(), _IOP_RESOURCE_REQUEST::Flags, IOP_ASSIGN_KEEP_CURRENT_CONFIG, IopFreeReqList(), NULL, PAGED_CODE, _IOP_RESOURCE_REQUEST::ReqList, and _IOP_RESOURCE_REQUEST::ResourceRequirements.

Referenced by IopAllocateResources(), IopGetResourceRequirementsForAssignTable(), IopReallocateResources(), IopRebalance(), and IopRestoreResourcesInternal().

01995 : 01996 01997 For each AssignTable entry, this routine frees its attached REQ_LIST. 01998 01999 Parameters: 02000 02001 AssignTable - supplies a pointer to the first entry of a IOP_RESOURCE_REQUEST table. 02002 02003 AssignTableEnd - supplies a pointer to the end of IOP_RESOURCE_REQUEST table. 02004 02005 Return Value: 02006 02007 None. 02008 02009 --*/ 02010 02011 { 02012 PIOP_RESOURCE_REQUEST AssignEntry; 02013 02014 PAGED_CODE(); 02015 02016 for (AssignEntry = AssignTable; AssignEntry < AssignTableEnd; ++AssignEntry) { 02017 IopFreeReqList(AssignEntry->ReqList); 02018 AssignEntry->ReqList = NULL; 02019 if (AssignEntry->Flags & IOP_ASSIGN_KEEP_CURRENT_CONFIG && 02020 AssignEntry->ResourceRequirements) { 02021 02022 // 02023 // The REAL resreq list is cached in DeviceNode->ResourceRequirements. 02024 // We need to free the filtered list. 02025 // 02026 02027 ExFreePool(AssignEntry->ResourceRequirements); 02028 AssignEntry->ResourceRequirements = NULL; 02029 } 02030 } 02031 }

NTSTATUS IopGetResourceRequirementsForAssignTable IN PIOP_RESOURCE_REQUEST  AssignTable,
IN PIOP_RESOURCE_REQUEST  AssignTableEnd,
OUT PULONG  DeviceCount
 

Definition at line 1066 of file pnpres.c.

References _IOP_RESOURCE_REQUEST::AllocationType, ArbiterRequestPnpEnumerated, Count, DebugMessage, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, DNF_RESOURCE_REQUIREMENTS_CHANGED, DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED, DUMP_DETAIL, DUMP_INFO, ExFreePool(), _DEVICE_NODE::Flags, _IOP_RESOURCE_REQUEST::Flags, _DEVICE_NODE::InstancePath, IOP_ASSIGN_CLEAR_RESOURCE_REQUIREMENTS_CHANGE_FLAG, IOP_ASSIGN_IGNORE, IOP_ASSIGN_KEEP_CURRENT_CONFIG, IopDumpResourceRequirementsList(), IopFilterResourceRequirementsList(), IopFreeResourceRequirementsForAssignTable(), IopQueryDeviceResources(), IopRearrangeReqList(), IopResourceRequirementsListToReqList(), NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, _IOP_RESOURCE_REQUEST::PhysicalDevice, PnpResDebugLevel, PREQ_LIST, _IOP_RESOURCE_REQUEST::Priority, QUERY_RESOURCE_REQUIREMENTS, _IOP_RESOURCE_REQUEST::ReqList, _IOP_RESOURCE_REQUEST::ResourceAssignment, _DEVICE_NODE::ResourceList, _IOP_RESOURCE_REQUEST::ResourceRequirements, _DEVICE_NODE::ResourceRequirements, _IOP_RESOURCE_REQUEST::Status, Status, and _IOP_RESOURCE_REQUEST::TranslatedResourceAssignment.

Referenced by IopAllocateResources(), IopReallocateResources(), and IopRebalance().

01074 : 01075 01076 For each AssignTable entry, this routine queries device's IO resource requirements 01077 list and converts it to our internal REQ_LIST format. 01078 01079 Parameters: 01080 01081 AssignTable - supplies a pointer to the first entry of a IOP_RESOURCE_REQUEST table. 01082 01083 AssignTableEnd - supplies a pointer to the end of IOP_RESOURCE_REQUEST table. 01084 01085 Return Value: 01086 01087 Status code that indicates whether or not the function was successful. 01088 01089 --*/ 01090 01091 { 01092 NTSTATUS Status, FinalStatus = STATUS_UNSUCCESSFUL; 01093 PIOP_RESOURCE_REQUEST AssignEntry; 01094 PDEVICE_OBJECT PhysicalDevice; 01095 PDEVICE_NODE DeviceNode; 01096 ULONG Length, Count = 0; 01097 01098 PAGED_CODE(); 01099 01100 // 01101 // Go thru each entry, if the io resource requirements is not established, 01102 // we will first see if the device node contains an io resreq, if yes, we will 01103 // use it. Otherwise, we will query resource requirements from the driver and cache 01104 // it in our device node structure. 01105 // 01106 01107 for (AssignEntry = AssignTable; AssignEntry < AssignTableEnd; ++AssignEntry) { 01108 01109 AssignEntry->ReqList = NULL; 01110 if (AssignEntry->Flags & IOP_ASSIGN_IGNORE) { 01111 FinalStatus = STATUS_SUCCESS; 01112 continue; 01113 } 01114 01115 AssignEntry->ResourceAssignment = NULL; 01116 AssignEntry->TranslatedResourceAssignment = NULL; 01117 PhysicalDevice = AssignEntry->PhysicalDevice; 01118 DeviceNode = (PDEVICE_NODE)PhysicalDevice->DeviceObjectExtension->DeviceNode; 01119 01120 if (DeviceNode->Flags & DNF_RESOURCE_REQUIREMENTS_CHANGED) { 01121 if (DeviceNode->ResourceRequirements) { 01122 ExFreePool(DeviceNode->ResourceRequirements); 01123 DeviceNode->ResourceRequirements = NULL; 01124 01125 // 01126 // Mark that we need to cleare the resource requirements changed flag when 01127 // succeed. 01128 // 01129 01130 AssignEntry->Flags |= IOP_ASSIGN_CLEAR_RESOURCE_REQUIREMENTS_CHANGE_FLAG; 01131 DeviceNode->Flags &= ~DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED; 01132 //DeviceNode->Flags &= ~DNF_RESOURCE_REQUIREMENTS_CHANGED; 01133 } 01134 } 01135 01136 if (!AssignEntry->ResourceRequirements) { 01137 if (DeviceNode->ResourceRequirements && 01138 !(DeviceNode->Flags & DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED)) { 01139 DebugMessage(DUMP_DETAIL, ("Pnpres: Resource requirements list already exists for %ws\n", DeviceNode->InstancePath.Buffer)); 01140 AssignEntry->ResourceRequirements = DeviceNode->ResourceRequirements; 01141 AssignEntry->AllocationType = ArbiterRequestPnpEnumerated; 01142 } else { 01143 DebugMessage(DUMP_INFO,("Pnpres: Query Resource requirements list for %ws...\n", DeviceNode->InstancePath.Buffer)); 01144 Status = IopQueryDeviceResources (PhysicalDevice, 01145 QUERY_RESOURCE_REQUIREMENTS, 01146 &AssignEntry->ResourceRequirements, 01147 &Length 01148 ); 01149 if (!NT_SUCCESS(Status)) { 01150 AssignEntry->Flags |= IOP_ASSIGN_IGNORE; 01151 AssignEntry->Status = Status; 01152 continue; 01153 } else if (AssignEntry->ResourceRequirements == NULL) { 01154 01155 // 01156 // Status Success with NULL ResourceRequirements means 01157 // no resource required. 01158 // 01159 01160 AssignEntry->Flags |= IOP_ASSIGN_IGNORE; 01161 AssignEntry->Status = Status; 01162 continue; 01163 } 01164 if (DeviceNode->ResourceRequirements) { 01165 ExFreePool(DeviceNode->ResourceRequirements); 01166 DeviceNode->Flags &= ~DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED; 01167 } 01168 DeviceNode->ResourceRequirements = AssignEntry->ResourceRequirements; 01169 } 01170 } 01171 01172 // 01173 // For non-stop case, even though the res req list has changed, we need 01174 // to guarantee that it still get its current setting, if possible. 01175 // Note, if the new resreq list does not cover the old setting. It's bus 01176 // drivers' responsibility to guarantee that non of their child would be 01177 // affected. Otherwise, the bus drivers should not ask for non-stop. 01178 // 01179 01180 if (AssignEntry->Flags & IOP_ASSIGN_KEEP_CURRENT_CONFIG) { 01181 PIO_RESOURCE_REQUIREMENTS_LIST filteredList; 01182 BOOLEAN exactMatch; 01183 01184 Status = IopFilterResourceRequirementsList ( 01185 AssignEntry->ResourceRequirements, 01186 DeviceNode->ResourceList, 01187 &filteredList, 01188 &exactMatch 01189 ); 01190 if (NT_SUCCESS(Status)) { 01191 01192 // 01193 // Do not free the original AssignEntry->ResourceRequirements. 01194 // It is used by deviceNode->ResourceRequirements. 01195 // 01196 01197 AssignEntry->ResourceRequirements = filteredList; 01198 } else { 01199 AssignEntry->Flags &= ~IOP_ASSIGN_KEEP_CURRENT_CONFIG; 01200 } 01201 } 01202 01203 #if DBG_SCOPE 01204 if (PnpResDebugLevel & DUMP_INFO) { 01205 IopDumpResourceRequirementsList(AssignEntry->ResourceRequirements); 01206 } 01207 #endif 01208 01209 // 01210 // Convert Io resource requirements list to our internal representation. 01211 // 01212 01213 Status = IopResourceRequirementsListToReqList( 01214 AssignEntry->AllocationType, 01215 AssignEntry->ResourceRequirements, 01216 PhysicalDevice, 01217 &AssignEntry->ReqList); 01218 01219 if (!NT_SUCCESS(Status) || AssignEntry->ReqList == NULL) { 01220 AssignEntry->Flags |= IOP_ASSIGN_IGNORE; 01221 AssignEntry->Status = Status; 01222 continue; 01223 } else { 01224 PREQ_LIST ReqList; 01225 01226 ReqList = (PREQ_LIST)AssignEntry->ReqList; 01227 ReqList->AssignEntry = AssignEntry; 01228 01229 // 01230 // Sort the ReqList such that the higher priority Alternative list are 01231 // placed in the front of the list. 01232 // 01233 01234 IopRearrangeReqList(ReqList); 01235 if (ReqList->ReqBestAlternative == NULL) { 01236 01237 AssignEntry->Flags |= IOP_ASSIGN_IGNORE; 01238 AssignEntry->Status = STATUS_DEVICE_CONFIGURATION_ERROR; 01239 IopFreeResourceRequirementsForAssignTable(AssignEntry, AssignEntry + 1); 01240 continue; 01241 01242 } else if (ReqList->ReqAlternativeCount < 3) { 01243 01244 AssignEntry->Priority = 0; 01245 01246 } else { 01247 01248 AssignEntry->Priority = ReqList->ReqAlternativeCount; 01249 01250 } 01251 } 01252 01253 AssignEntry->Status = STATUS_SUCCESS; 01254 Count++; 01255 01256 // 01257 // As long as there is one entry established, we will return success. 01258 // 01259 01260 FinalStatus = STATUS_SUCCESS; 01261 } 01262 *DeviceCount = Count; 01263 return FinalStatus; 01264 }

BOOLEAN IopIsBestConfiguration IN  VOID  ) 
 

Definition at line 2845 of file pnpres.c.

References FALSE, _IOP_RESOURCE_REQUEST::Flags, IOP_ASSIGN_EXCLUDE, PiAssignTable, PiAssignTableCount, PiBestPriority, PiNoRetest, PREQ_ALTERNATIVE, PREQ_LIST, _IOP_RESOURCE_REQUEST::Priority, _IOP_RESOURCE_REQUEST::ReqList, and TRUE.

Referenced by IopAssign().

02851 : 02852 02853 This routine checks if the current resource assignment yields the best score. 02854 If yes, this routine updates the static variable to reflect the best score. 02855 02856 Parameters: 02857 02858 None. 02859 02860 Return Value: 02861 02862 TRUE or FALSE. 02863 02864 --*/ 02865 02866 { 02867 ULONG i, priority = 0; 02868 PREQ_ALTERNATIVE reqAlternative; 02869 PIOP_RESOURCE_REQUEST assignEntry; 02870 02871 // 02872 // If PiNoRetest is set. There is only one. So, it is the best. 02873 // 02874 02875 if (PiNoRetest) { 02876 return TRUE; 02877 } 02878 02879 // 02880 // Go thru all the assign tables to collect priority 02881 // 02882 02883 for (i = 0; i < PiAssignTableCount; i++) { 02884 assignEntry = PiAssignTable + i; 02885 02886 if (!(assignEntry->Flags & IOP_ASSIGN_EXCLUDE)) { 02887 reqAlternative = *((PREQ_LIST)assignEntry->ReqList)->SelectedAlternative; 02888 priority += reqAlternative->Priority; 02889 } 02890 } 02891 02892 // 02893 // If the new priority is better than current best priority. 02894 // Update the current best. 02895 // 02896 02897 if (priority < PiBestPriority) { 02898 PiBestPriority = priority; 02899 return TRUE; 02900 } else { 02901 return FALSE; 02902 } 02903 }

NTSTATUS IopLegacyResourceAllocation IN ARBITER_REQUEST_SOURCE  AllocationType,
IN PDRIVER_OBJECT  DriverObject,
IN PDEVICE_OBJECT DeviceObject  OPTIONAL,
IN PIO_RESOURCE_REQUIREMENTS_LIST  ResourceRequirements,
IN OUT PCM_RESOURCE_LIST *AllocatedResources  OPTIONAL
 

Definition at line 6180 of file pnpres.c.

References _IOP_RESOURCE_REQUEST::AllocationType, ArbiterRequestPnpDetected, ASSERT, DebugMessage, DelayExecution, DNF_ASSIGNING_RESOURCES, DNF_RESOURCE_ASSIGNED, DNF_RESOURCE_REPORTED, DRVO_LEGACY_RESOURCES, DUMP_ERROR, ExAllocatePoolIORL, ExFreePool(), FALSE, _IOP_RESOURCE_REQUEST::Flags, _DEVICE_NODE::Flags, IOP_ASSIGN_NO_REBALANCE, IopAllocateResources(), IopCombineLegacyResources(), IopDatabaseLock, IopDetermineResourceListSize(), IopFindLegacyDeviceNode(), IoPnpDriverObject, IopRegistrySemaphore, IopReleaseResources(), IopRemoveLegacyDeviceNode(), IopRootDeviceNode, IopWriteAllocatedResourcesToRegistry(), KeEnterCriticalRegion, KeLeaveCriticalRegion, KeReleaseSemaphore(), KernelMode, KeWaitForSingleObject(), NT_SUCCESS, NTSTATUS(), NULL, _DEVICE_NODE::OverUsed1, PagedPool, _DEVICE_NODE::Parent, _IOP_RESOURCE_REQUEST::PhysicalDevice, PnpDefaultInterfaceType, _DEVICE_NODE::ResourceList, _DEVICE_NODE::ResourceListTranslated, _IOP_RESOURCE_REQUEST::ResourceRequirements, and TRUE.

Referenced by IoAssignResources(), IopReleaseDeviceResources(), and IoReportResourceUsageInternal().

06190 : 06191 06192 This routine handles legacy interface IoAssignResources and IoReportResourcesUsage, 06193 It converts the request to call IopAllocateResources. 06194 06195 Parameters: 06196 06197 AllocationType - Allocation type for the legacy request. 06198 06199 DriverObject - Driver object doing the legacy allocation. 06200 06201 DeviceObject - Device object. 06202 06203 ResourceRequirements - Legacy resource requirements. If NULL, caller want to free resources. 06204 06205 AllocatedResources - Pointer to a variable that receives pointer to allocated resources. 06206 06207 Return Value: 06208 06209 Status code that indicates whether or not the function was successful. 06210 06211 --*/ 06212 06213 { 06214 PDEVICE_OBJECT pdo; 06215 PDEVICE_NODE deviceNode; 06216 PDEVICE_NODE legacyDeviceNode; 06217 NTSTATUS status; 06218 PCM_RESOURCE_LIST combinedResources; 06219 KIRQL irql; 06220 06221 ASSERT(DriverObject); 06222 06223 // 06224 // Grab the IO registry semaphore to make sure no other device is 06225 // reporting it's resource usage while we are searching for conflicts. 06226 // 06227 06228 KeEnterCriticalRegion(); 06229 06230 status = KeWaitForSingleObject( &IopRegistrySemaphore, 06231 DelayExecution, 06232 KernelMode, 06233 FALSE, 06234 NULL); 06235 if (NT_SUCCESS(status)) { 06236 06237 status = IopFindLegacyDeviceNode(DriverObject, DeviceObject, &deviceNode, &pdo); 06238 if (NT_SUCCESS(status)) { 06239 06240 legacyDeviceNode = NULL; 06241 if (!deviceNode->Parent && ResourceRequirements) { 06242 06243 // 06244 // Make IopRootDeviceNode the bus pdo so we will search the right bus pdo 06245 // on resource descriptor level. 06246 // 06247 06248 if (ResourceRequirements->InterfaceType == InterfaceTypeUndefined) { 06249 06250 ResourceRequirements->InterfaceType = PnpDefaultInterfaceType; 06251 06252 } 06253 deviceNode->Parent = IopRootDeviceNode; 06254 06255 } 06256 06257 // 06258 // Release resources for this device node. 06259 // 06260 06261 if ( (!ResourceRequirements && deviceNode->Parent) || 06262 (deviceNode->Flags & (DNF_RESOURCE_REPORTED | DNF_RESOURCE_ASSIGNED))) { 06263 06264 IopReleaseResources(deviceNode); 06265 06266 } 06267 06268 if (ResourceRequirements) { 06269 06270 IOP_RESOURCE_REQUEST requestTable; 06271 IOP_RESOURCE_REQUEST *requestTablep; 06272 ULONG count; 06273 06274 // 06275 // Try to allocate these resource requirements. 06276 // 06277 06278 count = 1; 06279 RtlZeroMemory(&requestTable, sizeof(IOP_RESOURCE_REQUEST)); 06280 requestTable.ResourceRequirements = ResourceRequirements; 06281 requestTable.PhysicalDevice = pdo; 06282 requestTable.Flags = IOP_ASSIGN_NO_REBALANCE; 06283 requestTable.AllocationType = AllocationType; 06284 06285 deviceNode->Flags |= DNF_ASSIGNING_RESOURCES; 06286 requestTablep = &requestTable; 06287 IopAllocateResources(&count, &requestTablep, TRUE, TRUE); 06288 deviceNode->Flags &= ~DNF_ASSIGNING_RESOURCES; 06289 status = requestTable.Status; 06290 if (NT_SUCCESS(status)) { 06291 06292 deviceNode->Flags |= DNF_RESOURCE_REPORTED; 06293 //deviceNode->Flags &= ~DNF_INSUFFICIENT_RESOURCES; 06294 deviceNode->ResourceListTranslated = requestTable.TranslatedResourceAssignment; 06295 count = IopDetermineResourceListSize((*AllocatedResources) ? *AllocatedResources : requestTable.ResourceAssignment); 06296 deviceNode->ResourceList = ExAllocatePoolIORL(PagedPool, count); 06297 if (deviceNode->ResourceList) { 06298 06299 if (*AllocatedResources) { 06300 06301 // 06302 // We got called from IoReportResourceUsage. 06303 // 06304 06305 ASSERT(requestTable.ResourceAssignment); 06306 ExFreePool(requestTable.ResourceAssignment); 06307 06308 } else { 06309 06310 // 06311 // We got called from IoAssignResources. 06312 // 06313 06314 *AllocatedResources = requestTable.ResourceAssignment; 06315 06316 } 06317 RtlCopyMemory(deviceNode->ResourceList, *AllocatedResources, count); 06318 legacyDeviceNode = (PDEVICE_NODE)deviceNode->OverUsed1.LegacyDeviceNode; 06319 06320 } else { 06321 06322 deviceNode->ResourceList = requestTable.ResourceAssignment; 06323 IopReleaseResources(deviceNode); 06324 status = STATUS_INSUFFICIENT_RESOURCES; 06325 06326 } 06327 } 06328 06329 // 06330 // Remove the madeup PDO and device node if there was some error. 06331 // 06332 06333 if (!NT_SUCCESS(status)) { 06334 06335 IopRemoveLegacyDeviceNode(DeviceObject, deviceNode); 06336 06337 } 06338 06339 } else { 06340 06341 // 06342 // Caller wants to release resources. 06343 // 06344 06345 legacyDeviceNode = (PDEVICE_NODE)deviceNode->OverUsed1.LegacyDeviceNode; 06346 IopRemoveLegacyDeviceNode(DeviceObject, deviceNode); 06347 06348 } 06349 06350 if (NT_SUCCESS(status)) { 06351 06352 if (legacyDeviceNode) { 06353 06354 // 06355 // After the resource is modified, update the allocated resource list 06356 // for the Root\Legacy_xxxx\0000 device instance. 06357 // 06358 06359 combinedResources = IopCombineLegacyResources(legacyDeviceNode); 06360 if (combinedResources) { 06361 06362 IopWriteAllocatedResourcesToRegistry( legacyDeviceNode, 06363 combinedResources, 06364 IopDetermineResourceListSize(combinedResources)); 06365 ExFreePool(combinedResources); 06366 } 06367 } 06368 06369 // 06370 // BUGBUG: Santoshj 10/01/99 06371 // Since IoReportDetectedDevice always uses IoPnpDriverObject instead of the one 06372 // passed in, we put in this hack so that we dont taint ourselves. Other bugs need 06373 // to be fixed before removing this hack (dont do resource allocation if this 06374 // was already reported). 06375 // 06376 06377 if (AllocationType != ArbiterRequestPnpDetected && DriverObject != IoPnpDriverObject) { 06378 // 06379 // Modify the DRVOBJ flags. 06380 // 06381 ExAcquireFastLock(&IopDatabaseLock, &irql); 06382 if (ResourceRequirements) { 06383 // 06384 // Once tainted, a driver can never lose it's legacy history 06385 // (unless unloaded). This is because the device object 06386 // field is optional, and we don't bother counting here... 06387 // 06388 DriverObject->Flags |= DRVO_LEGACY_RESOURCES; 06389 } 06390 ExReleaseFastLock(&IopDatabaseLock, irql); 06391 } 06392 } 06393 } 06394 06395 KeReleaseSemaphore(&IopRegistrySemaphore, 0, 1, FALSE); 06396 06397 } else { 06398 06399 DebugMessage(DUMP_ERROR, ("PNPRES: IopLegacyResourceAllocation: Failed to acquire registry semaphore, status %08X\n", status)); 06400 } 06401 06402 KeLeaveCriticalRegion(); 06403 06404 return status; 06405 }

BOOLEAN IopNeedToReleaseBootResources IN PDEVICE_NODE  DeviceNode,
IN PCM_RESOURCE_LIST  AllocatedResources
 

Definition at line 2391 of file pnpres.c.

References exit, FALSE, PAGED_CODE, and TRUE.

Referenced by IopReleaseFilteredBootResources().

02398 : 02399 02400 This routine checks the AllocatedResources against boot allocated resources. 02401 If the allocated resources do not cover all the resource types in boot resources, 02402 in another words some types of boot resources have not been released by arbiter, 02403 we will return TRUE to indicate we need to release the boot resources manually. 02404 02405 Parameters: 02406 02407 DeviceNode - A device node 02408 02409 AllocatedResources - the resources assigned to the devicenode by arbiters. 02410 02411 Return Value: 02412 02413 TRUE or FALSE. 02414 02415 --*/ 02416 02417 { 02418 PCM_FULL_RESOURCE_DESCRIPTOR cmFullDesc_a, cmFullDesc_b; 02419 PCM_PARTIAL_RESOURCE_DESCRIPTOR cmDescriptor_a, cmDescriptor_b; 02420 ULONG size_a, size_b, i, j, k; 02421 BOOLEAN returnValue = FALSE, found; 02422 PCM_RESOURCE_LIST bootResources; 02423 02424 PAGED_CODE(); 02425 02426 bootResources = DeviceNode->BootResources; 02427 if (AllocatedResources->Count == 1 && bootResources && bootResources->Count != 0) { 02428 02429 cmFullDesc_a = &AllocatedResources->List[0]; 02430 cmFullDesc_b = &bootResources->List[0]; 02431 for (i = 0; i < bootResources->Count; i++) { 02432 cmDescriptor_b = &cmFullDesc_b->PartialResourceList.PartialDescriptors[0]; 02433 for (j = 0; j < cmFullDesc_b->PartialResourceList.Count; j++) { 02434 size_b = 0; 02435 switch (cmDescriptor_b->Type) { 02436 case CmResourceTypeNull: 02437 break; 02438 case CmResourceTypeDeviceSpecific: 02439 size_b = cmDescriptor_b->u.DeviceSpecificData.DataSize; 02440 break; 02441 default: 02442 if (cmDescriptor_b->Type < CmResourceTypeMaximum) { 02443 found = FALSE; 02444 cmDescriptor_a = &cmFullDesc_a->PartialResourceList.PartialDescriptors[0]; 02445 for (k = 0; k < cmFullDesc_a->PartialResourceList.Count; k++) { 02446 size_a = 0; 02447 if (cmDescriptor_a->Type == CmResourceTypeDeviceSpecific) { 02448 size_a = cmDescriptor_a->u.DeviceSpecificData.DataSize; 02449 } else if (cmDescriptor_b->Type == cmDescriptor_a->Type) { 02450 found = TRUE; 02451 break; 02452 } 02453 cmDescriptor_a++; 02454 cmDescriptor_a = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmDescriptor_a + size_a); 02455 } 02456 if (found == FALSE) { 02457 returnValue = TRUE; 02458 goto exit; 02459 } 02460 } 02461 } 02462 cmDescriptor_b++; 02463 cmDescriptor_b = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmDescriptor_b + size_b); 02464 } 02465 cmFullDesc_b = (PCM_FULL_RESOURCE_DESCRIPTOR)cmDescriptor_b; 02466 } 02467 } 02468 exit: 02469 return returnValue; 02470 }

NTSTATUS IopParentToRawTranslation IN OUT PREQ_DESC  ReqDesc  ) 
 

Definition at line 3868 of file pnpres.c.

References ASSERT, _TRANSLATOR_INTERFACE::Context, DebugMessage, DUMP_ERROR, IS_TRANSLATED_REQ_DESC, NT_SUCCESS, NTSTATUS(), PREQ_DESC, TranslateParentToChild, and _TRANSLATOR_INTERFACE::TranslateResources.

Referenced by IopBuildCmResourceList().

03874 : 03875 03876 This routine translates an CmPartialResourceDescriptors 03877 from their translated form to their raw counterparts.. 03878 03879 Parameters: 03880 03881 ReqDesc - supplies a translated ReqDesc to be translated back to its raw form 03882 03883 Return Value: 03884 03885 Status code that indicates whether or not the function was successful. 03886 03887 --*/ 03888 { 03889 PTRANSLATOR_INTERFACE translator; 03890 NTSTATUS status = STATUS_SUCCESS; 03891 PREQ_DESC rawReqDesc; 03892 03893 if (ReqDesc->AlternativeTable.AlternativeCount == 0 || 03894 ReqDesc->Allocation.Type == CmResourceTypeMaximum) { 03895 DebugMessage(DUMP_ERROR, ("PnpRes : Invalid ReqDesc for parent-to-raw translation.\n")); 03896 return STATUS_INVALID_PARAMETER; 03897 } 03898 03899 // 03900 // If this ReqDesc is the raw reqDesc then we are done. 03901 // Else call its translator to translate the resource and leave the result 03902 // in its raw (next level) reqdesc. 03903 // 03904 03905 if (IS_TRANSLATED_REQ_DESC(ReqDesc)) { 03906 rawReqDesc = ReqDesc->TranslatedReqDesc; 03907 translator = ReqDesc->u.Translator->TranslatorInterface; 03908 status = (translator->TranslateResources)( 03909 translator->Context, 03910 ReqDesc->AlternativeTable.Assignment, 03911 TranslateParentToChild, 03912 rawReqDesc->AlternativeTable.AlternativeCount, 03913 rawReqDesc->AlternativeTable.Alternatives, 03914 rawReqDesc->AlternativeTable.PhysicalDeviceObject, 03915 rawReqDesc->AlternativeTable.Assignment 03916 ); 03917 if (NT_SUCCESS(status)) { 03918 03919 // 03920 // If the translator is non-hierarchial and performs a complete 03921 // translation to root (eg ISA interrups for PCI devices) then 03922 // don't pass translations to parent. 03923 // 03924 03925 ASSERT(status != STATUS_TRANSLATION_COMPLETE); 03926 status = IopParentToRawTranslation(rawReqDesc); 03927 } 03928 } 03929 return status; 03930 }

NTSTATUS IopPlacement IN ARBITER_ACTION  ArbiterAction,
IN BOOLEAN  Rebalance
 

Definition at line 2554 of file pnpres.c.

References _PI_RESOURCE_ARBITER_ENTRY::ActiveArbiterList, ArbiterActionCommitAllocation, ArbiterActionRetestAllocation, ArbiterActionTestAllocation, ASSERT, _PI_RESOURCE_ARBITER_ENTRY::BestConfig, _PI_RESOURCE_ARBITER_ENTRY::BestResourceList, FALSE, IopCallArbiter(), IopPlacementForRebalance(), IopRootDeviceNode, NT_SUCCESS, NTSTATUS(), NULL, PI_ARBITER_HAS_SOMETHING, PI_ARBITER_TEST_FAILED, PiActiveArbiterList, _PI_RESOURCE_ARBITER_ENTRY::ResourceList, _PI_RESOURCE_ARBITER_ENTRY::ResourcesChanged, and _PI_RESOURCE_ARBITER_ENTRY::State.

Referenced by IopAssign(), IopAssignInner(), and IopRebalance().

02561 : 02562 02563 This routine examines each arbiter if its resreq list changed its test function will be 02564 called. 02565 02566 Parameters: 02567 02568 ArbiterAction - supplies an arbiter action code to perform TEST or RETEST. 02569 02570 Return Value: 02571 02572 Status code that indicates whether or not the function was successful. 02573 02574 --*/ 02575 02576 { 02577 PLIST_ENTRY listEntry; 02578 PPI_RESOURCE_ARBITER_ENTRY arbiterEntry; 02579 NTSTATUS status; 02580 02581 ASSERT((ArbiterAction == ArbiterActionTestAllocation) || 02582 (ArbiterAction == ArbiterActionRetestAllocation) || 02583 (ArbiterAction == ArbiterActionCommitAllocation)); 02584 02585 if (Rebalance) { 02586 02587 // 02588 // For rebalance case, we always start from the root and work our way up. 02589 // 02590 02591 status = IopPlacementForRebalance (IopRootDeviceNode, ArbiterAction); 02592 } else { 02593 listEntry = PiActiveArbiterList.Flink; 02594 while (listEntry != &PiActiveArbiterList) { 02595 arbiterEntry = CONTAINING_RECORD(listEntry, PI_RESOURCE_ARBITER_ENTRY, ActiveArbiterList); 02596 listEntry = listEntry->Flink; 02597 ASSERT(IsListEmpty(&arbiterEntry->ResourceList) == FALSE); 02598 if (arbiterEntry->ResourcesChanged == FALSE) { 02599 02600 // 02601 // If the resource requirements are the same and it failed before, we know it 02602 // won't be able to succeed. So, return failure. 02603 // 02604 02605 if (arbiterEntry->State & PI_ARBITER_TEST_FAILED) { 02606 return STATUS_UNSUCCESSFUL; 02607 } 02608 } else { 02609 02610 // 02611 // If the resource requirements are changed, we need to call arbiter to test it. 02612 // 02613 02614 status = IopCallArbiter(arbiterEntry, 02615 ArbiterAction, 02616 &arbiterEntry->ResourceList, 02617 0, 02618 NULL 02619 ); 02620 if (!NT_SUCCESS(status)) { 02621 ASSERT(ArbiterAction == ArbiterActionTestAllocation); 02622 arbiterEntry->State |= PI_ARBITER_TEST_FAILED; 02623 return status; 02624 } else { 02625 arbiterEntry->State &= ~PI_ARBITER_TEST_FAILED; 02626 arbiterEntry->ResourcesChanged = FALSE; 02627 if (ArbiterAction == ArbiterActionTestAllocation) { 02628 arbiterEntry->State |= PI_ARBITER_HAS_SOMETHING; 02629 } else { 02630 if (ArbiterAction == ArbiterActionRetestAllocation) { 02631 status = IopCallArbiter(arbiterEntry, ArbiterActionCommitAllocation, NULL, NULL, NULL); 02632 ASSERT(status == STATUS_SUCCESS); 02633 } 02634 arbiterEntry->State = 0; 02635 InitializeListHead(&arbiterEntry->ActiveArbiterList); 02636 InitializeListHead(&arbiterEntry->BestConfig); 02637 InitializeListHead(&arbiterEntry->ResourceList); 02638 InitializeListHead(&arbiterEntry->BestResourceList); 02639 } 02640 } 02641 } 02642 } 02643 status = STATUS_SUCCESS; 02644 } 02645 return status; 02646 }

NTSTATUS IopPlacementForRebalance IN PDEVICE_NODE  DeviceNode,
IN ARBITER_ACTION  ArbiterAction
 

Definition at line 4946 of file pnpres.c.

References _DEVICE_NODE::Child, IopArbitrateDeviceResources(), _DEVICE_NODE::LockCount, NT_SUCCESS, NTSTATUS(), and _DEVICE_NODE::Sibling.

Referenced by IopPlacement().

04953 : 04954 04955 This routine walks the device tree bredth-first to arbitrate resources for 04956 device node it visits. 04957 04958 Parameters: 04959 04960 DeviceNode - supplies a pointer to a device node whoes subtree needs to be rebalanced. 04961 04962 ArbiterAction - specifies TEST or RETEST. 04963 04964 Return Value: 04965 04966 Status code that indicates whether or not the function was successful. 04967 04968 --*/ 04969 04970 { 04971 NTSTATUS status = STATUS_SUCCESS; 04972 PDEVICE_NODE node; 04973 04974 // 04975 // Perform breadth-first. Arbitrate resource for the current device node; 04976 // Place resources for its sibling subtree and then child subtree. 04977 // 04978 04979 node = DeviceNode; 04980 while (node) { 04981 04982 // 04983 // Arbitrate device resources iff its not locked for remove. 04984 // 04985 04986 if (node->LockCount == 0) { 04987 04988 status = IopArbitrateDeviceResources (node, ArbiterAction); 04989 if (!NT_SUCCESS(status)) { 04990 return status; 04991 } 04992 } 04993 node = node->Sibling; 04994 } 04995 node = DeviceNode; 04996 while (node) { 04997 04998 // 04999 // If this subtree is not being removed, then process it. 05000 // 05001 05002 if (node->Child && node->LockCount == 0) { 05003 05004 status = IopPlacementForRebalance (node->Child, ArbiterAction); 05005 if (!NT_SUCCESS(status)) { 05006 return status; 05007 } 05008 } 05009 node = node->Sibling; 05010 } 05011 05012 return status; 05013 }

NTSTATUS IopPlacementForReservation VOID   ) 
 

Definition at line 2649 of file pnpres.c.

References _PI_RESOURCE_ARBITER_ENTRY::ActiveArbiterList, _ARBITER_LIST_ENTRY::AlternativeCount, _ARBITER_LIST_ENTRY::Alternatives, ArbiterActionBootAllocation, ASSERT, _PI_RESOURCE_ARBITER_ENTRY::BestConfig, _PI_RESOURCE_ARBITER_ENTRY::BestResourceList, DbgPrint, FALSE, IopCallArbiter(), IopDumpResourceDescriptor(), NT_SUCCESS, NTSTATUS(), NULL, _ARBITER_LIST_ENTRY::PhysicalDeviceObject, PiActiveArbiterList, _PI_RESOURCE_ARBITER_ENTRY::ResourceList, _PI_RESOURCE_ARBITER_ENTRY::ResourcesChanged, and _PI_RESOURCE_ARBITER_ENTRY::State.

Referenced by IopReserve().

02655 : 02656 02657 This routine examines each arbiter if its resreq list changed its test function will be 02658 called. 02659 02660 Parameters: 02661 02662 None. 02663 02664 Return Value: 02665 02666 Status code that indicates whether or not the function was successful. 02667 02668 --*/ 02669 02670 { 02671 PLIST_ENTRY listEntry; 02672 PPI_RESOURCE_ARBITER_ENTRY arbiterEntry; 02673 NTSTATUS status, returnStatus = STATUS_SUCCESS; 02674 02675 listEntry = PiActiveArbiterList.Flink; 02676 while (listEntry != &PiActiveArbiterList) { 02677 arbiterEntry = CONTAINING_RECORD(listEntry, PI_RESOURCE_ARBITER_ENTRY, ActiveArbiterList); 02678 listEntry = listEntry->Flink; 02679 ASSERT(IsListEmpty(&arbiterEntry->ResourceList) == FALSE); 02680 if (arbiterEntry->ResourcesChanged) { 02681 02682 // 02683 // If the resource requirements are changed, we need to call arbiter to reserve it. 02684 // 02685 02686 status = IopCallArbiter(arbiterEntry, 02687 ArbiterActionBootAllocation, 02688 &arbiterEntry->ResourceList, 02689 0, 02690 NULL 02691 ); 02692 if (!NT_SUCCESS(status)) { 02693 #if MYDBG 02694 PARBITER_LIST_ENTRY arbiterListEntry = (PARBITER_LIST_ENTRY) arbiterEntry->ResourceList.Flink; 02695 DbgPrint("Allocate Boot Resources Failed ::\n"); 02696 DbgPrint(" Count = %x, PDO = %x\n", 02697 arbiterListEntry->AlternativeCount, arbiterListEntry->PhysicalDeviceObject); 02698 IopDumpResourceDescriptor( 02699 " ", 02700 arbiterListEntry->Alternatives); 02701 #endif 02702 returnStatus = status; 02703 } 02704 arbiterEntry->ResourcesChanged = FALSE; 02705 arbiterEntry->State = 0; 02706 InitializeListHead(&arbiterEntry->ActiveArbiterList); 02707 InitializeListHead(&arbiterEntry->BestConfig); 02708 InitializeListHead(&arbiterEntry->ResourceList); 02709 InitializeListHead(&arbiterEntry->BestResourceList); 02710 } 02711 } 02712 return returnStatus; 02713 }

NTSTATUS IopQueryConflictFillConflicts PDEVICE_OBJECT  PhysicalDeviceObject,
IN ULONG  ConflictCount,
IN PARBITER_CONFLICT_INFO  ConflictInfoList,
OUT PPLUGPLAY_CONTROL_CONFLICT_LIST  ConflictList,
IN ULONG  ConflictListSize,
IN ULONG  Flags
 

Definition at line 8022 of file pnpres.c.

References ARBITER_CONFLICT_INFO, ASSERT, DebugMessage, DUMP_DETAIL, Index, IopEliminateBogusConflict(), IopQueryConflictFillString(), NTSTATUS(), NULL, and PAGED_CODE.

Referenced by IopQueryConflictListInternal().

08032 : 08033 08034 Fill ConflictList with information on as many conflicts as possible 08035 08036 Arguments: 08037 08038 PhysicalDeviceObject The PDO we're performing the test on 08039 ConflictCount Number of Conflicts. 08040 ConflictInfoList List of conflicting device info, can be NULL if ConflictCount is 0 08041 ConflictList Structure to fill in with conflicts 08042 ConflictListSize Size of Conflict List 08043 Flags if non-zero, dummy conflict is created 08044 08045 Return Value: 08046 08047 Should be success in most cases 08048 08049 --*/ 08050 { 08051 NTSTATUS status = STATUS_SUCCESS; 08052 ULONG ConflictListIdealSize; 08053 ULONG ConflictListBaseSize; 08054 ULONG ConflictListCount; 08055 ULONG Index; 08056 ULONG ConflictIndex; 08057 ULONG EntrySize; 08058 ULONG ConflictStringsOffset; 08059 ULONG stringSize; 08060 ULONG stringTotalSize; 08061 ULONG DummyCount; 08062 PPLUGPLAY_CONTROL_CONFLICT_STRINGS ConfStrings; 08063 08064 PAGED_CODE(); 08065 08066 // 08067 // determine how many conflicts we can 08068 // 08069 // for each conflict 08070 // translate to bus/resource/address in respect to conflicting device 08071 // add to conflict list 08072 // 08073 // 08074 08075 // 08076 // preprocessing - given our ConflictInfoList and ConflictCount 08077 // remove any that appear to be bogus - ie, that are the same device that we are testing against 08078 // this stops mostly legacy issues 08079 // 08080 for(Index = 0;Index < ConflictCount; Index++) { 08081 if (IopEliminateBogusConflict(PhysicalDeviceObject,ConflictInfoList[Index].OwningObject)) { 08082 08083 DebugMessage(DUMP_DETAIL, ("IopQueryConflictFillConflicts: eliminating \"identical\" PDO %08x conflicting with self (%08x)\n", 08084 ConflictInfoList[Index].OwningObject,PhysicalDeviceObject)); 08085 // 08086 // move the last listed conflict into this space 08087 // 08088 if (Index+1 < ConflictCount) { 08089 RtlCopyMemory(&ConflictInfoList[Index],&ConflictInfoList[ConflictCount-1],sizeof(ARBITER_CONFLICT_INFO)); 08090 } 08091 // 08092 // account for deleting this item 08093 // 08094 ConflictCount--; 08095 Index--; 08096 } 08097 } 08098 08099 // 08100 // preprocessing - in our conflict list, we may have PDO's for legacy devices, and resource nodes for the same 08101 // or other duplicate entities (we only ever want to report a conflict once, even if there's multiple conflicting ranges) 08102 // 08103 08104 RestartScan: 08105 08106 for(Index = 0;Index < ConflictCount; Index++) { 08107 if (ConflictInfoList[Index].OwningObject != NULL) { 08108 08109 ULONG Index2; 08110 08111 for (Index2 = Index+1; Index2 < ConflictCount; Index2++) { 08112 if (IopEliminateBogusConflict(ConflictInfoList[Index].OwningObject,ConflictInfoList[Index2].OwningObject)) { 08113 // 08114 // Index2 is considered a dup of Index 08115 // 08116 08117 DebugMessage(DUMP_DETAIL, ("IopQueryConflictFillConflicts: eliminating \"identical\" PDO %08x conflicting with PDO %08x\n", 08118 ConflictInfoList[Index2].OwningObject,ConflictInfoList[Index].OwningObject)); 08119 // 08120 // move the last listed conflict into this space 08121 // 08122 if (Index2+1 < ConflictCount) { 08123 RtlCopyMemory(&ConflictInfoList[Index2],&ConflictInfoList[ConflictCount-1],sizeof(ARBITER_CONFLICT_INFO)); 08124 } 08125 // 08126 // account for deleting this item 08127 // 08128 ConflictCount--; 08129 Index2--; 08130 } else if (IopEliminateBogusConflict(ConflictInfoList[Index2].OwningObject,ConflictInfoList[Index].OwningObject)) { 08131 // 08132 // Index is considered a dup of Index2 (some legacy case) 08133 // 08134 DebugMessage(DUMP_DETAIL, ("IopQueryConflictFillConflicts: eliminating \"identical\" PDO %08x conflicting with PDO %08x\n", 08135 ConflictInfoList[Index2].OwningObject,ConflictInfoList[Index].OwningObject)); 08136 // 08137 // move the one we want (Index2) into the space occupied by Index 08138 // 08139 RtlCopyMemory(&ConflictInfoList[Index],&ConflictInfoList[Index2],sizeof(ARBITER_CONFLICT_INFO)); 08140 // 08141 // move the last listed conflict into the space we just created 08142 // 08143 if (Index2+1 < ConflictCount) { 08144 RtlCopyMemory(&ConflictInfoList[Index2],&ConflictInfoList[ConflictCount-1],sizeof(ARBITER_CONFLICT_INFO)); 08145 } 08146 // 08147 // account for deleting this item 08148 // 08149 ConflictCount--; 08150 // 08151 // but as this is quirky, restart the scan 08152 // 08153 goto RestartScan; 08154 } 08155 } 08156 } 08157 } 08158 08159 // 08160 // preprocessing - if we have any known reported conflicts, don't report back any unknown 08161 // 08162 08163 for(Index = 0;Index < ConflictCount; Index++) { 08164 // 08165 // find first unknown 08166 // 08167 if (ConflictInfoList[Index].OwningObject == NULL) { 08168 // 08169 // eliminate all other unknowns 08170 // 08171 08172 ULONG Index2; 08173 08174 for (Index2 = Index+1; Index2 < ConflictCount; Index2++) { 08175 if (ConflictInfoList[Index2].OwningObject == NULL) { 08176 08177 DebugMessage(DUMP_DETAIL, ("IopQueryConflictFillConflicts: eliminating extra unknown\n")); 08178 // 08179 // move the last listed conflict into this space 08180 // 08181 if (Index2+1 < ConflictCount) { 08182 RtlCopyMemory(&ConflictInfoList[Index2],&ConflictInfoList[ConflictCount-1],sizeof(ARBITER_CONFLICT_INFO)); 08183 } 08184 // 08185 // account for deleting this item 08186 // 08187 ConflictCount--; 08188 Index2--; 08189 } 08190 } 08191 08192 if(ConflictCount != 1) { 08193 08194 DebugMessage(DUMP_DETAIL, ("IopQueryConflictFillConflicts: eliminating first unknown\n")); 08195 // 08196 // there were others, so ignore the unknown 08197 // 08198 if (Index+1 < ConflictCount) { 08199 RtlCopyMemory(&ConflictInfoList[Index],&ConflictInfoList[ConflictCount-1],sizeof(ARBITER_CONFLICT_INFO)); 08200 } 08201 ConflictCount --; 08202 } 08203 08204 break; 08205 } 08206 } 08207 08208 // 08209 // set number of actual and listed conflicts 08210 // 08211 08212 ConflictListIdealSize = (sizeof(PLUGPLAY_CONTROL_CONFLICT_LIST) - sizeof(PLUGPLAY_CONTROL_CONFLICT_ENTRY)) + sizeof(PLUGPLAY_CONTROL_CONFLICT_STRINGS); 08213 ConflictListCount = 0; 08214 stringTotalSize = 0; 08215 DummyCount = 0; 08216 08217 ASSERT(ConflictListSize >= ConflictListIdealSize); // we should have checked to see if buffer is at least this big 08218 08219 DebugMessage(DUMP_DETAIL, ("IopQueryConflictFillConflicts: Detected %d conflicts\n", ConflictCount)); 08220 08221 // 08222 // estimate sizes 08223 // 08224 if (Flags) { 08225 // 08226 // flags entry required (ie resource not available for some specified reason) 08227 // 08228 stringSize = 1; // null-length string 08229 DummyCount ++; 08230 EntrySize = sizeof(PLUGPLAY_CONTROL_CONFLICT_ENTRY); 08231 EntrySize += sizeof(WCHAR) * stringSize; 08232 08233 if((ConflictListIdealSize+EntrySize) <= ConflictListSize) { 08234 // 08235 // we can fit this one in 08236 // 08237 ConflictListCount++; 08238 stringTotalSize += stringSize; 08239 } 08240 ConflictListIdealSize += EntrySize; 08241 } 08242 // 08243 // report conflicts 08244 // 08245 for(Index = 0; Index < ConflictCount; Index ++) { 08246 08247 stringSize = 0; 08248 IopQueryConflictFillString(ConflictInfoList[Index].OwningObject,NULL,&stringSize,NULL); 08249 08250 // 08251 // account for entry 08252 // 08253 EntrySize = sizeof(PLUGPLAY_CONTROL_CONFLICT_ENTRY); 08254 EntrySize += sizeof(WCHAR) * stringSize; 08255 08256 if((ConflictListIdealSize+EntrySize) <= ConflictListSize) { 08257 // 08258 // we can fit this one in 08259 // 08260 ConflictListCount++; 08261 stringTotalSize += stringSize; 08262 } 08263 ConflictListIdealSize += EntrySize; 08264 } 08265 08266 ConflictList->ConflictsCounted = ConflictCount+DummyCount; // number of conflicts detected including any dummy conflict 08267 ConflictList->ConflictsListed = ConflictListCount; // how many we could fit in 08268 ConflictList->RequiredBufferSize = ConflictListIdealSize; // how much buffer space to supply on next call 08269 08270 DebugMessage(DUMP_DETAIL, ("IopQueryConflictFillConflicts: Listing %d conflicts\n", ConflictListCount)); 08271 DebugMessage(DUMP_DETAIL, ("IopQueryConflictFillConflicts: Need %08x bytes to list all conflicts\n", ConflictListIdealSize)); 08272 08273 ConfStrings = (PPLUGPLAY_CONTROL_CONFLICT_STRINGS)&(ConflictList->ConflictEntry[ConflictListCount]); 08274 ConfStrings->NullDeviceInstance = (ULONG)(-1); 08275 ConflictStringsOffset = 0; 08276 08277 for(ConflictIndex = 0; ConflictIndex < DummyCount; ConflictIndex++) { 08278 // 08279 // flags entry required (ie resource not available for some specified reason) 08280 // 08281 if (Flags && ConflictIndex == 0) { 08282 ConflictList->ConflictEntry[ConflictIndex].DeviceInstance = ConflictStringsOffset; 08283 ConflictList->ConflictEntry[ConflictIndex].DeviceFlags = Flags; 08284 ConflictList->ConflictEntry[ConflictIndex].ResourceType = 0; 08285 ConflictList->ConflictEntry[ConflictIndex].ResourceStart = 0; 08286 ConflictList->ConflictEntry[ConflictIndex].ResourceEnd = 0; 08287 ConflictList->ConflictEntry[ConflictIndex].ResourceFlags = 0; 08288 08289 ConfStrings->DeviceInstanceStrings[ConflictStringsOffset] = 0; // null string 08290 stringTotalSize --; 08291 ConflictStringsOffset ++; 08292 DebugMessage(DUMP_DETAIL, ("IopQueryConflictFillConflicts: Listing flags %08x\n", Flags)); 08293 } 08294 } 08295 // 08296 // get/fill in details for all those we can fit into the buffer 08297 // 08298 for(Index = 0; ConflictIndex < ConflictListCount ; Index ++, ConflictIndex++) { 08299 08300 ASSERT(Index < ConflictCount); 08301 // 08302 // assign conflict information 08303 // 08304 ConflictList->ConflictEntry[ConflictIndex].DeviceInstance = ConflictStringsOffset; 08305 ConflictList->ConflictEntry[ConflictIndex].DeviceFlags = 0; 08306 ConflictList->ConflictEntry[ConflictIndex].ResourceType = 0; // BUGBUG!!! (jamiehun) remember to do this (post NT5)! 08307 ConflictList->ConflictEntry[ConflictIndex].ResourceStart = (ULONGLONG)(1); // for now, return totally invalid range (1-0) 08308 ConflictList->ConflictEntry[ConflictIndex].ResourceEnd = 0; 08309 ConflictList->ConflictEntry[ConflictIndex].ResourceFlags = 0; 08310 08311 // 08312 // fill string details 08313 // 08314 stringSize = stringTotalSize; 08315 IopQueryConflictFillString(ConflictInfoList[Index].OwningObject, 08316 &(ConfStrings->DeviceInstanceStrings[ConflictStringsOffset]), 08317 &stringSize, 08318 &(ConflictList->ConflictEntry[ConflictIndex].DeviceFlags)); 08319 stringTotalSize -= stringSize; 08320 DebugMessage(DUMP_DETAIL, ("IopQueryConflictFillConflicts: Listing \"%S\"\n", &(ConfStrings->DeviceInstanceStrings[ConflictStringsOffset]))); 08321 ConflictStringsOffset += stringSize; 08322 } 08323 08324 // 08325 // another NULL at end of strings (this is accounted for in the PPLUGPLAY_CONTROL_CONFLICT_STRINGS structure) 08326 // 08327 ConfStrings->DeviceInstanceStrings[ConflictStringsOffset] = 0; 08328 08329 //Clean0: 08330 ; 08331 return status; 08332 }

NTSTATUS IopQueryConflictFillString IN PDEVICE_OBJECT  DeviceObject,
IN PWSTR  Buffer,
IN OUT PULONG  Length,
IN OUT PULONG  Flags
 

Definition at line 7876 of file pnpres.c.

References ASSERT, Buffer, DO_BUS_ENUMERATED_DEVICE, _DRIVER_OBJECT::DriverName, _DEVICE_NODE::DuplicatePDO, _DEVICE_NODE::InstancePath, IopRootDeviceNode, NTSTATUS(), NULL, and PAGED_CODE.

Referenced by IopQueryConflictFillConflicts().

07884 : 07885 07886 Obtain string or string-length for details of conflicting device 07887 07888 Arguments: 07889 07890 DeviceObject Device object we want Device-Instance-String or Service Name 07891 Buffer Buffer to Fill, NULL if we just want length 07892 Length Filled with length of Buffer, including terminated NULL (Words) 07893 Flags Apropriate flags set describing what the string represents 07894 07895 Return Value: 07896 07897 Should be success in most cases 07898 07899 --*/ 07900 { 07901 NTSTATUS status = STATUS_SUCCESS; 07902 PDEVICE_NODE deviceNode; 07903 PDRIVER_OBJECT driverObject; 07904 PUNICODE_STRING infoString = NULL; 07905 ULONG MaxLength = 0; // words 07906 ULONG ReqLength = 0; // words 07907 ULONG flags = 0; 07908 07909 PAGED_CODE(); 07910 07911 if (Length != NULL) { 07912 MaxLength = *Length; 07913 } 07914 07915 if (Flags != NULL) { 07916 flags = *Flags; 07917 } 07918 07919 if (DeviceObject == NULL) { 07920 // 07921 // unknown 07922 // 07923 goto final; 07924 07925 } 07926 07927 if ((DeviceObject->Flags & DO_BUS_ENUMERATED_DEVICE) == 0 ) { 07928 // 07929 // FDO, report driver name 07930 // 07931 driverObject = DeviceObject->DriverObject; 07932 if(driverObject == NULL) { 07933 // 07934 // should not be NULL 07935 // 07936 ASSERT(driverObject); 07937 goto final; 07938 } 07939 infoString = & (driverObject->DriverName); 07940 flags |= PNP_CE_LEGACY_DRIVER; 07941 goto final; 07942 } 07943 07944 // 07945 // we should in actual fact have a PDO 07946 // 07947 if (DeviceObject->DeviceObjectExtension == NULL) { 07948 // 07949 // should not be NULL 07950 // 07951 ASSERT(DeviceObject->DeviceObjectExtension); 07952 goto final; 07953 } 07954 07955 deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode; 07956 if (deviceNode == NULL) { 07957 // 07958 // should not be NULL 07959 // 07960 ASSERT(deviceNode); 07961 goto final; 07962 } 07963 07964 if (deviceNode == IopRootDeviceNode) { 07965 // 07966 // owned by root device 07967 // 07968 flags |= PNP_CE_ROOT_OWNED; 07969 07970 } else if (deviceNode -> Parent == NULL) { 07971 // 07972 // faked out PDO - must be legacy device 07973 // 07974 driverObject = (PDRIVER_OBJECT)(deviceNode->DuplicatePDO); 07975 if(driverObject == NULL) { 07976 // 07977 // should not be NULL 07978 // 07979 ASSERT(driverObject); 07980 goto final; 07981 } 07982 infoString = & (driverObject->DriverName); 07983 flags |= PNP_CE_LEGACY_DRIVER; 07984 goto final; 07985 } 07986 07987 // 07988 // we should be happy with what we have 07989 // 07990 infoString = &deviceNode->InstancePath; 07991 07992 final: 07993 07994 if (infoString != NULL) { 07995 // 07996 // we have a string to copy 07997 // 07998 if ((Buffer != NULL) && (MaxLength*sizeof(WCHAR) > infoString->Length)) { 07999 RtlCopyMemory(Buffer, infoString->Buffer, infoString->Length); 08000 } 08001 ReqLength += infoString->Length / sizeof(WCHAR); 08002 } 08003 08004 if ((Buffer != NULL) && (MaxLength > ReqLength)) { 08005 Buffer[ReqLength] = 0; 08006 } 08007 08008 ReqLength++; 08009 08010 if (Length != NULL) { 08011 *Length = ReqLength; 08012 } 08013 if (Flags != NULL) { 08014 *Flags = flags; 08015 } 08016 08017 return status; 08018 }

NTSTATUS IopQueryConflictList PDEVICE_OBJECT  PhysicalDeviceObject,
IN PCM_RESOURCE_LIST  ResourceList,
IN ULONG  ResourceListSize,
OUT PPLUGPLAY_CONTROL_CONFLICT_LIST  ConflictList,
IN ULONG  ConflictListSize,
IN ULONG  Flags
 

Definition at line 7717 of file pnpres.c.

References DebugMessage, DelayExecution, DUMP_ERROR, FALSE, IopQueryConflictListInternal(), IopRegistrySemaphore, KeEnterCriticalRegion, KeLeaveCriticalRegion, KeReleaseSemaphore(), KernelMode, KeWaitForSingleObject(), NT_SUCCESS, NTSTATUS(), NULL, and PAGED_CODE.

07727 : 07728 07729 This routine performs the querying of device conflicts 07730 returning data in ConflictList 07731 07732 Arguments: 07733 07734 PhysicalDeviceObject PDO of device to Query 07735 ResourceList CM resource list containing single resource to query 07736 ResourceListSize Size of ResourceList 07737 ConflictList Conflict list to fill query details in 07738 ConflictListSize Size of buffer that we can fill with Conflict information 07739 Flags Currently unused (zero) for future passing of flags 07740 07741 Return Value: 07742 07743 Should be success in most cases 07744 07745 --*/ 07746 { 07747 NTSTATUS status; 07748 07749 PAGED_CODE(); 07750 07751 KeEnterCriticalRegion( ); 07752 07753 status = KeWaitForSingleObject( &IopRegistrySemaphore, 07754 DelayExecution, 07755 KernelMode, 07756 FALSE, 07757 NULL ); 07758 07759 if (!NT_SUCCESS( status )) { 07760 DebugMessage(DUMP_ERROR, ("IopQueryConflictList: Get RegustrySemaphore failed. Status %x\n", status)); 07761 KeLeaveCriticalRegion( ); 07762 return status; 07763 } else { 07764 status = IopQueryConflictListInternal(PhysicalDeviceObject, ResourceList, ResourceListSize, ConflictList, ConflictListSize, Flags); 07765 KeReleaseSemaphore( &IopRegistrySemaphore, 0, 1, FALSE ); 07766 KeLeaveCriticalRegion( ); 07767 } 07768 07769 return status; 07770 }

NTSTATUS IopQueryConflictListInternal PDEVICE_OBJECT  PhysicalDeviceObject,
IN PCM_RESOURCE_LIST  ResourceList,
IN ULONG  ResourceListSize,
OUT PPLUGPLAY_CONTROL_CONFLICT_LIST  ConflictList,
IN ULONG  ConflictListSize,
IN ULONG  Flags
 

Definition at line 8336 of file pnpres.c.

References ArbiterActionQueryConflict, ArbiterRequestUndefined, ASSERT, _DEVICE_NODE::ChildBusNumber, _DEVICE_NODE::ChildInterfaceType, CmResourceTypeReserved, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, ExFreePool(), IopCallArbiter(), IopCheckDataStructures(), IopCmResourcesToIoResources(), IopFreeReqList(), IopQueryConflictFillConflicts(), IopResourceRequirementsListToReqList(), IopRootDeviceNode, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PnpDefaultInterfaceType, PnpResDebugLevel, PREQ_ALTERNATIVE, PREQ_DESC, PREQ_LIST, RA, _DEVICE_NODE::ResourceRequirements, and STOP_ERROR.

Referenced by IopQueryConflictList().

08346 : 08347 08348 Version of IopQueryConflictList without the locking 08349 08350 --*/ 08351 { 08352 08353 NTSTATUS status = STATUS_SUCCESS; 08354 PDEVICE_NODE deviceNode = NULL; 08355 PIO_RESOURCE_REQUIREMENTS_LIST ioResources; 08356 PREQ_LIST reqList; 08357 PREQ_DESC reqDesc, reqDescTranslated; 08358 PLIST_ENTRY listHead; 08359 PPI_RESOURCE_ARBITER_ENTRY arbiterEntry; 08360 PREQ_ALTERNATIVE RA; 08361 PREQ_ALTERNATIVE *reqAlternative; 08362 ULONG ConflictCount = 0; 08363 PARBITER_CONFLICT_INFO ConflictInfoList = NULL; 08364 PIO_RESOURCE_DESCRIPTOR ConflictDesc = NULL; 08365 ULONG ReqDescCount = 0; 08366 PREQ_DESC *ReqDescTable = NULL; 08367 PIO_RESOURCE_REQUIREMENTS_LIST pIoReqList = NULL; 08368 PVOID ExtParams[4]; 08369 08370 PAGED_CODE(); 08371 08372 ASSERT(PhysicalDeviceObject); 08373 ASSERT(ResourceList); 08374 ASSERT(ResourceListSize); 08375 // 08376 // these parameters were generated by umpnpmgr 08377 // so should be correct - one resource, and one resource only 08378 // 08379 ASSERT(ResourceList->Count == 1); 08380 ASSERT(ResourceList->List[0].PartialResourceList.Count == 1); 08381 08382 if (ConflictList == NULL || (ConflictListSize < (sizeof(PLUGPLAY_CONTROL_CONFLICT_LIST) - sizeof(PLUGPLAY_CONTROL_CONFLICT_ENTRY)) + sizeof(PLUGPLAY_CONTROL_CONFLICT_STRINGS))) { 08383 // 08384 // sanity check 08385 // 08386 status = STATUS_BUFFER_TOO_SMALL; 08387 goto Clean0; 08388 } 08389 // 08390 // whatever other error we return, ensure that ConflictList is interpretable 08391 // 08392 08393 ConflictList->ConflictsCounted = 0; 08394 ConflictList->ConflictsListed = 0; 08395 ConflictList->RequiredBufferSize = (sizeof(PLUGPLAY_CONTROL_CONFLICT_LIST) - sizeof(PLUGPLAY_CONTROL_CONFLICT_ENTRY)) + sizeof(PLUGPLAY_CONTROL_CONFLICT_STRINGS); 08396 08397 // 08398 // Retrieve the devnode from the PDO 08399 // 08400 deviceNode = (PDEVICE_NODE)PhysicalDeviceObject->DeviceObjectExtension->DeviceNode; 08401 if (!deviceNode) { 08402 status = STATUS_NO_SUCH_DEVICE; 08403 goto Clean0; 08404 } 08405 08406 // 08407 // type-specific validation 08408 // 08409 switch(ResourceList->List[0].PartialResourceList.PartialDescriptors[0].Type) { 08410 case CmResourceTypePort: 08411 case CmResourceTypeMemory: 08412 if(ResourceList->List[0].PartialResourceList.PartialDescriptors[0].u.Generic.Length == 0) { 08413 // 08414 // zero-range resource can never conflict 08415 // 08416 status = STATUS_SUCCESS; 08417 goto Clean0; 08418 } 08419 break; 08420 case CmResourceTypeInterrupt: 08421 case CmResourceTypeDma: 08422 break; 08423 default: 08424 ASSERT(0); 08425 status = STATUS_INVALID_PARAMETER; 08426 goto Clean0; 08427 } 08428 08429 // 08430 // apply bus details from node 08431 // 08432 if (deviceNode->ChildInterfaceType == InterfaceTypeUndefined) { 08433 // 08434 // we have to grovel around to find real Interface Type 08435 // 08436 pIoReqList = deviceNode->ResourceRequirements; 08437 if (pIoReqList != NULL && pIoReqList->InterfaceType != InterfaceTypeUndefined) { 08438 ResourceList->List[0].InterfaceType = pIoReqList->InterfaceType; 08439 } else { 08440 // 08441 // BUGBUG!!! (jamiehun) 08442 // we should never get here 08443 // if we do, I need to look at this more 08444 // 08445 #if MYDBG 08446 ASSERT(0); 08447 #endif 08448 ResourceList->List[0].InterfaceType = PnpDefaultInterfaceType; 08449 } 08450 08451 } else { 08452 // 08453 // we trust the deviceNode to tell us Interface Type 08454 // 08455 ResourceList->List[0].InterfaceType = deviceNode->ChildInterfaceType; 08456 } 08457 // 08458 // HACKHACK!!! (jamiehun) some bus-types we are better off considered as default 08459 // 08460 switch(ResourceList->List[0].InterfaceType) { 08461 case InterfaceTypeUndefined: 08462 case PCMCIABus: 08463 ResourceList->List[0].InterfaceType = PnpDefaultInterfaceType; 08464 } 08465 if ((deviceNode->ChildBusNumber & 0x80000000) == 0x80000000) { 08466 // 08467 // we have to grovel around to find real Bus Number 08468 // 08469 pIoReqList = deviceNode->ResourceRequirements; 08470 if (pIoReqList != NULL && (pIoReqList->BusNumber & 0x80000000) != 0x80000000) { 08471 ResourceList->List[0].BusNumber = pIoReqList->BusNumber; 08472 } else { 08473 // 08474 // a resonable default, but assert is here so I remember to look at this more 08475 // BUGBUG!!! (jamiehun) 08476 // 08477 #if MYDBG 08478 ASSERT(0); 08479 #endif 08480 ResourceList->List[0].BusNumber = 0; 08481 } 08482 08483 } else { 08484 // 08485 // we trust the deviceNode to tell us Bus Number 08486 // 08487 ResourceList->List[0].BusNumber = deviceNode->ChildBusNumber; 08488 } 08489 08490 // 08491 // from our CM Resource List, obtain an IO Resource Requirements List 08492 // 08493 ioResources = IopCmResourcesToIoResources(0, ResourceList, LCPRI_FORCECONFIG); 08494 if (!ioResources) { 08495 status = STATUS_INVALID_PARAMETER; 08496 goto Clean0; 08497 } 08498 // 08499 // Convert ioResources to a Request list 08500 // and in the processess, determine any Arbiters/Translators to use 08501 // 08502 status = IopResourceRequirementsListToReqList( 08503 ArbiterRequestUndefined, // BUGBUG!!! (jamiehun) better alternative??? 08504 ioResources, 08505 PhysicalDeviceObject, 08506 &reqList); 08507 08508 // 08509 // get arbitrator/translator for current device/bus 08510 // 08511 08512 if (NT_SUCCESS(status) && reqList) { 08513 08514 reqAlternative = reqList->ReqAlternativeTable; 08515 RA = *reqAlternative; 08516 reqList->SelectedAlternative = reqAlternative; 08517 08518 ReqDescCount = RA->ReqDescCount; 08519 ReqDescTable = RA->ReqDescTable; 08520 08521 // 08522 // we should have got only one descriptor, use only the first one 08523 // 08524 if (ReqDescCount>0) { 08525 08526 // 08527 // get first descriptor & it's arbitor 08528 // 08529 08530 reqDesc = *ReqDescTable; 08531 if (reqDesc->ArbitrationRequired) { 08532 reqDescTranslated = reqDesc->TranslatedReqDesc; // Could be reqDesc itself 08533 08534 arbiterEntry = reqDesc->u.Arbiter; 08535 ASSERT(arbiterEntry); 08536 // 08537 // the descriptor of interest - translated, first alternative in the table 08538 // 08539 ConflictDesc = reqDescTranslated->AlternativeTable.Alternatives; 08540 // 08541 // skip special descriptor 08542 // to get to the actual descriptor 08543 // 08544 if(ConflictDesc->Type == CmResourceTypeConfigData || ConflictDesc->Type == CmResourceTypeReserved) 08545 ConflictDesc++; 08546 08547 // 08548 // finally we can call the arbiter to get a conflict list (returning PDO's and Global Address Ranges) 08549 // 08550 ExtParams[0] = PhysicalDeviceObject; 08551 ExtParams[1] = ConflictDesc; 08552 ExtParams[2] = &ConflictCount; 08553 ExtParams[3] = &ConflictInfoList; 08554 status = IopCallArbiter(arbiterEntry, ArbiterActionQueryConflict , ExtParams, NULL , NULL); 08555 08556 if (NT_SUCCESS(status)) { 08557 // 08558 // fill in user-memory buffer with conflict 08559 // 08560 status = IopQueryConflictFillConflicts(PhysicalDeviceObject,ConflictCount,ConflictInfoList,ConflictList,ConflictListSize,0); 08561 if(ConflictInfoList != NULL) { 08562 ExFreePool(ConflictInfoList); 08563 } 08564 } 08565 else if(status == STATUS_RANGE_NOT_FOUND) { 08566 // 08567 // fill in with flag indicating bad range (this means range is not available) 08568 // ConflictInfoList should not be allocated 08569 // 08570 status = IopQueryConflictFillConflicts(NULL,0,NULL,ConflictList,ConflictListSize,PNP_CE_TRANSLATE_FAILED); 08571 } 08572 08573 } else { 08574 #if MYDBG 08575 ASSERT(0); // For now 08576 #endif 08577 status = STATUS_INVALID_PARAMETER; // if we failed, it's prob because ResourceList was invalid 08578 } 08579 } else { 08580 #if MYDBG 08581 ASSERT(0); // For now 08582 #endif 08583 status = STATUS_INVALID_PARAMETER; // if we failed, it's prob because ResourceList was invalid 08584 } 08585 08586 #if DBG_SCOPE 08587 if (PnpResDebugLevel & STOP_ERROR) { 08588 IopCheckDataStructures(IopRootDeviceNode); 08589 } 08590 #endif 08591 08592 IopFreeReqList(reqList); 08593 } else { 08594 #if MYDBG 08595 ASSERT(0); // For now 08596 #endif 08597 if(NT_SUCCESS(status)) { 08598 // 08599 // it was NULL because we had a zero resource count, must be invalid parameter 08600 // 08601 status = STATUS_INVALID_PARAMETER; 08602 } 08603 08604 } 08605 ExFreePool(ioResources); 08606 08607 Clean0: 08608 ; 08609 08610 return status; 08611 } }

VOID IopQueryRebalance IN PDEVICE_NODE  DeviceNode,
IN ULONG  Phase,
IN PULONG  RebalanceCount,
IN PDEVICE_OBJECT **  DeviceTable
 

Definition at line 4589 of file pnpres.c.

References ExAllocatePoolPDO, ExFreePool(), IopQueryRebalanceWorker(), NULL, PagedPool, and PDEVICE_OBJECT.

Referenced by IopRebalance().

04598 : 04599 04600 This routine walks hardware tree depth first. For each device node it visits, 04601 it call IopQueryReconfigureDevice to query-stop device for resource 04602 reconfiguration. 04603 04604 Note, Under rebalancing situation, all the participated devices will be asked to 04605 stop. Even they support non-stopped rebalancing. 04606 04607 Parameters: 04608 04609 DeviceNode - supplies a pionter a device node which is the root of the tree to 04610 be tested. 04611 04612 Phase - Supplies a value to specify the phase of the rebalance. 04613 04614 RebalanceCount - supplies a pointer to a variable to receive the number of devices 04615 participating the rebalance. 04616 04617 Return Value: 04618 04619 None. 04620 04621 --*/ 04622 04623 { 04624 LONG oldState; 04625 PDEVICE_OBJECT *deviceList, *deviceTable, *device; 04626 ULONG count; 04627 PDEVICE_NODE deviceNode; 04628 04629 04630 // 04631 // Call worker routine to get a list of devices to be rebalanced. 04632 // 04633 04634 deviceTable = *DeviceTable; 04635 IopQueryRebalanceWorker (DeviceNode, Phase, RebalanceCount, DeviceTable); 04636 04637 count = *RebalanceCount; 04638 if (count != 0 && Phase == 0) { 04639 04640 // 04641 // At phase 0, we did not actually query-stop the device. 04642 // We need to do it now. 04643 // 04644 04645 deviceList = (PDEVICE_OBJECT *)ExAllocatePoolPDO(PagedPool, count * sizeof(PDEVICE_OBJECT)); 04646 if (deviceList == NULL) { 04647 *RebalanceCount = 0; 04648 return; 04649 } 04650 RtlMoveMemory(deviceList, deviceTable, sizeof(PDEVICE_OBJECT) * count); 04651 04652 // 04653 // Rebuild the returned device list 04654 // 04655 04656 *RebalanceCount = 0; 04657 *DeviceTable = deviceTable; 04658 for (device = deviceList; device < (deviceList + count); device++) { 04659 deviceNode = (PDEVICE_NODE)((*device)->DeviceObjectExtension->DeviceNode); 04660 IopQueryRebalanceWorker (deviceNode, 1, RebalanceCount, DeviceTable); 04661 } 04662 ExFreePool(deviceList); 04663 } 04664 return; 04665 } VOID

VOID IopQueryRebalanceWorker IN PDEVICE_NODE  DeviceNode,
IN ULONG  RebalancePhase,
IN PULONG  RebalanceCount,
IN PDEVICE_OBJECT **  DeviceTable
 

Definition at line 4667 of file pnpres.c.

References ASSERT, _DEVICE_NODE::Child, DebugMessage, DNF_ASSIGNING_RESOURCES, DNF_ASYNC_REQUEST_PENDING, DNF_LEGACY_DRIVER, DNF_NEEDS_REBALANCE, DNF_STOPPED, DUMP_ERROR, _DEVICE_NODE::EnumerationMutex, Executive, FALSE, _DEVICE_NODE::InstancePath, IopDoesDevNodeHaveProblem, IopTestForReconfiguration(), KernelMode, KeSetEvent(), KeWaitForSingleObject(), _DEVICE_NODE::LockCount, NULL, and _DEVICE_NODE::Sibling.

Referenced by IopQueryRebalance().

04676 : 04677 04678 This routine walks hardware tree depth first. For each device node it visits, 04679 it call IopQueryReconfigureDevice to query-stop and stop device for resource 04680 reconfiguration. 04681 04682 Parameters: 04683 04684 DeviceNode - supplies a pionter a device node which is the root of the tree to 04685 be tested. 04686 04687 Phase - Supplies a value to specify the phase of the rebalance. 04688 04689 RebalanceCount - supplies a pointer to a variable to receive the number of devices 04690 participating the rebalance. 04691 04692 Return Value: 04693 04694 None. 04695 04696 --*/ 04697 04698 { 04699 PDEVICE_NODE node; 04700 04701 if (DeviceNode == NULL) 04702 { 04703 ASSERT(DeviceNode); 04704 return; 04705 } 04706 04707 // 04708 // Include Insufficient_resources checking. THis is because a driver (scsiminiport) may call 04709 // IoReportResourceUsage to perform detection and cause the (Isapnp) enumerated device 04710 // insufficient_resources to start. At this point, the enumerated device resources should be locked down 04711 // for the detected instance. 04712 // 04713 04714 if (((DeviceNode->Flags & DNF_ASYNC_REQUEST_PENDING) || 04715 (DeviceNode->Flags & DNF_STOPPED) || 04716 (IopDoesDevNodeHaveProblem(DeviceNode)) || 04717 (DeviceNode->Flags & DNF_LEGACY_DRIVER) || 04718 (DeviceNode->Flags & DNF_ASSIGNING_RESOURCES)) && 04719 !(DeviceNode->Flags & DNF_NEEDS_REBALANCE)) { 04720 04721 node = DeviceNode->Sibling; 04722 04723 } else { 04724 04725 node = DeviceNode; 04726 04727 } 04728 04729 for (; node; node = node->Sibling) { 04730 04731 if (node->Child) { 04732 04733 // 04734 // If this subtree is not being removed, wait for current enumeration to complete. 04735 // 04736 04737 if (node->LockCount == 0) { 04738 04739 KeWaitForSingleObject( &node->EnumerationMutex, 04740 Executive, 04741 KernelMode, 04742 FALSE, 04743 NULL); 04744 04745 IopQueryRebalanceWorker (node->Child, Phase, RebalanceCount, DeviceTable); 04746 04747 KeSetEvent(&node->EnumerationMutex, 0, FALSE); 04748 } 04749 } 04750 } 04751 04752 for (node = DeviceNode; node; node = node->Sibling) { 04753 04754 if (node->LockCount == 0) { 04755 04756 IopTestForReconfiguration (node, Phase, RebalanceCount, DeviceTable); 04757 04758 } else { 04759 04760 DebugMessage(DUMP_ERROR, ("PNPRES: %ws enum lock is taken, skipping during REBALANCE!\n", node->InstancePath.Buffer)); 04761 04762 } 04763 } 04764 }

VOID IopReallocateResources IN PDEVICE_OBJECT  DeviceObject  ) 
 

Definition at line 7470 of file pnpres.c.

References ASSERT, DebugMessage, DelayExecution, DNF_ASSIGNING_RESOURCES, DNF_HAS_RESOURCE, DNF_NON_STOPPED_REBALANCE, DNF_RESOURCE_ASSIGNED, DNF_RESOURCE_REPORTED, DNF_RESOURCE_REQUIREMENTS_CHANGED, DUMP_ERROR, ExAcquireResourceShared, ExFreePool(), ExReleaseResource, FALSE, _IOP_RESOURCE_REQUEST::Flags, _DEVICE_NODE::Flags, IOP_ASSIGN_KEEP_CURRENT_CONFIG, IOP_ASSIGN_NO_REBALANCE, IopAcquireEnumerationLock, IopAssignInner(), IopBuildCmResourceLists(), IopDeviceTreeLock, IopFreeResourceRequirementsForAssignTable(), IopGetResourceRequirementsForAssignTable(), IopRebalance(), IopRegistrySemaphore, IopReleaseEnumerationLock, IopReleaseResourcesInternal(), IopRequestDeviceRemoval(), IopRestoreResourcesInternal(), IopStartDevice(), KeEnterCriticalRegion, KeLeaveCriticalRegion, KeReleaseSemaphore(), KernelMode, KeWaitForSingleObject(), NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, _IOP_RESOURCE_REQUEST::PhysicalDevice, _DEVICE_NODE::PhysicalDeviceObject, _IOP_RESOURCE_REQUEST::ResourceAssignment, _DEVICE_NODE::ResourceList, _DEVICE_NODE::ResourceListTranslated, _IOP_RESOURCE_REQUEST::TranslatedResourceAssignment, and TRUE.

Referenced by IopDeviceActionWorker().

07476 : 07477 07478 This routine performs the real work for IoInvalidateDeviceState - ResourceRequirementsChanged. 07479 07480 Arguments: 07481 07482 DeviceObject - Supplies a pointer to the device object. 07483 07484 Return Value: 07485 07486 None. 07487 07488 --*/ 07489 { 07490 PDEVICE_NODE deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode; 07491 IOP_RESOURCE_REQUEST requestTable, *requestTablep; 07492 ULONG deviceCount, oldFlags; 07493 NTSTATUS status; 07494 07495 PAGED_CODE(); 07496 07497 // 07498 // Grab the IO registry semaphore to make sure no other device is 07499 // reporting it's resource usage while we are searching for conflicts. 07500 // 07501 07502 KeEnterCriticalRegion(); 07503 status = KeWaitForSingleObject( &IopRegistrySemaphore, 07504 DelayExecution, 07505 KernelMode, 07506 FALSE, 07507 NULL); 07508 if (NT_SUCCESS(status)) { 07509 07510 // 07511 // Acquire the tree lock so we block remove for this device node. 07512 // 07513 07514 ExAcquireResourceShared(&IopDeviceTreeLock, TRUE); 07515 07516 // 07517 // Check the flags after acquiring the semaphore. 07518 // 07519 07520 if (deviceNode->Flags & DNF_RESOURCE_REQUIREMENTS_CHANGED) { 07521 // 07522 // Save the flags which we may have to restore in case of failure. 07523 // 07524 07525 oldFlags = deviceNode->Flags & DNF_HAS_RESOURCE; 07526 deviceNode->Flags &= ~(DNF_HAS_RESOURCE); 07527 07528 if (deviceNode->Flags & DNF_NON_STOPPED_REBALANCE) { 07529 07530 IopAcquireEnumerationLock(deviceNode); 07531 07532 // 07533 // Set up parameters to call real routine 07534 // 07535 07536 deviceNode->Flags |= DNF_ASSIGNING_RESOURCES; 07537 07538 RtlZeroMemory(&requestTable, sizeof(IOP_RESOURCE_REQUEST)); 07539 requestTable.PhysicalDevice = DeviceObject; 07540 requestTablep = &requestTable; 07541 requestTable.Flags |= IOP_ASSIGN_NO_REBALANCE + IOP_ASSIGN_KEEP_CURRENT_CONFIG; 07542 07543 status = IopGetResourceRequirementsForAssignTable( requestTablep, 07544 requestTablep + 1, 07545 &deviceCount); 07546 if (NT_SUCCESS(status) && deviceCount) { 07547 07548 // 07549 // Release the current resources to the arbiters. 07550 // Memory for ResourceList is not released. 07551 // 07552 07553 if (deviceNode->ResourceList) { 07554 07555 IopReleaseResourcesInternal(deviceNode); 07556 } 07557 07558 // 07559 // Try to do the assignment. 07560 // 07561 07562 status = IopAssignInner(deviceCount, requestTablep, FALSE); 07563 if (NT_SUCCESS(status)) { 07564 07565 deviceNode->Flags &= ~(DNF_RESOURCE_REQUIREMENTS_CHANGED | DNF_NON_STOPPED_REBALANCE); 07566 07567 IopBuildCmResourceLists(requestTablep, requestTablep + 1); 07568 07569 // 07570 // We need to release the pool space for ResourceList and ResourceListTranslated. 07571 // Because the earlier IopReleaseResourcesInternal does not release the pool. 07572 // 07573 07574 if (deviceNode->ResourceList) { 07575 07576 ExFreePool(deviceNode->ResourceList); 07577 07578 } 07579 if (deviceNode->ResourceListTranslated) { 07580 07581 ExFreePool(deviceNode->ResourceListTranslated); 07582 07583 } 07584 07585 deviceNode->ResourceList = requestTablep->ResourceAssignment; 07586 deviceNode->ResourceListTranslated = requestTablep->TranslatedResourceAssignment; 07587 deviceNode->Flags |= DNF_RESOURCE_ASSIGNED; 07588 deviceNode->Flags &= ~DNF_RESOURCE_REPORTED; 07589 07590 IopStartDevice(deviceNode->PhysicalDeviceObject); 07591 07592 } else { 07593 07594 NTSTATUS restoreResourcesStatus; 07595 07596 restoreResourcesStatus = IopRestoreResourcesInternal(deviceNode); 07597 if (!NT_SUCCESS(restoreResourcesStatus)) { 07598 07599 ASSERT(NT_SUCCESS(restoreResourcesStatus)); 07600 IopRequestDeviceRemoval(DeviceObject, CM_PROB_NORMAL_CONFLICT); 07601 07602 } 07603 07604 // 07605 // BUGBUG - once we failed, what will trigger us to try again? 07606 // 07607 } 07608 07609 IopFreeResourceRequirementsForAssignTable(requestTablep, requestTablep + 1); 07610 07611 07612 } else { 07613 07614 status = NT_SUCCESS(status)? STATUS_UNSUCCESSFUL : status; 07615 07616 } 07617 07618 deviceNode->Flags &= ~DNF_ASSIGNING_RESOURCES; 07619 IopReleaseEnumerationLock(deviceNode); 07620 07621 } else { 07622 07623 // 07624 // The device needs to be stopped to change resources. 07625 // 07626 07627 status = IopRebalance(0, NULL); 07628 07629 } 07630 07631 // 07632 // Restore the flags in case of failure. 07633 // 07634 07635 if (!NT_SUCCESS(status)) { 07636 07637 deviceNode->Flags &= ~DNF_HAS_RESOURCE; 07638 deviceNode->Flags |= oldFlags; 07639 07640 } 07641 07642 } else { 07643 07644 DebugMessage(DUMP_ERROR, ("PNPRES: Resource requirements not changed in IopReallocateResources, returning error!\n")); 07645 } 07646 07647 ExReleaseResource(&IopDeviceTreeLock); 07648 KeReleaseSemaphore(&IopRegistrySemaphore, 0, 1, FALSE); 07649 07650 } else { 07651 07652 DebugMessage(DUMP_ERROR, ("PNPRES: IopReallocateResources failed to acquire Registry semaphore, status %08X\n", status)); 07653 07654 } 07655 07656 KeLeaveCriticalRegion(); 07657 }

VOID IopRearrangeAssignTable IN PIOP_RESOURCE_REQUEST  AssignTable,
IN ULONG  Count
 

Definition at line 1878 of file pnpres.c.

References Count, IopCompareAlternativeCount(), and PAGED_CODE.

Referenced by IopAllocateResources().

01885 : 01886 01887 This routine sorts the REQ_ALTERNATIVE lists of REQ_LIST in increasing order (in terms of 01888 priority value.) Priority 1 is considered better than priority 2. 01889 01890 So, the better choice is placed in front of the list. 01891 01892 Parameters: 01893 01894 ReqList - Supplies a pointer to a REQ_LIST. 01895 01896 Return Value: 01897 01898 None. 01899 01900 --*/ 01901 01902 { 01903 PAGED_CODE(); 01904 01905 if (Count == 1 || Count == 0) { 01906 01907 // 01908 // Most ReqLists only have one alternative... 01909 // 01910 01911 return; 01912 } 01913 01914 qsort((void *)AssignTable, 01915 Count, 01916 sizeof(IOP_RESOURCE_REQUEST), 01917 IopCompareAlternativeCount 01918 ); 01919 }

VOID IopRearrangeReqList IN PREQ_LIST  ReqList  ) 
 

Definition at line 1811 of file pnpres.c.

References DebugMessage, DUMP_ERROR, _DEVICE_NODE::InstancePath, IopComparePriority(), NULL, PAGED_CODE, and PREQ_ALTERNATIVE.

Referenced by IopGetResourceRequirementsForAssignTable(), and IopRestoreResourcesInternal().

01817 : 01818 01819 This routine sorts the REQ_ALTERNATIVE lists of REQ_LIST in increasing order (in terms of 01820 priority value.) Priority 1 is considered better than priority 2. 01821 01822 So, the better choice is placed in front of the list. 01823 01824 Parameters: 01825 01826 ReqList - Supplies a pointer to a REQ_LIST. 01827 01828 Return Value: 01829 01830 None. 01831 01832 --*/ 01833 01834 { 01835 PREQ_ALTERNATIVE *alternative; 01836 PREQ_ALTERNATIVE *lastAlternative; 01837 01838 PAGED_CODE(); 01839 01840 if (ReqList->ReqAlternativeCount > 1) { 01841 01842 qsort( (void *)ReqList->ReqAlternativeTable, 01843 ReqList->ReqAlternativeCount, 01844 sizeof(PREQ_ALTERNATIVE), 01845 IopComparePriority); 01846 01847 } 01848 01849 // 01850 // Set the BestAlternative so that we try alternatives with priority <= LCPRI_LASTSOFTCONFIG. 01851 // 01852 01853 alternative = &ReqList->ReqAlternativeTable[0]; 01854 for (lastAlternative = alternative + ReqList->ReqAlternativeCount; alternative < lastAlternative; alternative++) { 01855 01856 if ((*alternative)->Priority > LCPRI_LASTSOFTCONFIG) { 01857 01858 break; 01859 01860 } 01861 } 01862 01863 if (alternative == &ReqList->ReqAlternativeTable[0]) { 01864 01865 PDEVICE_NODE deviceNode = (PDEVICE_NODE)ReqList->PhysicalDevice->DeviceObjectExtension->DeviceNode; 01866 01867 DebugMessage(DUMP_ERROR, ("PNPRES: Invalid priorities in the logical configs for %ws\n", deviceNode->InstancePath.Buffer)); 01868 // ASSERT(alternative != &ReqList->ReqAlternativeTable[0]); 01869 ReqList->ReqBestAlternative = NULL; 01870 01871 } else { 01872 01873 ReqList->ReqBestAlternative = alternative; 01874 } 01875 }

NTSTATUS IopRebalance IN ULONG  AssignTableCont,
IN PIOP_RESOURCE_REQUEST  AssignTable
 

Definition at line 5215 of file pnpres.c.

References _IOP_RESOURCE_REQUEST::AllocationType, ArbiterActionCommitAllocation, ArbiterRequestPnpEnumerated, ASSERT, DebugMessage, DelayExecution, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, DNF_NO_RESOURCE_REQUIRED, DNF_NON_STOPPED_REBALANCE, DNF_RESOURCE_ASSIGNED, DNF_RESOURCE_REPORTED, DNF_RESOURCE_REQUIREMENTS_CHANGED, DNF_STOPPED, DUMP_DETAIL, DUMP_ERROR, DUMP_INFO, ExAllocatePoolIORR, ExAllocatePoolPDO, ExFreePool(), exit, FALSE, _DEVICE_NODE::Flags, _IOP_RESOURCE_REQUEST::Flags, IOP_ASSIGN_CLEAR_RESOURCE_REQUIREMENTS_CHANGE_FLAG, IOP_ASSIGN_EXCLUDE, IOP_ASSIGN_IGNORE, IOP_ASSIGN_RESOURCES_RELEASED, IOP_RESOURCE_REQUEST, IopAssignInner(), IopBuildCmResourceLists(), IopCheckDataStructures(), IopFreeResourceRequirementsForAssignTable(), IopGetResourceRequirementsForAssignTable(), IopNumberDeviceNodes, IopPlacement(), IopQueryRebalance(), IopQueryReconfiguration(), IopRegistrySemaphore, IopReleaseResourcesInternal(), IopRequestDeviceRemoval(), IopRestoreResourcesInternal(), IopRootDeviceNode, IopStartDevice(), IRP_MN_CANCEL_STOP_DEVICE, IRP_MN_STOP_DEVICE, KeEnterCriticalRegion, KeLeaveCriticalRegion, KeReleaseSemaphore(), KernelMode, KeWaitForSingleObject(), NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, PagedPool, _IOP_RESOURCE_REQUEST::PhysicalDevice, PnpResDebugLevel, _IOP_RESOURCE_REQUEST::ResourceAssignment, _DEVICE_NODE::ResourceList, _DEVICE_NODE::ResourceListTranslated, _IOP_RESOURCE_REQUEST::Status, STOP_ERROR, _IOP_RESOURCE_REQUEST::TranslatedResourceAssignment, and TRUE.

Referenced by IopAllocateResources(), and IopReallocateResources().

05223 : 05224 05225 This routine performs rebalancing operation. There are two rebalance phases: 05226 In the phase 0, we only consider the devices whoes resource requirements changed 05227 and their children; in phase 1, we consider anyone who succeeds the query-stop. 05228 05229 Parameters: 05230 05231 AssignTableCount, 05232 AssignTable - Supplies the number of origianl AssignTableCout and AssignTable which 05233 triggers the rebalance operation. 05234 05235 (if AssignTableCount == 0, we are processing device state change.) 05236 05237 Return Value: 05238 05239 Status code that indicates whether or not the function was successful. 05240 05241 --*/ 05242 05243 { 05244 ULONG count, i; 05245 PIOP_RESOURCE_REQUEST table = NULL, tableEnd, newEntry; 05246 PIOP_RESOURCE_REQUEST requestTable = NULL, requestTableEnd, entry1, entry2; 05247 ULONG phase0RebalanceCount = 0, rebalanceCount = 0, deviceCount; 05248 NTSTATUS status, statusx; 05249 PDEVICE_OBJECT *deviceTable, *deviceTablex; 05250 PDEVICE_NODE deviceNode; 05251 ULONG rebalancePhase = 0; 05252 05253 // 05254 // Query all the device nodes to see who are willing to participate the rebalance 05255 // process. 05256 // 05257 05258 deviceTable = (PDEVICE_OBJECT *) ExAllocatePoolPDO( 05259 PagedPool, 05260 sizeof(PDEVICE_OBJECT) * IopNumberDeviceNodes); 05261 if (deviceTable == NULL) { 05262 DebugMessage(DUMP_ERROR, ("Rebalance: Not enough memory to perform rebalance\n")); 05263 return STATUS_INSUFFICIENT_RESOURCES; 05264 } 05265 05266 05267 tryAgain: 05268 deviceTablex = deviceTable + phase0RebalanceCount; 05269 05270 // 05271 // Walk device node tree depth-first to query-stop and stop devices. 05272 // At this point the resources of the stopped devices are not released yet. 05273 // Also, the leaf nodes are in the front of the device table and non leaf nodes 05274 // are at the end of the table. 05275 // 05276 05277 IopQueryRebalance (IopRootDeviceNode, rebalancePhase, &rebalanceCount, &deviceTablex); 05278 if (rebalanceCount == 0) { 05279 05280 // 05281 // If no one is interested and we are not processing resources req change, 05282 // move to next phase. 05283 // 05284 05285 if (rebalancePhase == 0 && AssignTableCount != 0) { 05286 rebalancePhase = 1; 05287 goto tryAgain; 05288 } 05289 DebugMessage(DUMP_INFO, ("Rebalance: No device participates in rebalance phase %x\n", rebalancePhase)); 05290 ExFreePool(deviceTable); 05291 deviceTable = NULL; 05292 status = STATUS_UNSUCCESSFUL; 05293 goto exit; 05294 } 05295 if (rebalanceCount == phase0RebalanceCount) { 05296 05297 // 05298 // Phase 0 failed and no new device participates. failed the rebalance. 05299 // 05300 05301 status = STATUS_UNSUCCESSFUL; 05302 goto exit; 05303 } 05304 if (rebalancePhase == 0) { 05305 phase0RebalanceCount = rebalanceCount; 05306 } 05307 05308 // 05309 // Allocate pool for the new reconfiguration requests and the original requests. 05310 // 05311 05312 table = (PIOP_RESOURCE_REQUEST) ExAllocatePoolIORR( 05313 PagedPool, 05314 sizeof(IOP_RESOURCE_REQUEST) * (AssignTableCount + rebalanceCount) 05315 ); 05316 if (table == NULL) { 05317 DebugMessage(DUMP_ERROR, ("Rebalance: Not enough memory to perform rebalance\n")); 05318 status = STATUS_INSUFFICIENT_RESOURCES; 05319 goto exit; 05320 } 05321 tableEnd = table + AssignTableCount + rebalanceCount; 05322 05323 // 05324 // Build a new resource request table. The original requests will be at the beginning 05325 // of the table and new requests (reconfigured devices) are at the end. 05326 // After the new request table is built, the leaf nodes will be in front of the table, 05327 // and non leaf nodes will be close to the end of the table. This is for optimization. 05328 // 05329 05330 // 05331 // Copy the original request to the front of our new request table. 05332 // 05333 05334 if (AssignTableCount != 0) { 05335 RtlMoveMemory(table, AssignTable, sizeof(IOP_RESOURCE_REQUEST) * AssignTableCount); 05336 } 05337 05338 // 05339 // Initialize all the new entries of our new request table, 05340 // 05341 05342 newEntry = table + AssignTableCount; 05343 RtlZeroMemory(newEntry, sizeof(IOP_RESOURCE_REQUEST) * rebalanceCount); 05344 for (i = 0, deviceTablex = deviceTable; i < rebalanceCount; i++, deviceTablex++) { 05345 newEntry[i].AllocationType = ArbiterRequestPnpEnumerated; 05346 newEntry[i].PhysicalDevice = *deviceTablex; 05347 } 05348 05349 status = IopGetResourceRequirementsForAssignTable( 05350 newEntry, 05351 tableEnd , 05352 &deviceCount); 05353 if (!NT_SUCCESS(status) || deviceCount == 0) { 05354 DebugMessage(DUMP_ERROR, ("Rebalance: GetResourceRequirementsForAssignTable failed\n")); 05355 status = NT_SUCCESS(status)? STATUS_UNSUCCESSFUL : status; 05356 goto exit; 05357 } 05358 05359 // 05360 // Process the AssignTable to remove any entry which is marked as IOP_ASSIGN_IGNORE 05361 // 05362 05363 if (deviceCount != rebalanceCount) { 05364 05365 deviceCount += AssignTableCount; 05366 requestTable = (PIOP_RESOURCE_REQUEST) ExAllocatePoolIORR( 05367 PagedPool, 05368 sizeof(IOP_RESOURCE_REQUEST) * deviceCount 05369 ); 05370 if (requestTable == NULL) { 05371 IopFreeResourceRequirementsForAssignTable(newEntry, tableEnd); 05372 status = STATUS_INSUFFICIENT_RESOURCES; 05373 goto exit; 05374 } 05375 for (entry1 = table, entry2 = requestTable; entry1 < tableEnd; entry1++) { 05376 if (!(entry1->Flags & IOP_ASSIGN_IGNORE)) { 05377 *entry2 = *entry1; 05378 entry2++; 05379 } else { 05380 // 05381 // BUGBUG!!! ??? (jamiehun) 05382 // if this assert fails, parts of this code are broken 05383 // 05384 ASSERT(entry1 >= newEntry); 05385 } 05386 } 05387 requestTableEnd = requestTable + deviceCount; 05388 } else { 05389 requestTable = table; 05390 requestTableEnd = tableEnd; 05391 deviceCount += AssignTableCount; 05392 } 05393 05394 // 05395 // DO NOT Sort the AssignTable 05396 // 05397 05398 //IopRearrangeAssignTable(requestTable, deviceCount); 05399 05400 #if 0 05401 05402 // 05403 // We are about to perform rebalance. Release the resources of the reconfiguration devices 05404 // 05405 05406 for (entry1 = newEntry; entry1 < tableEnd; entry1++) { 05407 if (!(entry1->Flags & IOP_ASSIGN_IGNORE) && 05408 !(entry1->Flags & IOP_ASSIGN_RESOURCES_RELEASED)) { 05409 deviceNode = (PDEVICE_NODE)entry1->PhysicalDevice->DeviceObjectExtension->DeviceNode; 05410 if (deviceNode->ResourceList) { 05411 05412 // 05413 // Call IopReleaseResourcesInternal instead of IopReleaseResources such that 05414 // the pool for devicenode->ResourceList is not freed. We need it to restart 05415 // the reconfigured devices in case rebalance failed. 05416 // 05417 05418 IopReleaseResourcesInternal(deviceNode); 05419 entry1->Flags |= IOP_ASSIGN_RESOURCES_RELEASED; 05420 } 05421 } 05422 } 05423 05424 #endif 05425 05426 // 05427 // Assign the resources. If we succeed, or if 05428 // there is a memory shortage return immediately. 05429 // 05430 05431 status = IopAssignInner(deviceCount, requestTable, TRUE); 05432 if (NT_SUCCESS(status)) { 05433 05434 // 05435 // If the rebalance succeeded, we need to restart all the reconfigured devices. 05436 // For the original devices, we will return and let IopAllocateResources to deal 05437 // with them. 05438 // 05439 05440 IopBuildCmResourceLists(requestTable, requestTableEnd); 05441 05442 // 05443 // Copy the new status back to the original AssignTable. 05444 // 05445 05446 if (AssignTableCount != 0) { 05447 RtlMoveMemory(AssignTable, requestTable, sizeof(IOP_RESOURCE_REQUEST) * AssignTableCount); 05448 } 05449 // 05450 // free resource requirements we allocated while here 05451 // 05452 IopFreeResourceRequirementsForAssignTable(requestTable+AssignTableCount, requestTableEnd); 05453 05454 if (table != requestTable) { 05455 05456 // 05457 // If we switched request table ... copy the contents of new table back to 05458 // the old table. 05459 // 05460 05461 for (entry1 = table, entry2 = requestTable; entry2 < requestTableEnd;) { 05462 05463 if (entry1->Flags & IOP_ASSIGN_IGNORE) { 05464 entry1++; 05465 continue; 05466 } 05467 *entry1 = *entry2; 05468 if (entry2->Flags & IOP_ASSIGN_EXCLUDE) { 05469 entry1->Status = STATUS_CONFLICTING_ADDRESSES; 05470 } 05471 entry2++; 05472 entry1++; 05473 } 05474 } 05475 05476 // 05477 // Go thru the origianl request table to stop each query-stopped/reconfigured device. 05478 // 05479 05480 DebugMessage(DUMP_DETAIL, ("PnpRes: STOP reconfigured devices during REBALANCE.\n")); 05481 05482 for (entry1 = newEntry; entry1 < tableEnd; entry1++) { 05483 if (NT_SUCCESS(entry1->Status)) { 05484 IopQueryReconfiguration (IRP_MN_STOP_DEVICE, entry1->PhysicalDevice); 05485 } else { 05486 IopQueryReconfiguration (IRP_MN_CANCEL_STOP_DEVICE, entry1->PhysicalDevice); 05487 deviceNode = (PDEVICE_NODE)entry1->PhysicalDevice->DeviceObjectExtension->DeviceNode; 05488 deviceNode->Flags &= ~DNF_STOPPED; 05489 } 05490 } 05491 05492 // 05493 // Commit the allocation AFTER stopping rebalance candidates. 05494 // 05495 05496 DebugMessage(DUMP_DETAIL, ("PnpRes: Commit the new allocation during REBALANCE.\n")); 05497 05498 IopPlacement(ArbiterActionCommitAllocation, TRUE); 05499 05500 #if DBG_SCOPE 05501 if (PnpResDebugLevel & STOP_ERROR) { 05502 IopCheckDataStructures(IopRootDeviceNode); 05503 } 05504 #endif 05505 05506 // 05507 // Go thru the origianl request table to start each stopped/reconfigured device. 05508 // 05509 05510 for (entry1 = tableEnd - 1; entry1 >= newEntry; entry1--) { 05511 deviceNode = (PDEVICE_NODE)entry1->PhysicalDevice->DeviceObjectExtension->DeviceNode; 05512 05513 if (NT_SUCCESS(entry1->Status)) { 05514 05515 // 05516 // We need to release the pool space for ResourceList and ResourceListTranslated. 05517 // Because the earlier IopReleaseResourcesInternal does not release the pool. 05518 // 05519 05520 if (deviceNode->ResourceList) { 05521 ExFreePool(deviceNode->ResourceList); 05522 } 05523 deviceNode->ResourceList = entry1->ResourceAssignment; 05524 if (deviceNode->ResourceListTranslated) { 05525 ExFreePool(deviceNode->ResourceListTranslated); 05526 } 05527 deviceNode->ResourceListTranslated = entry1->TranslatedResourceAssignment; 05528 if (deviceNode->ResourceList) { 05529 deviceNode->Flags |= DNF_RESOURCE_ASSIGNED; 05530 deviceNode->Flags &= ~DNF_RESOURCE_REPORTED; 05531 } else { 05532 deviceNode->Flags |= DNF_NO_RESOURCE_REQUIRED; 05533 } 05534 if (entry1->Flags & IOP_ASSIGN_CLEAR_RESOURCE_REQUIREMENTS_CHANGE_FLAG) { 05535 05536 // 05537 // If we are processing the resource requirements change request, 05538 // clear its related flags. 05539 // 05540 05541 deviceNode->Flags &= ~(DNF_RESOURCE_REQUIREMENTS_CHANGED | DNF_NON_STOPPED_REBALANCE); 05542 } 05543 05544 // 05545 // Some drivers (like ndis) may want to do resource allocation during START. 05546 // So let go of the IopRegistrySemaphore during the start. 05547 // 05548 05549 KeReleaseSemaphore(&IopRegistrySemaphore, 0, 1, FALSE); 05550 KeLeaveCriticalRegion(); 05551 IopStartDevice(entry1->PhysicalDevice); 05552 KeEnterCriticalRegion(); 05553 KeWaitForSingleObject( &IopRegistrySemaphore, 05554 DelayExecution, 05555 KernelMode, 05556 FALSE, 05557 NULL ); 05558 } 05559 } 05560 05561 // 05562 // Finally release the references of the reconfigured device objects 05563 // 05564 05565 for (deviceTablex = (deviceTable + rebalanceCount - 1); 05566 deviceTablex >= deviceTable; 05567 deviceTablex--) { 05568 ObDereferenceObject(*deviceTablex); 05569 } 05570 status = STATUS_SUCCESS; 05571 } else { 05572 05573 // 05574 // Rebalance failed. Free our internal representation of the rebalance 05575 // candidates' resource requirements lists. 05576 // BugBug - should optimize the code. 05577 // 05578 05579 IopFreeResourceRequirementsForAssignTable(requestTable + AssignTableCount, requestTableEnd); 05580 if (rebalancePhase == 0) { 05581 rebalancePhase++; 05582 if (requestTable) { 05583 ExFreePool(requestTable); 05584 } 05585 if (table && (table != requestTable)) { 05586 ExFreePool(table); 05587 } 05588 table = requestTable = NULL; 05589 goto tryAgain; 05590 } 05591 05592 // 05593 // Rebalance failed. Restore the resources for the reconfiguration participated devices. 05594 // Note, for some devices, their resource requirements may already changed. In this 05595 // case, the resources we restore do not reflect the new requirements. 05596 // 05597 05598 for (deviceTablex = (deviceTable + rebalanceCount - 1); 05599 deviceTablex >= deviceTable; 05600 deviceTablex--) { 05601 deviceNode = (PDEVICE_NODE)((*deviceTablex)->DeviceObjectExtension->DeviceNode); 05602 #if 0 05603 statusx = IopRestoreResourcesInternal(deviceNode); 05604 if (NT_SUCCESS(statusx)) { 05605 IopQueryReconfiguration (IRP_MN_CANCEL_STOP_DEVICE, *deviceTablex); 05606 deviceNode->Flags &= ~DNF_STOPPED; 05607 } else { 05608 ASSERT(0); 05609 IopRequestDeviceRemoval(*deviceTablex); 05610 } 05611 #else 05612 IopQueryReconfiguration (IRP_MN_CANCEL_STOP_DEVICE, *deviceTablex); 05613 deviceNode->Flags &= ~DNF_STOPPED; 05614 #endif 05615 ObDereferenceObject(*deviceTablex); 05616 } 05617 } 05618 ExFreePool(deviceTable); 05619 deviceTable = NULL; 05620 05621 exit: 05622 05623 if (!NT_SUCCESS(status) && deviceTable) { 05624 05625 // 05626 // If we failed before trying to perform resource assignment, 05627 // we will end up here. 05628 // 05629 05630 DebugMessage(DUMP_INFO, ("Rebalance: Rebalance failed\n")); 05631 05632 // 05633 // Somehow we failed to start the rebalance operation. 05634 // We will cancel the query-stop request for the query-stopped devices bredth first. 05635 // 05636 05637 for (deviceTablex = (deviceTable + rebalanceCount - 1); 05638 deviceTablex >= deviceTable; 05639 deviceTablex--) { 05640 05641 deviceNode = (PDEVICE_NODE)((*deviceTablex)->DeviceObjectExtension->DeviceNode); 05642 IopQueryReconfiguration (IRP_MN_CANCEL_STOP_DEVICE, *deviceTablex); 05643 deviceNode->Flags &= ~DNF_STOPPED; 05644 ObDereferenceObject(*deviceTablex); 05645 } 05646 } 05647 if (deviceTable) { 05648 ExFreePool(deviceTable); 05649 } 05650 if (requestTable) { 05651 ExFreePool(requestTable); 05652 } 05653 if (table && (table != requestTable)) { 05654 ExFreePool(table); 05655 } 05656 return status; 05657 }

VOID IopReleaseFilteredBootResources IN PIOP_RESOURCE_REQUEST  AssignTable,
IN PIOP_RESOURCE_REQUEST  AssignTableEnd
 

Definition at line 2474 of file pnpres.c.

References ArbiterRequestPnpEnumerated, ASSERT, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, DNF_BOOT_CONFIG_RESERVED, ExFreePool(), _IOP_RESOURCE_REQUEST::Flags, _DEVICE_NODE::Flags, IOP_ASSIGN_EXCLUDE, IopNeedToReleaseBootResources(), IopReleaseResourcesInternal(), IopReserveBootResourcesInternal(), IopRestoreResourcesInternal(), NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, _IOP_RESOURCE_REQUEST::PhysicalDevice, _IOP_RESOURCE_REQUEST::ResourceAssignment, _DEVICE_NODE::ResourceList, and _IOP_RESOURCE_REQUEST::Status.

Referenced by IopAllocateResources().

02481 : 02482 02483 For each AssignTable entry, this routine checks if we need to manually release the device's 02484 boot resources. 02485 02486 Parameters: 02487 02488 AssignTable - supplies a pointer to the first entry of a IOP_RESOURCE_REQUEST table. 02489 02490 AssignTableEnd - supplies a pointer to the end of IOP_RESOURCE_REQUEST table. 02491 02492 Return Value: 02493 02494 None. 02495 02496 --*/ 02497 02498 { 02499 NTSTATUS status; 02500 PIOP_RESOURCE_REQUEST assignEntry; 02501 PDEVICE_OBJECT physicalDevice; 02502 PDEVICE_NODE deviceNode; 02503 02504 PAGED_CODE(); 02505 02506 // 02507 // Go thru each entry, for each Physical device object, we build a CmResourceList 02508 // from its ListOfAssignedResources. 02509 // 02510 02511 for (assignEntry = AssignTable; assignEntry < AssignTableEnd; ++assignEntry) { 02512 02513 if (assignEntry->ResourceAssignment) { 02514 physicalDevice = assignEntry->PhysicalDevice; 02515 deviceNode = (PDEVICE_NODE)physicalDevice->DeviceObjectExtension->DeviceNode; 02516 02517 // 02518 // Release the device's boot resources if desired 02519 // (If a driver filters its res req list and removes some boot resources, after arbiter satisfies 02520 // the new res req list, the filtered out boot resources do not get 02521 // released by arbiters. Because they no longer passed to arbiters. ) 02522 // I am not 100% sure we should release the filtered boot resources. But that's what arbiters try 02523 // to achieve. So, we will do it. 02524 // 02525 02526 if (IopNeedToReleaseBootResources(deviceNode, assignEntry->ResourceAssignment)) { 02527 IopReleaseResourcesInternal(deviceNode); 02528 IopReserveBootResourcesInternal( 02529 ArbiterRequestPnpEnumerated, 02530 physicalDevice, 02531 assignEntry->ResourceAssignment); 02532 deviceNode->Flags &= ~DNF_BOOT_CONFIG_RESERVED; // Keep DeviceNode->BootResources 02533 deviceNode->ResourceList = assignEntry->ResourceAssignment; 02534 status = IopRestoreResourcesInternal(deviceNode); 02535 ASSERT(status == STATUS_SUCCESS); 02536 if (!NT_SUCCESS(status)) { 02537 02538 // 02539 // BUGBUG - according to arbiter design, we should bugcheck. 02540 // 02541 02542 assignEntry->Flags = IOP_ASSIGN_EXCLUDE; 02543 assignEntry->Status = status; 02544 ExFreePool(assignEntry->ResourceAssignment); 02545 assignEntry->ResourceAssignment = NULL; 02546 } 02547 deviceNode->ResourceList = NULL; 02548 } 02549 } 02550 } 02551 }

VOID IopReleaseResources IN PDEVICE_NODE  DeviceNode  ) 
 

Definition at line 7383 of file pnpres.c.

References ArbiterRequestPnpEnumerated, DNF_BOOT_CONFIG_RESERVED, DNF_DEVICE_GONE, DNF_HAS_BOOT_CONFIG, DNF_MADEUP, DNF_RESOURCE_ASSIGNED, DNF_RESOURCE_REPORTED, ExFreePool(), IopReleaseResourcesInternal(), IopReserveBootResourcesInternal(), NT_SUCCESS, and NULL.

Referenced by IopLegacyResourceAllocation().

07389 : 07390 07391 IopReleaseResources releases resources owned by the device and release 07392 the memory pool. We also release the cached resource requirements list. 07393 If the device is a root enumerated device with BOOT config, we will preallocate 07394 boot config resources for this device. 07395 07396 NOTE, this is a routine INTERNAL to this file. NO one should call this function 07397 outside of this file. Outside of this file, IopReleaseDeviceResources should be 07398 used. 07399 07400 Arguments: 07401 07402 DeviceNode - Supplies a pointer to the device node.object. If present, caller wants to 07403 07404 Return Value: 07405 07406 None. 07407 07408 --*/ 07409 { 07410 07411 // 07412 // Release the resources owned by the device 07413 // 07414 07415 IopReleaseResourcesInternal(DeviceNode); 07416 DeviceNode->Flags &= ~DNF_RESOURCE_ASSIGNED; 07417 DeviceNode->Flags &= ~DNF_RESOURCE_REPORTED; 07418 07419 #if DBG_SCOPE 07420 07421 if (DeviceNode->PreviousResourceList) { 07422 ExFreePool(DeviceNode->PreviousResourceList); 07423 DeviceNode->PreviousResourceList = NULL; 07424 } 07425 if (DeviceNode->PreviousResourceRequirements) { 07426 ExFreePool(DeviceNode->PreviousResourceRequirements); 07427 DeviceNode->PreviousResourceRequirements = NULL; 07428 } 07429 #endif 07430 07431 if (DeviceNode->ResourceList) { 07432 07433 #if DBG_SCOPE 07434 if (!NT_SUCCESS(DeviceNode->FailureStatus)) { 07435 DeviceNode->PreviousResourceList = DeviceNode->ResourceList; 07436 } else { 07437 ExFreePool(DeviceNode->ResourceList); 07438 } 07439 #else 07440 ExFreePool(DeviceNode->ResourceList); 07441 #endif 07442 07443 DeviceNode->ResourceList = NULL; 07444 } 07445 if (DeviceNode->ResourceListTranslated) { 07446 ExFreePool(DeviceNode->ResourceListTranslated); 07447 DeviceNode->ResourceListTranslated = NULL; 07448 } 07449 07450 // 07451 // If this device is a root enumerated device, preallocate its BOOT resources 07452 // 07453 07454 if ((DeviceNode->Flags & (DNF_MADEUP | DNF_DEVICE_GONE)) == DNF_MADEUP) { 07455 if (DeviceNode->Flags & DNF_HAS_BOOT_CONFIG && DeviceNode->BootResources) { 07456 IopReserveBootResourcesInternal(ArbiterRequestPnpEnumerated, 07457 DeviceNode->PhysicalDeviceObject, 07458 DeviceNode->BootResources); 07459 } 07460 } else { 07461 DeviceNode->Flags &= ~(DNF_HAS_BOOT_CONFIG | DNF_BOOT_CONFIG_RESERVED); 07462 if (DeviceNode->BootResources) { 07463 ExFreePool(DeviceNode->BootResources); 07464 DeviceNode->BootResources = NULL; 07465 } 07466 } 07467 }

VOID IopReleaseResourcesInternal IN PDEVICE_NODE  DeviceNode  ) 
 

Definition at line 5757 of file pnpres.c.

References _ARBITER_LIST_ENTRY::AlternativeCount, _ARBITER_LIST_ENTRY::Alternatives, ArbiterActionCommitAllocation, ArbiterActionTestAllocation, _PI_RESOURCE_ARBITER_ENTRY::ArbiterInterface, ArbiterRequestPnpEnumerated, ASSERT, _ARBITER_LIST_ENTRY::Assignment, _DEVICE_NODE::DeviceArbiterList, FALSE, _ARBITER_LIST_ENTRY::Flags, IopCallArbiter(), IopFindBusDeviceNode(), IopRootDeviceNode, IopWriteAllocatedResourcesToRegistry(), _ARBITER_LIST_ENTRY::ListEntry, NTSTATUS(), NULL, _DEVICE_NODE::Parent, _ARBITER_LIST_ENTRY::PhysicalDeviceObject, PnpDefaultInterfaceType, _ARBITER_LIST_ENTRY::RequestSource, _PI_RESOURCE_ARBITER_ENTRY::ResourceList, TRUE, and _ARBITER_LIST_ENTRY::WorkSpace.

Referenced by IopReallocateResources(), IopRebalance(), IopReleaseFilteredBootResources(), and IopReleaseResources().

05763 : 05764 05765 This routine releases the assigned resources for device specified by DeviceNode. 05766 Note, this routine does not reset the resource related fields in DeviceNode structure. 05767 05768 Parameters: 05769 05770 DeviceNode - specifies the device node whose resources are goint to be released. 05771 05772 Return Value: 05773 05774 Status code that indicates whether or not the function was successful. 05775 05776 --*/ 05777 05778 { 05779 PDEVICE_NODE device; 05780 PLIST_ENTRY listHead, listEntry; 05781 PPI_RESOURCE_ARBITER_ENTRY arbiterEntry; 05782 ARBITER_LIST_ENTRY arbiterListEntry; 05783 INTERFACE_TYPE interfaceType; 05784 ULONG busNumber, listCount, i, j, size; 05785 PCM_RESOURCE_LIST resourceList; 05786 PCM_FULL_RESOURCE_DESCRIPTOR cmFullDesc; 05787 PCM_PARTIAL_RESOURCE_DESCRIPTOR cmPartDesc; 05788 BOOLEAN search = TRUE; 05789 #if DBG 05790 NTSTATUS status; 05791 #endif 05792 05793 InitializeListHead(&arbiterListEntry.ListEntry); 05794 arbiterListEntry.AlternativeCount = 0; 05795 arbiterListEntry.Alternatives = NULL; 05796 arbiterListEntry.PhysicalDeviceObject = DeviceNode->PhysicalDeviceObject; 05797 arbiterListEntry.Flags = 0; 05798 arbiterListEntry.WorkSpace = 0; 05799 arbiterListEntry.Assignment = NULL; 05800 arbiterListEntry.RequestSource = ArbiterRequestPnpEnumerated; 05801 05802 resourceList = DeviceNode->ResourceList; 05803 if (resourceList == NULL) { 05804 resourceList = DeviceNode->BootResources; 05805 } 05806 if (resourceList && resourceList->Count > 0) { 05807 listCount = resourceList->Count; 05808 cmFullDesc = &resourceList->List[0]; 05809 } else { 05810 listCount = 1; 05811 resourceList = NULL; 05812 } 05813 for (i = 0; i < listCount; i++) { 05814 05815 if (resourceList) { 05816 interfaceType = cmFullDesc->InterfaceType; 05817 busNumber = cmFullDesc->BusNumber; 05818 if (interfaceType == InterfaceTypeUndefined) { 05819 interfaceType = PnpDefaultInterfaceType; 05820 } 05821 } else { 05822 interfaceType = PnpDefaultInterfaceType; 05823 busNumber = 0; 05824 } 05825 05826 device = DeviceNode->Parent; 05827 while (device) { 05828 if ((device == IopRootDeviceNode) && search) { 05829 device = IopFindBusDeviceNode ( 05830 IopRootDeviceNode, 05831 interfaceType, 05832 busNumber, 05833 0 05834 ); 05835 05836 // 05837 // If we did not find a PDO, try again with InterfaceType == Isa. This allows 05838 // drivers that request Internal to get resources even if there is no PDO 05839 // that is Internal. (but if there is an Internal PDO, they get that one) 05840 // 05841 05842 if ((device == IopRootDeviceNode) && (interfaceType == Internal)) { 05843 device = IopFindBusDeviceNode(IopRootDeviceNode, Isa, 0, 0); 05844 } 05845 search = FALSE; 05846 05847 } 05848 listHead = &device->DeviceArbiterList; 05849 listEntry = listHead->Flink; 05850 while (listEntry != listHead) { 05851 arbiterEntry = CONTAINING_RECORD(listEntry, PI_RESOURCE_ARBITER_ENTRY, DeviceArbiterList); 05852 if (arbiterEntry->ArbiterInterface != NULL) { 05853 search = FALSE; 05854 ASSERT(IsListEmpty(&arbiterEntry->ResourceList)); 05855 InitializeListHead(&arbiterEntry->ResourceList); // Recover from assert 05856 InsertTailList(&arbiterEntry->ResourceList, &arbiterListEntry.ListEntry); 05857 #if DBG 05858 status = 05859 #endif 05860 IopCallArbiter(arbiterEntry, 05861 ArbiterActionTestAllocation, 05862 &arbiterEntry->ResourceList, 05863 NULL, 05864 NULL 05865 ); 05866 #if DBG 05867 ASSERT(status == STATUS_SUCCESS); 05868 status = 05869 #endif 05870 IopCallArbiter(arbiterEntry, 05871 ArbiterActionCommitAllocation, 05872 NULL, 05873 NULL, 05874 NULL 05875 ); 05876 #if DBG 05877 ASSERT(status == STATUS_SUCCESS); 05878 #endif 05879 RemoveEntryList(&arbiterListEntry.ListEntry); 05880 InitializeListHead(&arbiterListEntry.ListEntry); 05881 } 05882 listEntry = listEntry->Flink; 05883 } 05884 device = device->Parent; 05885 } 05886 05887 // 05888 // If there are more than 1 list, move to next list 05889 // 05890 05891 if (listCount > 1) { 05892 cmPartDesc = &cmFullDesc->PartialResourceList.PartialDescriptors[0]; 05893 for (j = 0; j < cmFullDesc->PartialResourceList.Count; j++) { 05894 size = 0; 05895 switch (cmPartDesc->Type) { 05896 case CmResourceTypeDeviceSpecific: 05897 size = cmPartDesc->u.DeviceSpecificData.DataSize; 05898 break; 05899 } 05900 cmPartDesc++; 05901 cmPartDesc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmPartDesc + size); 05902 } 05903 cmFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)cmPartDesc; 05904 } 05905 } 05906 05907 IopWriteAllocatedResourcesToRegistry (DeviceNode, NULL, 0); 05908 }

VOID IopRemoveLegacyDeviceNode IN PDEVICE_OBJECT DeviceObject  OPTIONAL,
IN PDEVICE_NODE  LegacyDeviceNode
 

Definition at line 6083 of file pnpres.c.

References ASSERT, DebugMessage, DO_BUS_ENUMERATED_DEVICE, _DEVICE_OBJECT::DriverObject, DUMP_ERROR, IoDeleteDevice(), IopDestroyDeviceNode(), IopLegacyDeviceNode, IoPnpDriverObject, NULL, _DEVICE_NODE::OverUsed1, and _DEVICE_NODE::OverUsed2.

Referenced by IopLegacyResourceAllocation().

06090 : 06091 06092 This routine removes the device node and device object created for legacy resource 06093 allocation for the DeviceObject. 06094 06095 Parameters: 06096 06097 DeviceObject - specifies the device object. 06098 06099 LegacyDeviceNode - receives the pointer to the legacy device node if found. 06100 06101 Return Value: 06102 06103 Status code that indicates whether or not the function was successful. 06104 06105 --*/ 06106 06107 { 06108 ASSERT(LegacyDeviceNode); 06109 06110 06111 if (!DeviceObject) { 06112 06113 if (LegacyDeviceNode->DuplicatePDO) { 06114 06115 LegacyDeviceNode->DuplicatePDO = NULL; 06116 if (LegacyDeviceNode->PreviousDeviceNode) { 06117 06118 LegacyDeviceNode->PreviousDeviceNode->NextDeviceNode = LegacyDeviceNode->NextDeviceNode; 06119 06120 } 06121 06122 if (LegacyDeviceNode->NextDeviceNode) { 06123 06124 LegacyDeviceNode->NextDeviceNode->PreviousDeviceNode = LegacyDeviceNode->PreviousDeviceNode; 06125 06126 } 06127 06128 if (IopLegacyDeviceNode == LegacyDeviceNode) { 06129 06130 IopLegacyDeviceNode = LegacyDeviceNode->NextDeviceNode; 06131 06132 } 06133 06134 } else { 06135 06136 DebugMessage(DUMP_ERROR, ("PNPRES: %ws does not have a duplicate PDO\n", LegacyDeviceNode->InstancePath.Buffer)); 06137 ASSERT(LegacyDeviceNode->DuplicatePDO); 06138 return; 06139 06140 } 06141 } 06142 06143 if (!(DeviceObject && (DeviceObject->Flags & DO_BUS_ENUMERATED_DEVICE))) { 06144 06145 PDEVICE_NODE resourceDeviceNode; 06146 PDEVICE_OBJECT pdo; 06147 06148 for ( resourceDeviceNode = (PDEVICE_NODE)LegacyDeviceNode->OverUsed1.LegacyDeviceNode; 06149 resourceDeviceNode; 06150 resourceDeviceNode = resourceDeviceNode->OverUsed2.NextResourceDeviceNode) { 06151 06152 if (resourceDeviceNode->OverUsed2.NextResourceDeviceNode == LegacyDeviceNode) { 06153 06154 resourceDeviceNode->OverUsed2.NextResourceDeviceNode = LegacyDeviceNode->OverUsed2.NextResourceDeviceNode; 06155 break; 06156 06157 } 06158 } 06159 06160 LegacyDeviceNode->Parent = LegacyDeviceNode->Sibling = 06161 LegacyDeviceNode->Child = LegacyDeviceNode->LastChild = NULL; 06162 06163 // 06164 // Delete the dummy PDO and device node. 06165 // 06166 06167 pdo = LegacyDeviceNode->PhysicalDeviceObject; 06168 IopDestroyDeviceNode(LegacyDeviceNode); 06169 06170 if (!DeviceObject) { 06171 06172 pdo->DriverObject = IoPnpDriverObject; 06173 IoDeleteDevice(pdo); 06174 } 06175 } 06176 }

VOID IopRemoveReqDescsFromArbiters ULONG  ReqDescCount,
PREQ_DESC ReqDescTable
 

Definition at line 2780 of file pnpres.c.

References _PI_RESOURCE_ARBITER_ENTRY::ActiveArbiterList, ArbiterActionRollbackAllocation, ASSERT, FALSE, IopCallArbiter(), NULL, PI_ARBITER_HAS_SOMETHING, PREQ_DESC, _PI_RESOURCE_ARBITER_ENTRY::ResourceList, _PI_RESOURCE_ARBITER_ENTRY::ResourcesChanged, _PI_RESOURCE_ARBITER_ENTRY::State, _REQ_DESC::TranslatedReqDesc, and TRUE.

Referenced by IopAssign().

02787 : 02788 02789 This routine removes a list of a req descriptors from their arbiters. 02790 02791 Parameters: 02792 02793 P1 - 02794 02795 Return Value: 02796 02797 None. 02798 02799 --*/ 02800 { 02801 PREQ_DESC reqDesc; 02802 PREQ_DESC reqDescTranslated; 02803 PLIST_ENTRY listHead; 02804 PPI_RESOURCE_ARBITER_ENTRY arbiterEntry; 02805 PREQ_DESC *reqDescTableEnd; 02806 02807 for (reqDescTableEnd = ReqDescTable + ReqDescCount; ReqDescTable < reqDescTableEnd; ReqDescTable++) { 02808 02809 // 02810 // For each req desc, find its arbiter, remove the req desc from its arbiter. 02811 // 02812 02813 reqDesc = *ReqDescTable; 02814 if (reqDesc->ArbitrationRequired) { 02815 02816 reqDescTranslated = reqDesc->TranslatedReqDesc; 02817 arbiterEntry = reqDesc->u.Arbiter; 02818 ASSERT(IsListEmpty(&arbiterEntry->ResourceList) == FALSE); 02819 02820 arbiterEntry->ResourcesChanged = TRUE; 02821 if (arbiterEntry->State & PI_ARBITER_HAS_SOMETHING) { 02822 02823 IopCallArbiter(arbiterEntry, ArbiterActionRollbackAllocation, NULL, NULL, NULL); 02824 arbiterEntry->State &= ~PI_ARBITER_HAS_SOMETHING; 02825 } 02826 02827 RemoveEntryList(&reqDescTranslated->AlternativeTable.ListEntry); 02828 InitializeListHead(&reqDescTranslated->AlternativeTable.ListEntry); 02829 listHead = &arbiterEntry->ResourceList; 02830 if (IsListEmpty(listHead)) { 02831 02832 // 02833 // Remove the arbiter entry from our active arbiter list if it has no resource 02834 // to arbitrate. 02835 // 02836 02837 RemoveEntryList(&arbiterEntry->ActiveArbiterList); 02838 InitializeListHead(&arbiterEntry->ActiveArbiterList); 02839 } 02840 } 02841 } 02842 }

NTSTATUS IopReserve IN PREQ_LIST  ReqList  ) 
 

Definition at line 3376 of file pnpres.c.

References IopAddReqDescsToArbiters(), IopCheckDataStructures(), IopPlacementForReservation(), IopRootDeviceNode, NTSTATUS(), PAGED_CODE, PiActiveArbiterList, PiBestArbiterList, PnpResDebugLevel, PREQ_ALTERNATIVE, RA, and STOP_ERROR.

Referenced by IopReserveBootResourcesInternal().

03382 : 03383 03384 This routine performs the resource allocation for the passed in AssignTables. 03385 03386 Parameters: 03387 03388 03389 Return Value: 03390 03391 Status code that indicates whether or not the function was successful. 03392 03393 --*/ 03394 03395 { 03396 NTSTATUS status; 03397 PREQ_ALTERNATIVE RA; 03398 PREQ_ALTERNATIVE *reqAlternative; 03399 03400 PAGED_CODE(); 03401 03402 // 03403 // Initialize static variable 03404 // 03405 03406 InitializeListHead(&PiBestArbiterList); 03407 InitializeListHead(&PiActiveArbiterList); 03408 03409 reqAlternative = ReqList->ReqAlternativeTable; 03410 03411 RA = *reqAlternative; 03412 ReqList->SelectedAlternative = reqAlternative; 03413 IopAddReqDescsToArbiters(RA->ReqDescCount, RA->ReqDescTable); 03414 status = IopPlacementForReservation(); 03415 #if DBG_SCOPE 03416 if (PnpResDebugLevel & STOP_ERROR) { 03417 IopCheckDataStructures(IopRootDeviceNode); 03418 } 03419 #endif 03420 return status; 03421 }

NTSTATUS IopReserveBootResources IN ARBITER_REQUEST_SOURCE  ArbiterRequestSource,
IN PDEVICE_OBJECT  DeviceObject,
IN PCM_RESOURCE_LIST  BootResources
 

Definition at line 7291 of file pnpres.c.

References ASSERT, _DEVICE_NODE::BootResources, DNF_MADEUP, ExAllocatePoolIORL, ExAllocatePoolIORRR, ExFreePool(), _DEVICE_NODE::Flags, IopAllocateBootResources(), IopDetermineResourceListSize(), IopInitReservedResourceList, NTSTATUS(), NULL, PagedPool, and PIOP_RESERVED_RESOURCES_RECORD.

Referenced by IopInitializePlugPlayServices().

07299 : 07300 07301 This routine reports boot resources for the specified device to 07302 arbiters. Since the real resource pre-alloc routine can only be called after 07303 all the arbiters and translators are present, all the calls to pre-alloc resources 07304 before the preallocation routine is available will be routed to this routine. 07305 07306 Arguments: 07307 07308 DeviceObject - Supplies a pointer to the device object. If present, caller wants to 07309 preallocate BOOT resources for a device object. If NULL, caller wants to reserved 07310 resources for some unknown devices. 07311 07312 BootResources - Supplies a pointer to the Boot resources. 07313 07314 Return Value: 07315 07316 None. 07317 07318 --*/ 07319 { 07320 PIOP_RESERVED_RESOURCES_RECORD resourceRecord; 07321 PDEVICE_NODE deviceNode; 07322 ULONG size; 07323 NTSTATUS status; 07324 07325 status = STATUS_SUCCESS;; 07326 size = IopDetermineResourceListSize(BootResources); 07327 if (size != 0) { 07328 07329 deviceNode = (PDEVICE_NODE)((DeviceObject)? DeviceObject->DeviceObjectExtension->DeviceNode : NULL); 07330 07331 // 07332 // Pre-allocate BOOT configs right away for non-madeup devices. 07333 // 07334 07335 if (DeviceObject && !(deviceNode->Flags & DNF_MADEUP)) { 07336 07337 return IopAllocateBootResources(ArbiterRequestSource, DeviceObject, BootResources); 07338 07339 } 07340 07341 07342 if (DeviceObject) { 07343 07344 ASSERT(deviceNode); 07345 deviceNode->BootResources = ExAllocatePoolIORL(PagedPool, size); 07346 if (deviceNode->BootResources) { 07347 07348 RtlMoveMemory(deviceNode->BootResources, BootResources, size); 07349 07350 } else { 07351 07352 return STATUS_INSUFFICIENT_RESOURCES; 07353 07354 } 07355 } 07356 07357 resourceRecord = (PIOP_RESERVED_RESOURCES_RECORD) ExAllocatePoolIORRR( PagedPool, 07358 sizeof(IOP_RESERVED_RESOURCES_RECORD)); 07359 if (resourceRecord) { 07360 07361 resourceRecord->ReservedResources = (DeviceObject)? deviceNode->BootResources : BootResources; 07362 resourceRecord->DeviceObject = DeviceObject; 07363 resourceRecord->Next = IopInitReservedResourceList; 07364 IopInitReservedResourceList = resourceRecord; 07365 07366 } else { 07367 07368 if (deviceNode && deviceNode->BootResources) { 07369 07370 ExFreePool(deviceNode->BootResources); 07371 07372 } 07373 07374 return STATUS_INSUFFICIENT_RESOURCES; 07375 07376 } 07377 } 07378 07379 return status; 07380 }

NTSTATUS IopReserveBootResourcesInternal IN ARBITER_REQUEST_SOURCE  ArbiterRequestSource,
IN PDEVICE_OBJECT  DeviceObject,
IN PCM_RESOURCE_LIST  BootResources
 

Definition at line 7198 of file pnpres.c.

References ASSERT, _DEVICE_NODE::BootResources, DbgPrint, DNF_BOOT_CONFIG_RESERVED, ExAllocatePoolIORL, ExFreePool(), _DEVICE_NODE::Flags, _DEVICE_NODE::InstancePath, IopCmResourcesToIoResources(), IopDetermineResourceListSize(), IopDumpResourceRequirementsList(), IopFreeReqList(), IopReserve(), IopResourceRequirementsListToReqList(), NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, and PREQ_LIST.

Referenced by IopAllocateBootResources(), IopReleaseFilteredBootResources(), and IopReleaseResources().

07206 : 07207 07208 This routine reports boot resources for the specified device to 07209 arbiters. 07210 07211 Arguments: 07212 07213 DeviceObject - Supplies a pointer to the device object, could be NULL 07214 if DeviceObject is NULL, the BootResources are reserved and will not be given 07215 to a device unless there is no other choice. The caller must release the 07216 pool for BootResources. 07217 if DeviceObject is NON_NULL, BootResources are BOOT reserved (preallocated.) 07218 07219 BootResources - Supplies a pointer to the Boot resources. 07220 07221 Return Value: 07222 07223 None. 07224 07225 --*/ 07226 { 07227 PIO_RESOURCE_REQUIREMENTS_LIST ioResources; 07228 PREQ_LIST reqList; 07229 NTSTATUS status = STATUS_SUCCESS; 07230 PDEVICE_NODE deviceNode; 07231 07232 PAGED_CODE(); 07233 07234 if (DeviceObject) { 07235 deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode; 07236 } 07237 ioResources = IopCmResourcesToIoResources(0, BootResources, LCPRI_BOOTCONFIG); 07238 if (ioResources) { 07239 #if MYDBG 07240 if (deviceNode) { 07241 DbgPrint("\n===================================\n"); 07242 DbgPrint("PreAllocate Resource List for %wZ :: \n", &deviceNode->InstancePath); 07243 } else { 07244 DbgPrint("Reserve Resource List :: "); 07245 } 07246 IopDumpResourceRequirementsList(ioResources); 07247 DbgPrint(" ++++++++++++++++++++++++++++++\n"); 07248 #endif 07249 07250 status = IopResourceRequirementsListToReqList( 07251 ArbiterRequestSource, 07252 ioResources, 07253 DeviceObject, 07254 &reqList); 07255 07256 if (NT_SUCCESS(status) && reqList) { 07257 IopReserve(reqList); 07258 if (DeviceObject) { 07259 deviceNode->Flags |= DNF_BOOT_CONFIG_RESERVED; 07260 if (deviceNode->BootResources == NULL) { 07261 ULONG size; 07262 07263 // 07264 // If we have not remember the root enumerated device's boot resources 07265 // do it now. We always need to pre-allocate boot config for root enumerated 07266 // devices when their resources are released. 07267 // 07268 07269 size = IopDetermineResourceListSize (BootResources); 07270 deviceNode->BootResources = ExAllocatePoolIORL(PagedPool, size); 07271 if (deviceNode->BootResources) { 07272 RtlMoveMemory(deviceNode->BootResources, BootResources, size); 07273 } else { 07274 status = STATUS_INSUFFICIENT_RESOURCES; 07275 } 07276 } 07277 } 07278 IopFreeReqList(reqList); 07279 } else { 07280 #if MYDBG 07281 ASSERT(0); // For now 07282 #endif 07283 } 07284 ExFreePool(ioResources); 07285 } 07286 07287 return status; 07288 }

NTSTATUS IopReserveLegacyBootResources IN INTERFACE_TYPE  InterfaceType,
IN ULONG  BusNumber
 

Definition at line 6996 of file pnpres.c.

References ArbiterRequestHalReported, ArbiterRequestPnpEnumerated, ASSERT, _DEVICE_NODE::BootResources, BusNumber, DbgPrint, DebugMessage, DNF_HAS_BOOT_CONFIG, DUMP_INFO, ExFreePool(), _DEVICE_NODE::Flags, InterfaceType, IopAllocateBootResources(), IopCombineCmResourceList(), IopCreateCmResourceList(), IopDumpCmResourceList(), IopInitHalDeviceNode, IopInitHalResources, IopInitReservedResourceList, NT_SUCCESS, NTSTATUS(), NULL, _DEVICE_NODE::PhysicalDeviceObject, PIOP_RESERVED_RESOURCES_RECORD, and PnpResDebugLevel.

Referenced by IopEnumerateDevice(), and IopInitializeBootDrivers().

07003 : 07004 07005 This routine is called to reserve legacy BOOT resources for the specified InterfaceType 07006 and BusNumber. This is done everytime a new bus with a legacy InterfaceType gets enumerated. 07007 07008 Arguments: 07009 07010 InterfaceType - Legacy InterfaceType. 07011 07012 BusNumber - Legacy BusNumber 07013 07014 Return Value: 07015 07016 The status returned is the final completion status of the operation. 07017 07018 --*/ 07019 07020 { 07021 NTSTATUS status; 07022 PIOP_RESERVED_RESOURCES_RECORD resourceRecord, prevRecord; 07023 PCM_RESOURCE_LIST newList, remainingList; 07024 07025 if (IopInitHalDeviceNode && IopInitHalResources) { 07026 07027 remainingList = NULL; 07028 newList = IopCreateCmResourceList(IopInitHalResources, InterfaceType, BusNumber, &remainingList); 07029 if (newList) { 07030 07031 if (remainingList == NULL) { 07032 07033 // 07034 // Full match. Check for error. 07035 // 07036 07037 ASSERT(newList == IopInitHalResources); 07038 07039 } else { 07040 07041 // 07042 // Partial match. Check for error. 07043 // 07044 07045 ASSERT(IopInitHalResources != newList); 07046 ASSERT(IopInitHalResources != remainingList); 07047 07048 } 07049 07050 DebugMessage(DUMP_INFO, ("IopReserveLegacyBootResources: Allocating HAL BOOT config for interface %08X and bus %08X...\n", InterfaceType, BusNumber)); 07051 if (PnpResDebugLevel & DUMP_INFO) { 07052 07053 IopDumpCmResourceList(newList); 07054 07055 } 07056 if (remainingList) { 07057 ExFreePool(IopInitHalResources); 07058 } 07059 IopInitHalResources = remainingList; 07060 remainingList = IopInitHalDeviceNode->BootResources; 07061 IopInitHalDeviceNode->Flags |= DNF_HAS_BOOT_CONFIG; 07062 status = IopAllocateBootResources( ArbiterRequestHalReported, 07063 IopInitHalDeviceNode->PhysicalDeviceObject, 07064 newList); 07065 ASSERT(NT_SUCCESS(status)); 07066 IopInitHalDeviceNode->BootResources = IopCombineCmResourceList(remainingList, newList); 07067 ASSERT(IopInitHalDeviceNode->BootResources); 07068 07069 // 07070 // Free previous BOOT config if any. 07071 // 07072 07073 if (remainingList) { 07074 07075 ExFreePool(remainingList); 07076 07077 } 07078 } else { 07079 07080 // 07081 // No match. Check that there was no error. 07082 // 07083 07084 ASSERT(remainingList && remainingList == IopInitHalResources); 07085 } 07086 } 07087 07088 for (prevRecord = NULL, resourceRecord = IopInitReservedResourceList; resourceRecord;) { 07089 07090 if ( resourceRecord->ReservedResources && 07091 resourceRecord->ReservedResources->List[0].InterfaceType == InterfaceType && 07092 resourceRecord->ReservedResources->List[0].BusNumber == BusNumber) { 07093 07094 DebugMessage(DUMP_INFO, ("IopReserveLegacyBootResources: Allocating BOOT config...\n")); 07095 if (PnpResDebugLevel & DUMP_INFO) { 07096 07097 IopDumpCmResourceList(resourceRecord->ReservedResources); 07098 07099 } 07100 07101 status = IopAllocateBootResources( ArbiterRequestPnpEnumerated, 07102 resourceRecord->DeviceObject, 07103 resourceRecord->ReservedResources); 07104 if (!NT_SUCCESS(status)) { 07105 07106 DbgPrint("IopReserveLegacyBootResources: IopAllocateBootResources failed with status = %08X\n", status); 07107 ASSERT(NT_SUCCESS(status)); 07108 07109 } 07110 07111 if (resourceRecord->DeviceObject == NULL) { 07112 07113 ExFreePool(resourceRecord->ReservedResources); 07114 07115 } 07116 07117 if (prevRecord) { 07118 07119 prevRecord->Next = resourceRecord->Next; 07120 07121 } else { 07122 07123 IopInitReservedResourceList = resourceRecord->Next; 07124 07125 } 07126 ExFreePool(resourceRecord); 07127 resourceRecord = (prevRecord)? prevRecord->Next : IopInitReservedResourceList; 07128 07129 } else { 07130 07131 prevRecord = resourceRecord; 07132 resourceRecord = resourceRecord->Next; 07133 07134 } 07135 } 07136 07137 return STATUS_SUCCESS; 07138 }

NTSTATUS IopResourceRequirementsListToReqList IN ARBITER_REQUEST_SOURCE  AllocationType,
IN PIO_RESOURCE_REQUIREMENTS_LIST  IoResources,
IN PDEVICE_OBJECT  PhysicalDevice,
OUT PVOID *  ResReqList
 

Definition at line 1267 of file pnpres.c.

References _ARBITER_LIST_ENTRY::AlternativeCount, _ARBITER_LIST_ENTRY::Alternatives, ARBITER_FLAG_BOOT_CONFIG, ArbiterResultUndefined, ASSERT, _ARBITER_LIST_ENTRY::Assignment, _ARBITER_LIST_ENTRY::BusNumber, CmResourceTypeReserved, DbgPrint, DebugMessage, DUMP_ERROR, DUMP_INFO, ExAllocatePoolRD, FALSE, _ARBITER_LIST_ENTRY::Flags, _ARBITER_LIST_ENTRY::InterfaceType, IopAllocPool, IopAllocPoolAligned, IopFreeReqAlternative(), IopFreeReqList(), IopInitPool, IopSetupArbiterAndTranslators(), _ARBITER_LIST_ENTRY::ListEntry, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, _ARBITER_LIST_ENTRY::PhysicalDeviceObject, PnpDefaultInterfaceType, PnpResDebugLevel, PREQ_ALTERNATIVE, PREQ_DESC, PREQ_LIST, _ARBITER_LIST_ENTRY::RequestSource, _ARBITER_LIST_ENTRY::Result, _ARBITER_LIST_ENTRY::SlotNumber, STRUCTURE_ALIGNMENT, TRUE, and _ARBITER_LIST_ENTRY::WorkSpace.

Referenced by IopGetResourceRequirementsForAssignTable(), IopQueryConflictListInternal(), IopReserveBootResourcesInternal(), and IopRestoreResourcesInternal().

01276 : 01277 01278 This routine processes the input Io resource requirements list and 01279 generates an internal REQ_LIST and its related structures. 01280 01281 Parameters: 01282 01283 IoResources - supplies a pointer to the Io resource requirements List. 01284 01285 PhysicalDevice - supplies a pointer to the physical device object requesting 01286 the resources. 01287 01288 ReqList - supplies a pointer to a variable to receive the returned REQ_LIST. 01289 01290 Return Value: 01291 01292 Status code that indicates whether or not the function was successful. 01293 01294 --*/ 01295 01296 { 01297 NTSTATUS status; 01298 PIO_RESOURCE_LIST IoResourceList = IoResources->List; 01299 PIO_RESOURCE_DESCRIPTOR IoResourceDescriptor, BaseDescriptor, firstDescriptor; 01300 PIO_RESOURCE_DESCRIPTOR IoResourceDescriptorEnd; 01301 LONG IoResourceListCount = (LONG) IoResources->AlternativeLists; 01302 PUCHAR CoreEnd = (PUCHAR) IoResources + IoResources->ListSize; 01303 ULONG ReqAlternativeCount = IoResourceListCount; 01304 ULONG ReqDescAlternativeCount = 0; 01305 ULONG AlternativeDescriptorCount = 0; // count of descriptors with IO_RESOURCE_ALTERNATIVE flag set 01306 PREQ_LIST ReqList; 01307 BOOLEAN NoAlternativeDescriptor; 01308 INTERFACE_TYPE interfaceType; 01309 ULONG busNumber; 01310 NTSTATUS failureStatus = STATUS_UNSUCCESSFUL; 01311 NTSTATUS finalStatus = STATUS_SUCCESS; 01312 01313 PAGED_CODE(); 01314 01315 *ResReqList = NULL; 01316 01317 // 01318 // Make sure there is some resource requirements to be fulfilled. 01319 // 01320 01321 if (IoResourceListCount == 0) { 01322 DebugMessage(DUMP_INFO, ("PnpRes: No ResReqList to convert to ReqList\n")); 01323 return STATUS_SUCCESS; 01324 } 01325 01326 // 01327 // ***** Phase 1 ***** 01328 // 01329 // Parse the IO ResReq list to make sure it is valid and to determine the sizes of 01330 // internal structures. 01331 // 01332 01333 while (--IoResourceListCount >= 0) { 01334 01335 IoResourceDescriptor = firstDescriptor = IoResourceList->Descriptors; 01336 IoResourceDescriptorEnd = IoResourceDescriptor + IoResourceList->Count; 01337 01338 if (IoResourceDescriptor == IoResourceDescriptorEnd) { 01339 01340 // 01341 // An alternative list with zero descriptor count 01342 // 01343 01344 return STATUS_SUCCESS; 01345 } 01346 // 01347 // Perform sanity check. We have not allocated any pool space. 01348 // If failed, simply return failure status. 01349 // 01350 01351 if ((PUCHAR) IoResourceDescriptor > CoreEnd) { 01352 01353 // 01354 // The structure header (excluding the variable length Descriptors array) is 01355 // invalid. 01356 // 01357 01358 DebugMessage(DUMP_ERROR, ("PnpRes: Invalid ResReqList\n")); 01359 goto InvalidParameter; 01360 } 01361 01362 if (IoResourceDescriptor > IoResourceDescriptorEnd || 01363 (PUCHAR) IoResourceDescriptorEnd > CoreEnd) { 01364 01365 // 01366 // IoResourceDescriptorEnd is the result of arithmetic overflow; 01367 // or, the descriptor array is outside of the valid memory. 01368 // 01369 01370 DebugMessage(DUMP_ERROR, ("PnpRes: Invalid ResReqList\n")); 01371 goto InvalidParameter; 01372 } 01373 01374 if (IoResourceDescriptor->Type == CmResourceTypeConfigData) { 01375 IoResourceDescriptor++; 01376 firstDescriptor++; 01377 } 01378 NoAlternativeDescriptor = TRUE; 01379 while (IoResourceDescriptor < IoResourceDescriptorEnd) { 01380 switch (IoResourceDescriptor->Type) { 01381 case CmResourceTypeConfigData: 01382 #if DBG_SCOPE 01383 if (PnpResDebugLevel & DUMP_ERROR) { 01384 DbgPrint("PnPRes: Invalid ResReq list !!!\n"); 01385 DbgPrint(" ConfigData descriptors are per-LogConf and\n"); 01386 DbgPrint(" should be at the beginning of an AlternativeList\n"); 01387 ASSERT(0); 01388 } 01389 #endif 01390 goto InvalidParameter; 01391 01392 case CmResourceTypeDevicePrivate: 01393 while (IoResourceDescriptor < IoResourceDescriptorEnd && 01394 IoResourceDescriptor->Type == CmResourceTypeDevicePrivate) { 01395 if (IoResourceDescriptor == firstDescriptor) { 01396 #if DBG_SCOPE 01397 if (PnpResDebugLevel & DUMP_ERROR) { 01398 DbgPrint("PnPRes: Invalid ResReq list !!!\n"); 01399 DbgPrint(" The first descriptor of a LogConf can not be\n"); 01400 DbgPrint(" a DevicePrivate descriptor.\n"); 01401 ASSERT(0); 01402 } 01403 #endif 01404 goto InvalidParameter; 01405 } 01406 ReqDescAlternativeCount++; // Count number of descriptors 01407 IoResourceDescriptor++; 01408 } 01409 NoAlternativeDescriptor = TRUE; 01410 break; 01411 01412 default: 01413 01414 ++ReqDescAlternativeCount; // Count number of descriptors 01415 01416 // 01417 // For non-arbitrated resource type, set its Option to preferred such 01418 // that we won't get confused. 01419 // 01420 01421 if ((IoResourceDescriptor->Type & CmResourceTypeNonArbitrated) || 01422 (IoResourceDescriptor->Type == CmResourceTypeNull)) { 01423 01424 if (IoResourceDescriptor->Type == CmResourceTypeReserved) { 01425 --ReqDescAlternativeCount; 01426 } 01427 IoResourceDescriptor->Option = IO_RESOURCE_PREFERRED; 01428 IoResourceDescriptor++; 01429 NoAlternativeDescriptor = TRUE; 01430 break; 01431 } 01432 if (IoResourceDescriptor->Option & IO_RESOURCE_ALTERNATIVE) { 01433 if (NoAlternativeDescriptor) { 01434 #if DBG_SCOPE 01435 if (PnpResDebugLevel & DUMP_ERROR) { 01436 DbgPrint("PnPRes: Invalid ResReq list !!!\n"); 01437 DbgPrint(" Alternative descriptor without Default or Preferred descriptor.\n"); 01438 ASSERT(0); 01439 } 01440 #endif 01441 goto InvalidParameter; 01442 } 01443 ++AlternativeDescriptorCount; // Count number of Alternative descriptors 01444 } else { 01445 NoAlternativeDescriptor = FALSE; 01446 } 01447 IoResourceDescriptor++; 01448 break; 01449 } 01450 } 01451 ASSERT(IoResourceDescriptor == IoResourceDescriptorEnd); 01452 IoResourceList = (PIO_RESOURCE_LIST) IoResourceDescriptorEnd; 01453 } 01454 01455 // 01456 // ***** Phase 2 ***** 01457 // 01458 // Allocate structures and initialize them according to caller's Io ResReq list. 01459 // 01460 01461 { 01462 ULONG ReqDescCount = ReqDescAlternativeCount - AlternativeDescriptorCount; 01463 PUCHAR PoolStart; 01464 ULONG PoolSize; 01465 IOP_POOL OuterPool; 01466 IOP_POOL ReqAlternativePool; 01467 IOP_POOL ReqDescPool; 01468 01469 PREQ_ALTERNATIVE ReqAlternative; 01470 PREQ_ALTERNATIVE *ReqAlternativePP; 01471 #if DBG 01472 PREQ_ALTERNATIVE *ReqAlternativeEndPP; 01473 #endif 01474 PREQ_DESC ReqDesc; 01475 PREQ_DESC *ReqDescPP; 01476 ULONG ReqAlternativeIndex; 01477 ULONG ReqDescIndex; 01478 01479 // 01480 // Each structure in the list has a variable length array. 01481 // Those arrays are declared in their typedefs as arrays with one element, 01482 // that extra element is not being substracted because it provides an 01483 // extra 4 bytes of memory that is 50% (statistically) wasted and 50% 01484 // (statistically) used to allow for 8 byte alignment of all the structures. 01485 // 01486 // Allocate the pool and fail if the allocation failed. 01487 // 01488 01489 { 01490 ULONG ReqListPoolSize = 01491 (FIELD_OFFSET(REQ_LIST, ReqAlternativeTable) + 01492 sizeof(PVOID) * ReqAlternativeCount + STRUCTURE_ALIGNMENT - 1) & 01493 ~(STRUCTURE_ALIGNMENT - 1); 01494 01495 ULONG ReqAlternativePoolSize = (ReqAlternativeCount * 01496 (FIELD_OFFSET(REQ_ALTERNATIVE, ReqDescTable) + 01497 + sizeof(PVOID) * ReqDescCount + STRUCTURE_ALIGNMENT - 1)) 01498 & ~(STRUCTURE_ALIGNMENT - 1); 01499 01500 ULONG ReqDescPoolSize = (ReqDescCount * (sizeof(REQ_DESC) + STRUCTURE_ALIGNMENT - 1)) 01501 & ~(STRUCTURE_ALIGNMENT - 1); 01502 01503 PoolSize = ReqListPoolSize + ReqAlternativePoolSize + ReqDescPoolSize; 01504 01505 PoolStart = ExAllocatePoolRD(PagedPool, PoolSize); 01506 if (!PoolStart) { 01507 return STATUS_INSUFFICIENT_RESOURCES; 01508 } 01509 IopInitPool(&OuterPool, PoolStart, PoolSize); 01510 01511 // 01512 // Partition the OuterPool into inner pools. 01513 // 01514 01515 IopAllocPoolAligned(&ReqList, &OuterPool, ReqListPoolSize); 01516 01517 IopAllocPoolAligned(&PoolStart, &OuterPool, ReqAlternativePoolSize); 01518 IopInitPool(&ReqAlternativePool, PoolStart, ReqAlternativePoolSize); 01519 01520 IopAllocPoolAligned(&PoolStart, &OuterPool, ReqDescPoolSize); 01521 IopInitPool(&ReqDescPool, PoolStart, ReqDescPoolSize); 01522 } 01523 01524 // 01525 // Convert the IO_RESOURCE_REQUIREMENTS_LIST into the REQ_LIST. 01526 // 01527 01528 ReqAlternativePP = ReqList->ReqAlternativeTable; 01529 RtlZeroMemory(ReqAlternativePP, ReqAlternativeCount * sizeof(PREQ_ALTERNATIVE)); 01530 #if DBG 01531 ReqAlternativeEndPP = ReqAlternativePP + ReqAlternativeCount; 01532 #endif 01533 ReqList->ReqAlternativeCount = ReqAlternativeCount; 01534 ReqList->PhysicalDevice = PhysicalDevice; 01535 ReqList->InterfaceType = IoResources->InterfaceType; 01536 if (ReqList->InterfaceType == InterfaceTypeUndefined) { 01537 ReqList->InterfaceType = PnpDefaultInterfaceType; 01538 } 01539 01540 ReqList->BusNumber = IoResources->BusNumber; 01541 ReqList->SelectedAlternative = NULL; 01542 ReqAlternativeIndex = 0; 01543 01544 interfaceType = IoResources->InterfaceType; 01545 if (interfaceType == InterfaceTypeUndefined) { 01546 interfaceType = PnpDefaultInterfaceType; 01547 } 01548 busNumber = IoResources->BusNumber; 01549 IoResourceList = IoResources->List; 01550 IoResourceListCount = IoResources->AlternativeLists; 01551 01552 while (--IoResourceListCount >= 0) { 01553 ULONG arbiterFlag; 01554 01555 IoResourceDescriptor = IoResourceList->Descriptors; 01556 IoResourceDescriptorEnd = IoResourceDescriptor + IoResourceList->Count; 01557 01558 // 01559 // For each Io alternate list, we create a REQ_ALTERNATE table 01560 // 01561 01562 IopAllocPoolAligned(&ReqAlternative, &ReqAlternativePool, FIELD_OFFSET(REQ_ALTERNATIVE, ReqDescTable)); 01563 ReqAlternative->ReqList = ReqList; 01564 ReqAlternative->ReqAlternativeIndex = ReqAlternativeIndex++; 01565 ASSERT(ReqAlternativePP < ReqAlternativeEndPP); 01566 *ReqAlternativePP++ = ReqAlternative; 01567 ReqAlternative->ReqDescCount = 0; 01568 ReqAlternative->ReqDescTableEnd = ReqAlternative->ReqDescTable; 01569 01570 // 01571 // If the first descriptor of the alternative is a CmResourceTypeConfigData 01572 // it contains priority information. 01573 // 01574 01575 if (IoResourceDescriptor->Type == CmResourceTypeConfigData) { 01576 ReqAlternative->Priority = IoResourceDescriptor->u.ConfigData.Priority; 01577 IoResourceDescriptor++; 01578 } else { 01579 ReqAlternative->Priority = LCPRI_NORMAL; 01580 } 01581 01582 if (ReqAlternative->Priority == LCPRI_BOOTCONFIG) { 01583 arbiterFlag = ARBITER_FLAG_BOOT_CONFIG; 01584 } else { 01585 arbiterFlag = 0; 01586 } 01587 01588 ReqDescPP = ReqAlternative->ReqDescTable; 01589 ReqDescIndex = 0; 01590 01591 while (IoResourceDescriptor < IoResourceDescriptorEnd) { 01592 01593 PARBITER_LIST_ENTRY ArbiterListEntry; 01594 01595 if (IoResourceDescriptor->Type == CmResourceTypeReserved) { 01596 interfaceType = IoResourceDescriptor->u.DevicePrivate.Data[0]; 01597 if (interfaceType == InterfaceTypeUndefined) { 01598 interfaceType = PnpDefaultInterfaceType; 01599 } 01600 busNumber = IoResourceDescriptor->u.DevicePrivate.Data[1]; 01601 IoResourceDescriptor++; 01602 } else { 01603 IopAllocPoolAligned(&ReqDesc, &ReqDescPool, sizeof(REQ_DESC)); 01604 ReqDesc->ArbitrationRequired = 01605 (IoResourceDescriptor->Type & CmResourceTypeNonArbitrated || 01606 IoResourceDescriptor->Type == CmResourceTypeNull) ? FALSE : TRUE; 01607 ReqDesc->ReqAlternative = ReqAlternative; 01608 ReqDesc->ReqDescIndex = ReqDescIndex++; 01609 ReqDesc->DevicePrivateCount = 0; 01610 ReqDesc->DevicePrivate = NULL; 01611 ReqDesc->InterfaceType = interfaceType; 01612 ReqDesc->BusNumber = busNumber; 01613 01614 IopAllocPool(&PoolStart, &ReqAlternativePool, sizeof(PVOID)); 01615 01616 ASSERT(PoolStart == (PUCHAR) ReqDescPP); 01617 01618 *ReqDescPP++ = ReqDesc; 01619 ++ReqAlternative->ReqDescCount; 01620 ++ReqAlternative->ReqDescTableEnd; 01621 01622 ReqDesc->TranslatedReqDesc = ReqDesc; // TranslatedReqDesc points to itself. 01623 01624 ArbiterListEntry = &ReqDesc->AlternativeTable; 01625 InitializeListHead(&ArbiterListEntry->ListEntry); 01626 ArbiterListEntry->AlternativeCount = 0; 01627 ArbiterListEntry->Alternatives = IoResourceDescriptor; 01628 ArbiterListEntry->PhysicalDeviceObject = PhysicalDevice; 01629 ArbiterListEntry->RequestSource = AllocationType; 01630 ArbiterListEntry->Flags = arbiterFlag; 01631 ArbiterListEntry->WorkSpace = 0; 01632 ArbiterListEntry->InterfaceType = interfaceType; 01633 ArbiterListEntry->SlotNumber = IoResources->SlotNumber; 01634 ArbiterListEntry->BusNumber = IoResources->BusNumber; 01635 ArbiterListEntry->Assignment = &ReqDesc->Allocation; 01636 ArbiterListEntry->Result = ArbiterResultUndefined; 01637 01638 if (ReqDesc->ArbitrationRequired) { 01639 01640 // 01641 // The BestAlternativeTable and BestAllocation are not initialized. 01642 // They will be initialized when needed. 01643 01644 // 01645 // Initialize the Cm partial resource descriptor to NOT_ALLOCATED. 01646 // 01647 01648 ReqDesc->Allocation.Type = CmResourceTypeMaximum; 01649 01650 ASSERT((IoResourceDescriptor->Option & IO_RESOURCE_ALTERNATIVE) == 0); 01651 01652 ArbiterListEntry->AlternativeCount++; 01653 IoResourceDescriptor++; 01654 while (IoResourceDescriptor < IoResourceDescriptorEnd) { 01655 if (IoResourceDescriptor->Type == CmResourceTypeDevicePrivate) { 01656 ReqDesc->DevicePrivate = IoResourceDescriptor; 01657 while (IoResourceDescriptor < IoResourceDescriptorEnd && 01658 IoResourceDescriptor->Type == CmResourceTypeDevicePrivate) { 01659 ReqDesc->DevicePrivateCount++; 01660 ++IoResourceDescriptor; 01661 } 01662 break; 01663 } 01664 if (IoResourceDescriptor->Option & IO_RESOURCE_ALTERNATIVE) { 01665 ArbiterListEntry->AlternativeCount++; 01666 IoResourceDescriptor++; 01667 } else { 01668 break; 01669 } 01670 } 01671 01672 // 01673 // Next query Arbiter and Translator interfaces for the resource desc. 01674 // 01675 01676 status = IopSetupArbiterAndTranslators(ReqDesc); 01677 if (!NT_SUCCESS(status)) { 01678 DebugMessage(DUMP_ERROR, ("PnpRes: Unable to setup Arbiter and Translators\n")); 01679 ReqAlternativeIndex--; 01680 ReqAlternativePP--; 01681 ReqList->ReqAlternativeCount--; 01682 IopFreeReqAlternative(ReqAlternative); 01683 failureStatus = status; 01684 break; 01685 } 01686 } else { 01687 ReqDesc->Allocation.Type = IoResourceDescriptor->Type; 01688 ReqDesc->Allocation.ShareDisposition = IoResourceDescriptor->ShareDisposition; 01689 ReqDesc->Allocation.Flags = IoResourceDescriptor->Flags; 01690 ReqDesc->Allocation.u.DevicePrivate.Data[0] = 01691 IoResourceDescriptor->u.DevicePrivate.Data[0]; 01692 ReqDesc->Allocation.u.DevicePrivate.Data[1] = 01693 IoResourceDescriptor->u.DevicePrivate.Data[1]; 01694 ReqDesc->Allocation.u.DevicePrivate.Data[2] = 01695 IoResourceDescriptor->u.DevicePrivate.Data[2]; 01696 01697 IoResourceDescriptor++; 01698 } 01699 } 01700 01701 if (IoResourceDescriptor >= IoResourceDescriptorEnd) break; 01702 } 01703 IoResourceList = (PIO_RESOURCE_LIST) IoResourceDescriptorEnd; 01704 } 01705 if (ReqAlternativeIndex == 0) { 01706 finalStatus = failureStatus; 01707 IopFreeReqList(ReqList); 01708 } 01709 } 01710 01711 if (finalStatus == STATUS_SUCCESS) { 01712 *ResReqList = ReqList; 01713 } 01714 01715 return finalStatus; 01716 01717 InvalidParameter: 01718 return STATUS_INVALID_PARAMETER; 01719 }

VOID IopRestoreBestConfiguration IN  VOID  ) 
 

Definition at line 2997 of file pnpres.c.

References _PI_RESOURCE_ARBITER_ENTRY::ActiveArbiterList, _PI_RESOURCE_ARBITER_ENTRY::BestConfig, _PI_RESOURCE_ARBITER_ENTRY::BestResourceList, FALSE, _IOP_RESOURCE_REQUEST::Flags, IOP_ASSIGN_EXCLUDE, PiActiveArbiterList, PiAssignTable, PiAssignTableCount, PiBestArbiterList, PiNoRetest, PREQ_ALTERNATIVE, PREQ_DESC, PREQ_LIST, _IOP_RESOURCE_REQUEST::ReqList, _PI_RESOURCE_ARBITER_ENTRY::ResourceList, _PI_RESOURCE_ARBITER_ENTRY::ResourcesChanged, and TRUE.

Referenced by IopAssignInner().

03003 : 03004 03005 This routine restores the arbiters info and all the resources requirements 03006 info to prepare arbiter restest. 03007 03008 Parameters: 03009 03010 None. 03011 03012 Return Value: 03013 03014 None. 03015 03016 --*/ 03017 03018 { 03019 PREQ_ALTERNATIVE reqAlternative; 03020 PIOP_RESOURCE_REQUEST assignEntry; 03021 PREQ_DESC reqDesc, *reqDescpp; 03022 PREQ_LIST reqList; 03023 PLIST_ENTRY listEntry; 03024 PPI_RESOURCE_ARBITER_ENTRY arbiterEntry; 03025 ULONG i; 03026 03027 if (PiNoRetest == FALSE) { 03028 03029 // 03030 // Go thru all the assign tables to save the current configuration. 03031 // 03032 03033 for (i = 0; i < PiAssignTableCount; i++) { 03034 assignEntry = PiAssignTable + i; 03035 03036 if (!(assignEntry->Flags & IOP_ASSIGN_EXCLUDE)) { 03037 reqList = assignEntry->ReqList; 03038 03039 // 03040 // Set the BestAlternative as the current selection. 03041 // 03042 03043 reqAlternative = *reqList->ReqBestAlternative; 03044 reqList->SelectedAlternative = reqList->ReqBestAlternative; 03045 03046 // 03047 // For each REQ_DESC in the best alternative list, restore its arbiter list entry 03048 // and its assignments from saved area. 03049 // 03050 03051 for (reqDescpp = reqAlternative->ReqDescTable; 03052 reqDescpp < reqAlternative->ReqDescTableEnd; 03053 reqDescpp++) { 03054 03055 if ((*reqDescpp)->ArbitrationRequired) { 03056 reqDesc = (*reqDescpp)->TranslatedReqDesc; 03057 reqDesc->AlternativeTable = reqDesc->BestAlternativeTable; 03058 reqDesc->Allocation = reqDesc->BestAllocation; 03059 } 03060 } 03061 } 03062 } 03063 PiActiveArbiterList = PiBestArbiterList; 03064 } 03065 03066 // 03067 // Go throught the active arbiter list to restore the current configuration 03068 // for retest. 03069 // 03070 03071 listEntry = PiActiveArbiterList.Flink; 03072 while (listEntry != &PiActiveArbiterList) { 03073 arbiterEntry = CONTAINING_RECORD(listEntry, PI_RESOURCE_ARBITER_ENTRY, ActiveArbiterList); 03074 if (PiNoRetest == FALSE) { 03075 arbiterEntry->ResourceList = arbiterEntry->BestResourceList; 03076 arbiterEntry->ActiveArbiterList = arbiterEntry->BestConfig; 03077 } 03078 arbiterEntry->ResourcesChanged = TRUE; 03079 listEntry = listEntry->Flink; 03080 } 03081 }

NTSTATUS IopRestoreResourcesInternal IN PDEVICE_NODE  DeviceNode  ) 
 

Definition at line 5660 of file pnpres.c.

References _IOP_RESOURCE_REQUEST::AllocationType, ArbiterRequestPnpEnumerated, ASSERT, DbgPrint, DebugMessage, DUMP_ERROR, ExFreePool(), FALSE, _IOP_RESOURCE_REQUEST::Flags, IopAssignInner(), IopCmResourcesToIoResources(), IopDetermineResourceListSize(), IopFreeResourceRequirementsForAssignTable(), IopRearrangeReqList(), IopResourceRequirementsListToReqList(), IopWriteAllocatedResourcesToRegistry(), NT_SUCCESS, NTSTATUS(), NULL, _IOP_RESOURCE_REQUEST::PhysicalDevice, PREQ_LIST, _IOP_RESOURCE_REQUEST::Priority, _IOP_RESOURCE_REQUEST::ReqList, _IOP_RESOURCE_REQUEST::ResourceAssignment, _IOP_RESOURCE_REQUEST::ResourceRequirements, _IOP_RESOURCE_REQUEST::Status, and _IOP_RESOURCE_REQUEST::TranslatedResourceAssignment.

Referenced by IopReallocateResources(), IopRebalance(), and IopReleaseFilteredBootResources().

05666 : 05667 05668 This routine reassigns the released resources for device specified by DeviceNode. 05669 05670 Parameters: 05671 05672 DeviceNode - specifies the device node whose resources are goint to be released. 05673 05674 Return Value: 05675 05676 Status code that indicates whether or not the function was successful. 05677 05678 --*/ 05679 05680 { 05681 IOP_RESOURCE_REQUEST requestTable; 05682 NTSTATUS status; 05683 05684 if (DeviceNode->ResourceList == NULL) { 05685 return STATUS_SUCCESS; 05686 } 05687 requestTable.ResourceRequirements = 05688 IopCmResourcesToIoResources (0, DeviceNode->ResourceList, LCPRI_FORCECONFIG); 05689 if (requestTable.ResourceRequirements == NULL) { 05690 DebugMessage(DUMP_ERROR, ("PnpRes: Not enough memory to clean up rebalance failure\n")); 05691 return STATUS_INSUFFICIENT_RESOURCES; 05692 } 05693 requestTable.Priority = 0; 05694 requestTable.Flags = 0; 05695 requestTable.AllocationType = ArbiterRequestPnpEnumerated; 05696 requestTable.PhysicalDevice = DeviceNode->PhysicalDeviceObject; 05697 requestTable.ReqList = NULL; 05698 requestTable.ResourceAssignment = NULL; 05699 requestTable.TranslatedResourceAssignment = NULL; 05700 requestTable.Status = 0; 05701 05702 // 05703 // rebuild internal representation of the resource requirements list 05704 // 05705 05706 status = IopResourceRequirementsListToReqList( 05707 requestTable.AllocationType, 05708 requestTable.ResourceRequirements, 05709 requestTable.PhysicalDevice, 05710 &requestTable.ReqList); 05711 05712 if (!NT_SUCCESS(status) || requestTable.ReqList == NULL) { 05713 DebugMessage(DUMP_ERROR, ("PnpRes: Not enough memory to restore previous resources\n")); 05714 ExFreePool (requestTable.ResourceRequirements); 05715 return status; 05716 } else { 05717 PREQ_LIST reqList; 05718 05719 reqList = (PREQ_LIST)requestTable.ReqList; 05720 reqList->AssignEntry = &requestTable; 05721 05722 // 05723 // Sort the ReqList such that the higher priority Alternative list are 05724 // placed in the front of the list. 05725 // 05726 05727 IopRearrangeReqList(reqList); 05728 if (reqList->ReqBestAlternative == NULL) { 05729 05730 IopFreeResourceRequirementsForAssignTable(&requestTable, (&requestTable) + 1); 05731 return STATUS_DEVICE_CONFIGURATION_ERROR; 05732 05733 } 05734 } 05735 05736 status = IopAssignInner(1, &requestTable, FALSE); 05737 IopFreeResourceRequirementsForAssignTable(&requestTable, (&requestTable) + 1); 05738 if (!NT_SUCCESS(status)) { 05739 DbgPrint("IopRestoreResourcesInternal: BOOT conflict for %ws\n", DeviceNode->InstancePath.Buffer); 05740 ASSERT(NT_SUCCESS(status)); 05741 } 05742 if (requestTable.ResourceAssignment) { 05743 ExFreePool(requestTable.ResourceAssignment); 05744 } 05745 if (requestTable.TranslatedResourceAssignment) { 05746 ExFreePool(requestTable.TranslatedResourceAssignment); 05747 } 05748 IopWriteAllocatedResourcesToRegistry ( 05749 DeviceNode, 05750 DeviceNode->ResourceList, 05751 IopDetermineResourceListSize(DeviceNode->ResourceList) 05752 ); 05753 return status; 05754 }

VOID IopSaveCurrentConfiguration IN  VOID  ) 
 

Definition at line 2906 of file pnpres.c.

References _PI_RESOURCE_ARBITER_ENTRY::ActiveArbiterList, _PI_RESOURCE_ARBITER_ENTRY::BestConfig, _PI_RESOURCE_ARBITER_ENTRY::BestResourceList, _IOP_RESOURCE_REQUEST::Flags, IOP_ASSIGN_EXCLUDE, PiActiveArbiterList, PiAssignTable, PiAssignTableCount, PiBestArbiterList, PiNoRetest, PREQ_ALTERNATIVE, PREQ_DESC, PREQ_LIST, _IOP_RESOURCE_REQUEST::ReqList, and _PI_RESOURCE_ARBITER_ENTRY::ResourceList.

Referenced by IopAssign().

02912 : 02913 02914 This routine goes thru every resource requirememts list to save the current 02915 best resource assignments. 02916 02917 Parameters: 02918 02919 None. 02920 02921 Return Value: 02922 02923 None. 02924 02925 --*/ 02926 02927 { 02928 PREQ_ALTERNATIVE reqAlternative; 02929 PIOP_RESOURCE_REQUEST assignEntry; 02930 PREQ_DESC reqDesc, *reqDescpp; 02931 PREQ_LIST reqList; 02932 PLIST_ENTRY listEntry; 02933 PPI_RESOURCE_ARBITER_ENTRY arbiterEntry; 02934 ULONG i; 02935 02936 // 02937 // If PiNoRetest is set, do nothing. We don't need to save/restore 02938 // 02939 02940 if (PiNoRetest) { 02941 PiBestArbiterList = PiActiveArbiterList; 02942 return; 02943 } 02944 02945 // 02946 // Go thru all the assign tables to save the current assignment and mark 02947 // it as the current best selection. 02948 // 02949 02950 for (i = 0; i < PiAssignTableCount; i++) { 02951 assignEntry = PiAssignTable + i; 02952 02953 if (!(assignEntry->Flags & IOP_ASSIGN_EXCLUDE)) { 02954 reqList = assignEntry->ReqList; 02955 02956 // 02957 // Save the current selected Alternative as the BestAlternative. 02958 // 02959 02960 reqAlternative = *reqList->SelectedAlternative; 02961 reqList->ReqBestAlternative = reqList->SelectedAlternative; 02962 02963 // 02964 // For each REQ_DESC in the best alternative list, save its arbiter list entry 02965 // and its assignments. 02966 // 02967 02968 for (reqDescpp = reqAlternative->ReqDescTable; 02969 reqDescpp < reqAlternative->ReqDescTableEnd; 02970 reqDescpp++) { 02971 02972 if ((*reqDescpp)->ArbitrationRequired) { 02973 reqDesc = (*reqDescpp)->TranslatedReqDesc; 02974 reqDesc->BestAlternativeTable = reqDesc->AlternativeTable; 02975 reqDesc->BestAllocation = reqDesc->Allocation; 02976 } 02977 } 02978 } 02979 } 02980 02981 // 02982 // Go throught the active arbiter list to save the current assignment 02983 // for retest. 02984 // 02985 02986 listEntry = PiActiveArbiterList.Flink; 02987 while (listEntry != &PiActiveArbiterList) { 02988 arbiterEntry = CONTAINING_RECORD(listEntry, PI_RESOURCE_ARBITER_ENTRY, ActiveArbiterList); 02989 arbiterEntry->BestResourceList = arbiterEntry->ResourceList; 02990 arbiterEntry->BestConfig = arbiterEntry->ActiveArbiterList; 02991 listEntry = listEntry->Flink; 02992 } 02993 PiBestArbiterList = PiActiveArbiterList; 02994 }

VOID IopSetLegacyDeviceInstance IN PDRIVER_OBJECT  DriverObject,
IN PDEVICE_NODE  DeviceNode
 

Definition at line 6660 of file pnpres.c.

References _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, FALSE, IopDeviceObjectFromDeviceInstance(), IopServiceInstanceToDeviceInstance(), L, NT_SUCCESS, NTSTATUS(), NULL, _DEVICE_NODE::OverUsed2, PAGED_CODE, RtlFreeUnicodeString(), RtlInitUnicodeString(), RtlPrefixUnicodeString(), and TRUE.

Referenced by IopFindLegacyDeviceNode().

06667 : 06668 06669 This routine sets the Root\Legacy_xxxx\0000 device instance path to the 06670 madeup PDO (i.e. DeviceNode) which is created only for legacy resource allocation. 06671 This routine also links the madeup PDO to the Root\Legacy_xxxx\0000 device node 06672 to keep track what resources are assigned to the driver which services the 06673 root\legacy_xxxx\0000 device. 06674 06675 Parameters: 06676 06677 P1 - 06678 06679 Return Value: 06680 06681 Status code that indicates whether or not the function was successful. 06682 06683 --*/ 06684 06685 { 06686 NTSTATUS status; 06687 UNICODE_STRING instancePath, rootString; 06688 HANDLE handle; 06689 PDEVICE_NODE legacyDeviceNode; 06690 PDEVICE_OBJECT legacyPdo; 06691 06692 PAGED_CODE(); 06693 06694 DeviceNode->OverUsed1.LegacyDeviceNode = 0; 06695 instancePath.Length = 0; 06696 instancePath.Buffer = NULL; 06697 06698 status = IopServiceInstanceToDeviceInstance ( 06699 NULL, 06700 &DriverObject->DriverExtension->ServiceKeyName, 06701 0, 06702 &instancePath, 06703 &handle, 06704 KEY_READ 06705 ); 06706 if (NT_SUCCESS(status) && (instancePath.Length != 0)) { 06707 RtlInitUnicodeString(&rootString, L"ROOT\\LEGACY"); 06708 if (RtlPrefixUnicodeString(&rootString, &instancePath, TRUE) == FALSE) { 06709 RtlFreeUnicodeString(&instancePath); 06710 } else { 06711 DeviceNode->InstancePath = instancePath; 06712 legacyPdo = IopDeviceObjectFromDeviceInstance (handle, NULL); 06713 if (legacyPdo) { 06714 legacyDeviceNode = (PDEVICE_NODE)legacyPdo->DeviceObjectExtension->DeviceNode; 06715 DeviceNode->OverUsed2.NextResourceDeviceNode = 06716 legacyDeviceNode->OverUsed2.NextResourceDeviceNode; 06717 legacyDeviceNode->OverUsed2.NextResourceDeviceNode = DeviceNode; 06718 DeviceNode->OverUsed1.LegacyDeviceNode = legacyDeviceNode; 06719 } 06720 } 06721 ZwClose(handle); 06722 } 06723 }

NTSTATUS IopSetupArbiterAndTranslators IN PREQ_DESC  ReqDesc  ) 
 

Definition at line 3534 of file pnpres.c.

References _PI_RESOURCE_ARBITER_ENTRY::ActiveArbiterList, ARBITER_PARTIAL, ArbiterActionQueryArbitrate, _PI_RESOURCE_ARBITER_ENTRY::ArbiterInterface, ArbiterRequestHalReported, ASSERT, _PI_RESOURCE_ARBITER_ENTRY::BestConfig, _PI_RESOURCE_ARBITER_ENTRY::BestResourceList, DebugMessage, _DEVICE_NODE::DeviceArbiterList, _PI_RESOURCE_ARBITER_ENTRY::DeviceArbiterList, _PI_RESOURCE_TRANSLATOR_ENTRY::DeviceNode, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, _DEVICE_NODE::DeviceTranslatorList, _PI_RESOURCE_TRANSLATOR_ENTRY::DeviceTranslatorList, DUMP_ERROR, DUMP_INFO, ExAllocatePoolAE, ExAllocatePoolTE, FALSE, _ARBITER_INTERFACE::Flags, _DEVICE_NODE::InterfaceType, IopCallArbiter(), IopFindBusDeviceNode(), IopFindResourceHandlerInfo(), IopQueryResourceHandlerInterface(), IopRootDeviceNode, IopTranslateAndAdjustReqDesc(), _DEVICE_NODE::NoArbiterMask, _DEVICE_NODE::NoTranslatorMask, NT_SUCCESS, NTSTATUS(), NULL, PagedPool, _DEVICE_NODE::Parent, _DEVICE_NODE::PhysicalDeviceObject, PI_MAXIMUM_RESOURCE_TYPE_TRACKED, PREQ_DESC, _DEVICE_NODE::QueryArbiterMask, _DEVICE_NODE::QueryTranslatorMask, ResourceArbiter, _PI_RESOURCE_ARBITER_ENTRY::ResourceList, _PI_RESOURCE_ARBITER_ENTRY::ResourcesChanged, ResourceTranslator, _PI_RESOURCE_TRANSLATOR_ENTRY::ResourceType, _PI_RESOURCE_ARBITER_ENTRY::ResourceType, _PI_RESOURCE_ARBITER_ENTRY::State, _PI_RESOURCE_TRANSLATOR_ENTRY::TranslatorInterface, TRUE, and USHORT.

Referenced by IopResourceRequirementsListToReqList().

03540 : 03541 03542 This routine searches the arbiter and translators which arbitrates and translate 03543 the resources for the specified device. This routine tries to find all the 03544 translator on the path of current device node to root device node 03545 03546 Parameters: 03547 03548 ReqDesc - supplies a pointer to REQ_DESC which contains all the required information 03549 03550 Return Value: 03551 03552 NTSTATUS value to indicate success or failure. 03553 03554 --*/ 03555 03556 { 03557 PLIST_ENTRY listHead, nextEntry; 03558 PPI_RESOURCE_ARBITER_ENTRY arbiterEntry; 03559 PDEVICE_OBJECT deviceObject = ReqDesc->AlternativeTable.PhysicalDeviceObject; 03560 PDEVICE_NODE deviceNode; 03561 PREQ_DESC reqDesc = ReqDesc, translatedReqDesc; 03562 BOOLEAN found, arbiterFound = FALSE, restartedAlready; 03563 BOOLEAN searchTranslator = TRUE, translatorFound = FALSE; 03564 NTSTATUS status; 03565 PPI_RESOURCE_TRANSLATOR_ENTRY translatorEntry; 03566 UCHAR resourceType = ReqDesc->TranslatedReqDesc->AlternativeTable.Alternatives->Type; 03567 PINTERFACE interface; 03568 USHORT resourceMask; 03569 03570 if ((ReqDesc->AlternativeTable.RequestSource == ArbiterRequestHalReported) && 03571 (ReqDesc->InterfaceType == Internal)) { 03572 03573 // Trust hal if it says internal bus. 03574 03575 restartedAlready = TRUE; 03576 } else { 03577 restartedAlready = FALSE; 03578 } 03579 03580 // 03581 // If ReqDesc contains DeviceObject, this is for regular resources allocation 03582 // or boot resources preallocation. Otherwise, it is for resources reservation. 03583 // 03584 03585 if (deviceObject && ReqDesc->AlternativeTable.RequestSource != ArbiterRequestHalReported) { 03586 deviceNode = (PDEVICE_NODE)deviceObject->DeviceObjectExtension->DeviceNode; 03587 // We want to start with the deviceNode instead of its parent. Because the 03588 // deviceNode may provide a translator interface. 03589 // deviceNode = deviceNode->Parent; 03590 } else { 03591 03592 // 03593 // For resource reservation, we always need to find the arbiter and translators 03594 // so set the device node to Root. 03595 // 03596 03597 deviceNode = IopRootDeviceNode; 03598 } 03599 while (deviceNode) { 03600 if ((deviceNode == IopRootDeviceNode) && (translatorFound == FALSE)) { 03601 03602 // 03603 // If we reach the root and have not find any translator, the device is on the 03604 // wrong way. 03605 // 03606 03607 if (restartedAlready == FALSE) { 03608 restartedAlready = TRUE; 03609 03610 deviceNode = IopFindBusDeviceNode ( 03611 IopRootDeviceNode, 03612 ReqDesc->InterfaceType, 03613 ReqDesc->BusNumber, 03614 0 03615 ); 03616 03617 // 03618 // If we did not find a PDO, try again with InterfaceType == Isa. This allows 03619 // drivers that request Internal to get resources even if there is no PDO 03620 // that is Internal. (but if there is an Internal PDO, they get that one) 03621 // 03622 03623 if ((deviceNode == IopRootDeviceNode) && 03624 (ReqDesc->ReqAlternative->ReqList->InterfaceType == Internal)) { 03625 deviceNode = IopFindBusDeviceNode( 03626 IopRootDeviceNode, 03627 Isa, 03628 0, 03629 0 03630 ); 03631 } 03632 03633 //if ((PVOID)deviceNode == deviceObject->DeviceObjectExtension->DeviceNode) { 03634 // deviceNode = IopRootDeviceNode; 03635 //} else { 03636 continue; 03637 //} 03638 } 03639 } 03640 03641 // 03642 // Check is there an arbiter for the device node? 03643 // if yes, set up ReqDesc->u.Arbiter and set ArbiterFound to true. 03644 // else move up to the parent of current device node. 03645 // 03646 03647 if ((arbiterFound == FALSE) && (deviceNode->PhysicalDeviceObject != deviceObject)) { 03648 found = IopFindResourceHandlerInfo( 03649 ResourceArbiter, 03650 deviceNode, 03651 resourceType, 03652 &arbiterEntry); 03653 if (found == FALSE) { 03654 03655 // 03656 // no information found on arbiter. Try to query translator interface ... 03657 // 03658 03659 if (resourceType <= PI_MAXIMUM_RESOURCE_TYPE_TRACKED) { 03660 resourceMask = 1 << resourceType; 03661 } else { 03662 resourceMask = 0; 03663 } 03664 status = IopQueryResourceHandlerInterface(ResourceArbiter, 03665 deviceNode->PhysicalDeviceObject, 03666 resourceType, 03667 &interface); 03668 deviceNode->QueryArbiterMask |= resourceMask; 03669 if (!NT_SUCCESS(status)) { 03670 deviceNode->NoArbiterMask |= resourceMask; 03671 if (resourceType <= PI_MAXIMUM_RESOURCE_TYPE_TRACKED) { 03672 found = TRUE; 03673 } else { 03674 interface = NULL; 03675 } 03676 } 03677 if (found == FALSE) { 03678 arbiterEntry = (PPI_RESOURCE_ARBITER_ENTRY)ExAllocatePoolAE( 03679 PagedPool, 03680 sizeof(PI_RESOURCE_ARBITER_ENTRY)); 03681 if (!arbiterEntry) { 03682 status = STATUS_INSUFFICIENT_RESOURCES; 03683 return status; 03684 } 03685 InitializeListHead(&arbiterEntry->ActiveArbiterList); 03686 InitializeListHead(&arbiterEntry->DeviceArbiterList); 03687 InitializeListHead(&arbiterEntry->BestConfig); 03688 InitializeListHead(&arbiterEntry->ResourceList); 03689 InitializeListHead(&arbiterEntry->BestResourceList); 03690 arbiterEntry->ResourceType =resourceType; 03691 arbiterEntry->State = 0; 03692 arbiterEntry->ResourcesChanged = FALSE; 03693 listHead = &deviceNode->DeviceArbiterList; 03694 InsertTailList(listHead, &arbiterEntry->DeviceArbiterList); 03695 arbiterEntry->ArbiterInterface = (PARBITER_INTERFACE)interface; 03696 if (!interface) { 03697 03698 // 03699 // if interface is NULL we really don't have translator. 03700 // 03701 03702 arbiterEntry = NULL; 03703 } 03704 } 03705 } 03706 03707 // 03708 // If there is an desired resourcetype arbiter in the device node, make sure 03709 // it handle this resource requriements. 03710 // 03711 03712 if (arbiterEntry) { 03713 arbiterFound = TRUE; 03714 if (arbiterEntry->ArbiterInterface->Flags & ARBITER_PARTIAL) { 03715 03716 // 03717 // If the arbiter is partial, ask if it handles the resources 03718 // if not, goto its parent. 03719 // 03720 03721 status = IopCallArbiter( 03722 arbiterEntry, 03723 ArbiterActionQueryArbitrate, 03724 ReqDesc->TranslatedReqDesc, 03725 NULL, 03726 NULL 03727 ); 03728 if (!NT_SUCCESS(status)) { 03729 arbiterFound = FALSE; 03730 } 03731 } 03732 } 03733 if (arbiterFound) { 03734 ReqDesc->u.Arbiter = arbiterEntry; 03735 03736 // 03737 // Initialize the arbiter entry 03738 // 03739 03740 arbiterEntry->State = 0; 03741 arbiterEntry->ResourcesChanged = FALSE; 03742 } 03743 03744 } 03745 03746 if (searchTranslator) { 03747 // 03748 // First, check if there is a translator for the device node? 03749 // If yes, translate the req desc and link it to the front of ReqDesc->TranslatedReqDesc 03750 // else do nothing. 03751 // 03752 03753 found = IopFindResourceHandlerInfo( 03754 ResourceTranslator, 03755 deviceNode, 03756 resourceType, 03757 &translatorEntry); 03758 03759 if (found == FALSE) { 03760 03761 // 03762 // no information found on translator. Try to query translator interface ... 03763 // 03764 03765 if (resourceType <= PI_MAXIMUM_RESOURCE_TYPE_TRACKED) { 03766 resourceMask = 1 << resourceType; 03767 } else { 03768 resourceMask = 0; 03769 } 03770 status = IopQueryResourceHandlerInterface(ResourceTranslator, 03771 deviceNode->PhysicalDeviceObject, 03772 resourceType, 03773 &interface); 03774 deviceNode->QueryTranslatorMask |= resourceMask; 03775 if (!NT_SUCCESS(status)) { 03776 deviceNode->NoTranslatorMask |= resourceMask; 03777 if (resourceType <= PI_MAXIMUM_RESOURCE_TYPE_TRACKED) { 03778 found = TRUE; 03779 } else { 03780 interface = NULL; 03781 } 03782 } 03783 if (found == FALSE) { 03784 translatorEntry = (PPI_RESOURCE_TRANSLATOR_ENTRY)ExAllocatePoolTE( 03785 PagedPool, 03786 sizeof(PI_RESOURCE_TRANSLATOR_ENTRY)); 03787 if (!translatorEntry) { 03788 status = STATUS_INSUFFICIENT_RESOURCES; 03789 return status; 03790 } 03791 translatorEntry->ResourceType = resourceType; 03792 InitializeListHead(&translatorEntry->DeviceTranslatorList); 03793 translatorEntry->TranslatorInterface = (PTRANSLATOR_INTERFACE)interface; 03794 translatorEntry->DeviceNode = deviceNode; 03795 listHead = &deviceNode->DeviceTranslatorList; 03796 InsertTailList(listHead, &translatorEntry->DeviceTranslatorList); 03797 if (!interface) { 03798 03799 // 03800 // if interface is NULL we really don't have translator. 03801 // 03802 03803 translatorEntry = NULL; 03804 } 03805 } 03806 } 03807 if (translatorEntry) { 03808 translatorFound = TRUE; 03809 } 03810 if ((arbiterFound == FALSE) && translatorEntry) { 03811 03812 // 03813 // Find a translator to translate the req desc ... Translate it and link it to 03814 // the front of ReqDesc->TranslatedReqDesc such that the first in the list is for 03815 // the Arbiter to use. 03816 // 03817 03818 reqDesc = ReqDesc->TranslatedReqDesc; 03819 status = IopTranslateAndAdjustReqDesc( 03820 reqDesc, 03821 translatorEntry, 03822 &translatedReqDesc); 03823 if (NT_SUCCESS(status)) { 03824 ASSERT(translatedReqDesc); 03825 resourceType = translatedReqDesc->AlternativeTable.Alternatives->Type; 03826 translatedReqDesc->TranslatedReqDesc = ReqDesc->TranslatedReqDesc; 03827 ReqDesc->TranslatedReqDesc = translatedReqDesc; 03828 // 03829 // If the translator is non-hierarchial and performs a complete 03830 // translation to root (eg ISA interrups for PCI devices) then 03831 // don't pass translations to parent. 03832 // 03833 03834 if (status == STATUS_TRANSLATION_COMPLETE) { 03835 searchTranslator = FALSE; 03836 } 03837 } else { 03838 DebugMessage(DUMP_INFO, ("PnpResr: resreq list TranslationAndAdjusted failed\n")); 03839 return status; 03840 } 03841 } 03842 03843 } 03844 03845 // 03846 // Move up to current device node's parent 03847 // 03848 03849 deviceNode = deviceNode->Parent; 03850 } 03851 03852 if (arbiterFound) { 03853 return STATUS_SUCCESS; 03854 } else { 03855 03856 // 03857 // We should BugCheck in this case. 03858 // 03859 03860 DebugMessage(DUMP_ERROR, ("PnpResr: can not find resource type %x arbiter\n", resourceType)); 03861 ASSERT(0); 03862 return STATUS_UNSUCCESSFUL; 03863 } 03864 03865 }

VOID IopTestForReconfiguration IN PDEVICE_NODE  DeviceNode,
IN ULONG  RebalancePhase,
IN PULONG  RebalanceCount,
IN PDEVICE_OBJECT **  DeviceTable
 

Definition at line 4767 of file pnpres.c.

References ASSERT, _DEVICE_NODE::Child, DebugMessage, DNF_ADDED, DNF_ASSIGNING_RESOURCES, DNF_ASYNC_REQUEST_PENDING, DNF_BOOT_CONFIG_RESERVED, DNF_HAS_BOOT_CONFIG, DNF_LEGACY_DRIVER, DNF_MADEUP, DNF_NEEDS_REBALANCE, DNF_NON_STOPPED_REBALANCE, DNF_RESOURCE_REQUIREMENTS_CHANGED, DNF_STARTED, DNF_STOPPED, DUMP_INFO, FALSE, _DEVICE_NODE::Flags, _DEVICE_NODE::InstancePath, IopDoesDevNodeHaveProblem, IopQueryReconfiguration(), IopReleaseBootResources, IRP_MN_CANCEL_STOP_DEVICE, IRP_MN_QUERY_STOP_DEVICE, IRP_MN_STOP_DEVICE, NT_SUCCESS, NTSTATUS(), ObReferenceObject, _DEVICE_NODE::Sibling, and TRUE.

Referenced by IopQueryRebalanceWorker().

04777 : 04778 04779 This routine query-stops a device which is started and owns resources. 04780 Note the resources for the device are not released at this point. 04781 04782 Parameters: 04783 04784 DeviceNode - supplies a pointer to the device node to be tested for reconfiguration. 04785 04786 Phase - Supplies a value to specify the phase of the rebalance. 04787 04788 RebalanceCount - supplies a pointer to a variable to receive the number of devices 04789 participating the rebalance. 04790 04791 Return Value: 04792 04793 Status code that indicates whether or not the function was successful. 04794 04795 --*/ 04796 04797 { 04798 PDEVICE_NODE nodex; 04799 NTSTATUS status; 04800 BOOLEAN addToList = FALSE; 04801 04802 // 04803 // We still need to perform the test for sibling nodes. 04804 // 04805 04806 if ((DeviceNode->Flags & DNF_ASYNC_REQUEST_PENDING) || 04807 (DeviceNode->Flags & DNF_STOPPED) || 04808 (IopDoesDevNodeHaveProblem(DeviceNode)) || 04809 (DeviceNode->Flags & DNF_LEGACY_DRIVER) || 04810 (DeviceNode->Flags & DNF_ASSIGNING_RESOURCES)) { 04811 return; 04812 } 04813 04814 if (Phase == 0) { 04815 04816 // 04817 // At phase zero, this routine only wants to find out which devices's resource 04818 // requirements lists chagned. No one actually gets stopped. 04819 // 04820 04821 if (DeviceNode->Flags & DNF_RESOURCE_REQUIREMENTS_CHANGED && 04822 !(DeviceNode->Flags & DNF_NON_STOPPED_REBALANCE) ) { 04823 04824 // 04825 // It's too hard to handle non-stop rebalancing devices during rebalance. 04826 // So, We will skip it. 04827 // 04828 04829 addToList = TRUE; 04830 } else { 04831 04832 if (DeviceNode->Flags & DNF_STARTED) { 04833 status = IopQueryReconfiguration (IRP_MN_QUERY_STOP_DEVICE, DeviceNode->PhysicalDeviceObject); 04834 if (NT_SUCCESS(status)) { 04835 if (status == STATUS_RESOURCE_REQUIREMENTS_CHANGED) { 04836 04837 // 04838 // If we find out a device's resource requirements changed this way, 04839 // it will be stopped and reassigned resources even if it supports 04840 // non-stopped rebalance. 04841 // 04842 04843 DeviceNode->Flags |= DNF_RESOURCE_REQUIREMENTS_CHANGED; 04844 addToList = TRUE; 04845 } 04846 } 04847 IopQueryReconfiguration (IRP_MN_CANCEL_STOP_DEVICE, DeviceNode->PhysicalDeviceObject); 04848 } 04849 } 04850 if (addToList) { 04851 *RebalanceCount = *RebalanceCount + 1; 04852 **DeviceTable = DeviceNode->PhysicalDeviceObject; 04853 *DeviceTable = *DeviceTable + 1; 04854 } 04855 } else { 04856 04857 // 04858 // Phase 1 04859 // 04860 04861 if (DeviceNode->Flags & DNF_STARTED) { 04862 04863 // 04864 // Make sure all the resources required children of the DeviceNode are stopped. 04865 // 04866 04867 nodex = DeviceNode->Child; 04868 while (nodex) { 04869 if (!(nodex->Flags & (DNF_STARTED | DNF_ASSIGNING_RESOURCES)) || 04870 (nodex->Flags & DNF_STOPPED) || 04871 (nodex->Flags & DNF_NEEDS_REBALANCE)) { 04872 nodex = nodex->Sibling; 04873 } else { 04874 break; 04875 } 04876 } 04877 if (nodex) { 04878 04879 // 04880 // If any resource required child of the DeviceNode does not stopped, 04881 // we won't ask the DeviceNode to stop. 04882 // BUGBUG: We may want to restart the stopped subtrees. 04883 // 04884 04885 DebugMessage(DUMP_INFO, ("Rebalance: Child %ws not stopped for %ws\n", nodex->InstancePath.Buffer, DeviceNode->InstancePath.Buffer)); 04886 return; 04887 } 04888 } else if ((DeviceNode->Flags & DNF_HAS_BOOT_CONFIG) == 0 || 04889 !(DeviceNode->Flags & DNF_ADDED) || 04890 DeviceNode->Flags & DNF_MADEUP) { 04891 04892 // 04893 // The device is not started and has no boot config. There is no need to query-stop it. 04894 // Or if the device has BOOT config but there is no driver installed for it. We don't query 04895 // stop it. (There may be legacy drivers are using the resources.) 04896 // We also don't want to query stop root enumerated devices (for performance reason.) 04897 // BUGBUG - We really want to query stop the root enumerated devices which do not have 04898 // Boot Config and have resource requirement alternatives. (But today some legacy 04899 // driver installers do not create boot resources.) 04900 // 04901 04902 return; 04903 } 04904 status = IopQueryReconfiguration (IRP_MN_QUERY_STOP_DEVICE, DeviceNode->PhysicalDeviceObject); 04905 if (NT_SUCCESS(status)) { 04906 DebugMessage(DUMP_INFO, ("Rebalance: %ws succeeded QueryStop\n", DeviceNode->InstancePath.Buffer)); 04907 if (DeviceNode->Flags & DNF_STARTED) { 04908 04909 //DeviceNode->Flags &= ~DNF_STARTED; 04910 DeviceNode->Flags |= DNF_STOPPED; 04911 *RebalanceCount = *RebalanceCount + 1; 04912 **DeviceTable = DeviceNode->PhysicalDeviceObject; 04913 04914 // 04915 // Add a reference to the device object such that it won't disapear during rebalance. 04916 // 04917 04918 ObReferenceObject(DeviceNode->PhysicalDeviceObject); 04919 *DeviceTable = *DeviceTable + 1; 04920 } else { 04921 04922 // 04923 // We need to release the device's prealloc boot config. This device will NOT 04924 // participate in resource rebalancing. 04925 // 04926 04927 ASSERT(DeviceNode->Flags & DNF_HAS_BOOT_CONFIG); 04928 status = IopQueryReconfiguration (IRP_MN_STOP_DEVICE, DeviceNode->PhysicalDeviceObject); 04929 ASSERT(NT_SUCCESS(status)); 04930 IopReleaseBootResources(DeviceNode); 04931 04932 // 04933 // Reset BOOT CONFIG flags. DO NOT set DNF_STOPPED. 04934 // 04935 04936 DeviceNode->Flags &= ~(DNF_HAS_BOOT_CONFIG + DNF_BOOT_CONFIG_RESERVED); 04937 } 04938 } else { 04939 IopQueryReconfiguration (IRP_MN_CANCEL_STOP_DEVICE, DeviceNode->PhysicalDeviceObject); 04940 } 04941 } 04942 04943 }

NTSTATUS IopTranslateAndAdjustReqDesc IN PREQ_DESC  ReqDesc,
IN PPI_RESOURCE_TRANSLATOR_ENTRY  TranslatorEntry,
OUT PREQ_DESC TranslatedReqDesc
 

Definition at line 4129 of file pnpres.c.

References _ARBITER_LIST_ENTRY::AlternativeCount, _ARBITER_LIST_ENTRY::Alternatives, ASSERT, _ARBITER_LIST_ENTRY::Assignment, _TRANSLATOR_INTERFACE::Context, DebugMessage, DUMP_ERROR, ExAllocatePool, ExAllocatePool1RD, ExAllocatePoolIORD, ExFreePool(), exit, FALSE, _ARBITER_LIST_ENTRY::ListEntry, NT_SUCCESS, NTSTATUS(), NULL, PagedPool, PREQ_DESC, _TRANSLATOR_INTERFACE::TranslateResourceRequirements, and TRUE.

Referenced by IopSetupArbiterAndTranslators().

04137 : 04138 04139 This routine translates and adjusts ReqDesc IoResourceDescriptors to 04140 their translated and adjusted form. 04141 04142 Parameters: 04143 04144 ReqDesc - supplies a pointer to the REQ_DESC to be translated. 04145 04146 TranslatorEntry - supplies a pointer to the translator infor structure. 04147 04148 TranslatedReqDesc - supplies a pointer to a variable to receive the 04149 translated REQ_DESC. 04150 04151 Return Value: 04152 04153 Status code that indicates whether or not the function was successful. 04154 04155 --*/ 04156 { 04157 ULONG i, total = 0, *targetCount; 04158 PTRANSLATOR_INTERFACE translator = TranslatorEntry->TranslatorInterface; 04159 PIO_RESOURCE_DESCRIPTOR ioDesc, *target, tIoDesc; 04160 PREQ_DESC tReqDesc; 04161 PARBITER_LIST_ENTRY arbiterEntry; 04162 NTSTATUS status, returnStatus = STATUS_SUCCESS; 04163 BOOLEAN reqTranslated = FALSE; 04164 04165 if (ReqDesc->AlternativeTable.AlternativeCount == 0) { 04166 return STATUS_INVALID_PARAMETER; 04167 } 04168 04169 *TranslatedReqDesc = NULL; 04170 04171 target = (PIO_RESOURCE_DESCRIPTOR *) ExAllocatePoolIORD( 04172 PagedPool, 04173 sizeof(PIO_RESOURCE_DESCRIPTOR) * ReqDesc->AlternativeTable.AlternativeCount 04174 ); 04175 if (target == NULL) { 04176 DebugMessage(DUMP_ERROR, ("PnpRes: Not Enough memory to perform resreqlist adjustment\n")); 04177 return STATUS_INSUFFICIENT_RESOURCES; 04178 } 04179 RtlZeroMemory(target, sizeof(PIO_RESOURCE_DESCRIPTOR) * ReqDesc->AlternativeTable.AlternativeCount); 04180 04181 targetCount = (PULONG) ExAllocatePool( 04182 PagedPool, 04183 sizeof(ULONG) * ReqDesc->AlternativeTable.AlternativeCount 04184 ); 04185 if (targetCount == NULL) { 04186 DebugMessage(DUMP_ERROR, ("PnpRes: Not Enough memory to perform resreqlist adjustment\n")); 04187 ExFreePool(target); 04188 return STATUS_INSUFFICIENT_RESOURCES; 04189 } 04190 04191 RtlZeroMemory(targetCount, sizeof(ULONG) * ReqDesc->AlternativeTable.AlternativeCount); 04192 04193 // 04194 // Determine the number of IO_RESOURCE_DESCRIPTORs after translation. 04195 // 04196 04197 ioDesc = ReqDesc->AlternativeTable.Alternatives; 04198 for (i = 0; i < ReqDesc->AlternativeTable.AlternativeCount; i++) { 04199 status = (translator->TranslateResourceRequirements)( 04200 translator->Context, 04201 ioDesc, 04202 ReqDesc->AlternativeTable.PhysicalDeviceObject, 04203 &targetCount[i], 04204 &target[i] 04205 ); 04206 if (!NT_SUCCESS(status) || targetCount[i] == 0) { 04207 DebugMessage(DUMP_ERROR, ("PnpRes:Translator failed to adjust resreqlist\n")); 04208 target[i] = ioDesc; 04209 targetCount[i] = 0; 04210 total++; 04211 } else { 04212 total += targetCount[i]; 04213 reqTranslated = TRUE; 04214 } 04215 ioDesc++; 04216 if (NT_SUCCESS(status) && (returnStatus != STATUS_TRANSLATION_COMPLETE)) { 04217 returnStatus = status; 04218 } 04219 } 04220 04221 if (!reqTranslated) { 04222 DebugMessage(DUMP_ERROR, ("PnpRes:Failed to translate any requirement for %ws!\n", ((PDEVICE_NODE)(ReqDesc->AlternativeTable.PhysicalDeviceObject->DeviceObjectExtension->DeviceNode))->InstancePath.Buffer)); 04223 returnStatus = status; 04224 } 04225 04226 // 04227 // Allocate memory for the adjusted/translated resources descriptors 04228 // 04229 04230 tIoDesc = (PIO_RESOURCE_DESCRIPTOR) ExAllocatePoolIORD( 04231 PagedPool, 04232 total * sizeof(IO_RESOURCE_DESCRIPTOR)); 04233 if (!tIoDesc) { 04234 DebugMessage(DUMP_ERROR, ("PnpRes: Not Enough memory to perform resreqlist adjustment\n")); 04235 returnStatus = STATUS_INSUFFICIENT_RESOURCES; 04236 goto exit; 04237 } 04238 04239 tReqDesc = (PREQ_DESC) ExAllocatePool1RD (PagedPool, sizeof(REQ_DESC)); 04240 if (tReqDesc == NULL) { 04241 DebugMessage(DUMP_ERROR, ("PnpRes: Not Enough memory to perform resreqlist adjustment\n")); 04242 ExFreePool(tIoDesc); 04243 returnStatus = STATUS_INSUFFICIENT_RESOURCES; 04244 goto exit; 04245 } 04246 04247 // 04248 // Create and initialize a new REQ_DESC for the translated/adjusted io resources 04249 // 04250 04251 RtlMoveMemory(tReqDesc, ReqDesc, sizeof(REQ_DESC)); 04252 04253 // 04254 // Set the translated req desc's ReqAlternative to NULL to indicated this 04255 // is not the original req desc. 04256 // 04257 04258 tReqDesc->ReqAlternative = NULL; 04259 04260 tReqDesc->u.Translator = TranslatorEntry; 04261 tReqDesc->TranslatedReqDesc = NULL; 04262 arbiterEntry = &tReqDesc->AlternativeTable; 04263 InitializeListHead(&arbiterEntry->ListEntry); 04264 arbiterEntry->AlternativeCount = total; 04265 arbiterEntry->Alternatives = tIoDesc; 04266 arbiterEntry->Assignment = &tReqDesc->Allocation; 04267 04268 ioDesc = ReqDesc->AlternativeTable.Alternatives; 04269 for (i = 0; i < ReqDesc->AlternativeTable.AlternativeCount; i++) { 04270 if (targetCount[i] != 0) { 04271 RtlMoveMemory(tIoDesc, target[i], targetCount[i] * sizeof(IO_RESOURCE_DESCRIPTOR)); 04272 tIoDesc += targetCount[i]; 04273 } else { 04274 04275 // 04276 // Make it become impossible to satisfy. 04277 // 04278 04279 RtlMoveMemory(tIoDesc, ioDesc, sizeof(IO_RESOURCE_DESCRIPTOR)); 04280 switch (tIoDesc->Type) { 04281 case CmResourceTypePort: 04282 case CmResourceTypeMemory: 04283 tIoDesc->u.Port.MinimumAddress.LowPart = 2; 04284 tIoDesc->u.Port.MinimumAddress.HighPart = 0; 04285 tIoDesc->u.Port.MaximumAddress.LowPart = 1; 04286 tIoDesc->u.Port.MaximumAddress.HighPart = 0; 04287 break; 04288 case CmResourceTypeBusNumber: 04289 tIoDesc->u.BusNumber.MinBusNumber = 2; 04290 tIoDesc->u.BusNumber.MaxBusNumber = 1; 04291 break; 04292 04293 case CmResourceTypeInterrupt: 04294 tIoDesc->u.Interrupt.MinimumVector = 2; 04295 tIoDesc->u.Interrupt.MaximumVector = 1; 04296 break; 04297 04298 case CmResourceTypeDma: 04299 tIoDesc->u.Dma.MinimumChannel = 2; 04300 tIoDesc->u.Dma.MaximumChannel = 1; 04301 break; 04302 default: 04303 ASSERT(0); 04304 break; 04305 } 04306 tIoDesc += 1; 04307 } 04308 ioDesc++; 04309 04310 } 04311 04312 #if DBG 04313 // 04314 // Verify the adjusted resource descriptors are valid 04315 // 04316 04317 ioDesc = arbiterEntry->Alternatives; 04318 ASSERT((ioDesc->Option & IO_RESOURCE_ALTERNATIVE) == 0); 04319 ioDesc++; 04320 for (i = 1; i < total; i++) { 04321 ASSERT(ioDesc->Option & IO_RESOURCE_ALTERNATIVE); 04322 ioDesc++; 04323 } 04324 #endif 04325 *TranslatedReqDesc = tReqDesc; 04326 exit: 04327 for (i = 0; i < ReqDesc->AlternativeTable.AlternativeCount; i++) { 04328 if (targetCount[i] != 0) { 04329 ASSERT(target[i]); 04330 ExFreePool(target[i]); 04331 } 04332 } 04333 ExFreePool(target); 04334 ExFreePool(targetCount); 04335 return returnStatus; 04336 }


Variable Documentation

PDEVICE_NODE IopLegacyDeviceNode
 

Definition at line 239 of file pnpres.c.

Referenced by IopFindLegacyDeviceNode(), and IopRemoveLegacyDeviceNode().

WCHAR IopWstrRaw[]
 

Definition at line 259 of file pnpres.c.

WCHAR IopWstrTranslated[]
 

Definition at line 258 of file pnpres.c.

LIST_ENTRY PiActiveArbiterList
 

Definition at line 234 of file pnpres.c.

Referenced by IopAddReqDescsToArbiters(), IopAssignInner(), IopPlacement(), IopPlacementForReservation(), IopReserve(), IopRestoreBestConfiguration(), and IopSaveCurrentConfiguration().

PIOP_RESOURCE_REQUEST PiAssignTable
 

Definition at line 237 of file pnpres.c.

Referenced by IopAssignInner(), IopFindResourcesForArbiter(), IopIsBestConfiguration(), IopRestoreBestConfiguration(), and IopSaveCurrentConfiguration().

ULONG PiAssignTableCount
 

Definition at line 238 of file pnpres.c.

Referenced by IopAssignInner(), IopFindResourcesForArbiter(), IopIsBestConfiguration(), IopRestoreBestConfiguration(), and IopSaveCurrentConfiguration().

LIST_ENTRY PiBestArbiterList
 

Definition at line 235 of file pnpres.c.

Referenced by IopAssignInner(), IopReserve(), IopRestoreBestConfiguration(), and IopSaveCurrentConfiguration().

ULONG PiBestPriority
 

Definition at line 236 of file pnpres.c.

Referenced by IopAssignInner(), and IopIsBestConfiguration().

BOOLEAN PiNoRetest
 

Definition at line 241 of file pnpres.c.

Referenced by IopAssign(), IopAssignInner(), IopIsBestConfiguration(), IopRestoreBestConfiguration(), and IopSaveCurrentConfiguration().

BOOLEAN PiUseTimeout = TRUE
 

Definition at line 245 of file pnpres.c.

Referenced by IopAssign().

ULONG PnpResDebugLevel = 0
 

Definition at line 273 of file pnpres.c.

Referenced by IopAssignInner(), IopBuildCmResourceLists(), IopChildToRootTranslation(), IopGetResourceRequirementsForAssignTable(), IopQueryConflictListInternal(), IopRebalance(), IopReserve(), IopReserveLegacyBootResources(), and IopResourceRequirementsListToReqList().

PNPRESDEBUGTRANSLATIONFAILURE* PnpResDebugTranslationFailure = PnpResDebugTranslationFailureArray
 

Definition at line 287 of file pnpres.c.

Referenced by IopChildToRootTranslation().

PNPRESDEBUGTRANSLATIONFAILURE PnpResDebugTranslationFailureArray[32]
 

Definition at line 286 of file pnpres.c.

ULONG PnpResDebugTranslationFailureCount = 32
 

Definition at line 285 of file pnpres.c.

Referenced by IopChildToRootTranslation().


Generated on Sat May 15 19:45:15 2004 for test by doxygen 1.3.7