ShellPkg/map: Recognize CDROM change
authorRuiyu Ni <ruiyu.ni@intel.com>
Tue, 25 Jul 2017 07:30:23 +0000 (15:30 +0800)
committerRuiyu Ni <ruiyu.ni@intel.com>
Wed, 26 Jul 2017 09:19:28 +0000 (17:19 +0800)
The patch adds logic to probe the media change for physical
block devices. So that when media change happens, the BlockIo
is re-installed again.

It fixes the issue when CDROM is removed UEFI Shell still shows
the BlockIo in the output of "map -r".

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
ShellPkg/Library/UefiShellLevel2CommandsLib/Map.c

index 20eb528..3f5925f 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Main file for map shell level 2 command.\r
 \r
-  Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>\r
   (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>\r
   (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
   \r
@@ -979,6 +979,57 @@ STATIC CONST SHELL_PARAM_ITEM MapParamList[] = {
   {NULL, TypeMax}\r
   };\r
 \r
+/**\r
+  The routine issues dummy read for every physical block device to cause\r
+  the BlockIo re-installed if media change happened.\r
+**/\r
+VOID\r
+ProbeForMediaChange (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                            Status;\r
+  UINTN                                 HandleCount;\r
+  EFI_HANDLE                            *Handles;\r
+  EFI_BLOCK_IO_PROTOCOL                 *BlockIo;\r
+  UINTN                                 Index;\r
+\r
+  gBS->LocateHandleBuffer (\r
+         ByProtocol,\r
+         &gEfiBlockIoProtocolGuid,\r
+         NULL,\r
+         &HandleCount,\r
+         &Handles\r
+         );\r
+  //\r
+  // Probe for media change for every physical block io\r
+  //\r
+  for (Index = 0; Index < HandleCount; Index++) {\r
+    Status = gBS->HandleProtocol (\r
+                    Handles[Index],\r
+                    &gEfiBlockIoProtocolGuid,\r
+                    (VOID **) &BlockIo\r
+                    );\r
+    if (!EFI_ERROR (Status)) {\r
+      if (!BlockIo->Media->LogicalPartition) {\r
+        //\r
+        // Per spec:\r
+        //   The function (ReadBlocks) must return EFI_NO_MEDIA or\r
+        //   EFI_MEDIA_CHANGED even if LBA, BufferSize, or Buffer are invalid so the caller can probe\r
+        //   for changes in media state.\r
+        //\r
+        BlockIo->ReadBlocks (\r
+                   BlockIo,\r
+                   BlockIo->Media->MediaId,\r
+                   0,\r
+                   0,\r
+                   NULL\r
+                   );\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
 /**\r
   Function for 'map' command.\r
 \r
@@ -1087,6 +1138,7 @@ ShellCommandRunMap (
                || ShellCommandLineGetFlag(Package, L"-u")\r
                || ShellCommandLineGetFlag(Package, L"-t")\r
               ){\r
+        ProbeForMediaChange ();\r
         if ( ShellCommandLineGetFlag(Package, L"-r")) {\r
           //\r
           // Do the reset\r