3 * PROJECT: ReactOS ACPI bus driver
4 * FILE: acpi/ospm/fdo.c
5 * PURPOSE: ACPI device object dispatch routines
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * Hervé Poussineau (hpoussin@reactos.com)
9 * 08-08-2001 CSH Created
16 FADT_DESCRIPTOR_REV2 acpi_fadt
;
18 /*** PRIVATE *****************************************************************/
22 AcpiCreateUnicodeString(
23 PUNICODE_STRING Destination
,
31 RtlInitUnicodeString(Destination
, NULL
);
35 Length
= (wcslen(Source
) + 1) * sizeof(WCHAR
);
37 Destination
->Buffer
= ExAllocatePool(PoolType
, Length
);
38 if (Destination
->Buffer
== NULL
)
43 RtlCopyMemory(Destination
->Buffer
, Source
, Length
);
45 Destination
->MaximumLength
= Length
;
47 Destination
->Length
= Length
- sizeof(WCHAR
);
53 AcpiCreateDeviceIDString(PUNICODE_STRING DeviceID
,
62 return AcpiCreateUnicodeString(DeviceID
, Buffer
, PagedPool
);
67 AcpiCreateHardwareIDsString(PUNICODE_STRING HardwareIDs
,
75 Index
+= swprintf(&Buffer
[Index
],
80 Index
+= swprintf(&Buffer
[Index
],
84 Buffer
[Index
] = UNICODE_NULL
;
86 Length
= (Index
+ 1) * sizeof(WCHAR
);
87 HardwareIDs
->Buffer
= ExAllocatePool(PagedPool
, Length
);
88 if (HardwareIDs
->Buffer
== NULL
)
93 HardwareIDs
->Length
= Length
- sizeof(WCHAR
);
94 HardwareIDs
->MaximumLength
= Length
;
95 RtlCopyMemory(HardwareIDs
->Buffer
, Buffer
, Length
);
102 AcpiCreateInstanceIDString(PUNICODE_STRING InstanceID
,
107 if (Node
->device
.id
.uid
[0])
108 swprintf(Buffer
, L
"%S", Node
->device
.id
.uid
);
110 /* FIXME: Generate unique id! */
111 swprintf(Buffer
, L
"%S", L
"0000");
113 return AcpiCreateUnicodeString(InstanceID
, Buffer
, PagedPool
);
118 AcpiCreateDeviceDescriptionString(PUNICODE_STRING DeviceDescription
,
123 if (RtlCompareMemory(Node
->device
.id
.hid
, "PNP000", 6) == 6)
124 Buffer
= L
"Programmable interrupt controller";
125 else if (RtlCompareMemory(Node
->device
.id
.hid
, "PNP010", 6) == 6)
126 Buffer
= L
"System timer";
127 else if (RtlCompareMemory(Node
->device
.id
.hid
, "PNP020", 6) == 6)
128 Buffer
= L
"DMA controller";
129 else if (RtlCompareMemory(Node
->device
.id
.hid
, "PNP03", 5) == 5)
130 Buffer
= L
"Keyboard";
131 else if (RtlCompareMemory(Node
->device
.id
.hid
, "PNP040", 6) == 6)
132 Buffer
= L
"Parallel port";
133 else if (RtlCompareMemory(Node
->device
.id
.hid
, "PNP05", 5) == 5)
134 Buffer
= L
"Serial port";
135 else if (RtlCompareMemory(Node
->device
.id
.hid
, "PNP06", 5) ==5)
136 Buffer
= L
"Disk controller";
137 else if (RtlCompareMemory(Node
->device
.id
.hid
, "PNP07", 5) == 5)
138 Buffer
= L
"Disk controller";
139 else if (RtlCompareMemory(Node
->device
.id
.hid
, "PNP09", 5) == 5)
140 Buffer
= L
"Display adapter";
141 else if (RtlCompareMemory(Node
->device
.id
.hid
, "PNP0A0", 6) == 6)
142 Buffer
= L
"Bus controller";
143 else if (RtlCompareMemory(Node
->device
.id
.hid
, "PNP0E0", 6) == 6)
144 Buffer
= L
"PCMCIA controller";
145 else if (RtlCompareMemory(Node
->device
.id
.hid
, "PNP0F", 5) == 5)
146 Buffer
= L
"Mouse device";
147 else if (RtlCompareMemory(Node
->device
.id
.hid
, "PNP8", 4) == 4)
148 Buffer
= L
"Network adapter";
149 else if (RtlCompareMemory(Node
->device
.id
.hid
, "PNPA0", 5) == 5)
150 Buffer
= L
"SCSI controller";
151 else if (RtlCompareMemory(Node
->device
.id
.hid
, "PNPB0", 5) == 5)
152 Buffer
= L
"Multimedia device";
153 else if (RtlCompareMemory(Node
->device
.id
.hid
, "PNPC00", 6) == 6)
156 Buffer
= L
"Other ACPI device";
158 return AcpiCreateUnicodeString(DeviceDescription
, Buffer
, PagedPool
);
163 AcpiCreateResourceList(PCM_RESOURCE_LIST
* pResourceList
,
164 PULONG ResourceListSize
,
165 PIO_RESOURCE_REQUIREMENTS_LIST
* pRequirementsList
,
166 PULONG RequirementsListSize
,
170 ULONG NumberOfResources
= 0;
171 PCM_RESOURCE_LIST ResourceList
;
172 PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList
;
173 PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor
;
174 PIO_RESOURCE_DESCRIPTOR RequirementDescriptor
;
178 /* Count number of resources */
180 resource
= resources
;
183 switch (resource
->id
)
187 IRQ_RESOURCE
*irq_data
= (IRQ_RESOURCE
*) &resource
->data
;
188 NumberOfResources
+= irq_data
->number_of_interrupts
;
193 DMA_RESOURCE
*dma_data
= (DMA_RESOURCE
*) &resource
->data
;
194 NumberOfResources
+= dma_data
->number_of_channels
;
212 resource
= NEXT_RESOURCE(resource
);
215 /* Allocate memory */
216 *ResourceListSize
= sizeof(CM_RESOURCE_LIST
) + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
) * (NumberOfResources
- 1);
217 ResourceList
= (PCM_RESOURCE_LIST
)ExAllocatePool(PagedPool
, *ResourceListSize
);
218 *pResourceList
= ResourceList
;
221 ResourceList
->Count
= 1;
222 ResourceList
->List
[0].InterfaceType
= Internal
; /* FIXME */
223 ResourceList
->List
[0].BusNumber
= 0; /* We're the only ACPI bus device in the system */
224 ResourceList
->List
[0].PartialResourceList
.Version
= 1;
225 ResourceList
->List
[0].PartialResourceList
.Revision
= 1;
226 ResourceList
->List
[0].PartialResourceList
.Count
= NumberOfResources
;
227 ResourceDescriptor
= ResourceList
->List
[0].PartialResourceList
.PartialDescriptors
;
229 *RequirementsListSize
= sizeof(IO_RESOURCE_REQUIREMENTS_LIST
) + sizeof(IO_RESOURCE_DESCRIPTOR
) * (NumberOfResources
- 1);
230 RequirementsList
= (PIO_RESOURCE_REQUIREMENTS_LIST
)ExAllocatePool(PagedPool
, *RequirementsListSize
);
231 *pRequirementsList
= RequirementsList
;
232 if (!RequirementsList
)
234 ExFreePool(ResourceList
);
237 RequirementsList
->ListSize
= *RequirementsListSize
;
238 RequirementsList
->InterfaceType
= ResourceList
->List
[0].InterfaceType
;
239 RequirementsList
->BusNumber
= ResourceList
->List
[0].BusNumber
;
240 RequirementsList
->SlotNumber
= 0; /* Not used by WDM drivers */
241 RequirementsList
->AlternativeLists
= 1;
242 RequirementsList
->List
[0].Version
= 1;
243 RequirementsList
->List
[0].Revision
= 1;
244 RequirementsList
->List
[0].Count
= NumberOfResources
;
245 RequirementDescriptor
= RequirementsList
->List
[0].Descriptors
;
247 /* Fill resources list structure */
249 resource
= resources
;
252 switch (resource
->id
)
256 IRQ_RESOURCE
*irq_data
= (IRQ_RESOURCE
*) &resource
->data
;
257 for (i
= 0; i
< irq_data
->number_of_interrupts
; i
++)
259 ResourceDescriptor
->Type
= CmResourceTypeInterrupt
;
261 ResourceDescriptor
->ShareDisposition
=
262 (irq_data
->shared_exclusive
== SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
263 ResourceDescriptor
->Flags
=
264 (irq_data
->edge_level
== LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
265 ResourceDescriptor
->u
.Interrupt
.Level
= irq_data
->interrupts
[i
];
266 ResourceDescriptor
->u
.Interrupt
.Vector
= 0;
267 ResourceDescriptor
->u
.Interrupt
.Affinity
= (KAFFINITY
)(-1);
269 RequirementDescriptor
->Option
= 0; /* Required */
270 RequirementDescriptor
->Type
= ResourceDescriptor
->Type
;
271 RequirementDescriptor
->ShareDisposition
= ResourceDescriptor
->ShareDisposition
;
272 RequirementDescriptor
->Flags
= ResourceDescriptor
->Flags
;
273 RequirementDescriptor
->u
.Interrupt
.MinimumVector
= RequirementDescriptor
->u
.Interrupt
.MaximumVector
274 = irq_data
->interrupts
[i
];
276 ResourceDescriptor
++;
277 RequirementDescriptor
++;
283 DMA_RESOURCE
*dma_data
= (DMA_RESOURCE
*) &resource
->data
;
284 for (i
= 0; i
< dma_data
->number_of_channels
; i
++)
286 ResourceDescriptor
->Type
= CmResourceTypeDma
;
287 ResourceDescriptor
->Flags
= 0;
288 switch (dma_data
->type
)
290 case TYPE_A
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_A
; break;
291 case TYPE_B
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_B
; break;
292 case TYPE_F
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_F
; break;
294 if (dma_data
->bus_master
== BUS_MASTER
)
295 ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_BUS_MASTER
;
296 switch (dma_data
->transfer
)
298 case TRANSFER_8
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_8
; break;
299 case TRANSFER_16
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_16
; break;
300 case TRANSFER_8_16
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_8_AND_16
; break;
302 ResourceDescriptor
->u
.Dma
.Channel
= dma_data
->channels
[i
];
304 RequirementDescriptor
->Option
= 0; /* Required */
305 RequirementDescriptor
->Type
= ResourceDescriptor
->Type
;
306 RequirementDescriptor
->ShareDisposition
= ResourceDescriptor
->ShareDisposition
;
307 RequirementDescriptor
->Flags
= ResourceDescriptor
->Flags
;
308 RequirementDescriptor
->u
.Dma
.MinimumChannel
= RequirementDescriptor
->u
.Dma
.MaximumChannel
309 = ResourceDescriptor
->u
.Dma
.Channel
;
311 ResourceDescriptor
++;
312 RequirementDescriptor
++;
318 IO_RESOURCE
*io_data
= (IO_RESOURCE
*) &resource
->data
;
319 ResourceDescriptor
->Type
= CmResourceTypePort
;
320 ResourceDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
321 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
322 if (io_data
->io_decode
== DECODE_16
)
323 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_16_BIT_DECODE
;
325 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_10_BIT_DECODE
;
326 ResourceDescriptor
->u
.Port
.Start
.u
.HighPart
= 0;
327 ResourceDescriptor
->u
.Port
.Start
.u
.LowPart
= io_data
->min_base_address
;
328 ResourceDescriptor
->u
.Port
.Length
= io_data
->range_length
;
330 RequirementDescriptor
->Option
= 0; /* Required */
331 RequirementDescriptor
->Type
= ResourceDescriptor
->Type
;
332 RequirementDescriptor
->ShareDisposition
= ResourceDescriptor
->ShareDisposition
;
333 RequirementDescriptor
->Flags
= ResourceDescriptor
->Flags
;
334 RequirementDescriptor
->u
.Port
.Length
= ResourceDescriptor
->u
.Port
.Length
;
335 RequirementDescriptor
->u
.Port
.Alignment
= 1; /* Start address is specified, so it doesn't matter */
336 RequirementDescriptor
->u
.Port
.MinimumAddress
= RequirementDescriptor
->u
.Port
.MaximumAddress
337 = ResourceDescriptor
->u
.Port
.Start
;
339 ResourceDescriptor
++;
340 RequirementDescriptor
++;
353 resource
= NEXT_RESOURCE(resource
);
356 acpi_rs_dump_resource_list(resource
);
362 AcpiCheckIfIsSerialDebugPort(
363 IN PACPI_DEVICE Device
)
365 ACPI_STATUS AcpiStatus
;
371 AcpiStatus
= bm_get_node(Device
->BmHandle
, 0, &Node
);
372 if (!ACPI_SUCCESS(AcpiStatus
))
375 /* Get current resources */
377 AcpiStatus
= acpi_get_current_resources(Node
->device
.acpi_handle
, &Buffer
);
378 if ((AcpiStatus
& ACPI_OK
) == 0)
380 if (Buffer
.length
== 0)
383 Buffer
.pointer
= ExAllocatePool(PagedPool
, Buffer
.length
);
386 AcpiStatus
= acpi_get_current_resources(Node
->device
.acpi_handle
, &Buffer
);
387 if (!ACPI_SUCCESS(AcpiStatus
))
389 ExFreePool(Buffer
.pointer
);
393 /* Loop through the list of resources to see if the
394 * device is using the serial port address
397 resource
= (RESOURCE
*)Buffer
.pointer
;
400 switch (resource
->id
)
404 IO_RESOURCE
*io_data
= (IO_RESOURCE
*) &resource
->data
;
405 if (KdComPortInUse
== (PUCHAR
)io_data
->min_base_address
)
407 ExFreePool(Buffer
.pointer
);
422 resource
= (RESOURCE
*) ((NATIVE_UINT
) resource
+ (NATIVE_UINT
) resource
->length
);
425 ExFreePool(Buffer
.pointer
);
430 FdoQueryBusRelations(
431 IN PDEVICE_OBJECT DeviceObject
,
433 PIO_STACK_LOCATION IrpSp
)
435 PPDO_DEVICE_EXTENSION PdoDeviceExtension
;
436 PFDO_DEVICE_EXTENSION DeviceExtension
;
437 PDEVICE_RELATIONS Relations
;
438 PLIST_ENTRY CurrentEntry
;
439 ACPI_STATUS AcpiStatus
;
441 NTSTATUS Status
= STATUS_SUCCESS
;
448 DeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
450 Size
= sizeof(DEVICE_RELATIONS
) + sizeof(Relations
->Objects
) *
451 (DeviceExtension
->DeviceListCount
- 1);
452 Relations
= (PDEVICE_RELATIONS
)ExAllocatePool(PagedPool
, Size
);
454 return STATUS_INSUFFICIENT_RESOURCES
;
456 Relations
->Count
= DeviceExtension
->DeviceListCount
;
459 CurrentEntry
= DeviceExtension
->DeviceListHead
.Flink
;
460 while (CurrentEntry
!= &DeviceExtension
->DeviceListHead
)
463 Device
= CONTAINING_RECORD(CurrentEntry
, ACPI_DEVICE
, DeviceListEntry
);
465 if (AcpiCheckIfIsSerialDebugPort(Device
))
467 /* Skip this device */
468 DPRINT("Found debug serial port ; skipping it\n");
470 CurrentEntry
= CurrentEntry
->Flink
;
474 /* FIXME: For ACPI namespace devices on the motherboard create filter DOs
475 and attach them just above the ACPI bus device object (PDO) */
477 /* FIXME: For other devices in ACPI namespace, but not on motherboard,
482 /* Create a physical device object for the
483 device as it does not already have one */
484 Status
= IoCreateDevice(DeviceObject
->DriverObject
,
485 sizeof(PDO_DEVICE_EXTENSION
),
487 FILE_DEVICE_CONTROLLER
,
488 FILE_AUTOGENERATED_DEVICE_NAME
,
491 if (!NT_SUCCESS(Status
))
493 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
494 /* FIXME: Cleanup all new PDOs created in this call */
495 ExFreePool(Relations
);
499 PdoDeviceExtension
= (PPDO_DEVICE_EXTENSION
)Device
->Pdo
->DeviceExtension
;
501 RtlZeroMemory(PdoDeviceExtension
, sizeof(PDO_DEVICE_EXTENSION
));
503 Device
->Pdo
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
505 Device
->Pdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
507 //Device->Pdo->Flags |= DO_POWER_PAGABLE;
509 PdoDeviceExtension
->Common
.DeviceObject
= Device
->Pdo
;
511 PdoDeviceExtension
->Common
.DevicePowerState
= PowerDeviceD0
;
513 // PdoDeviceExtension->Common.Ldo = IoAttachDeviceToDeviceStack(DeviceObject,
516 RtlInitUnicodeString(&PdoDeviceExtension
->DeviceID
, NULL
);
517 RtlInitUnicodeString(&PdoDeviceExtension
->InstanceID
, NULL
);
518 RtlInitUnicodeString(&PdoDeviceExtension
->HardwareIDs
, NULL
);
520 AcpiStatus
= bm_get_node(Device
->BmHandle
, 0, &Node
);
521 if (ACPI_SUCCESS(AcpiStatus
))
523 /* Get current resources */
525 Status
= acpi_get_current_resources(Node
->device
.acpi_handle
, &Buffer
);
526 if ((Status
& ACPI_OK
) == 0)
530 if (Buffer
.length
> 0)
532 Buffer
.pointer
= ExAllocatePool(PagedPool
, Buffer
.length
);
537 Status
= acpi_get_current_resources(Node
->device
.acpi_handle
, &Buffer
);
538 if (ACPI_FAILURE(Status
))
542 if (!AcpiCreateResourceList(&PdoDeviceExtension
->ResourceList
,
543 &PdoDeviceExtension
->ResourceListSize
,
544 &PdoDeviceExtension
->ResourceRequirementsList
,
545 &PdoDeviceExtension
->ResourceRequirementsListSize
,
546 (RESOURCE
*)Buffer
.pointer
))
550 ExFreePool(Buffer
.pointer
);
553 /* Add Device ID string */
554 if (!AcpiCreateDeviceIDString(&PdoDeviceExtension
->DeviceID
,
558 // ErrorStatus = STATUS_INSUFFICIENT_RESOURCES;
559 // ErrorOccurred = TRUE;
563 if (!AcpiCreateInstanceIDString(&PdoDeviceExtension
->InstanceID
,
567 // ErrorStatus = STATUS_INSUFFICIENT_RESOURCES;
568 // ErrorOccurred = TRUE;
572 if (!AcpiCreateHardwareIDsString(&PdoDeviceExtension
->HardwareIDs
,
576 // ErrorStatus = STATUS_INSUFFICIENT_RESOURCES;
577 // ErrorOccurred = TRUE;
581 if (!AcpiCreateDeviceDescriptionString(&PdoDeviceExtension
->DeviceDescription
,
585 // ErrorStatus = STATUS_INSUFFICIENT_RESOURCES;
586 // ErrorOccurred = TRUE;
592 /* Reference the physical device object. The PnP manager
593 will dereference it again when it is no longer needed */
594 ObReferenceObject(Device
->Pdo
);
596 Relations
->Objects
[i
] = Device
->Pdo
;
600 CurrentEntry
= CurrentEntry
->Flink
;
603 Irp
->IoStatus
.Information
= (ULONG
)Relations
;
611 PFDO_DEVICE_EXTENSION DeviceExtension
)
613 DbgPrint("ACPI: System firmware supports:\n");
616 * Print out basic system information
618 DbgPrint("+------------------------------------------------------------\n");
619 DbgPrint("| Sx states: %cS0 %cS1 %cS2 %cS3 %cS4 %cS5\n",
620 (DeviceExtension
->SystemStates
[0]?'+':'-'),
621 (DeviceExtension
->SystemStates
[1]?'+':'-'),
622 (DeviceExtension
->SystemStates
[2]?'+':'-'),
623 (DeviceExtension
->SystemStates
[3]?'+':'-'),
624 (DeviceExtension
->SystemStates
[4]?'+':'-'),
625 (DeviceExtension
->SystemStates
[5]?'+':'-'));
626 DbgPrint("+------------------------------------------------------------\n");
631 ACPIInitializeInternalDriver(
632 PFDO_DEVICE_EXTENSION DeviceExtension
,
633 ACPI_DRIVER_FUNCTION Initialize
,
634 ACPI_DRIVER_FUNCTION Terminate
)
636 ACPI_STATUS AcpiStatus
;
638 AcpiStatus
= Initialize();
639 if (!ACPI_SUCCESS(AcpiStatus
)) {
640 DPRINT("BN init status 0x%X\n", AcpiStatus
);
641 return STATUS_UNSUCCESSFUL
;
644 AcpiDevice
= (PACPI_DEVICE
)ExAllocatePool(
645 NonPagedPool
, sizeof(ACPI_DEVICE
));
647 return STATUS_INSUFFICIENT_RESOURCES
;
650 AcpiDevice
->Initialize
= Initialize
;
651 AcpiDevice
->Terminate
= Terminate
;
653 /* FIXME: Create PDO */
655 AcpiDevice
->Pdo
= NULL
;
656 //AcpiDevice->BmHandle = HandleList.handles[i];
658 ExInterlockedInsertHeadList(&DeviceExtension
->DeviceListHead
,
659 &AcpiDevice
->ListEntry
, &DeviceExtension
->DeviceListLock
);
661 return STATUS_SUCCESS
;
666 ACPIInitializeInternalDrivers(
667 PFDO_DEVICE_EXTENSION DeviceExtension
)
671 Status
= ACPIInitializeInternalDriver(DeviceExtension
,
672 bn_initialize
, bn_terminate
);
674 return STATUS_SUCCESS
;
680 IN PDEVICE_OBJECT DeviceObject
,
683 PFDO_DEVICE_EXTENSION DeviceExtension
;
684 ACPI_PHYSICAL_ADDRESS rsdp
;
685 ACPI_SYSTEM_INFO SysInfo
;
686 ACPI_STATUS AcpiStatus
;
693 DeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
695 ASSERT(DeviceExtension
->State
== dsStopped
);
697 AcpiStatus
= acpi_initialize_subsystem();
698 if (!ACPI_SUCCESS(AcpiStatus
)) {
699 DPRINT("acpi_initialize_subsystem() failed with status 0x%X\n", AcpiStatus
);
700 return STATUS_UNSUCCESSFUL
;
703 AcpiStatus
= acpi_find_root_pointer(&rsdp
);
704 if (!ACPI_SUCCESS(AcpiStatus
)) {
705 DPRINT("acpi_find_root_pointer() failed with status 0x%X\n", AcpiStatus
);
706 return STATUS_UNSUCCESSFUL
;
709 /* From this point on, on error we must call acpi_terminate() */
711 AcpiStatus
= acpi_load_tables(rsdp
);
712 if (!ACPI_SUCCESS(AcpiStatus
)) {
713 DPRINT("acpi_load_tables() failed with status 0x%X\n", AcpiStatus
);
715 return STATUS_UNSUCCESSFUL
;
718 Buffer
.length
= sizeof(SysInfo
);
719 Buffer
.pointer
= &SysInfo
;
721 AcpiStatus
= acpi_get_system_info(&Buffer
);
722 if (!ACPI_SUCCESS(AcpiStatus
)) {
723 DPRINT("acpi_get_system_info() failed with status 0x%X\n", AcpiStatus
);
725 return STATUS_UNSUCCESSFUL
;
728 DPRINT("ACPI CA Core Subsystem version 0x%X\n", SysInfo
.acpi_ca_version
);
730 ASSERT(SysInfo
.num_table_types
> ACPI_TABLE_FADT
);
732 RtlMoveMemory(&acpi_fadt
,
733 &SysInfo
.table_info
[ACPI_TABLE_FADT
],
734 sizeof(FADT_DESCRIPTOR_REV2
));
736 AcpiStatus
= acpi_enable_subsystem(ACPI_FULL_INITIALIZATION
);
737 if (!ACPI_SUCCESS(AcpiStatus
)) {
738 DPRINT("acpi_enable_subsystem() failed with status 0x%X\n", AcpiStatus
);
740 return STATUS_UNSUCCESSFUL
;
743 DPRINT("ACPI CA Core Subsystem enabled\n");
748 * Figure out which Sx states are supported
750 for (i
=0; i
<=ACPI_S_STATES_MAX
; i
++) {
751 AcpiStatus
= acpi_hw_obtain_sleep_type_register_data(
755 DPRINT("acpi_hw_obtain_sleep_type_register_data (%d) status 0x%X\n",
757 if (ACPI_SUCCESS(AcpiStatus
)) {
758 DeviceExtension
->SystemStates
[i
] = TRUE
;
763 ACPIPrintInfo(DeviceExtension
);
766 /* Initialize ACPI bus manager */
767 AcpiStatus
= bm_initialize();
768 if (!ACPI_SUCCESS(AcpiStatus
)) {
769 DPRINT("bm_initialize() failed with status 0x%X\n", AcpiStatus
);
771 return STATUS_UNSUCCESSFUL
;
774 InitializeListHead(&DeviceExtension
->DeviceListHead
);
775 KeInitializeSpinLock(&DeviceExtension
->DeviceListLock
);
776 DeviceExtension
->DeviceListCount
= 0;
779 ACPIEnumerateDevices(DeviceExtension
);
782 ACPIInitializeInternalDrivers(DeviceExtension
);
784 DeviceExtension
->State
= dsStarted
;
786 return STATUS_SUCCESS
;
792 IN PDEVICE_OBJECT DeviceObject
,
794 PIO_STACK_LOCATION IrpSp
)
796 PFDO_DEVICE_EXTENSION DeviceExtension
;
797 ACPI_STATUS AcpiStatus
;
803 DeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
805 if (IrpSp
->Parameters
.Power
.Type
== SystemPowerState
) {
806 Status
= STATUS_SUCCESS
;
807 switch (IrpSp
->Parameters
.Power
.State
.SystemState
) {
808 case PowerSystemSleeping1
:
809 AcpiState
= ACPI_STATE_S1
;
811 case PowerSystemSleeping2
:
812 AcpiState
= ACPI_STATE_S2
;
814 case PowerSystemSleeping3
:
815 AcpiState
= ACPI_STATE_S3
;
817 case PowerSystemHibernate
:
818 AcpiState
= ACPI_STATE_S4
;
820 case PowerSystemShutdown
:
821 AcpiState
= ACPI_STATE_S5
;
824 Status
= STATUS_UNSUCCESSFUL
;
827 if (!DeviceExtension
->SystemStates
[AcpiState
]) {
828 DPRINT("System sleep state S%d is not supported by hardware\n", AcpiState
);
829 Status
= STATUS_UNSUCCESSFUL
;
832 if (NT_SUCCESS(Status
)) {
833 DPRINT("Trying to enter sleep state %d\n", AcpiState
);
835 AcpiStatus
= acpi_enter_sleep_state(AcpiState
);
836 if (!ACPI_SUCCESS(AcpiStatus
)) {
837 DPRINT("Failed to enter sleep state %d (Status 0x%X)\n",
838 AcpiState
, AcpiStatus
);
839 Status
= STATUS_UNSUCCESSFUL
;
843 Status
= STATUS_UNSUCCESSFUL
;
850 /*** PUBLIC ******************************************************************/
855 PDEVICE_OBJECT DeviceObject
,
858 * FUNCTION: Handle Plug and Play IRPs for the ACPI device
860 * DeviceObject = Pointer to functional device object of the ACPI driver
861 * Irp = Pointer to IRP that should be handled
866 PIO_STACK_LOCATION IrpSp
;
871 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
872 switch (IrpSp
->MinorFunction
) {
873 //case IRP_MN_CANCEL_REMOVE_DEVICE:
874 // Status = STATUS_NOT_IMPLEMENTED;
877 //case IRP_MN_CANCEL_STOP_DEVICE:
878 // Status = STATUS_NOT_IMPLEMENTED;
881 //case IRP_MN_DEVICE_USAGE_NOTIFICATION:
882 // Status = STATUS_NOT_IMPLEMENTED;
885 //case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
886 // Status = STATUS_NOT_IMPLEMENTED;
889 case IRP_MN_QUERY_DEVICE_RELATIONS
:
890 Status
= FdoQueryBusRelations(DeviceObject
, Irp
, IrpSp
);
893 //case IRP_MN_QUERY_PNP_DEVICE_STATE:
894 // Status = STATUS_NOT_IMPLEMENTED;
897 //case IRP_MN_QUERY_REMOVE_DEVICE:
898 // Status = STATUS_NOT_IMPLEMENTED;
901 //case IRP_MN_QUERY_STOP_DEVICE:
902 // Status = STATUS_NOT_IMPLEMENTED;
905 //case IRP_MN_REMOVE_DEVICE:
906 // Status = STATUS_NOT_IMPLEMENTED;
909 case IRP_MN_START_DEVICE
:
910 DPRINT("IRP_MN_START_DEVICE received\n");
911 Status
= FdoStartDevice(DeviceObject
, Irp
);
914 case IRP_MN_STOP_DEVICE
:
915 /* Currently not supported */
917 Status
= STATUS_UNSUCCESSFUL
;
920 //case IRP_MN_SURPRISE_REMOVAL:
921 // Status = STATUS_NOT_IMPLEMENTED;
925 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
926 Status
= Irp
->IoStatus
.Status
;
930 if (Status
!= STATUS_PENDING
) {
931 Irp
->IoStatus
.Status
= Status
;
932 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
935 DPRINT("Leaving. Status 0x%X\n", Status
);
944 PDEVICE_OBJECT DeviceObject
,
947 * FUNCTION: Handle power management IRPs for the ACPI device
949 * DeviceObject = Pointer to functional device object of the ACPI driver
950 * Irp = Pointer to IRP that should be handled
955 PIO_STACK_LOCATION IrpSp
;
960 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
962 switch (IrpSp
->MinorFunction
) {
963 case IRP_MN_SET_POWER
:
964 Status
= FdoSetPower(DeviceObject
, Irp
, IrpSp
);
968 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
969 Status
= STATUS_NOT_IMPLEMENTED
;
973 if (Status
!= STATUS_PENDING
) {
974 Irp
->IoStatus
.Status
= Status
;
975 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
978 DPRINT("Leaving. Status 0x%X\n", Status
);