Correct return status for the unsupported condition
[people/mcb30/edk2.git] / edk2 / MdeModulePkg / Universal / CapsuleRuntimeDxe / CapsuleService.c
index 5a923cd..383916e 100644 (file)
@@ -47,50 +47,62 @@ Returns:
                                  not set, the capsule has been successfully processed by the firmware.\r
                                  If it set, the ScattlerGatherList is successfully to be set.\r
   EFI_INVALID_PARAMETER          CapsuleCount is less than 1,CapsuleGuid is not supported.\r
-  EFI_DEVICE_ERROR               Failed to SetVariable or AllocatePool or ProcessFirmwareVolume.\r
+  EFI_DEVICE_ERROR               Failed to SetVariable or ProcessFirmwareVolume.\r
 \r
 --*/\r
 {\r
-  UINTN                     CapsuleSize;\r
   UINTN                     ArrayNumber;\r
-  VOID                      *BufferPtr;\r
   EFI_STATUS                Status;\r
-  EFI_HANDLE                FvHandle;\r
   EFI_CAPSULE_HEADER        *CapsuleHeader;\r
 \r
   if (CapsuleCount < 1) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  BufferPtr       = NULL;\r
   CapsuleHeader   = NULL;\r
 \r
   for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {\r
+    //\r
+    // A capsule which has the CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE flag must have\r
+    // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well.\r
+    //\r
     CapsuleHeader = CapsuleHeaderArray[ArrayNumber];\r
     if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)) == CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
-    if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) {\r
+    //\r
+    // Check Capsule image without populate flag by firmware support capsule function  \r
+    //\r
+    if (((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) && \r
+        (SupportCapsuleImage (CapsuleHeader) != EFI_SUCCESS)) {\r
       return EFI_UNSUPPORTED;\r
     }\r
   }\r
 \r
   //\r
-  //Assume that capsules have the same flags on reseting or not.\r
+  // Assume that capsules have the same flags on reseting or not.\r
   //\r
   CapsuleHeader = CapsuleHeaderArray[0];\r
 \r
   if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {\r
     //\r
-    //Check if the platform supports update capsule across a system reset\r
+    // Check if the platform supports update capsule across a system reset\r
     //\r
     if (!FeaturePcdGet(PcdSupportUpdateCapsuleRest)) {\r
       return EFI_UNSUPPORTED;\r
     }\r
-\r
-    if (ScatterGatherList == 0) {\r
+    //\r
+    // ScatterGatherList is only referenced if the capsules are defined to persist across\r
+    // system reset. \r
+    //\r
+    if (ScatterGatherList == (EFI_PHYSICAL_ADDRESS) NULL) {\r
       return EFI_INVALID_PARAMETER;\r
     } else {\r
+      //\r
+      // ScatterGatherList is only referenced if the capsules are defined to persist across\r
+      // system reset. Set its value into NV storage to let pre-boot driver to pick it up \r
+      // after coming through a system reset.\r
+      //\r
       Status = EfiSetVariable (\r
                  EFI_CAPSULE_VARIABLE_NAME,\r
                  &gEfiCapsuleVendorGuid,\r
@@ -99,43 +111,32 @@ Returns:
                  (VOID *) &ScatterGatherList\r
                  );\r
       if (Status != EFI_SUCCESS) {\r
-        return EFI_DEVICE_ERROR;\r
+        return Status;\r
       }\r
+      //\r
+      // Successfully set the capsule image address into variable.\r
+      //\r
+      return EFI_SUCCESS;\r
     }\r
-    return EFI_SUCCESS;\r
   }\r
 \r
   //\r
-  //The rest occurs in the condition of non-reset mode\r
+  // The rest occurs in the condition of non-reset mode\r
+  // Now Runtime mode doesn't support the non-reset capsule image.\r
   //\r
   if (EfiAtRuntime ()) {\r
-    return EFI_INVALID_PARAMETER;\r
+    return EFI_UNSUPPORTED;\r
   }\r
 \r
   //\r
-  //Here should be in the boot-time\r
+  // Here should be in the boot-time for non-reset capsule image\r
+  // Default process to Update Capsule image into Flash.\r
   //\r
   for (ArrayNumber = 0; ArrayNumber < CapsuleCount ; ArrayNumber++) {\r
-    CapsuleHeader = CapsuleHeaderArray[ArrayNumber];\r
-    CapsuleSize = CapsuleHeader->CapsuleImageSize - CapsuleHeader->HeaderSize;\r
-\r
-    BufferPtr = AllocatePool (CapsuleSize);\r
-    if (BufferPtr == NULL) {\r
-      return EFI_DEVICE_ERROR;\r
-    }\r
-\r
-    CopyMem (BufferPtr, (UINT8*)CapsuleHeader+ CapsuleHeader->HeaderSize, CapsuleSize);\r
-\r
-    //\r
-    //Call DXE service ProcessFirmwareVolume to process immediatelly\r
-    //\r
-    Status = gDS->ProcessFirmwareVolume (BufferPtr, CapsuleSize, &FvHandle);\r
-    if (Status != EFI_SUCCESS) {\r
-      FreePool (BufferPtr);\r
-      return EFI_DEVICE_ERROR;\r
+    Status = ProcessCapsuleImage (CapsuleHeaderArray[ArrayNumber]);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
     }\r
-    gDS->Dispatch ();\r
-    FreePool (BufferPtr);\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -189,10 +190,18 @@ Returns:
 \r
   for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {\r
     CapsuleHeader = CapsuleHeaderArray[ArrayNumber];\r
+    //\r
+    // A capsule which has the CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE flag must have\r
+    // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well.\r
+    //\r
     if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)) == CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
-    if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) {\r
+    //\r
+    // Check Capsule image without populate flag by firmware support capsule function  \r
+    //\r
+    if (((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) && \r
+        (SupportCapsuleImage (CapsuleHeader) != EFI_SUCCESS)) {\r
       return EFI_UNSUPPORTED;\r
     }\r
   }\r