EraseBlockProtocol implementation

Signed-off-by: Shivamurthy Shastri <shivamurthy.shastri@linaro.org>
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
diff --git a/EmbeddedPkg/Include/Protocol/MmcHost.h b/EmbeddedPkg/Include/Protocol/MmcHost.h
index 4d11338..dbf3291 100644
--- a/EmbeddedPkg/Include/Protocol/MmcHost.h
+++ b/EmbeddedPkg/Include/Protocol/MmcHost.h
@@ -63,6 +63,9 @@
 #define MMC_CMD23             (MMC_INDX(23) | MMC_CMD_WAIT_RESPONSE)

 #define MMC_CMD24             (MMC_INDX(24) | MMC_CMD_WAIT_RESPONSE)

 #define MMC_CMD25             (MMC_INDX(25) | MMC_CMD_WAIT_RESPONSE)

+#define MMC_CMD35             (MMC_INDX(35) | MMC_CMD_WAIT_RESPONSE)

+#define MMC_CMD36             (MMC_INDX(36) | MMC_CMD_WAIT_RESPONSE)

+#define MMC_CMD38             (MMC_INDX(38) | MMC_CMD_WAIT_RESPONSE)

 #define MMC_CMD55             (MMC_INDX(55) | MMC_CMD_WAIT_RESPONSE)

 #define MMC_ACMD41            (MMC_INDX(41) | MMC_CMD_WAIT_RESPONSE | MMC_CMD_NO_CRC_RESPONSE)

 #define MMC_ACMD51            (MMC_INDX(51) | MMC_CMD_WAIT_RESPONSE)

diff --git a/EmbeddedPkg/Universal/MmcDxe/Mmc.c b/EmbeddedPkg/Universal/MmcDxe/Mmc.c
index 570e1d2..30268e3 100644
--- a/EmbeddedPkg/Universal/MmcDxe/Mmc.c
+++ b/EmbeddedPkg/Universal/MmcDxe/Mmc.c
@@ -111,6 +111,10 @@
   MmcHostInstance->BlockIo.WriteBlocks = MmcWriteBlocks;

   MmcHostInstance->BlockIo.FlushBlocks = MmcFlushBlocks;

 

+  MmcHostInstance->EraseBlockProtocol.Revision = EFI_ERASE_BLOCK_PROTOCOL_REVISION;

+  MmcHostInstance->EraseBlockProtocol.EraseLengthGranularity = 1; //TO BE CHANGED, SHIVA

+  MmcHostInstance->EraseBlockProtocol.EraseBlocks = MmcEraseBlocks;

+

   MmcHostInstance->MmcHost = MmcHost;

 

   // Create DevicePath for the new MMC Host

@@ -131,6 +135,7 @@
   Status = gBS->InstallMultipleProtocolInterfaces (

                 &MmcHostInstance->MmcHandle,

                 &gEfiBlockIoProtocolGuid,&MmcHostInstance->BlockIo,

+                &gEfiEraseBlockProtocolGuid,&MmcHostInstance->EraseBlockProtocol,

                 &gEfiDevicePathProtocolGuid,MmcHostInstance->DevicePath,

                 NULL

                 );

@@ -162,6 +167,7 @@
   Status = gBS->UninstallMultipleProtocolInterfaces (

         MmcHostInstance->MmcHandle,

         &gEfiBlockIoProtocolGuid,&(MmcHostInstance->BlockIo),

+        &gEfiEraseBlockProtocolGuid,&MmcHostInstance->EraseBlockProtocol,

         &gEfiDevicePathProtocolGuid,MmcHostInstance->DevicePath,

         NULL

         );

@@ -377,6 +383,12 @@
                     &(MmcHostInstance->BlockIo),

                     &(MmcHostInstance->BlockIo)

                     );

+      Status = gBS->ReinstallProtocolInterface (

+                    (MmcHostInstance->MmcHandle),

+                    &gEfiEraseBlockProtocolGuid,

+                    &(MmcHostInstance->EraseBlockProtocol),

+                    &(MmcHostInstance->EraseBlockProtocol)

+                    );

 

       if (EFI_ERROR(Status)) {

         Print(L"MMC Card: Error reinstalling BlockIo interface\n");

diff --git a/EmbeddedPkg/Universal/MmcDxe/Mmc.h b/EmbeddedPkg/Universal/MmcDxe/Mmc.h
index 8a7d5a3..b7b9454 100644
--- a/EmbeddedPkg/Universal/MmcDxe/Mmc.h
+++ b/EmbeddedPkg/Universal/MmcDxe/Mmc.h
@@ -20,6 +20,7 @@
 

 #include <Protocol/DiskIo.h>

 #include <Protocol/BlockIo.h>

+#include <Protocol/EraseBlock.h>

 #include <Protocol/DevicePath.h>

 #include <Protocol/MmcHost.h>

 

@@ -330,6 +331,7 @@
 

   MMC_STATE                 State;

   EFI_BLOCK_IO_PROTOCOL     BlockIo;

+  EFI_ERASE_BLOCK_PROTOCOL  EraseBlockProtocol;

   CARD_INFO                 CardInfo;

   EFI_MMC_HOST_PROTOCOL     *MmcHost;

 

@@ -339,6 +341,7 @@
 #define MMC_HOST_INSTANCE_SIGNATURE                 SIGNATURE_32('m', 'm', 'c', 'h')

 #define MMC_HOST_INSTANCE_FROM_BLOCK_IO_THIS(a)     CR (a, MMC_HOST_INSTANCE, BlockIo, MMC_HOST_INSTANCE_SIGNATURE)

 #define MMC_HOST_INSTANCE_FROM_LINK(a)              CR (a, MMC_HOST_INSTANCE, Link, MMC_HOST_INSTANCE_SIGNATURE)

+#define MMC_HOST_INSTANCE_FROM_ERASEBLK(a)          CR (a, MMC_HOST_INSTANCE, EraseBlockProtocol, MMC_HOST_INSTANCE_SIGNATURE)

 

 

 EFI_STATUS

@@ -473,6 +476,38 @@
   IN EFI_BLOCK_IO_PROTOCOL  *This

   );

 

+/**

+  Erase a specified number of device blocks.

+

+  This function implements EFI_ERASE_BLOCK_PROTOCOL.EraseBlocks().

+

+  @param  This       Indicates a pointer to the calling context.

+  @param  MediaId    The media ID that the erase request is for.

+  @param  Lba        The starting logical block address to be erased. The caller is

+                     responsible for erasing only legitimate locations.

+  @param  Token      A pointer to the token associated with the transaction.

+  @param  Size       The size in bytes to be erased. This must be a multiple of the

+                     physical block size of the device.

+

+  @retval EFI_SUCCESS           The erase request was queued if Event is not NULL. The data was

+                                erased correctly to the device if the Event is NULL.

+  @retval EFI_WRITE_PROTECTED   The device cannot be erased due to write protection.

+  @retval EFI_DEVICE_ERROR      The device reported an error while attempting to perform the erase operation.

+  @retval EFI_INVALID_PARAMETER The erase request contain LBAs that are not valid.

+  @retval EFI_NO_MEDIA          There is no media in the device.

+  @retval EFI_MEDIA_CHANGED     The MediaId is not for the current media.

+

+**/

+EFI_STATUS

+EFIAPI

+MmcEraseBlocks (

+  IN EFI_ERASE_BLOCK_PROTOCOL       *This,

+  IN UINT32                         MediaId,

+  IN EFI_LBA                        Lba,

+  IN OUT EFI_ERASE_BLOCK_TOKEN      *Token,

+  IN UINTN                          Size

+  );

+

 EFI_STATUS

 MmcNotifyState (

   IN MMC_HOST_INSTANCE      *MmcHostInstance,

diff --git a/EmbeddedPkg/Universal/MmcDxe/MmcBlockIo.c b/EmbeddedPkg/Universal/MmcDxe/MmcBlockIo.c
index 403db96..de488ba 100644
--- a/EmbeddedPkg/Universal/MmcDxe/MmcBlockIo.c
+++ b/EmbeddedPkg/Universal/MmcDxe/MmcBlockIo.c
@@ -376,3 +376,56 @@
 {

   return EFI_SUCCESS;

 }

+

+EFI_STATUS

+EFIAPI

+MmcEraseBlocks (

+  IN EFI_ERASE_BLOCK_PROTOCOL       *This,

+  IN UINT32                         MediaId,

+  IN EFI_LBA                        Lba,

+  IN OUT EFI_ERASE_BLOCK_TOKEN      *Token,

+  IN UINTN                          Size

+  )

+{

+  EFI_STATUS             Status;

+  MMC_HOST_INSTANCE      *MmcHostInstance;

+  EFI_MMC_HOST_PROTOCOL  *MmcHost;

+  UINT32                 Response[4];

+  UINTN                  CmdArg;

+

+  MmcHostInstance = MMC_HOST_INSTANCE_FROM_ERASEBLK (This);

+  ASSERT (MmcHostInstance != NULL);

+  MmcHost = MmcHostInstance->MmcHost;

+  ASSERT (MmcHost);

+

+  if (MmcHostInstance->BlockIo.Media->ReadOnly == TRUE)

+     return EFI_WRITE_PROTECTED;

+

+// EFI_DEVICE_ERROR, EFI_INVALID_PARAMETER

+

+  if (!MmcHostInstance->BlockIo.Media->MediaPresent)

+     return EFI_NO_MEDIA;

+

+  if (MmcHostInstance->BlockIo.Media->MediaId != MediaId)

+     return EFI_MEDIA_CHANGED;

+

+  CmdArg = Lba;

+  Status = MmcHost->SendCommand (MmcHost, MMC_CMD35, CmdArg);

+  if (!EFI_ERROR (Status)) {

+     MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_R1, Response);

+  }

+

+  CmdArg = Lba + Size;

+  Status = MmcHost->SendCommand (MmcHost, MMC_CMD36, CmdArg);

+  if (!EFI_ERROR (Status)) {

+     MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_R1, Response);

+  }

+

+  CmdArg = 0;

+  Status = MmcHost->SendCommand (MmcHost, MMC_CMD38, CmdArg);

+  if (!EFI_ERROR (Status)) {

+     MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_R1b, Response);

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf b/EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf
index a07288c..4ad7016 100644
--- a/EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf
+++ b/EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf
@@ -46,6 +46,7 @@
   gEfiDevicePathProtocolGuid

   gEfiMmcHostProtocolGuid

   gEfiDriverDiagnostics2ProtocolGuid

+  gEfiEraseBlockProtocolGuid

 

 [Depex]

   TRUE