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