MdeModulePkg RamDiskDxe: Install Block I/O 2 Protocol on RAM disk devices

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Hao Wu <hao.a.wu@intel.com>
Reviewed-by: Samer El-Haj-Mahmoud <elhaj@hpe.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>
This commit is contained in:
Hao Wu
2016-02-17 11:25:14 +08:00
parent 20752cb8e7
commit 216fefa3f5
5 changed files with 373 additions and 5 deletions

View File

@ -27,9 +27,21 @@ EFI_BLOCK_IO_PROTOCOL mRamDiskBlockIoTemplate = {
RamDiskBlkIoFlushBlocks RamDiskBlkIoFlushBlocks
}; };
//
// The EFI_BLOCK_IO_PROTOCOL2 instances that is installed onto the handle
// for newly registered RAM disks
//
EFI_BLOCK_IO2_PROTOCOL mRamDiskBlockIo2Template = {
(EFI_BLOCK_IO_MEDIA *) 0,
RamDiskBlkIo2Reset,
RamDiskBlkIo2ReadBlocksEx,
RamDiskBlkIo2WriteBlocksEx,
RamDiskBlkIo2FlushBlocksEx
};
/** /**
Initialize the BlockIO protocol of a RAM disk device. Initialize the BlockIO & BlockIO2 protocol of a RAM disk device.
@param[in] PrivateData Points to RAM disk private data. @param[in] PrivateData Points to RAM disk private data.
@ -40,14 +52,18 @@ RamDiskInitBlockIo (
) )
{ {
EFI_BLOCK_IO_PROTOCOL *BlockIo; EFI_BLOCK_IO_PROTOCOL *BlockIo;
EFI_BLOCK_IO2_PROTOCOL *BlockIo2;
EFI_BLOCK_IO_MEDIA *Media; EFI_BLOCK_IO_MEDIA *Media;
BlockIo = &PrivateData->BlockIo; BlockIo = &PrivateData->BlockIo;
Media = &PrivateData->Media; BlockIo2 = &PrivateData->BlockIo2;
Media = &PrivateData->Media;
CopyMem (BlockIo, &mRamDiskBlockIoTemplate, sizeof (EFI_BLOCK_IO_PROTOCOL)); CopyMem (BlockIo, &mRamDiskBlockIoTemplate, sizeof (EFI_BLOCK_IO_PROTOCOL));
CopyMem (BlockIo2, &mRamDiskBlockIo2Template, sizeof (EFI_BLOCK_IO2_PROTOCOL));
BlockIo->Media = Media; BlockIo->Media = Media;
BlockIo2->Media = Media;
Media->RemovableMedia = FALSE; Media->RemovableMedia = FALSE;
Media->MediaPresent = TRUE; Media->MediaPresent = TRUE;
Media->LogicalPartition = FALSE; Media->LogicalPartition = FALSE;
@ -256,3 +272,214 @@ RamDiskBlkIoFlushBlocks (
{ {
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/**
Resets the block device hardware.
@param[in] This The pointer of EFI_BLOCK_IO2_PROTOCOL.
@param[in] ExtendedVerification The flag about if extend verificate.
@retval EFI_SUCCESS The device was reset.
@retval EFI_DEVICE_ERROR The block device is not functioning correctly
and could not be reset.
**/
EFI_STATUS
EFIAPI
RamDiskBlkIo2Reset (
IN EFI_BLOCK_IO2_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
{
return EFI_SUCCESS;
}
/**
Reads the requested number of blocks from the device.
@param[in] This Indicates a pointer to the calling context.
@param[in] MediaId The media ID that the read request is for.
@param[in] Lba The starting logical block address to read
from on the device.
@param[in, out] Token A pointer to the token associated with the
transaction.
@param[in] BufferSize The size of the Buffer in bytes. This must be
a multiple of the intrinsic block size of the
device.
@param[out] Buffer A pointer to the destination buffer for the
data. The caller is responsible for either
having implicit or explicit ownership of the
buffer.
@retval EFI_SUCCESS The read request was queued if Token->Event
is not NULL. The data was read correctly from
the device if the Token->Event is NULL.
@retval EFI_DEVICE_ERROR The device reported an error while attempting
to perform the read operation.
@retval EFI_NO_MEDIA There is no media in the device.
@retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
@retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of
the intrinsic block size of the device.
@retval EFI_INVALID_PARAMETER The read request contains LBAs that are not
valid, or the buffer is not on proper
alignment.
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
lack of resources.
**/
EFI_STATUS
EFIAPI
RamDiskBlkIo2ReadBlocksEx (
IN EFI_BLOCK_IO2_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN OUT EFI_BLOCK_IO2_TOKEN *Token,
IN UINTN BufferSize,
OUT VOID *Buffer
)
{
RAM_DISK_PRIVATE_DATA *PrivateData;
EFI_STATUS Status;
PrivateData = RAM_DISK_PRIVATE_FROM_BLKIO2 (This);
Status = RamDiskBlkIoReadBlocks (
&PrivateData->BlockIo,
MediaId,
Lba,
BufferSize,
Buffer
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// If caller's event is given, signal it after the memory read completes.
//
if ((Token != NULL) && (Token->Event != NULL)) {
Token->TransactionStatus = EFI_SUCCESS;
gBS->SignalEvent (Token->Event);
}
return EFI_SUCCESS;
}
/**
Writes a specified number of blocks to the device.
@param[in] This Indicates a pointer to the calling context.
@param[in] MediaId The media ID that the write request is for.
@param[in] Lba The starting logical block address to be
written. The caller is responsible for
writing to only legitimate locations.
@param[in, out] Token A pointer to the token associated with the
transaction.
@param[in] BufferSize The size in bytes of Buffer. This must be a
multiple of the intrinsic block size of the
device.
@param[in] Buffer A pointer to the source buffer for the data.
@retval EFI_SUCCESS The write request was queued if Event is not
NULL. The data was written correctly to the
device if the Event is NULL.
@retval EFI_WRITE_PROTECTED The device cannot be written to.
@retval EFI_NO_MEDIA There is no media in the device.
@retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
@retval EFI_DEVICE_ERROR The device reported an error while attempting
to perform the write operation.
@retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of
the intrinsic block size of the device.
@retval EFI_INVALID_PARAMETER The write request contains LBAs that are not
valid, or the buffer is not on proper
alignment.
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
lack of resources.
**/
EFI_STATUS
EFIAPI
RamDiskBlkIo2WriteBlocksEx (
IN EFI_BLOCK_IO2_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN OUT EFI_BLOCK_IO2_TOKEN *Token,
IN UINTN BufferSize,
IN VOID *Buffer
)
{
RAM_DISK_PRIVATE_DATA *PrivateData;
EFI_STATUS Status;
PrivateData = RAM_DISK_PRIVATE_FROM_BLKIO2 (This);
Status = RamDiskBlkIoWriteBlocks (
&PrivateData->BlockIo,
MediaId,
Lba,
BufferSize,
Buffer
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// If caller's event is given, signal it after the memory write completes.
//
if ((Token != NULL) && (Token->Event != NULL)) {
Token->TransactionStatus = EFI_SUCCESS;
gBS->SignalEvent (Token->Event);
}
return EFI_SUCCESS;
}
/**
Flushes all modified data to a physical block device.
@param[in] This Indicates a pointer to the calling context.
@param[in, out] Token A pointer to the token associated with the
transaction.
@retval EFI_SUCCESS The flush request was queued if Event is not
NULL. All outstanding data was written
correctly to the device if the Event is NULL.
@retval EFI_DEVICE_ERROR The device reported an error while attempting
to write data.
@retval EFI_WRITE_PROTECTED The device cannot be written to.
@retval EFI_NO_MEDIA There is no media in the device.
@retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
lack of resources.
**/
EFI_STATUS
EFIAPI
RamDiskBlkIo2FlushBlocksEx (
IN EFI_BLOCK_IO2_PROTOCOL *This,
IN OUT EFI_BLOCK_IO2_TOKEN *Token
)
{
RAM_DISK_PRIVATE_DATA *PrivateData;
PrivateData = RAM_DISK_PRIVATE_FROM_BLKIO2 (This);
if (TRUE == PrivateData->Media.ReadOnly) {
return EFI_WRITE_PROTECTED;
}
//
// If caller's event is given, signal it directly.
//
if ((Token != NULL) && (Token->Event != NULL)) {
Token->TransactionStatus = EFI_SUCCESS;
gBS->SignalEvent (Token->Event);
}
return EFI_SUCCESS;
}

View File

@ -71,6 +71,7 @@
gEfiHiiConfigAccessProtocolGuid ## PRODUCES gEfiHiiConfigAccessProtocolGuid ## PRODUCES
gEfiDevicePathProtocolGuid ## PRODUCES gEfiDevicePathProtocolGuid ## PRODUCES
gEfiBlockIoProtocolGuid ## PRODUCES gEfiBlockIoProtocolGuid ## PRODUCES
gEfiBlockIo2ProtocolGuid ## PRODUCES
gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES
[Depex] [Depex]

View File

@ -173,6 +173,8 @@ UnregisterAllRamDisks (
PrivateData->Handle, PrivateData->Handle,
&gEfiBlockIoProtocolGuid, &gEfiBlockIoProtocolGuid,
&PrivateData->BlockIo, &PrivateData->BlockIo,
&gEfiBlockIo2ProtocolGuid,
&PrivateData->BlockIo2,
&gEfiDevicePathProtocolGuid, &gEfiDevicePathProtocolGuid,
(EFI_DEVICE_PATH_PROTOCOL *) PrivateData->DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) PrivateData->DevicePath,
NULL NULL

View File

@ -30,6 +30,7 @@
#include <Library/PrintLib.h> #include <Library/PrintLib.h>
#include <Protocol/RamDisk.h> #include <Protocol/RamDisk.h>
#include <Protocol/BlockIo.h> #include <Protocol/BlockIo.h>
#include <Protocol/BlockIo2.h>
#include <Protocol/HiiConfigAccess.h> #include <Protocol/HiiConfigAccess.h>
#include <Protocol/SimpleFileSystem.h> #include <Protocol/SimpleFileSystem.h>
#include <Guid/MdeModuleHii.h> #include <Guid/MdeModuleHii.h>
@ -86,6 +87,7 @@ typedef struct {
EFI_HANDLE Handle; EFI_HANDLE Handle;
EFI_BLOCK_IO_PROTOCOL BlockIo; EFI_BLOCK_IO_PROTOCOL BlockIo;
EFI_BLOCK_IO2_PROTOCOL BlockIo2;
EFI_BLOCK_IO_MEDIA Media; EFI_BLOCK_IO_MEDIA Media;
EFI_DEVICE_PATH_PROTOCOL *DevicePath; EFI_DEVICE_PATH_PROTOCOL *DevicePath;
@ -100,6 +102,7 @@ typedef struct {
#define RAM_DISK_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('R', 'D', 'S', 'K') #define RAM_DISK_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('R', 'D', 'S', 'K')
#define RAM_DISK_PRIVATE_FROM_BLKIO(a) CR (a, RAM_DISK_PRIVATE_DATA, BlockIo, RAM_DISK_PRIVATE_DATA_SIGNATURE) #define RAM_DISK_PRIVATE_FROM_BLKIO(a) CR (a, RAM_DISK_PRIVATE_DATA, BlockIo, RAM_DISK_PRIVATE_DATA_SIGNATURE)
#define RAM_DISK_PRIVATE_FROM_BLKIO2(a) CR (a, RAM_DISK_PRIVATE_DATA, BlockIo2, RAM_DISK_PRIVATE_DATA_SIGNATURE)
#define RAM_DISK_PRIVATE_FROM_THIS(a) CR (a, RAM_DISK_PRIVATE_DATA, ThisInstance, RAM_DISK_PRIVATE_DATA_SIGNATURE) #define RAM_DISK_PRIVATE_FROM_THIS(a) CR (a, RAM_DISK_PRIVATE_DATA, ThisInstance, RAM_DISK_PRIVATE_DATA_SIGNATURE)
/// ///
@ -310,6 +313,137 @@ RamDiskBlkIoFlushBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This IN EFI_BLOCK_IO_PROTOCOL *This
); );
/**
Resets the block device hardware.
@param[in] This The pointer of EFI_BLOCK_IO2_PROTOCOL.
@param[in] ExtendedVerification The flag about if extend verificate.
@retval EFI_SUCCESS The device was reset.
@retval EFI_DEVICE_ERROR The block device is not functioning correctly
and could not be reset.
**/
EFI_STATUS
EFIAPI
RamDiskBlkIo2Reset (
IN EFI_BLOCK_IO2_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
);
/**
Reads the requested number of blocks from the device.
@param[in] This Indicates a pointer to the calling context.
@param[in] MediaId The media ID that the read request is for.
@param[in] Lba The starting logical block address to read
from on the device.
@param[in, out] Token A pointer to the token associated with the
transaction.
@param[in] BufferSize The size of the Buffer in bytes. This must be
a multiple of the intrinsic block size of the
device.
@param[out] Buffer A pointer to the destination buffer for the
data. The caller is responsible for either
having implicit or explicit ownership of the
buffer.
@retval EFI_SUCCESS The read request was queued if Token->Event
is not NULL. The data was read correctly from
the device if the Token->Event is NULL.
@retval EFI_DEVICE_ERROR The device reported an error while attempting
to perform the read operation.
@retval EFI_NO_MEDIA There is no media in the device.
@retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
@retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of
the intrinsic block size of the device.
@retval EFI_INVALID_PARAMETER The read request contains LBAs that are not
valid, or the buffer is not on proper
alignment.
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
lack of resources.
**/
EFI_STATUS
EFIAPI
RamDiskBlkIo2ReadBlocksEx (
IN EFI_BLOCK_IO2_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN OUT EFI_BLOCK_IO2_TOKEN *Token,
IN UINTN BufferSize,
OUT VOID *Buffer
);
/**
Writes a specified number of blocks to the device.
@param[in] This Indicates a pointer to the calling context.
@param[in] MediaId The media ID that the write request is for.
@param[in] Lba The starting logical block address to be
written. The caller is responsible for
writing to only legitimate locations.
@param[in, out] Token A pointer to the token associated with the
transaction.
@param[in] BufferSize The size in bytes of Buffer. This must be a
multiple of the intrinsic block size of the
device.
@param[in] Buffer A pointer to the source buffer for the data.
@retval EFI_SUCCESS The write request was queued if Event is not
NULL. The data was written correctly to the
device if the Event is NULL.
@retval EFI_WRITE_PROTECTED The device cannot be written to.
@retval EFI_NO_MEDIA There is no media in the device.
@retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
@retval EFI_DEVICE_ERROR The device reported an error while attempting
to perform the write operation.
@retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of
the intrinsic block size of the device.
@retval EFI_INVALID_PARAMETER The write request contains LBAs that are not
valid, or the buffer is not on proper
alignment.
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
lack of resources.
**/
EFI_STATUS
EFIAPI
RamDiskBlkIo2WriteBlocksEx (
IN EFI_BLOCK_IO2_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN OUT EFI_BLOCK_IO2_TOKEN *Token,
IN UINTN BufferSize,
IN VOID *Buffer
);
/**
Flushes all modified data to a physical block device.
@param[in] This Indicates a pointer to the calling context.
@param[in, out] Token A pointer to the token associated with the
transaction.
@retval EFI_SUCCESS The flush request was queued if Event is not
NULL. All outstanding data was written
correctly to the device if the Event is NULL.
@retval EFI_DEVICE_ERROR The device reported an error while attempting
to write data.
@retval EFI_WRITE_PROTECTED The device cannot be written to.
@retval EFI_NO_MEDIA There is no media in the device.
@retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a
lack of resources.
**/
EFI_STATUS
EFIAPI
RamDiskBlkIo2FlushBlocksEx (
IN EFI_BLOCK_IO2_PROTOCOL *This,
IN OUT EFI_BLOCK_IO2_TOKEN *Token
);
/** /**
This function publish the RAM disk configuration Form. This function publish the RAM disk configuration Form.

View File

@ -192,13 +192,15 @@ RamDiskRegister (
RamDiskInitBlockIo (PrivateData); RamDiskInitBlockIo (PrivateData);
// //
// Install EFI_DEVICE_PATH_PROTOCOL & EFI_BLOCK_IO_PROTOCOL on a new // Install EFI_DEVICE_PATH_PROTOCOL & EFI_BLOCK_IO(2)_PROTOCOL on a new
// handle // handle
// //
Status = gBS->InstallMultipleProtocolInterfaces ( Status = gBS->InstallMultipleProtocolInterfaces (
&PrivateData->Handle, &PrivateData->Handle,
&gEfiBlockIoProtocolGuid, &gEfiBlockIoProtocolGuid,
&PrivateData->BlockIo, &PrivateData->BlockIo,
&gEfiBlockIo2ProtocolGuid,
&PrivateData->BlockIo2,
&gEfiDevicePathProtocolGuid, &gEfiDevicePathProtocolGuid,
PrivateData->DevicePath, PrivateData->DevicePath,
NULL NULL
@ -313,12 +315,14 @@ RamDiskUnregister (
(EndingAddr == PrivateData->StartingAddr + PrivateData->Size) && (EndingAddr == PrivateData->StartingAddr + PrivateData->Size) &&
(CompareGuid (&RamDiskDevNode->TypeGuid, &PrivateData->TypeGuid))) { (CompareGuid (&RamDiskDevNode->TypeGuid, &PrivateData->TypeGuid))) {
// //
// Uninstall the EFI_DEVICE_PATH_PROTOCOL & EFI_BLOCK_IO_PROTOCOL // Uninstall the EFI_DEVICE_PATH_PROTOCOL & EFI_BLOCK_IO(2)_PROTOCOL
// //
gBS->UninstallMultipleProtocolInterfaces ( gBS->UninstallMultipleProtocolInterfaces (
PrivateData->Handle, PrivateData->Handle,
&gEfiBlockIoProtocolGuid, &gEfiBlockIoProtocolGuid,
&PrivateData->BlockIo, &PrivateData->BlockIo,
&gEfiBlockIo2ProtocolGuid,
&PrivateData->BlockIo2,
&gEfiDevicePathProtocolGuid, &gEfiDevicePathProtocolGuid,
DevicePath, DevicePath,
NULL NULL