9 #include <acpi_drivers.h>
18 #pragma alloc_text (PAGE, Bus_PDO_PnP)
19 #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceCaps)
20 #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceId)
21 #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceText)
22 #pragma alloc_text (PAGE, Bus_PDO_QueryResources)
23 #pragma alloc_text (PAGE, Bus_PDO_QueryResourceRequirements)
24 #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceRelations)
25 #pragma alloc_text (PAGE, Bus_PDO_QueryBusInformation)
26 #pragma alloc_text (PAGE, Bus_GetDeviceCapabilities)
31 PDEVICE_OBJECT DeviceObject
,
33 PIO_STACK_LOCATION IrpStack
,
34 PPDO_DEVICE_DATA DeviceData
39 struct acpi_device
*device
= NULL
;
43 if (DeviceData
->AcpiHandle
)
44 acpi_bus_get_device(DeviceData
->AcpiHandle
, &device
);
47 // NB: Because we are a bus enumerator, we have no one to whom we could
48 // defer these irps. Therefore we do not pass them down but merely
52 switch (IrpStack
->MinorFunction
) {
54 case IRP_MN_START_DEVICE
:
56 // Here we do what ever initialization and ``turning on'' that is
57 // required to allow others to access this device.
58 // Power up the device.
60 if (DeviceData
->AcpiHandle
&& acpi_bus_power_manageable(DeviceData
->AcpiHandle
) &&
61 !ACPI_SUCCESS(acpi_bus_set_power(DeviceData
->AcpiHandle
, ACPI_STATE_D0
)))
63 DPRINT1("Device %x failed to start!\n", DeviceData
->AcpiHandle
);
64 status
= STATUS_UNSUCCESSFUL
;
68 DeviceData
->InterfaceName
.Length
= 0;
72 IoRegisterDeviceInterface(DeviceData
->Common
.Self
,
73 &GUID_DEVICE_SYS_BUTTON
,
75 &DeviceData
->InterfaceName
);
77 else if (device
->flags
.hardware_id
&&
78 strstr(device
->pnp
.hardware_id
, ACPI_THERMAL_HID
))
80 IoRegisterDeviceInterface(DeviceData
->Common
.Self
,
81 &GUID_DEVICE_THERMAL_ZONE
,
83 &DeviceData
->InterfaceName
);
85 else if (device
->flags
.hardware_id
&&
86 strstr(device
->pnp
.hardware_id
, ACPI_BUTTON_HID_LID
))
88 IoRegisterDeviceInterface(DeviceData
->Common
.Self
,
91 &DeviceData
->InterfaceName
);
93 else if (device
->flags
.hardware_id
&&
94 strstr(device
->pnp
.hardware_id
, ACPI_PROCESSOR_HID
))
96 IoRegisterDeviceInterface(DeviceData
->Common
.Self
,
97 &GUID_DEVICE_PROCESSOR
,
99 &DeviceData
->InterfaceName
);
102 if (DeviceData
->InterfaceName
.Length
!= 0)
103 IoSetDeviceInterfaceState(&DeviceData
->InterfaceName
, TRUE
);
105 state
.DeviceState
= PowerDeviceD0
;
106 PoSetPowerState(DeviceData
->Common
.Self
, DevicePowerState
, state
);
107 DeviceData
->Common
.DevicePowerState
= PowerDeviceD0
;
108 SET_NEW_PNP_STATE(DeviceData
->Common
, Started
);
109 status
= STATUS_SUCCESS
;
112 case IRP_MN_STOP_DEVICE
:
114 if (DeviceData
->InterfaceName
.Length
!= 0)
115 IoSetDeviceInterfaceState(&DeviceData
->InterfaceName
, FALSE
);
118 // Here we shut down the device and give up and unmap any resources
119 // we acquired for the device.
121 if (DeviceData
->AcpiHandle
&& acpi_bus_power_manageable(DeviceData
->AcpiHandle
) &&
122 !ACPI_SUCCESS(acpi_bus_set_power(DeviceData
->AcpiHandle
, ACPI_STATE_D3
)))
124 DPRINT1("Device %x failed to stop!\n", DeviceData
->AcpiHandle
);
125 status
= STATUS_UNSUCCESSFUL
;
129 state
.DeviceState
= PowerDeviceD3
;
130 PoSetPowerState(DeviceData
->Common
.Self
, DevicePowerState
, state
);
131 DeviceData
->Common
.DevicePowerState
= PowerDeviceD3
;
132 SET_NEW_PNP_STATE(DeviceData
->Common
, Stopped
);
133 status
= STATUS_SUCCESS
;
137 case IRP_MN_QUERY_STOP_DEVICE
:
140 // No reason here why we can't stop the device.
141 // If there were a reason we should speak now, because answering success
142 // here may result in a stop device irp.
145 SET_NEW_PNP_STATE(DeviceData
->Common
, StopPending
);
146 status
= STATUS_SUCCESS
;
149 case IRP_MN_CANCEL_STOP_DEVICE
:
152 // The stop was canceled. Whatever state we set, or resources we put
153 // on hold in anticipation of the forthcoming STOP device IRP should be
154 // put back to normal. Someone, in the long list of concerned parties,
155 // has failed the stop device query.
159 // First check to see whether you have received cancel-stop
160 // without first receiving a query-stop. This could happen if someone
161 // above us fails a query-stop and passes down the subsequent
165 if (StopPending
== DeviceData
->Common
.DevicePnPState
)
168 // We did receive a query-stop, so restore.
170 RESTORE_PREVIOUS_PNP_STATE(DeviceData
->Common
);
172 status
= STATUS_SUCCESS
;// We must not fail this IRP.
174 case IRP_MN_QUERY_CAPABILITIES
:
177 // Return the capabilities of a device, such as whether the device
178 // can be locked or ejected..etc
181 status
= Bus_PDO_QueryDeviceCaps(DeviceData
, Irp
);
185 case IRP_MN_QUERY_ID
:
187 // Query the IDs of the device
188 status
= Bus_PDO_QueryDeviceId(DeviceData
, Irp
);
192 case IRP_MN_QUERY_DEVICE_RELATIONS
:
194 DPRINT("\tQueryDeviceRelation Type: %s\n",DbgDeviceRelationString(\
195 IrpStack
->Parameters
.QueryDeviceRelations
.Type
));
197 status
= Bus_PDO_QueryDeviceRelations(DeviceData
, Irp
);
201 case IRP_MN_QUERY_DEVICE_TEXT
:
203 status
= Bus_PDO_QueryDeviceText(DeviceData
, Irp
);
207 case IRP_MN_QUERY_RESOURCES
:
209 status
= Bus_PDO_QueryResources(DeviceData
, Irp
);
213 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
215 status
= Bus_PDO_QueryResourceRequirements(DeviceData
, Irp
);
219 case IRP_MN_QUERY_BUS_INFORMATION
:
221 status
= Bus_PDO_QueryBusInformation(DeviceData
, Irp
);
225 case IRP_MN_QUERY_INTERFACE
:
227 status
= Bus_PDO_QueryInterface(DeviceData
, Irp
);
232 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
235 // OPTIONAL for bus drivers.
236 // The PnP Manager sends this IRP to a device
237 // stack so filter and function drivers can adjust the
238 // resources required by the device, if appropriate.
243 //case IRP_MN_QUERY_PNP_DEVICE_STATE:
246 // OPTIONAL for bus drivers.
247 // The PnP Manager sends this IRP after the drivers for
248 // a device return success from the IRP_MN_START_DEVICE
249 // request. The PnP Manager also sends this IRP when a
250 // driver for the device calls IoInvalidateDeviceState.
255 //case IRP_MN_READ_CONFIG:
256 //case IRP_MN_WRITE_CONFIG:
259 // Bus drivers for buses with configuration space must handle
260 // this request for their child devices. Our devices don't
261 // have a config space.
266 //case IRP_MN_SET_LOCK:
273 // For PnP requests to the PDO that we do not understand we should
274 // return the IRP WITHOUT setting the status or information fields.
275 // These fields may have already been set by a filter (eg acpi).
276 status
= Irp
->IoStatus
.Status
;
281 Irp
->IoStatus
.Status
= status
;
282 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
288 Bus_PDO_QueryDeviceCaps(
289 PPDO_DEVICE_DATA DeviceData
,
293 PIO_STACK_LOCATION stack
;
294 PDEVICE_CAPABILITIES deviceCapabilities
;
295 struct acpi_device
*device
= NULL
;
300 if (DeviceData
->AcpiHandle
)
301 acpi_bus_get_device(DeviceData
->AcpiHandle
, &device
);
303 stack
= IoGetCurrentIrpStackLocation (Irp
);
308 deviceCapabilities
=stack
->Parameters
.DeviceCapabilities
.Capabilities
;
311 // Set the capabilities.
314 if (deviceCapabilities
->Version
!= 1 ||
315 deviceCapabilities
->Size
< sizeof(DEVICE_CAPABILITIES
))
317 return STATUS_UNSUCCESSFUL
;
320 deviceCapabilities
->D1Latency
= 0;
321 deviceCapabilities
->D2Latency
= 0;
322 deviceCapabilities
->D3Latency
= 0;
324 deviceCapabilities
->DeviceState
[PowerSystemWorking
] = PowerDeviceD0
;
325 deviceCapabilities
->DeviceState
[PowerSystemSleeping1
] = PowerDeviceD3
;
326 deviceCapabilities
->DeviceState
[PowerSystemSleeping2
] = PowerDeviceD3
;
327 deviceCapabilities
->DeviceState
[PowerSystemSleeping3
] = PowerDeviceD3
;
329 for (i
= 0; i
< ACPI_D_STATE_COUNT
&& device
; i
++)
331 if (!device
->power
.states
[i
].flags
.valid
)
337 deviceCapabilities
->DeviceState
[PowerSystemWorking
] = PowerDeviceD0
;
341 deviceCapabilities
->DeviceState
[PowerSystemSleeping1
] = PowerDeviceD1
;
342 deviceCapabilities
->D1Latency
= device
->power
.states
[i
].latency
;
346 deviceCapabilities
->DeviceState
[PowerSystemSleeping2
] = PowerDeviceD2
;
347 deviceCapabilities
->D2Latency
= device
->power
.states
[i
].latency
;
351 deviceCapabilities
->DeviceState
[PowerSystemSleeping3
] = PowerDeviceD3
;
352 deviceCapabilities
->D3Latency
= device
->power
.states
[i
].latency
;
357 // We can wake the system from D1
358 deviceCapabilities
->DeviceWake
= PowerDeviceD1
;
361 deviceCapabilities
->DeviceD1
=
362 (deviceCapabilities
->DeviceState
[PowerSystemSleeping1
] == PowerDeviceD1
) ? TRUE
: FALSE
;
363 deviceCapabilities
->DeviceD2
=
364 (deviceCapabilities
->DeviceState
[PowerSystemSleeping2
] == PowerDeviceD2
) ? TRUE
: FALSE
;
366 deviceCapabilities
->WakeFromD0
= FALSE
;
367 deviceCapabilities
->WakeFromD1
= TRUE
; //Yes we can
368 deviceCapabilities
->WakeFromD2
= FALSE
;
369 deviceCapabilities
->WakeFromD3
= FALSE
;
373 deviceCapabilities
->EjectSupported
= device
->flags
.ejectable
;
374 deviceCapabilities
->HardwareDisabled
= !device
->status
.enabled
;
375 deviceCapabilities
->Removable
= device
->flags
.removable
;
376 deviceCapabilities
->SurpriseRemovalOK
= device
->flags
.suprise_removal_ok
;
377 deviceCapabilities
->UniqueID
= device
->flags
.unique_id
;
378 deviceCapabilities
->NoDisplayInUI
= !device
->status
.show_in_ui
;
379 deviceCapabilities
->Address
= device
->pnp
.bus_address
;
383 (device
->flags
.hardware_id
&&
384 (strstr(device
->pnp
.hardware_id
, ACPI_BUTTON_HID_LID
) ||
385 strstr(device
->pnp
.hardware_id
, ACPI_THERMAL_HID
) ||
386 strstr(device
->pnp
.hardware_id
, ACPI_PROCESSOR_HID
))))
388 /* Allow ACPI to control the device if it is a lid button,
389 * a thermal zone, a processor, or a fixed feature button */
390 deviceCapabilities
->RawDeviceOK
= TRUE
;
393 deviceCapabilities
->SilentInstall
= FALSE
;
394 deviceCapabilities
->UINumber
= (ULONG
)-1;
396 return STATUS_SUCCESS
;
401 Bus_PDO_QueryDeviceId(
402 PPDO_DEVICE_DATA DeviceData
,
405 PIO_STACK_LOCATION stack
;
409 NTSTATUS status
= STATUS_SUCCESS
;
410 struct acpi_device
*Device
;
414 stack
= IoGetCurrentIrpStackLocation (Irp
);
416 switch (stack
->Parameters
.QueryId
.IdType
) {
418 case BusQueryDeviceID
:
419 if (DeviceData
->AcpiHandle
)
421 acpi_bus_get_device(DeviceData
->AcpiHandle
, &Device
);
423 length
= swprintf(temp
,
425 Device
->pnp
.hardware_id
);
429 /* We know it's a fixed feature button because
430 * these are direct children of the ACPI root device
431 * and therefore have no handle
433 length
= swprintf(temp
,
434 L
"ACPI\\FixedButton");
437 temp
[++length
] = UNICODE_NULL
;
439 buffer
= ExAllocatePoolWithTag (PagedPool
, length
* sizeof(WCHAR
), 'IPCA');
442 status
= STATUS_INSUFFICIENT_RESOURCES
;
446 RtlCopyMemory (buffer
, temp
, length
* sizeof(WCHAR
));
447 Irp
->IoStatus
.Information
= (ULONG_PTR
) buffer
;
448 DPRINT("BusQueryDeviceID: %ls\n",buffer
);
451 case BusQueryInstanceID
:
452 /* See comment in BusQueryDeviceID case */
453 if(DeviceData
->AcpiHandle
)
455 acpi_bus_get_device(DeviceData
->AcpiHandle
, &Device
);
457 if (Device
->flags
.unique_id
)
458 length
= swprintf(temp
,
460 Device
->pnp
.unique_id
);
462 /* FIXME: Generate unique id! */
463 length
= swprintf(temp
, L
"%ls", L
"0000");
466 /* FIXME: Generate unique id! */
467 length
= swprintf(temp
, L
"%ls", L
"0000");
469 temp
[++length
] = UNICODE_NULL
;
471 buffer
= ExAllocatePoolWithTag (PagedPool
, length
* sizeof (WCHAR
), 'IPCA');
473 status
= STATUS_INSUFFICIENT_RESOURCES
;
477 RtlCopyMemory (buffer
, temp
, length
* sizeof (WCHAR
));
478 DPRINT("BusQueryInstanceID: %ls\n",buffer
);
479 Irp
->IoStatus
.Information
= (ULONG_PTR
) buffer
;
482 case BusQueryHardwareIDs
:
485 /* See comment in BusQueryDeviceID case */
486 if (DeviceData
->AcpiHandle
)
488 acpi_bus_get_device(DeviceData
->AcpiHandle
, &Device
);
490 length
+= swprintf(&temp
[length
],
492 Device
->pnp
.hardware_id
);
495 length
+= swprintf(&temp
[length
],
497 Device
->pnp
.hardware_id
);
502 length
+= swprintf(&temp
[length
],
503 L
"ACPI\\FixedButton");
506 length
+= swprintf(&temp
[length
],
511 temp
[length
] = UNICODE_NULL
;
515 temp
[length
] = UNICODE_NULL
;
517 buffer
= ExAllocatePoolWithTag (PagedPool
, length
* sizeof(WCHAR
), 'IPCA');
520 status
= STATUS_INSUFFICIENT_RESOURCES
;
524 RtlCopyMemory (buffer
, temp
, length
* sizeof(WCHAR
));
525 Irp
->IoStatus
.Information
= (ULONG_PTR
) buffer
;
526 DPRINT("BusQueryHardwareIDs: %ls\n",buffer
);
530 status
= Irp
->IoStatus
.Status
;
536 Bus_PDO_QueryDeviceText(
537 PPDO_DEVICE_DATA DeviceData
,
541 PIO_STACK_LOCATION stack
;
545 stack
= IoGetCurrentIrpStackLocation (Irp
);
547 switch (stack
->Parameters
.QueryDeviceText
.DeviceTextType
) {
549 case DeviceTextDescription
:
551 if (!Irp
->IoStatus
.Information
) {
552 if (wcsstr (DeviceData
->HardwareIDs
, L
"PNP000") != 0)
553 Buffer
= L
"Programmable interrupt controller";
554 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP010") != 0)
555 Buffer
= L
"System timer";
556 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP020") != 0)
557 Buffer
= L
"DMA controller";
558 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP03") != 0)
559 Buffer
= L
"Keyboard";
560 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP040") != 0)
561 Buffer
= L
"Parallel port";
562 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP05") != 0)
563 Buffer
= L
"Serial port";
564 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP06") != 0)
565 Buffer
= L
"Disk controller";
566 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP07") != 0)
567 Buffer
= L
"Disk controller";
568 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP09") != 0)
569 Buffer
= L
"Display adapter";
570 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A0") != 0)
571 Buffer
= L
"Bus controller";
572 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0E0") != 0)
573 Buffer
= L
"PCMCIA controller";
574 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0F") != 0)
575 Buffer
= L
"Mouse device";
576 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP8") != 0)
577 Buffer
= L
"Network adapter";
578 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNPA0") != 0)
579 Buffer
= L
"SCSI controller";
580 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNPB0") != 0)
581 Buffer
= L
"Multimedia device";
582 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNPC00") != 0)
584 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0C") != 0)
585 Buffer
= L
"Power Button";
586 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0E") != 0)
587 Buffer
= L
"Sleep Button";
588 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0D") != 0)
589 Buffer
= L
"Lid Switch";
590 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C09") != 0)
591 Buffer
= L
"ACPI Embedded Controller";
592 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0B") != 0)
593 Buffer
= L
"ACPI Fan";
594 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A03") != 0)
595 Buffer
= L
"PCI Root Bridge";
596 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0A") != 0)
597 Buffer
= L
"ACPI Battery";
598 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0F") != 0)
599 Buffer
= L
"PCI Interrupt Link";
600 else if (wcsstr(DeviceData
->HardwareIDs
, L
"ACPI_PWR") != 0)
601 Buffer
= L
"ACPI Power Resource";
602 else if (wcsstr(DeviceData
->HardwareIDs
, L
"Processor") != 0)
603 Buffer
= L
"Processor";
604 else if (wcsstr(DeviceData
->HardwareIDs
, L
"ThermalZone") != 0)
605 Buffer
= L
"ACPI Thermal Zone";
606 else if (wcsstr(DeviceData
->HardwareIDs
, L
"ACPI0002") != 0)
607 Buffer
= L
"Smart Battery";
608 else if (wcsstr(DeviceData
->HardwareIDs
, L
"ACPI0003") != 0)
609 Buffer
= L
"AC Adapter";
610 /* Simply checking if AcpiHandle is NULL eliminates the need to check
611 * for the 4 different names that ACPI knows the fixed feature button as internally
613 else if (!DeviceData
->AcpiHandle
)
614 Buffer
= L
"ACPI Fixed Feature Button";
616 Buffer
= L
"Other ACPI device";
618 DPRINT("\tDeviceTextDescription :%ws\n", Buffer
);
620 Irp
->IoStatus
.Information
= (ULONG_PTR
) Buffer
;
622 status
= STATUS_SUCCESS
;
626 status
= Irp
->IoStatus
.Status
;
635 Bus_PDO_QueryResources(
636 PPDO_DEVICE_DATA DeviceData
,
639 ULONG NumberOfResources
= 0;
640 PCM_RESOURCE_LIST ResourceList
;
641 PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor
;
642 ACPI_STATUS AcpiStatus
;
644 ACPI_RESOURCE
* resource
;
645 ULONG ResourceListSize
;
649 /* A bus number resource is not included in the list of current resources
650 * for the root PCI bus so we manually query one here and if we find it
651 * we create a resource list and add a bus number descriptor to it */
652 AcpiStatus
= acpi_evaluate_integer(DeviceData
->AcpiHandle
, "_BBN", NULL
, &BusNumber
);
653 if (AcpiStatus
== AE_OK
)
655 DPRINT1("Found PCI root hub: %d\n", BusNumber
);
657 ResourceListSize
= sizeof(CM_RESOURCE_LIST
);
658 ResourceList
= (PCM_RESOURCE_LIST
)ExAllocatePool(PagedPool
, ResourceListSize
);
660 return STATUS_INSUFFICIENT_RESOURCES
;
662 ResourceList
->Count
= 1;
663 ResourceList
->List
[0].InterfaceType
= Internal
;
664 ResourceList
->List
[0].BusNumber
= 0;
665 ResourceList
->List
[0].PartialResourceList
.Version
= 1;
666 ResourceList
->List
[0].PartialResourceList
.Revision
= 1;
667 ResourceList
->List
[0].PartialResourceList
.Count
= 1;
668 ResourceDescriptor
= ResourceList
->List
[0].PartialResourceList
.PartialDescriptors
;
670 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
671 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
672 ResourceDescriptor
->u
.BusNumber
.Start
= BusNumber
;
673 ResourceDescriptor
->u
.BusNumber
.Length
= 1;
675 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
676 return STATUS_SUCCESS
;
679 /* Get current resources */
681 AcpiStatus
= AcpiGetCurrentResources(DeviceData
->AcpiHandle
, &Buffer
);
682 if ((!ACPI_SUCCESS(AcpiStatus
) && AcpiStatus
!= AE_BUFFER_OVERFLOW
) ||
685 return Irp
->IoStatus
.Status
;
688 Buffer
.Pointer
= ExAllocatePool(PagedPool
, Buffer
.Length
);
690 return STATUS_INSUFFICIENT_RESOURCES
;
692 AcpiStatus
= AcpiGetCurrentResources(DeviceData
->AcpiHandle
, &Buffer
);
693 if (!ACPI_SUCCESS(AcpiStatus
))
695 DPRINT1("AcpiGetCurrentResources #2 failed (0x%x)\n", AcpiStatus
);
697 return STATUS_UNSUCCESSFUL
;
700 resource
= Buffer
.Pointer
;
701 /* Count number of resources */
702 while (resource
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
)
704 switch (resource
->Type
)
706 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
708 ACPI_RESOURCE_EXTENDED_IRQ
*irq_data
= (ACPI_RESOURCE_EXTENDED_IRQ
*) &resource
->Data
;
709 NumberOfResources
+= irq_data
->InterruptCount
;
712 case ACPI_RESOURCE_TYPE_IRQ
:
714 ACPI_RESOURCE_IRQ
*irq_data
= (ACPI_RESOURCE_IRQ
*) &resource
->Data
;
715 NumberOfResources
+= irq_data
->InterruptCount
;
718 case ACPI_RESOURCE_TYPE_DMA
:
720 ACPI_RESOURCE_DMA
*dma_data
= (ACPI_RESOURCE_DMA
*) &resource
->Data
;
721 NumberOfResources
+= dma_data
->ChannelCount
;
724 case ACPI_RESOURCE_TYPE_ADDRESS16
:
725 case ACPI_RESOURCE_TYPE_ADDRESS32
:
726 case ACPI_RESOURCE_TYPE_ADDRESS64
:
727 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
728 case ACPI_RESOURCE_TYPE_MEMORY24
:
729 case ACPI_RESOURCE_TYPE_MEMORY32
:
730 case ACPI_RESOURCE_TYPE_IO
:
737 DPRINT1("Unknown resource type: %d\n", resource
->Type
);
741 resource
= ACPI_NEXT_RESOURCE(resource
);
744 /* Allocate memory */
745 ResourceListSize
= sizeof(CM_RESOURCE_LIST
) + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
) * (NumberOfResources
- 1);
746 ResourceList
= (PCM_RESOURCE_LIST
)ExAllocatePool(PagedPool
, ResourceListSize
);
750 ExFreePool(Buffer
.Pointer
);
751 return STATUS_INSUFFICIENT_RESOURCES
;
753 ResourceList
->Count
= 1;
754 ResourceList
->List
[0].InterfaceType
= Internal
; /* FIXME */
755 ResourceList
->List
[0].BusNumber
= 0; /* We're the only ACPI bus device in the system */
756 ResourceList
->List
[0].PartialResourceList
.Version
= 1;
757 ResourceList
->List
[0].PartialResourceList
.Revision
= 1;
758 ResourceList
->List
[0].PartialResourceList
.Count
= NumberOfResources
;
759 ResourceDescriptor
= ResourceList
->List
[0].PartialResourceList
.PartialDescriptors
;
761 /* Fill resources list structure */
762 resource
= Buffer
.Pointer
;
763 while (resource
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
)
765 switch (resource
->Type
)
767 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
769 ACPI_RESOURCE_EXTENDED_IRQ
*irq_data
= (ACPI_RESOURCE_EXTENDED_IRQ
*) &resource
->Data
;
770 for (i
= 0; i
< irq_data
->InterruptCount
; i
++)
772 ResourceDescriptor
->Type
= CmResourceTypeInterrupt
;
774 ResourceDescriptor
->ShareDisposition
=
775 (irq_data
->Sharable
== ACPI_SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
776 ResourceDescriptor
->Flags
=
777 (irq_data
->Triggering
== ACPI_LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
778 ResourceDescriptor
->u
.Interrupt
.Level
=
779 ResourceDescriptor
->u
.Interrupt
.Vector
= irq_data
->Interrupts
[i
];
780 ResourceDescriptor
->u
.Interrupt
.Affinity
= (KAFFINITY
)(-1);
782 ResourceDescriptor
++;
786 case ACPI_RESOURCE_TYPE_IRQ
:
788 ACPI_RESOURCE_IRQ
*irq_data
= (ACPI_RESOURCE_IRQ
*) &resource
->Data
;
789 for (i
= 0; i
< irq_data
->InterruptCount
; i
++)
791 ResourceDescriptor
->Type
= CmResourceTypeInterrupt
;
793 ResourceDescriptor
->ShareDisposition
=
794 (irq_data
->Sharable
== ACPI_SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
795 ResourceDescriptor
->Flags
=
796 (irq_data
->Triggering
== ACPI_LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
797 ResourceDescriptor
->u
.Interrupt
.Level
=
798 ResourceDescriptor
->u
.Interrupt
.Vector
= irq_data
->Interrupts
[i
];
799 ResourceDescriptor
->u
.Interrupt
.Affinity
= (KAFFINITY
)(-1);
801 ResourceDescriptor
++;
805 case ACPI_RESOURCE_TYPE_DMA
:
807 ACPI_RESOURCE_DMA
*dma_data
= (ACPI_RESOURCE_DMA
*) &resource
->Data
;
808 for (i
= 0; i
< dma_data
->ChannelCount
; i
++)
810 ResourceDescriptor
->Type
= CmResourceTypeDma
;
811 ResourceDescriptor
->Flags
= 0;
812 switch (dma_data
->Type
)
814 case ACPI_TYPE_A
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_A
; break;
815 case ACPI_TYPE_B
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_B
; break;
816 case ACPI_TYPE_F
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_F
; break;
818 if (dma_data
->BusMaster
== ACPI_BUS_MASTER
)
819 ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_BUS_MASTER
;
820 switch (dma_data
->Transfer
)
822 case ACPI_TRANSFER_8
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_8
; break;
823 case ACPI_TRANSFER_16
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_16
; break;
824 case ACPI_TRANSFER_8_16
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_8_AND_16
; break;
826 ResourceDescriptor
->u
.Dma
.Channel
= dma_data
->Channels
[i
];
828 ResourceDescriptor
++;
832 case ACPI_RESOURCE_TYPE_IO
:
834 ACPI_RESOURCE_IO
*io_data
= (ACPI_RESOURCE_IO
*) &resource
->Data
;
835 ResourceDescriptor
->Type
= CmResourceTypePort
;
836 ResourceDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
837 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
838 if (io_data
->IoDecode
== ACPI_DECODE_16
)
839 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_16_BIT_DECODE
;
841 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_10_BIT_DECODE
;
842 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= io_data
->Minimum
;
843 ResourceDescriptor
->u
.Port
.Length
= io_data
->AddressLength
;
845 ResourceDescriptor
++;
848 case ACPI_RESOURCE_TYPE_ADDRESS16
:
850 ACPI_RESOURCE_ADDRESS16
*addr16_data
= (ACPI_RESOURCE_ADDRESS16
*) &resource
->Data
;
851 if (addr16_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
853 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
854 ResourceDescriptor
->ShareDisposition
= CmResourceShareShared
;
855 ResourceDescriptor
->Flags
= 0;
856 ResourceDescriptor
->u
.BusNumber
.Start
= addr16_data
->Minimum
;
857 ResourceDescriptor
->u
.BusNumber
.Length
= addr16_data
->AddressLength
;
859 else if (addr16_data
->ResourceType
== ACPI_IO_RANGE
)
861 ResourceDescriptor
->Type
= CmResourceTypePort
;
862 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
863 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
864 if (addr16_data
->Decode
== ACPI_POS_DECODE
)
865 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
866 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= addr16_data
->Minimum
;
867 ResourceDescriptor
->u
.Port
.Length
= addr16_data
->AddressLength
;
871 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
872 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
873 ResourceDescriptor
->Flags
= 0;
874 if (addr16_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
875 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
877 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
878 switch (addr16_data
->Info
.Mem
.Caching
)
880 case ACPI_CACHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
881 case ACPI_WRITE_COMBINING_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
882 case ACPI_PREFETCHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
884 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= addr16_data
->Minimum
;
885 ResourceDescriptor
->u
.Memory
.Length
= addr16_data
->AddressLength
;
887 ResourceDescriptor
++;
890 case ACPI_RESOURCE_TYPE_ADDRESS32
:
892 ACPI_RESOURCE_ADDRESS32
*addr32_data
= (ACPI_RESOURCE_ADDRESS32
*) &resource
->Data
;
893 if (addr32_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
895 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
896 ResourceDescriptor
->ShareDisposition
= CmResourceShareShared
;
897 ResourceDescriptor
->Flags
= 0;
898 ResourceDescriptor
->u
.BusNumber
.Start
= addr32_data
->Minimum
;
899 ResourceDescriptor
->u
.BusNumber
.Length
= addr32_data
->AddressLength
;
901 else if (addr32_data
->ResourceType
== ACPI_IO_RANGE
)
903 ResourceDescriptor
->Type
= CmResourceTypePort
;
904 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
905 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
906 if (addr32_data
->Decode
== ACPI_POS_DECODE
)
907 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
908 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= addr32_data
->Minimum
;
909 ResourceDescriptor
->u
.Port
.Length
= addr32_data
->AddressLength
;
913 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
914 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
915 ResourceDescriptor
->Flags
= 0;
916 if (addr32_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
917 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
919 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
920 switch (addr32_data
->Info
.Mem
.Caching
)
922 case ACPI_CACHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
923 case ACPI_WRITE_COMBINING_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
924 case ACPI_PREFETCHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
926 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= addr32_data
->Minimum
;
927 ResourceDescriptor
->u
.Memory
.Length
= addr32_data
->AddressLength
;
929 ResourceDescriptor
++;
932 case ACPI_RESOURCE_TYPE_ADDRESS64
:
934 ACPI_RESOURCE_ADDRESS64
*addr64_data
= (ACPI_RESOURCE_ADDRESS64
*) &resource
->Data
;
935 if (addr64_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
937 DPRINT1("64-bit bus address is not supported!\n");
938 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
939 ResourceDescriptor
->ShareDisposition
= CmResourceShareShared
;
940 ResourceDescriptor
->Flags
= 0;
941 ResourceDescriptor
->u
.BusNumber
.Start
= (ULONG
)addr64_data
->Minimum
;
942 ResourceDescriptor
->u
.BusNumber
.Length
= addr64_data
->AddressLength
;
944 else if (addr64_data
->ResourceType
== ACPI_IO_RANGE
)
946 ResourceDescriptor
->Type
= CmResourceTypePort
;
947 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
948 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
949 if (addr64_data
->Decode
== ACPI_POS_DECODE
)
950 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
951 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= addr64_data
->Minimum
;
952 ResourceDescriptor
->u
.Port
.Length
= addr64_data
->AddressLength
;
956 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
957 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
958 ResourceDescriptor
->Flags
= 0;
959 if (addr64_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
960 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
962 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
963 switch (addr64_data
->Info
.Mem
.Caching
)
965 case ACPI_CACHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
966 case ACPI_WRITE_COMBINING_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
967 case ACPI_PREFETCHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
969 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= addr64_data
->Minimum
;
970 ResourceDescriptor
->u
.Memory
.Length
= addr64_data
->AddressLength
;
972 ResourceDescriptor
++;
975 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
977 ACPI_RESOURCE_EXTENDED_ADDRESS64
*addr64_data
= (ACPI_RESOURCE_EXTENDED_ADDRESS64
*) &resource
->Data
;
978 if (addr64_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
980 DPRINT1("64-bit bus address is not supported!\n");
981 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
982 ResourceDescriptor
->ShareDisposition
= CmResourceShareShared
;
983 ResourceDescriptor
->Flags
= 0;
984 ResourceDescriptor
->u
.BusNumber
.Start
= (ULONG
)addr64_data
->Minimum
;
985 ResourceDescriptor
->u
.BusNumber
.Length
= addr64_data
->AddressLength
;
987 else if (addr64_data
->ResourceType
== ACPI_IO_RANGE
)
989 ResourceDescriptor
->Type
= CmResourceTypePort
;
990 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
991 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
992 if (addr64_data
->Decode
== ACPI_POS_DECODE
)
993 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
994 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= addr64_data
->Minimum
;
995 ResourceDescriptor
->u
.Port
.Length
= addr64_data
->AddressLength
;
999 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1000 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1001 ResourceDescriptor
->Flags
= 0;
1002 if (addr64_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1003 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1005 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1006 switch (addr64_data
->Info
.Mem
.Caching
)
1008 case ACPI_CACHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1009 case ACPI_WRITE_COMBINING_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1010 case ACPI_PREFETCHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1012 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= addr64_data
->Minimum
;
1013 ResourceDescriptor
->u
.Memory
.Length
= addr64_data
->AddressLength
;
1015 ResourceDescriptor
++;
1018 case ACPI_RESOURCE_TYPE_MEMORY24
:
1020 ACPI_RESOURCE_MEMORY24
*mem24_data
= (ACPI_RESOURCE_MEMORY24
*) &resource
->Data
;
1021 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1022 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1023 ResourceDescriptor
->Flags
= CM_RESOURCE_MEMORY_24
;
1024 if (mem24_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1025 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1027 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1028 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= mem24_data
->Minimum
;
1029 ResourceDescriptor
->u
.Memory
.Length
= mem24_data
->AddressLength
;
1031 ResourceDescriptor
++;
1034 case ACPI_RESOURCE_TYPE_MEMORY32
:
1036 ACPI_RESOURCE_MEMORY32
*mem32_data
= (ACPI_RESOURCE_MEMORY32
*) &resource
->Data
;
1037 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1038 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1039 ResourceDescriptor
->Flags
= 0;
1040 if (mem32_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1041 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1043 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1044 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= mem32_data
->Minimum
;
1045 ResourceDescriptor
->u
.Memory
.Length
= mem32_data
->AddressLength
;
1047 ResourceDescriptor
++;
1055 resource
= ACPI_NEXT_RESOURCE(resource
);
1058 ExFreePool(Buffer
.Pointer
);
1059 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
1060 return STATUS_SUCCESS
;
1064 Bus_PDO_QueryResourceRequirements(
1065 PPDO_DEVICE_DATA DeviceData
,
1068 ULONG NumberOfResources
= 0;
1069 ACPI_STATUS AcpiStatus
;
1071 ACPI_RESOURCE
* resource
;
1072 ULONG i
, RequirementsListSize
;
1073 PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList
;
1074 PIO_RESOURCE_DESCRIPTOR RequirementDescriptor
;
1075 BOOLEAN CurrentRes
= FALSE
;
1080 /* Get current resources */
1085 AcpiStatus
= AcpiGetCurrentResources(DeviceData
->AcpiHandle
, &Buffer
);
1087 AcpiStatus
= AcpiGetPossibleResources(DeviceData
->AcpiHandle
, &Buffer
);
1088 if ((!ACPI_SUCCESS(AcpiStatus
) && AcpiStatus
!= AE_BUFFER_OVERFLOW
) ||
1094 return Irp
->IoStatus
.Status
;
1100 Buffer
.Pointer
= ExAllocatePool(PagedPool
, Buffer
.Length
);
1101 if (!Buffer
.Pointer
)
1102 return STATUS_INSUFFICIENT_RESOURCES
;
1105 AcpiStatus
= AcpiGetCurrentResources(DeviceData
->AcpiHandle
, &Buffer
);
1107 AcpiStatus
= AcpiGetPossibleResources(DeviceData
->AcpiHandle
, &Buffer
);
1108 if (!ACPI_SUCCESS(AcpiStatus
))
1110 DPRINT1("AcpiGetCurrentResources #2 failed (0x%x)\n", AcpiStatus
);
1112 return STATUS_UNSUCCESSFUL
;
1115 resource
= Buffer
.Pointer
;
1116 /* Count number of resources */
1117 while (resource
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
)
1119 switch (resource
->Type
)
1121 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
1123 ACPI_RESOURCE_EXTENDED_IRQ
*irq_data
= (ACPI_RESOURCE_EXTENDED_IRQ
*) &resource
->Data
;
1124 NumberOfResources
+= irq_data
->InterruptCount
;
1127 case ACPI_RESOURCE_TYPE_IRQ
:
1129 ACPI_RESOURCE_IRQ
*irq_data
= (ACPI_RESOURCE_IRQ
*) &resource
->Data
;
1130 NumberOfResources
+= irq_data
->InterruptCount
;
1133 case ACPI_RESOURCE_TYPE_DMA
:
1135 ACPI_RESOURCE_DMA
*dma_data
= (ACPI_RESOURCE_DMA
*) &resource
->Data
;
1136 NumberOfResources
+= dma_data
->ChannelCount
;
1139 case ACPI_RESOURCE_TYPE_ADDRESS16
:
1140 case ACPI_RESOURCE_TYPE_ADDRESS32
:
1141 case ACPI_RESOURCE_TYPE_ADDRESS64
:
1142 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
1143 case ACPI_RESOURCE_TYPE_MEMORY24
:
1144 case ACPI_RESOURCE_TYPE_MEMORY32
:
1145 case ACPI_RESOURCE_TYPE_IO
:
1147 NumberOfResources
++;
1155 resource
= ACPI_NEXT_RESOURCE(resource
);
1158 RequirementsListSize
= sizeof(IO_RESOURCE_REQUIREMENTS_LIST
) + sizeof(IO_RESOURCE_DESCRIPTOR
) * (NumberOfResources
- 1);
1159 RequirementsList
= (PIO_RESOURCE_REQUIREMENTS_LIST
)ExAllocatePool(PagedPool
, RequirementsListSize
);
1161 if (!RequirementsList
)
1163 ExFreePool(Buffer
.Pointer
);
1164 return STATUS_INSUFFICIENT_RESOURCES
;
1166 RequirementsList
->ListSize
= RequirementsListSize
;
1167 RequirementsList
->InterfaceType
= Internal
;
1168 RequirementsList
->BusNumber
= 0;
1169 RequirementsList
->SlotNumber
= 0; /* Not used by WDM drivers */
1170 RequirementsList
->AlternativeLists
= 1;
1171 RequirementsList
->List
[0].Version
= 1;
1172 RequirementsList
->List
[0].Revision
= 1;
1173 RequirementsList
->List
[0].Count
= NumberOfResources
;
1174 RequirementDescriptor
= RequirementsList
->List
[0].Descriptors
;
1176 /* Fill resources list structure */
1177 resource
= Buffer
.Pointer
;
1178 while (resource
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
)
1180 switch (resource
->Type
)
1182 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
1184 ACPI_RESOURCE_EXTENDED_IRQ
*irq_data
= (ACPI_RESOURCE_EXTENDED_IRQ
*) &resource
->Data
;
1185 for (i
= 0; i
< irq_data
->InterruptCount
; i
++)
1187 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1188 RequirementDescriptor
->Type
= CmResourceTypeInterrupt
;
1189 RequirementDescriptor
->ShareDisposition
= (irq_data
->Sharable
== ACPI_SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
1190 RequirementDescriptor
->Flags
=(irq_data
->Triggering
== ACPI_LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
1191 RequirementDescriptor
->u
.Interrupt
.MinimumVector
=
1192 RequirementDescriptor
->u
.Interrupt
.MaximumVector
= irq_data
->Interrupts
[i
];
1194 RequirementDescriptor
++;
1198 case ACPI_RESOURCE_TYPE_IRQ
:
1200 ACPI_RESOURCE_IRQ
*irq_data
= (ACPI_RESOURCE_IRQ
*) &resource
->Data
;
1201 for (i
= 0; i
< irq_data
->InterruptCount
; i
++)
1203 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1204 RequirementDescriptor
->Type
= CmResourceTypeInterrupt
;
1205 RequirementDescriptor
->ShareDisposition
= (irq_data
->Sharable
== ACPI_SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
1206 RequirementDescriptor
->Flags
=(irq_data
->Triggering
== ACPI_LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
1207 RequirementDescriptor
->u
.Interrupt
.MinimumVector
=
1208 RequirementDescriptor
->u
.Interrupt
.MaximumVector
= irq_data
->Interrupts
[i
];
1210 RequirementDescriptor
++;
1214 case ACPI_RESOURCE_TYPE_DMA
:
1216 ACPI_RESOURCE_DMA
*dma_data
= (ACPI_RESOURCE_DMA
*) &resource
->Data
;
1217 for (i
= 0; i
< dma_data
->ChannelCount
; i
++)
1219 RequirementDescriptor
->Type
= CmResourceTypeDma
;
1220 RequirementDescriptor
->Flags
= 0;
1221 switch (dma_data
->Type
)
1223 case ACPI_TYPE_A
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_A
; break;
1224 case ACPI_TYPE_B
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_B
; break;
1225 case ACPI_TYPE_F
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_F
; break;
1227 if (dma_data
->BusMaster
== ACPI_BUS_MASTER
)
1228 RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_BUS_MASTER
;
1229 switch (dma_data
->Transfer
)
1231 case ACPI_TRANSFER_8
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_8
; break;
1232 case ACPI_TRANSFER_16
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_16
; break;
1233 case ACPI_TRANSFER_8_16
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_8_AND_16
; break;
1236 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1237 RequirementDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
1238 RequirementDescriptor
->u
.Dma
.MinimumChannel
=
1239 RequirementDescriptor
->u
.Dma
.MaximumChannel
= dma_data
->Channels
[i
];
1240 RequirementDescriptor
++;
1244 case ACPI_RESOURCE_TYPE_IO
:
1246 ACPI_RESOURCE_IO
*io_data
= (ACPI_RESOURCE_IO
*) &resource
->Data
;
1247 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1248 if (io_data
->IoDecode
== ACPI_DECODE_16
)
1249 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_16_BIT_DECODE
;
1251 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_10_BIT_DECODE
;
1252 RequirementDescriptor
->u
.Port
.Length
= io_data
->AddressLength
;
1253 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1254 RequirementDescriptor
->Type
= CmResourceTypePort
;
1255 RequirementDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
1256 RequirementDescriptor
->u
.Port
.Alignment
= io_data
->Alignment
;
1257 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= io_data
->Minimum
;
1258 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= io_data
->Maximum
;
1260 RequirementDescriptor
++;
1263 case ACPI_RESOURCE_TYPE_ADDRESS16
:
1265 ACPI_RESOURCE_ADDRESS16
*addr16_data
= (ACPI_RESOURCE_ADDRESS16
*) &resource
->Data
;
1266 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1267 if (addr16_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1269 RequirementDescriptor
->Type
= CmResourceTypeBusNumber
;
1270 RequirementDescriptor
->ShareDisposition
= CmResourceShareShared
;
1271 RequirementDescriptor
->Flags
= 0;
1272 RequirementDescriptor
->u
.BusNumber
.MinBusNumber
= addr16_data
->Minimum
;
1273 RequirementDescriptor
->u
.BusNumber
.MaxBusNumber
= addr16_data
->Maximum
;
1274 RequirementDescriptor
->u
.BusNumber
.Length
= addr16_data
->AddressLength
;
1276 else if (addr16_data
->ResourceType
== ACPI_IO_RANGE
)
1278 RequirementDescriptor
->Type
= CmResourceTypePort
;
1279 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1280 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1281 if (addr16_data
->Decode
== ACPI_POS_DECODE
)
1282 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1283 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= addr16_data
->Minimum
;
1284 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= addr16_data
->Maximum
;
1285 RequirementDescriptor
->u
.Port
.Length
= addr16_data
->AddressLength
;
1289 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1290 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1291 RequirementDescriptor
->Flags
= 0;
1292 if (addr16_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1293 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1295 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1296 switch (addr16_data
->Info
.Mem
.Caching
)
1298 case ACPI_CACHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1299 case ACPI_WRITE_COMBINING_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1300 case ACPI_PREFETCHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1302 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= addr16_data
->Minimum
;
1303 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= addr16_data
->Maximum
;
1304 RequirementDescriptor
->u
.Memory
.Length
= addr16_data
->AddressLength
;
1306 RequirementDescriptor
++;
1309 case ACPI_RESOURCE_TYPE_ADDRESS32
:
1311 ACPI_RESOURCE_ADDRESS32
*addr32_data
= (ACPI_RESOURCE_ADDRESS32
*) &resource
->Data
;
1312 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1313 if (addr32_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1315 RequirementDescriptor
->Type
= CmResourceTypeBusNumber
;
1316 RequirementDescriptor
->ShareDisposition
= CmResourceShareShared
;
1317 RequirementDescriptor
->Flags
= 0;
1318 RequirementDescriptor
->u
.BusNumber
.MinBusNumber
= addr32_data
->Minimum
;
1319 RequirementDescriptor
->u
.BusNumber
.MaxBusNumber
= addr32_data
->Maximum
;
1320 RequirementDescriptor
->u
.BusNumber
.Length
= addr32_data
->AddressLength
;
1322 else if (addr32_data
->ResourceType
== ACPI_IO_RANGE
)
1324 RequirementDescriptor
->Type
= CmResourceTypePort
;
1325 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1326 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1327 if (addr32_data
->Decode
== ACPI_POS_DECODE
)
1328 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1329 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= addr32_data
->Minimum
;
1330 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= addr32_data
->Maximum
;
1331 RequirementDescriptor
->u
.Port
.Length
= addr32_data
->AddressLength
;
1335 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1336 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1337 RequirementDescriptor
->Flags
= 0;
1338 if (addr32_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1339 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1341 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1342 switch (addr32_data
->Info
.Mem
.Caching
)
1344 case ACPI_CACHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1345 case ACPI_WRITE_COMBINING_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1346 case ACPI_PREFETCHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1348 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= addr32_data
->Minimum
;
1349 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= addr32_data
->Maximum
;
1350 RequirementDescriptor
->u
.Memory
.Length
= addr32_data
->AddressLength
;
1352 RequirementDescriptor
++;
1355 case ACPI_RESOURCE_TYPE_ADDRESS64
:
1357 ACPI_RESOURCE_ADDRESS64
*addr64_data
= (ACPI_RESOURCE_ADDRESS64
*) &resource
->Data
;
1358 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1359 if (addr64_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1361 DPRINT1("64-bit bus address is not supported!\n");
1362 RequirementDescriptor
->Type
= CmResourceTypeBusNumber
;
1363 RequirementDescriptor
->ShareDisposition
= CmResourceShareShared
;
1364 RequirementDescriptor
->Flags
= 0;
1365 RequirementDescriptor
->u
.BusNumber
.MinBusNumber
= (ULONG
)addr64_data
->Minimum
;
1366 RequirementDescriptor
->u
.BusNumber
.MaxBusNumber
= (ULONG
)addr64_data
->Maximum
;
1367 RequirementDescriptor
->u
.BusNumber
.Length
= addr64_data
->AddressLength
;
1369 else if (addr64_data
->ResourceType
== ACPI_IO_RANGE
)
1371 RequirementDescriptor
->Type
= CmResourceTypePort
;
1372 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1373 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1374 if (addr64_data
->Decode
== ACPI_POS_DECODE
)
1375 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1376 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= addr64_data
->Minimum
;
1377 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= addr64_data
->Maximum
;
1378 RequirementDescriptor
->u
.Port
.Length
= addr64_data
->AddressLength
;
1382 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1383 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1384 RequirementDescriptor
->Flags
= 0;
1385 if (addr64_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1386 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1388 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1389 switch (addr64_data
->Info
.Mem
.Caching
)
1391 case ACPI_CACHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1392 case ACPI_WRITE_COMBINING_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1393 case ACPI_PREFETCHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1395 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= addr64_data
->Minimum
;
1396 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= addr64_data
->Maximum
;
1397 RequirementDescriptor
->u
.Memory
.Length
= addr64_data
->AddressLength
;
1399 RequirementDescriptor
++;
1402 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
1404 ACPI_RESOURCE_EXTENDED_ADDRESS64
*addr64_data
= (ACPI_RESOURCE_EXTENDED_ADDRESS64
*) &resource
->Data
;
1405 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1406 if (addr64_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1408 DPRINT1("64-bit bus address is not supported!\n");
1409 RequirementDescriptor
->Type
= CmResourceTypeBusNumber
;
1410 RequirementDescriptor
->ShareDisposition
= CmResourceShareShared
;
1411 RequirementDescriptor
->Flags
= 0;
1412 RequirementDescriptor
->u
.BusNumber
.MinBusNumber
= (ULONG
)addr64_data
->Minimum
;
1413 RequirementDescriptor
->u
.BusNumber
.MaxBusNumber
= (ULONG
)addr64_data
->Maximum
;
1414 RequirementDescriptor
->u
.BusNumber
.Length
= addr64_data
->AddressLength
;
1416 else if (addr64_data
->ResourceType
== ACPI_IO_RANGE
)
1418 RequirementDescriptor
->Type
= CmResourceTypePort
;
1419 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1420 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1421 if (addr64_data
->Decode
== ACPI_POS_DECODE
)
1422 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1423 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= addr64_data
->Minimum
;
1424 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= addr64_data
->Maximum
;
1425 RequirementDescriptor
->u
.Port
.Length
= addr64_data
->AddressLength
;
1429 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1430 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1431 RequirementDescriptor
->Flags
= 0;
1432 if (addr64_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1433 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1435 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1436 switch (addr64_data
->Info
.Mem
.Caching
)
1438 case ACPI_CACHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1439 case ACPI_WRITE_COMBINING_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1440 case ACPI_PREFETCHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1442 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= addr64_data
->Minimum
;
1443 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= addr64_data
->Maximum
;
1444 RequirementDescriptor
->u
.Memory
.Length
= addr64_data
->AddressLength
;
1446 RequirementDescriptor
++;
1449 case ACPI_RESOURCE_TYPE_MEMORY24
:
1451 ACPI_RESOURCE_MEMORY24
*mem24_data
= (ACPI_RESOURCE_MEMORY24
*) &resource
->Data
;
1452 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1453 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1454 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1455 RequirementDescriptor
->Flags
= CM_RESOURCE_MEMORY_24
;
1456 if (mem24_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1457 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1459 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1460 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= mem24_data
->Minimum
;
1461 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= mem24_data
->Maximum
;
1462 RequirementDescriptor
->u
.Memory
.Length
= mem24_data
->AddressLength
;
1464 RequirementDescriptor
++;
1467 case ACPI_RESOURCE_TYPE_MEMORY32
:
1469 ACPI_RESOURCE_MEMORY32
*mem32_data
= (ACPI_RESOURCE_MEMORY32
*) &resource
->Data
;
1470 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1471 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1472 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1473 RequirementDescriptor
->Flags
= 0;
1474 if (mem32_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1475 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1477 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1478 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= mem32_data
->Minimum
;
1479 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= mem32_data
->Maximum
;
1480 RequirementDescriptor
->u
.Memory
.Length
= mem32_data
->AddressLength
;
1482 RequirementDescriptor
++;
1490 resource
= ACPI_NEXT_RESOURCE(resource
);
1492 ExFreePool(Buffer
.Pointer
);
1494 Irp
->IoStatus
.Information
= (ULONG_PTR
)RequirementsList
;
1496 return STATUS_SUCCESS
;
1500 Bus_PDO_QueryDeviceRelations(
1501 PPDO_DEVICE_DATA DeviceData
,
1505 Routine Description:
1507 The PnP Manager sends this IRP to gather information about
1508 devices with a relationship to the specified device.
1509 Bus drivers must handle this request for TargetDeviceRelation
1510 for their child devices (child PDOs).
1512 If a driver returns relations in response to this IRP,
1513 it allocates a DEVICE_RELATIONS structure from paged
1514 memory containing a count and the appropriate number of
1515 device object pointers. The PnP Manager frees the structure
1516 when it is no longer needed. If a driver replaces a
1517 DEVICE_RELATIONS structure allocated by another driver,
1518 it must free the previous structure.
1520 A driver must reference the PDO of any device that it
1521 reports in this IRP (ObReferenceObject). The PnP Manager
1522 removes the reference when appropriate.
1526 DeviceData - Pointer to the PDO's device extension.
1527 Irp - Pointer to the irp.
1536 PIO_STACK_LOCATION stack
;
1537 PDEVICE_RELATIONS deviceRelations
;
1542 stack
= IoGetCurrentIrpStackLocation (Irp
);
1544 switch (stack
->Parameters
.QueryDeviceRelations
.Type
) {
1546 case TargetDeviceRelation
:
1548 deviceRelations
= (PDEVICE_RELATIONS
) Irp
->IoStatus
.Information
;
1549 if (deviceRelations
) {
1551 // Only PDO can handle this request. Somebody above
1552 // is not playing by rule.
1554 ASSERTMSG("Someone above is handling TargetDeviceRelation", !deviceRelations
);
1557 deviceRelations
= (PDEVICE_RELATIONS
)
1558 ExAllocatePoolWithTag (PagedPool
,
1559 sizeof(DEVICE_RELATIONS
),
1561 if (!deviceRelations
) {
1562 status
= STATUS_INSUFFICIENT_RESOURCES
;
1567 // There is only one PDO pointer in the structure
1568 // for this relation type. The PnP Manager removes
1569 // the reference to the PDO when the driver or application
1570 // un-registers for notification on the device.
1573 deviceRelations
->Count
= 1;
1574 deviceRelations
->Objects
[0] = DeviceData
->Common
.Self
;
1575 ObReferenceObject(DeviceData
->Common
.Self
);
1577 status
= STATUS_SUCCESS
;
1578 Irp
->IoStatus
.Information
= (ULONG_PTR
) deviceRelations
;
1581 case BusRelations
: // Not handled by PDO
1582 case EjectionRelations
: // optional for PDO
1583 case RemovalRelations
: // // optional for PDO
1585 status
= Irp
->IoStatus
.Status
;
1592 Bus_PDO_QueryBusInformation(
1593 PPDO_DEVICE_DATA DeviceData
,
1597 Routine Description:
1599 The PnP Manager uses this IRP to request the type and
1600 instance number of a device's parent bus. Bus drivers
1601 should handle this request for their child devices (PDOs).
1605 DeviceData - Pointer to the PDO's device extension.
1606 Irp - Pointer to the irp.
1615 PPNP_BUS_INFORMATION busInfo
;
1619 busInfo
= ExAllocatePoolWithTag (PagedPool
, sizeof(PNP_BUS_INFORMATION
),
1622 if (busInfo
== NULL
) {
1623 return STATUS_INSUFFICIENT_RESOURCES
;
1626 busInfo
->BusTypeGuid
= GUID_ACPI_INTERFACE_STANDARD
;
1628 busInfo
->LegacyBusType
= InternalPowerBus
;
1630 busInfo
->BusNumber
= 0; //fixme
1632 Irp
->IoStatus
.Information
= (ULONG_PTR
)busInfo
;
1634 return STATUS_SUCCESS
;
1639 Bus_GetDeviceCapabilities(
1640 PDEVICE_OBJECT DeviceObject
,
1641 PDEVICE_CAPABILITIES DeviceCapabilities
1644 IO_STATUS_BLOCK ioStatus
;
1647 PDEVICE_OBJECT targetObject
;
1648 PIO_STACK_LOCATION irpStack
;
1654 // Initialize the capabilities that we will send down
1656 RtlZeroMemory( DeviceCapabilities
, sizeof(DEVICE_CAPABILITIES
) );
1657 DeviceCapabilities
->Size
= sizeof(DEVICE_CAPABILITIES
);
1658 DeviceCapabilities
->Version
= 1;
1659 DeviceCapabilities
->Address
= -1;
1660 DeviceCapabilities
->UINumber
= -1;
1663 // Initialize the event
1665 KeInitializeEvent( &pnpEvent
, NotificationEvent
, FALSE
);
1667 targetObject
= IoGetAttachedDeviceReference( DeviceObject
);
1672 pnpIrp
= IoBuildSynchronousFsdRequest(
1681 if (pnpIrp
== NULL
) {
1683 status
= STATUS_INSUFFICIENT_RESOURCES
;
1684 goto GetDeviceCapabilitiesExit
;
1689 // Pnp Irps all begin life as STATUS_NOT_SUPPORTED;
1691 pnpIrp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
1694 // Get the top of stack
1696 irpStack
= IoGetNextIrpStackLocation( pnpIrp
);
1699 // Set the top of stack
1701 RtlZeroMemory( irpStack
, sizeof(IO_STACK_LOCATION
) );
1702 irpStack
->MajorFunction
= IRP_MJ_PNP
;
1703 irpStack
->MinorFunction
= IRP_MN_QUERY_CAPABILITIES
;
1704 irpStack
->Parameters
.DeviceCapabilities
.Capabilities
= DeviceCapabilities
;
1709 status
= IoCallDriver( targetObject
, pnpIrp
);
1710 if (status
== STATUS_PENDING
) {
1713 // Block until the irp comes back.
1714 // Important thing to note here is when you allocate
1715 // the memory for an event in the stack you must do a
1716 // KernelMode wait instead of UserMode to prevent
1717 // the stack from getting paged out.
1720 KeWaitForSingleObject(
1727 status
= ioStatus
.Status
;
1731 GetDeviceCapabilitiesExit
:
1733 // Done with reference
1735 ObDereferenceObject( targetObject
);