diff options
author | Olivier Martin <olivier.martin@arm.com> | 2014-08-19 13:35:14 +0000 |
---|---|---|
committer | oliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524> | 2014-08-19 13:35:14 +0000 |
commit | 04ad241e2081312be62a9f299311949e85ed725c (patch) | |
tree | be2ad95339379a54c7a35813504c7e39ef01e078 /ArmPkg/Library/BdsLib | |
parent | 5e6322a53066b59c3d351d6ce3e07e07cd08e8dd (diff) | |
download | edk2-platforms-04ad241e2081312be62a9f299311949e85ed725c.tar.xz |
ArmPkg/BdsLib: Prevent a hang in BdsConnectDevicePath() when a sub-device path is not found
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
Diffstat (limited to 'ArmPkg/Library/BdsLib')
-rw-r--r-- | ArmPkg/Library/BdsLib/BdsFilePath.c | 29 | ||||
-rw-r--r-- | ArmPkg/Library/BdsLib/BdsHelper.c | 1 | ||||
-rw-r--r-- | ArmPkg/Library/BdsLib/BdsInternal.h | 1 |
3 files changed, 22 insertions, 9 deletions
diff --git a/ArmPkg/Library/BdsLib/BdsFilePath.c b/ArmPkg/Library/BdsLib/BdsFilePath.c index 710821cd05..f26ba39ddb 100644 --- a/ArmPkg/Library/BdsLib/BdsFilePath.c +++ b/ArmPkg/Library/BdsLib/BdsFilePath.c @@ -311,27 +311,40 @@ BdsConnectAndUpdateDevicePath ( EFI_DEVICE_PATH* Remaining;
EFI_DEVICE_PATH* NewDevicePath;
EFI_STATUS Status;
+ EFI_HANDLE PreviousHandle;
if ((DevicePath == NULL) || (*DevicePath == NULL) || (Handle == NULL)) {
return EFI_INVALID_PARAMETER;
}
+ PreviousHandle = NULL;
do {
Remaining = *DevicePath;
+
// The LocateDevicePath() function locates all devices on DevicePath that support Protocol and returns
// the handle to the device that is closest to DevicePath. On output, the device path pointer is modified
// to point to the remaining part of the device path
Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &Remaining, Handle);
+
if (!EFI_ERROR (Status)) {
- // Recursive = FALSE: We do not want to start all the device tree
- Status = gBS->ConnectController (*Handle, NULL, Remaining, FALSE);
- }
+ if (*Handle == PreviousHandle) {
+ //
+ // If no forward progress is made try invoking the Dispatcher.
+ // A new FV may have been added to the system and new drivers
+ // may now be found.
+ // Status == EFI_SUCCESS means a driver was dispatched
+ // Status == EFI_NOT_FOUND means no new drivers were dispatched
+ //
+ Status = gDS->Dispatch ();
+ }
- /*// We need to check if RemainingDevicePath does not point on the last node. Otherwise, calling
- // NextDevicePathNode () will return an undetermined Device Path Node
- if (!IsDevicePathEnd (RemainingDevicePath)) {
- RemainingDevicePath = NextDevicePathNode (RemainingDevicePath);
- }*/
+ if (!EFI_ERROR (Status)) {
+ PreviousHandle = *Handle;
+
+ // Recursive = FALSE: We do not want to start the whole device tree
+ Status = gBS->ConnectController (*Handle, NULL, Remaining, FALSE);
+ }
+ }
} while (!EFI_ERROR (Status) && !IsDevicePathEnd (Remaining));
if (!EFI_ERROR (Status)) {
diff --git a/ArmPkg/Library/BdsLib/BdsHelper.c b/ArmPkg/Library/BdsLib/BdsHelper.c index 1d4aa35728..7f83c2be8a 100644 --- a/ArmPkg/Library/BdsLib/BdsHelper.c +++ b/ArmPkg/Library/BdsLib/BdsHelper.c @@ -14,7 +14,6 @@ #include "BdsInternal.h"
-#include <Library/DxeServicesTableLib.h>
#include <Library/HobLib.h>
#include <Library/TimerLib.h>
#include <Library/PrintLib.h>
diff --git a/ArmPkg/Library/BdsLib/BdsInternal.h b/ArmPkg/Library/BdsLib/BdsInternal.h index 88117016ce..9b5d3a4ff6 100644 --- a/ArmPkg/Library/BdsLib/BdsInternal.h +++ b/ArmPkg/Library/BdsLib/BdsInternal.h @@ -19,6 +19,7 @@ #include <Library/ArmLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
+#include <Library/DxeServicesTableLib.h>
#include <Library/HobLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
|