]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Add the support for Boot Option with all 0xff USB class Device Path.
authorqianouyang <qianouyang@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 5 Jul 2011 02:08:21 +0000 (02:08 +0000)
committerqianouyang <qianouyang@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 5 Jul 2011 02:08:21 +0000 (02:08 +0000)
Signed-off-by: qianouyang
Reviewed-by: xdu2
Reviewed-by: niruiyu
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11972 6f19259b-4bc3-4df7-8a09-765794883524

IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c

index 4863b648f1f7eb448cc50ad4b02dd22d5146521f..774f0929443c9b49e951b2c1ea2b6ed84a1b2ffc 100644 (file)
@@ -356,15 +356,17 @@ BdsMatchUsbWwid (
 }\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
@@ -381,7 +383,13 @@ BdsFindUsbDevice (
   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
@@ -399,7 +407,6 @@ BdsFindUsbDevice (
     return NULL;\r
   }\r
 \r
-  ReturnHandle = NULL;\r
   ParentSize = (ParentDevicePath == NULL) ? 0 : GetDevicePathSize (ParentDevicePath);\r
   for (Index = 0; Index < UsbIoHandleCount; Index++) {\r
     //\r
@@ -414,13 +421,15 @@ BdsFindUsbDevice (
       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
@@ -430,18 +439,81 @@ BdsFindUsbDevice (
 \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
@@ -458,28 +530,25 @@ BdsFindUsbDevice (
 \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
@@ -487,7 +556,6 @@ BdsExpandUsbShortFormDevicePath (
       ShortFormDevicePath = TempDevicePath;\r
       break;\r
     }\r
-\r
     TempDevicePath = NextDevicePathNode (TempDevicePath);\r
   }\r
 \r
@@ -502,14 +570,14 @@ BdsExpandUsbShortFormDevicePath (
     //\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
@@ -524,53 +592,16 @@ BdsExpandUsbShortFormDevicePath (
     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
@@ -641,10 +672,7 @@ BdsLibBootViaBootOption (
   //\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
@@ -676,41 +704,46 @@ BdsLibBootViaBootOption (
           );\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
@@ -718,63 +751,67 @@ BdsLibBootViaBootOption (
       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