Enhance Capsule driver to update capsule one by one.
authorlgao4 <lgao4@de2fecce-e211-0410-80a6-f3fac2684e05>
Tue, 18 Aug 2009 01:23:29 +0000 (01:23 +0000)
committerlgao4 <lgao4@de2fecce-e211-0410-80a6-f3fac2684e05>
Tue, 18 Aug 2009 01:23:29 +0000 (01:23 +0000)
git-svn-id: https://edk2.tianocore.org/svn/edk2/trunk@9082 de2fecce-e211-0410-80a6-f3fac2684e05

edk2/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c

index 2bf456c..2a45bf3 100644 (file)
@@ -63,6 +63,7 @@ UpdateCapsule (
   UINTN                     ArrayNumber;\r
   EFI_STATUS                Status;\r
   EFI_CAPSULE_HEADER        *CapsuleHeader;\r
+  BOOLEAN                   NeedReset;\r
   \r
   //\r
   // Capsule Count can't be less than one.\r
@@ -70,8 +71,8 @@ UpdateCapsule (
   if (CapsuleCount < 1) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-\r
-  CapsuleHeader   = NULL;\r
+  NeedReset     = FALSE;\r
+  CapsuleHeader = NULL;\r
 \r
   for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {\r
     //\r
@@ -92,71 +93,66 @@ UpdateCapsule (
   }\r
 \r
   //\r
-  // Assume that capsules have the same flags on reseting or not.\r
-  //\r
-  CapsuleHeader = CapsuleHeaderArray[0];\r
-  \r
+  // Walk through all capsules, record whether there is a capsule \r
+  // needs reset. And then process capsules which has no reset flag directly.\r
   //\r
-  //  Process across reset capsule image.\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
-    //\r
-    if (!FeaturePcdGet(PcdSupportUpdateCapsuleReset)) {\r
-      return EFI_UNSUPPORTED;\r
-    }\r
+  for (ArrayNumber = 0; ArrayNumber < CapsuleCount ; ArrayNumber++) {\r
+    CapsuleHeader = CapsuleHeaderArray[ArrayNumber];\r
     //\r
-    // ScatterGatherList is only referenced if the capsules are defined to persist across\r
-    // system reset. \r
+    // Here should be in the boot-time for non-reset capsule image\r
+    // Platform specific update for the non-reset capsule image.\r
     //\r
-    if (ScatterGatherList == (EFI_PHYSICAL_ADDRESS) (UINTN) 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 = gRT->SetVariable (\r
-                     EFI_CAPSULE_VARIABLE_NAME,\r
-                     &gEfiCapsuleVendorGuid,\r
-                     EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
-                     sizeof (UINTN),\r
-                     (VOID *) &ScatterGatherList\r
-                     );\r
-      if (Status != EFI_SUCCESS) {\r
+    if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) == 0) {\r
+      if (EfiAtRuntime ()) { \r
+        Status = EFI_UNSUPPORTED;\r
+      } else {\r
+        Status = ProcessCapsuleImage(CapsuleHeader);\r
+      }\r
+      if (EFI_ERROR(Status)) {\r
         return Status;\r
       }\r
-      //\r
-      // Successfully set the capsule image address into EFI variable.\r
-      //\r
-      return EFI_SUCCESS;\r
+    } else {\r
+      NeedReset = TRUE;\r
     }\r
   }\r
+  \r
+  //\r
+  // After launching all capsules who has no reset flag, if no more capsules claims\r
+  // for a system reset just return.\r
+  //\r
+  if (!NeedReset) {\r
+    return EFI_SUCCESS;\r
+  }\r
 \r
   //\r
-  // Process the non-reset capsule image.\r
+  // ScatterGatherList is only referenced if the capsules are defined to persist across\r
+  // system reset. \r
   //\r
-  if (EfiAtRuntime ()) {\r
-    //\r
-    // Runtime mode doesn't support the non-reset capsule image.\r
-    //\r
-    return EFI_UNSUPPORTED;\r
+  if (ScatterGatherList == (EFI_PHYSICAL_ADDRESS) (UINTN) NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   //\r
-  // Here should be in the boot-time for non-reset capsule image\r
-  // Platform specific update for the non-reset capsule image.\r
+  // Check if the platform supports update capsule across a system reset\r
   //\r
-  for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {\r
-    Status = ProcessCapsuleImage (CapsuleHeaderArray[ArrayNumber]);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
+  if (!FeaturePcdGet(PcdSupportUpdateCapsuleReset)) {\r
+    return EFI_UNSUPPORTED;\r
   }\r
 \r
-  return EFI_SUCCESS;\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 = gRT->SetVariable (\r
+                 EFI_CAPSULE_VARIABLE_NAME,\r
+                 &gEfiCapsuleVendorGuid,\r
+                 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
+                 sizeof (UINTN),\r
+                 (VOID *) &ScatterGatherList\r
+                 );\r
+\r
+  return Status;\r
 }\r
 \r
 /**\r