- Silence TCPIP.
[reactos.git] / reactos / ntoskrnl / po / power.c
index b478b9c..d3f8322 100644 (file)
@@ -1,19 +1,32 @@
 /* $Id$
- * 
+ *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/po/power.c
  * PURPOSE:         Power Manager
- * 
+ *
  * 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
@@ -57,20 +70,110 @@ PoRegisterSystemState(
   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
@@ -91,7 +194,7 @@ PoSetPowerState(
   IN POWER_STATE State)
 {
   POWER_STATE ps;
-  
+
   ASSERT_IRQL(DISPATCH_LEVEL);
 
   ps.SystemState = PowerSystemWorking;  // Fully on
@@ -131,12 +234,10 @@ PoUnregisterSystemState(
 }
 
 NTSTATUS
+NTAPI
 PopSetSystemPowerState(
   SYSTEM_POWER_STATE PowerState)
 {
-
-#ifdef ACPI
-
   IO_STATUS_BLOCK IoStatusBlock;
   PDEVICE_OBJECT DeviceObject;
   PIO_STACK_LOCATION IrpSp;
@@ -145,6 +246,8 @@ PopSetSystemPowerState(
   KEVENT Event;
   PIRP Irp;
 
+  if (!PopAcpiPresent) return STATUS_NOT_IMPLEMENTED;
+
   Status = IopGetSystemPowerDeviceObject(&DeviceObject);
   if (!NT_SUCCESS(Status)) {
     CPRINT("No system power driver available\n");
@@ -190,15 +293,24 @@ PopSetSystemPowerState(
   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;
+    }
 }
 
 /*
@@ -219,8 +331,8 @@ NtInitiatePowerAction (
 /*
  * @unimplemented
  */
-NTSTATUS 
-STDCALL 
+NTSTATUS
+STDCALL
 NtPowerInformation(
        IN POWER_INFORMATION_LEVEL PowerInformationLevel,
        IN PVOID InputBuffer  OPTIONAL,
@@ -230,7 +342,7 @@ NtPowerInformation(
        )
 {
    NTSTATUS Status;
-   
+
    PAGED_CODE();
 
    DPRINT("NtPowerInformation(PowerInformationLevel 0x%x, InputBuffer 0x%x, "
@@ -268,4 +380,19 @@ NtPowerInformation(
    return Status;
 }
 
+
+NTSTATUS
+STDCALL
+PoQueueShutdownWorkItem(
+       IN PWORK_QUEUE_ITEM WorkItem
+       )
+{
+  PAGED_CODE();
+
+  DPRINT1("PoQueueShutdownWorkItem(%p)\n", WorkItem);
+
+  return STATUS_NOT_IMPLEMENTED;
+}
+
+
 /* EOF */