}\r
\r
/**\r
- Find a USB device which match the specified short-form device path start with \r
- USB Class or USB WWID device path. If ParentDevicePath is NULL, this function\r
- will search in all USB devices of the platform. If ParentDevicePath is not NULL,\r
- this function will only search in its child devices.\r
+ Find a USB device path which match the specified short-form device path start\r
+ with USB Class or USB WWID device path and load the boot file then return the \r
+ image handle. If ParentDevicePath is NULL, this function will search in all USB\r
+ devices of the platform. If ParentDevicePath is not NULL,this function will only\r
+ search in its child devices.\r
\r
@param ParentDevicePath The device path of the parent.\r
@param ShortFormDevicePath The USB Class or USB WWID device path to match.\r
\r
- @return The handle of matched USB device, or NULL if not found.\r
+ @return The image Handle if find load file from specified short-form device path\r
+ or NULL if not found.\r
\r
**/\r
EFI_HANDLE *\r
UINTN Index;\r
UINTN ParentSize;\r
UINTN Size;\r
- EFI_HANDLE ReturnHandle;\r
+ EFI_HANDLE ImageHandle;\r
+ EFI_HANDLE Handle;\r
+ EFI_DEVICE_PATH_PROTOCOL *FullDevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *NextDevicePath;\r
+\r
+ FullDevicePath = NULL;\r
+ ImageHandle = NULL;\r
\r
//\r
// Get all UsbIo Handles.\r
return NULL;\r
}\r
\r
- ReturnHandle = NULL;\r
ParentSize = (ParentDevicePath == NULL) ? 0 : GetDevicePathSize (ParentDevicePath);\r
for (Index = 0; Index < UsbIoHandleCount; Index++) {\r
//\r
continue;\r
}\r
\r
+ UsbIoDevicePath = DevicePathFromHandle (UsbIoHandleBuffer[Index]);\r
+ if (UsbIoDevicePath == NULL) {\r
+ continue;\r
+ }\r
+\r
if (ParentDevicePath != NULL) {\r
//\r
// Compare starting part of UsbIoHandle's device path with ParentDevicePath.\r
//\r
- UsbIoDevicePath = DevicePathFromHandle (UsbIoHandleBuffer[Index]);\r
- ASSERT (UsbIoDevicePath != NULL);\r
-\r
Size = GetDevicePathSize (UsbIoDevicePath);\r
if ((Size < ParentSize) ||\r
(CompareMem (UsbIoDevicePath, ParentDevicePath, ParentSize - END_DEVICE_PATH_LENGTH) != 0)) {\r
\r
if (BdsMatchUsbClass (UsbIo, (USB_CLASS_DEVICE_PATH *) ShortFormDevicePath) ||\r
BdsMatchUsbWwid (UsbIo, (USB_WWID_DEVICE_PATH *) ShortFormDevicePath)) {\r
- ReturnHandle = UsbIoHandleBuffer[Index];\r
+ //\r
+ // Try to find if there is the boot file in this DevicePath\r
+ //\r
+ NextDevicePath = NextDevicePathNode (ShortFormDevicePath);\r
+ if (!IsDevicePathEnd (NextDevicePath)) {\r
+ FullDevicePath = AppendDevicePath (UsbIoDevicePath, NextDevicePath);\r
+ //\r
+ // Connect the full device path, so that Simple File System protocol\r
+ // could be installed for this USB device.\r
+ //\r
+ BdsLibConnectDevicePath (FullDevicePath);\r
+ Status = gBS->LoadImage (\r
+ TRUE,\r
+ gImageHandle,\r
+ FullDevicePath,\r
+ NULL,\r
+ 0,\r
+ &ImageHandle\r
+ );\r
+ FreePool (FullDevicePath);\r
+ } else {\r
+ FullDevicePath = UsbIoDevicePath;\r
+ Status = EFI_NOT_FOUND;\r
+ }\r
+\r
+ //\r
+ // If we didn't find an image directly, we need to try as if it is a removable device boot option\r
+ // and load the image according to the default boot behavior for removable device.\r
+ //\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // check if there is a bootable removable media could be found in this device path ,\r
+ // and get the bootable media handle\r
+ //\r
+ Handle = BdsLibGetBootableHandle(UsbIoDevicePath);\r
+ if (Handle == NULL) {\r
+ continue;\r
+ }\r
+ //\r
+ // Load the default boot file \EFI\BOOT\boot{machinename}.EFI from removable Media\r
+ // machinename is ia32, ia64, x64, ...\r
+ //\r
+ FullDevicePath = FileDevicePath (Handle, EFI_REMOVABLE_MEDIA_FILE_NAME);\r
+ if (FullDevicePath != NULL) {\r
+ Status = gBS->LoadImage (\r
+ TRUE,\r
+ gImageHandle,\r
+ FullDevicePath,\r
+ NULL,\r
+ 0,\r
+ &ImageHandle\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // The DevicePath failed, and it's not a valid\r
+ // removable media device.\r
+ //\r
+ continue;\r
+ }\r
+ } else {\r
+ continue;\r
+ }\r
+ }\r
break;\r
}\r
}\r
\r
FreePool (UsbIoHandleBuffer);\r
- return ReturnHandle;\r
+ return ImageHandle;\r
}\r
\r
/**\r
Expand USB Class or USB WWID device path node to be full device path of a USB\r
- device in platform.\r
+ device in platform then load the boot file on this full device path and return the \r
+ image handle.\r
\r
This function support following 4 cases:\r
1) Boot Option device path starts with a USB Class or USB WWID device path,\r
\r
@param DevicePath The Boot Option device path.\r
\r
- @return The full device path after expanding, or NULL if there is no USB Class\r
- or USB WWID device path found, or USB Class or USB WWID device path\r
- was found but failed to expand it.\r
+ @return The image handle of boot file, or NULL if there is no boot file found in\r
+ the specified USB Class or USB WWID device path.\r
\r
**/\r
-EFI_DEVICE_PATH_PROTOCOL *\r
+EFI_HANDLE *\r
BdsExpandUsbShortFormDevicePath (\r
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
)\r
{\r
- EFI_DEVICE_PATH_PROTOCOL *FullDevicePath;\r
- EFI_HANDLE *UsbIoHandle;\r
- EFI_DEVICE_PATH_PROTOCOL *UsbIoDevicePath;\r
+ EFI_HANDLE *ImageHandle;\r
EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
- EFI_DEVICE_PATH_PROTOCOL *NextDevicePath;\r
EFI_DEVICE_PATH_PROTOCOL *ShortFormDevicePath;\r
\r
//\r
// Search for USB Class or USB WWID device path node.\r
//\r
ShortFormDevicePath = NULL;\r
- TempDevicePath = DevicePath;\r
+ ImageHandle = NULL;\r
+ TempDevicePath = DevicePath;\r
while (!IsDevicePathEnd (TempDevicePath)) {\r
if ((DevicePathType (TempDevicePath) == MESSAGING_DEVICE_PATH) &&\r
((DevicePathSubType (TempDevicePath) == MSG_USB_CLASS_DP) ||\r
ShortFormDevicePath = TempDevicePath;\r
break;\r
}\r
-\r
TempDevicePath = NextDevicePathNode (TempDevicePath);\r
}\r
\r
//\r
// Boot Option device path starts with USB Class or USB WWID device path.\r
//\r
- UsbIoHandle = BdsFindUsbDevice (NULL, ShortFormDevicePath);\r
- if (UsbIoHandle == NULL) {\r
+ ImageHandle = BdsFindUsbDevice (NULL, ShortFormDevicePath);\r
+ if (ImageHandle == NULL) {\r
//\r
// Failed to find a match in existing devices, connect the short form USB\r
// device path and try again.\r
//\r
BdsLibConnectUsbDevByShortFormDP (0xff, ShortFormDevicePath);\r
- UsbIoHandle = BdsFindUsbDevice (NULL, ShortFormDevicePath);\r
+ ImageHandle = BdsFindUsbDevice (NULL, ShortFormDevicePath);\r
}\r
} else {\r
//\r
SetDevicePathEndNode (((UINT8 *) TempDevicePath) + ((UINTN) ShortFormDevicePath - (UINTN) DevicePath));\r
\r
//\r
- // The USB Host Controller device path is in already in Boot Option device path\r
+ // The USB Host Controller device path is already in Boot Option device path\r
// and USB Bus driver already support RemainingDevicePath starts with USB\r
// Class or USB WWID device path, so just search in existing USB devices and\r
// doesn't perform ConnectController here.\r
//\r
- UsbIoHandle = BdsFindUsbDevice (TempDevicePath, ShortFormDevicePath);\r
+ ImageHandle = BdsFindUsbDevice (TempDevicePath, ShortFormDevicePath);\r
FreePool (TempDevicePath);\r
}\r
\r
- if (UsbIoHandle == NULL) {\r
- //\r
- // Failed to expand USB Class or USB WWID device path.\r
- //\r
- return NULL;\r
- }\r
-\r
- //\r
- // Get device path of the matched USB device.\r
- //\r
- UsbIoDevicePath = DevicePathFromHandle (UsbIoHandle);\r
- ASSERT (UsbIoDevicePath != NULL);\r
-\r
- FullDevicePath = NULL;\r
- //\r
- // Advance to next device path node to skip the USB Class or USB WWID device path.\r
- //\r
- NextDevicePath = NextDevicePathNode (ShortFormDevicePath);\r
- if (!IsDevicePathEnd (NextDevicePath)) {\r
- //\r
- // There is remaining device path after USB Class or USB WWID device path\r
- // node, append it to the USB device path.\r
- //\r
- FullDevicePath = AppendDevicePath (UsbIoDevicePath, NextDevicePath);\r
-\r
- //\r
- // Connect the full device path, so that Simple File System protocol\r
- // could be installed for this USB device.\r
- //\r
- BdsLibConnectDevicePath (FullDevicePath);\r
- } else {\r
- //\r
- // USB Class or WWID device path is in the end.\r
- //\r
- FullDevicePath = UsbIoDevicePath;\r
- }\r
-\r
- return FullDevicePath;\r
+ return ImageHandle;\r
}\r
\r
/**\r
//\r
// Expand USB Class or USB WWID drive path node to full device path.\r
//\r
- WorkingDevicePath = BdsExpandUsbShortFormDevicePath (DevicePath);\r
- if (WorkingDevicePath != NULL) {\r
- DevicePath = WorkingDevicePath;\r
- }\r
+ ImageHandle = BdsExpandUsbShortFormDevicePath (DevicePath);\r
\r
//\r
// Signal the EVT_SIGNAL_READY_TO_BOOT event\r
);\r
}\r
\r
- ASSERT (Option->DevicePath != NULL);\r
- if ((DevicePathType (Option->DevicePath) == BBS_DEVICE_PATH) &&\r
- (DevicePathSubType (Option->DevicePath) == BBS_BBS_DP)\r
- ) {\r
- //\r
- // Check to see if we should legacy BOOT. If yes then do the legacy boot\r
- //\r
- return BdsLibDoLegacyBoot (Option);\r
- }\r
-\r
//\r
- // If the boot option point to Internal FV shell, make sure it is valid\r
+ // By expanding the USB Class or WWID device path, the ImageHandle has returnned.\r
+ // Here get the ImageHandle for the non USB class or WWID device path.\r
//\r
- Status = BdsLibUpdateFvFileDevicePath (&DevicePath, PcdGetPtr(PcdShellFile));\r
- if (!EFI_ERROR(Status)) {\r
- if (Option->DevicePath != NULL) {\r
- FreePool(Option->DevicePath);\r
+ if (ImageHandle == NULL) {\r
+ ASSERT (Option->DevicePath != NULL);\r
+ if ((DevicePathType (Option->DevicePath) == BBS_DEVICE_PATH) &&\r
+ (DevicePathSubType (Option->DevicePath) == BBS_BBS_DP)\r
+ ) {\r
+ //\r
+ // Check to see if we should legacy BOOT. If yes then do the legacy boot\r
+ //\r
+ return BdsLibDoLegacyBoot (Option);\r
}\r
- Option->DevicePath = AllocateZeroPool (GetDevicePathSize (DevicePath));\r
- ASSERT(Option->DevicePath != NULL);\r
- CopyMem (Option->DevicePath, DevicePath, GetDevicePathSize (DevicePath));\r
- //\r
- // Update the shell boot option\r
- //\r
- InitializeListHead (&TempBootLists);\r
- BdsLibRegisterNewOption (&TempBootLists, DevicePath, L"EFI Internal Shell", L"BootOrder");\r
\r
//\r
- // free the temporary device path created by BdsLibUpdateFvFileDevicePath()\r
+ // If the boot option point to Internal FV shell, make sure it is valid\r
//\r
- FreePool (DevicePath);\r
- DevicePath = Option->DevicePath;\r
- }\r
+ Status = BdsLibUpdateFvFileDevicePath (&DevicePath, PcdGetPtr(PcdShellFile));\r
+ if (!EFI_ERROR(Status)) {\r
+ if (Option->DevicePath != NULL) {\r
+ FreePool(Option->DevicePath);\r
+ }\r
+ Option->DevicePath = AllocateZeroPool (GetDevicePathSize (DevicePath));\r
+ ASSERT(Option->DevicePath != NULL);\r
+ CopyMem (Option->DevicePath, DevicePath, GetDevicePathSize (DevicePath));\r
+ //\r
+ // Update the shell boot option\r
+ //\r
+ InitializeListHead (&TempBootLists);\r
+ BdsLibRegisterNewOption (&TempBootLists, DevicePath, L"EFI Internal Shell", L"BootOrder");\r
\r
- DEBUG_CODE_BEGIN();\r
+ //\r
+ // free the temporary device path created by BdsLibUpdateFvFileDevicePath()\r
+ //\r
+ FreePool (DevicePath);\r
+ DevicePath = Option->DevicePath;\r
+ }\r
+\r
+ DEBUG_CODE_BEGIN();\r
\r
if (Option->Description == NULL) {\r
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Booting from unknown device path\n"));\r
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Booting %S\n", Option->Description));\r
}\r
\r
- DEBUG_CODE_END();\r
+ DEBUG_CODE_END();\r
\r
- Status = gBS->LoadImage (\r
- TRUE,\r
- gImageHandle,\r
- DevicePath,\r
- NULL,\r
- 0,\r
- &ImageHandle\r
- );\r
+ Status = gBS->LoadImage (\r
+ TRUE,\r
+ gImageHandle,\r
+ DevicePath,\r
+ NULL,\r
+ 0,\r
+ &ImageHandle\r
+ );\r
\r
- //\r
- // If we didn't find an image directly, we need to try as if it is a removable device boot option\r
- // and load the image according to the default boot behavior for removable device.\r
- //\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // check if there is a bootable removable media could be found in this device path ,\r
- // and get the bootable media handle\r
- //\r
- Handle = BdsLibGetBootableHandle(DevicePath);\r
- if (Handle == NULL) {\r
- goto Done;\r
- }\r
//\r
- // Load the default boot file \EFI\BOOT\boot{machinename}.EFI from removable Media\r
- // machinename is ia32, ia64, x64, ...\r
+ // If we didn't find an image directly, we need to try as if it is a removable device boot option\r
+ // and load the image according to the default boot behavior for removable device.\r
//\r
- FilePath = FileDevicePath (Handle, EFI_REMOVABLE_MEDIA_FILE_NAME);\r
- if (FilePath != NULL) {\r
- Status = gBS->LoadImage (\r
- TRUE,\r
- gImageHandle,\r
- FilePath,\r
- NULL,\r
- 0,\r
- &ImageHandle\r
- );\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // The DevicePath failed, and it's not a valid\r
- // removable media device.\r
- //\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // check if there is a bootable removable media could be found in this device path ,\r
+ // and get the bootable media handle\r
+ //\r
+ Handle = BdsLibGetBootableHandle(DevicePath);\r
+ if (Handle == NULL) {\r
goto Done;\r
}\r
+ //\r
+ // Load the default boot file \EFI\BOOT\boot{machinename}.EFI from removable Media\r
+ // machinename is ia32, ia64, x64, ...\r
+ //\r
+ FilePath = FileDevicePath (Handle, EFI_REMOVABLE_MEDIA_FILE_NAME);\r
+ if (FilePath != NULL) {\r
+ Status = gBS->LoadImage (\r
+ TRUE,\r
+ gImageHandle,\r
+ FilePath,\r
+ NULL,\r
+ 0,\r
+ &ImageHandle\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // The DevicePath failed, and it's not a valid\r
+ // removable media device.\r
+ //\r
+ goto Done;\r
+ }\r
+ }\r
}\r
- }\r
\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // It there is any error from the Boot attempt exit now.\r
- //\r
- goto Done;\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // It there is any error from the Boot attempt exit now.\r
+ //\r
+ goto Done;\r
+ }\r
}\r
//\r
// Provide the image with it's load options\r
//\r
+ if (ImageHandle == NULL) {\r
+ goto Done;\r
+ }\r
Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &ImageInfo);\r
ASSERT_EFI_ERROR (Status);\r
\r