Skip to content

Commit

Permalink
MdeModulePkg/Sd: add Erase Block support on sd/emmc device
Browse files Browse the repository at this point in the history
It's done by producing EFI_ERASE_BLOCK_PROTOCOL protocol instance.

Cc: Hao Wu <[email protected]>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Feng Tian <[email protected]>
Reviewed-by: Hao Wu <[email protected]>
  • Loading branch information
ftian1 committed May 9, 2016
1 parent 140cc80 commit 275d513
Show file tree
Hide file tree
Showing 10 changed files with 978 additions and 6 deletions.
413 changes: 413 additions & 0 deletions MdeModulePkg/Bus/Sd/EmmcDxe/EmmcBlockIo.c

Large diffs are not rendered by default.

39 changes: 38 additions & 1 deletion MdeModulePkg/Bus/Sd/EmmcDxe/EmmcBlockIo.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
This file defines common data structures, macro definitions and some module
internal function header files.
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
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
which accompanies this distribution. The full text of the license may be found at
Expand Down Expand Up @@ -462,5 +462,42 @@ EmmcSecurityProtocolOut (
IN VOID *PayloadBuffer
);

/**
Erase a specified number of device blocks.
@param[in] This Indicates a pointer to the calling context.
@param[in] MediaId The media ID that the erase request is for.
@param[in] Lba The starting logical block address to be
erased. The caller is responsible for erasing
only legitimate locations.
@param[in, out] Token A pointer to the token associated with the
transaction.
@param[in] 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.to the device.
@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 contains 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
EmmcEraseBlocks (
IN EFI_ERASE_BLOCK_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN OUT EFI_ERASE_BLOCK_TOKEN *Token,
IN UINTN Size
);

#endif

74 changes: 73 additions & 1 deletion MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ EMMC_PARTITION mEmmcPartitionTemplate = {
EmmcSecurityProtocolIn,
EmmcSecurityProtocolOut
},
{ // EraseBlock
EFI_ERASE_BLOCK_PROTOCOL_REVISION,
1,
EmmcEraseBlocks
},
{
NULL,
NULL
Expand Down Expand Up @@ -369,6 +374,16 @@ DiscoverAllPartitions (
Partition->Enable = TRUE;
Partition->BlockMedia.LastBlock = DivU64x32 (Capacity, Partition->BlockMedia.BlockSize) - 1;
}

if ((ExtCsd->EraseGroupDef & BIT0) == 0) {
if (Csd->WriteBlLen < 9) {
Partition->EraseBlock.EraseLengthGranularity = 1;
} else {
Partition->EraseBlock.EraseLengthGranularity = (Csd->EraseGrpMult + 1) * (Csd->EraseGrpSize + 1) * (1 << (Csd->WriteBlLen - 9));
}
} else {
Partition->EraseBlock.EraseLengthGranularity = 1024 * ExtCsd->HcEraseGrpSize;
}
}

return EFI_SUCCESS;
Expand Down Expand Up @@ -438,10 +453,32 @@ InstallProtocolOnPartition (
&Partition->BlockIo2,
NULL
);
if (EFI_ERROR (Status)) {
if (EFI_ERROR (Status)) {
goto Error;
}

if (Partition->PartitionType != EmmcPartitionRPMB) {
Status = gBS->InstallProtocolInterface (
&Partition->Handle,
&gEfiEraseBlockProtocolGuid,
EFI_NATIVE_INTERFACE,
&Partition->EraseBlock
);
if (EFI_ERROR (Status)) {
gBS->UninstallMultipleProtocolInterfaces (
&Partition->Handle,
&gEfiDevicePathProtocolGuid,
Partition->DevicePath,
&gEfiBlockIoProtocolGuid,
&Partition->BlockIo,
&gEfiBlockIo2ProtocolGuid,
&Partition->BlockIo2,
NULL
);
goto Error;
}
}

if (((Partition->PartitionType == EmmcPartitionUserData) ||
(Partition->PartitionType == EmmcPartitionBoot1) ||
(Partition->PartitionType == EmmcPartitionBoot2)) &&
Expand All @@ -461,6 +498,8 @@ InstallProtocolOnPartition (
&Partition->BlockIo,
&gEfiBlockIo2ProtocolGuid,
&Partition->BlockIo2,
&gEfiEraseBlockProtocolGuid,
&Partition->EraseBlock,
NULL
);
goto Error;
Expand Down Expand Up @@ -954,6 +993,7 @@ EmmcDxeDriverBindingStop (
EFI_BLOCK_IO_PROTOCOL *BlockIo;
EFI_BLOCK_IO2_PROTOCOL *BlockIo2;
EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *StorageSecurity;
EFI_ERASE_BLOCK_PROTOCOL *EraseBlock;
LIST_ENTRY *Link;
LIST_ENTRY *NextLink;
EMMC_REQUEST *Request;
Expand Down Expand Up @@ -1095,6 +1135,38 @@ EmmcDxeDriverBindingStop (
continue;
}

//
// If Erase Block Protocol is installed, then uninstall this protocol.
//
Status = gBS->OpenProtocol (
ChildHandleBuffer[Index],
&gEfiEraseBlockProtocolGuid,
(VOID **) &EraseBlock,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);

if (!EFI_ERROR (Status)) {
Status = gBS->UninstallProtocolInterface (
ChildHandleBuffer[Index],
&gEfiEraseBlockProtocolGuid,
&Partition->EraseBlock
);
if (EFI_ERROR (Status)) {
gBS->OpenProtocol (
Controller,
&gEfiSdMmcPassThruProtocolGuid,
(VOID **) &Partition->Device->Private->PassThru,
This->DriverBindingHandle,
ChildHandleBuffer[Index],
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
AllChildrenStopped = FALSE;
continue;
}
}

//
// If Storage Security Command Protocol is installed, then uninstall this protocol.
//
Expand Down
5 changes: 5 additions & 0 deletions MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <Protocol/BlockIo.h>
#include <Protocol/BlockIo2.h>
#include <Protocol/StorageSecurityCommand.h>
#include <Protocol/EraseBlock.h>

#include <Protocol/DevicePath.h>

Expand Down Expand Up @@ -57,6 +58,9 @@ extern EFI_COMPONENT_NAME2_PROTOCOL gEmmcDxeComponentName2;
#define EMMC_PARTITION_DATA_FROM_SSP(a) \
CR(a, EMMC_PARTITION, StorageSecurity, EMMC_PARTITION_SIGNATURE)

#define EMMC_PARTITION_DATA_FROM_ERASEBLK(a) \
CR(a, EMMC_PARTITION, EraseBlock, EMMC_PARTITION_SIGNATURE)

//
// Take 2.5 seconds as generic time out value, 1 microsecond as unit.
//
Expand Down Expand Up @@ -97,6 +101,7 @@ typedef struct {
EFI_BLOCK_IO2_PROTOCOL BlockIo2;
EFI_BLOCK_IO_MEDIA BlockMedia;
EFI_STORAGE_SECURITY_COMMAND_PROTOCOL StorageSecurity;
EFI_ERASE_BLOCK_PROTOCOL EraseBlock;

LIST_ENTRY Queue;

Expand Down
3 changes: 2 additions & 1 deletion MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.inf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# It produces BlockIo, BlockIo2 and StorageSecurity protocols to allow upper layer
# access the EMMC device.
#
# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
# 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
Expand Down Expand Up @@ -60,6 +60,7 @@
gEfiBlockIoProtocolGuid ## BY_START
gEfiBlockIo2ProtocolGuid ## BY_START
gEfiStorageSecurityCommandProtocolGuid ## SOMETIMES_PRODUCES
gEfiEraseBlockProtocolGuid ## BY_START
## TO_START
## BY_START
gEfiDevicePathProtocolGuid
Expand Down
Loading

0 comments on commit 275d513

Please sign in to comment.