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)
8 * 08-08-2001 CSH Created
17 /*** PRIVATE *****************************************************************/
19 FADT_DESCRIPTOR_REV2 acpi_fadt;
23 IN PDEVICE_OBJECT DeviceObject,
25 PIO_STACK_LOCATION IrpSp)
27 PPDO_DEVICE_EXTENSION PdoDeviceExtension;
28 PFDO_DEVICE_EXTENSION DeviceExtension;
29 PDEVICE_RELATIONS Relations;
30 PLIST_ENTRY CurrentEntry;
31 ANSI_STRING AnsiString;
32 ACPI_STATUS AcpiStatus;
41 DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
43 Size = sizeof(DEVICE_RELATIONS) + sizeof(Relations->Objects) *
44 (DeviceExtension->DeviceListCount - 1);
45 Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, Size);
47 return STATUS_INSUFFICIENT_RESOURCES;
49 Relations->Count = DeviceExtension->DeviceListCount;
52 CurrentEntry = DeviceExtension->DeviceListHead.Flink;
53 while (CurrentEntry != &DeviceExtension->DeviceListHead) {
54 Device = CONTAINING_RECORD(CurrentEntry, ACPI_DEVICE, DeviceListEntry);
56 /* FIXME: For ACPI namespace devices on the motherboard create filter DOs
57 and attach them just above the ACPI bus device object (PDO) */
59 /* FIXME: For other devices in ACPI namespace, but not on motherboard,
63 /* Create a physical device object for the
64 device as it does not already have one */
65 Status = IoCreateDevice(DeviceObject->DriverObject, 0,
66 NULL, FILE_DEVICE_CONTROLLER, 0, FALSE, &Device->Pdo);
67 if (!NT_SUCCESS(Status)) {
68 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
69 /* FIXME: Cleanup all new PDOs created in this call */
70 ExFreePool(Relations);
74 PdoDeviceExtension = ExAllocatePool(
76 sizeof(PDO_DEVICE_EXTENSION));
77 if (!PdoDeviceExtension) {
78 /* FIXME: Cleanup all new PDOs created in this call */
79 ExFreePool(Relations);
84 sizeof(PDO_DEVICE_EXTENSION));
86 Device->Pdo->DeviceExtension = PdoDeviceExtension;
88 Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
90 PdoDeviceExtension->Common.DeviceObject = Device->Pdo;
92 PdoDeviceExtension->Common.DevicePowerState = PowerDeviceD0;
94 PdoDeviceExtension->Common.Ldo = IoAttachDeviceToDeviceStack(
98 RtlInitUnicodeString(&PdoDeviceExtension->HardwareIDs, NULL);
99 RtlInitUnicodeString(&PdoDeviceExtension->CompatibleIDs, NULL);
101 AcpiStatus = bm_get_node(Device->BmHandle, 0, &Node);
102 if (ACPI_SUCCESS(AcpiStatus)) {
103 if (Node->device.flags & BM_FLAGS_HAS_A_HID) {
104 RtlInitAnsiString(&AnsiString, Node->device.id.hid);
105 Status = RtlAnsiStringToUnicodeString(
106 &PdoDeviceExtension->HardwareIDs,
109 assert(NT_SUCCESS(Status));
112 if (Node->device.flags & BM_FLAGS_HAS_A_CID) {
113 RtlInitAnsiString(&AnsiString, Node->device.id.cid);
114 Status = RtlAnsiStringToUnicodeString(
115 &PdoDeviceExtension->CompatibleIDs,
118 assert(NT_SUCCESS(Status));
123 /* Reference the physical device object. The PnP manager
124 will dereference it again when it is no longer needed */
125 ObReferenceObject(Device->Pdo);
127 Relations->Objects[i] = Device->Pdo;
131 CurrentEntry = CurrentEntry->Flink;
134 Irp->IoStatus.Information = (ULONG)Relations;
141 PFDO_DEVICE_EXTENSION DeviceExtension)
143 DbgPrint("ACPI: System firmware supports:\n");
146 * Print out basic system information
148 DbgPrint("+------------------------------------------------------------\n");
149 DbgPrint("| Sx states: %cS0 %cS1 %cS2 %cS3 %cS4 %cS5\n",
150 (DeviceExtension->SystemStates[0]?'+':'-'),
151 (DeviceExtension->SystemStates[1]?'+':'-'),
152 (DeviceExtension->SystemStates[2]?'+':'-'),
153 (DeviceExtension->SystemStates[3]?'+':'-'),
154 (DeviceExtension->SystemStates[4]?'+':'-'),
155 (DeviceExtension->SystemStates[5]?'+':'-'));
156 DbgPrint("+------------------------------------------------------------\n");
160 ACPIInitializeInternalDriver(
161 PFDO_DEVICE_EXTENSION DeviceExtension,
162 ACPI_DRIVER_FUNCTION Initialize,
163 ACPI_DRIVER_FUNCTION Terminate)
165 ACPI_STATUS AcpiStatus;
166 PACPI_DEVICE AcpiDevice;
168 AcpiStatus = Initialize();
169 if (!ACPI_SUCCESS(AcpiStatus)) {
170 DPRINT("BN init status 0x%X\n", AcpiStatus);
171 return STATUS_UNSUCCESSFUL;
174 AcpiDevice = (PACPI_DEVICE)ExAllocatePool(
175 NonPagedPool, sizeof(ACPI_DEVICE));
177 return STATUS_INSUFFICIENT_RESOURCES;
180 AcpiDevice->Initialize = Initialize;
181 AcpiDevice->Terminate = Terminate;
183 /* FIXME: Create PDO */
185 AcpiDevice->Pdo = NULL;
186 //AcpiDevice->BmHandle = HandleList.handles[i];
188 ExInterlockedInsertHeadList(&DeviceExtension->DeviceListHead,
189 &AcpiDevice->ListEntry, &DeviceExtension->DeviceListLock);
191 return STATUS_SUCCESS;
196 ACPIInitializeInternalDrivers(
197 PFDO_DEVICE_EXTENSION DeviceExtension)
203 Status = ACPIInitializeInternalDriver(DeviceExtension,
204 bn_initialize, bn_terminate);
206 return STATUS_SUCCESS;
212 IN PDEVICE_OBJECT DeviceObject,
215 PFDO_DEVICE_EXTENSION DeviceExtension;
216 ACPI_PHYSICAL_ADDRESS rsdp;
217 ACPI_SYSTEM_INFO SysInfo;
218 ACPI_STATUS AcpiStatus;
225 DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
227 assert(DeviceExtension->State == dsStopped);
229 AcpiStatus = acpi_initialize_subsystem();
230 if (!ACPI_SUCCESS(AcpiStatus)) {
231 DPRINT("acpi_initialize_subsystem() failed with status 0x%X\n", AcpiStatus);
232 return STATUS_UNSUCCESSFUL;
235 AcpiStatus = acpi_find_root_pointer(&rsdp);
236 if (!ACPI_SUCCESS(AcpiStatus)) {
237 DPRINT("acpi_find_root_pointer() failed with status 0x%X\n", AcpiStatus);
238 return STATUS_UNSUCCESSFUL;
241 /* From this point on, on error we must call acpi_terminate() */
243 AcpiStatus = acpi_load_tables(rsdp);
244 if (!ACPI_SUCCESS(AcpiStatus)) {
245 DPRINT("acpi_load_tables() failed with status 0x%X\n", AcpiStatus);
247 return STATUS_UNSUCCESSFUL;
250 Buffer.length = sizeof(SysInfo);
251 Buffer.pointer = &SysInfo;
253 AcpiStatus = acpi_get_system_info(&Buffer);
254 if (!ACPI_SUCCESS(AcpiStatus)) {
255 DPRINT("acpi_get_system_info() failed with status 0x%X\n", AcpiStatus);
257 return STATUS_UNSUCCESSFUL;
260 DPRINT("ACPI CA Core Subsystem version 0x%X\n", SysInfo.acpi_ca_version);
262 assert(SysInfo.num_table_types > ACPI_TABLE_FADT);
264 RtlMoveMemory(&acpi_fadt,
265 &SysInfo.table_info[ACPI_TABLE_FADT],
266 sizeof(FADT_DESCRIPTOR_REV2));
268 AcpiStatus = acpi_enable_subsystem(ACPI_FULL_INITIALIZATION);
269 if (!ACPI_SUCCESS(AcpiStatus)) {
270 DPRINT("acpi_enable_subsystem() failed with status 0x%X\n", AcpiStatus);
272 return STATUS_UNSUCCESSFUL;
275 DPRINT("ACPI CA Core Subsystem enabled\n");
280 * Figure out which Sx states are supported
282 for (i=0; i<=ACPI_S_STATES_MAX; i++) {
283 AcpiStatus = acpi_hw_obtain_sleep_type_register_data(
287 DPRINT("acpi_hw_obtain_sleep_type_register_data (%d) status 0x%X\n",
289 if (ACPI_SUCCESS(AcpiStatus)) {
290 DeviceExtension->SystemStates[i] = TRUE;
294 ACPIPrintInfo(DeviceExtension);
296 /* Initialize ACPI bus manager */
297 AcpiStatus = bm_initialize();
298 if (!ACPI_SUCCESS(AcpiStatus)) {
299 DPRINT("bm_initialize() failed with status 0x%X\n", AcpiStatus);
301 return STATUS_UNSUCCESSFUL;
304 InitializeListHead(&DeviceExtension->DeviceListHead);
305 KeInitializeSpinLock(&DeviceExtension->DeviceListLock);
306 DeviceExtension->DeviceListCount = 0;
308 ACPIEnumerateNamespace(DeviceExtension);
310 //ACPIEnumerateRootBusses(DeviceExtension);
312 ACPIInitializeInternalDrivers(DeviceExtension);
314 DeviceExtension->State = dsStarted;
316 return STATUS_SUCCESS;
322 IN PDEVICE_OBJECT DeviceObject,
324 PIO_STACK_LOCATION IrpSp)
326 PFDO_DEVICE_EXTENSION DeviceExtension;
327 ACPI_STATUS AcpiStatus;
333 DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
335 if (IrpSp->Parameters.Power.Type == SystemPowerState) {
336 Status = STATUS_SUCCESS;
337 switch (IrpSp->Parameters.Power.State.SystemState) {
338 case PowerSystemSleeping1:
339 AcpiState = ACPI_STATE_S1;
341 case PowerSystemSleeping2:
342 AcpiState = ACPI_STATE_S2;
344 case PowerSystemSleeping3:
345 AcpiState = ACPI_STATE_S3;
347 case PowerSystemHibernate:
348 AcpiState = ACPI_STATE_S4;
350 case PowerSystemShutdown:
351 AcpiState = ACPI_STATE_S5;
354 Status = STATUS_UNSUCCESSFUL;
356 if (!DeviceExtension->SystemStates[AcpiState]) {
357 DPRINT("System sleep state S%d is not supported by hardware\n", AcpiState);
358 Status = STATUS_UNSUCCESSFUL;
361 if (NT_SUCCESS(Status)) {
362 DPRINT("Trying to enter sleep state %d\n", AcpiState);
364 AcpiStatus = acpi_enter_sleep_state(AcpiState);
365 if (!ACPI_SUCCESS(AcpiStatus)) {
366 DPRINT("Failed to enter sleep state %d (Status 0x%X)\n",
367 AcpiState, AcpiStatus);
368 Status = STATUS_UNSUCCESSFUL;
372 Status = STATUS_UNSUCCESSFUL;
379 /*** PUBLIC ******************************************************************/
384 PDEVICE_OBJECT DeviceObject,
387 * FUNCTION: Handle Plug and Play IRPs for the ACPI device
389 * DeviceObject = Pointer to functional device object of the ACPI driver
390 * Irp = Pointer to IRP that should be handled
395 PIO_STACK_LOCATION IrpSp;
400 IrpSp = IoGetCurrentIrpStackLocation(Irp);
401 switch (IrpSp->MinorFunction) {
402 case IRP_MN_CANCEL_REMOVE_DEVICE:
403 Status = STATUS_NOT_IMPLEMENTED;
406 case IRP_MN_CANCEL_STOP_DEVICE:
407 Status = STATUS_NOT_IMPLEMENTED;
410 case IRP_MN_DEVICE_USAGE_NOTIFICATION:
411 Status = STATUS_NOT_IMPLEMENTED;
414 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
415 Status = STATUS_NOT_IMPLEMENTED;
418 case IRP_MN_QUERY_DEVICE_RELATIONS:
419 Status = FdoQueryBusRelations(DeviceObject, Irp, IrpSp);
422 case IRP_MN_QUERY_PNP_DEVICE_STATE:
423 Status = STATUS_NOT_IMPLEMENTED;
426 case IRP_MN_QUERY_REMOVE_DEVICE:
427 Status = STATUS_NOT_IMPLEMENTED;
430 case IRP_MN_QUERY_STOP_DEVICE:
431 Status = STATUS_NOT_IMPLEMENTED;
434 case IRP_MN_REMOVE_DEVICE:
435 Status = STATUS_NOT_IMPLEMENTED;
438 case IRP_MN_START_DEVICE:
439 DPRINT("IRP_MN_START_DEVICE received\n");
440 Status = FdoStartDevice(DeviceObject, Irp);
443 case IRP_MN_STOP_DEVICE:
444 /* Currently not supported */
446 Status = STATUS_UNSUCCESSFUL;
449 case IRP_MN_SURPRISE_REMOVAL:
450 Status = STATUS_NOT_IMPLEMENTED;
454 DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
455 Status = STATUS_NOT_IMPLEMENTED;
459 if (Status != STATUS_PENDING) {
460 Irp->IoStatus.Status = Status;
461 IoCompleteRequest(Irp, IO_NO_INCREMENT);
464 DPRINT("Leaving. Status 0x%X\n", Status);
473 PDEVICE_OBJECT DeviceObject,
476 * FUNCTION: Handle power management IRPs for the ACPI device
478 * DeviceObject = Pointer to functional device object of the ACPI driver
479 * Irp = Pointer to IRP that should be handled
484 PIO_STACK_LOCATION IrpSp;
489 IrpSp = IoGetCurrentIrpStackLocation(Irp);
491 switch (IrpSp->MinorFunction) {
492 case IRP_MN_SET_POWER:
493 Status = FdoSetPower(DeviceObject, Irp, IrpSp);
497 DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
498 Status = STATUS_NOT_IMPLEMENTED;
502 if (Status != STATUS_PENDING) {
503 Irp->IoStatus.Status = Status;
504 IoCompleteRequest(Irp, IO_NO_INCREMENT);
507 DPRINT("Leaving. Status 0x%X\n", Status);