]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/IScsiDxe/IScsiConfig.c
MdeModulePkg-DxeCore: rename CoreGetMemoryMapPropertiesTable
[mirror_edk2.git] / NetworkPkg / IScsiDxe / IScsiConfig.c
index 3c299be94928354ce8c58ce3b3759f3d9b59bcb2..69a400389dc5d57372b665ac1f0a2e3442dacdb6 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Helper functions for configuring or getting the parameters relating to iSCSI.\r
 \r
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -14,7 +14,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "IScsiImpl.h"\r
 \r
-EFI_GUID        mVendorGuid              = ISCSI_CONFIG_GUID;\r
 CHAR16          mVendorStorageName[]     = L"ISCSI_CONFIG_IFR_NVDATA";\r
 BOOLEAN         mIScsiDeviceListUpdated  = FALSE;\r
 UINTN           mNumberOfIScsiDevices    = 0;\r
@@ -30,10 +29,7 @@ HII_VENDOR_DEVICE_PATH  mIScsiHiiVendorDevicePath = {
         (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
       }\r
     },\r
-    //\r
-    // {49D7B73E-143D-4716-977B-C45F1CB038CC}\r
-    //\r
-    { 0x49d7b73e, 0x143d, 0x4716, { 0x97, 0x7b, 0xc4, 0x5f, 0x1c, 0xb0, 0x38, 0xcc } }\r
+    ISCSI_CONFIG_GUID\r
   },\r
   {\r
     END_DEVICE_PATH_TYPE,\r
@@ -421,15 +417,16 @@ IScsiConvertAttemptConfigDataToIfrNvData (
   AsciiStrToUnicodeStr (Attempt->AttemptName, IfrNvData->AttemptName);\r
 }\r
 \r
-\r
 /**\r
   Convert the IFR data to iSCSI configuration data.\r
 \r
-  @param[in]       IfrNvData              The IFR nv data.\r
+  @param[in]       IfrNvData              Point to ISCSI_CONFIG_IFR_NVDATA.\r
   @param[in, out]  Attempt                The iSCSI attempt config data.\r
 \r
   @retval EFI_INVALID_PARAMETER  Any input or configured parameter is invalid.\r
   @retval EFI_NOT_FOUND          Cannot find the corresponding variable.\r
+  @retval EFI_OUT_OF_RESOURCES   The operation is failed due to lack of resources.\r
+  @retval EFI_ABORTED            The operation is aborted.\r
   @retval EFI_SUCCESS            The operation is completed successfully.\r
 \r
 **/\r
@@ -451,6 +448,11 @@ IScsiConvertIfrNvDataToAttemptConfigData (
   CHAR16                      IpMode[64];\r
   ISCSI_NIC_INFO              *NicInfo;\r
   EFI_INPUT_KEY               Key;\r
+  UINT8                       *AttemptConfigOrder;\r
+  UINTN                       AttemptConfigOrderSize;\r
+  UINT8                       *AttemptOrderTmp;\r
+  UINTN                       TotalNumber;\r
+  EFI_STATUS                  Status;\r
 \r
   if (IfrNvData == NULL || Attempt == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -539,7 +541,24 @@ IScsiConvertIfrNvDataToAttemptConfigData (
           );\r
         return EFI_INVALID_PARAMETER;\r
       }\r
+\r
+      //\r
+      // Validate iSCSI target name configuration again:\r
+      // The format of iSCSI target name is already verified in IScsiFormCallback() when\r
+      // user input the name; here we only check the case user does not input the name.\r
+      //\r
+      if (Attempt->SessionConfigData.TargetName[0] == '\0') {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &Key,\r
+          L"iSCSI target name is NULL!",\r
+          NULL\r
+          );\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
     }\r
+\r
+\r
     //\r
     // Validate the authentication info.\r
     //\r
@@ -614,6 +633,61 @@ IScsiConvertIfrNvDataToAttemptConfigData (
     }\r
   }\r
 \r
+  //\r
+  // Update the iSCSI Mode data and record it in attempt help info.\r
+  //\r
+  Attempt->SessionConfigData.Enabled = IfrNvData->Enabled;\r
+  if (IfrNvData->Enabled == ISCSI_DISABLED) {\r
+    UnicodeSPrint (IScsiMode, 64, L"Disabled");\r
+  } else if (IfrNvData->Enabled == ISCSI_ENABLED) {\r
+    UnicodeSPrint (IScsiMode, 64, L"Enabled");\r
+  } else if (IfrNvData->Enabled == ISCSI_ENABLED_FOR_MPIO) {\r
+    UnicodeSPrint (IScsiMode, 64, L"Enabled for MPIO");\r
+  }\r
+\r
+  if (IfrNvData->IpMode == IP_MODE_IP4) {\r
+    UnicodeSPrint (IpMode, 64, L"IP4");\r
+  } else if (IfrNvData->IpMode == IP_MODE_IP6) {\r
+    UnicodeSPrint (IpMode, 64, L"IP6");\r
+  } else if (IfrNvData->IpMode == IP_MODE_AUTOCONFIG) {\r
+    UnicodeSPrint (IpMode, 64, L"Autoconfigure");\r
+  }\r
+\r
+  NicInfo = IScsiGetNicInfoByIndex (Attempt->NicIndex);\r
+  if (NicInfo == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  MacString = (CHAR16 *) AllocateZeroPool (ISCSI_MAX_MAC_STRING_LEN * sizeof (CHAR16));\r
+  if (MacString == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  AsciiStrToUnicodeStr (Attempt->MacString, MacString);\r
+\r
+  UnicodeSPrint (\r
+    mPrivate->PortString,\r
+    (UINTN) ISCSI_NAME_IFR_MAX_SIZE,\r
+    L"MAC: %s, PFA: Bus %d | Dev %d | Func %d, iSCSI mode: %s, IP version: %s",\r
+    MacString,\r
+    NicInfo->BusNumber,\r
+    NicInfo->DeviceNumber,\r
+    NicInfo->FunctionNumber,\r
+    IScsiMode,\r
+    IpMode\r
+    );\r
+\r
+  Attempt->AttemptTitleHelpToken = HiiSetString (\r
+                                     mCallbackInfo->RegisteredHandle,\r
+                                     Attempt->AttemptTitleHelpToken,\r
+                                     mPrivate->PortString,\r
+                                     NULL\r
+                                     );\r
+  if (Attempt->AttemptTitleHelpToken == 0) {\r
+    FreePool (MacString);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
   //\r
   // Check whether this attempt is an existing one.\r
   //\r
@@ -683,7 +757,70 @@ IScsiConvertIfrNvDataToAttemptConfigData (
       }\r
     }\r
 \r
-  } else if (ExistAttempt == NULL && IfrNvData->Enabled != ISCSI_DISABLED) {\r
+  } else if (ExistAttempt == NULL) {\r
+    //\r
+    // When a new attempt is created, pointer of the attempt is saved to\r
+    // mPrivate->NewAttempt, and also saved to mCallbackInfo->Current in\r
+    // IScsiConfigProcessDefault. If input Attempt does not match any existing\r
+    // attempt, it should be a new created attempt. Save it to system now.\r
+    //    \r
+    ASSERT (Attempt == mPrivate->NewAttempt);\r
+\r
+    //\r
+    // Save current order number for this attempt.\r
+    //\r
+    AttemptConfigOrder = IScsiGetVariableAndSize (\r
+                           L"AttemptOrder",\r
+                           &gIScsiConfigGuid,\r
+                           &AttemptConfigOrderSize\r
+                           );\r
+\r
+    TotalNumber = AttemptConfigOrderSize / sizeof (UINT8);\r
+    TotalNumber++;\r
+\r
+    //\r
+    // Append the new created attempt order to the end.\r
+    //\r
+    AttemptOrderTmp = AllocateZeroPool (TotalNumber * sizeof (UINT8));\r
+    if (AttemptOrderTmp == NULL) {\r
+      if (AttemptConfigOrder != NULL) {\r
+        FreePool (AttemptConfigOrder);\r
+      }\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
+    if (AttemptConfigOrder != NULL) {\r
+      CopyMem (AttemptOrderTmp, AttemptConfigOrder, AttemptConfigOrderSize);\r
+      FreePool (AttemptConfigOrder);\r
+    }\r
+\r
+    AttemptOrderTmp[TotalNumber - 1] = Attempt->AttemptConfigIndex;\r
+    AttemptConfigOrder               = AttemptOrderTmp;\r
+    AttemptConfigOrderSize           = TotalNumber * sizeof (UINT8);\r
+\r
+    Status = gRT->SetVariable (\r
+                    L"AttemptOrder",\r
+                    &gIScsiConfigGuid,\r
+                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+                    AttemptConfigOrderSize,\r
+                    AttemptConfigOrder\r
+                    );\r
+    FreePool (AttemptConfigOrder);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+    //\r
+    // Insert new created attempt to array.\r
+    //\r
+    InsertTailList (&mPrivate->AttemptConfigs, &Attempt->Link);\r
+    mPrivate->AttemptCount++;\r
+    //\r
+    // Reset mPrivate->NewAttempt to NULL, which indicates none attempt is created\r
+    // but not saved now.\r
+    //\r
+    mPrivate->NewAttempt = NULL;\r
+\r
     if (IfrNvData->Enabled == ISCSI_ENABLED_FOR_MPIO) {\r
       //\r
       // This new Attempt is enabled for MPIO; enable the multipath mode.\r
@@ -693,61 +830,8 @@ IScsiConvertIfrNvDataToAttemptConfigData (
     } else if (IfrNvData->Enabled == ISCSI_ENABLED) {\r
       mPrivate->SinglePathCount++;\r
     }\r
-  }\r
-\r
-  //\r
-  // Update the iSCSI Mode data and record it in attempt help info.\r
-  //\r
-  Attempt->SessionConfigData.Enabled = IfrNvData->Enabled;\r
-  if (IfrNvData->Enabled == ISCSI_DISABLED) {\r
-    UnicodeSPrint (IScsiMode, 64, L"Disabled");\r
-  } else if (IfrNvData->Enabled == ISCSI_ENABLED) {\r
-    UnicodeSPrint (IScsiMode, 64, L"Enabled");\r
-  } else if (IfrNvData->Enabled == ISCSI_ENABLED_FOR_MPIO) {\r
-    UnicodeSPrint (IScsiMode, 64, L"Enabled for MPIO");\r
-  }\r
-\r
-  if (IfrNvData->IpMode == IP_MODE_IP4) {\r
-    UnicodeSPrint (IpMode, 64, L"IP4");\r
-  } else if (IfrNvData->IpMode == IP_MODE_IP6) {\r
-    UnicodeSPrint (IpMode, 64, L"IP6");\r
-  } else if (IfrNvData->IpMode == IP_MODE_AUTOCONFIG) {\r
-    UnicodeSPrint (IpMode, 64, L"Autoconfigure");\r
-  }\r
-\r
-  NicInfo = IScsiGetNicInfoByIndex (Attempt->NicIndex);\r
-  if (NicInfo == NULL) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  MacString = (CHAR16 *) AllocateZeroPool (ISCSI_MAX_MAC_STRING_LEN * sizeof (CHAR16));\r
-  if (MacString == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  AsciiStrToUnicodeStr (Attempt->MacString, MacString);\r
-\r
-  UnicodeSPrint (\r
-    mPrivate->PortString,\r
-    (UINTN) ISCSI_NAME_IFR_MAX_SIZE,\r
-    L"MAC: %s, PFA: Bus %d | Dev %d | Func %d, iSCSI mode: %s, IP version: %s",\r
-    MacString,\r
-    NicInfo->BusNumber,\r
-    NicInfo->DeviceNumber,\r
-    NicInfo->FunctionNumber,\r
-    IScsiMode,\r
-    IpMode\r
-    );\r
 \r
-  Attempt->AttemptTitleHelpToken = HiiSetString (\r
-                                     mCallbackInfo->RegisteredHandle,\r
-                                     Attempt->AttemptTitleHelpToken,\r
-                                     mPrivate->PortString,\r
-                                     NULL\r
-                                     );\r
-  if (Attempt->AttemptTitleHelpToken == 0) {\r
-    FreePool (MacString);\r
-    return EFI_OUT_OF_RESOURCES;\r
+    IScsiConfigUpdateAttempt ();\r
   }\r
 \r
   //\r
@@ -919,7 +1003,7 @@ IScsiConfigAddAttempt (
       MacString\r
       );\r
 \r
-    UnicodeSPrint (mPrivate->PortString, (UINTN) ISCSI_NAME_IFR_MAX_SIZE, L"Port %s", MacString);\r
+    UnicodeSPrint (mPrivate->PortString, (UINTN) ISCSI_NAME_IFR_MAX_SIZE, L"MAC %s", MacString);\r
     PortTitleToken = HiiSetString (\r
                        mCallbackInfo->RegisteredHandle,\r
                        0,\r
@@ -957,7 +1041,7 @@ IScsiConfigAddAttempt (
 \r
   Status = HiiUpdateForm (\r
              mCallbackInfo->RegisteredHandle, // HII handle\r
-             &mVendorGuid,                    // Formset GUID\r
+             &gIScsiConfigGuid,               // Formset GUID\r
              FORMID_MAC_FORM,                 // Form ID\r
              StartOpCodeHandle,               // Label for where to insert opcodes\r
              EndOpCodeHandle                  // Replace data\r
@@ -1027,7 +1111,7 @@ IScsiConfigUpdateAttempt (
 \r
   HiiUpdateForm (\r
     mCallbackInfo->RegisteredHandle, // HII handle\r
-    &mVendorGuid,                    // Formset GUID\r
+    &gIScsiConfigGuid,               // Formset GUID\r
     FORMID_MAIN_FORM,                // Form ID\r
     StartOpCodeHandle,               // Label for where to insert opcodes\r
     EndOpCodeHandle                  // Replace data\r
@@ -1072,7 +1156,7 @@ IScsiConfigDeleteAttempts (
 \r
   AttemptConfigOrder = IScsiGetVariableAndSize (\r
                          L"AttemptOrder",\r
-                         &mVendorGuid,\r
+                         &gIScsiConfigGuid,\r
                          &AttemptConfigOrderSize\r
                          );\r
   if ((AttemptConfigOrder == NULL) || (AttemptConfigOrderSize == 0)) {\r
@@ -1081,7 +1165,8 @@ IScsiConfigDeleteAttempts (
 \r
   AttemptNewOrder = AllocateZeroPool (AttemptConfigOrderSize);\r
   if (AttemptNewOrder == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Error;\r
   }\r
 \r
   Total    = AttemptConfigOrderSize / sizeof (UINT8);\r
@@ -1178,23 +1263,27 @@ IScsiConfigDeleteAttempts (
     }\r
   }\r
 \r
-  Attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS\r
-              | EFI_VARIABLE_NON_VOLATILE;\r
+  Attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE;\r
 \r
   //\r
   // Update AttemptOrder in NVR.\r
   //\r
   Status = gRT->SetVariable (\r
                   L"AttemptOrder",\r
-                  &mVendorGuid,\r
+                  &gIScsiConfigGuid,\r
                   Attribute,\r
                   NewTotal * sizeof (UINT8),\r
                   AttemptNewOrder\r
                   );\r
 \r
 Error:\r
-  FreePool (AttemptConfigOrder);\r
-  FreePool (AttemptNewOrder);\r
+  if (AttemptConfigOrder != NULL) {\r
+    FreePool (AttemptConfigOrder);\r
+  }\r
+\r
+  if (AttemptNewOrder != NULL) {\r
+    FreePool (AttemptNewOrder);\r
+  }\r
   \r
   return Status;\r
 }\r
@@ -1240,7 +1329,7 @@ IScsiConfigDisplayDeleteAttempts (
 \r
   AttemptConfigOrder = IScsiGetVariableAndSize (\r
                          L"AttemptOrder",\r
-                         &mVendorGuid,\r
+                         &gIScsiConfigGuid,\r
                          &AttemptConfigOrderSize\r
                          );\r
   if (AttemptConfigOrder != NULL) {\r
@@ -1277,7 +1366,7 @@ IScsiConfigDisplayDeleteAttempts (
 \r
   Status = HiiUpdateForm (\r
              mCallbackInfo->RegisteredHandle, // HII handle\r
-             &mVendorGuid,                    // Formset GUID\r
+             &gIScsiConfigGuid,               // Formset GUID\r
              FORMID_DELETE_FORM,              // Form ID\r
              StartOpCodeHandle,               // Label for where to insert opcodes\r
              EndOpCodeHandle                  // Replace data\r
@@ -1324,6 +1413,7 @@ IScsiConfigDisplayOrderAttempts (
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
+  ASSERT (StartOpCodeHandle != NULL);\r
 \r
   OptionsOpCodeHandle = NULL;\r
 \r
@@ -1377,7 +1467,7 @@ IScsiConfigDisplayOrderAttempts (
 Exit:\r
   Status = HiiUpdateForm (\r
              mCallbackInfo->RegisteredHandle, // HII handle\r
-             &mVendorGuid,                    // Formset GUID\r
+             &gIScsiConfigGuid,               // Formset GUID\r
              FORMID_ORDER_FORM,               // Form ID\r
              StartOpCodeHandle,               // Label for where to insert opcodes\r
              EndOpCodeHandle                  // Replace data\r
@@ -1421,7 +1511,7 @@ IScsiConfigOrderAttempts (
 \r
   AttemptConfigOrder = IScsiGetVariableAndSize (\r
                          L"AttemptOrder",\r
-                         &mVendorGuid,\r
+                         &gIScsiConfigGuid,\r
                          &AttemptConfigOrderSize\r
                          );\r
   if (AttemptConfigOrder == NULL) {\r
@@ -1483,8 +1573,8 @@ IScsiConfigOrderAttempts (
 \r
   Status = gRT->SetVariable (\r
                   L"AttemptOrder",\r
-                  &mVendorGuid,\r
-                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+                  &gIScsiConfigGuid,\r
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
                   AttemptConfigOrderSize,\r
                   AttemptConfigOrderTmp\r
                   );\r
@@ -1530,10 +1620,11 @@ IScsiConfigProcessDefault (
   UINT8                       *AttemptConfigOrder;\r
   UINTN                       AttemptConfigOrderSize;\r
   UINTN                       TotalNumber;\r
-  UINT8                       *AttemptOrderTmp;\r
   UINTN                       Index;\r
-  EFI_STATUS                  Status;\r
 \r
+  //\r
+  // Is User creating a new attempt?\r
+  //\r
   NewAttempt = FALSE;\r
 \r
   if ((KeyValue >= KEY_MAC_ENTRY_BASE) &&\r
@@ -1555,6 +1646,14 @@ IScsiConfigProcessDefault (
     //\r
     return EFI_SUCCESS;\r
   }\r
+  \r
+  //\r
+  // Free any attempt that is previously created but not saved to system.\r
+  //\r
+  if (mPrivate->NewAttempt != NULL) {\r
+    FreePool (mPrivate->NewAttempt);\r
+    mPrivate->NewAttempt = NULL;\r
+  }\r
 \r
   if (NewAttempt) {\r
     //\r
@@ -1567,7 +1666,7 @@ IScsiConfigProcessDefault (
     }\r
     \r
     //\r
-    // Create the new attempt and save to NVR.\r
+    // Create new attempt.\r
     //\r
 \r
     AttemptConfigData = AllocateZeroPool (sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA));\r
@@ -1588,7 +1687,7 @@ IScsiConfigProcessDefault (
     //\r
     AttemptConfigOrder = IScsiGetVariableAndSize (\r
                            L"AttemptOrder",\r
-                           &mVendorGuid,\r
+                           &gIScsiConfigGuid,\r
                            &AttemptConfigOrderSize\r
                            );\r
 \r
@@ -1613,46 +1712,14 @@ IScsiConfigProcessDefault (
     TotalNumber++;\r
 \r
     //\r
-    // Append the new created attempt order to the end.\r
+    // Record the mapping between attempt order and attempt's configdata.\r
     //\r
-    AttemptOrderTmp = AllocateZeroPool (TotalNumber * sizeof (UINT8));\r
-    if (AttemptOrderTmp == NULL) {\r
-      FreePool (AttemptConfigData);\r
-      if (AttemptConfigOrder != NULL) {\r
-        FreePool (AttemptConfigOrder);\r
-      }\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
+    AttemptConfigData->AttemptConfigIndex  = CurrentAttemptConfigIndex;\r
 \r
     if (AttemptConfigOrder != NULL) {\r
-      CopyMem (AttemptOrderTmp, AttemptConfigOrder, AttemptConfigOrderSize);\r
-      FreePool (AttemptConfigOrder);      \r
+      FreePool (AttemptConfigOrder);\r
     }\r
 \r
-    AttemptOrderTmp[TotalNumber - 1] = CurrentAttemptConfigIndex;    \r
-    AttemptConfigOrder               = AttemptOrderTmp;\r
-    AttemptConfigOrderSize           = TotalNumber * sizeof (UINT8);\r
-\r
-    Status = gRT->SetVariable (\r
-                    L"AttemptOrder",\r
-                    &mVendorGuid,\r
-                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
-                    AttemptConfigOrderSize,\r
-                    AttemptConfigOrder\r
-                    );\r
-    FreePool (AttemptConfigOrder);\r
-    if (EFI_ERROR (Status)) {\r
-      FreePool (AttemptConfigData);\r
-      return Status;\r
-    }\r
-\r
-    //\r
-    // Record the mapping between attempt order and attempt's configdata.\r
-    //\r
-    AttemptConfigData->AttemptConfigIndex  = CurrentAttemptConfigIndex;\r
-    InsertTailList (&mPrivate->AttemptConfigs, &AttemptConfigData->Link);\r
-    mPrivate->AttemptCount++;\r
-\r
     //\r
     // Record the MAC info in Config Data.\r
     //\r
@@ -1708,6 +1775,13 @@ IScsiConfigProcessDefault (
       );\r
     UnicodeStrToAsciiStr (mPrivate->PortString, AttemptConfigData->AttemptName);\r
 \r
+    //\r
+    // Save the created Attempt temporarily. If user does not save the attempt\r
+    // by press 'KEY_SAVE_ATTEMPT_CONFIG' later, iSCSI driver would know that\r
+    // and free resources.\r
+    //\r
+    mPrivate->NewAttempt = (VOID *) AttemptConfigData;\r
+\r
   } else {\r
     //\r
     // Determine which Attempt user has selected to configure.\r
@@ -1734,10 +1808,11 @@ IScsiConfigProcessDefault (
   \r
   IScsiConvertAttemptConfigDataToIfrNvData (AttemptConfigData, IfrNvData);\r
 \r
+  //\r
+  // Update current attempt to be a new created attempt or an existing attempt.\r
+  //\r
   mCallbackInfo->Current = AttemptConfigData;\r
 \r
-  IScsiConfigUpdateAttempt ();\r
-\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -1837,7 +1912,7 @@ IScsiFormExtractConfig (
   }\r
 \r
   *Progress = Request;\r
-  if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &mVendorGuid, mVendorStorageName)) {\r
+  if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gIScsiConfigGuid, mVendorStorageName)) {\r
     return EFI_NOT_FOUND;\r
   }\r
 \r
@@ -1881,7 +1956,7 @@ IScsiFormExtractConfig (
     // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
     // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
     //\r
-    ConfigRequestHdr = HiiConstructConfigHdr (&mVendorGuid, mVendorStorageName, Private->DriverHandle);\r
+    ConfigRequestHdr = HiiConstructConfigHdr (&gIScsiConfigGuid, mVendorStorageName, Private->DriverHandle);\r
     Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
     ConfigRequest = AllocateZeroPool (Size);\r
     ASSERT (ConfigRequest != NULL);\r
@@ -1977,7 +2052,7 @@ IScsiFormRouteConfig (
   // Check routing data in <ConfigHdr>.\r
   // Note: if only one Storage is used, then this checking could be skipped.\r
   //\r
-  if (!HiiIsConfigHdrMatch (Configuration, &mVendorGuid, mVendorStorageName)) {\r
+  if (!HiiIsConfigHdrMatch (Configuration, &gIScsiConfigGuid, mVendorStorageName)) {\r
     *Progress = Configuration;\r
     return EFI_NOT_FOUND;\r
   }\r
@@ -2045,56 +2120,65 @@ IScsiFormCallback (
     return EFI_SUCCESS;\r
   }\r
 \r
-  if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
-    if (This == NULL || Value == NULL || ActionRequest == NULL) {\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-\r
-    Private = ISCSI_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This);\r
-\r
+  if ((Action != EFI_BROWSER_ACTION_CHANGING) && (Action != EFI_BROWSER_ACTION_CHANGED)) {\r
     //\r
-    // Retrieve uncommitted data from Browser\r
+    // All other type return unsupported.\r
     //\r
+    return EFI_UNSUPPORTED;\r
+  }\r
 \r
-    BufferSize = sizeof (ISCSI_CONFIG_IFR_NVDATA);\r
-    IfrNvData = AllocateZeroPool (BufferSize);\r
-    if (IfrNvData == NULL) {\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-\r
-    IScsiName = (CHAR8 *) AllocateZeroPool (ISCSI_NAME_MAX_SIZE);\r
-    if (IScsiName == NULL) {\r
-      FreePool (IfrNvData);\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-\r
-    Status = EFI_SUCCESS;\r
-\r
-    ZeroMem (&OldIfrNvData, BufferSize);\r
-\r
-    HiiGetBrowserData (NULL, NULL, BufferSize, (UINT8 *) IfrNvData);\r
+  if ((Value == NULL) || (ActionRequest == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
 \r
-    CopyMem (&OldIfrNvData, IfrNvData, BufferSize);\r
+  Private = ISCSI_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This);\r
+  \r
+  //\r
+  // Retrieve uncommitted data from Browser\r
+  //\r
+  \r
+  BufferSize = sizeof (ISCSI_CONFIG_IFR_NVDATA);\r
+  IfrNvData = AllocateZeroPool (BufferSize);\r
+  if (IfrNvData == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  \r
+  IScsiName = (CHAR8 *) AllocateZeroPool (ISCSI_NAME_MAX_SIZE);\r
+  if (IScsiName == NULL) {\r
+    FreePool (IfrNvData);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  \r
+  Status = EFI_SUCCESS;\r
+  \r
+  ZeroMem (&OldIfrNvData, BufferSize);\r
+  \r
+  HiiGetBrowserData (NULL, NULL, BufferSize, (UINT8 *) IfrNvData);\r
+  \r
+  CopyMem (&OldIfrNvData, IfrNvData, BufferSize);\r
 \r
+  if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
     switch (QuestionId) {\r
-    case KEY_INITIATOR_NAME:\r
-      UnicodeStrToAsciiStr (IfrNvData->InitiatorName, IScsiName);\r
-      BufferSize  = AsciiStrSize (IScsiName);\r
-\r
-      Status      = gIScsiInitiatorName.Set (&gIScsiInitiatorName, &BufferSize, IScsiName);\r
+    case KEY_ADD_ATTEMPT:\r
+      //\r
+      // Check whether iSCSI initiator name is configured already.\r
+      //\r
+      mPrivate->InitiatorNameLength = ISCSI_NAME_MAX_SIZE;\r
+      Status = gIScsiInitiatorName.Get (\r
+                                     &gIScsiInitiatorName,\r
+                                     &mPrivate->InitiatorNameLength,\r
+                                     mPrivate->InitiatorName\r
+                                     );\r
       if (EFI_ERROR (Status)) {\r
         CreatePopUp (\r
           EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
           &Key,\r
-          L"Invalid iSCSI Name!",\r
+          L"Error: please configure iSCSI initiator name first!",\r
           NULL\r
-          );      \r
+          );        \r
+        break;\r
       }\r
-\r
-      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
-      break;\r
-\r
-    case KEY_ADD_ATTEMPT:\r
+      \r
       Status = IScsiConfigAddAttempt ();\r
       break;\r
 \r
@@ -2107,28 +2191,6 @@ IScsiFormCallback (
       Status = IScsiConfigDisplayDeleteAttempts (IfrNvData);\r
       break;\r
 \r
-    case KEY_SAVE_DELETE_ATTEMPT:\r
-      //\r
-      // Delete the Attempt Order from NVR\r
-      //\r
-      Status = IScsiConfigDeleteAttempts (IfrNvData);\r
-      if (EFI_ERROR (Status)) {\r
-        break;\r
-      }\r
-\r
-      IScsiConfigUpdateAttempt ();\r
-      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
-      break;\r
-\r
-    case KEY_IGNORE_DELETE_ATTEMPT:\r
-      CopyMem (\r
-        IfrNvData->DeleteAttemptList,\r
-        OldIfrNvData.DeleteAttemptList,\r
-        sizeof (IfrNvData->DeleteAttemptList)\r
-        );\r
-      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
-      break;\r
-\r
     case KEY_ORDER_ATTEMPT_CONFIG:\r
       //\r
       // Order the attempt according to user input.\r
@@ -2140,6 +2202,56 @@ IScsiFormCallback (
         );\r
       IScsiConfigDisplayOrderAttempts ();\r
       break;\r
+    \r
+    default:\r
+      Status = IScsiConfigProcessDefault (QuestionId, IfrNvData);\r
+      break;\r
+    }\r
+  } else if (Action == EFI_BROWSER_ACTION_CHANGED) {  \r
+    switch (QuestionId) {\r
+    case KEY_INITIATOR_NAME:\r
+      UnicodeStrToAsciiStr (IfrNvData->InitiatorName, IScsiName);\r
+      BufferSize  = AsciiStrSize (IScsiName);\r
+\r
+      Status      = gIScsiInitiatorName.Set (&gIScsiInitiatorName, &BufferSize, IScsiName);\r
+      if (EFI_ERROR (Status)) {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &Key,\r
+          L"Invalid iSCSI Name!",\r
+          NULL\r
+          );      \r
+      }\r
+\r
+      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;\r
+      break;\r
+    case KEY_ATTEMPT_NAME:\r
+      if (StrLen (IfrNvData->AttemptName) > ATTEMPT_NAME_SIZE) {\r
+        CopyMem (AttemptName, IfrNvData->AttemptName, ATTEMPT_NAME_SIZE * sizeof (CHAR16));\r
+        CopyMem (&AttemptName[ATTEMPT_NAME_SIZE], L"...", 4 * sizeof (CHAR16));\r
+      } else {\r
+        CopyMem (\r
+          AttemptName,\r
+          IfrNvData->AttemptName,\r
+          (StrLen (IfrNvData->AttemptName) + 1) * sizeof (CHAR16)\r
+          );\r
+      }\r
+\r
+      UnicodeStrToAsciiStr (IfrNvData->AttemptName, Private->Current->AttemptName);\r
+\r
+      IScsiConfigUpdateAttempt ();\r
+\r
+      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;\r
+      break;\r
+      \r
+    case KEY_SAVE_ATTEMPT_CONFIG:\r
+      Status = IScsiConvertIfrNvDataToAttemptConfigData (IfrNvData, Private->Current);\r
+      if (EFI_ERROR (Status)) {\r
+        break;\r
+      }\r
+\r
+      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;\r
+      break;\r
 \r
     case KEY_SAVE_ORDER_CHANGES:\r
       //\r
@@ -2151,7 +2263,7 @@ IScsiFormCallback (
       }\r
 \r
       IScsiConfigUpdateAttempt ();\r
-      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
+      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
       break;\r
 \r
     case KEY_IGNORE_ORDER_CHANGES:\r
@@ -2160,26 +2272,29 @@ IScsiFormCallback (
         OldIfrNvData.DynamicOrderedList,\r
         sizeof (IfrNvData->DynamicOrderedList)\r
         );\r
-      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
+      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
       break;\r
 \r
-    case KEY_ATTEMPT_NAME:\r
-      if (StrLen (IfrNvData->AttemptName) > ATTEMPT_NAME_SIZE) {\r
-        CopyMem (AttemptName, IfrNvData->AttemptName, ATTEMPT_NAME_SIZE * sizeof (CHAR16));\r
-        CopyMem (&AttemptName[ATTEMPT_NAME_SIZE], L"...", 4 * sizeof (CHAR16));\r
-      } else {\r
-        CopyMem (\r
-          AttemptName,\r
-          IfrNvData->AttemptName,\r
-          (StrLen (IfrNvData->AttemptName) + 1) * sizeof (CHAR16)\r
-          );\r
+    case KEY_SAVE_DELETE_ATTEMPT:\r
+      //\r
+      // Delete the Attempt Order from NVR\r
+      //\r
+      Status = IScsiConfigDeleteAttempts (IfrNvData);\r
+      if (EFI_ERROR (Status)) {\r
+        break;\r
       }\r
 \r
-      UnicodeStrToAsciiStr (IfrNvData->AttemptName, Private->Current->AttemptName);\r
-\r
       IScsiConfigUpdateAttempt ();\r
+      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
+      break;\r
 \r
-      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
+    case KEY_IGNORE_DELETE_ATTEMPT:\r
+      CopyMem (\r
+        IfrNvData->DeleteAttemptList,\r
+        OldIfrNvData.DeleteAttemptList,\r
+        sizeof (IfrNvData->DeleteAttemptList)\r
+        );\r
+      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
       break;\r
 \r
     case KEY_IP_MODE:\r
@@ -2276,9 +2391,9 @@ IScsiFormCallback (
           &Key,\r
           L"Invalid iSCSI Name!",\r
           NULL\r
-          );       \r
+          );\r
       } else {\r
-        AsciiStrCpy (Private->Current->SessionConfigData.TargetName, IScsiName);\r
+        AsciiStrCpyS (Private->Current->SessionConfigData.TargetName, ISCSI_NAME_MAX_SIZE, IScsiName);\r
       }\r
 \r
       break;\r
@@ -2351,38 +2466,23 @@ IScsiFormCallback (
 \r
       break;\r
 \r
-    case KEY_SAVE_ATTEMPT_CONFIG:\r
-      Status = IScsiConvertIfrNvDataToAttemptConfigData (IfrNvData, Private->Current);\r
-      if (EFI_ERROR (Status)) {\r
-        break;\r
-      }\r
-\r
-      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
-      break;\r
-\r
     default:\r
-      Status = IScsiConfigProcessDefault (QuestionId, IfrNvData);\r
       break;\r
     }\r
+  }\r
 \r
-    if (!EFI_ERROR (Status)) {\r
-      //\r
-      // Pass changed uncommitted data back to Form Browser.\r
-      //\r
-      BufferSize = sizeof (ISCSI_CONFIG_IFR_NVDATA);\r
-      HiiSetBrowserData (NULL, NULL, BufferSize, (UINT8 *) IfrNvData, NULL);\r
-    }\r
-\r
-    FreePool (IfrNvData);\r
-    FreePool (IScsiName);\r
-\r
-    return Status;\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Pass changed uncommitted data back to Form Browser.\r
+    //\r
+    BufferSize = sizeof (ISCSI_CONFIG_IFR_NVDATA);\r
+    HiiSetBrowserData (NULL, NULL, BufferSize, (UINT8 *) IfrNvData, NULL);\r
   }\r
 \r
-  //\r
-  // All other action return unsupported.\r
-  //\r
-  return EFI_UNSUPPORTED;\r
+  FreePool (IfrNvData);\r
+  FreePool (IScsiName);\r
+\r
+  return Status;\r
 }\r
 \r
 \r
@@ -2432,7 +2532,7 @@ IScsiConfigFormInit (
   // Publish our HII data.\r
   //\r
   CallbackInfo->RegisteredHandle = HiiAddPackages (\r
-                                     &mVendorGuid,\r
+                                     &gIScsiConfigGuid,\r
                                      CallbackInfo->DriverHandle,\r
                                      IScsiDxeStrings,\r
                                      IScsiConfigVfrBin,\r
@@ -2496,6 +2596,13 @@ IScsiConfigFormUnload (
 \r
   ASSERT (mPrivate->NicCount == 0);\r
 \r
+  //\r
+  // Free attempt is created but not saved to system.\r
+  //\r
+  if (mPrivate->NewAttempt != NULL) {\r
+    FreePool (mPrivate->NewAttempt);\r
+  }\r
+\r
   FreePool (mPrivate);\r
   mPrivate = NULL;\r
 \r