test: pnpres.c File Reference

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 _Counter * | PCOUNTER
typedef _DUPLICATE_DETECTION_CONTEXT | DUPLICATE_DETECTION_CONTEXT
typedef _DUPLICATE_DETECTION_CONTEXT * | PDUPLICATE_DETECTION_CONTEXT
typedef _IOP_POOL | IOP_POOL
typedef _IOP_POOL * | PIOP_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]
PNPRESDEBUGTRANSLATIONFAILURE * | PnpResDebugTranslationFailure = 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,
|  | b |  | ) | ExAllocatePool(a,b)

| Definition at line 68 of file pnpres.c. Referenced by IopTranslateAndAdjustReqDesc().

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

| Definition at line 64 of file pnpres.c. Referenced by IopSetupArbiterAndTranslators().

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

| Definition at line 60 of file pnpres.c. Referenced by IopAllocateResources().

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

| Definition at line 62 of file pnpres.c. Referenced by IopBuildCmResourceList(), and IopCombineLegacyResources().

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

| Definition at line 63 of file pnpres.c. Referenced by IopBuildCmResourceList().

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

| Definition at line 67 of file pnpres.c. Referenced by IopTranslateAndAdjustReqDesc().

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

| Definition at line 71 of file pnpres.c. Referenced by IopLegacyResourceAllocation(), IopReserveBootResources(), and IopReserveBootResourcesInternal().

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

| Definition at line 70 of file pnpres.c. Referenced by IopRebalance().

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

| Definition at line 72 of file pnpres.c. Referenced by IopCombineCmResourceList(), IopCreateCmResourceList(), and IopReserveBootResources().

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

| Definition at line 69 of file pnpres.c. Referenced by IopQueryRebalance(), and IopRebalance().

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

| Definition at line 66 of file pnpres.c. Referenced by IopChildToRootTranslation(), and IopFindResourcesForArbiter().

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

| Definition at line 61 of file pnpres.c. Referenced by IopResourceRequirementsListToReqList().

#define ExAllocatePoolTE | ( | a,
|  | b |  | ) | 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 |  | ) | ((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().