From 216fefa3f5f41c726d71d4d3566323043f40edd8 Mon Sep 17 00:00:00 2001 From: Hao Wu Date: Wed, 17 Feb 2016 11:25:14 +0800 Subject: [PATCH] MdeModulePkg RamDiskDxe: Install Block I/O 2 Protocol on RAM disk devices Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Hao Wu Reviewed-by: Samer El-Haj-Mahmoud Reviewed-by: Feng Tian --- .../Disk/RamDiskDxe/RamDiskBlockIo.c | 233 +++++++++++++++++- .../Universal/Disk/RamDiskDxe/RamDiskDxe.inf | 1 + .../Universal/Disk/RamDiskDxe/RamDiskImpl.c | 2 + .../Universal/Disk/RamDiskDxe/RamDiskImpl.h | 134 ++++++++++ .../Disk/RamDiskDxe/RamDiskProtocol.c | 8 +- 5 files changed, 373 insertions(+), 5 deletions(-) diff --git a/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskBlockIo.c b/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskBlockIo.c index 1687da3690..f36e1c8ff2 100644 --- a/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskBlockIo.c +++ b/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskBlockIo.c @@ -27,9 +27,21 @@ EFI_BLOCK_IO_PROTOCOL mRamDiskBlockIoTemplate = { 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. @@ -40,14 +52,18 @@ RamDiskInitBlockIo ( ) { EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_BLOCK_IO2_PROTOCOL *BlockIo2; EFI_BLOCK_IO_MEDIA *Media; - BlockIo = &PrivateData->BlockIo; - Media = &PrivateData->Media; + BlockIo = &PrivateData->BlockIo; + BlockIo2 = &PrivateData->BlockIo2; + Media = &PrivateData->Media; CopyMem (BlockIo, &mRamDiskBlockIoTemplate, sizeof (EFI_BLOCK_IO_PROTOCOL)); + CopyMem (BlockIo2, &mRamDiskBlockIo2Template, sizeof (EFI_BLOCK_IO2_PROTOCOL)); BlockIo->Media = Media; + BlockIo2->Media = Media; Media->RemovableMedia = FALSE; Media->MediaPresent = TRUE; Media->LogicalPartition = FALSE; @@ -256,3 +272,214 @@ RamDiskBlkIoFlushBlocks ( { 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; +} diff --git a/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf b/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf index 85913c55cb..9fe35996ee 100644 --- a/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf +++ b/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf @@ -71,6 +71,7 @@ gEfiHiiConfigAccessProtocolGuid ## PRODUCES gEfiDevicePathProtocolGuid ## PRODUCES gEfiBlockIoProtocolGuid ## PRODUCES + gEfiBlockIo2ProtocolGuid ## PRODUCES gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES [Depex] diff --git a/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskImpl.c b/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskImpl.c index a2c48b23e3..b5770dd85a 100644 --- a/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskImpl.c +++ b/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskImpl.c @@ -173,6 +173,8 @@ UnregisterAllRamDisks ( PrivateData->Handle, &gEfiBlockIoProtocolGuid, &PrivateData->BlockIo, + &gEfiBlockIo2ProtocolGuid, + &PrivateData->BlockIo2, &gEfiDevicePathProtocolGuid, (EFI_DEVICE_PATH_PROTOCOL *) PrivateData->DevicePath, NULL diff --git a/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskImpl.h b/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskImpl.h index 47250068d7..0b9a4f9ec8 100644 --- a/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskImpl.h +++ b/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskImpl.h @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -86,6 +87,7 @@ typedef struct { EFI_HANDLE Handle; EFI_BLOCK_IO_PROTOCOL BlockIo; + EFI_BLOCK_IO2_PROTOCOL BlockIo2; EFI_BLOCK_IO_MEDIA Media; 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_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) /// @@ -310,6 +313,137 @@ RamDiskBlkIoFlushBlocks ( 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. diff --git a/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskProtocol.c b/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskProtocol.c index 9fe888eb9b..cfeae218e7 100644 --- a/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskProtocol.c +++ b/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskProtocol.c @@ -192,13 +192,15 @@ RamDiskRegister ( 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 // Status = gBS->InstallMultipleProtocolInterfaces ( &PrivateData->Handle, &gEfiBlockIoProtocolGuid, &PrivateData->BlockIo, + &gEfiBlockIo2ProtocolGuid, + &PrivateData->BlockIo2, &gEfiDevicePathProtocolGuid, PrivateData->DevicePath, NULL @@ -313,12 +315,14 @@ RamDiskUnregister ( (EndingAddr == PrivateData->StartingAddr + PrivateData->Size) && (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 ( PrivateData->Handle, &gEfiBlockIoProtocolGuid, &PrivateData->BlockIo, + &gEfiBlockIo2ProtocolGuid, + &PrivateData->BlockIo2, &gEfiDevicePathProtocolGuid, DevicePath, NULL -- 2.39.2