Skip to content

Commit eed6de8

Browse files
committed
Fix unloading of drivers for some platforms/medias
* Depending on the platform/media, the file system handle may have additional "phantom" disk instances with no drivers attached. * As a result our assertion that OpenInfoCount will always be 1 is wrong and we must ensure that we process all the open disk protocols until we find one with a driver we can unload.
1 parent ee57bd9 commit eed6de8

File tree

1 file changed

+23
-15
lines changed

1 file changed

+23
-15
lines changed

boot.c

+23-15
Original file line numberDiff line numberDiff line change
@@ -150,29 +150,37 @@ EFI_STATUS UnloadDriver(
150150
)
151151
{
152152
EFI_STATUS Status;
153-
UINTN OpenInfoCount;
153+
UINTN OpenInfoCount, i;
154154
EFI_OPEN_PROTOCOL_INFORMATION_ENTRY* OpenInfo;
155155
EFI_DRIVER_BINDING_PROTOCOL* DriverBinding;
156156
CHAR16* DriverName;
157157

158-
// Open the disk instance associated with the filesystem handle (there should be only one)
158+
// Open the disk instance associated with the filesystem handle
159159
Status = gBS->OpenProtocolInformation(FileSystemHandle, &gEfiDiskIoProtocolGuid, &OpenInfo, &OpenInfoCount);
160-
if (EFI_ERROR(Status) || (OpenInfoCount != 1))
160+
if (EFI_ERROR(Status))
161161
return EFI_NOT_FOUND;
162162

163-
// Obtain the info of the driver servicing this specific disk instance
164-
Status = gBS->OpenProtocol(OpenInfo[0].AgentHandle, &gEfiDriverBindingProtocolGuid, (VOID**)&DriverBinding,
165-
MainImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
166-
if (EFI_ERROR(Status))
167-
return Status;
163+
// There may be multiple disk instances, including "phantom" ones (without a
164+
// bound driver) so try to process them all until we manage to unload a driver.
165+
for (i = 0; i < OpenInfoCount; i++) {
166+
// Obtain the info of the driver servicing this specific disk instance
167+
Status = gBS->OpenProtocol(OpenInfo[i].AgentHandle, &gEfiDriverBindingProtocolGuid,
168+
(VOID**)&DriverBinding, MainImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
169+
if (EFI_ERROR(Status))
170+
continue;
168171

169-
// Display the driver name and version, then unload it using its image handle
170-
DriverName = GetDriverName(OpenInfo[0].AgentHandle);
171-
PrintWarning(L"Unloading existing '%s v0x%x'", DriverName, DriverBinding->Version);
172-
Status = gBS->UnloadImage(DriverBinding->ImageHandle);
173-
if (EFI_ERROR(Status))
174-
PrintWarning(L" Could not unload driver: %r", Status);
175-
return Status;
172+
// Display the driver name and version, then unload it using its image handle
173+
DriverName = GetDriverName(OpenInfo[i].AgentHandle);
174+
PrintWarning(L"Unloading existing '%s v0x%x'", DriverName, DriverBinding->Version);
175+
Status = gBS->UnloadImage(DriverBinding->ImageHandle);
176+
if (EFI_ERROR(Status)) {
177+
PrintWarning(L" Could not unload driver: %r", Status);
178+
continue;
179+
}
180+
return EFI_SUCCESS;
181+
}
182+
183+
return EFI_NOT_FOUND;
176184
}
177185

178186
/*

0 commit comments

Comments
 (0)