/** @file
  SMM Power Button Dispatch2 Protocol as defined in PI 1.1 Specification
  Volume 4 System Management Mode Core Interface.

  This protocol provides the parent dispatch service for the power button SMI source generator.

  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

  @par Revision Reference:
  This protocol is from PI Version 1.1.

**/

#ifndef _SMM_POWER_BUTTON_DISPATCH2_H_
#define _SMM_POWER_BUTTON_DISPATCH2_H_

#include <Pi/PiSmmCis.h>

#define EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL_GUID \
  { \
    0x1b1183fa, 0x1823, 0x46a7, {0x88, 0x72, 0x9c, 0x57, 0x87, 0x55, 0x40, 0x9d } \
  }

///
/// Power Button phases.
///
typedef enum {
  EfiPowerButtonEntry,
  EfiPowerButtonExit,
  EfiPowerButtonMax
} EFI_POWER_BUTTON_PHASE;

///
/// The dispatch function's context.
///
typedef struct {
  ///
  /// Designates whether this handler should be invoked upon entry or exit.
  ///
  EFI_POWER_BUTTON_PHASE  Phase;
} EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT;

typedef struct _EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL;

/**
  Provides the parent dispatch service for a power button event.

  This service registers a function (DispatchFunction) which will be called when an SMI is 
  generated because the power button was pressed or released, as specified by RegisterContext. 
  On return, DispatchHandle contains a unique handle which may be used later to unregister the 
  function using UnRegister().
  The DispatchFunction will be called with Context set to the same value as was passed into 
  this function in RegisterContext and with CommBuffer and CommBufferSize set to NULL.

  @param[in]  This               Pointer to the EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL instance.
  @param[in]  DispatchFunction   Function to register for handler when power button is pressed or released.
  @param[in]  RegisterContext    Pointer to the dispatch function's context. The caller fills in this context
                                 before calling the Register() function to indicate to the Register() function
                                 the power button SMI phase for which the dispatch function should be invoked.
  @param[out] DispatchHandle     Handle generated by the dispatcher to track the function instance. 

  @retval EFI_SUCCESS            The dispatch function has been successfully
                                 registered and the SMI source has been enabled.
  @retval EFI_DEVICE_ERROR       The driver was unable to enable the SMI source.
  @retval EFI_INVALID_PARAMETER  RegisterContext is invalid. The power button input value
                                 is not within valid range.
  @retval EFI_OUT_OF_RESOURCES   There is not enough memory (system or SMM) to manage this child.
**/
typedef
EFI_STATUS
(EFIAPI *EFI_SMM_POWER_BUTTON_REGISTER2)(
  IN CONST EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL  *This,
  IN       EFI_SMM_HANDLER_ENTRY_POINT2             DispatchFunction,
  IN       EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT    *RegisterContext,
  OUT      EFI_HANDLE                               *DispatchHandle
  );

/**
  Unregisters a power-button service.

  This service removes the handler associated with DispatchHandle so that it will no longer be 
  called when the standby button is pressed or released. 

  @param[in] This                Pointer to the EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL instance.
  @param[in] DispatchHandle      Handle of the service to remove.

  @retval EFI_SUCCESS            The service has been successfully removed.
  @retval EFI_INVALID_PARAMETER  The DispatchHandle was not valid.
**/
typedef
EFI_STATUS
(EFIAPI *EFI_SMM_POWER_BUTTON_UNREGISTER2)(
  IN CONST EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL  *This,
  IN       EFI_HANDLE                               DispatchHandle
  );

///
/// Interface structure for the SMM Power Button Dispatch2 Protocol.
///
/// This protocol provides the parent dispatch service for the power button SMI source generator.
///
struct _EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL {
  EFI_SMM_POWER_BUTTON_REGISTER2    Register;
  EFI_SMM_POWER_BUTTON_UNREGISTER2  UnRegister;
};

extern EFI_GUID gEfiSmmPowerButtonDispatch2ProtocolGuid;

#endif

