/** @file
  This is service binding for Hash driver.

Copyright (c) 2015 - 2016, 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 that 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.

**/

#include "Driver.h"

EFI_SERVICE_BINDING_PROTOCOL    mHash2ServiceBindingProtocol = {
  Hash2ServiceBindingCreateChild,
  Hash2ServiceBindingDestroyChild
};

/**
  Creates a child handle with a set of I/O services.

  @param[in]       This              Protocol instance pointer.
  @param[in, out]  ChildHandle       Pointer to the handle of the child to create. If
                                     it is NULL, then a new handle is created. If
                                     it is not NULL, then the I/O services are added
                                     to the existing child handle.

  @retval EFI_SUCCES                 The protocol was added to ChildHandle.
  @retval EFI_INVALID_PARAMETER      ChildHandle is NULL.
  @retval EFI_OUT_OF_RESOURCES       There are not enough resources available to
                                     create the child.
  @retval Others                     The child handle was not created.

**/
EFI_STATUS
EFIAPI
Hash2ServiceBindingCreateChild (
  IN     EFI_SERVICE_BINDING_PROTOCOL    *This,
  IN OUT EFI_HANDLE                      *ChildHandle
  )
{
  EFI_STATUS          Status;
  HASH2_SERVICE_DATA  *Hash2ServiceData;
  HASH2_INSTANCE_DATA *Instance;
  EFI_TPL             OldTpl;

  if ((This == NULL) || (ChildHandle == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Hash2ServiceData = HASH2_SERVICE_DATA_FROM_THIS (This);

  //
  // Allocate buffer for the new instance.
  //
  Instance = AllocateZeroPool (sizeof (HASH2_INSTANCE_DATA));
  if (Instance == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Init the instance data.
  //
  Instance->Signature = HASH2_INSTANCE_DATA_SIGNATURE;
  CopyMem (&Instance->Hash2Protocol, &mHash2Protocol, sizeof (Instance->Hash2Protocol));
  Instance->Hash2ServiceData = Hash2ServiceData;

  Status = gBS->InstallMultipleProtocolInterfaces (
                  ChildHandle,
                  &gEfiHash2ProtocolGuid,
                  &Instance->Hash2Protocol,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    FreePool (Instance);
    return Status;
  }

  Instance->Handle = *ChildHandle;

  //
  // Add the child instance into ChildrenList.
  //
  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  InsertTailList (&Hash2ServiceData->ChildrenList, &Instance->InstEntry);

  gBS->RestoreTPL (OldTpl);

  return Status;
}


/**
  Destroys a child handle with a set of I/O services.

  The DestroyChild() function does the opposite of CreateChild(). It removes a
  protocol that was installed by CreateChild() from ChildHandle. If the removed
  protocol is the last protocol on ChildHandle, then ChildHandle is destroyed.

  @param[in]  This               Pointer to the EFI_SERVICE_BINDING_PROTOCOL
                                 instance.
  @param[in]  ChildHandle        Handle of the child to destroy.

  @retval EFI_SUCCES             The protocol was removed from ChildHandle.
  @retval EFI_UNSUPPORTED        ChildHandle does not support the protocol that
                                 is being removed.
  @retval EFI_INVALID_PARAMETER  ChildHandle is NULL.
  @retval EFI_ACCESS_DENIED      The protocol could not be removed from the
                                 ChildHandle because its services are being
                                 used.
  @retval Others                 The child handle was not destroyed.

**/
EFI_STATUS
EFIAPI
Hash2ServiceBindingDestroyChild (
  IN EFI_SERVICE_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                      ChildHandle
  )
{
  EFI_STATUS                     Status;
  HASH2_SERVICE_DATA             *Hash2ServiceData;
  EFI_HASH2_PROTOCOL             *Hash2Protocol;
  HASH2_INSTANCE_DATA            *Instance;
  EFI_TPL                        OldTpl;
  LIST_ENTRY                     *Entry;

  if ((This == NULL) || (ChildHandle == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Hash2ServiceData = HASH2_SERVICE_DATA_FROM_THIS (This);

  //
  // Check if this ChildHandle is valid
  //
  Instance = NULL;
  for(Entry = (&Hash2ServiceData->ChildrenList)->ForwardLink; Entry != (&Hash2ServiceData->ChildrenList); Entry = Entry->ForwardLink) {
    Instance = HASH2_INSTANCE_DATA_FROM_LINK (Entry);
    if (Instance->Handle == ChildHandle) {
      break;
    } else {
      Instance = NULL;
    }
  }
  if (Instance == NULL) {
    DEBUG ((EFI_D_ERROR, "Hash2ServiceBindingDestroyChild - Invalid handle\n"));
    return EFI_UNSUPPORTED;
  }

  //
  // Get HashProtocol
  //
  Status = gBS->HandleProtocol (
                  ChildHandle,
                  &gEfiHash2ProtocolGuid,
                  (VOID **)&Hash2Protocol
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  ASSERT (Hash2Protocol == &Instance->Hash2Protocol);

  //
  // Uninstall the Hash protocol.
  //
  Status = gBS->UninstallMultipleProtocolInterfaces (
                  ChildHandle,
                  &gEfiHash2ProtocolGuid,
                  &Instance->Hash2Protocol,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  //
  // Remove this instance from the ChildrenList.
  //
  RemoveEntryList (&Instance->InstEntry);

  gBS->RestoreTPL (OldTpl);

  FreePool (Instance);

  return Status;
}

/**
  The entry point for Hash driver which installs the service binding protocol.

  @param[in]  ImageHandle  The image handle of the driver.
  @param[in]  SystemTable  The system table.

  @retval EFI_SUCCES       The service binding protocols is successfully installed.
  @retval Others           Other errors as indicated.

**/
EFI_STATUS
EFIAPI
Hash2DriverEntryPoint (
  IN EFI_HANDLE          ImageHandle,
  IN EFI_SYSTEM_TABLE    *SystemTable
  )
{
  EFI_STATUS         Status;
  HASH2_SERVICE_DATA *Hash2ServiceData;

  //
  // Initialize the Hash Service Data.
  //
  Hash2ServiceData = AllocateZeroPool (sizeof (HASH2_SERVICE_DATA));
  if (Hash2ServiceData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Hash2ServiceData->Signature     = HASH2_SERVICE_DATA_SIGNATURE;
  CopyMem (&Hash2ServiceData->ServiceBinding, &mHash2ServiceBindingProtocol, sizeof (EFI_SERVICE_BINDING_PROTOCOL));
  InitializeListHead (&Hash2ServiceData->ChildrenList);

  //
  // Install the HASH Service Binding Protocol
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Hash2ServiceData->ServiceHandle,
                  &gEfiHash2ServiceBindingProtocolGuid,
                  &Hash2ServiceData->ServiceBinding,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    FreePool (Hash2ServiceData);
  }

  return Status;
}