]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskBlockIo.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / Disk / RamDiskDxe / RamDiskBlockIo.c
index 1687da36902d24dc436511ada371e15e08cf0725..13f81bae1e07b07d118c22009dd712dde94c09b0 100644 (file)
@@ -1,14 +1,8 @@
 /** @file\r
   Produce EFI_BLOCK_IO_PROTOCOL on a RAM disk device.\r
 \r
-  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-  This program and the accompanying materials\r
-  are licensed and made available under the terms and conditions of the BSD License\r
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+  Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -27,9 +21,21 @@ EFI_BLOCK_IO_PROTOCOL  mRamDiskBlockIoTemplate = {
   RamDiskBlkIoFlushBlocks\r
 };\r
 \r
+//\r
+// The EFI_BLOCK_IO_PROTOCOL2 instances that is installed onto the handle\r
+// for newly registered RAM disks\r
+//\r
+EFI_BLOCK_IO2_PROTOCOL  mRamDiskBlockIo2Template = {\r
+  (EFI_BLOCK_IO_MEDIA *) 0,\r
+  RamDiskBlkIo2Reset,\r
+  RamDiskBlkIo2ReadBlocksEx,\r
+  RamDiskBlkIo2WriteBlocksEx,\r
+  RamDiskBlkIo2FlushBlocksEx\r
+};\r
+\r
 \r
 /**\r
-  Initialize the BlockIO protocol of a RAM disk device.\r
+  Initialize the BlockIO & BlockIO2 protocol of a RAM disk device.\r
 \r
   @param[in] PrivateData     Points to RAM disk private data.\r
 \r
@@ -40,24 +46,36 @@ RamDiskInitBlockIo (
   )\r
 {\r
   EFI_BLOCK_IO_PROTOCOL           *BlockIo;\r
+  EFI_BLOCK_IO2_PROTOCOL          *BlockIo2;\r
   EFI_BLOCK_IO_MEDIA              *Media;\r
+  UINT32                          Remainder;\r
 \r
-  BlockIo = &PrivateData->BlockIo;\r
-  Media   = &PrivateData->Media;\r
+  BlockIo  = &PrivateData->BlockIo;\r
+  BlockIo2 = &PrivateData->BlockIo2;\r
+  Media    = &PrivateData->Media;\r
 \r
   CopyMem (BlockIo, &mRamDiskBlockIoTemplate, sizeof (EFI_BLOCK_IO_PROTOCOL));\r
+  CopyMem (BlockIo2, &mRamDiskBlockIo2Template, sizeof (EFI_BLOCK_IO2_PROTOCOL));\r
 \r
   BlockIo->Media          = Media;\r
+  BlockIo2->Media         = Media;\r
   Media->RemovableMedia   = FALSE;\r
   Media->MediaPresent     = TRUE;\r
   Media->LogicalPartition = FALSE;\r
   Media->ReadOnly         = FALSE;\r
   Media->WriteCaching     = FALSE;\r
-  Media->BlockSize        = RAM_DISK_BLOCK_SIZE;\r
-  Media->LastBlock        = DivU64x32 (\r
-                              PrivateData->Size + RAM_DISK_BLOCK_SIZE - 1,\r
-                              RAM_DISK_BLOCK_SIZE\r
-                              ) - 1;\r
+\r
+  for (Media->BlockSize = RAM_DISK_DEFAULT_BLOCK_SIZE;\r
+       Media->BlockSize >= 1;\r
+       Media->BlockSize = Media->BlockSize >> 1) {\r
+    Media->LastBlock = DivU64x32Remainder (PrivateData->Size, Media->BlockSize, &Remainder) - 1;\r
+    if (Remainder == 0) {\r
+      break;\r
+    }\r
+  }\r
+  ASSERT (Media->BlockSize != 0);\r
+\r
+  return;\r
 }\r
 \r
 \r
@@ -121,6 +139,12 @@ RamDiskBlkIoReadBlocks (
   RAM_DISK_PRIVATE_DATA           *PrivateData;\r
   UINTN                           NumberOfBlocks;\r
 \r
+  PrivateData = RAM_DISK_PRIVATE_FROM_BLKIO (This);\r
+\r
+  if (MediaId != PrivateData->Media.MediaId) {\r
+    return EFI_MEDIA_CHANGED;\r
+  }\r
+\r
   if (Buffer == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
@@ -129,12 +153,6 @@ RamDiskBlkIoReadBlocks (
     return EFI_SUCCESS;\r
   }\r
 \r
-  PrivateData = RAM_DISK_PRIVATE_FROM_BLKIO (This);\r
-\r
-  if (MediaId != PrivateData->Media.MediaId) {\r
-    return EFI_MEDIA_CHANGED;\r
-  }\r
-\r
   if ((BufferSize % PrivateData->Media.BlockSize) != 0) {\r
     return EFI_BAD_BUFFER_SIZE;\r
   }\r
@@ -196,14 +214,6 @@ RamDiskBlkIoWriteBlocks (
   RAM_DISK_PRIVATE_DATA           *PrivateData;\r
   UINTN                           NumberOfBlocks;\r
 \r
-  if (Buffer == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (BufferSize == 0) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
   PrivateData = RAM_DISK_PRIVATE_FROM_BLKIO (This);\r
 \r
   if (MediaId != PrivateData->Media.MediaId) {\r
@@ -214,6 +224,14 @@ RamDiskBlkIoWriteBlocks (
     return EFI_WRITE_PROTECTED;\r
   }\r
 \r
+  if (Buffer == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (BufferSize == 0) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
   if ((BufferSize % PrivateData->Media.BlockSize) != 0) {\r
     return EFI_BAD_BUFFER_SIZE;\r
   }\r
@@ -256,3 +274,214 @@ RamDiskBlkIoFlushBlocks (
 {\r
   return EFI_SUCCESS;\r
 }\r
+\r
+\r
+/**\r
+  Resets the block device hardware.\r
+\r
+  @param[in] This                 The pointer of EFI_BLOCK_IO2_PROTOCOL.\r
+  @param[in] ExtendedVerification The flag about if extend verificate.\r
+\r
+  @retval EFI_SUCCESS             The device was reset.\r
+  @retval EFI_DEVICE_ERROR        The block device is not functioning correctly\r
+                                  and could not be reset.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RamDiskBlkIo2Reset (\r
+  IN EFI_BLOCK_IO2_PROTOCOL       *This,\r
+  IN BOOLEAN                      ExtendedVerification\r
+  )\r
+{\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Reads the requested number of blocks from the device.\r
+\r
+  @param[in]      This            Indicates a pointer to the calling context.\r
+  @param[in]      MediaId         The media ID that the read request is for.\r
+  @param[in]      Lba             The starting logical block address to read\r
+                                  from on the device.\r
+  @param[in, out] Token           A pointer to the token associated with the\r
+                                  transaction.\r
+  @param[in]      BufferSize      The size of the Buffer in bytes. This must be\r
+                                  a multiple of the intrinsic block size of the\r
+                                  device.\r
+  @param[out]     Buffer          A pointer to the destination buffer for the\r
+                                  data. The caller is responsible for either\r
+                                  having implicit or explicit ownership of the\r
+                                  buffer.\r
+\r
+  @retval EFI_SUCCESS             The read request was queued if Token->Event\r
+                                  is not NULL. The data was read correctly from\r
+                                  the device if the Token->Event is NULL.\r
+  @retval EFI_DEVICE_ERROR        The device reported an error while attempting\r
+                                  to perform the read operation.\r
+  @retval EFI_NO_MEDIA            There is no media in the device.\r
+  @retval EFI_MEDIA_CHANGED       The MediaId is not for the current media.\r
+  @retval EFI_BAD_BUFFER_SIZE     The BufferSize parameter is not a multiple of\r
+                                  the intrinsic block size of the device.\r
+  @retval EFI_INVALID_PARAMETER   The read request contains LBAs that are not\r
+                                  valid, or the buffer is not on proper\r
+                                  alignment.\r
+  @retval EFI_OUT_OF_RESOURCES    The request could not be completed due to a\r
+                                  lack of resources.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RamDiskBlkIo2ReadBlocksEx (\r
+  IN     EFI_BLOCK_IO2_PROTOCOL   *This,\r
+  IN     UINT32                   MediaId,\r
+  IN     EFI_LBA                  Lba,\r
+  IN OUT EFI_BLOCK_IO2_TOKEN      *Token,\r
+  IN     UINTN                    BufferSize,\r
+     OUT VOID                     *Buffer\r
+  )\r
+{\r
+  RAM_DISK_PRIVATE_DATA           *PrivateData;\r
+  EFI_STATUS                      Status;\r
+\r
+  PrivateData = RAM_DISK_PRIVATE_FROM_BLKIO2 (This);\r
+\r
+  Status = RamDiskBlkIoReadBlocks (\r
+              &PrivateData->BlockIo,\r
+              MediaId,\r
+              Lba,\r
+              BufferSize,\r
+              Buffer\r
+              );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // If caller's event is given, signal it after the memory read completes.\r
+  //\r
+  if ((Token != NULL) && (Token->Event != NULL)) {\r
+    Token->TransactionStatus = EFI_SUCCESS;\r
+    gBS->SignalEvent (Token->Event);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Writes a specified number of blocks to the device.\r
+\r
+  @param[in]      This            Indicates a pointer to the calling context.\r
+  @param[in]      MediaId         The media ID that the write request is for.\r
+  @param[in]      Lba             The starting logical block address to be\r
+                                  written. The caller is responsible for\r
+                                  writing to only legitimate locations.\r
+  @param[in, out] Token           A pointer to the token associated with the\r
+                                  transaction.\r
+  @param[in]      BufferSize      The size in bytes of Buffer. This must be a\r
+                                  multiple of the intrinsic block size of the\r
+                                  device.\r
+  @param[in]      Buffer          A pointer to the source buffer for the data.\r
+\r
+  @retval EFI_SUCCESS             The write request was queued if Event is not\r
+                                  NULL. The data was written correctly to the\r
+                                  device if the Event is NULL.\r
+  @retval EFI_WRITE_PROTECTED     The device cannot be written to.\r
+  @retval EFI_NO_MEDIA            There is no media in the device.\r
+  @retval EFI_MEDIA_CHANGED       The MediaId is not for the current media.\r
+  @retval EFI_DEVICE_ERROR        The device reported an error while attempting\r
+                                  to perform the write operation.\r
+  @retval EFI_BAD_BUFFER_SIZE     The BufferSize parameter is not a multiple of\r
+                                  the intrinsic block size of the device.\r
+  @retval EFI_INVALID_PARAMETER   The write request contains LBAs that are not\r
+                                  valid, or the buffer is not on proper\r
+                                  alignment.\r
+  @retval EFI_OUT_OF_RESOURCES    The request could not be completed due to a\r
+                                  lack of resources.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RamDiskBlkIo2WriteBlocksEx (\r
+  IN     EFI_BLOCK_IO2_PROTOCOL   *This,\r
+  IN     UINT32                   MediaId,\r
+  IN     EFI_LBA                  Lba,\r
+  IN OUT EFI_BLOCK_IO2_TOKEN      *Token,\r
+  IN     UINTN                    BufferSize,\r
+  IN     VOID                     *Buffer\r
+  )\r
+{\r
+  RAM_DISK_PRIVATE_DATA           *PrivateData;\r
+  EFI_STATUS                      Status;\r
+\r
+  PrivateData = RAM_DISK_PRIVATE_FROM_BLKIO2 (This);\r
+\r
+  Status = RamDiskBlkIoWriteBlocks (\r
+              &PrivateData->BlockIo,\r
+              MediaId,\r
+              Lba,\r
+              BufferSize,\r
+              Buffer\r
+              );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // If caller's event is given, signal it after the memory write completes.\r
+  //\r
+  if ((Token != NULL) && (Token->Event != NULL)) {\r
+    Token->TransactionStatus = EFI_SUCCESS;\r
+    gBS->SignalEvent (Token->Event);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Flushes all modified data to a physical block device.\r
+\r
+  @param[in]      This            Indicates a pointer to the calling context.\r
+  @param[in, out] Token           A pointer to the token associated with the\r
+                                  transaction.\r
+\r
+  @retval EFI_SUCCESS             The flush request was queued if Event is not\r
+                                  NULL. All outstanding data was written\r
+                                  correctly to the device if the Event is NULL.\r
+  @retval EFI_DEVICE_ERROR        The device reported an error while attempting\r
+                                  to write data.\r
+  @retval EFI_WRITE_PROTECTED     The device cannot be written to.\r
+  @retval EFI_NO_MEDIA            There is no media in the device.\r
+  @retval EFI_MEDIA_CHANGED       The MediaId is not for the current media.\r
+  @retval EFI_OUT_OF_RESOURCES    The request could not be completed due to a\r
+                                  lack of resources.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RamDiskBlkIo2FlushBlocksEx (\r
+  IN     EFI_BLOCK_IO2_PROTOCOL   *This,\r
+  IN OUT EFI_BLOCK_IO2_TOKEN      *Token\r
+  )\r
+{\r
+  RAM_DISK_PRIVATE_DATA           *PrivateData;\r
+\r
+  PrivateData = RAM_DISK_PRIVATE_FROM_BLKIO2 (This);\r
+\r
+  if (TRUE == PrivateData->Media.ReadOnly) {\r
+    return EFI_WRITE_PROTECTED;\r
+  }\r
+\r
+  //\r
+  // If caller's event is given, signal it directly.\r
+  //\r
+  if ((Token != NULL) && (Token->Event != NULL)) {\r
+    Token->TransactionStatus = EFI_SUCCESS;\r
+    gBS->SignalEvent (Token->Event);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r