-/*
- * ReactOS kernel
- * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+/* $Id$
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-/* $Id: power.c,v 1.11 2004/08/15 16:39:10 chorns Exp $
+ * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/po/power.c
* PURPOSE: Power Manager
- * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
- * UPDATE HISTORY:
- * 20/08/1999 EA Created
- * 16/04/2001 CSH Stubs added
+ *
+ * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * Hervé Poussineau (hpoussin@reactos.com)
*/
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, PoInit)
+#endif
+
+
+typedef struct _REQUEST_POWER_ITEM
+{
+ PREQUEST_POWER_COMPLETE CompletionRoutine;
+ POWER_STATE PowerState;
+ PVOID Context;
+} REQUEST_POWER_ITEM, *PREQUEST_POWER_ITEM;
PDEVICE_NODE PopSystemPowerDeviceNode = NULL;
+BOOLEAN PopAcpiPresent = FALSE;
/*
* @implemented
return NULL;
}
+static
+NTSTATUS STDCALL
+PopRequestPowerIrpCompletion(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context)
+{
+ PIO_STACK_LOCATION Stack;
+ PREQUEST_POWER_ITEM RequestPowerItem;
+
+ Stack = IoGetNextIrpStackLocation(Irp);
+ RequestPowerItem = (PREQUEST_POWER_ITEM)Context;
+
+ RequestPowerItem->CompletionRoutine(
+ DeviceObject,
+ Stack->MinorFunction,
+ RequestPowerItem->PowerState,
+ RequestPowerItem->Context,
+ &Irp->IoStatus);
+
+ ExFreePool(&Irp->IoStatus);
+ ExFreePool(Context);
+ return STATUS_SUCCESS;
+}
+
/*
- * @unimplemented
+ * @implemented
*/
NTSTATUS
STDCALL
PoRequestPowerIrp(
IN PDEVICE_OBJECT DeviceObject,
- IN UCHAR MinorFunction,
+ IN UCHAR MinorFunction,
IN POWER_STATE PowerState,
IN PREQUEST_POWER_COMPLETE CompletionFunction,
IN PVOID Context,
- OUT PIRP *Irp OPTIONAL)
+ OUT PIRP *pIrp OPTIONAL)
{
- return STATUS_NOT_IMPLEMENTED;
+ PDEVICE_OBJECT TopDeviceObject;
+ PIO_STACK_LOCATION Stack;
+ PIRP Irp;
+ PIO_STATUS_BLOCK IoStatusBlock;
+ PREQUEST_POWER_ITEM RequestPowerItem;
+ NTSTATUS Status;
+
+ if (MinorFunction != IRP_MN_QUERY_POWER
+ && MinorFunction != IRP_MN_SET_POWER
+ && MinorFunction != IRP_MN_WAIT_WAKE)
+ return STATUS_INVALID_PARAMETER_2;
+
+ RequestPowerItem = ExAllocatePool(NonPagedPool, sizeof(REQUEST_POWER_ITEM));
+ if (!RequestPowerItem)
+ return STATUS_INSUFFICIENT_RESOURCES;
+ IoStatusBlock = ExAllocatePool(NonPagedPool, sizeof(IO_STATUS_BLOCK));
+ if (!IoStatusBlock)
+ {
+ ExFreePool(RequestPowerItem);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* Always call the top of the device stack */
+ TopDeviceObject = IoGetAttachedDeviceReference(DeviceObject);
+
+ Irp = IoBuildSynchronousFsdRequest(
+ IRP_MJ_PNP,
+ TopDeviceObject,
+ NULL,
+ 0,
+ NULL,
+ NULL,
+ IoStatusBlock);
+ if (!Irp)
+ {
+ ExFreePool(RequestPowerItem);
+ ExFreePool(IoStatusBlock);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* POWER IRPs are always initialized with a status code of
+ STATUS_NOT_IMPLEMENTED */
+ Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
+ Irp->IoStatus.Information = 0;
+
+ Stack = IoGetNextIrpStackLocation(Irp);
+ Stack->MinorFunction = MinorFunction;
+ if (MinorFunction == IRP_MN_WAIT_WAKE)
+ Stack->Parameters.WaitWake.PowerState = PowerState.SystemState;
+ else
+ Stack->Parameters.WaitWake.PowerState = PowerState.DeviceState;
+
+ RequestPowerItem->CompletionRoutine = CompletionFunction;
+ RequestPowerItem->PowerState = PowerState;
+ RequestPowerItem->Context = Context;
+
+ if (pIrp != NULL)
+ *pIrp = Irp;
+
+ IoSetCompletionRoutine(Irp, PopRequestPowerIrpCompletion, RequestPowerItem, TRUE, TRUE, TRUE);
+ Status = IoCallDriver(TopDeviceObject, Irp);
+
+ /* Always return STATUS_PENDING. The completion routine
+ * will call CompletionFunction and complete the Irp.
+ */
+ return STATUS_PENDING;
}
VOID
{
POWER_STATE ps;
+ ASSERT_IRQL(DISPATCH_LEVEL);
+
ps.SystemState = PowerSystemWorking; // Fully on
ps.DeviceState = PowerDeviceD0; // Fully on
}
NTSTATUS
+NTAPI
PopSetSystemPowerState(
SYSTEM_POWER_STATE PowerState)
{
-
-#ifdef ACPI
-
IO_STATUS_BLOCK IoStatusBlock;
PDEVICE_OBJECT DeviceObject;
PIO_STACK_LOCATION IrpSp;
KEVENT Event;
PIRP Irp;
+ if (!PopAcpiPresent) return STATUS_NOT_IMPLEMENTED;
+
Status = IopGetSystemPowerDeviceObject(&DeviceObject);
if (!NT_SUCCESS(Status)) {
CPRINT("No system power driver available\n");
ObDereferenceObject(Fdo);
return Status;
-
-#endif /* ACPI */
-
- return STATUS_NOT_IMPLEMENTED;
}
-VOID INIT_FUNCTION
-PoInit(VOID)
+VOID
+INIT_FUNCTION
+NTAPI
+PoInit(PLOADER_PARAMETER_BLOCK LoaderBlock,
+ BOOLEAN ForceAcpiDisable)
{
+ if (ForceAcpiDisable)
+ {
+ /* Set the ACPI State to False if it's been forced that way */
+ PopAcpiPresent = FALSE;
+ }
+ else
+ {
+ /* Otherwise check the LoaderBlock's Flag */
+ PopAcpiPresent = (LoaderBlock->Flags & MB_FLAGS_ACPI_TABLE) ? TRUE : FALSE;
+ }
}
/*
NTSTATUS
STDCALL
NtInitiatePowerAction (
- POWER_ACTION SystemAction,
- SYSTEM_POWER_STATE MinSystemState,
- ULONG Flags,
- BOOLEAN Asynchronous)
+ IN POWER_ACTION SystemAction,
+ IN SYSTEM_POWER_STATE MinSystemState,
+ IN ULONG Flags,
+ IN BOOLEAN Asynchronous)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
/*
* @unimplemented
*/
-NTSTATUS
-STDCALL
+NTSTATUS
+STDCALL
NtPowerInformation(
- POWER_INFORMATION_LEVEL PowerInformationLevel,
- PVOID InputBuffer,
- ULONG InputBufferLength,
- PVOID OutputBuffer,
- ULONG OutputBufferLength
+ IN POWER_INFORMATION_LEVEL PowerInformationLevel,
+ IN PVOID InputBuffer OPTIONAL,
+ IN ULONG InputBufferLength,
+ OUT PVOID OutputBuffer OPTIONAL,
+ IN ULONG OutputBufferLength
)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ DPRINT("NtPowerInformation(PowerInformationLevel 0x%x, InputBuffer 0x%x, "
+ "InputBufferLength 0x%x, OutputBuffer 0x%x, OutputBufferLength 0x%x)\n",
+ PowerInformationLevel,
+ InputBuffer, InputBufferLength,
+ OutputBuffer, OutputBufferLength);
+ switch (PowerInformationLevel)
+ {
+ case SystemBatteryState:
+ {
+ PSYSTEM_BATTERY_STATE BatteryState = (PSYSTEM_BATTERY_STATE)OutputBuffer;
+
+ if (InputBuffer != NULL)
+ return STATUS_INVALID_PARAMETER;
+ if (OutputBufferLength < sizeof(SYSTEM_BATTERY_STATE))
+ return STATUS_BUFFER_TOO_SMALL;
+
+ /* Just zero the struct (and thus set BatteryState->BatteryPresent = FALSE) */
+ RtlZeroMemory(BatteryState, sizeof(SYSTEM_BATTERY_STATE));
+ BatteryState->EstimatedTime = (ULONG)-1;
+
+ Status = STATUS_SUCCESS;
+ break;
+ }
+
+ default:
+ Status = STATUS_NOT_IMPLEMENTED;
+ DPRINT1("PowerInformationLevel 0x%x is UNIMPLEMENTED! Have a nice day.\n",
+ PowerInformationLevel);
+ for (;;);
+ break;
+ }
+
+ return Status;
}
+NTSTATUS
+STDCALL
+PoQueueShutdownWorkItem(
+ IN PWORK_QUEUE_ITEM WorkItem
+ )
+{
+ PAGED_CODE();
+
+ DPRINT1("PoQueueShutdownWorkItem(%p)\n", WorkItem);
+
+ return STATUS_NOT_IMPLEMENTED;
+}
+
/* EOF */