/** @file
  Main file of the MMC Dxe driver. The driver entrypoint is defined into this file.

  Copyright (c) 2011-2013, ARM Limited. All rights reserved.

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Protocol/DevicePath.h>

#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DevicePathLib.h>

#include "Mmc.h"

EFI_BLOCK_IO_MEDIA  mMmcMediaTemplate = {
  SIGNATURE_32 ('m', 'm', 'c', 'o'), // MediaId
  TRUE,                              // RemovableMedia
  FALSE,                             // MediaPresent
  FALSE,                             // LogicalPartition
  FALSE,                             // ReadOnly
  FALSE,                             // WriteCaching
  512,                               // BlockSize
  4,                                 // IoAlign
  0,                                 // Pad
  0                                  // LastBlock
};

//
// This device structure is serviced as a header.
// Its next field points to the first root bridge device node.
//
LIST_ENTRY  mMmcHostPool;

/**
  Event triggered by the timer to check if any cards have been removed
  or if new ones have been plugged in
**/

EFI_EVENT  gCheckCardsEvent;

/**
  Initialize the MMC Host Pool to support multiple MMC devices
**/
VOID
InitializeMmcHostPool (
  VOID
  )
{
  InitializeListHead (&mMmcHostPool);
}

/**
  Insert a new Mmc Host controller to the pool
**/
VOID
InsertMmcHost (
  IN MMC_HOST_INSTANCE  *MmcHostInstance
  )
{
  InsertTailList (&mMmcHostPool, &(MmcHostInstance->Link));
}

/*
  Remove a new Mmc Host controller to the pool
*/
VOID
RemoveMmcHost (
  IN MMC_HOST_INSTANCE  *MmcHostInstance
  )
{
  RemoveEntryList (&(MmcHostInstance->Link));
}

MMC_HOST_INSTANCE *
CreateMmcHostInstance (
  IN EFI_MMC_HOST_PROTOCOL  *MmcHost
  )
{
  EFI_STATUS                Status;
  MMC_HOST_INSTANCE         *MmcHostInstance;
  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePathNode;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

  MmcHostInstance = AllocateZeroPool (sizeof (MMC_HOST_INSTANCE));
  if (MmcHostInstance == NULL) {
    return NULL;
  }

  MmcHostInstance->Signature = MMC_HOST_INSTANCE_SIGNATURE;

  MmcHostInstance->State = MmcHwInitializationState;

  MmcHostInstance->BlockIo.Media = AllocateCopyPool (sizeof (EFI_BLOCK_IO_MEDIA), &mMmcMediaTemplate);
  if (MmcHostInstance->BlockIo.Media == NULL) {
    goto FREE_INSTANCE;
  }

  MmcHostInstance->BlockIo.Revision    = EFI_BLOCK_IO_INTERFACE_REVISION;
  MmcHostInstance->BlockIo.Reset       = MmcReset;
  MmcHostInstance->BlockIo.ReadBlocks  = MmcReadBlocks;
  MmcHostInstance->BlockIo.WriteBlocks = MmcWriteBlocks;
  MmcHostInstance->BlockIo.FlushBlocks = MmcFlushBlocks;

  MmcHostInstance->MmcHost = MmcHost;

  // Create DevicePath for the new MMC Host
  Status = MmcHost->BuildDevicePath (MmcHost, &NewDevicePathNode);
  if (EFI_ERROR (Status)) {
    goto FREE_MEDIA;
  }

  DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)AllocatePool (END_DEVICE_PATH_LENGTH);
  if (DevicePath == NULL) {
    goto FREE_MEDIA;
  }

  SetDevicePathEndNode (DevicePath);
  MmcHostInstance->DevicePath = AppendDevicePathNode (DevicePath, NewDevicePathNode);

  // Publish BlockIO protocol interface
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &MmcHostInstance->MmcHandle,
                  &gEfiBlockIoProtocolGuid,
                  &MmcHostInstance->BlockIo,
                  &gEfiDevicePathProtocolGuid,
                  MmcHostInstance->DevicePath,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    goto FREE_DEVICE_PATH;
  }

  return MmcHostInstance;

FREE_DEVICE_PATH:
  FreePool (DevicePath);

FREE_MEDIA:
  FreePool (MmcHostInstance->BlockIo.Media);

FREE_INSTANCE:
  FreePool (MmcHostInstance);

  return NULL;
}

EFI_STATUS
DestroyMmcHostInstance (
  IN MMC_HOST_INSTANCE  *MmcHostInstance
  )
{
  EFI_STATUS  Status;

  // Uninstall Protocol Interfaces
  Status = gBS->UninstallMultipleProtocolInterfaces (
                  MmcHostInstance->MmcHandle,
                  &gEfiBlockIoProtocolGuid,
                  &(MmcHostInstance->BlockIo),
                  &gEfiDevicePathProtocolGuid,
                  MmcHostInstance->DevicePath,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

  // Free Memory allocated for the instance
  if (MmcHostInstance->BlockIo.Media) {
    FreePool (MmcHostInstance->BlockIo.Media);
  }

  if (MmcHostInstance->CardInfo.ECSDData) {
    FreePages (MmcHostInstance->CardInfo.ECSDData, EFI_SIZE_TO_PAGES (sizeof (ECSD)));
  }

  FreePool (MmcHostInstance);

  return Status;
}

/**
  This function checks if the controller implement the Mmc Host and the Device Path Protocols
**/
EFI_STATUS
EFIAPI
MmcDriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS  Status;
  // EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath;
  EFI_MMC_HOST_PROTOCOL  *MmcHost;
  EFI_DEV_PATH_PTR       Node;

  //
  // Check RemainingDevicePath validation
  //
  if (RemainingDevicePath != NULL) {
    //
    // Check if RemainingDevicePath is the End of Device Path Node,
    // if yes, go on checking other conditions
    //
    if (!IsDevicePathEnd (RemainingDevicePath)) {
      //
      // If RemainingDevicePath isn't the End of Device Path Node,
      // check its validation
      //
      Node.DevPath = RemainingDevicePath;
      if ((Node.DevPath->Type != HARDWARE_DEVICE_PATH) ||
          (Node.DevPath->SubType != HW_VENDOR_DP) ||
          (DevicePathNodeLength (Node.DevPath) != sizeof (VENDOR_DEVICE_PATH)))
      {
        return EFI_UNSUPPORTED;
      }
    }
  }

  //
  // Check if Mmc Host protocol is installed by platform
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEmbeddedMmcHostProtocolGuid,
                  (VOID **)&MmcHost,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (Status == EFI_ALREADY_STARTED) {
    return EFI_SUCCESS;
  }

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Close the Mmc Host used to perform the supported test
  //
  gBS->CloseProtocol (
         Controller,
         &gEmbeddedMmcHostProtocolGuid,
         This->DriverBindingHandle,
         Controller
         );

  return EFI_SUCCESS;
}

/**

**/
EFI_STATUS
EFIAPI
MmcDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS             Status;
  MMC_HOST_INSTANCE      *MmcHostInstance;
  EFI_MMC_HOST_PROTOCOL  *MmcHost;

  //
  // Check RemainingDevicePath validation
  //
  if (RemainingDevicePath != NULL) {
    //
    // Check if RemainingDevicePath is the End of Device Path Node,
    // if yes, return EFI_SUCCESS
    //
    if (IsDevicePathEnd (RemainingDevicePath)) {
      return EFI_SUCCESS;
    }
  }

  //
  // Get the Mmc Host protocol
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEmbeddedMmcHostProtocolGuid,
                  (VOID **)&MmcHost,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    if (Status == EFI_ALREADY_STARTED) {
      return EFI_SUCCESS;
    }

    return Status;
  }

  MmcHostInstance = CreateMmcHostInstance (MmcHost);
  if (MmcHostInstance != NULL) {
    // Add the handle to the pool
    InsertMmcHost (MmcHostInstance);

    MmcHostInstance->Initialized = FALSE;

    // Detect card presence now
    CheckCardsCallback (NULL, NULL);
  }

  return EFI_SUCCESS;
}

/**

**/
EFI_STATUS
EFIAPI
MmcDriverBindingStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   Controller,
  IN  UINTN                        NumberOfChildren,
  IN  EFI_HANDLE                   *ChildHandleBuffer
  )
{
  EFI_STATUS         Status = EFI_SUCCESS;
  LIST_ENTRY         *CurrentLink;
  MMC_HOST_INSTANCE  *MmcHostInstance;

  MMC_TRACE ("MmcDriverBindingStop()");

  // For each MMC instance
  CurrentLink = mMmcHostPool.ForwardLink;
  while (CurrentLink != NULL && CurrentLink != &mMmcHostPool && (Status == EFI_SUCCESS)) {
    MmcHostInstance = MMC_HOST_INSTANCE_FROM_LINK (CurrentLink);
    ASSERT (MmcHostInstance != NULL);

    // Close gEmbeddedMmcHostProtocolGuid
    Status = gBS->CloseProtocol (
                    Controller,
                    &gEmbeddedMmcHostProtocolGuid,
                    This->DriverBindingHandle,
                    Controller
                    );

    // Remove MMC Host Instance from the pool
    RemoveMmcHost (MmcHostInstance);

    // Destroy MmcHostInstance
    DestroyMmcHostInstance (MmcHostInstance);
  }

  return Status;
}

VOID
EFIAPI
CheckCardsCallback (
  IN  EFI_EVENT  Event,
  IN  VOID       *Context
  )
{
  LIST_ENTRY         *CurrentLink;
  MMC_HOST_INSTANCE  *MmcHostInstance;
  EFI_STATUS         Status;

  CurrentLink = mMmcHostPool.ForwardLink;
  while (CurrentLink != NULL && CurrentLink != &mMmcHostPool) {
    MmcHostInstance = MMC_HOST_INSTANCE_FROM_LINK (CurrentLink);
    ASSERT (MmcHostInstance != NULL);

    if (MmcHostInstance->MmcHost->IsCardPresent (MmcHostInstance->MmcHost) == !MmcHostInstance->Initialized) {
      MmcHostInstance->State                       = MmcHwInitializationState;
      MmcHostInstance->BlockIo.Media->MediaPresent = !MmcHostInstance->Initialized;
      MmcHostInstance->Initialized                 = !MmcHostInstance->Initialized;

      if (MmcHostInstance->BlockIo.Media->MediaPresent) {
        InitializeMmcDevice (MmcHostInstance);
      }

      Status = gBS->ReinstallProtocolInterface (
                      (MmcHostInstance->MmcHandle),
                      &gEfiBlockIoProtocolGuid,
                      &(MmcHostInstance->BlockIo),
                      &(MmcHostInstance->BlockIo)
                      );

      if (EFI_ERROR (Status)) {
        Print (L"MMC Card: Error reinstalling BlockIo interface\n");
      }
    }

    CurrentLink = CurrentLink->ForwardLink;
  }
}

EFI_DRIVER_BINDING_PROTOCOL  gMmcDriverBinding = {
  MmcDriverBindingSupported,
  MmcDriverBindingStart,
  MmcDriverBindingStop,
  0xa,
  NULL,
  NULL
};

/**

**/
EFI_STATUS
EFIAPI
MmcDxeInitialize (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  //
  // Initializes MMC Host pool
  //
  InitializeMmcHostPool ();

  //
  // Install driver model protocol(s).
  //
  Status = EfiLibInstallDriverBindingComponentName2 (
             ImageHandle,
             SystemTable,
             &gMmcDriverBinding,
             ImageHandle,
             &gMmcComponentName,
             &gMmcComponentName2
             );
  ASSERT_EFI_ERROR (Status);

  // Install driver diagnostics
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &ImageHandle,
                  &gEfiDriverDiagnostics2ProtocolGuid,
                  &gMmcDriverDiagnostics2,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

  // Use a timer to detect if a card has been plugged in or removed
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL | EVT_TIMER,
                  TPL_CALLBACK,
                  CheckCardsCallback,
                  NULL,
                  &gCheckCardsEvent
                  );
  ASSERT_EFI_ERROR (Status);

  Status = gBS->SetTimer (
                  gCheckCardsEvent,
                  TimerPeriodic,
                  (UINT64)(10*1000*200)
                  );                    // 200 ms
  ASSERT_EFI_ERROR (Status);

  return Status;
}
