PNP Resource Management
Proper management of hardware resources is a cornerstone of the Windows Plug and Play (PnP) subsystem. PnP ensures that devices are detected, configured, and assigned resources (such as I/O port addresses, interrupt request lines (IRQs), and direct memory access (DMA) channels) without conflicts.
Key Concepts
- Resource Detectors: Components responsible for identifying hardware and reporting their resource needs.
- Resource Arbitrators: System components that resolve resource requests, ensuring no two devices are assigned the same resource.
- Configuration Manager: The central PnP component that manages device information, resource allocation, and device state.
- Resource Requirements Lists (RRLs): Data structures describing the resources a device requires.
- Resource Settings Lists (RSLs): Data structures describing the resources a device has been assigned.
Resource Types
The PnP manager handles several types of hardware resources:
- I/O Port Addresses: Ranges of addresses used for communication with hardware devices.
- Memory-Mapped I/O (MMIO) Regions: Ranges of system memory mapped to device registers.
- Interrupt Request (IRQ) Lines: Hardware signals used by devices to interrupt the processor.
- Direct Memory Access (DMA) Channels: Dedicated pathways for devices to transfer data directly to and from system memory without involving the CPU.
- Bus Numbers: Used for bus hierarchies (e.g., PCI bus numbers).
Resource Allocation Process
When a device is detected, the PnP manager initiates a resource allocation process:
- The PnP enumerator for the bus (e.g., PCI, USB) identifies a new device.
- The PnP manager queries the device's driver for its resource requirements (often defined in the hardware's BIOS or configuration space). This information is typically returned in a Resource Requirements List (RRL).
- The PnP manager consults its database of currently allocated resources and requests from other devices.
- Resource arbitrators are invoked to determine a conflict-free assignment of resources from the RRL. This might involve negotiating with other drivers or modifying existing assignments.
- Once a valid set of resources is identified, the PnP manager assigns them to the device, storing the information in a Resource Settings List (RSL).
- The PnP manager then informs the device's driver of the assigned resources by sending a
IRP_MN_START_DEVICEIRP. The driver uses this information to initialize and configure the device.
Driver's Role in Resource Management
Drivers play a crucial role in resource management:
- Reporting Requirements: Drivers must accurately report their device's resource needs when queried by the PnP manager. This is typically done by parsing the hardware ID and then providing a list of potential resource configurations.
- Handling Resource Assignments: Drivers receive assigned resources via the
IRP_MN_START_DEVICEIRP. They must then program the hardware to use these resources and initialize any necessary data structures. - Rebalancing Resources: In some dynamic scenarios, drivers might be asked to relinquish resources or accept new ones. They must handle these requests gracefully.
Important: Drivers should never attempt to directly access or claim hardware resources without going through the PnP manager. This can lead to system instability and resource conflicts.
Example: Requesting Resources in a Driver
While the PnP manager handles the allocation, drivers provide the requirements. A common way to represent these requirements is using data structures like CM_PARTIAL_RESOURCE_DESCRIPTOR and building up a CM_RESOURCE_LIST.
NTSTATUS AddDevice(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PDEVICE_OBJECT PDO
)
{
// ... (Create device object, etc.)
PDEVICE_EXTENSION devExt = (PDEVICE_EXTENSION)PhysicalDeviceObject->DeviceExtension;
// Report resource requirements (simplified)
// This would involve querying registry or hardware for specific needs.
// The PnP Manager's IoQueryDeviceResources would eventually be involved.
devExt->IoResourceRequirementList.ListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST);
devExt->IoResourceRequirementList.AlternativeLists[0].Count = 1; // One alternative list
devExt->IoResourceRequirementList.AlternativeLists[0].List[0].Type = CmResourceTypePort;
devExt->IoResourceRequirementList.AlternativeLists[0].List[0].Start.LowPart = 0x300; // Example start port
devExt->IoResourceRequirementList.AlternativeLists[0].List[0].Length = 8; // Example length
// ... more resource types like IRQ, DMA etc.
// The PnP Manager will use this information during StartDevice.
return STATUS_SUCCESS;
}
// During IRP_MN_START_DEVICE handler:
NTSTATUS StartDevice(
_In_ PDEVICE_OBJECT DeviceObject,
_In_ PIRP Irp
)
{
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
PCM_RESOURCE_LIST allocatedResources = irpSp->Parameters.StartDevice.AllocatedResourcesTranslated;
if (allocatedResources) {
// Process the allocated resources
for (ULONG i = 0; i < allocatedResources->List[0].PartialResourceList.Count; i++) {
PCM_PARTIAL_RESOURCE_DESCRIPTOR resource = &allocatedResources->List[0].PartialResourceList.PartialDescriptors[i];
switch (resource->Type) {
case CmResourceTypePort:
devExt->IoPortBase = resource->u.Port.Start.LowPart;
devExt->IoPortCount = resource->u.Port.Length;
break;
case CmResourceTypeInterrupt:
// Configure interrupt
break;
case CmResourceTypeDma:
// Configure DMA
break;
case CmResourceTypeMemory:
// Map memory region
break;
default:
break;
}
}
// Initialize hardware with allocated resources
}
// ...
return STATUS_SUCCESS;
}
Dynamic Resource Rebalancing
Windows supports dynamic resource rebalancing, allowing the system to reassign resources to optimize their usage or accommodate newly added hardware. Drivers may receive IRP_MN_REBALANCE and IRP_MN_QUERY_REMOVE / IRP_MN_REMOVE_DEVICE IRPs to manage these changes.
Understanding the PnP IRPs related to resource management (IRP_MN_QUERY_RESOURCE_REQUIREMENTS, IRP_MN_FILTER_RESOURCE_REQUIREMENTS, IRP_MN_START_DEVICE, IRP_MN_REBALANCE) is crucial for developing robust PnP drivers.