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
"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
;
179 /* Count number of resources */
181 resource
= resources
;
184 switch (resource
->id
)
188 IRQ_RESOURCE
*irq_data
= (IRQ_RESOURCE
*) &resource
->data
;
189 NumberOfResources
+= irq_data
->number_of_interrupts
;
194 DMA_RESOURCE
*dma_data
= (DMA_RESOURCE
*) &resource
->data
;
195 NumberOfResources
+= dma_data
->number_of_channels
;
213 resource
= (RESOURCE
*) ((NATIVE_UINT
) resource
+ (NATIVE_UINT
) resource
->length
);
216 /* Allocate memory */
217 *ResourceListSize
= sizeof(CM_RESOURCE_LIST
) + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR
) * (NumberOfResources
- 1);
218 ResourceList
= (PCM_RESOURCE_LIST
)ExAllocatePool(PagedPool
, *ResourceListSize
);
219 *pResourceList
= ResourceList
;
222 ResourceList
->Count
= 1;
223 ResourceList
->List
[0].InterfaceType
= Internal
; /* FIXME */
224 ResourceList
->List
[0].BusNumber
= 0; /* We're the only ACPI bus device in the system */
225 ResourceList
->List
[0].PartialResourceList
.Version
= 1;
226 ResourceList
->List
[0].PartialResourceList
.Revision
= 1;
227 ResourceList
->List
[0].PartialResourceList
.Count
= NumberOfResources
;
228 ResourceDescriptor
= ResourceList
->List
[0].PartialResourceList
.PartialDescriptors
;
230 *RequirementsListSize
= sizeof(IO_RESOURCE_REQUIREMENTS_LIST
) + sizeof(IO_RESOURCE_DESCRIPTOR
) * (NumberOfResources
- 1);
231 RequirementsList
= (PIO_RESOURCE_REQUIREMENTS_LIST
)ExAllocatePool(PagedPool
, *RequirementsListSize
);
232 *pRequirementsList
= RequirementsList
;
233 if (!RequirementsList
)
235 ExFreePool(ResourceList
);
238 RequirementsList
->ListSize
= *RequirementsListSize
;
239 RequirementsList
->InterfaceType
= ResourceList
->List
[0].InterfaceType
;
240 RequirementsList
->BusNumber
= ResourceList
->List
[0].BusNumber
;
241 RequirementsList
->SlotNumber
= 0; /* Not used by WDM drivers */
242 RequirementsList
->AlternativeLists
= 1;
243 RequirementsList
->List
[0].Version
= 1;
244 RequirementsList
->List
[0].Revision
= 1;
245 RequirementsList
->List
[0].Count
= NumberOfResources
;
246 RequirementDescriptor
= RequirementsList
->List
[0].Descriptors
;
248 /* Fill resources list structure */
250 resource
= resources
;
253 switch (resource
->id
)
257 IRQ_RESOURCE
*irq_data
= (IRQ_RESOURCE
*) &resource
->data
;
258 for (i
= 0; i
< irq_data
->number_of_interrupts
; i
++)
260 ResourceDescriptor
->Type
= CmResourceTypeInterrupt
;
262 ResourceDescriptor
->ShareDisposition
=
263 (irq_data
->shared_exclusive
== SHARED
? CmResourceShareShared
: CmResourceShareDeviceExclusive
);
264 ResourceDescriptor
->Flags
=
265 (irq_data
->edge_level
== LEVEL_SENSITIVE
? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
: CM_RESOURCE_INTERRUPT_LATCHED
);
266 ResourceDescriptor
->u
.Interrupt
.Vector
= HalGetInterruptVector(
267 Internal
, 0, 0, irq_data
->interrupts
[i
],
269 &ResourceDescriptor
->u
.Interrupt
.Affinity
);
270 ResourceDescriptor
->u
.Interrupt
.Level
= (ULONG
)Dirql
;
272 RequirementDescriptor
->Option
= 0; /* Required */
273 RequirementDescriptor
->Type
= ResourceDescriptor
->Type
;
274 RequirementDescriptor
->ShareDisposition
= ResourceDescriptor
->ShareDisposition
;
275 RequirementDescriptor
->Flags
= ResourceDescriptor
->Flags
;
276 RequirementDescriptor
->u
.Interrupt
.MinimumVector
= RequirementDescriptor
->u
.Interrupt
.MaximumVector
277 = irq_data
->interrupts
[i
];
279 ResourceDescriptor
++;
280 RequirementDescriptor
++;
286 DMA_RESOURCE
*dma_data
= (DMA_RESOURCE
*) &resource
->data
;
287 for (i
= 0; i
< dma_data
->number_of_channels
; i
++)
289 ResourceDescriptor
->Type
= CmResourceTypeDma
;
290 ResourceDescriptor
->Flags
= 0;
291 switch (dma_data
->type
)
293 case TYPE_A
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_A
; break;
294 case TYPE_B
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_B
; break;
295 case TYPE_F
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_TYPE_F
; break;
297 if (dma_data
->bus_master
== BUS_MASTER
)
298 ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_BUS_MASTER
;
299 switch (dma_data
->transfer
)
301 case TRANSFER_8
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_8
; break;
302 case TRANSFER_16
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_16
; break;
303 case TRANSFER_8_16
: ResourceDescriptor
->Flags
|= CM_RESOURCE_DMA_8_AND_16
; break;
305 ResourceDescriptor
->u
.Dma
.Channel
= dma_data
->channels
[i
];
307 RequirementDescriptor
->Option
= 0; /* Required */
308 RequirementDescriptor
->Type
= ResourceDescriptor
->Type
;
309 RequirementDescriptor
->ShareDisposition
= ResourceDescriptor
->ShareDisposition
;
310 RequirementDescriptor
->Flags
= ResourceDescriptor
->Flags
;
311 RequirementDescriptor
->u
.Dma
.MinimumChannel
= RequirementDescriptor
->u
.Dma
.MaximumChannel
312 = ResourceDescriptor
->u
.Dma
.Channel
;
314 ResourceDescriptor
++;
315 RequirementDescriptor
++;
321 IO_RESOURCE
*io_data
= (IO_RESOURCE
*) &resource
->data
;
322 ResourceDescriptor
->Type
= CmResourceTypePort
;
323 ResourceDescriptor
->ShareDisposition
= CmResourceShareDriverExclusive
;
324 ResourceDescriptor
->Flags
= CM_RESOURCE_PORT_IO
;
325 if (io_data
->io_decode
== DECODE_16
)
326 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_16_BIT_DECODE
;
328 ResourceDescriptor
->Flags
|= CM_RESOURCE_PORT_10_BIT_DECODE
;
329 ResourceDescriptor
->u
.Port
.Start
.u
.HighPart
= 0;
330 ResourceDescriptor
->u
.Port
.Start
.u
.LowPart
= io_data
->min_base_address
;
331 ResourceDescriptor
->u
.Port
.Length
= io_data
->range_length
;
333 RequirementDescriptor
->Option
= 0; /* Required */
334 RequirementDescriptor
->Type
= ResourceDescriptor
->Type
;
335 RequirementDescriptor
->ShareDisposition
= ResourceDescriptor
->ShareDisposition
;
336 RequirementDescriptor
->Flags
= ResourceDescriptor
->Flags
;
337 RequirementDescriptor
->u
.Port
.Length
= ResourceDescriptor
->u
.Port
.Length
;
338 RequirementDescriptor
->u
.Port
.Alignment
= 1; /* Start address is specified, so it doesn't matter */
339 RequirementDescriptor
->u
.Port
.MinimumAddress
= RequirementDescriptor
->u
.Port
.MaximumAddress
340 = ResourceDescriptor
->u
.Port
.Start
;
342 ResourceDescriptor
++;
343 RequirementDescriptor
++;
356 resource
= (RESOURCE
*) ((NATIVE_UINT
) resource
+ (NATIVE_UINT
) resource
->length
);
359 acpi_rs_dump_resource_list(resource
);
365 FdoQueryBusRelations(
366 IN PDEVICE_OBJECT DeviceObject
,
368 PIO_STACK_LOCATION IrpSp
)
370 PPDO_DEVICE_EXTENSION PdoDeviceExtension
;
371 PFDO_DEVICE_EXTENSION DeviceExtension
;
372 PDEVICE_RELATIONS Relations
;
373 PLIST_ENTRY CurrentEntry
;
374 ACPI_STATUS AcpiStatus
;
376 NTSTATUS Status
= STATUS_SUCCESS
;
383 DeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
385 Size
= sizeof(DEVICE_RELATIONS
) + sizeof(Relations
->Objects
) *
386 (DeviceExtension
->DeviceListCount
- 1);
387 Relations
= (PDEVICE_RELATIONS
)ExAllocatePool(PagedPool
, Size
);
389 return STATUS_INSUFFICIENT_RESOURCES
;
391 Relations
->Count
= DeviceExtension
->DeviceListCount
;
394 CurrentEntry
= DeviceExtension
->DeviceListHead
.Flink
;
395 while (CurrentEntry
!= &DeviceExtension
->DeviceListHead
)
398 Device
= CONTAINING_RECORD(CurrentEntry
, ACPI_DEVICE
, DeviceListEntry
);
400 /* FIXME: For ACPI namespace devices on the motherboard create filter DOs
401 and attach them just above the ACPI bus device object (PDO) */
403 /* FIXME: For other devices in ACPI namespace, but not on motherboard,
408 /* Create a physical device object for the
409 device as it does not already have one */
410 Status
= IoCreateDevice(DeviceObject
->DriverObject
,
411 sizeof(PDO_DEVICE_EXTENSION
),
413 FILE_DEVICE_CONTROLLER
,
414 FILE_AUTOGENERATED_DEVICE_NAME
,
417 if (!NT_SUCCESS(Status
))
419 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status
);
420 /* FIXME: Cleanup all new PDOs created in this call */
421 ExFreePool(Relations
);
425 PdoDeviceExtension
= (PPDO_DEVICE_EXTENSION
)Device
->Pdo
->DeviceExtension
;
427 RtlZeroMemory(PdoDeviceExtension
, sizeof(PDO_DEVICE_EXTENSION
));
429 Device
->Pdo
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
431 Device
->Pdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
433 //Device->Pdo->Flags |= DO_POWER_PAGABLE;
435 PdoDeviceExtension
->Common
.DeviceObject
= Device
->Pdo
;
437 PdoDeviceExtension
->Common
.DevicePowerState
= PowerDeviceD0
;
439 // PdoDeviceExtension->Common.Ldo = IoAttachDeviceToDeviceStack(DeviceObject,
442 RtlInitUnicodeString(&PdoDeviceExtension
->DeviceID
, NULL
);
443 RtlInitUnicodeString(&PdoDeviceExtension
->InstanceID
, NULL
);
444 RtlInitUnicodeString(&PdoDeviceExtension
->HardwareIDs
, NULL
);
446 AcpiStatus
= bm_get_node(Device
->BmHandle
, 0, &Node
);
447 if (ACPI_SUCCESS(AcpiStatus
))
449 /* Get current resources */
451 Status
= acpi_get_current_resources(Node
->device
.acpi_handle
, &Buffer
);
452 if ((Status
& ACPI_OK
) == 0)
456 if (Buffer
.length
> 0)
458 Buffer
.pointer
= ExAllocatePool(PagedPool
, Buffer
.length
);
463 Status
= acpi_get_current_resources(Node
->device
.acpi_handle
, &Buffer
);
464 if (ACPI_FAILURE(Status
))
468 if (!AcpiCreateResourceList(&PdoDeviceExtension
->ResourceList
,
469 &PdoDeviceExtension
->ResourceListSize
,
470 &PdoDeviceExtension
->ResourceRequirementsList
,
471 &PdoDeviceExtension
->ResourceRequirementsListSize
,
472 (RESOURCE
*)Buffer
.pointer
))
476 ExFreePool(Buffer
.pointer
);
479 /* Add Device ID string */
480 if (!AcpiCreateDeviceIDString(&PdoDeviceExtension
->DeviceID
,
484 // ErrorStatus = STATUS_INSUFFICIENT_RESOURCES;
485 // ErrorOccurred = TRUE;
489 if (!AcpiCreateInstanceIDString(&PdoDeviceExtension
->InstanceID
,
493 // ErrorStatus = STATUS_INSUFFICIENT_RESOURCES;
494 // ErrorOccurred = TRUE;
498 if (!AcpiCreateHardwareIDsString(&PdoDeviceExtension
->HardwareIDs
,
502 // ErrorStatus = STATUS_INSUFFICIENT_RESOURCES;
503 // ErrorOccurred = TRUE;
507 if (!AcpiCreateDeviceDescriptionString(&PdoDeviceExtension
->DeviceDescription
,
511 // ErrorStatus = STATUS_INSUFFICIENT_RESOURCES;
512 // ErrorOccurred = TRUE;
518 /* Reference the physical device object. The PnP manager
519 will dereference it again when it is no longer needed */
520 ObReferenceObject(Device
->Pdo
);
522 Relations
->Objects
[i
] = Device
->Pdo
;
526 CurrentEntry
= CurrentEntry
->Flink
;
529 Irp
->IoStatus
.Information
= (ULONG
)Relations
;
537 PFDO_DEVICE_EXTENSION DeviceExtension
)
539 DbgPrint("ACPI: System firmware supports:\n");
542 * Print out basic system information
544 DbgPrint("+------------------------------------------------------------\n");
545 DbgPrint("| Sx states: %cS0 %cS1 %cS2 %cS3 %cS4 %cS5\n",
546 (DeviceExtension
->SystemStates
[0]?'+':'-'),
547 (DeviceExtension
->SystemStates
[1]?'+':'-'),
548 (DeviceExtension
->SystemStates
[2]?'+':'-'),
549 (DeviceExtension
->SystemStates
[3]?'+':'-'),
550 (DeviceExtension
->SystemStates
[4]?'+':'-'),
551 (DeviceExtension
->SystemStates
[5]?'+':'-'));
552 DbgPrint("+------------------------------------------------------------\n");
557 ACPIInitializeInternalDriver(
558 PFDO_DEVICE_EXTENSION DeviceExtension
,
559 ACPI_DRIVER_FUNCTION Initialize
,
560 ACPI_DRIVER_FUNCTION Terminate
)
562 ACPI_STATUS AcpiStatus
;
564 AcpiStatus
= Initialize();
565 if (!ACPI_SUCCESS(AcpiStatus
)) {
566 DPRINT("BN init status 0x%X\n", AcpiStatus
);
567 return STATUS_UNSUCCESSFUL
;
570 AcpiDevice
= (PACPI_DEVICE
)ExAllocatePool(
571 NonPagedPool
, sizeof(ACPI_DEVICE
));
573 return STATUS_INSUFFICIENT_RESOURCES
;
576 AcpiDevice
->Initialize
= Initialize
;
577 AcpiDevice
->Terminate
= Terminate
;
579 /* FIXME: Create PDO */
581 AcpiDevice
->Pdo
= NULL
;
582 //AcpiDevice->BmHandle = HandleList.handles[i];
584 ExInterlockedInsertHeadList(&DeviceExtension
->DeviceListHead
,
585 &AcpiDevice
->ListEntry
, &DeviceExtension
->DeviceListLock
);
587 return STATUS_SUCCESS
;
592 ACPIInitializeInternalDrivers(
593 PFDO_DEVICE_EXTENSION DeviceExtension
)
597 Status
= ACPIInitializeInternalDriver(DeviceExtension
,
598 bn_initialize
, bn_terminate
);
600 return STATUS_SUCCESS
;
606 IN PDEVICE_OBJECT DeviceObject
,
609 PFDO_DEVICE_EXTENSION DeviceExtension
;
610 ACPI_PHYSICAL_ADDRESS rsdp
;
611 ACPI_SYSTEM_INFO SysInfo
;
612 ACPI_STATUS AcpiStatus
;
619 DeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
621 ASSERT(DeviceExtension
->State
== dsStopped
);
623 AcpiStatus
= acpi_initialize_subsystem();
624 if (!ACPI_SUCCESS(AcpiStatus
)) {
625 DPRINT("acpi_initialize_subsystem() failed with status 0x%X\n", AcpiStatus
);
626 return STATUS_UNSUCCESSFUL
;
629 AcpiStatus
= acpi_find_root_pointer(&rsdp
);
630 if (!ACPI_SUCCESS(AcpiStatus
)) {
631 DPRINT("acpi_find_root_pointer() failed with status 0x%X\n", AcpiStatus
);
632 return STATUS_UNSUCCESSFUL
;
635 /* From this point on, on error we must call acpi_terminate() */
637 AcpiStatus
= acpi_load_tables(rsdp
);
638 if (!ACPI_SUCCESS(AcpiStatus
)) {
639 DPRINT("acpi_load_tables() failed with status 0x%X\n", AcpiStatus
);
641 return STATUS_UNSUCCESSFUL
;
644 Buffer
.length
= sizeof(SysInfo
);
645 Buffer
.pointer
= &SysInfo
;
647 AcpiStatus
= acpi_get_system_info(&Buffer
);
648 if (!ACPI_SUCCESS(AcpiStatus
)) {
649 DPRINT("acpi_get_system_info() failed with status 0x%X\n", AcpiStatus
);
651 return STATUS_UNSUCCESSFUL
;
654 DPRINT("ACPI CA Core Subsystem version 0x%X\n", SysInfo
.acpi_ca_version
);
656 ASSERT(SysInfo
.num_table_types
> ACPI_TABLE_FADT
);
658 RtlMoveMemory(&acpi_fadt
,
659 &SysInfo
.table_info
[ACPI_TABLE_FADT
],
660 sizeof(FADT_DESCRIPTOR_REV2
));
662 AcpiStatus
= acpi_enable_subsystem(ACPI_FULL_INITIALIZATION
);
663 if (!ACPI_SUCCESS(AcpiStatus
)) {
664 DPRINT("acpi_enable_subsystem() failed with status 0x%X\n", AcpiStatus
);
666 return STATUS_UNSUCCESSFUL
;
669 DPRINT("ACPI CA Core Subsystem enabled\n");
674 * Figure out which Sx states are supported
676 for (i
=0; i
<=ACPI_S_STATES_MAX
; i
++) {
677 AcpiStatus
= acpi_hw_obtain_sleep_type_register_data(
681 DPRINT("acpi_hw_obtain_sleep_type_register_data (%d) status 0x%X\n",
683 if (ACPI_SUCCESS(AcpiStatus
)) {
684 DeviceExtension
->SystemStates
[i
] = TRUE
;
689 ACPIPrintInfo(DeviceExtension
);
692 /* Initialize ACPI bus manager */
693 AcpiStatus
= bm_initialize();
694 if (!ACPI_SUCCESS(AcpiStatus
)) {
695 DPRINT("bm_initialize() failed with status 0x%X\n", AcpiStatus
);
697 return STATUS_UNSUCCESSFUL
;
700 InitializeListHead(&DeviceExtension
->DeviceListHead
);
701 KeInitializeSpinLock(&DeviceExtension
->DeviceListLock
);
702 DeviceExtension
->DeviceListCount
= 0;
704 ACPIEnumerateDevices(DeviceExtension
);
706 ACPIInitializeInternalDrivers(DeviceExtension
);
708 DeviceExtension
->State
= dsStarted
;
710 return STATUS_SUCCESS
;
716 IN PDEVICE_OBJECT DeviceObject
,
718 PIO_STACK_LOCATION IrpSp
)
720 PFDO_DEVICE_EXTENSION DeviceExtension
;
721 ACPI_STATUS AcpiStatus
;
727 DeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
729 if (IrpSp
->Parameters
.Power
.Type
== SystemPowerState
) {
730 Status
= STATUS_SUCCESS
;
731 switch (IrpSp
->Parameters
.Power
.State
.SystemState
) {
732 case PowerSystemSleeping1
:
733 AcpiState
= ACPI_STATE_S1
;
735 case PowerSystemSleeping2
:
736 AcpiState
= ACPI_STATE_S2
;
738 case PowerSystemSleeping3
:
739 AcpiState
= ACPI_STATE_S3
;
741 case PowerSystemHibernate
:
742 AcpiState
= ACPI_STATE_S4
;
744 case PowerSystemShutdown
:
745 AcpiState
= ACPI_STATE_S5
;
748 Status
= STATUS_UNSUCCESSFUL
;
751 if (!DeviceExtension
->SystemStates
[AcpiState
]) {
752 DPRINT("System sleep state S%d is not supported by hardware\n", AcpiState
);
753 Status
= STATUS_UNSUCCESSFUL
;
756 if (NT_SUCCESS(Status
)) {
757 DPRINT("Trying to enter sleep state %d\n", AcpiState
);
759 AcpiStatus
= acpi_enter_sleep_state(AcpiState
);
760 if (!ACPI_SUCCESS(AcpiStatus
)) {
761 DPRINT("Failed to enter sleep state %d (Status 0x%X)\n",
762 AcpiState
, AcpiStatus
);
763 Status
= STATUS_UNSUCCESSFUL
;
767 Status
= STATUS_UNSUCCESSFUL
;
774 /*** PUBLIC ******************************************************************/
779 PDEVICE_OBJECT DeviceObject
,
782 * FUNCTION: Handle Plug and Play IRPs for the ACPI device
784 * DeviceObject = Pointer to functional device object of the ACPI driver
785 * Irp = Pointer to IRP that should be handled
790 PIO_STACK_LOCATION IrpSp
;
795 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
796 switch (IrpSp
->MinorFunction
) {
797 case IRP_MN_CANCEL_REMOVE_DEVICE
:
798 Status
= STATUS_NOT_IMPLEMENTED
;
801 case IRP_MN_CANCEL_STOP_DEVICE
:
802 Status
= STATUS_NOT_IMPLEMENTED
;
805 case IRP_MN_DEVICE_USAGE_NOTIFICATION
:
806 Status
= STATUS_NOT_IMPLEMENTED
;
809 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
810 Status
= STATUS_NOT_IMPLEMENTED
;
813 case IRP_MN_QUERY_DEVICE_RELATIONS
:
814 Status
= FdoQueryBusRelations(DeviceObject
, Irp
, IrpSp
);
817 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
818 Status
= STATUS_NOT_IMPLEMENTED
;
821 case IRP_MN_QUERY_REMOVE_DEVICE
:
822 Status
= STATUS_NOT_IMPLEMENTED
;
825 case IRP_MN_QUERY_STOP_DEVICE
:
826 Status
= STATUS_NOT_IMPLEMENTED
;
829 case IRP_MN_REMOVE_DEVICE
:
830 Status
= STATUS_NOT_IMPLEMENTED
;
833 case IRP_MN_START_DEVICE
:
834 DPRINT("IRP_MN_START_DEVICE received\n");
835 Status
= FdoStartDevice(DeviceObject
, Irp
);
838 case IRP_MN_STOP_DEVICE
:
839 /* Currently not supported */
841 Status
= STATUS_UNSUCCESSFUL
;
844 case IRP_MN_SURPRISE_REMOVAL
:
845 Status
= STATUS_NOT_IMPLEMENTED
;
849 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
850 Status
= STATUS_NOT_IMPLEMENTED
;
854 if (Status
!= STATUS_PENDING
) {
855 Irp
->IoStatus
.Status
= Status
;
856 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
859 DPRINT("Leaving. Status 0x%X\n", Status
);
868 PDEVICE_OBJECT DeviceObject
,
871 * FUNCTION: Handle power management IRPs for the ACPI device
873 * DeviceObject = Pointer to functional device object of the ACPI driver
874 * Irp = Pointer to IRP that should be handled
879 PIO_STACK_LOCATION IrpSp
;
884 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
886 switch (IrpSp
->MinorFunction
) {
887 case IRP_MN_SET_POWER
:
888 Status
= FdoSetPower(DeviceObject
, Irp
, IrpSp
);
892 DPRINT("Unknown IOCTL 0x%X\n", IrpSp
->MinorFunction
);
893 Status
= STATUS_NOT_IMPLEMENTED
;
897 if (Status
!= STATUS_PENDING
) {
898 Irp
->IoStatus
.Status
= Status
;
899 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
902 DPRINT("Leaving. Status 0x%X\n", Status
);