]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPkg/Library/BdsLib/BdsFilePath.c
ARM Packages: Corrected non-DOS line endings
[mirror_edk2.git] / ArmPkg / Library / BdsLib / BdsFilePath.c
index 90be9c1e117895282f106a47abb2dd21d80012c1..f754b8899bdc7d397b3c313a67839486d296aa5f 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 *\r
-*  Copyright (c) 2011-2013, ARM Limited. All rights reserved.\r
+*  Copyright (c) 2011-2014, ARM Limited. All rights reserved.\r
 *  \r
 *  This program and the accompanying materials                          \r
 *  are licensed and made available under the terms and conditions of the BSD License         \r
@@ -300,24 +300,24 @@ TryRemovableDevice (
   return Status;\r
 }\r
 \r
-STATIC
+STATIC\r
 EFI_STATUS\r
-BdsConnectAndUpdateDevicePath (
-  IN OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePath,
-  OUT    EFI_HANDLE                *Handle,
-  OUT    EFI_DEVICE_PATH_PROTOCOL  **RemainingDevicePath
+BdsConnectAndUpdateDevicePath (\r
+  IN OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePath,\r
+  OUT    EFI_HANDLE                *Handle,\r
+  OUT    EFI_DEVICE_PATH_PROTOCOL  **RemainingDevicePath\r
   )\r
 {\r
   EFI_DEVICE_PATH*            Remaining;\r
   EFI_DEVICE_PATH*            NewDevicePath;\r
   EFI_STATUS                  Status;\r
 \r
-  if ((DevicePath == NULL) || (*DevicePath == NULL) || (Handle == NULL)) {
+  if ((DevicePath == NULL) || (*DevicePath == NULL) || (Handle == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   do {\r
-    Remaining = *DevicePath;
+    Remaining = *DevicePath;\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
@@ -337,7 +337,7 @@ BdsConnectAndUpdateDevicePath (
   if (!EFI_ERROR (Status)) {\r
     // Now, we have got the whole Device Path connected, call again ConnectController to ensure all the supported Driver\r
     // Binding Protocol are connected (such as DiskIo and SimpleFileSystem)\r
-    Remaining = *DevicePath;
+    Remaining = *DevicePath;\r
     Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &Remaining, Handle);\r
     if (!EFI_ERROR (Status)) {\r
       Status = gBS->ConnectController (*Handle, NULL, Remaining, FALSE);\r
@@ -360,11 +360,11 @@ BdsConnectAndUpdateDevicePath (
     //TODO: Should we just return success and leave the caller decide if it is the expected RemainingPath\r
     Status = EFI_SUCCESS;\r
   } else {\r
-    Status = TryRemovableDevice (*DevicePath, Handle, &NewDevicePath);
+    Status = TryRemovableDevice (*DevicePath, Handle, &NewDevicePath);\r
     if (!EFI_ERROR (Status)) {\r
-      Status = BdsConnectAndUpdateDevicePath (&NewDevicePath, Handle, RemainingDevicePath);
-      *DevicePath = NewDevicePath;
-      return Status;
+      Status = BdsConnectAndUpdateDevicePath (&NewDevicePath, Handle, RemainingDevicePath);\r
+      *DevicePath = NewDevicePath;\r
+      return Status;\r
     }\r
   }\r
 \r
@@ -375,28 +375,28 @@ BdsConnectAndUpdateDevicePath (
   return Status;\r
 }\r
 \r
-/**
-  Connect a Device Path and return the handle of the driver that support this DevicePath
-
-  @param  DevicePath            Device Path of the File to connect
-  @param  Handle                Handle of the driver that support this DevicePath
-  @param  RemainingDevicePath   Remaining DevicePath nodes that do not match the driver DevicePath
-
-  @retval EFI_SUCCESS           A driver that matches the Device Path has been found
-  @retval EFI_NOT_FOUND         No handles match the search.
-  @retval EFI_INVALID_PARAMETER DevicePath or Handle is NULL
-
+/**\r
+  Connect a Device Path and return the handle of the driver that support this DevicePath\r
+\r
+  @param  DevicePath            Device Path of the File to connect\r
+  @param  Handle                Handle of the driver that support this DevicePath\r
+  @param  RemainingDevicePath   Remaining DevicePath nodes that do not match the driver DevicePath\r
+\r
+  @retval EFI_SUCCESS           A driver that matches the Device Path has been found\r
+  @retval EFI_NOT_FOUND         No handles match the search.\r
+  @retval EFI_INVALID_PARAMETER DevicePath or Handle is NULL\r
+\r
 **/\r
-EFI_STATUS
-BdsConnectDevicePath (
-  IN  EFI_DEVICE_PATH_PROTOCOL* DevicePath,
-  OUT EFI_HANDLE                *Handle,
-  OUT EFI_DEVICE_PATH_PROTOCOL  **RemainingDevicePath
-  )
-{
-  return BdsConnectAndUpdateDevicePath (&DevicePath, Handle, RemainingDevicePath);
-}
-
+EFI_STATUS\r
+BdsConnectDevicePath (\r
+  IN  EFI_DEVICE_PATH_PROTOCOL* DevicePath,\r
+  OUT EFI_HANDLE                *Handle,\r
+  OUT EFI_DEVICE_PATH_PROTOCOL  **RemainingDevicePath\r
+  )\r
+{\r
+  return BdsConnectAndUpdateDevicePath (&DevicePath, Handle, RemainingDevicePath);\r
+}\r
+\r
 BOOLEAN\r
 BdsFileSystemSupport (\r
   IN EFI_DEVICE_PATH *DevicePath,\r
@@ -756,6 +756,7 @@ BdsTftpLoadImage (
   EFI_STATUS                  Status;\r
   EFI_PXE_BASE_CODE_PROTOCOL  *Pxe;\r
   UINT64                      TftpBufferSize;\r
+  UINT64                      TftpTransferSize;\r
   EFI_IP_ADDRESS              ServerIp;\r
   IPv4_DEVICE_PATH*           IPv4DevicePathNode;\r
   FILEPATH_DEVICE_PATH*       FilePathDevicePath;\r
@@ -817,6 +818,7 @@ BdsTftpLoadImage (
   }\r
   UnicodeStrToAsciiStr (FilePathDevicePath->PathName, AsciiPathName);\r
 \r
+  // Try to get the size (required the TFTP server to have "tsize" extension)\r
   Status = Pxe->Mtftp (\r
                   Pxe,\r
                   EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE,\r
@@ -829,41 +831,83 @@ BdsTftpLoadImage (
                   NULL,\r
                   FALSE\r
                   );\r
-  if (EFI_ERROR(Status)) {\r
+  // Pxe.Mtftp replies EFI_PROTOCOL_ERROR if tsize is not supported by the TFTP server\r
+  if (EFI_ERROR (Status) && (Status != EFI_PROTOCOL_ERROR)) {\r
     if (Status == EFI_TFTP_ERROR) {\r
       DEBUG((EFI_D_ERROR, "TFTP Error: Fail to get the size of the file\n"));\r
     }\r
     goto EXIT;\r
   }\r
 \r
-  // Allocate a buffer to hold the whole file.\r
-  Status = gBS->AllocatePages (\r
-                  Type,\r
-                  EfiBootServicesCode,\r
-                  EFI_SIZE_TO_PAGES (TftpBufferSize),\r
-                  Image\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "Failed to allocate space for kernel image: %r\n", Status));\r
-    goto EXIT;\r
-  }\r
+  //\r
+  // Two cases:\r
+  //   1) the file size is unknown (tsize extension not supported)\r
+  //   2) tsize returned the file size\r
+  //\r
+  if (Status == EFI_PROTOCOL_ERROR) {\r
+    for (TftpBufferSize = SIZE_8MB; TftpBufferSize <= FixedPcdGet32 (PcdMaxTftpFileSize); TftpBufferSize += SIZE_8MB) {\r
+      // Allocate a buffer to hold the whole file.\r
+      Status = gBS->AllocatePages (\r
+                      Type,\r
+                      EfiBootServicesCode,\r
+                      EFI_SIZE_TO_PAGES (TftpBufferSize),\r
+                      Image\r
+                      );\r
+      if (EFI_ERROR (Status)) {\r
+        DEBUG ((EFI_D_ERROR, "Failed to allocate space for image: %r\n", Status));\r
+        goto EXIT;\r
+      }\r
 \r
-  Status = Pxe->Mtftp (\r
-                  Pxe,\r
-                  EFI_PXE_BASE_CODE_TFTP_READ_FILE,\r
-                  (VOID *)(UINTN)*Image,\r
-                  FALSE,\r
-                  &TftpBufferSize,\r
-                  NULL,\r
-                  &ServerIp,\r
-                  (UINT8*)AsciiPathName,\r
-                  NULL,\r
-                  FALSE\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    gBS->FreePages (*Image, EFI_SIZE_TO_PAGES (TftpBufferSize));\r
+      TftpTransferSize = TftpBufferSize;\r
+      Status = Pxe->Mtftp (\r
+                      Pxe,\r
+                      EFI_PXE_BASE_CODE_TFTP_READ_FILE,\r
+                      (VOID *)(UINTN)*Image,\r
+                      FALSE,\r
+                      &TftpTransferSize,\r
+                      NULL,\r
+                      &ServerIp,\r
+                      (UINT8*)AsciiPathName,\r
+                      NULL,\r
+                      FALSE\r
+                      );\r
+      if (EFI_ERROR (Status)) {\r
+        gBS->FreePages (*Image, EFI_SIZE_TO_PAGES (TftpBufferSize));\r
+      } else {\r
+        *ImageSize = (UINTN)TftpBufferSize;\r
+        break;\r
+      }\r
+    }\r
   } else {\r
-    *ImageSize = (UINTN)TftpBufferSize;\r
+    // Allocate a buffer to hold the whole file.\r
+    Status = gBS->AllocatePages (\r
+                    Type,\r
+                    EfiBootServicesCode,\r
+                    EFI_SIZE_TO_PAGES (TftpBufferSize),\r
+                    Image\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "Failed to allocate space for kernel image: %r\n", Status));\r
+      goto EXIT;\r
+    }\r
+\r
+    Status = Pxe->Mtftp (\r
+                    Pxe,\r
+                    EFI_PXE_BASE_CODE_TFTP_READ_FILE,\r
+                    (VOID *)(UINTN)*Image,\r
+                    FALSE,\r
+                    &TftpBufferSize,\r
+                    NULL,\r
+                    &ServerIp,\r
+                    (UINT8*)AsciiPathName,\r
+                    NULL,\r
+                    FALSE\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      gBS->FreePages (*Image, EFI_SIZE_TO_PAGES (TftpBufferSize));\r
+    } else {\r
+      *ImageSize = (UINTN)TftpBufferSize;\r
+    }\r
   }\r
 \r
 EXIT:\r
@@ -882,8 +926,8 @@ BDS_FILE_LOADER FileLoaders[] = {
 };\r
 \r
 EFI_STATUS\r
-BdsLoadImageAndUpdateDevicePath (
-  IN OUT EFI_DEVICE_PATH       **DevicePath,
+BdsLoadImageAndUpdateDevicePath (\r
+  IN OUT EFI_DEVICE_PATH       **DevicePath,\r
   IN     EFI_ALLOCATE_TYPE     Type,\r
   IN OUT EFI_PHYSICAL_ADDRESS* Image,\r
   OUT    UINTN                 *FileSize\r
@@ -894,15 +938,15 @@ BdsLoadImageAndUpdateDevicePath (
   EFI_DEVICE_PATH *RemainingDevicePath;\r
   BDS_FILE_LOADER*  FileLoader;\r
 \r
-  Status = BdsConnectAndUpdateDevicePath (DevicePath, &Handle, &RemainingDevicePath);
+  Status = BdsConnectAndUpdateDevicePath (DevicePath, &Handle, &RemainingDevicePath);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
   FileLoader = FileLoaders;\r
   while (FileLoader->Support != NULL) {\r
-    if (FileLoader->Support (*DevicePath, Handle, RemainingDevicePath)) {
-      return FileLoader->LoadImage (*DevicePath, Handle, RemainingDevicePath, Type, Image, FileSize);
+    if (FileLoader->Support (*DevicePath, Handle, RemainingDevicePath)) {\r
+      return FileLoader->LoadImage (*DevicePath, Handle, RemainingDevicePath, Type, Image, FileSize);\r
     }\r
     FileLoader++;\r
   }\r
@@ -911,16 +955,16 @@ BdsLoadImageAndUpdateDevicePath (
 }\r
 \r
 EFI_STATUS\r
-BdsLoadImage (
-  IN     EFI_DEVICE_PATH       *DevicePath,
-  IN     EFI_ALLOCATE_TYPE     Type,
-  IN OUT EFI_PHYSICAL_ADDRESS* Image,
-  OUT    UINTN                 *FileSize
-  )
-{
-  return BdsLoadImageAndUpdateDevicePath (&DevicePath, Type, Image, FileSize);
-}
-
+BdsLoadImage (\r
+  IN     EFI_DEVICE_PATH       *DevicePath,\r
+  IN     EFI_ALLOCATE_TYPE     Type,\r
+  IN OUT EFI_PHYSICAL_ADDRESS* Image,\r
+  OUT    UINTN                 *FileSize\r
+  )\r
+{\r
+  return BdsLoadImageAndUpdateDevicePath (&DevicePath, Type, Image, FileSize);\r
+}\r
+\r
 /**\r
   Start an EFI Application from a Device Path\r
 \r
@@ -947,7 +991,7 @@ BdsStartEfiApplication (
   EFI_LOADED_IMAGE_PROTOCOL*   LoadedImage;\r
 \r
   // Find the nearest supported file loader\r
-  Status = BdsLoadImageAndUpdateDevicePath (&DevicePath, AllocateAnyPages, &BinaryBuffer, &BinarySize);
+  Status = BdsLoadImageAndUpdateDevicePath (&DevicePath, AllocateAnyPages, &BinaryBuffer, &BinarySize);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r