The function ScsiDiskFlushBlocksEx() in ScsiDiskDxe/ScsiDisk.c originally
always returns EFI_SUCCESS, which is not aligned with the UEFI spec.

This commit adds addtional checks to see if the media in the device is
changed or removed. Check for whether the device can be written is also
added. Corresponding status will be returned according to the check
result.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Hao Wu <hao.a...@intel.com>
---
 MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c | 71 +++++++++++++++++++++++++---
 MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h | 10 ++--
 2 files changed, 71 insertions(+), 10 deletions(-)

diff --git a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c 
b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
index 88bce3f..a85cc94 100644
--- a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
+++ b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
@@ -1116,10 +1116,12 @@ Done:
   @param  This       Indicates a pointer to the calling context.
   @param  Token      A pointer to the token associated with the transaction.
 
-  @retval EFI_SUCCESS       All outstanding data was written to the device.
-  @retval EFI_DEVICE_ERROR  The device reported an error while writing back the
-                            data.
-  @retval EFI_NO_MEDIA      There is no media in the device.
+  @retval EFI_SUCCESS         All outstanding data was written to the device.
+  @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.
 
 **/
 EFI_STATUS
@@ -1129,15 +1131,72 @@ ScsiDiskFlushBlocksEx (
   IN OUT EFI_BLOCK_IO2_TOKEN     *Token
   )
 {
+  SCSI_DISK_DEV       *ScsiDiskDevice;
+  EFI_BLOCK_IO_MEDIA  *Media;
+  EFI_STATUS          Status;
+  BOOLEAN             MediaChange;
+  EFI_TPL             OldTpl;
+
+  MediaChange    = FALSE;
+  OldTpl         = gBS->RaiseTPL (TPL_CALLBACK);
+  ScsiDiskDevice = SCSI_DISK_DEV_FROM_BLKIO2 (This);
+
+  if (!IS_DEVICE_FIXED(ScsiDiskDevice)) {
+
+    Status = ScsiDiskDetectMedia (ScsiDiskDevice, FALSE, &MediaChange);
+    if (EFI_ERROR (Status)) {
+      Status = EFI_DEVICE_ERROR;
+      goto Done;
+    }
+
+    if (MediaChange) {
+      gBS->ReinstallProtocolInterface (
+            ScsiDiskDevice->Handle,
+            &gEfiBlockIoProtocolGuid,
+            &ScsiDiskDevice->BlkIo,
+            &ScsiDiskDevice->BlkIo
+            );
+      gBS->ReinstallProtocolInterface (
+             ScsiDiskDevice->Handle,
+             &gEfiBlockIo2ProtocolGuid,
+             &ScsiDiskDevice->BlkIo2,
+             &ScsiDiskDevice->BlkIo2
+             );
+      Status = EFI_MEDIA_CHANGED;
+      goto Done;
+    }
+  }
+
+  Media = ScsiDiskDevice->BlkIo2.Media;
+
+  if (!(Media->MediaPresent)) {
+    Status = EFI_NO_MEDIA;
+    goto Done;
+  }
+
+  if (Media->ReadOnly) {
+    Status = EFI_WRITE_PROTECTED;
+    goto Done;
+  }
+
   //
-  // Signal event and return directly.
+  // Wait for the BlockIo2 requests queue to become empty
+  //
+  while (!IsListEmpty (&ScsiDiskDevice->BlkIo2Queue));
+
+  Status = EFI_SUCCESS;
+
+  //
+  // Signal caller event
   //
   if ((Token != NULL) && (Token->Event != NULL)) {
     Token->TransactionStatus = EFI_SUCCESS;
     gBS->SignalEvent (Token->Event);
   }
 
-  return EFI_SUCCESS;
+Done:
+  gBS->RestoreTPL (OldTpl);
+  return Status;
 }
 
 
diff --git a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h 
b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h
index 836e7ca..b6f801d 100644
--- a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h
+++ b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h
@@ -555,10 +555,12 @@ ScsiDiskWriteBlocksEx (
   @param  This       Indicates a pointer to the calling context.
   @param  Token      A pointer to the token associated with the transaction.
 
-  @retval EFI_SUCCESS       All outstanding data was written to the device.
-  @retval EFI_DEVICE_ERROR  The device reported an error while writing back the
-                            data.
-  @retval EFI_NO_MEDIA      There is no media in the device.
+  @retval EFI_SUCCESS         All outstanding data was written to the device.
+  @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.
 
 **/
 EFI_STATUS
-- 
1.9.5.msysgit.0

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to