]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmPkg/BdsLib: Prevent a hang in BdsConnectDevicePath() when a sub-device path is...
authorOlivier Martin <olivier.martin@arm.com>
Tue, 19 Aug 2014 13:35:14 +0000 (13:35 +0000)
committeroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 19 Aug 2014 13:35:14 +0000 (13:35 +0000)
Some device paths were making BdsConnectDevicePath() hang.
To prevent these hangs we check if the handle returned by
gBS->LocateDevicePath() is the same after each iteration.

An example of a device path that hangs:
PciRoot(0x0)/Pci(0x1,0x0)/USB(0x0,0x0)/USB(0x3,0x0)/HD(...)
The connect controller function manages to find PciRoot()/Pci(0x1,0x0)
but the USB driver does not produce USB(0x0,0x0)/USB(0x3,0x0) and
returns EFI_SUCCESS on its initialization.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Olivier Martin <olivier.martin@arm.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15835 6f19259b-4bc3-4df7-8a09-765794883524

ArmPkg/Library/BdsLib/BdsFilePath.c
ArmPkg/Library/BdsLib/BdsHelper.c
ArmPkg/Library/BdsLib/BdsInternal.h

index 710821cd05abab65973dfba12fb7a6a6f113bd63..f26ba39ddba8bc1c9122085727336911ea18ee85 100644 (file)
@@ -311,27 +311,40 @@ BdsConnectAndUpdateDevicePath (
   EFI_DEVICE_PATH*            Remaining;\r
   EFI_DEVICE_PATH*            NewDevicePath;\r
   EFI_STATUS                  Status;\r
+  EFI_HANDLE                  PreviousHandle;\r
 \r
   if ((DevicePath == NULL) || (*DevicePath == NULL) || (Handle == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  PreviousHandle = NULL;\r
   do {\r
     Remaining = *DevicePath;\r
+\r
     // The LocateDevicePath() function locates all devices on DevicePath that support Protocol and returns\r
     // the handle to the device that is closest to DevicePath. On output, the device path pointer is modified\r
     // to point to the remaining part of the device path\r
     Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &Remaining, Handle);\r
+\r
     if (!EFI_ERROR (Status)) {\r
-      // Recursive = FALSE: We do not want to start all the device tree\r
-      Status = gBS->ConnectController (*Handle, NULL, Remaining, FALSE);\r
-    }\r
+      if (*Handle == PreviousHandle) {\r
+        //\r
+        // If no forward progress is made try invoking the Dispatcher.\r
+        // A new FV may have been added to the system and new drivers\r
+        // may now be found.\r
+        // Status == EFI_SUCCESS means a driver was dispatched\r
+        // Status == EFI_NOT_FOUND means no new drivers were dispatched\r
+        //\r
+        Status = gDS->Dispatch ();\r
+      }\r
 \r
-    /*// We need to check if RemainingDevicePath does not point on the last node. Otherwise, calling\r
-    // NextDevicePathNode () will return an undetermined Device Path Node\r
-    if (!IsDevicePathEnd (RemainingDevicePath)) {\r
-      RemainingDevicePath = NextDevicePathNode (RemainingDevicePath);\r
-    }*/\r
+      if (!EFI_ERROR (Status)) {\r
+        PreviousHandle = *Handle;\r
+\r
+        // Recursive = FALSE: We do not want to start the whole device tree\r
+        Status = gBS->ConnectController (*Handle, NULL, Remaining, FALSE);\r
+      }\r
+    }\r
   } while (!EFI_ERROR (Status) && !IsDevicePathEnd (Remaining));\r
 \r
   if (!EFI_ERROR (Status)) {\r
index 1d4aa3572840d7d3169949549069f9a330eefbdb..7f83c2be8a7a2a3a9fd6951097f3b38600f458d3 100644 (file)
@@ -14,7 +14,6 @@
 \r
 #include "BdsInternal.h"\r
 \r
-#include <Library/DxeServicesTableLib.h>\r
 #include <Library/HobLib.h>\r
 #include <Library/TimerLib.h>\r
 #include <Library/PrintLib.h>\r
index 88117016ce50f5ea154012a14df009a3be9f32f0..9b5d3a4ff69597a5a6f9de8fb1e4e8a02e38d304 100644 (file)
@@ -19,6 +19,7 @@
 #include <Library/ArmLib.h>\r
 #include <Library/BaseLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
+#include <Library/DxeServicesTableLib.h>\r
 #include <Library/HobLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/UefiLib.h>\r