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;
69 status
= STATUS_SUCCESS
;
73 status
= IoRegisterDeviceInterface(DeviceData
->Common
.Self
,
74 &GUID_DEVICE_SYS_BUTTON
,
76 &DeviceData
->InterfaceName
);
78 else if (device
->flags
.hardware_id
&&
79 strstr(device
->pnp
.hardware_id
, ACPI_THERMAL_HID
))
81 status
= IoRegisterDeviceInterface(DeviceData
->Common
.Self
,
82 &GUID_DEVICE_THERMAL_ZONE
,
84 &DeviceData
->InterfaceName
);
86 else if (device
->flags
.hardware_id
&&
87 strstr(device
->pnp
.hardware_id
, ACPI_BUTTON_HID_LID
))
89 status
= IoRegisterDeviceInterface(DeviceData
->Common
.Self
,
92 &DeviceData
->InterfaceName
);
94 else if (device
->flags
.hardware_id
&&
95 strstr(device
->pnp
.hardware_id
, ACPI_PROCESSOR_HID
))
97 status
= IoRegisterDeviceInterface(DeviceData
->Common
.Self
,
98 &GUID_DEVICE_PROCESSOR
,
100 &DeviceData
->InterfaceName
);
103 /* Failure to register an interface is not a fatal failure so don't return a failure status */
104 if (NT_SUCCESS(status
) && DeviceData
->InterfaceName
.Length
!= 0)
105 IoSetDeviceInterfaceState(&DeviceData
->InterfaceName
, TRUE
);
107 state
.DeviceState
= PowerDeviceD0
;
108 PoSetPowerState(DeviceData
->Common
.Self
, DevicePowerState
, state
);
109 DeviceData
->Common
.DevicePowerState
= PowerDeviceD0
;
110 SET_NEW_PNP_STATE(DeviceData
->Common
, Started
);
111 status
= STATUS_SUCCESS
;
114 case IRP_MN_STOP_DEVICE
:
116 if (DeviceData
->InterfaceName
.Length
!= 0)
117 IoSetDeviceInterfaceState(&DeviceData
->InterfaceName
, FALSE
);
120 // Here we shut down the device and give up and unmap any resources
121 // we acquired for the device.
123 if (DeviceData
->AcpiHandle
&& acpi_bus_power_manageable(DeviceData
->AcpiHandle
) &&
124 !ACPI_SUCCESS(acpi_bus_set_power(DeviceData
->AcpiHandle
, ACPI_STATE_D3
)))
126 DPRINT1("Device %x failed to stop!\n", DeviceData
->AcpiHandle
);
127 status
= STATUS_UNSUCCESSFUL
;
131 state
.DeviceState
= PowerDeviceD3
;
132 PoSetPowerState(DeviceData
->Common
.Self
, DevicePowerState
, state
);
133 DeviceData
->Common
.DevicePowerState
= PowerDeviceD3
;
134 SET_NEW_PNP_STATE(DeviceData
->Common
, Stopped
);
135 status
= STATUS_SUCCESS
;
139 case IRP_MN_QUERY_STOP_DEVICE
:
142 // No reason here why we can't stop the device.
143 // If there were a reason we should speak now, because answering success
144 // here may result in a stop device irp.
147 SET_NEW_PNP_STATE(DeviceData
->Common
, StopPending
);
148 status
= STATUS_SUCCESS
;
151 case IRP_MN_CANCEL_STOP_DEVICE
:
154 // The stop was canceled. Whatever state we set, or resources we put
155 // on hold in anticipation of the forthcoming STOP device IRP should be
156 // put back to normal. Someone, in the long list of concerned parties,
157 // has failed the stop device query.
161 // First check to see whether you have received cancel-stop
162 // without first receiving a query-stop. This could happen if someone
163 // above us fails a query-stop and passes down the subsequent
167 if (StopPending
== DeviceData
->Common
.DevicePnPState
)
170 // We did receive a query-stop, so restore.
172 RESTORE_PREVIOUS_PNP_STATE(DeviceData
->Common
);
174 status
= STATUS_SUCCESS
;// We must not fail this IRP.
176 case IRP_MN_QUERY_CAPABILITIES
:
179 // Return the capabilities of a device, such as whether the device
180 // can be locked or ejected..etc
183 status
= Bus_PDO_QueryDeviceCaps(DeviceData
, Irp
);
187 case IRP_MN_QUERY_ID
:
189 // Query the IDs of the device
190 status
= Bus_PDO_QueryDeviceId(DeviceData
, Irp
);
194 case IRP_MN_QUERY_DEVICE_RELATIONS
:
196 DPRINT("\tQueryDeviceRelation Type: %s\n",DbgDeviceRelationString(\
197 IrpStack
->Parameters
.QueryDeviceRelations
.Type
));
199 status
= Bus_PDO_QueryDeviceRelations(DeviceData
, Irp
);
203 case IRP_MN_QUERY_DEVICE_TEXT
:
205 status
= Bus_PDO_QueryDeviceText(DeviceData
, Irp
);
209 case IRP_MN_QUERY_RESOURCES
:
211 status
= Bus_PDO_QueryResources(DeviceData
, Irp
);
215 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
217 status
= Bus_PDO_QueryResourceRequirements(DeviceData
, Irp
);
221 case IRP_MN_QUERY_BUS_INFORMATION
:
223 status
= Bus_PDO_QueryBusInformation(DeviceData
, Irp
);
227 case IRP_MN_QUERY_INTERFACE
:
229 status
= Bus_PDO_QueryInterface(DeviceData
, Irp
);
234 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
237 // OPTIONAL for bus drivers.
238 // The PnP Manager sends this IRP to a device
239 // stack so filter and function drivers can adjust the
240 // resources required by the device, if appropriate.
245 //case IRP_MN_QUERY_PNP_DEVICE_STATE:
248 // OPTIONAL for bus drivers.
249 // The PnP Manager sends this IRP after the drivers for
250 // a device return success from the IRP_MN_START_DEVICE
251 // request. The PnP Manager also sends this IRP when a
252 // driver for the device calls IoInvalidateDeviceState.
257 //case IRP_MN_READ_CONFIG:
258 //case IRP_MN_WRITE_CONFIG:
261 // Bus drivers for buses with configuration space must handle
262 // this request for their child devices. Our devices don't
263 // have a config space.
268 //case IRP_MN_SET_LOCK:
275 // For PnP requests to the PDO that we do not understand we should
276 // return the IRP WITHOUT setting the status or information fields.
277 // These fields may have already been set by a filter (eg acpi).
278 status
= Irp
->IoStatus
.Status
;
283 Irp
->IoStatus
.Status
= status
;
284 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
290 Bus_PDO_QueryDeviceCaps(
291 PPDO_DEVICE_DATA DeviceData
,
295 PIO_STACK_LOCATION stack
;
296 PDEVICE_CAPABILITIES deviceCapabilities
;
297 struct acpi_device
*device
= NULL
;
302 if (DeviceData
->AcpiHandle
)
303 acpi_bus_get_device(DeviceData
->AcpiHandle
, &device
);
305 stack
= IoGetCurrentIrpStackLocation (Irp
);
310 deviceCapabilities
=stack
->Parameters
.DeviceCapabilities
.Capabilities
;
313 // Set the capabilities.
316 if (deviceCapabilities
->Version
!= 1 ||
317 deviceCapabilities
->Size
< sizeof(DEVICE_CAPABILITIES
))
319 return STATUS_UNSUCCESSFUL
;
322 deviceCapabilities
->D1Latency
= 0;
323 deviceCapabilities
->D2Latency
= 0;
324 deviceCapabilities
->D3Latency
= 0;
326 deviceCapabilities
->DeviceState
[PowerSystemWorking
] = PowerDeviceD0
;
327 deviceCapabilities
->DeviceState
[PowerSystemSleeping1
] = PowerDeviceD3
;
328 deviceCapabilities
->DeviceState
[PowerSystemSleeping2
] = PowerDeviceD3
;
329 deviceCapabilities
->DeviceState
[PowerSystemSleeping3
] = PowerDeviceD3
;
331 for (i
= 0; i
< ACPI_D_STATE_COUNT
&& device
; i
++)
333 if (!device
->power
.states
[i
].flags
.valid
)
339 deviceCapabilities
->DeviceState
[PowerSystemWorking
] = PowerDeviceD0
;
343 deviceCapabilities
->DeviceState
[PowerSystemSleeping1
] = PowerDeviceD1
;
344 deviceCapabilities
->D1Latency
= device
->power
.states
[i
].latency
;
348 deviceCapabilities
->DeviceState
[PowerSystemSleeping2
] = PowerDeviceD2
;
349 deviceCapabilities
->D2Latency
= device
->power
.states
[i
].latency
;
353 deviceCapabilities
->DeviceState
[PowerSystemSleeping3
] = PowerDeviceD3
;
354 deviceCapabilities
->D3Latency
= device
->power
.states
[i
].latency
;
359 // We can wake the system from D1
360 deviceCapabilities
->DeviceWake
= PowerDeviceD1
;
363 deviceCapabilities
->DeviceD1
=
364 (deviceCapabilities
->DeviceState
[PowerSystemSleeping1
] == PowerDeviceD1
) ? TRUE
: FALSE
;
365 deviceCapabilities
->DeviceD2
=
366 (deviceCapabilities
->DeviceState
[PowerSystemSleeping2
] == PowerDeviceD2
) ? TRUE
: FALSE
;
368 deviceCapabilities
->WakeFromD0
= FALSE
;
369 deviceCapabilities
->WakeFromD1
= TRUE
; //Yes we can
370 deviceCapabilities
->WakeFromD2
= FALSE
;
371 deviceCapabilities
->WakeFromD3
= FALSE
;
375 deviceCapabilities
->EjectSupported
= device
->flags
.ejectable
;
376 deviceCapabilities
->HardwareDisabled
= !device
->status
.enabled
;
377 deviceCapabilities
->Removable
= device
->flags
.removable
;
378 deviceCapabilities
->SurpriseRemovalOK
= device
->flags
.suprise_removal_ok
;
379 deviceCapabilities
->UniqueID
= device
->flags
.unique_id
;
380 deviceCapabilities
->NoDisplayInUI
= !device
->status
.show_in_ui
;
381 deviceCapabilities
->Address
= device
->pnp
.bus_address
;
385 (device
->flags
.hardware_id
&&
386 (strstr(device
->pnp
.hardware_id
, ACPI_BUTTON_HID_LID
) ||
387 strstr(device
->pnp
.hardware_id
, ACPI_THERMAL_HID
) ||
388 strstr(device
->pnp
.hardware_id
, ACPI_PROCESSOR_HID
))))
390 /* Allow ACPI to control the device if it is a lid button,
391 * a thermal zone, a processor, or a fixed feature button */
392 deviceCapabilities
->RawDeviceOK
= TRUE
;
395 deviceCapabilities
->SilentInstall
= FALSE
;
396 deviceCapabilities
->UINumber
= (ULONG
)-1;
398 return STATUS_SUCCESS
;
403 Bus_PDO_QueryDeviceId(
404 PPDO_DEVICE_DATA DeviceData
,
407 PIO_STACK_LOCATION stack
;
411 NTSTATUS status
= STATUS_SUCCESS
;
412 struct acpi_device
*Device
;
416 stack
= IoGetCurrentIrpStackLocation (Irp
);
418 switch (stack
->Parameters
.QueryId
.IdType
) {
420 case BusQueryDeviceID
:
421 if (DeviceData
->AcpiHandle
)
423 acpi_bus_get_device(DeviceData
->AcpiHandle
, &Device
);
425 length
= swprintf(temp
,
427 Device
->pnp
.hardware_id
);
431 /* We know it's a fixed feature button because
432 * these are direct children of the ACPI root device
433 * and therefore have no handle
435 length
= swprintf(temp
,
436 L
"ACPI\\FixedButton");
439 temp
[++length
] = UNICODE_NULL
;
441 buffer
= ExAllocatePoolWithTag (PagedPool
, length
* sizeof(WCHAR
), 'IPCA');
444 status
= STATUS_INSUFFICIENT_RESOURCES
;
448 RtlCopyMemory (buffer
, temp
, length
* sizeof(WCHAR
));
449 Irp
->IoStatus
.Information
= (ULONG_PTR
) buffer
;
450 DPRINT("BusQueryDeviceID: %ls\n",buffer
);
453 case BusQueryInstanceID
:
454 /* See comment in BusQueryDeviceID case */
455 if(DeviceData
->AcpiHandle
)
457 acpi_bus_get_device(DeviceData
->AcpiHandle
, &Device
);
459 if (Device
->flags
.unique_id
)
460 length
= swprintf(temp
,
462 Device
->pnp
.unique_id
);
464 /* FIXME: Generate unique id! */
465 length
= swprintf(temp
, L
"%ls", L
"0000");
468 /* FIXME: Generate unique id! */
469 length
= swprintf(temp
, L
"%ls", L
"0000");
471 temp
[++length
] = UNICODE_NULL
;
473 buffer
= ExAllocatePoolWithTag (PagedPool
, length
* sizeof (WCHAR
), 'IPCA');
475 status
= STATUS_INSUFFICIENT_RESOURCES
;
479 RtlCopyMemory (buffer
, temp
, length
* sizeof (WCHAR
));
480 DPRINT("BusQueryInstanceID: %ls\n",buffer
);
481 Irp
->IoStatus
.Information
= (ULONG_PTR
) buffer
;
484 case BusQueryHardwareIDs
:
487 /* See comment in BusQueryDeviceID case */
488 if (DeviceData
->AcpiHandle
)
490 acpi_bus_get_device(DeviceData
->AcpiHandle
, &Device
);
492 length
+= swprintf(&temp
[length
],
494 Device
->pnp
.hardware_id
);
497 length
+= swprintf(&temp
[length
],
499 Device
->pnp
.hardware_id
);
504 length
+= swprintf(&temp
[length
],
505 L
"ACPI\\FixedButton");
508 length
+= swprintf(&temp
[length
],
513 temp
[length
] = UNICODE_NULL
;
517 temp
[length
] = UNICODE_NULL
;
519 buffer
= ExAllocatePoolWithTag (PagedPool
, length
* sizeof(WCHAR
), 'IPCA');
522 status
= STATUS_INSUFFICIENT_RESOURCES
;
526 RtlCopyMemory (buffer
, temp
, length
* sizeof(WCHAR
));
527 Irp
->IoStatus
.Information
= (ULONG_PTR
) buffer
;
528 DPRINT("BusQueryHardwareIDs: %ls\n",buffer
);
532 status
= Irp
->IoStatus
.Status
;
538 Bus_PDO_QueryDeviceText(
539 PPDO_DEVICE_DATA DeviceData
,
543 PIO_STACK_LOCATION stack
;
544 NTSTATUS status
= Irp
->IoStatus
.Status
;
547 stack
= IoGetCurrentIrpStackLocation (Irp
);
549 switch (stack
->Parameters
.QueryDeviceText
.DeviceTextType
) {
551 case DeviceTextDescription
:
553 if (!Irp
->IoStatus
.Information
) {
554 if (wcsstr (DeviceData
->HardwareIDs
, L
"PNP000") != 0)
555 Temp
= L
"Programmable interrupt controller";
556 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP010") != 0)
557 Temp
= L
"System timer";
558 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP020") != 0)
559 Temp
= L
"DMA controller";
560 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP03") != 0)
562 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP040") != 0)
563 Temp
= L
"Parallel port";
564 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP05") != 0)
565 Temp
= L
"Serial port";
566 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP06") != 0)
567 Temp
= L
"Disk controller";
568 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP07") != 0)
569 Temp
= L
"Disk controller";
570 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP09") != 0)
571 Temp
= L
"Display adapter";
572 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A0") != 0)
573 Temp
= L
"Bus controller";
574 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0E0") != 0)
575 Temp
= L
"PCMCIA controller";
576 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0F") != 0)
577 Temp
= L
"Mouse device";
578 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP8") != 0)
579 Temp
= L
"Network adapter";
580 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNPA0") != 0)
581 Temp
= L
"SCSI controller";
582 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNPB0") != 0)
583 Temp
= L
"Multimedia device";
584 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNPC00") != 0)
586 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0C") != 0)
587 Temp
= L
"Power Button";
588 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0E") != 0)
589 Temp
= L
"Sleep Button";
590 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0D") != 0)
591 Temp
= L
"Lid Switch";
592 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C09") != 0)
593 Temp
= L
"ACPI Embedded Controller";
594 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0B") != 0)
596 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A03") != 0)
597 Temp
= L
"PCI Root Bridge";
598 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0A") != 0)
599 Temp
= L
"ACPI Battery";
600 else if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0C0F") != 0)
601 Temp
= L
"PCI Interrupt Link";
602 else if (wcsstr(DeviceData
->HardwareIDs
, L
"ACPI_PWR") != 0)
603 Temp
= L
"ACPI Power Resource";
604 else if (wcsstr(DeviceData
->HardwareIDs
, L
"Processor") != 0)
606 else if (wcsstr(DeviceData
->HardwareIDs
, L
"ThermalZone") != 0)
607 Temp
= L
"ACPI Thermal Zone";
608 else if (wcsstr(DeviceData
->HardwareIDs
, L
"ACPI0002") != 0)
609 Temp
= L
"Smart Battery";
610 else if (wcsstr(DeviceData
->HardwareIDs
, L
"ACPI0003") != 0)
611 Temp
= L
"AC Adapter";
612 /* Simply checking if AcpiHandle is NULL eliminates the need to check
613 * for the 4 different names that ACPI knows the fixed feature button as internally
615 else if (!DeviceData
->AcpiHandle
)
616 Temp
= L
"ACPI Fixed Feature Button";
618 Temp
= L
"Other ACPI device";
620 Buffer
= ExAllocatePoolWithTag (PagedPool
, (wcslen(Temp
) + 1) * sizeof(WCHAR
), 'IPCA');
623 status
= STATUS_INSUFFICIENT_RESOURCES
;
627 RtlCopyMemory (Buffer
, Temp
, (wcslen(Temp
) + 1) * sizeof(WCHAR
));
629 DPRINT("\tDeviceTextDescription :%ws\n", Buffer
);
631 Irp
->IoStatus
.Information
= (ULONG_PTR
) Buffer
;
632 status
= STATUS_SUCCESS
;
645 Bus_PDO_QueryResources(
646 PPDO_DEVICE_DATA DeviceData
,
649 ULONG NumberOfResources
= 0;
650 PCM_RESOURCE_LIST ResourceList
;
651 PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor
;
652 ACPI_STATUS AcpiStatus
;
654 ACPI_RESOURCE
* resource
;
655 ULONG ResourceListSize
;
658 struct acpi_device
*device
;
660 if (!DeviceData
->AcpiHandle
)
662 return Irp
->IoStatus
.Status
;
665 /* A bus number resource is not included in the list of current resources
666 * for the root PCI bus so we manually query one here and if we find it
667 * we create a resource list and add a bus number descriptor to it */
668 if (wcsstr(DeviceData
->HardwareIDs
, L
"PNP0A03") != 0)
670 acpi_bus_get_device(DeviceData
->AcpiHandle
, &device
);
672 AcpiStatus
= acpi_evaluate_integer(DeviceData
->AcpiHandle
, "_BBN", NULL
, &BusNumber
);
673 if (AcpiStatus
!= AE_OK
)
676 if (device
->flags
.unique_id
)
678 /* FIXME: Try the unique ID */
684 DPRINT1("Failed to find a bus number\n");
689 DPRINT1("Using _BBN for bus number\n");
692 DPRINT1("Found PCI root hub: %d\n", BusNumber
);
694 ResourceListSize
= sizeof(CM_RESOURCE_LIST
);
695 ResourceList
= (PCM_RESOURCE_LIST
)ExAllocatePool(PagedPool
, ResourceListSize
);
697 return STATUS_INSUFFICIENT_RESOURCES
;
699 ResourceList
->Count
= 1;
700 ResourceList
->List
[0].InterfaceType
= Internal
;
701 ResourceList
->List
[0].BusNumber
= 0;
702 ResourceList
->List
[0].PartialResourceList
.Version
= 1;
703 ResourceList
->List
[0].PartialResourceList
.Revision
= 1;
704 ResourceList
->List
[0].PartialResourceList
.Count
= 1;
705 ResourceDescriptor
= ResourceList
->List
[0].PartialResourceList
.PartialDescriptors
;
707 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
708 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
709 ResourceDescriptor
->u
.BusNumber
.Start
= BusNumber
;
710 ResourceDescriptor
->u
.BusNumber
.Length
= 1;
712 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
713 return STATUS_SUCCESS
;
716 /* Get current resources */
718 AcpiStatus
= AcpiGetCurrentResources(DeviceData
->AcpiHandle
, &Buffer
);
719 if ((!ACPI_SUCCESS(AcpiStatus
) && AcpiStatus
!= AE_BUFFER_OVERFLOW
) ||
722 return Irp
->IoStatus
.Status
;
725 Buffer
.Pointer
= ExAllocatePool(PagedPool
, Buffer
.Length
);
727 return STATUS_INSUFFICIENT_RESOURCES
;
729 AcpiStatus
= AcpiGetCurrentResources(DeviceData
->AcpiHandle
, &Buffer
);
730 if (!ACPI_SUCCESS(AcpiStatus
))
732 DPRINT1("AcpiGetCurrentResources #2 failed (0x%x)\n", AcpiStatus
);
734 return STATUS_UNSUCCESSFUL
;
737 resource
= Buffer
.Pointer
;
738 /* Count number of resources */
739 while (resource
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
)
741 switch (resource
->Type
)
743 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
745 ACPI_RESOURCE_EXTENDED_IRQ
*irq_data
= (ACPI_RESOURCE_EXTENDED_IRQ
*) &resource
->Data
;
746 NumberOfResources
+= irq_data
->InterruptCount
;
749 case ACPI_RESOURCE_TYPE_IRQ
:
751 ACPI_RESOURCE_IRQ
*irq_data
= (ACPI_RESOURCE_IRQ
*) &resource
->Data
;
752 NumberOfResources
+= irq_data
->InterruptCount
;
755 case ACPI_RESOURCE_TYPE_DMA
:
757 ACPI_RESOURCE_DMA
*dma_data
= (ACPI_RESOURCE_DMA
*) &resource
->Data
;
758 NumberOfResources
+= dma_data
->ChannelCount
;
761 case ACPI_RESOURCE_TYPE_ADDRESS16
:
762 case ACPI_RESOURCE_TYPE_ADDRESS32
:
763 case ACPI_RESOURCE_TYPE_ADDRESS64
:
764 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
765 case ACPI_RESOURCE_TYPE_MEMORY24
:
766 case ACPI_RESOURCE_TYPE_MEMORY32
:
767 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32
:
768 case ACPI_RESOURCE_TYPE_IO
:
775 DPRINT1("Unknown resource type: %d\n", resource
->Type
);
779 resource
= ACPI_NEXT_RESOURCE(resource
);
782 /* Allocate memory */
783 ResourceListSize
= sizeof(CM_RESOURCE_LIST
) + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
) * (NumberOfResources
- 1);
784 ResourceList
= (PCM_RESOURCE_LIST
)ExAllocatePool(PagedPool
, ResourceListSize
);
788 ExFreePool(Buffer
.Pointer
);
789 return STATUS_INSUFFICIENT_RESOURCES
;
791 ResourceList
->Count
= 1;
792 ResourceList
->List
[0].InterfaceType
= Internal
; /* FIXME */
793 ResourceList
->List
[0].BusNumber
= 0; /* We're the only ACPI bus device in the system */
794 ResourceList
->List
[0].PartialResourceList
.Version
= 1;
795 ResourceList
->List
[0].PartialResourceList
.Revision
= 1;
796 ResourceList
->List
[0].PartialResourceList
.Count
= NumberOfResources
;
797 ResourceDescriptor
= ResourceList
->List
[0].PartialResourceList
.PartialDescriptors
;
799 /* Fill resources list structure */
800 resource
= Buffer
.Pointer
;
801 while (resource
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
)
803 switch (resource
->Type
)
805 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
807 ACPI_RESOURCE_EXTENDED_IRQ
*irq_data
= (ACPI_RESOURCE_EXTENDED_IRQ
*) &resource
->Data
;
808 for (i
= 0; i
< irq_data
->InterruptCount
; i
++)
810 ResourceDescriptor
->Type
= CmResourceTypeInterrupt
;
812 ResourceDescriptor
->ShareDisposition
=
813 (irq_data
->Sharable
== ACPI_SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
814 ResourceDescriptor
->Flags
=
815 (irq_data
->Triggering
== ACPI_LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
816 ResourceDescriptor
->u
.Interrupt
.Level
=
817 ResourceDescriptor
->u
.Interrupt
.Vector
= irq_data
->Interrupts
[i
];
818 ResourceDescriptor
->u
.Interrupt
.Affinity
= (KAFFINITY
)(-1);
820 ResourceDescriptor
++;
824 case ACPI_RESOURCE_TYPE_IRQ
:
826 ACPI_RESOURCE_IRQ
*irq_data
= (ACPI_RESOURCE_IRQ
*) &resource
->Data
;
827 for (i
= 0; i
< irq_data
->InterruptCount
; i
++)
829 ResourceDescriptor
->Type
= CmResourceTypeInterrupt
;
831 ResourceDescriptor
->ShareDisposition
=
832 (irq_data
->Sharable
== ACPI_SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
833 ResourceDescriptor
->Flags
=
834 (irq_data
->Triggering
== ACPI_LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
835 ResourceDescriptor
->u
.Interrupt
.Level
=
836 ResourceDescriptor
->u
.Interrupt
.Vector
= irq_data
->Interrupts
[i
];
837 ResourceDescriptor
->u
.Interrupt
.Affinity
= (KAFFINITY
)(-1);
839 ResourceDescriptor
++;
843 case ACPI_RESOURCE_TYPE_DMA
:
845 ACPI_RESOURCE_DMA
*dma_data
= (ACPI_RESOURCE_DMA
*) &resource
->Data
;
846 for (i
= 0; i
< dma_data
->ChannelCount
; i
++)
848 ResourceDescriptor
->Type
= CmResourceTypeDma
;
849 ResourceDescriptor
->Flags
= 0;
850 switch (dma_data
->Type
)
852 case ACPI_TYPE_A
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_A
; break;
853 case ACPI_TYPE_B
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_B
; break;
854 case ACPI_TYPE_F
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_F
; break;
856 if (dma_data
->BusMaster
== ACPI_BUS_MASTER
)
857 ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_BUS_MASTER
;
858 switch (dma_data
->Transfer
)
860 case ACPI_TRANSFER_8
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_8
; break;
861 case ACPI_TRANSFER_16
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_16
; break;
862 case ACPI_TRANSFER_8_16
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_8_AND_16
; break;
864 ResourceDescriptor
->u
.Dma
.Channel
= dma_data
->Channels
[i
];
866 ResourceDescriptor
++;
870 case ACPI_RESOURCE_TYPE_IO
:
872 ACPI_RESOURCE_IO
*io_data
= (ACPI_RESOURCE_IO
*) &resource
->Data
;
873 ResourceDescriptor
->Type
= CmResourceTypePort
;
874 ResourceDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
875 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
876 if (io_data
->IoDecode
== ACPI_DECODE_16
)
877 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_16_BIT_DECODE
;
879 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_10_BIT_DECODE
;
880 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= io_data
->Minimum
;
881 ResourceDescriptor
->u
.Port
.Length
= io_data
->AddressLength
;
883 ResourceDescriptor
++;
886 case ACPI_RESOURCE_TYPE_ADDRESS16
:
888 ACPI_RESOURCE_ADDRESS16
*addr16_data
= (ACPI_RESOURCE_ADDRESS16
*) &resource
->Data
;
889 if (addr16_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
891 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
892 ResourceDescriptor
->ShareDisposition
= CmResourceShareShared
;
893 ResourceDescriptor
->Flags
= 0;
894 ResourceDescriptor
->u
.BusNumber
.Start
= addr16_data
->Minimum
;
895 ResourceDescriptor
->u
.BusNumber
.Length
= addr16_data
->AddressLength
;
897 else if (addr16_data
->ResourceType
== ACPI_IO_RANGE
)
899 ResourceDescriptor
->Type
= CmResourceTypePort
;
900 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
901 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
902 if (addr16_data
->Decode
== ACPI_POS_DECODE
)
903 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
904 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= addr16_data
->Minimum
;
905 ResourceDescriptor
->u
.Port
.Length
= addr16_data
->AddressLength
;
909 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
910 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
911 ResourceDescriptor
->Flags
= 0;
912 if (addr16_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
913 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
915 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
916 switch (addr16_data
->Info
.Mem
.Caching
)
918 case ACPI_CACHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
919 case ACPI_WRITE_COMBINING_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
920 case ACPI_PREFETCHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
922 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= addr16_data
->Minimum
;
923 ResourceDescriptor
->u
.Memory
.Length
= addr16_data
->AddressLength
;
925 ResourceDescriptor
++;
928 case ACPI_RESOURCE_TYPE_ADDRESS32
:
930 ACPI_RESOURCE_ADDRESS32
*addr32_data
= (ACPI_RESOURCE_ADDRESS32
*) &resource
->Data
;
931 if (addr32_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
933 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
934 ResourceDescriptor
->ShareDisposition
= CmResourceShareShared
;
935 ResourceDescriptor
->Flags
= 0;
936 ResourceDescriptor
->u
.BusNumber
.Start
= addr32_data
->Minimum
;
937 ResourceDescriptor
->u
.BusNumber
.Length
= addr32_data
->AddressLength
;
939 else if (addr32_data
->ResourceType
== ACPI_IO_RANGE
)
941 ResourceDescriptor
->Type
= CmResourceTypePort
;
942 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
943 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
944 if (addr32_data
->Decode
== ACPI_POS_DECODE
)
945 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
946 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= addr32_data
->Minimum
;
947 ResourceDescriptor
->u
.Port
.Length
= addr32_data
->AddressLength
;
951 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
952 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
953 ResourceDescriptor
->Flags
= 0;
954 if (addr32_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
955 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
957 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
958 switch (addr32_data
->Info
.Mem
.Caching
)
960 case ACPI_CACHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
961 case ACPI_WRITE_COMBINING_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
962 case ACPI_PREFETCHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
964 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= addr32_data
->Minimum
;
965 ResourceDescriptor
->u
.Memory
.Length
= addr32_data
->AddressLength
;
967 ResourceDescriptor
++;
970 case ACPI_RESOURCE_TYPE_ADDRESS64
:
972 ACPI_RESOURCE_ADDRESS64
*addr64_data
= (ACPI_RESOURCE_ADDRESS64
*) &resource
->Data
;
973 if (addr64_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
975 DPRINT1("64-bit bus address is not supported!\n");
976 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
977 ResourceDescriptor
->ShareDisposition
= CmResourceShareShared
;
978 ResourceDescriptor
->Flags
= 0;
979 ResourceDescriptor
->u
.BusNumber
.Start
= (ULONG
)addr64_data
->Minimum
;
980 ResourceDescriptor
->u
.BusNumber
.Length
= addr64_data
->AddressLength
;
982 else if (addr64_data
->ResourceType
== ACPI_IO_RANGE
)
984 ResourceDescriptor
->Type
= CmResourceTypePort
;
985 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
986 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
987 if (addr64_data
->Decode
== ACPI_POS_DECODE
)
988 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
989 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= addr64_data
->Minimum
;
990 ResourceDescriptor
->u
.Port
.Length
= addr64_data
->AddressLength
;
994 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
995 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
996 ResourceDescriptor
->Flags
= 0;
997 if (addr64_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
998 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1000 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1001 switch (addr64_data
->Info
.Mem
.Caching
)
1003 case ACPI_CACHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1004 case ACPI_WRITE_COMBINING_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1005 case ACPI_PREFETCHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1007 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= addr64_data
->Minimum
;
1008 ResourceDescriptor
->u
.Memory
.Length
= addr64_data
->AddressLength
;
1010 ResourceDescriptor
++;
1013 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
1015 ACPI_RESOURCE_EXTENDED_ADDRESS64
*addr64_data
= (ACPI_RESOURCE_EXTENDED_ADDRESS64
*) &resource
->Data
;
1016 if (addr64_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1018 DPRINT1("64-bit bus address is not supported!\n");
1019 ResourceDescriptor
->Type
= CmResourceTypeBusNumber
;
1020 ResourceDescriptor
->ShareDisposition
= CmResourceShareShared
;
1021 ResourceDescriptor
->Flags
= 0;
1022 ResourceDescriptor
->u
.BusNumber
.Start
= (ULONG
)addr64_data
->Minimum
;
1023 ResourceDescriptor
->u
.BusNumber
.Length
= addr64_data
->AddressLength
;
1025 else if (addr64_data
->ResourceType
== ACPI_IO_RANGE
)
1027 ResourceDescriptor
->Type
= CmResourceTypePort
;
1028 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1029 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1030 if (addr64_data
->Decode
== ACPI_POS_DECODE
)
1031 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1032 ResourceDescriptor
->u
.Port
.Start
.QuadPart
= addr64_data
->Minimum
;
1033 ResourceDescriptor
->u
.Port
.Length
= addr64_data
->AddressLength
;
1037 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1038 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1039 ResourceDescriptor
->Flags
= 0;
1040 if (addr64_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1041 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1043 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1044 switch (addr64_data
->Info
.Mem
.Caching
)
1046 case ACPI_CACHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1047 case ACPI_WRITE_COMBINING_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1048 case ACPI_PREFETCHABLE_MEMORY
: ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1050 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= addr64_data
->Minimum
;
1051 ResourceDescriptor
->u
.Memory
.Length
= addr64_data
->AddressLength
;
1053 ResourceDescriptor
++;
1056 case ACPI_RESOURCE_TYPE_MEMORY24
:
1058 ACPI_RESOURCE_MEMORY24
*mem24_data
= (ACPI_RESOURCE_MEMORY24
*) &resource
->Data
;
1059 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1060 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1061 ResourceDescriptor
->Flags
= CM_RESOURCE_MEMORY_24
;
1062 if (mem24_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1063 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1065 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1066 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= mem24_data
->Minimum
;
1067 ResourceDescriptor
->u
.Memory
.Length
= mem24_data
->AddressLength
;
1069 ResourceDescriptor
++;
1072 case ACPI_RESOURCE_TYPE_MEMORY32
:
1074 ACPI_RESOURCE_MEMORY32
*mem32_data
= (ACPI_RESOURCE_MEMORY32
*) &resource
->Data
;
1075 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1076 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1077 ResourceDescriptor
->Flags
= 0;
1078 if (mem32_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1079 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1081 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1082 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= mem32_data
->Minimum
;
1083 ResourceDescriptor
->u
.Memory
.Length
= mem32_data
->AddressLength
;
1085 ResourceDescriptor
++;
1088 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32
:
1090 ACPI_RESOURCE_FIXED_MEMORY32
*memfixed32_data
= (ACPI_RESOURCE_FIXED_MEMORY32
*) &resource
->Data
;
1091 ResourceDescriptor
->Type
= CmResourceTypeMemory
;
1092 ResourceDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1093 ResourceDescriptor
->Flags
= 0;
1094 if (memfixed32_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1095 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1097 ResourceDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1098 ResourceDescriptor
->u
.Memory
.Start
.QuadPart
= memfixed32_data
->Address
;
1099 ResourceDescriptor
->u
.Memory
.Length
= memfixed32_data
->AddressLength
;
1101 ResourceDescriptor
++;
1109 resource
= ACPI_NEXT_RESOURCE(resource
);
1112 ExFreePool(Buffer
.Pointer
);
1113 Irp
->IoStatus
.Information
= (ULONG_PTR
)ResourceList
;
1114 return STATUS_SUCCESS
;
1118 Bus_PDO_QueryResourceRequirements(
1119 PPDO_DEVICE_DATA DeviceData
,
1122 ULONG NumberOfResources
= 0;
1123 ACPI_STATUS AcpiStatus
;
1125 ACPI_RESOURCE
* resource
;
1126 ULONG i
, RequirementsListSize
;
1127 PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList
;
1128 PIO_RESOURCE_DESCRIPTOR RequirementDescriptor
;
1129 BOOLEAN CurrentRes
= FALSE
;
1133 if (!DeviceData
->AcpiHandle
)
1135 return Irp
->IoStatus
.Status
;
1138 /* Get current resources */
1143 AcpiStatus
= AcpiGetCurrentResources(DeviceData
->AcpiHandle
, &Buffer
);
1145 AcpiStatus
= AcpiGetPossibleResources(DeviceData
->AcpiHandle
, &Buffer
);
1146 if ((!ACPI_SUCCESS(AcpiStatus
) && AcpiStatus
!= AE_BUFFER_OVERFLOW
) ||
1152 return Irp
->IoStatus
.Status
;
1158 Buffer
.Pointer
= ExAllocatePool(PagedPool
, Buffer
.Length
);
1159 if (!Buffer
.Pointer
)
1160 return STATUS_INSUFFICIENT_RESOURCES
;
1163 AcpiStatus
= AcpiGetCurrentResources(DeviceData
->AcpiHandle
, &Buffer
);
1165 AcpiStatus
= AcpiGetPossibleResources(DeviceData
->AcpiHandle
, &Buffer
);
1166 if (!ACPI_SUCCESS(AcpiStatus
))
1168 DPRINT1("AcpiGetCurrentResources #2 failed (0x%x)\n", AcpiStatus
);
1170 return STATUS_UNSUCCESSFUL
;
1173 resource
= Buffer
.Pointer
;
1174 /* Count number of resources */
1175 while (resource
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
)
1177 switch (resource
->Type
)
1179 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
1181 ACPI_RESOURCE_EXTENDED_IRQ
*irq_data
= (ACPI_RESOURCE_EXTENDED_IRQ
*) &resource
->Data
;
1182 NumberOfResources
+= irq_data
->InterruptCount
;
1185 case ACPI_RESOURCE_TYPE_IRQ
:
1187 ACPI_RESOURCE_IRQ
*irq_data
= (ACPI_RESOURCE_IRQ
*) &resource
->Data
;
1188 NumberOfResources
+= irq_data
->InterruptCount
;
1191 case ACPI_RESOURCE_TYPE_DMA
:
1193 ACPI_RESOURCE_DMA
*dma_data
= (ACPI_RESOURCE_DMA
*) &resource
->Data
;
1194 NumberOfResources
+= dma_data
->ChannelCount
;
1197 case ACPI_RESOURCE_TYPE_ADDRESS16
:
1198 case ACPI_RESOURCE_TYPE_ADDRESS32
:
1199 case ACPI_RESOURCE_TYPE_ADDRESS64
:
1200 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
1201 case ACPI_RESOURCE_TYPE_MEMORY24
:
1202 case ACPI_RESOURCE_TYPE_MEMORY32
:
1203 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32
:
1204 case ACPI_RESOURCE_TYPE_IO
:
1206 NumberOfResources
++;
1214 resource
= ACPI_NEXT_RESOURCE(resource
);
1217 RequirementsListSize
= sizeof(IO_RESOURCE_REQUIREMENTS_LIST
) + sizeof(IO_RESOURCE_DESCRIPTOR
) * (NumberOfResources
- 1);
1218 RequirementsList
= (PIO_RESOURCE_REQUIREMENTS_LIST
)ExAllocatePool(PagedPool
, RequirementsListSize
);
1220 if (!RequirementsList
)
1222 ExFreePool(Buffer
.Pointer
);
1223 return STATUS_INSUFFICIENT_RESOURCES
;
1225 RequirementsList
->ListSize
= RequirementsListSize
;
1226 RequirementsList
->InterfaceType
= Internal
;
1227 RequirementsList
->BusNumber
= 0;
1228 RequirementsList
->SlotNumber
= 0; /* Not used by WDM drivers */
1229 RequirementsList
->AlternativeLists
= 1;
1230 RequirementsList
->List
[0].Version
= 1;
1231 RequirementsList
->List
[0].Revision
= 1;
1232 RequirementsList
->List
[0].Count
= NumberOfResources
;
1233 RequirementDescriptor
= RequirementsList
->List
[0].Descriptors
;
1235 /* Fill resources list structure */
1236 resource
= Buffer
.Pointer
;
1237 while (resource
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
)
1239 switch (resource
->Type
)
1241 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
1243 ACPI_RESOURCE_EXTENDED_IRQ
*irq_data
= (ACPI_RESOURCE_EXTENDED_IRQ
*) &resource
->Data
;
1244 for (i
= 0; i
< irq_data
->InterruptCount
; i
++)
1246 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1247 RequirementDescriptor
->Type
= CmResourceTypeInterrupt
;
1248 RequirementDescriptor
->ShareDisposition
= (irq_data
->Sharable
== ACPI_SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
1249 RequirementDescriptor
->Flags
=(irq_data
->Triggering
== ACPI_LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
1250 RequirementDescriptor
->u
.Interrupt
.MinimumVector
=
1251 RequirementDescriptor
->u
.Interrupt
.MaximumVector
= irq_data
->Interrupts
[i
];
1253 RequirementDescriptor
++;
1257 case ACPI_RESOURCE_TYPE_IRQ
:
1259 ACPI_RESOURCE_IRQ
*irq_data
= (ACPI_RESOURCE_IRQ
*) &resource
->Data
;
1260 for (i
= 0; i
< irq_data
->InterruptCount
; i
++)
1262 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1263 RequirementDescriptor
->Type
= CmResourceTypeInterrupt
;
1264 RequirementDescriptor
->ShareDisposition
= (irq_data
->Sharable
== ACPI_SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
1265 RequirementDescriptor
->Flags
=(irq_data
->Triggering
== ACPI_LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
1266 RequirementDescriptor
->u
.Interrupt
.MinimumVector
=
1267 RequirementDescriptor
->u
.Interrupt
.MaximumVector
= irq_data
->Interrupts
[i
];
1269 RequirementDescriptor
++;
1273 case ACPI_RESOURCE_TYPE_DMA
:
1275 ACPI_RESOURCE_DMA
*dma_data
= (ACPI_RESOURCE_DMA
*) &resource
->Data
;
1276 for (i
= 0; i
< dma_data
->ChannelCount
; i
++)
1278 RequirementDescriptor
->Type
= CmResourceTypeDma
;
1279 RequirementDescriptor
->Flags
= 0;
1280 switch (dma_data
->Type
)
1282 case ACPI_TYPE_A
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_A
; break;
1283 case ACPI_TYPE_B
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_B
; break;
1284 case ACPI_TYPE_F
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_F
; break;
1286 if (dma_data
->BusMaster
== ACPI_BUS_MASTER
)
1287 RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_BUS_MASTER
;
1288 switch (dma_data
->Transfer
)
1290 case ACPI_TRANSFER_8
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_8
; break;
1291 case ACPI_TRANSFER_16
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_16
; break;
1292 case ACPI_TRANSFER_8_16
: RequirementDescriptor
->Flags
|= CM_RESOURCE_DMA_8_AND_16
; break;
1295 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1296 RequirementDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
1297 RequirementDescriptor
->u
.Dma
.MinimumChannel
=
1298 RequirementDescriptor
->u
.Dma
.MaximumChannel
= dma_data
->Channels
[i
];
1299 RequirementDescriptor
++;
1303 case ACPI_RESOURCE_TYPE_IO
:
1305 ACPI_RESOURCE_IO
*io_data
= (ACPI_RESOURCE_IO
*) &resource
->Data
;
1306 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1307 if (io_data
->IoDecode
== ACPI_DECODE_16
)
1308 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_16_BIT_DECODE
;
1310 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_10_BIT_DECODE
;
1311 RequirementDescriptor
->u
.Port
.Length
= io_data
->AddressLength
;
1312 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1313 RequirementDescriptor
->Type
= CmResourceTypePort
;
1314 RequirementDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
1315 RequirementDescriptor
->u
.Port
.Alignment
= io_data
->Alignment
;
1316 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= io_data
->Minimum
;
1317 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= io_data
->Maximum
;
1319 RequirementDescriptor
++;
1322 case ACPI_RESOURCE_TYPE_ADDRESS16
:
1324 ACPI_RESOURCE_ADDRESS16
*addr16_data
= (ACPI_RESOURCE_ADDRESS16
*) &resource
->Data
;
1325 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1326 if (addr16_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1328 RequirementDescriptor
->Type
= CmResourceTypeBusNumber
;
1329 RequirementDescriptor
->ShareDisposition
= CmResourceShareShared
;
1330 RequirementDescriptor
->Flags
= 0;
1331 RequirementDescriptor
->u
.BusNumber
.MinBusNumber
= addr16_data
->Minimum
;
1332 RequirementDescriptor
->u
.BusNumber
.MaxBusNumber
= addr16_data
->Maximum
;
1333 RequirementDescriptor
->u
.BusNumber
.Length
= addr16_data
->AddressLength
;
1335 else if (addr16_data
->ResourceType
== ACPI_IO_RANGE
)
1337 RequirementDescriptor
->Type
= CmResourceTypePort
;
1338 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1339 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1340 if (addr16_data
->Decode
== ACPI_POS_DECODE
)
1341 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1342 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= addr16_data
->Minimum
;
1343 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= addr16_data
->Maximum
;
1344 RequirementDescriptor
->u
.Port
.Length
= addr16_data
->AddressLength
;
1348 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1349 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1350 RequirementDescriptor
->Flags
= 0;
1351 if (addr16_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1352 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1354 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1355 switch (addr16_data
->Info
.Mem
.Caching
)
1357 case ACPI_CACHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1358 case ACPI_WRITE_COMBINING_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1359 case ACPI_PREFETCHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1361 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= addr16_data
->Minimum
;
1362 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= addr16_data
->Maximum
;
1363 RequirementDescriptor
->u
.Memory
.Length
= addr16_data
->AddressLength
;
1365 RequirementDescriptor
++;
1368 case ACPI_RESOURCE_TYPE_ADDRESS32
:
1370 ACPI_RESOURCE_ADDRESS32
*addr32_data
= (ACPI_RESOURCE_ADDRESS32
*) &resource
->Data
;
1371 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1372 if (addr32_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1374 RequirementDescriptor
->Type
= CmResourceTypeBusNumber
;
1375 RequirementDescriptor
->ShareDisposition
= CmResourceShareShared
;
1376 RequirementDescriptor
->Flags
= 0;
1377 RequirementDescriptor
->u
.BusNumber
.MinBusNumber
= addr32_data
->Minimum
;
1378 RequirementDescriptor
->u
.BusNumber
.MaxBusNumber
= addr32_data
->Maximum
;
1379 RequirementDescriptor
->u
.BusNumber
.Length
= addr32_data
->AddressLength
;
1381 else if (addr32_data
->ResourceType
== ACPI_IO_RANGE
)
1383 RequirementDescriptor
->Type
= CmResourceTypePort
;
1384 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1385 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1386 if (addr32_data
->Decode
== ACPI_POS_DECODE
)
1387 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1388 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= addr32_data
->Minimum
;
1389 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= addr32_data
->Maximum
;
1390 RequirementDescriptor
->u
.Port
.Length
= addr32_data
->AddressLength
;
1394 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1395 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1396 RequirementDescriptor
->Flags
= 0;
1397 if (addr32_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1398 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1400 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1401 switch (addr32_data
->Info
.Mem
.Caching
)
1403 case ACPI_CACHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1404 case ACPI_WRITE_COMBINING_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1405 case ACPI_PREFETCHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1407 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= addr32_data
->Minimum
;
1408 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= addr32_data
->Maximum
;
1409 RequirementDescriptor
->u
.Memory
.Length
= addr32_data
->AddressLength
;
1411 RequirementDescriptor
++;
1414 case ACPI_RESOURCE_TYPE_ADDRESS64
:
1416 ACPI_RESOURCE_ADDRESS64
*addr64_data
= (ACPI_RESOURCE_ADDRESS64
*) &resource
->Data
;
1417 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1418 if (addr64_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1420 DPRINT1("64-bit bus address is not supported!\n");
1421 RequirementDescriptor
->Type
= CmResourceTypeBusNumber
;
1422 RequirementDescriptor
->ShareDisposition
= CmResourceShareShared
;
1423 RequirementDescriptor
->Flags
= 0;
1424 RequirementDescriptor
->u
.BusNumber
.MinBusNumber
= (ULONG
)addr64_data
->Minimum
;
1425 RequirementDescriptor
->u
.BusNumber
.MaxBusNumber
= (ULONG
)addr64_data
->Maximum
;
1426 RequirementDescriptor
->u
.BusNumber
.Length
= addr64_data
->AddressLength
;
1428 else if (addr64_data
->ResourceType
== ACPI_IO_RANGE
)
1430 RequirementDescriptor
->Type
= CmResourceTypePort
;
1431 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1432 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1433 if (addr64_data
->Decode
== ACPI_POS_DECODE
)
1434 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1435 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= addr64_data
->Minimum
;
1436 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= addr64_data
->Maximum
;
1437 RequirementDescriptor
->u
.Port
.Length
= addr64_data
->AddressLength
;
1441 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1442 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1443 RequirementDescriptor
->Flags
= 0;
1444 if (addr64_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1445 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1447 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1448 switch (addr64_data
->Info
.Mem
.Caching
)
1450 case ACPI_CACHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1451 case ACPI_WRITE_COMBINING_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1452 case ACPI_PREFETCHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1454 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= addr64_data
->Minimum
;
1455 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= addr64_data
->Maximum
;
1456 RequirementDescriptor
->u
.Memory
.Length
= addr64_data
->AddressLength
;
1458 RequirementDescriptor
++;
1461 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64
:
1463 ACPI_RESOURCE_EXTENDED_ADDRESS64
*addr64_data
= (ACPI_RESOURCE_EXTENDED_ADDRESS64
*) &resource
->Data
;
1464 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1465 if (addr64_data
->ResourceType
== ACPI_BUS_NUMBER_RANGE
)
1467 DPRINT1("64-bit bus address is not supported!\n");
1468 RequirementDescriptor
->Type
= CmResourceTypeBusNumber
;
1469 RequirementDescriptor
->ShareDisposition
= CmResourceShareShared
;
1470 RequirementDescriptor
->Flags
= 0;
1471 RequirementDescriptor
->u
.BusNumber
.MinBusNumber
= (ULONG
)addr64_data
->Minimum
;
1472 RequirementDescriptor
->u
.BusNumber
.MaxBusNumber
= (ULONG
)addr64_data
->Maximum
;
1473 RequirementDescriptor
->u
.BusNumber
.Length
= addr64_data
->AddressLength
;
1475 else if (addr64_data
->ResourceType
== ACPI_IO_RANGE
)
1477 RequirementDescriptor
->Type
= CmResourceTypePort
;
1478 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1479 RequirementDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
1480 if (addr64_data
->Decode
== ACPI_POS_DECODE
)
1481 RequirementDescriptor
->Flags
|= CM_RESOURCE_PORT_POSITIVE_DECODE
;
1482 RequirementDescriptor
->u
.Port
.MinimumAddress
.QuadPart
= addr64_data
->Minimum
;
1483 RequirementDescriptor
->u
.Port
.MaximumAddress
.QuadPart
= addr64_data
->Maximum
;
1484 RequirementDescriptor
->u
.Port
.Length
= addr64_data
->AddressLength
;
1488 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1489 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1490 RequirementDescriptor
->Flags
= 0;
1491 if (addr64_data
->Info
.Mem
.WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1492 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1494 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1495 switch (addr64_data
->Info
.Mem
.Caching
)
1497 case ACPI_CACHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_CACHEABLE
; break;
1498 case ACPI_WRITE_COMBINING_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_COMBINEDWRITE
; break;
1499 case ACPI_PREFETCHABLE_MEMORY
: RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_PREFETCHABLE
; break;
1501 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= addr64_data
->Minimum
;
1502 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= addr64_data
->Maximum
;
1503 RequirementDescriptor
->u
.Memory
.Length
= addr64_data
->AddressLength
;
1505 RequirementDescriptor
++;
1508 case ACPI_RESOURCE_TYPE_MEMORY24
:
1510 ACPI_RESOURCE_MEMORY24
*mem24_data
= (ACPI_RESOURCE_MEMORY24
*) &resource
->Data
;
1511 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1512 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1513 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1514 RequirementDescriptor
->Flags
= CM_RESOURCE_MEMORY_24
;
1515 if (mem24_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1516 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1518 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1519 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= mem24_data
->Minimum
;
1520 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= mem24_data
->Maximum
;
1521 RequirementDescriptor
->u
.Memory
.Length
= mem24_data
->AddressLength
;
1523 RequirementDescriptor
++;
1526 case ACPI_RESOURCE_TYPE_MEMORY32
:
1528 ACPI_RESOURCE_MEMORY32
*mem32_data
= (ACPI_RESOURCE_MEMORY32
*) &resource
->Data
;
1529 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1530 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1531 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1532 RequirementDescriptor
->Flags
= 0;
1533 if (mem32_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1534 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1536 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1537 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= mem32_data
->Minimum
;
1538 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= mem32_data
->Maximum
;
1539 RequirementDescriptor
->u
.Memory
.Length
= mem32_data
->AddressLength
;
1541 RequirementDescriptor
++;
1544 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32
:
1546 ACPI_RESOURCE_FIXED_MEMORY32
*fixedmem32_data
= (ACPI_RESOURCE_FIXED_MEMORY32
*) &resource
->Data
;
1547 RequirementDescriptor
->Option
= CurrentRes
? 0 : IO_RESOURCE_PREFERRED
;
1548 RequirementDescriptor
->Type
= CmResourceTypeMemory
;
1549 RequirementDescriptor
->ShareDisposition
= CmResourceShareDeviceExclusive
;
1550 RequirementDescriptor
->Flags
= 0;
1551 if (fixedmem32_data
->WriteProtect
== ACPI_READ_ONLY_MEMORY
)
1552 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_ONLY
;
1554 RequirementDescriptor
->Flags
|= CM_RESOURCE_MEMORY_READ_WRITE
;
1555 RequirementDescriptor
->u
.Memory
.MinimumAddress
.QuadPart
= fixedmem32_data
->Address
;
1556 RequirementDescriptor
->u
.Memory
.MaximumAddress
.QuadPart
= fixedmem32_data
->Address
;
1557 RequirementDescriptor
->u
.Memory
.Length
= fixedmem32_data
->AddressLength
;
1559 RequirementDescriptor
++;
1567 resource
= ACPI_NEXT_RESOURCE(resource
);
1569 ExFreePool(Buffer
.Pointer
);
1571 Irp
->IoStatus
.Information
= (ULONG_PTR
)RequirementsList
;
1573 return STATUS_SUCCESS
;
1577 Bus_PDO_QueryDeviceRelations(
1578 PPDO_DEVICE_DATA DeviceData
,
1582 Routine Description:
1584 The PnP Manager sends this IRP to gather information about
1585 devices with a relationship to the specified device.
1586 Bus drivers must handle this request for TargetDeviceRelation
1587 for their child devices (child PDOs).
1589 If a driver returns relations in response to this IRP,
1590 it allocates a DEVICE_RELATIONS structure from paged
1591 memory containing a count and the appropriate number of
1592 device object pointers. The PnP Manager frees the structure
1593 when it is no longer needed. If a driver replaces a
1594 DEVICE_RELATIONS structure allocated by another driver,
1595 it must free the previous structure.
1597 A driver must reference the PDO of any device that it
1598 reports in this IRP (ObReferenceObject). The PnP Manager
1599 removes the reference when appropriate.
1603 DeviceData - Pointer to the PDO's device extension.
1604 Irp - Pointer to the irp.
1613 PIO_STACK_LOCATION stack
;
1614 PDEVICE_RELATIONS deviceRelations
;
1619 stack
= IoGetCurrentIrpStackLocation (Irp
);
1621 switch (stack
->Parameters
.QueryDeviceRelations
.Type
) {
1623 case TargetDeviceRelation
:
1625 deviceRelations
= (PDEVICE_RELATIONS
) Irp
->IoStatus
.Information
;
1626 if (deviceRelations
) {
1628 // Only PDO can handle this request. Somebody above
1629 // is not playing by rule.
1631 ASSERTMSG("Someone above is handling TargetDeviceRelation", !deviceRelations
);
1634 deviceRelations
= (PDEVICE_RELATIONS
)
1635 ExAllocatePoolWithTag (PagedPool
,
1636 sizeof(DEVICE_RELATIONS
),
1638 if (!deviceRelations
) {
1639 status
= STATUS_INSUFFICIENT_RESOURCES
;
1644 // There is only one PDO pointer in the structure
1645 // for this relation type. The PnP Manager removes
1646 // the reference to the PDO when the driver or application
1647 // un-registers for notification on the device.
1650 deviceRelations
->Count
= 1;
1651 deviceRelations
->Objects
[0] = DeviceData
->Common
.Self
;
1652 ObReferenceObject(DeviceData
->Common
.Self
);
1654 status
= STATUS_SUCCESS
;
1655 Irp
->IoStatus
.Information
= (ULONG_PTR
) deviceRelations
;
1658 case BusRelations
: // Not handled by PDO
1659 case EjectionRelations
: // optional for PDO
1660 case RemovalRelations
: // // optional for PDO
1662 status
= Irp
->IoStatus
.Status
;
1669 Bus_PDO_QueryBusInformation(
1670 PPDO_DEVICE_DATA DeviceData
,
1674 Routine Description:
1676 The PnP Manager uses this IRP to request the type and
1677 instance number of a device's parent bus. Bus drivers
1678 should handle this request for their child devices (PDOs).
1682 DeviceData - Pointer to the PDO's device extension.
1683 Irp - Pointer to the irp.
1692 PPNP_BUS_INFORMATION busInfo
;
1696 busInfo
= ExAllocatePoolWithTag (PagedPool
, sizeof(PNP_BUS_INFORMATION
),
1699 if (busInfo
== NULL
) {
1700 return STATUS_INSUFFICIENT_RESOURCES
;
1703 busInfo
->BusTypeGuid
= GUID_ACPI_INTERFACE_STANDARD
;
1705 busInfo
->LegacyBusType
= InternalPowerBus
;
1707 busInfo
->BusNumber
= 0; //fixme
1709 Irp
->IoStatus
.Information
= (ULONG_PTR
)busInfo
;
1711 return STATUS_SUCCESS
;
1716 Bus_GetDeviceCapabilities(
1717 PDEVICE_OBJECT DeviceObject
,
1718 PDEVICE_CAPABILITIES DeviceCapabilities
1721 IO_STATUS_BLOCK ioStatus
;
1724 PDEVICE_OBJECT targetObject
;
1725 PIO_STACK_LOCATION irpStack
;
1731 // Initialize the capabilities that we will send down
1733 RtlZeroMemory( DeviceCapabilities
, sizeof(DEVICE_CAPABILITIES
) );
1734 DeviceCapabilities
->Size
= sizeof(DEVICE_CAPABILITIES
);
1735 DeviceCapabilities
->Version
= 1;
1736 DeviceCapabilities
->Address
= -1;
1737 DeviceCapabilities
->UINumber
= -1;
1740 // Initialize the event
1742 KeInitializeEvent( &pnpEvent
, NotificationEvent
, FALSE
);
1744 targetObject
= IoGetAttachedDeviceReference( DeviceObject
);
1749 pnpIrp
= IoBuildSynchronousFsdRequest(
1758 if (pnpIrp
== NULL
) {
1760 status
= STATUS_INSUFFICIENT_RESOURCES
;
1761 goto GetDeviceCapabilitiesExit
;
1766 // Pnp Irps all begin life as STATUS_NOT_SUPPORTED;
1768 pnpIrp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
1771 // Get the top of stack
1773 irpStack
= IoGetNextIrpStackLocation( pnpIrp
);
1776 // Set the top of stack
1778 RtlZeroMemory( irpStack
, sizeof(IO_STACK_LOCATION
) );
1779 irpStack
->MajorFunction
= IRP_MJ_PNP
;
1780 irpStack
->MinorFunction
= IRP_MN_QUERY_CAPABILITIES
;
1781 irpStack
->Parameters
.DeviceCapabilities
.Capabilities
= DeviceCapabilities
;
1786 status
= IoCallDriver( targetObject
, pnpIrp
);
1787 if (status
== STATUS_PENDING
) {
1790 // Block until the irp comes back.
1791 // Important thing to note here is when you allocate
1792 // the memory for an event in the stack you must do a
1793 // KernelMode wait instead of UserMode to prevent
1794 // the stack from getting paged out.
1797 KeWaitForSingleObject(
1804 status
= ioStatus
.Status
;
1808 GetDeviceCapabilitiesExit
:
1810 // Done with reference
1812 ObDereferenceObject( targetObject
);