]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/IScsiDxe/IScsiConfig.c
OvmfPkg: raise DXEFV size to 13 MB in the traditional platform FDFs
[mirror_edk2.git] / NetworkPkg / IScsiDxe / IScsiConfig.c
index 3c299be94928354ce8c58ce3b3759f3d9b59bcb2..37f6255af0e9f74e4a12e35a73b4d6fd793c9d30 100644 (file)
@@ -1,24 +1,15 @@
 /** @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
-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
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \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
-ISCSI_FORM_CALLBACK_INFO  *mCallbackInfo = NULL;\r
+CHAR16                    mVendorStorageName[] = L"ISCSI_CONFIG_IFR_NVDATA";\r
+ISCSI_FORM_CALLBACK_INFO  *mCallbackInfo       = NULL;\r
 \r
 HII_VENDOR_DEVICE_PATH  mIScsiHiiVendorDevicePath = {\r
   {\r
@@ -26,26 +17,22 @@ HII_VENDOR_DEVICE_PATH  mIScsiHiiVendorDevicePath = {
       HARDWARE_DEVICE_PATH,\r
       HW_VENDOR_DP,\r
       {\r
-        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
-        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
+        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),\r
+        (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
     END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
-    { \r
-      (UINT8) (END_DEVICE_PATH_LENGTH),\r
-      (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
+    {\r
+      (UINT8)(END_DEVICE_PATH_LENGTH),\r
+      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)\r
     }\r
   }\r
 };\r
 \r
-\r
 /**\r
   Convert the IP address into a dotted string.\r
 \r
@@ -56,32 +43,32 @@ HII_VENDOR_DEVICE_PATH  mIScsiHiiVendorDevicePath = {
 **/\r
 VOID\r
 IScsiIpToStr (\r
-  IN  EFI_IP_ADDRESS    *Ip,\r
-  IN  BOOLEAN           Ipv6Flag,\r
-  OUT CHAR16            *Str\r
+  IN  EFI_IP_ADDRESS  *Ip,\r
+  IN  BOOLEAN         Ipv6Flag,\r
+  OUT CHAR16          *Str\r
   )\r
 {\r
-  EFI_IPv4_ADDRESS      *Ip4;\r
-  EFI_IPv6_ADDRESS      *Ip6;\r
-  UINTN                 Index;\r
-  BOOLEAN               Short;\r
-  UINTN                 Number;\r
-  CHAR16                FormatString[8];\r
+  EFI_IPv4_ADDRESS  *Ip4;\r
+  EFI_IPv6_ADDRESS  *Ip6;\r
+  UINTN             Index;\r
+  BOOLEAN           Short;\r
+  UINTN             Number;\r
+  CHAR16            FormatString[8];\r
 \r
   if (!Ipv6Flag) {\r
     Ip4 = &Ip->v4;\r
 \r
     UnicodeSPrint (\r
       Str,\r
-      (UINTN) 2 * IP4_STR_MAX_SIZE,\r
+      (UINTN)2 * IP4_STR_MAX_SIZE,\r
       L"%d.%d.%d.%d",\r
-      (UINTN) Ip4->Addr[0],\r
-      (UINTN) Ip4->Addr[1],\r
-      (UINTN) Ip4->Addr[2],\r
-      (UINTN) Ip4->Addr[3]\r
+      (UINTN)Ip4->Addr[0],\r
+      (UINTN)Ip4->Addr[1],\r
+      (UINTN)Ip4->Addr[2],\r
+      (UINTN)Ip4->Addr[3]\r
       );\r
 \r
-    return ;\r
+    return;\r
   }\r
 \r
   Ip6   = &Ip->v6;\r
@@ -89,10 +76,11 @@ IScsiIpToStr (
 \r
   for (Index = 0; Index < 15; Index = Index + 2) {\r
     if (!Short &&\r
-        Index % 2 == 0 &&\r
-        Ip6->Addr[Index] == 0 &&\r
-        Ip6->Addr[Index + 1] == 0\r
-        ) {\r
+        (Index % 2 == 0) &&\r
+        (Ip6->Addr[Index] == 0) &&\r
+        (Ip6->Addr[Index + 1] == 0)\r
+        )\r
+    {\r
       //\r
       // Deal with the case of ::.\r
       //\r
@@ -101,8 +89,8 @@ IScsiIpToStr (
         *(Str + 1) = L':';\r
         Str        = Str + 2;\r
       } else {\r
-        *Str       = L':';\r
-        Str        = Str + 1;\r
+        *Str = L':';\r
+        Str  = Str + 1;\r
       }\r
 \r
       while ((Index < 15) && (Ip6->Addr[Index] == 0) && (Ip6->Addr[Index + 1] == 0)) {\r
@@ -123,7 +111,7 @@ IScsiIpToStr (
     ASSERT (Index < 15);\r
 \r
     if (Ip6->Addr[Index] == 0) {\r
-      Number = UnicodeSPrint (Str, 2 * IP_STR_MAX_SIZE, L"%x:", (UINTN) Ip6->Addr[Index + 1]);\r
+      Number = UnicodeSPrint (Str, 2 * IP_STR_MAX_SIZE, L"%x:", (UINTN)Ip6->Addr[Index + 1]);\r
     } else {\r
       if (Ip6->Addr[Index + 1] < 0x10) {\r
         CopyMem (FormatString, L"%x0%x:", StrSize (L"%x0%x:"));\r
@@ -134,9 +122,9 @@ IScsiIpToStr (
       Number = UnicodeSPrint (\r
                  Str,\r
                  2 * IP_STR_MAX_SIZE,\r
-                 (CONST CHAR16 *) FormatString,\r
-                 (UINTN) Ip6->Addr[Index],\r
-                 (UINTN) Ip6->Addr[Index + 1]\r
+                 (CONST CHAR16 *)FormatString,\r
+                 (UINTN)Ip6->Addr[Index],\r
+                 (UINTN)Ip6->Addr[Index + 1]\r
                  );\r
     }\r
 \r
@@ -163,12 +151,16 @@ IScsiIpToStr (
 **/\r
 BOOLEAN\r
 IpIsUnicast (\r
-  IN EFI_IP_ADDRESS *Ip,\r
+  IN EFI_IP_ADDRESS  *Ip,\r
   IN  UINT8          IpMode\r
   )\r
 {\r
   if (IpMode == IP_MODE_IP4) {\r
-    return NetIp4IsUnicast (NTOHL (Ip->Addr[0]), 0);\r
+    if (IP4_IS_UNSPECIFIED (NTOHL (Ip->Addr[0])) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip->Addr[0]))) {\r
+      return FALSE;\r
+    }\r
+\r
+    return TRUE;\r
   } else if (IpMode == IP_MODE_IP6) {\r
     return NetIp6IsValidUnicast (&Ip->v6);\r
   } else {\r
@@ -189,28 +181,28 @@ IpIsUnicast (
 **/\r
 EFI_STATUS\r
 IScsiParseIsIdFromString (\r
-  IN CONST CHAR16                    *String,\r
-  IN OUT   UINT8                     *IsId\r
+  IN CONST CHAR16  *String,\r
+  IN OUT   UINT8   *IsId\r
   )\r
 {\r
-  UINT8                          Index;\r
-  CHAR16                         *IsIdStr;\r
-  CHAR16                         TempStr[3];\r
-  UINTN                          NodeVal;\r
-  CHAR16                         PortString[ISCSI_NAME_IFR_MAX_SIZE];\r
-  EFI_INPUT_KEY                  Key;\r
+  UINT8          Index;\r
+  CHAR16         *IsIdStr;\r
+  CHAR16         TempStr[3];\r
+  UINTN          NodeVal;\r
+  CHAR16         PortString[ISCSI_NAME_IFR_MAX_SIZE];\r
+  EFI_INPUT_KEY  Key;\r
 \r
   if ((String == NULL) || (IsId == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  IsIdStr = (CHAR16 *) String;\r
+  IsIdStr = (CHAR16 *)String;\r
 \r
-  if (StrLen (IsIdStr) != 6) {\r
+  if ((StrLen (IsIdStr) != 6) && (StrLen (IsIdStr) != 12)) {\r
     UnicodeSPrint (\r
       PortString,\r
-      (UINTN) ISCSI_NAME_IFR_MAX_SIZE,\r
-      L"Error! Input is incorrect, please input 6 hex numbers!\n"\r
+      (UINTN)ISCSI_NAME_IFR_MAX_SIZE,\r
+      L"Error! Only last 3 bytes are configurable, please input 6 hex numbers for last 3 bytes only or 12 hex numbers for full SSID!\n"\r
       );\r
 \r
     CreatePopUp (\r
@@ -223,6 +215,10 @@ IScsiParseIsIdFromString (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  if (StrLen (IsIdStr) == 12) {\r
+    IsIdStr += 6;\r
+  }\r
+\r
   for (Index = 3; Index < 6; Index++) {\r
     CopyMem (TempStr, IsIdStr, sizeof (TempStr));\r
     TempStr[2] = L'\0';\r
@@ -233,7 +229,7 @@ IScsiParseIsIdFromString (
     //\r
     NodeVal = StrHexToUintn (TempStr);\r
 \r
-    IsId[Index] = (UINT8) NodeVal;\r
+    IsId[Index] = (UINT8)NodeVal;\r
 \r
     IsIdStr = IsIdStr + 2;\r
   }\r
@@ -253,12 +249,12 @@ IScsiParseIsIdFromString (
 **/\r
 EFI_STATUS\r
 IScsiConvertIsIdToString (\r
-  OUT CHAR16                         *String,\r
-  IN  UINT8                          *IsId\r
+  OUT CHAR16  *String,\r
+  IN  UINT8   *IsId\r
   )\r
 {\r
-  UINT8                          Index;\r
-  UINTN                          Number;\r
+  UINT8  Index;\r
+  UINTN  Number;\r
 \r
   if ((String == NULL) || (IsId == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -270,16 +266,15 @@ IScsiConvertIsIdToString (
                  String,\r
                  2 * ISID_CONFIGURABLE_STORAGE,\r
                  L"0%X",\r
-                 (UINTN) IsId[Index]\r
+                 (UINTN)IsId[Index]\r
                  );\r
     } else {\r
       Number = UnicodeSPrint (\r
                  String,\r
                  2 * ISID_CONFIGURABLE_STORAGE,\r
                  L"%X",\r
-                 (UINTN) IsId[Index]\r
+                 (UINTN)IsId[Index]\r
                  );\r
-\r
     }\r
 \r
     String = String + Number;\r
@@ -290,6 +285,99 @@ IScsiConvertIsIdToString (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Get the Offset value specified by the input String.\r
+\r
+  @param[in]  Configuration      A null-terminated Unicode string in\r
+                                 <ConfigString> format.\r
+  @param[in]  String             The string is "&OFFSET=".\r
+  @param[out] Value              The Offset value.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to store necessary\r
+                                 structures.\r
+  @retval EFI_SUCCESS            Value of <Number> is outputted in Number\r
+                                 successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+IScsiGetValue (\r
+  IN  CONST EFI_STRING  Configuration,\r
+  IN  CHAR16            *String,\r
+  OUT UINTN             *Value\r
+  )\r
+{\r
+  CHAR16      *StringPtr;\r
+  CHAR16      *TmpPtr;\r
+  CHAR16      *Str;\r
+  CHAR16      TmpStr[2];\r
+  UINTN       Length;\r
+  UINTN       Len;\r
+  UINTN       Index;\r
+  UINT8       *Buf;\r
+  UINT8       DigitUint8;\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // Get Value.\r
+  //\r
+  Buf       = NULL;\r
+  StringPtr = StrStr (Configuration, String);\r
+  ASSERT (StringPtr != NULL);\r
+  StringPtr += StrLen (String);\r
+  TmpPtr     = StringPtr;\r
+\r
+  while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
+    StringPtr++;\r
+  }\r
+\r
+  Length = StringPtr - TmpPtr;\r
+  Len    = Length + 1;\r
+\r
+  Str = AllocateZeroPool (Len * sizeof (CHAR16));\r
+  if (Str == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Exit;\r
+  }\r
+\r
+  CopyMem (Str, TmpPtr, Len * sizeof (CHAR16));\r
+  *(Str + Length) = L'\0';\r
+\r
+  Len = (Len + 1) / 2;\r
+  Buf = (UINT8 *)AllocateZeroPool (Len);\r
+  if (Buf == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Exit;\r
+  }\r
+\r
+  ZeroMem (TmpStr, sizeof (TmpStr));\r
+  for (Index = 0; Index < Length; Index++) {\r
+    TmpStr[0]  = Str[Length - Index - 1];\r
+    DigitUint8 = (UINT8)StrHexToUint64 (TmpStr);\r
+    if ((Index & 1) == 0) {\r
+      Buf[Index/2] = DigitUint8;\r
+    } else {\r
+      Buf[Index/2] = (UINT8)((DigitUint8 << 4) + Buf[Index/2]);\r
+    }\r
+  }\r
+\r
+  *Value = 0;\r
+  CopyMem (\r
+    Value,\r
+    Buf,\r
+    (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)\r
+    );\r
+\r
+  FreePool (Buf);\r
+  Status = EFI_SUCCESS;\r
+\r
+Exit:\r
+  if (Str != NULL) {\r
+    FreePool (Str);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
 /**\r
   Get the attempt config data from global structure by the ConfigIndex.\r
 \r
@@ -301,7 +389,7 @@ IScsiConvertIsIdToString (
 **/\r
 ISCSI_ATTEMPT_CONFIG_NVDATA *\r
 IScsiConfigGetAttemptByConfigIndex (\r
-  IN UINT8                     AttemptConfigIndex\r
+  IN UINT8  AttemptConfigIndex\r
   )\r
 {\r
   LIST_ENTRY                   *Entry;\r
@@ -317,7 +405,6 @@ IScsiConfigGetAttemptByConfigIndex (
   return NULL;\r
 }\r
 \r
-\r
 /**\r
   Get the existing attempt config data from global structure by the NicIndex.\r
 \r
@@ -332,8 +419,8 @@ IScsiConfigGetAttemptByConfigIndex (
 **/\r
 ISCSI_ATTEMPT_CONFIG_NVDATA *\r
 IScsiConfigGetAttemptByNic (\r
-  IN ISCSI_ATTEMPT_CONFIG_NVDATA *NewAttempt,\r
-  IN UINT8                       IScsiMode\r
+  IN ISCSI_ATTEMPT_CONFIG_NVDATA  *NewAttempt,\r
+  IN UINT8                        IScsiMode\r
   )\r
 {\r
   LIST_ENTRY                   *Entry;\r
@@ -341,8 +428,9 @@ IScsiConfigGetAttemptByNic (
 \r
   NET_LIST_FOR_EACH (Entry, &mPrivate->AttemptConfigs) {\r
     Attempt = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);\r
-    if (Attempt != NewAttempt && Attempt->NicIndex == NewAttempt->NicIndex &&\r
-        Attempt->SessionConfigData.Enabled == IScsiMode) {\r
+    if ((Attempt != NewAttempt) && (Attempt->NicIndex == NewAttempt->NicIndex) &&\r
+        (Attempt->SessionConfigData.Enabled == IScsiMode))\r
+    {\r
       return Attempt;\r
     }\r
   }\r
@@ -350,6 +438,66 @@ IScsiConfigGetAttemptByNic (
   return NULL;\r
 }\r
 \r
+/**\r
+  Extract the Index of the attempt list.\r
+\r
+  @param[in]   AttemptNameList     The Name list of the Attempts.\r
+  @param[out]  AttemptIndexList    The Index list of the Attempts.\r
+  @param[in]   IsAddAttempts       If TRUE, Indicates add one or more attempts.\r
+                                   If FALSE, Indicates delete attempts or change attempt order.\r
+\r
+  @retval EFI_SUCCESS              The Attempt list is valid.\r
+  @retval EFI_INVALID_PARAMETERS   The Attempt List is invalid.\r
+\r
+**/\r
+EFI_STATUS\r
+IScsiGetAttemptIndexList (\r
+  IN      CHAR16   *AttemptNameList,\r
+  OUT  UINT8       *AttemptIndexList,\r
+  IN      BOOLEAN  IsAddAttempts\r
+  )\r
+{\r
+  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptConfigData;\r
+  CHAR16                       *AttemptStr;\r
+  UINT8                        AttemptIndex;\r
+  UINTN                        Len;\r
+  UINTN                        Index;\r
+\r
+  Index = 0;\r
+\r
+  if ((AttemptNameList == NULL) || (*AttemptNameList == L'\0')) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  AttemptStr = AttemptNameList;\r
+  Len        = StrLen (L"attempt:");\r
+\r
+  while (*AttemptStr != L'\0') {\r
+    AttemptStr = StrStr (AttemptStr, L"attempt:");\r
+    if (AttemptStr == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    AttemptStr       += Len;\r
+    AttemptIndex      = (UINT8)(*AttemptStr - L'0');\r
+    AttemptConfigData = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);\r
+    if (IsAddAttempts) {\r
+      if ((AttemptConfigData != NULL) || ((AttemptIndex) > PcdGet8 (PcdMaxIScsiAttemptNumber))) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+    } else {\r
+      if (AttemptConfigData == NULL) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+    }\r
+\r
+    AttemptIndexList[Index] = AttemptIndex;\r
+    Index++;\r
+    AttemptStr += 2;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
 \r
 /**\r
   Convert the iSCSI configuration data into the IFR data.\r
@@ -364,20 +512,22 @@ IScsiConvertAttemptConfigDataToIfrNvData (
   IN OUT ISCSI_CONFIG_IFR_NVDATA  *IfrNvData\r
   )\r
 {\r
-  ISCSI_SESSION_CONFIG_NVDATA   *SessionConfigData;\r
-  ISCSI_CHAP_AUTH_CONFIG_NVDATA *AuthConfigData;\r
-  EFI_IP_ADDRESS                Ip;\r
+  ISCSI_SESSION_CONFIG_NVDATA    *SessionConfigData;\r
+  ISCSI_CHAP_AUTH_CONFIG_NVDATA  *AuthConfigData;\r
+  EFI_IP_ADDRESS                 Ip;\r
+  BOOLEAN                        DnsMode;\r
 \r
   //\r
   // Normal session configuration parameters.\r
   //\r
-  SessionConfigData                 = &Attempt->SessionConfigData;\r
-  IfrNvData->Enabled                = SessionConfigData->Enabled;\r
-  IfrNvData->IpMode                 = SessionConfigData->IpMode;\r
+  SessionConfigData  = &Attempt->SessionConfigData;\r
+  IfrNvData->Enabled = SessionConfigData->Enabled;\r
+  IfrNvData->IpMode  = SessionConfigData->IpMode;\r
+  DnsMode            = SessionConfigData->DnsMode;\r
 \r
-  IfrNvData->InitiatorInfoFromDhcp  = SessionConfigData->InitiatorInfoFromDhcp;\r
-  IfrNvData->TargetInfoFromDhcp     = SessionConfigData->TargetInfoFromDhcp;\r
-  IfrNvData->TargetPort             = SessionConfigData->TargetPort;\r
+  IfrNvData->InitiatorInfoFromDhcp = SessionConfigData->InitiatorInfoFromDhcp;\r
+  IfrNvData->TargetInfoFromDhcp    = SessionConfigData->TargetInfoFromDhcp;\r
+  IfrNvData->TargetPort            = SessionConfigData->TargetPort;\r
 \r
   if (IfrNvData->IpMode == IP_MODE_IP4) {\r
     CopyMem (&Ip.v4, &SessionConfigData->LocalIp, sizeof (EFI_IPv4_ADDRESS));\r
@@ -386,15 +536,33 @@ IScsiConvertAttemptConfigDataToIfrNvData (
     IScsiIpToStr (&Ip, FALSE, IfrNvData->SubnetMask);\r
     CopyMem (&Ip.v4, &SessionConfigData->Gateway, sizeof (EFI_IPv4_ADDRESS));\r
     IScsiIpToStr (&Ip, FALSE, IfrNvData->Gateway);\r
-    CopyMem (&Ip.v4, &SessionConfigData->TargetIp, sizeof (EFI_IPv4_ADDRESS));\r
-    IScsiIpToStr (&Ip, FALSE, IfrNvData->TargetIp);\r
+    ZeroMem (IfrNvData->TargetIp, sizeof (IfrNvData->TargetIp));\r
+    if (SessionConfigData->TargetIp.v4.Addr[0] != '\0') {\r
+      CopyMem (&Ip.v4, &SessionConfigData->TargetIp, sizeof (EFI_IPv4_ADDRESS));\r
+      IScsiIpToStr (&Ip, FALSE, IfrNvData->TargetIp);\r
+    }\r
   } else if (IfrNvData->IpMode == IP_MODE_IP6) {\r
     ZeroMem (IfrNvData->TargetIp, sizeof (IfrNvData->TargetIp));\r
-    IP6_COPY_ADDRESS (&Ip.v6, &SessionConfigData->TargetIp);\r
-    IScsiIpToStr (&Ip, TRUE, IfrNvData->TargetIp);\r
+    if (SessionConfigData->TargetIp.v6.Addr[0] != '\0') {\r
+      IP6_COPY_ADDRESS (&Ip.v6, &SessionConfigData->TargetIp);\r
+      IScsiIpToStr (&Ip, TRUE, IfrNvData->TargetIp);\r
+    }\r
+  }\r
+\r
+  AsciiStrToUnicodeStrS (\r
+    SessionConfigData->TargetName,\r
+    IfrNvData->TargetName,\r
+    sizeof (IfrNvData->TargetName) / sizeof (IfrNvData->TargetName[0])\r
+    );\r
+\r
+  if (DnsMode) {\r
+    AsciiStrToUnicodeStrS (\r
+      SessionConfigData->TargetUrl,\r
+      IfrNvData->TargetIp,\r
+      sizeof (IfrNvData->TargetIp) / sizeof (IfrNvData->TargetIp[0])\r
+      );\r
   }\r
 \r
-  AsciiStrToUnicodeStr (SessionConfigData->TargetName, IfrNvData->TargetName);\r
   IScsiLunToUnicodeStr (SessionConfigData->BootLun, IfrNvData->BootLun);\r
   IScsiConvertIsIdToString (IfrNvData->IsId, SessionConfigData->IsId);\r
 \r
@@ -409,27 +577,208 @@ IScsiConvertAttemptConfigDataToIfrNvData (
   if (IfrNvData->AuthenticationType == ISCSI_AUTH_TYPE_CHAP) {\r
     AuthConfigData      = &Attempt->AuthConfigData.CHAP;\r
     IfrNvData->CHAPType = AuthConfigData->CHAPType;\r
-    AsciiStrToUnicodeStr (AuthConfigData->CHAPName, IfrNvData->CHAPName);\r
-    AsciiStrToUnicodeStr (AuthConfigData->CHAPSecret, IfrNvData->CHAPSecret);\r
-    AsciiStrToUnicodeStr (AuthConfigData->ReverseCHAPName, IfrNvData->ReverseCHAPName);\r
-    AsciiStrToUnicodeStr (AuthConfigData->ReverseCHAPSecret, IfrNvData->ReverseCHAPSecret);\r
+    AsciiStrToUnicodeStrS (\r
+      AuthConfigData->CHAPName,\r
+      IfrNvData->CHAPName,\r
+      sizeof (IfrNvData->CHAPName) / sizeof (IfrNvData->CHAPName[0])\r
+      );\r
+    AsciiStrToUnicodeStrS (\r
+      AuthConfigData->CHAPSecret,\r
+      IfrNvData->CHAPSecret,\r
+      sizeof (IfrNvData->CHAPSecret) / sizeof (IfrNvData->CHAPSecret[0])\r
+      );\r
+    AsciiStrToUnicodeStrS (\r
+      AuthConfigData->ReverseCHAPName,\r
+      IfrNvData->ReverseCHAPName,\r
+      sizeof (IfrNvData->ReverseCHAPName) / sizeof (IfrNvData->ReverseCHAPName[0])\r
+      );\r
+    AsciiStrToUnicodeStrS (\r
+      AuthConfigData->ReverseCHAPSecret,\r
+      IfrNvData->ReverseCHAPSecret,\r
+      sizeof (IfrNvData->ReverseCHAPSecret) / sizeof (IfrNvData->ReverseCHAPSecret[0])\r
+      );\r
   }\r
 \r
   //\r
   // Other parameters.\r
   //\r
-  AsciiStrToUnicodeStr (Attempt->AttemptName, IfrNvData->AttemptName);\r
+  AsciiStrToUnicodeStrS (\r
+    Attempt->AttemptName,\r
+    IfrNvData->AttemptName,\r
+    sizeof (IfrNvData->AttemptName) / sizeof (IfrNvData->AttemptName[0])\r
+    );\r
 }\r
 \r
+/**\r
+  Convert the iSCSI configuration data into the IFR data Which will be used\r
+  to extract the iSCSI Keyword configuration in <ConfigAltResp> format.\r
+\r
+  @param[in, out]  IfrNvData              The IFR nv data.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+IScsiConvertAttemptConfigDataToIfrNvDataByKeyword (\r
+  IN OUT ISCSI_CONFIG_IFR_NVDATA  *IfrNvData\r
+  )\r
+{\r
+  LIST_ENTRY                     *Entry;\r
+  ISCSI_ATTEMPT_CONFIG_NVDATA    *Attempt;\r
+  ISCSI_SESSION_CONFIG_NVDATA    *SessionConfigData;\r
+  ISCSI_CHAP_AUTH_CONFIG_NVDATA  *AuthConfigData;\r
+  CHAR16                         AttemptNameList[ATTEMPT_NAME_LIST_SIZE];\r
+  ISCSI_NIC_INFO                 *NicInfo;\r
+  CHAR16                         MacString[ISCSI_MAX_MAC_STRING_LEN];\r
+  EFI_IP_ADDRESS                 Ip;\r
+  UINTN                          Index;\r
+  UINTN                          StringLen;\r
+\r
+  NicInfo = NULL;\r
+  ZeroMem (AttemptNameList, sizeof (AttemptNameList));\r
+\r
+  if ((mPrivate != NULL) && (mPrivate->AttemptCount != 0)) {\r
+    NET_LIST_FOR_EACH (Entry, &mPrivate->AttemptConfigs) {\r
+      Attempt = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);\r
+      //\r
+      // Normal session configuration parameters.\r
+      //\r
+      SessionConfigData = &Attempt->SessionConfigData;\r
+\r
+      ASSERT ((Attempt->AttemptConfigIndex > 0) && (Attempt->AttemptConfigIndex <= FixedPcdGet8 (PcdMaxIScsiAttemptNumber)));\r
+      Index = Attempt->AttemptConfigIndex - 1;\r
+\r
+      //\r
+      // Save the attempt to AttemptNameList as Attempt:1 Attempt:2\r
+      //\r
+      AsciiStrToUnicodeStrS (\r
+        Attempt->AttemptName,\r
+        AttemptNameList + StrLen (AttemptNameList),\r
+        ATTEMPT_NAME_LIST_SIZE - StrLen (AttemptNameList)\r
+        );\r
+\r
+      StringLen = StrLen (AttemptNameList);\r
+      ASSERT (StringLen > 2);\r
+      *(AttemptNameList + StringLen - 2) = L':';\r
+      *(AttemptNameList + StringLen)     = L' ';\r
+\r
+      AsciiStrToUnicodeStrS (\r
+        Attempt->AttemptName,\r
+        IfrNvData->ISCSIAttemptName  + ATTEMPT_NAME_SIZE * Index,\r
+        ATTEMPT_NAME_LIST_SIZE - ATTEMPT_NAME_SIZE * Index\r
+        );\r
+\r
+      IfrNvData->ISCSIBootEnableList[Index]    = SessionConfigData->Enabled;\r
+      IfrNvData->ISCSIIpAddressTypeList[Index] = SessionConfigData->IpMode;\r
+\r
+      IfrNvData->ISCSIInitiatorInfoViaDHCP[Index] = SessionConfigData->InitiatorInfoFromDhcp;\r
+      IfrNvData->ISCSITargetInfoViaDHCP[Index]    = SessionConfigData->TargetInfoFromDhcp;\r
+      IfrNvData->ISCSIConnectRetry[Index]         = SessionConfigData->ConnectRetryCount;\r
+      IfrNvData->ISCSIConnectTimeout[Index]       = SessionConfigData->ConnectTimeout;\r
+      IfrNvData->ISCSITargetTcpPort[Index]        = SessionConfigData->TargetPort;\r
+\r
+      if (SessionConfigData->IpMode == IP_MODE_IP4) {\r
+        CopyMem (&Ip.v4, &SessionConfigData->LocalIp, sizeof (EFI_IPv4_ADDRESS));\r
+        IScsiIpToStr (&Ip, FALSE, IfrNvData->Keyword[Index].ISCSIInitiatorIpAddress);\r
+        CopyMem (&Ip.v4, &SessionConfigData->SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
+        IScsiIpToStr (&Ip, FALSE, IfrNvData->Keyword[Index].ISCSIInitiatorNetmask);\r
+        CopyMem (&Ip.v4, &SessionConfigData->Gateway, sizeof (EFI_IPv4_ADDRESS));\r
+        IScsiIpToStr (&Ip, FALSE, IfrNvData->Keyword[Index].ISCSIInitiatorGateway);\r
+        if (SessionConfigData->TargetIp.v4.Addr[0] != '\0') {\r
+          CopyMem (&Ip.v4, &SessionConfigData->TargetIp, sizeof (EFI_IPv4_ADDRESS));\r
+          IScsiIpToStr (&Ip, FALSE, IfrNvData->Keyword[Index].ISCSITargetIpAddress);\r
+        }\r
+      } else if (SessionConfigData->IpMode == IP_MODE_IP6) {\r
+        ZeroMem (IfrNvData->Keyword[Index].ISCSITargetIpAddress, sizeof (IfrNvData->TargetIp));\r
+        if (SessionConfigData->TargetIp.v6.Addr[0] != '\0') {\r
+          IP6_COPY_ADDRESS (&Ip.v6, &SessionConfigData->TargetIp);\r
+          IScsiIpToStr (&Ip, TRUE, IfrNvData->Keyword[Index].ISCSITargetIpAddress);\r
+        }\r
+      }\r
+\r
+      AsciiStrToUnicodeStrS (\r
+        SessionConfigData->TargetName,\r
+        IfrNvData->Keyword[Index].ISCSITargetName,\r
+        ISCSI_NAME_MAX_SIZE\r
+        );\r
+\r
+      if (SessionConfigData->DnsMode) {\r
+        AsciiStrToUnicodeStrS (\r
+          SessionConfigData->TargetUrl,\r
+          IfrNvData->Keyword[Index].ISCSITargetIpAddress,\r
+          sizeof (IfrNvData->Keyword[Index].ISCSITargetIpAddress) / sizeof (IfrNvData->Keyword[Index].ISCSITargetIpAddress[0])\r
+          );\r
+      }\r
+\r
+      IScsiLunToUnicodeStr (SessionConfigData->BootLun, IfrNvData->Keyword[Index].ISCSILun);\r
+      IScsiConvertIsIdToString (IfrNvData->Keyword[Index].ISCSIIsId, SessionConfigData->IsId);\r
+\r
+      IfrNvData->ISCSIAuthenticationMethod[Index] = Attempt->AuthenticationType;\r
+\r
+      if (Attempt->AuthenticationType == ISCSI_AUTH_TYPE_CHAP) {\r
+        AuthConfigData                  = &Attempt->AuthConfigData.CHAP;\r
+        IfrNvData->ISCSIChapType[Index] = AuthConfigData->CHAPType;\r
+        AsciiStrToUnicodeStrS (\r
+          AuthConfigData->CHAPName,\r
+          IfrNvData->Keyword[Index].ISCSIChapUsername,\r
+          ISCSI_CHAP_NAME_STORAGE\r
+          );\r
+\r
+        AsciiStrToUnicodeStrS (\r
+          AuthConfigData->CHAPSecret,\r
+          IfrNvData->Keyword[Index].ISCSIChapSecret,\r
+          ISCSI_CHAP_SECRET_STORAGE\r
+          );\r
+\r
+        AsciiStrToUnicodeStrS (\r
+          AuthConfigData->ReverseCHAPName,\r
+          IfrNvData->Keyword[Index].ISCSIReverseChapUsername,\r
+          ISCSI_CHAP_NAME_STORAGE\r
+          );\r
+\r
+        AsciiStrToUnicodeStrS (\r
+          AuthConfigData->ReverseCHAPSecret,\r
+          IfrNvData->Keyword[Index].ISCSIReverseChapSecret,\r
+          ISCSI_CHAP_SECRET_STORAGE\r
+          );\r
+      }\r
+    }\r
+    CopyMem (IfrNvData->ISCSIDisplayAttemptList, AttemptNameList, ATTEMPT_NAME_LIST_SIZE);\r
+\r
+    ZeroMem (IfrNvData->ISCSIMacAddr, sizeof (IfrNvData->ISCSIMacAddr));\r
+    NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {\r
+      NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);\r
+      IScsiMacAddrToStr (\r
+        &NicInfo->PermanentAddress,\r
+        NicInfo->HwAddressSize,\r
+        NicInfo->VlanId,\r
+        MacString\r
+        );\r
+      CopyMem (\r
+        IfrNvData->ISCSIMacAddr + StrLen (IfrNvData->ISCSIMacAddr),\r
+        MacString,\r
+        StrLen (MacString) * sizeof (CHAR16)\r
+        );\r
+\r
+      *(IfrNvData->ISCSIMacAddr + StrLen (IfrNvData->ISCSIMacAddr)) = L'/';\r
+    }\r
+\r
+    StringLen = StrLen (IfrNvData->ISCSIMacAddr);\r
+    if (StringLen > 0) {\r
+      *(IfrNvData->ISCSIMacAddr + StringLen - 1) = L'\0';\r
+    }\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
@@ -439,29 +788,34 @@ IScsiConvertIfrNvDataToAttemptConfigData (
   IN OUT ISCSI_ATTEMPT_CONFIG_NVDATA  *Attempt\r
   )\r
 {\r
-  EFI_IP_ADDRESS              HostIp;\r
-  EFI_IP_ADDRESS              SubnetMask;\r
-  EFI_IP_ADDRESS              Gateway;\r
-  CHAR16                      *MacString;\r
-  CHAR16                      *AttemptName1;\r
-  CHAR16                      *AttemptName2;\r
-  ISCSI_ATTEMPT_CONFIG_NVDATA *ExistAttempt;\r
-  ISCSI_ATTEMPT_CONFIG_NVDATA *SameNicAttempt;\r
-  CHAR16                      IScsiMode[64];\r
-  CHAR16                      IpMode[64];\r
-  ISCSI_NIC_INFO              *NicInfo;\r
-  EFI_INPUT_KEY               Key;\r
-\r
-  if (IfrNvData == NULL || Attempt == NULL) {\r
+  EFI_IP_ADDRESS               HostIp;\r
+  EFI_IP_ADDRESS               SubnetMask;\r
+  EFI_IP_ADDRESS               Gateway;\r
+  CHAR16                       *MacString;\r
+  CHAR16                       *AttemptName1;\r
+  CHAR16                       *AttemptName2;\r
+  ISCSI_ATTEMPT_CONFIG_NVDATA  *ExistAttempt;\r
+  ISCSI_ATTEMPT_CONFIG_NVDATA  *SameNicAttempt;\r
+  CHAR16                       IScsiMode[64];\r
+  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
   }\r
 \r
   //\r
   // Update those fields which don't have INTERACTIVE attribute.\r
   //\r
-  Attempt->SessionConfigData.ConnectRetryCount     = IfrNvData->ConnectRetryCount;\r
-  Attempt->SessionConfigData.ConnectTimeout        = IfrNvData->ConnectTimeout;\r
-  Attempt->SessionConfigData.IpMode                = IfrNvData->IpMode;\r
+  Attempt->SessionConfigData.ConnectRetryCount = IfrNvData->ConnectRetryCount;\r
+  Attempt->SessionConfigData.ConnectTimeout    = IfrNvData->ConnectTimeout;\r
+  Attempt->SessionConfigData.IpMode            = IfrNvData->IpMode;\r
 \r
   if (IfrNvData->IpMode < IP_MODE_AUTOCONFIG) {\r
     Attempt->SessionConfigData.InitiatorInfoFromDhcp = IfrNvData->InitiatorInfoFromDhcp;\r
@@ -491,7 +845,7 @@ IScsiConvertIfrNvDataToAttemptConfigData (
         L"Connection Establishing Timeout is less than minimum value 100ms.",\r
         NULL\r
         );\r
-      \r
+\r
       return EFI_INVALID_PARAMETER;\r
     }\r
 \r
@@ -512,7 +866,7 @@ IScsiConvertIfrNvDataToAttemptConfigData (
             L"Gateway address is set but subnet mask is zero.",\r
             NULL\r
             );\r
-          \r
+\r
           return EFI_INVALID_PARAMETER;\r
         } else if (!IP4_NET_EQUAL (HostIp.Addr[0], Gateway.Addr[0], SubnetMask.Addr[0])) {\r
           CreatePopUp (\r
@@ -521,25 +875,54 @@ IScsiConvertIfrNvDataToAttemptConfigData (
             L"Local IP and Gateway are not in the same subnet.",\r
             NULL\r
             );\r
-          \r
+\r
           return EFI_INVALID_PARAMETER;\r
         }\r
       }\r
     }\r
+\r
     //\r
     // Validate target configuration if DHCP isn't deployed.\r
     //\r
-    if (!Attempt->SessionConfigData.TargetInfoFromDhcp && Attempt->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG) {\r
-      if (!IpIsUnicast (&Attempt->SessionConfigData.TargetIp, IfrNvData->IpMode)) {\r
+    if (!Attempt->SessionConfigData.TargetInfoFromDhcp && (Attempt->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG)) {\r
+      if (!Attempt->SessionConfigData.DnsMode) {\r
+        if (!IpIsUnicast (&Attempt->SessionConfigData.TargetIp, IfrNvData->IpMode)) {\r
+          CreatePopUp (\r
+            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+            &Key,\r
+            L"Target IP is invalid!",\r
+            NULL\r
+            );\r
+          return EFI_INVALID_PARAMETER;\r
+        }\r
+      } else {\r
+        if (Attempt->SessionConfigData.TargetUrl[0] == '\0') {\r
+          CreatePopUp (\r
+            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+            &Key,\r
+            L"iSCSI target Url should not be NULL!",\r
+            NULL\r
+            );\r
+          return EFI_INVALID_PARAMETER;\r
+        }\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"Target IP is invalid!",\r
+          L"iSCSI target name is NULL!",\r
           NULL\r
           );\r
         return EFI_INVALID_PARAMETER;\r
       }\r
     }\r
+\r
     //\r
     // Validate the authentication info.\r
     //\r
@@ -551,19 +934,20 @@ IScsiConvertIfrNvDataToAttemptConfigData (
           L"CHAP Name or CHAP Secret is invalid!",\r
           NULL\r
           );\r
-        \r
+\r
         return EFI_INVALID_PARAMETER;\r
       }\r
 \r
       if ((IfrNvData->CHAPType == ISCSI_CHAP_MUTUAL) &&\r
           ((IfrNvData->ReverseCHAPName[0] == '\0') || (IfrNvData->ReverseCHAPSecret[0] == '\0'))\r
-          ) {\r
+          )\r
+      {\r
         CreatePopUp (\r
           EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
           &Key,\r
           L"Reverse CHAP Name or Reverse CHAP Secret is invalid!",\r
           NULL\r
-          );        \r
+          );\r
         return EFI_INVALID_PARAMETER;\r
       }\r
     }\r
@@ -573,30 +957,23 @@ IScsiConvertIfrNvDataToAttemptConfigData (
     //\r
     SameNicAttempt = IScsiConfigGetAttemptByNic (Attempt, IfrNvData->Enabled);\r
     if (SameNicAttempt != NULL) {\r
-      AttemptName1 = (CHAR16 *) AllocateZeroPool (ATTEMPT_NAME_MAX_SIZE * sizeof (CHAR16));\r
+      AttemptName1 = (CHAR16 *)AllocateZeroPool (ATTEMPT_NAME_SIZE * sizeof (CHAR16));\r
       if (AttemptName1 == NULL) {\r
         return EFI_OUT_OF_RESOURCES;\r
       }\r
 \r
-      AttemptName2 = (CHAR16 *) AllocateZeroPool (ATTEMPT_NAME_MAX_SIZE * sizeof (CHAR16));\r
+      AttemptName2 = (CHAR16 *)AllocateZeroPool (ATTEMPT_NAME_SIZE * sizeof (CHAR16));\r
       if (AttemptName2 == NULL) {\r
         FreePool (AttemptName1);\r
         return EFI_OUT_OF_RESOURCES;\r
-      }      \r
-      \r
-      AsciiStrToUnicodeStr (Attempt->AttemptName, AttemptName1);\r
-      if (StrLen (AttemptName1) > ATTEMPT_NAME_SIZE) {\r
-        CopyMem (&AttemptName1[ATTEMPT_NAME_SIZE], L"...", 4 * sizeof (CHAR16));\r
       }\r
 \r
-      AsciiStrToUnicodeStr (SameNicAttempt->AttemptName, AttemptName2);\r
-      if (StrLen (AttemptName2) > ATTEMPT_NAME_SIZE) {\r
-        CopyMem (&AttemptName2[ATTEMPT_NAME_SIZE], L"...", 4 * sizeof (CHAR16));\r
-      }\r
+      AsciiStrToUnicodeStrS (Attempt->AttemptName, AttemptName1, ATTEMPT_NAME_SIZE);\r
+      AsciiStrToUnicodeStrS (SameNicAttempt->AttemptName, AttemptName2, ATTEMPT_NAME_SIZE);\r
 \r
       UnicodeSPrint (\r
         mPrivate->PortString,\r
-        (UINTN) ISCSI_NAME_IFR_MAX_SIZE,\r
+        (UINTN)ISCSI_NAME_IFR_MAX_SIZE,\r
         L"Warning! Attempt \"%s\" uses same NIC as Attempt \"%s\".",\r
         AttemptName1,\r
         AttemptName2\r
@@ -607,13 +984,67 @@ IScsiConvertIfrNvDataToAttemptConfigData (
         &Key,\r
         mPrivate->PortString,\r
         NULL\r
-        );       \r
+        );\r
 \r
       FreePool (AttemptName1);\r
       FreePool (AttemptName2);\r
     }\r
   }\r
 \r
+  //\r
+  // Update the iSCSI Mode data and record it in attempt help info.\r
+  //\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
+  AsciiStrToUnicodeStrS (Attempt->MacString, MacString, ISCSI_MAX_MAC_STRING_LEN);\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
@@ -621,9 +1052,9 @@ IScsiConvertIfrNvDataToAttemptConfigData (
   if (ExistAttempt != NULL) {\r
     ASSERT (ExistAttempt == Attempt);\r
 \r
-    if (IfrNvData->Enabled == ISCSI_DISABLED &&\r
-        Attempt->SessionConfigData.Enabled != ISCSI_DISABLED) {\r
-\r
+    if ((IfrNvData->Enabled == ISCSI_DISABLED) &&\r
+        (Attempt->SessionConfigData.Enabled != ISCSI_DISABLED))\r
+    {\r
       //\r
       // User updates the Attempt from "Enabled"/"Enabled for MPIO" to "Disabled".\r
       //\r
@@ -639,11 +1070,12 @@ IScsiConvertIfrNvDataToAttemptConfigData (
         if (mPrivate->SinglePathCount < 1) {\r
           return EFI_ABORTED;\r
         }\r
+\r
         mPrivate->SinglePathCount--;\r
       }\r
-\r
-    } else if (IfrNvData->Enabled == ISCSI_ENABLED_FOR_MPIO &&\r
-               Attempt->SessionConfigData.Enabled == ISCSI_ENABLED) {\r
+    } else if ((IfrNvData->Enabled == ISCSI_ENABLED_FOR_MPIO) &&\r
+               (Attempt->SessionConfigData.Enabled == ISCSI_ENABLED))\r
+    {\r
       //\r
       // User updates the Attempt from "Enabled" to "Enabled for MPIO".\r
       //\r
@@ -654,9 +1086,9 @@ IScsiConvertIfrNvDataToAttemptConfigData (
       mPrivate->EnableMpio = TRUE;\r
       mPrivate->MpioCount++;\r
       mPrivate->SinglePathCount--;\r
-\r
-    } else if (IfrNvData->Enabled == ISCSI_ENABLED &&\r
-               Attempt->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO) {\r
+    } else if ((IfrNvData->Enabled == ISCSI_ENABLED) &&\r
+               (Attempt->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO))\r
+    {\r
       //\r
       // User updates the Attempt from "Enabled for MPIO" to "Enabled".\r
       //\r
@@ -667,102 +1099,674 @@ IScsiConvertIfrNvDataToAttemptConfigData (
       if (--mPrivate->MpioCount == 0) {\r
         mPrivate->EnableMpio = FALSE;\r
       }\r
-      mPrivate->SinglePathCount++;\r
 \r
-    } else if (IfrNvData->Enabled != ISCSI_DISABLED &&\r
-               Attempt->SessionConfigData.Enabled == ISCSI_DISABLED) {\r
+      mPrivate->SinglePathCount++;\r
+    } else if ((IfrNvData->Enabled != ISCSI_DISABLED) &&\r
+               (Attempt->SessionConfigData.Enabled == ISCSI_DISABLED))\r
+    {\r
       //\r
       // User updates the Attempt from "Disabled" to "Enabled"/"Enabled for MPIO".\r
       //\r
       if (IfrNvData->Enabled == ISCSI_ENABLED_FOR_MPIO) {\r
         mPrivate->EnableMpio = TRUE;\r
         mPrivate->MpioCount++;\r
-\r
       } else if (IfrNvData->Enabled == ISCSI_ENABLED) {\r
         mPrivate->SinglePathCount++;\r
       }\r
     }\r
+  } else if (ExistAttempt == NULL) {\r
+    //\r
+    // When a new attempt is created, pointer of the attempt is saved to\r
+    // mCallbackInfo->Current in IScsiConfigProcessDefault. If input Attempt\r
+    // does not match any existing attempt, it should be a new created attempt.\r
+    // Save it to system now.\r
+    //\r
 \r
-  } else if (ExistAttempt == NULL && IfrNvData->Enabled != ISCSI_DISABLED) {\r
-    if (IfrNvData->Enabled == ISCSI_ENABLED_FOR_MPIO) {\r
-      //\r
-      // This new Attempt is enabled for MPIO; enable the multipath mode.\r
-      //\r
-      mPrivate->EnableMpio = TRUE;\r
-      mPrivate->MpioCount++;\r
-    } else if (IfrNvData->Enabled == ISCSI_ENABLED) {\r
-      mPrivate->SinglePathCount++;\r
-    }\r
-  }\r
+    //\r
+    // Save current order number for this attempt.\r
+    //\r
+    AttemptConfigOrder = IScsiGetVariableAndSize (\r
+                           L"AttemptOrder",\r
+                           &gIScsiConfigGuid,\r
+                           &AttemptConfigOrderSize\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
+    TotalNumber = AttemptConfigOrderSize / sizeof (UINT8);\r
+    TotalNumber++;\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
+    // 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
 \r
-  NicInfo = IScsiGetNicInfoByIndex (Attempt->NicIndex);\r
-  if (NicInfo == NULL) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
 \r
-  MacString = (CHAR16 *) AllocateZeroPool (ISCSI_MAX_MAC_STRING_LEN * sizeof (CHAR16));\r
-  if (MacString == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\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
+    if (IfrNvData->Enabled == ISCSI_ENABLED_FOR_MPIO) {\r
+      //\r
+      // This new Attempt is enabled for MPIO; enable the multipath mode.\r
+      //\r
+      mPrivate->EnableMpio = TRUE;\r
+      mPrivate->MpioCount++;\r
+    } else if (IfrNvData->Enabled == ISCSI_ENABLED) {\r
+      mPrivate->SinglePathCount++;\r
+    }\r
+\r
+    IScsiConfigUpdateAttempt ();\r
   }\r
 \r
-  AsciiStrToUnicodeStr (Attempt->MacString, MacString);\r
+  Attempt->SessionConfigData.Enabled = IfrNvData->Enabled;\r
+\r
+  //\r
+  // Record the user configuration information in NVR.\r
+  //\r
+  UnicodeSPrint (mPrivate->PortString, (UINTN)ISCSI_NAME_IFR_MAX_SIZE, L"Attempt %d", Attempt->AttemptConfigIndex);\r
+\r
+  FreePool (MacString);\r
+\r
+  return gRT->SetVariable (\r
+                mPrivate->PortString,\r
+                &gEfiIScsiInitiatorNameProtocolGuid,\r
+                ISCSI_CONFIG_VAR_ATTR,\r
+                sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),\r
+                Attempt\r
+                );\r
+}\r
+\r
+/**\r
+  Convert the IFR data configured by keyword to iSCSI configuration data.\r
+\r
+  @param[in]  IfrNvData      Point to ISCSI_CONFIG_IFR_NVDATA.\r
+  @param[in]  OffSet         The offset of the variable to the configuration structure.\r
+\r
+  @retval EFI_INVALID_PARAMETER  Any input or configured parameter is invalid.\r
+  @retval EFI_SUCCESS            The operation is completed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+IScsiConvertlfrNvDataToAttemptConfigDataByKeyword (\r
+  IN ISCSI_CONFIG_IFR_NVDATA  *IfrNvData,\r
+  IN UINTN                    OffSet\r
+  )\r
+{\r
+  ISCSI_ATTEMPT_CONFIG_NVDATA  *Attempt;\r
+  UINT8                        AttemptIndex;\r
+  UINT8                        Index;\r
+  UINT8                        ChapSecretLen;\r
+  UINT8                        ReverseChapSecretLen;\r
+  CHAR16                       *AttemptName1;\r
+  CHAR16                       *AttemptName2;\r
+  ISCSI_ATTEMPT_CONFIG_NVDATA  *SameNicAttempt;\r
+  CHAR8                        LunString[ISCSI_LUN_STR_MAX_LEN];\r
+  CHAR8                        IScsiName[ISCSI_NAME_MAX_SIZE];\r
+  CHAR8                        IpString[IP_STR_MAX_SIZE];\r
+  EFI_IP_ADDRESS               HostIp;\r
+  EFI_IP_ADDRESS               SubnetMask;\r
+  EFI_IP_ADDRESS               Gateway;\r
+  EFI_INPUT_KEY                Key;\r
+  UINT64                       Lun;\r
+  EFI_STATUS                   Status;\r
+\r
+  Attempt = NULL;\r
+  ZeroMem (IScsiName, sizeof (IScsiName));\r
+\r
+  if (OffSet < ATTEMPT_BOOTENABLE_VAR_OFFSET) {\r
+    return EFI_SUCCESS;\r
+  } else if ((OffSet >= ATTEMPT_BOOTENABLE_VAR_OFFSET) && (OffSet < ATTEMPT_ADDRESS_TYPE_VAR_OFFSET)) {\r
+    AttemptIndex = (UINT8)((OffSet - ATTEMPT_BOOTENABLE_VAR_OFFSET) + 1);\r
+    Attempt      = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);\r
+    if (Attempt == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    IfrNvData->Enabled = IfrNvData->ISCSIBootEnableList[AttemptIndex - 1];\r
+    //\r
+    // Validate the configuration of attempt.\r
+    //\r
+    if (IfrNvData->Enabled != ISCSI_DISABLED) {\r
+      //\r
+      // Check whether this attempt uses NIC which is already used by existing attempt.\r
+      //\r
+      SameNicAttempt = IScsiConfigGetAttemptByNic (Attempt, IfrNvData->Enabled);\r
+      if (SameNicAttempt != NULL) {\r
+        AttemptName1 = (CHAR16 *)AllocateZeroPool (ATTEMPT_NAME_SIZE * sizeof (CHAR16));\r
+        if (AttemptName1 == NULL) {\r
+          return EFI_OUT_OF_RESOURCES;\r
+        }\r
+\r
+        AttemptName2 = (CHAR16 *)AllocateZeroPool (ATTEMPT_NAME_SIZE * sizeof (CHAR16));\r
+        if (AttemptName2 == NULL) {\r
+          FreePool (AttemptName1);\r
+          return EFI_OUT_OF_RESOURCES;\r
+        }\r
+\r
+        AsciiStrToUnicodeStrS (Attempt->AttemptName, AttemptName1, ATTEMPT_NAME_SIZE);\r
+        AsciiStrToUnicodeStrS (SameNicAttempt->AttemptName, AttemptName2, ATTEMPT_NAME_SIZE);\r
+\r
+        UnicodeSPrint (\r
+          mPrivate->PortString,\r
+          (UINTN)ISCSI_NAME_IFR_MAX_SIZE,\r
+          L"Warning! \"%s\" uses same NIC as Attempt \"%s\".",\r
+          AttemptName1,\r
+          AttemptName2\r
+          );\r
+\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &Key,\r
+          mPrivate->PortString,\r
+          NULL\r
+          );\r
+\r
+        FreePool (AttemptName1);\r
+        FreePool (AttemptName2);\r
+      }\r
+    }\r
+\r
+    if ((IfrNvData->Enabled == ISCSI_DISABLED) &&\r
+        (Attempt->SessionConfigData.Enabled != ISCSI_DISABLED))\r
+    {\r
+      //\r
+      // User updates the Attempt from "Enabled"/"Enabled for MPIO" to "Disabled".\r
+      //\r
+      if (Attempt->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO) {\r
+        if (mPrivate->MpioCount < 1) {\r
+          return EFI_ABORTED;\r
+        }\r
+\r
+        if (--mPrivate->MpioCount == 0) {\r
+          mPrivate->EnableMpio = FALSE;\r
+        }\r
+      } else if (Attempt->SessionConfigData.Enabled == ISCSI_ENABLED) {\r
+        if (mPrivate->SinglePathCount < 1) {\r
+          return EFI_ABORTED;\r
+        }\r
+\r
+        mPrivate->SinglePathCount--;\r
+      }\r
+    } else if ((IfrNvData->Enabled == ISCSI_ENABLED_FOR_MPIO) &&\r
+               (Attempt->SessionConfigData.Enabled == ISCSI_ENABLED))\r
+    {\r
+      //\r
+      // User updates the Attempt from "Enabled" to "Enabled for MPIO".\r
+      //\r
+      if (mPrivate->SinglePathCount < 1) {\r
+        return EFI_ABORTED;\r
+      }\r
+\r
+      mPrivate->EnableMpio = TRUE;\r
+      mPrivate->MpioCount++;\r
+      mPrivate->SinglePathCount--;\r
+    } else if ((IfrNvData->Enabled == ISCSI_ENABLED) &&\r
+               (Attempt->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO))\r
+    {\r
+      //\r
+      // User updates the Attempt from "Enabled for MPIO" to "Enabled".\r
+      //\r
+      if (mPrivate->MpioCount < 1) {\r
+        return EFI_ABORTED;\r
+      }\r
+\r
+      if (--mPrivate->MpioCount == 0) {\r
+        mPrivate->EnableMpio = FALSE;\r
+      }\r
+\r
+      mPrivate->SinglePathCount++;\r
+    } else if ((IfrNvData->Enabled != ISCSI_DISABLED) &&\r
+               (Attempt->SessionConfigData.Enabled == ISCSI_DISABLED))\r
+    {\r
+      //\r
+      // User updates the Attempt from "Disabled" to "Enabled"/"Enabled for MPIO".\r
+      //\r
+      if (IfrNvData->Enabled == ISCSI_ENABLED_FOR_MPIO) {\r
+        mPrivate->EnableMpio = TRUE;\r
+        mPrivate->MpioCount++;\r
+      } else if (IfrNvData->Enabled == ISCSI_ENABLED) {\r
+        mPrivate->SinglePathCount++;\r
+      }\r
+    }\r
+\r
+    Attempt->SessionConfigData.Enabled = IfrNvData->Enabled;\r
+  } else if ((OffSet >= ATTEMPT_ADDRESS_TYPE_VAR_OFFSET) && (OffSet < ATTEMPT_CONNECT_RETRY_VAR_OFFSET)) {\r
+    AttemptIndex = (UINT8)((OffSet - ATTEMPT_ADDRESS_TYPE_VAR_OFFSET) + 1);\r
+    Attempt      = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);\r
+    if (Attempt == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    Attempt->SessionConfigData.IpMode = IfrNvData->ISCSIIpAddressTypeList[AttemptIndex - 1];\r
+    if (Attempt->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG) {\r
+      Attempt->AutoConfigureMode = 0;\r
+    }\r
+  } else if ((OffSet >= ATTEMPT_CONNECT_RETRY_VAR_OFFSET) && (OffSet < ATTEMPT_CONNECT_TIMEOUT_VAR_OFFSET)) {\r
+    AttemptIndex = (UINT8)((OffSet - ATTEMPT_CONNECT_RETRY_VAR_OFFSET) + 1);\r
+    Attempt      = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);\r
+    if (Attempt == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    if (IfrNvData->ISCSIConnectRetry[AttemptIndex - 1] > CONNECT_MAX_RETRY) {\r
+      CreatePopUp (\r
+        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+        &Key,\r
+        L"The minimum value is 0 and the maximum is 16. 0 means no retry.",\r
+        NULL\r
+        );\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    Attempt->SessionConfigData.ConnectRetryCount = IfrNvData->ISCSIConnectRetry[AttemptIndex - 1];\r
+  } else if ((OffSet >= ATTEMPT_CONNECT_TIMEOUT_VAR_OFFSET) && (OffSet < ATTEMPT_INITIATOR_VIA_DHCP_VAR_OFFSET)) {\r
+    AttemptIndex = (UINT8)((OffSet - ATTEMPT_CONNECT_TIMEOUT_VAR_OFFSET) / 2 + 1);\r
+    Attempt      = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);\r
+    if (Attempt == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    if ((IfrNvData->ISCSIConnectTimeout[AttemptIndex - 1] < CONNECT_MIN_TIMEOUT) ||\r
+        (IfrNvData->ISCSIConnectTimeout[AttemptIndex - 1] > CONNECT_MAX_TIMEOUT))\r
+    {\r
+      CreatePopUp (\r
+        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+        &Key,\r
+        L"The minimum value is 100 milliseconds and the maximum is 20 seconds.",\r
+        NULL\r
+        );\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    Attempt->SessionConfigData.ConnectTimeout = IfrNvData->ISCSIConnectTimeout[AttemptIndex - 1];\r
+    if (Attempt->SessionConfigData.ConnectTimeout == 0) {\r
+      Attempt->SessionConfigData.ConnectTimeout = CONNECT_DEFAULT_TIMEOUT;\r
+    }\r
+  } else if ((OffSet >= ATTEMPT_INITIATOR_VIA_DHCP_VAR_OFFSET) && (OffSet < ATTEMPT_TARGET_VIA_DHCP_VAR_OFFSET)) {\r
+    AttemptIndex = (UINT8)((OffSet - ATTEMPT_INITIATOR_VIA_DHCP_VAR_OFFSET) + 1);\r
+    Attempt      = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);\r
+    if (Attempt == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    Attempt->SessionConfigData.InitiatorInfoFromDhcp = IfrNvData->ISCSIInitiatorInfoViaDHCP[AttemptIndex - 1];\r
+  } else if ((OffSet >= ATTEMPT_TARGET_VIA_DHCP_VAR_OFFSET) && (OffSet < ATTEMPT_TARGET_TCP_PORT_VAR_OFFSET)) {\r
+    AttemptIndex = (UINT8)((OffSet - ATTEMPT_TARGET_VIA_DHCP_VAR_OFFSET) + 1);\r
+    Attempt      = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);\r
+    if (Attempt == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    if ((Attempt->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG) && (Attempt->SessionConfigData.InitiatorInfoFromDhcp)) {\r
+      Attempt->SessionConfigData.TargetInfoFromDhcp = IfrNvData->ISCSITargetInfoViaDHCP[AttemptIndex - 1];\r
+    } else {\r
+      CreatePopUp (\r
+        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+        &Key,\r
+        L"Invalid Configuration, Check value of IpMode or Enable DHCP!",\r
+        NULL\r
+        );\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  } else if ((OffSet >= ATTEMPT_TARGET_TCP_PORT_VAR_OFFSET) && (OffSet < ATTEMPT_AUTHENTICATION_METHOD_VAR_OFFSET)) {\r
+    AttemptIndex = (UINT8)((OffSet - ATTEMPT_TARGET_TCP_PORT_VAR_OFFSET) / 2 + 1);\r
+    Attempt      = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);\r
+    if (Attempt == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    if ((Attempt->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG) && (!Attempt->SessionConfigData.TargetInfoFromDhcp)) {\r
+      Attempt->SessionConfigData.TargetPort = IfrNvData->ISCSITargetTcpPort[AttemptIndex - 1];\r
+      if (Attempt->SessionConfigData.TargetPort == 0) {\r
+        Attempt->SessionConfigData.TargetPort = ISCSI_WELL_KNOWN_PORT;\r
+      }\r
+    } else {\r
+      CreatePopUp (\r
+        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+        &Key,\r
+        L"Invalid Configuration, Check value of IpMode or Target Via DHCP!",\r
+        NULL\r
+        );\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  } else if ((OffSet >= ATTEMPT_AUTHENTICATION_METHOD_VAR_OFFSET) && (OffSet < ATTEMPT_CHARTYPE_VAR_OFFSET)) {\r
+    AttemptIndex = (UINT8)((OffSet - ATTEMPT_AUTHENTICATION_METHOD_VAR_OFFSET) + 1);\r
+    Attempt      = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);\r
+    if (Attempt == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    Attempt->AuthenticationType = IfrNvData->ISCSIAuthenticationMethod[AttemptIndex - 1];\r
+  } else if ((OffSet >= ATTEMPT_CHARTYPE_VAR_OFFSET) && (OffSet < ATTEMPT_ISID_VAR_OFFSET)) {\r
+    AttemptIndex = (UINT8)((OffSet - ATTEMPT_CHARTYPE_VAR_OFFSET) + 1);\r
+    Attempt      = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);\r
+    if (Attempt == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    if (Attempt->AuthenticationType == ISCSI_AUTH_TYPE_CHAP) {\r
+      Attempt->AuthConfigData.CHAP.CHAPType = IfrNvData->ISCSIChapType[AttemptIndex - 1];\r
+    }\r
+  } else if (OffSet >= ATTEMPT_ISID_VAR_OFFSET) {\r
+    Index        = (UINT8)((OffSet - ATTEMPT_ISID_VAR_OFFSET) / sizeof (KEYWORD_STR));\r
+    AttemptIndex = Index + 1;\r
+    Attempt      = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);\r
+    if (Attempt == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    OffSet = OffSet - Index * sizeof (KEYWORD_STR);\r
+\r
+    if ((OffSet >= ATTEMPT_ISID_VAR_OFFSET) && (OffSet < ATTEMPT_INITIATOR_IP_ADDRESS_VAR_OFFSET)) {\r
+      IScsiParseIsIdFromString (IfrNvData->Keyword[Index].ISCSIIsId, Attempt->SessionConfigData.IsId);\r
+    } else if ((OffSet >= ATTEMPT_INITIATOR_IP_ADDRESS_VAR_OFFSET) && (OffSet < ATTEMPT_INITIATOR_NET_MASK_VAR_OFFSET)) {\r
+      if ((Attempt->SessionConfigData.IpMode == IP_MODE_IP4) && (!Attempt->SessionConfigData.InitiatorInfoFromDhcp)) {\r
+        //\r
+        // Config Local ip\r
+        //\r
+        Status = NetLibStrToIp4 (IfrNvData->Keyword[Index].ISCSIInitiatorIpAddress, &HostIp.v4);\r
+        if (EFI_ERROR (Status) || ((Attempt->SessionConfigData.SubnetMask.Addr[0] != 0) &&\r
+                                   !NetIp4IsUnicast (NTOHL (HostIp.Addr[0]), NTOHL (*(UINT32 *)Attempt->SessionConfigData.SubnetMask.Addr))))\r
+        {\r
+          CreatePopUp (\r
+            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+            &Key,\r
+            L"Invalid IP address!",\r
+            NULL\r
+            );\r
+          return EFI_INVALID_PARAMETER;\r
+        } else {\r
+          CopyMem (&Attempt->SessionConfigData.LocalIp, &HostIp.v4, sizeof (HostIp.v4));\r
+        }\r
+      } else {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &Key,\r
+          L"Invalid Configuration, Check value of IpMode or Enable DHCP!",\r
+          NULL\r
+          );\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+    } else if ((OffSet >= ATTEMPT_INITIATOR_NET_MASK_VAR_OFFSET) && (OffSet < ATTEMPT_INITIATOR_GATE_WAY_VAR_OFFSET)) {\r
+      if ((Attempt->SessionConfigData.IpMode == IP_MODE_IP4) && (!Attempt->SessionConfigData.InitiatorInfoFromDhcp)) {\r
+        Status = NetLibStrToIp4 (IfrNvData->Keyword[Index].ISCSIInitiatorNetmask, &SubnetMask.v4);\r
+        if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (IScsiGetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) {\r
+          CreatePopUp (\r
+            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+            &Key,\r
+            L"Invalid Subnet Mask!",\r
+            NULL\r
+            );\r
+          return EFI_INVALID_PARAMETER;\r
+        } else {\r
+          CopyMem (&Attempt->SessionConfigData.SubnetMask, &SubnetMask.v4, sizeof (SubnetMask.v4));\r
+        }\r
+      } else {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &Key,\r
+          L"Invalid Configuration, Check value of IpMode or Enable DHCP!",\r
+          NULL\r
+          );\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+    } else if ((OffSet >= ATTEMPT_INITIATOR_GATE_WAY_VAR_OFFSET) && (OffSet < ATTEMPT_TARGET_NAME_VAR_OFFSET)) {\r
+      if ((Attempt->SessionConfigData.IpMode == IP_MODE_IP4) && (!Attempt->SessionConfigData.InitiatorInfoFromDhcp)) {\r
+        Status = NetLibStrToIp4 (IfrNvData->Keyword[Index].ISCSIInitiatorGateway, &Gateway.v4);\r
+        if (EFI_ERROR (Status) ||\r
+            ((Gateway.Addr[0] != 0) && (Attempt->SessionConfigData.SubnetMask.Addr[0] != 0) &&\r
+             !NetIp4IsUnicast (NTOHL (Gateway.Addr[0]), NTOHL (*(UINT32 *)Attempt->SessionConfigData.SubnetMask.Addr))))\r
+        {\r
+          CreatePopUp (\r
+            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+            &Key,\r
+            L"Invalid Gateway!",\r
+            NULL\r
+            );\r
+          return EFI_INVALID_PARAMETER;\r
+        } else {\r
+          CopyMem (&Attempt->SessionConfigData.Gateway, &Gateway.v4, sizeof (Gateway.v4));\r
+        }\r
+      } else {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &Key,\r
+          L"Invalid Configuration, Check value of IpMode or Enable DHCP!",\r
+          NULL\r
+          );\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+    } else if ((OffSet >= ATTEMPT_TARGET_NAME_VAR_OFFSET) && (OffSet < ATTEMPT_TARGET_IP_ADDRESS_VAR_OFFSET)) {\r
+      if ((Attempt->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG) && (!Attempt->SessionConfigData.TargetInfoFromDhcp)) {\r
+        UnicodeStrToAsciiStrS (IfrNvData->Keyword[Index].ISCSITargetName, IScsiName, ISCSI_NAME_MAX_SIZE);\r
+        Status = IScsiNormalizeName (IScsiName, AsciiStrLen (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
+        } else {\r
+          AsciiStrCpyS (Attempt->SessionConfigData.TargetName, ISCSI_NAME_MAX_SIZE, IScsiName);\r
+        }\r
+\r
+        if (Attempt->SessionConfigData.Enabled != ISCSI_DISABLED) {\r
+          if (Attempt->SessionConfigData.TargetName[0] == L'\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
+      } else {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &Key,\r
+          L"Invalid Configuration, Check value of IpMode or Target Via DHCP!",\r
+          NULL\r
+          );\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+    } else if ((OffSet >= ATTEMPT_TARGET_IP_ADDRESS_VAR_OFFSET) && (OffSet < ATTEMPT_LUN_VAR_OFFSET)) {\r
+      if ((Attempt->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG) && (!Attempt->SessionConfigData.TargetInfoFromDhcp)) {\r
+        UnicodeStrToAsciiStrS (IfrNvData->Keyword[Index].ISCSITargetIpAddress, IpString, sizeof (IpString));\r
+        Status = IScsiAsciiStrToIp (IpString, Attempt->SessionConfigData.IpMode, &HostIp);\r
+        if (EFI_ERROR (Status) || !IpIsUnicast (&HostIp, Attempt->SessionConfigData.IpMode)) {\r
+          Attempt->SessionConfigData.DnsMode = TRUE;\r
+          ZeroMem (&Attempt->SessionConfigData.TargetIp, sizeof (Attempt->SessionConfigData.TargetIp));\r
+          UnicodeStrToAsciiStrS (IfrNvData->Keyword[Index].ISCSITargetIpAddress, Attempt->SessionConfigData.TargetUrl, ISCSI_NAME_MAX_SIZE);\r
+        } else {\r
+          Attempt->SessionConfigData.DnsMode = FALSE;\r
+          CopyMem (&Attempt->SessionConfigData.TargetIp, &HostIp, sizeof (HostIp));\r
+        }\r
+      } else {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &Key,\r
+          L"Invalid Configuration, Check value of IpMode or Target Via DHCP!",\r
+          NULL\r
+          );\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+    } else if ((OffSet >= ATTEMPT_LUN_VAR_OFFSET) && (OffSet < ATTEMPT_CHAR_USER_NAME_VAR_OFFSET)) {\r
+      if ((Attempt->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG) && (Attempt->SessionConfigData.TargetInfoFromDhcp == 0)) {\r
+        //\r
+        // Config LUN.\r
+        //\r
+        UnicodeStrToAsciiStrS (IfrNvData->Keyword[Index].ISCSILun, LunString, ISCSI_LUN_STR_MAX_LEN);\r
+        Status = IScsiAsciiStrToLun (LunString, (UINT8 *)&Lun);\r
+        if (EFI_ERROR (Status)) {\r
+          CreatePopUp (\r
+            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+            &Key,\r
+            L"Invalid LUN string, Examples are: 4752-3A4F-6b7e-2F99, 6734-9-156f-127, 4186-9!",\r
+            NULL\r
+            );\r
+        } else {\r
+          CopyMem (&Attempt->SessionConfigData.BootLun, &Lun, sizeof (Lun));\r
+        }\r
+      } else {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &Key,\r
+          L"Invalid Configuration, Check value of IpMode or Target Via DHCP!",\r
+          NULL\r
+          );\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+    } else if ((OffSet >= ATTEMPT_CHAR_USER_NAME_VAR_OFFSET) && (OffSet < ATTEMPT_CHAR_SECRET_VAR_OFFSET)) {\r
+      if (Attempt->AuthenticationType == ISCSI_AUTH_TYPE_CHAP) {\r
+        UnicodeStrToAsciiStrS (\r
+          IfrNvData->Keyword[Index].ISCSIChapUsername,\r
+          Attempt->AuthConfigData.CHAP.CHAPName,\r
+          ISCSI_CHAP_NAME_STORAGE\r
+          );\r
+\r
+        if (Attempt->SessionConfigData.Enabled != ISCSI_DISABLED) {\r
+          if (IfrNvData->Keyword[Index].ISCSIChapUsername[0] == L'\0') {\r
+            CreatePopUp (\r
+              EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+              &Key,\r
+              L"CHAP Name is invalid!",\r
+              NULL\r
+              );\r
+            return EFI_INVALID_PARAMETER;\r
+          }\r
+        }\r
+      } else {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &Key,\r
+          L"Invalid Configuration, Check value of AuthenticationType!",\r
+          NULL\r
+          );\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+    } else if ((OffSet >= ATTEMPT_CHAR_SECRET_VAR_OFFSET) && (OffSet < ATTEMPT_CHAR_REVERSE_USER_NAME_VAR_OFFSET)) {\r
+      if (Attempt->AuthenticationType == ISCSI_AUTH_TYPE_CHAP) {\r
+        ChapSecretLen = (UINT8)StrLen (IfrNvData->Keyword[Index].ISCSIChapSecret);\r
+        UnicodeStrToAsciiStrS (\r
+          IfrNvData->Keyword[Index].ISCSIChapSecret,\r
+          Attempt->AuthConfigData.CHAP.CHAPSecret,\r
+          ISCSI_CHAP_SECRET_STORAGE\r
+          );\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
+        if (Attempt->SessionConfigData.Enabled != ISCSI_DISABLED) {\r
+          if ((ChapSecretLen < ISCSI_CHAP_SECRET_MIN_LEN) || (ChapSecretLen > ISCSI_CHAP_SECRET_MAX_LEN)) {\r
+            CreatePopUp (\r
+              EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+              &Key,\r
+              L"The Chap Secret minimum length is 12 bytes and the maximum length is 16 bytes.",\r
+              NULL\r
+              );\r
+            return EFI_INVALID_PARAMETER;\r
+          }\r
+        }\r
+      } else {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &Key,\r
+          L"Invalid Configuration, Check value of AuthenticationType!",\r
+          NULL\r
+          );\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+    } else if ((OffSet >= ATTEMPT_CHAR_REVERSE_USER_NAME_VAR_OFFSET) && (OffSet < ATTEMPT_CHAR_REVERSE_SECRET_VAR_OFFSET)) {\r
+      if (Attempt->AuthConfigData.CHAP.CHAPType == ISCSI_CHAP_MUTUAL) {\r
+        UnicodeStrToAsciiStrS (\r
+          IfrNvData->Keyword[Index].ISCSIReverseChapUsername,\r
+          Attempt->AuthConfigData.CHAP.ReverseCHAPName,\r
+          ISCSI_CHAP_NAME_STORAGE\r
+          );\r
+        if (Attempt->SessionConfigData.Enabled != ISCSI_DISABLED) {\r
+          if (IfrNvData->Keyword[Index].ISCSIReverseChapUsername[0] == L'\0') {\r
+            CreatePopUp (\r
+              EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+              &Key,\r
+              L"Reverse CHAP Name is invalid!",\r
+              NULL\r
+              );\r
+            return EFI_INVALID_PARAMETER;\r
+          }\r
+        }\r
+      } else {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &Key,\r
+          L"Invalid Configuration, Check value of AuthenticationType or Chap Type!",\r
+          NULL\r
+          );\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+    } else if (OffSet >= ATTEMPT_CHAR_REVERSE_SECRET_VAR_OFFSET) {\r
+      if (Attempt->AuthConfigData.CHAP.CHAPType == ISCSI_CHAP_MUTUAL) {\r
+        ReverseChapSecretLen = (UINT8)StrLen (IfrNvData->Keyword[Index].ISCSIReverseChapSecret);\r
+        UnicodeStrToAsciiStrS (\r
+          IfrNvData->Keyword[Index].ISCSIReverseChapSecret,\r
+          Attempt->AuthConfigData.CHAP.ReverseCHAPSecret,\r
+          ISCSI_CHAP_SECRET_STORAGE\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
+        if (Attempt->SessionConfigData.Enabled != ISCSI_DISABLED) {\r
+          if ((ReverseChapSecretLen < ISCSI_CHAP_SECRET_MIN_LEN) || (ReverseChapSecretLen > ISCSI_CHAP_SECRET_MAX_LEN)) {\r
+            CreatePopUp (\r
+              EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+              &Key,\r
+              L"The Reverse CHAP Secret minimum length is 12 bytes and the maximum length is 16 bytes.",\r
+              NULL\r
+              );\r
+            return EFI_INVALID_PARAMETER;\r
+          }\r
+        }\r
+      } else {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &Key,\r
+          L"Invalid Configuration, Check value of AuthenticationType or Chap Type!",\r
+          NULL\r
+          );\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+    }\r
   }\r
 \r
   //\r
   // Record the user configuration information in NVR.\r
   //\r
-  UnicodeSPrint (\r
-    mPrivate->PortString,\r
-    (UINTN) ISCSI_NAME_IFR_MAX_SIZE,\r
-    L"%s%d",\r
-    MacString,\r
-    (UINTN) Attempt->AttemptConfigIndex\r
-    );\r
-\r
-  FreePool (MacString);\r
-\r
+  ASSERT (Attempt != NULL);\r
+  UnicodeSPrint (mPrivate->PortString, (UINTN)ISCSI_NAME_IFR_MAX_SIZE, L"Attempt %d", Attempt->AttemptConfigIndex);\r
   return gRT->SetVariable (\r
                 mPrivate->PortString,\r
                 &gEfiIScsiInitiatorNameProtocolGuid,\r
@@ -773,7 +1777,7 @@ IScsiConvertIfrNvDataToAttemptConfigData (
 }\r
 \r
 /**\r
-  Create Hii Extend Label OpCode as the start opcode and end opcode. It is \r
+  Create Hii Extend Label OpCode as the start opcode and end opcode. It is\r
   a help function.\r
 \r
   @param[in]  StartLabelNumber   The number of start label.\r
@@ -784,24 +1788,24 @@ IScsiConvertIfrNvDataToAttemptConfigData (
 \r
   @retval EFI_OUT_OF_RESOURCES   Do not have sufficient resource to finish this\r
                                  operation.\r
-  @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.                                 \r
+  @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.\r
   @retval EFI_SUCCESS            The operation is completed successfully.\r
 \r
 **/\r
 EFI_STATUS\r
 IScsiCreateOpCode (\r
-  IN  UINT16                        StartLabelNumber,\r
-  OUT VOID                          **StartOpCodeHandle,\r
-  OUT EFI_IFR_GUID_LABEL            **StartLabel,\r
-  OUT VOID                          **EndOpCodeHandle,\r
-  OUT EFI_IFR_GUID_LABEL            **EndLabel\r
+  IN  UINT16              StartLabelNumber,\r
+  OUT VOID                **StartOpCodeHandle,\r
+  OUT EFI_IFR_GUID_LABEL  **StartLabel,\r
+  OUT VOID                **EndOpCodeHandle,\r
+  OUT EFI_IFR_GUID_LABEL  **EndLabel\r
   )\r
 {\r
-  EFI_STATUS                        Status;\r
-  EFI_IFR_GUID_LABEL                *InternalStartLabel;\r
-  EFI_IFR_GUID_LABEL                *InternalEndLabel;\r
+  EFI_STATUS          Status;\r
+  EFI_IFR_GUID_LABEL  *InternalStartLabel;\r
+  EFI_IFR_GUID_LABEL  *InternalEndLabel;\r
 \r
-  if (StartOpCodeHandle == NULL || StartLabel == NULL || EndOpCodeHandle == NULL || EndLabel == NULL) {\r
+  if ((StartOpCodeHandle == NULL) || (StartLabel == NULL) || (EndOpCodeHandle == NULL) || (EndLabel == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -825,28 +1829,28 @@ IScsiCreateOpCode (
   //\r
   // Create Hii Extend Label OpCode as the start opcode.\r
   //\r
-  InternalStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
-                                                *StartOpCodeHandle,\r
-                                                &gEfiIfrTianoGuid,\r
-                                                NULL,\r
-                                                sizeof (EFI_IFR_GUID_LABEL)\r
-                                                );\r
+  InternalStartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (\r
+                                               *StartOpCodeHandle,\r
+                                               &gEfiIfrTianoGuid,\r
+                                               NULL,\r
+                                               sizeof (EFI_IFR_GUID_LABEL)\r
+                                               );\r
   if (InternalStartLabel == NULL) {\r
     goto Exit;\r
   }\r
-  \r
+\r
   InternalStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
   InternalStartLabel->Number       = StartLabelNumber;\r
 \r
   //\r
   // Create Hii Extend Label OpCode as the end opcode.\r
   //\r
-  InternalEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
-                                              *EndOpCodeHandle,\r
-                                              &gEfiIfrTianoGuid,\r
-                                              NULL,\r
-                                              sizeof (EFI_IFR_GUID_LABEL)\r
-                                              );\r
+  InternalEndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (\r
+                                             *EndOpCodeHandle,\r
+                                             &gEfiIfrTianoGuid,\r
+                                             NULL,\r
+                                             sizeof (EFI_IFR_GUID_LABEL)\r
+                                             );\r
   if (InternalEndLabel == NULL) {\r
     goto Exit;\r
   }\r
@@ -868,10 +1872,78 @@ Exit:
   if (*EndOpCodeHandle != NULL) {\r
     HiiFreeOpCodeHandle (*EndOpCodeHandle);\r
   }\r
-  \r
+\r
   return Status;\r
 }\r
 \r
+/**\r
+  Update the MAIN form to display the configured attempts.\r
+\r
+**/\r
+VOID\r
+IScsiConfigUpdateAttempt (\r
+  VOID\r
+  )\r
+{\r
+  LIST_ENTRY                   *Entry;\r
+  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptConfigData;\r
+  VOID                         *StartOpCodeHandle;\r
+  EFI_IFR_GUID_LABEL           *StartLabel;\r
+  VOID                         *EndOpCodeHandle;\r
+  EFI_IFR_GUID_LABEL           *EndLabel;\r
+  EFI_STATUS                   Status;\r
+\r
+  Status = IScsiCreateOpCode (\r
+             ATTEMPT_ENTRY_LABEL,\r
+             &StartOpCodeHandle,\r
+             &StartLabel,\r
+             &EndOpCodeHandle,\r
+             &EndLabel\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return;\r
+  }\r
+\r
+  NET_LIST_FOR_EACH (Entry, &mPrivate->AttemptConfigs) {\r
+    AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);\r
+    if (AttemptConfigData->Actived == ISCSI_ACTIVE_ENABLED) {\r
+      //\r
+      // Update Attempt Help Info.\r
+      //\r
+      UnicodeSPrint (mPrivate->PortString, (UINTN)ISCSI_NAME_IFR_MAX_SIZE, L"Attempt %d", (UINTN)AttemptConfigData->AttemptConfigIndex);\r
+      AttemptConfigData->AttemptTitleToken = HiiSetString (\r
+                                               mCallbackInfo->RegisteredHandle,\r
+                                               0,\r
+                                               mPrivate->PortString,\r
+                                               NULL\r
+                                               );\r
+      if (AttemptConfigData->AttemptTitleToken == 0) {\r
+        return;\r
+      }\r
+\r
+      HiiCreateGotoOpCode (\r
+        StartOpCodeHandle,                                                       // Container for dynamic created opcodes\r
+        FORMID_ATTEMPT_FORM,                                                     // Form ID\r
+        AttemptConfigData->AttemptTitleToken,                                    // Prompt text\r
+        AttemptConfigData->AttemptTitleHelpToken,                                // Help text\r
+        EFI_IFR_FLAG_CALLBACK,                                                   // Question flag\r
+        (UINT16)(KEY_ATTEMPT_ENTRY_BASE + AttemptConfigData->AttemptConfigIndex) // Question ID\r
+        );\r
+    }\r
+  }\r
+\r
+  HiiUpdateForm (\r
+    mCallbackInfo->RegisteredHandle, // HII handle\r
+    &gIScsiConfigGuid,               // Formset GUID\r
+    FORMID_MAIN_FORM,                // Form ID\r
+    StartOpCodeHandle,               // Label for where to insert opcodes\r
+    EndOpCodeHandle                  // Replace data\r
+    );\r
+\r
+  HiiFreeOpCodeHandle (StartOpCodeHandle);\r
+  HiiFreeOpCodeHandle (EndOpCodeHandle);\r
+}\r
+\r
 /**\r
   Callback function when user presses "Add an Attempt".\r
 \r
@@ -885,16 +1957,16 @@ IScsiConfigAddAttempt (
   VOID\r
   )\r
 {\r
-  LIST_ENTRY                    *Entry;\r
-  ISCSI_NIC_INFO                *NicInfo;\r
-  EFI_STRING_ID                 PortTitleToken;\r
-  EFI_STRING_ID                 PortTitleHelpToken;\r
-  CHAR16                        MacString[ISCSI_MAX_MAC_STRING_LEN];\r
-  EFI_STATUS                    Status;\r
-  VOID                          *StartOpCodeHandle;\r
-  EFI_IFR_GUID_LABEL            *StartLabel;\r
-  VOID                          *EndOpCodeHandle;\r
-  EFI_IFR_GUID_LABEL            *EndLabel;\r
+  LIST_ENTRY          *Entry;\r
+  ISCSI_NIC_INFO      *NicInfo;\r
+  EFI_STRING_ID       PortTitleToken;\r
+  EFI_STRING_ID       PortTitleHelpToken;\r
+  CHAR16              MacString[ISCSI_MAX_MAC_STRING_LEN];\r
+  EFI_STATUS          Status;\r
+  VOID                *StartOpCodeHandle;\r
+  EFI_IFR_GUID_LABEL  *StartLabel;\r
+  VOID                *EndOpCodeHandle;\r
+  EFI_IFR_GUID_LABEL  *EndLabel;\r
 \r
   Status = IScsiCreateOpCode (\r
              MAC_ENTRY_LABEL,\r
@@ -919,7 +1991,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
@@ -933,7 +2005,7 @@ IScsiConfigAddAttempt (
 \r
     UnicodeSPrint (\r
       mPrivate->PortString,\r
-      (UINTN) ISCSI_NAME_IFR_MAX_SIZE,\r
+      (UINTN)ISCSI_NAME_IFR_MAX_SIZE,\r
       L"PFA: Bus %d | Dev %d | Func %d",\r
       NicInfo->BusNumber,\r
       NicInfo->DeviceNumber,\r
@@ -942,7 +2014,7 @@ IScsiConfigAddAttempt (
     PortTitleHelpToken = HiiSetString (mCallbackInfo->RegisteredHandle, 0, mPrivate->PortString, NULL);\r
     if (PortTitleHelpToken == 0) {\r
       Status = EFI_INVALID_PARAMETER;\r
-      goto Exit;      \r
+      goto Exit;\r
     }\r
 \r
     HiiCreateGotoOpCode (\r
@@ -951,13 +2023,13 @@ IScsiConfigAddAttempt (
       PortTitleToken,\r
       PortTitleHelpToken,\r
       EFI_IFR_FLAG_CALLBACK,                  // Question flag\r
-      (UINT16) (KEY_MAC_ENTRY_BASE + NicInfo->NicIndex)\r
+      (UINT16)(KEY_MAC_ENTRY_BASE + NicInfo->NicIndex)\r
       );\r
   }\r
 \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
@@ -966,86 +2038,195 @@ IScsiConfigAddAttempt (
 Exit:\r
   HiiFreeOpCodeHandle (StartOpCodeHandle);\r
   HiiFreeOpCodeHandle (EndOpCodeHandle);\r
-  \r
+\r
   return Status;\r
 }\r
 \r
-\r
 /**\r
-  Update the MAIN form to display the configured attempts.\r
+  Add the attempts by keyword 'iSCSIAddAttempts', you can use this keyword with\r
+  value 'attempt:1 attempt:2' etc to add one or more attempts once. This is different\r
+  with IScsiConfigAddAttempt function which is used to add attempt by UI configuration.\r
+\r
+  @param[in]  AttemptList        The new attempt List will be added.\r
+\r
+  @retval EFI_SUCCESS            The operation to add attempt list successfully.\r
+  @retval EFI_INVALID_PARAMETER  Any parameter is invalid.\r
+  @retval EFI_NOT_FOUND          Cannot find the corresponding variable.\r
+  @retval EFI_OUT_OF_RESOURCES   Fail to finish the operation due to lack of\r
+                                 resources.\r
 \r
 **/\r
-VOID\r
-IScsiConfigUpdateAttempt (\r
-  VOID\r
+EFI_STATUS\r
+IScsiConfigAddAttemptsByKeywords (\r
+  IN UINT8  *AttemptList\r
   )\r
 {\r
-  CHAR16                        AttemptName[ATTEMPT_NAME_MAX_SIZE];\r
-  LIST_ENTRY                    *Entry;\r
-  ISCSI_ATTEMPT_CONFIG_NVDATA   *AttemptConfigData;\r
-  VOID                          *StartOpCodeHandle;\r
-  EFI_IFR_GUID_LABEL            *StartLabel;\r
-  VOID                          *EndOpCodeHandle;\r
-  EFI_IFR_GUID_LABEL            *EndLabel;\r
-  EFI_STATUS                    Status;\r
-\r
-  Status = IScsiCreateOpCode (\r
-             ATTEMPT_ENTRY_LABEL,\r
-             &StartOpCodeHandle,\r
-             &StartLabel,\r
-             &EndOpCodeHandle,\r
-             &EndLabel\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    return ;\r
+  UINT8                        Index;\r
+  UINT8                        Number;\r
+  UINTN                        TotalNumber;\r
+  UINT8                        Nic;\r
+  UINT8                        *AttemptConfigOrder;\r
+  UINTN                        AttemptConfigOrderSize;\r
+  UINT8                        *AttemptConfigOrderTmp;\r
+  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptConfigData;\r
+  ISCSI_NIC_INFO               *NicInfo;\r
+  CHAR16                       MacString[ISCSI_MAX_MAC_STRING_LEN];\r
+  CHAR16                       IScsiMode[64];\r
+  CHAR16                       IpMode[64];\r
+  EFI_STATUS                   Status;\r
+\r
+  Nic     = mPrivate->CurrentNic;\r
+  NicInfo = IScsiGetNicInfoByIndex (Nic);\r
+  if (NicInfo == NULL) {\r
+    return EFI_NOT_FOUND;\r
   }\r
 \r
-  NET_LIST_FOR_EACH (Entry, &mPrivate->AttemptConfigs) {\r
-    AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);\r
+  //\r
+  // The MAC info will be recorded in Config Data.\r
+  //\r
+  IScsiMacAddrToStr (\r
+    &NicInfo->PermanentAddress,\r
+    NicInfo->HwAddressSize,\r
+    NicInfo->VlanId,\r
+    MacString\r
+    );\r
 \r
-    AsciiStrToUnicodeStr (AttemptConfigData->AttemptName, AttemptName);\r
-    UnicodeSPrint (mPrivate->PortString, (UINTN) 128, L"Attempt %s", AttemptName);\r
-    AttemptConfigData->AttemptTitleToken = HiiSetString (\r
-                                             mCallbackInfo->RegisteredHandle,\r
-                                             0,\r
-                                             mPrivate->PortString,\r
-                                             NULL\r
-                                             );\r
-    if (AttemptConfigData->AttemptTitleToken == 0) {\r
-      return ;\r
+  for (Index = 0; Index < PcdGet8 (PcdMaxIScsiAttemptNumber); Index++) {\r
+    if (AttemptList[Index] == 0) {\r
+      continue;\r
     }\r
 \r
-    HiiCreateGotoOpCode (\r
-      StartOpCodeHandle,                         // Container for dynamic created opcodes\r
-      FORMID_ATTEMPT_FORM,                       // Form ID\r
-      AttemptConfigData->AttemptTitleToken,      // Prompt text\r
-      AttemptConfigData->AttemptTitleHelpToken,  // Help text\r
-      EFI_IFR_FLAG_CALLBACK,                     // Question flag\r
-      (UINT16) (KEY_ATTEMPT_ENTRY_BASE + AttemptConfigData->AttemptConfigIndex)   // Question ID\r
+    //\r
+    // Add the attempt.\r
+    //\r
+    Number = AttemptList[Index];\r
+\r
+    UnicodeSPrint (\r
+      mPrivate->PortString,\r
+      (UINTN)ISCSI_NAME_IFR_MAX_SIZE,\r
+      L"Attempt %d",\r
+      Number\r
       );\r
-  }\r
 \r
-  HiiUpdateForm (\r
-    mCallbackInfo->RegisteredHandle, // HII handle\r
-    &mVendorGuid,                    // Formset GUID\r
-    FORMID_MAIN_FORM,                // Form ID\r
-    StartOpCodeHandle,               // Label for where to insert opcodes\r
-    EndOpCodeHandle                  // Replace data\r
-  );    \r
+    GetVariable2 (\r
+      mPrivate->PortString,\r
+      &gEfiIScsiInitiatorNameProtocolGuid,\r
+      (VOID **)&AttemptConfigData,\r
+      NULL\r
+      );\r
+    if ((AttemptConfigData == NULL) || (AttemptConfigData->Actived == ISCSI_ACTIVE_ENABLED)) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
 \r
-  HiiFreeOpCodeHandle (StartOpCodeHandle);\r
-  HiiFreeOpCodeHandle (EndOpCodeHandle);\r
-}\r
+    AttemptConfigData->Actived  = ISCSI_ACTIVE_ENABLED;\r
+    AttemptConfigData->NicIndex = NicInfo->NicIndex;\r
+    UnicodeStrToAsciiStrS (MacString, AttemptConfigData->MacString, ISCSI_MAX_MAC_STRING_LEN);\r
+\r
+    //\r
+    // Generate OUI-format ISID based on MAC address.\r
+    //\r
+    CopyMem (AttemptConfigData->SessionConfigData.IsId, &NicInfo->PermanentAddress, 6);\r
+    AttemptConfigData->SessionConfigData.IsId[0] =\r
+      (UINT8)(AttemptConfigData->SessionConfigData.IsId[0] & 0x3F);\r
+\r
+    //\r
+    // Configure the iSCSI Mode and IpMode to default.\r
+    // Add Attempt Help Info.\r
+    //\r
+    UnicodeSPrint (IScsiMode, 64, L"Disabled");\r
+    UnicodeSPrint (IpMode, 64, L"IP4");\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
+    AttemptConfigData->AttemptTitleHelpToken = HiiSetString (\r
+                                                 mCallbackInfo->RegisteredHandle,\r
+                                                 0,\r
+                                                 mPrivate->PortString,\r
+                                                 NULL\r
+                                                 );\r
+    if (AttemptConfigData->AttemptTitleHelpToken == 0) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
+    //\r
+    // Get current Attempt order and number.\r
+    //\r
+    AttemptConfigOrder = IScsiGetVariableAndSize (\r
+                           L"AttemptOrder",\r
+                           &gIScsiConfigGuid,\r
+                           &AttemptConfigOrderSize\r
+                           );\r
+    TotalNumber = AttemptConfigOrderSize / sizeof (UINT8);\r
+    TotalNumber++;\r
+\r
+    //\r
+    // Append the new created attempt order to the end.\r
+    //\r
+    AttemptConfigOrderTmp = AllocateZeroPool (TotalNumber * sizeof (UINT8));\r
+    if (AttemptConfigOrderTmp == NULL) {\r
+      if (AttemptConfigOrder != NULL) {\r
+        FreePool (AttemptConfigOrder);\r
+      }\r
+\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
+    if (AttemptConfigOrder != NULL) {\r
+      CopyMem (AttemptConfigOrderTmp, AttemptConfigOrder, AttemptConfigOrderSize);\r
+      FreePool (AttemptConfigOrder);\r
+    }\r
+\r
+    AttemptConfigOrderTmp[TotalNumber - 1] = Number;\r
+    AttemptConfigOrder                     = AttemptConfigOrderTmp;\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
+    // Record the attempt in global link list.\r
+    //\r
+    InsertTailList (&mPrivate->AttemptConfigs, &AttemptConfigData->Link);\r
+    mPrivate->AttemptCount++;\r
+    UnicodeSPrint (mPrivate->PortString, (UINTN)ISCSI_NAME_IFR_MAX_SIZE, L"Attempt %d", AttemptConfigData->AttemptConfigIndex);\r
+    gRT->SetVariable (\r
+           mPrivate->PortString,\r
+           &gEfiIScsiInitiatorNameProtocolGuid,\r
+           ISCSI_CONFIG_VAR_ATTR,\r
+           sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),\r
+           AttemptConfigData\r
+           );\r
+  }\r
 \r
+  return EFI_SUCCESS;\r
+}\r
 \r
 /**\r
-  Callback function when user presses "Commit Changes and Exit" in Delete Attempts.\r
+  Callback function when user presses "Commit Changes and Exit" in Delete Attempts or Delete Attempts by Keyword.\r
 \r
   @param[in]  IfrNvData          The IFR NV data.\r
 \r
   @retval EFI_NOT_FOUND          Cannot find the corresponding variable.\r
   @retval EFI_SUCCESS            The operation is completed successfully.\r
-  @retval EFI_ABOTRED            This operation is aborted cause of error\r
+  @retval EFI_ABORTED            This operation is aborted cause of error\r
                                  configuration.\r
   @retval EFI_OUT_OF_RESOURCES   Fail to finish the operation due to lack of\r
                                  resources.\r
@@ -1056,23 +2237,26 @@ IScsiConfigDeleteAttempts (
   IN ISCSI_CONFIG_IFR_NVDATA  *IfrNvData\r
   )\r
 {\r
-  EFI_STATUS                  Status;\r
-  UINTN                       Index;\r
-  UINTN                       NewIndex;\r
-  ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;\r
-  UINT8                       *AttemptConfigOrder;\r
-  UINTN                       AttemptConfigOrderSize;\r
-  UINT8                       *AttemptNewOrder;\r
-  UINT32                      Attribute;\r
-  UINTN                       Total;\r
-  UINTN                       NewTotal;\r
-  LIST_ENTRY                  *Entry;\r
-  LIST_ENTRY                  *NextEntry;\r
-  CHAR16                      MacString[ISCSI_MAX_MAC_STRING_LEN];\r
+  EFI_STATUS                   Status;\r
+  UINTN                        Index;\r
+  UINTN                        NewIndex;\r
+  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptConfigData;\r
+  UINT8                        *AttemptConfigOrder;\r
+  UINTN                        AttemptConfigOrderSize;\r
+  UINT8                        *AttemptNewOrder;\r
+  UINT8                        AttemptConfigIndex;\r
+  UINT32                       Attribute;\r
+  UINTN                        Total;\r
+  UINTN                        NewTotal;\r
+  LIST_ENTRY                   *Entry;\r
+  LIST_ENTRY                   *NextEntry;\r
+  ISCSI_SESSION_CONFIG_NVDATA  *ConfigData;\r
+\r
+  Index = 0;\r
 \r
   AttemptConfigOrder = IScsiGetVariableAndSize (\r
                          L"AttemptOrder",\r
-                         &mVendorGuid,\r
+                         &gIScsiConfigGuid,\r
                          &AttemptConfigOrderSize\r
                          );\r
   if ((AttemptConfigOrder == NULL) || (AttemptConfigOrderSize == 0)) {\r
@@ -1081,12 +2265,12 @@ 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
   NewTotal = Total;\r
-  Index    = 0;\r
 \r
   NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &mPrivate->AttemptConfigs) {\r
     if (IfrNvData->DeleteAttemptList[Index] == 0) {\r
@@ -1099,10 +2283,6 @@ IScsiConfigDeleteAttempts (
     //\r
 \r
     AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);\r
-    if (AttemptConfigData == NULL) {\r
-      Status = EFI_NOT_FOUND;\r
-      goto Error;\r
-    }\r
 \r
     //\r
     // Remove this attempt from UI configured attempt list.\r
@@ -1131,22 +2311,45 @@ IScsiConfigDeleteAttempts (
       mPrivate->SinglePathCount--;\r
     }\r
 \r
-    AsciiStrToUnicodeStr (AttemptConfigData->MacString, MacString);\r
+    AttemptConfigIndex = AttemptConfigData->AttemptConfigIndex;\r
+    FreePool (AttemptConfigData);\r
+\r
+    //\r
+    // Create a new Attempt\r
+    //\r
+    AttemptConfigData = AllocateZeroPool (sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA));\r
+    if (AttemptConfigData == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
+    ConfigData                    = &AttemptConfigData->SessionConfigData;\r
+    ConfigData->TargetPort        = ISCSI_WELL_KNOWN_PORT;\r
+    ConfigData->ConnectTimeout    = CONNECT_DEFAULT_TIMEOUT;\r
+    ConfigData->ConnectRetryCount = CONNECT_MIN_RETRY;\r
+\r
+    AttemptConfigData->AuthenticationType           = ISCSI_AUTH_TYPE_CHAP;\r
+    AttemptConfigData->AuthConfigData.CHAP.CHAPType = ISCSI_CHAP_UNI;\r
+    //\r
+    // Configure the Attempt index and set variable.\r
+    //\r
+    AttemptConfigData->AttemptConfigIndex = AttemptConfigIndex;\r
 \r
+    //\r
+    // Set the attempt name to default.\r
+    //\r
     UnicodeSPrint (\r
       mPrivate->PortString,\r
-      (UINTN) 128,\r
-      L"%s%d",\r
-      MacString,\r
-      (UINTN) AttemptConfigData->AttemptConfigIndex\r
+      (UINTN)ISCSI_NAME_IFR_MAX_SIZE,\r
+      L"Attempt %d",\r
+      (UINTN)AttemptConfigData->AttemptConfigIndex\r
       );\r
-\r
+    UnicodeStrToAsciiStrS (mPrivate->PortString, AttemptConfigData->AttemptName, ATTEMPT_NAME_SIZE);\r
     gRT->SetVariable (\r
            mPrivate->PortString,\r
            &gEfiIScsiInitiatorNameProtocolGuid,\r
-           0,\r
-           0,\r
-           NULL\r
+           ISCSI_CONFIG_VAR_ATTR,\r
+           sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),\r
+           AttemptConfigData\r
            );\r
 \r
     //\r
@@ -1160,6 +2363,10 @@ IScsiConfigDeleteAttempts (
     }\r
 \r
     NewTotal--;\r
+    if (mCallbackInfo->Current == AttemptConfigData) {\r
+      mCallbackInfo->Current = NULL;\r
+    }\r
+\r
     FreePool (AttemptConfigData);\r
 \r
     //\r
@@ -1178,28 +2385,31 @@ 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
-  \r
+  if (AttemptConfigOrder != NULL) {\r
+    FreePool (AttemptConfigOrder);\r
+  }\r
+\r
+  if (AttemptNewOrder != NULL) {\r
+    FreePool (AttemptNewOrder);\r
+  }\r
+\r
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Callback function when user presses "Delete Attempts".\r
 \r
@@ -1215,17 +2425,16 @@ IScsiConfigDisplayDeleteAttempts (
   IN ISCSI_CONFIG_IFR_NVDATA  *IfrNvData\r
   )\r
 {\r
-\r
-  UINT8                       *AttemptConfigOrder;\r
-  UINTN                       AttemptConfigOrderSize;\r
-  LIST_ENTRY                  *Entry;\r
-  ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;\r
-  UINT8                       Index;\r
-  VOID                        *StartOpCodeHandle;\r
-  EFI_IFR_GUID_LABEL          *StartLabel;\r
-  VOID                        *EndOpCodeHandle;\r
-  EFI_IFR_GUID_LABEL          *EndLabel;\r
-  EFI_STATUS                  Status;\r
+  UINT8                        *AttemptConfigOrder;\r
+  UINTN                        AttemptConfigOrderSize;\r
+  LIST_ENTRY                   *Entry;\r
+  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptConfigData;\r
+  UINT8                        Index;\r
+  VOID                         *StartOpCodeHandle;\r
+  EFI_IFR_GUID_LABEL           *StartLabel;\r
+  VOID                         *EndOpCodeHandle;\r
+  EFI_IFR_GUID_LABEL           *EndLabel;\r
+  EFI_STATUS                   Status;\r
 \r
   Status = IScsiCreateOpCode (\r
              DELETE_ENTRY_LABEL,\r
@@ -1240,7 +2449,7 @@ IScsiConfigDisplayDeleteAttempts (
 \r
   AttemptConfigOrder = IScsiGetVariableAndSize (\r
                          L"AttemptOrder",\r
-                         &mVendorGuid,\r
+                         &gIScsiConfigGuid,\r
                          &AttemptConfigOrderSize\r
                          );\r
   if (AttemptConfigOrder != NULL) {\r
@@ -1250,14 +2459,14 @@ IScsiConfigDisplayDeleteAttempts (
     Index = 0;\r
 \r
     NET_LIST_FOR_EACH (Entry, &mPrivate->AttemptConfigs) {\r
-      AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);\r
+      AttemptConfigData                   = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);\r
       IfrNvData->DeleteAttemptList[Index] = 0x00;\r
 \r
-      HiiCreateCheckBoxOpCode(\r
+      HiiCreateCheckBoxOpCode (\r
         StartOpCodeHandle,\r
-        (EFI_QUESTION_ID) (ATTEMPT_DEL_QUESTION_ID + Index),\r
+        (EFI_QUESTION_ID)(ATTEMPT_DEL_QUESTION_ID + Index),\r
         CONFIGURATION_VARSTORE_ID,\r
-        (UINT16) (ATTEMPT_DEL_VAR_OFFSET + Index),\r
+        (UINT16)(ATTEMPT_DEL_VAR_OFFSET + Index),\r
         AttemptConfigData->AttemptTitleToken,\r
         AttemptConfigData->AttemptTitleHelpToken,\r
         0,\r
@@ -1277,11 +2486,11 @@ 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
-             );    \r
+             );\r
 \r
   HiiFreeOpCodeHandle (StartOpCodeHandle);\r
   HiiFreeOpCodeHandle (EndOpCodeHandle);\r
@@ -1289,7 +2498,6 @@ IScsiConfigDisplayDeleteAttempts (
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Callback function when user presses "Change Attempt Order".\r
 \r
@@ -1304,16 +2512,16 @@ IScsiConfigDisplayOrderAttempts (
   VOID\r
   )\r
 {\r
-  EFI_STATUS                  Status;\r
-  UINT8                       Index;\r
-  LIST_ENTRY                  *Entry;\r
-  ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;\r
-  VOID                        *StartOpCodeHandle;\r
-  EFI_IFR_GUID_LABEL          *StartLabel;\r
-  VOID                        *EndOpCodeHandle;\r
-  EFI_IFR_GUID_LABEL          *EndLabel;\r
-  VOID                        *OptionsOpCodeHandle;  \r
-  \r
+  EFI_STATUS                   Status;\r
+  UINT8                        Index;\r
+  LIST_ENTRY                   *Entry;\r
+  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptConfigData;\r
+  VOID                         *StartOpCodeHandle;\r
+  EFI_IFR_GUID_LABEL           *StartLabel;\r
+  VOID                         *EndOpCodeHandle;\r
+  EFI_IFR_GUID_LABEL           *EndLabel;\r
+  VOID                         *OptionsOpCodeHandle;\r
+\r
   Status = IScsiCreateOpCode (\r
              ORDER_ENTRY_LABEL,\r
              &StartOpCodeHandle,\r
@@ -1325,6 +2533,8 @@ IScsiConfigDisplayOrderAttempts (
     return Status;\r
   }\r
 \r
+  ASSERT (StartOpCodeHandle != NULL);\r
+\r
   OptionsOpCodeHandle = NULL;\r
 \r
   //\r
@@ -1364,28 +2574,28 @@ IScsiConfigDisplayOrderAttempts (
     DYNAMIC_ORDERED_LIST_QUESTION_ID,           // Question ID\r
     CONFIGURATION_VARSTORE_ID,                  // VarStore ID\r
     DYNAMIC_ORDERED_LIST_VAR_OFFSET,            // Offset in Buffer Storage\r
-    STRING_TOKEN (STR_ORDER_ATTEMPT_ENTRY),     // Question prompt text        \r
-    STRING_TOKEN (STR_ORDER_ATTEMPT_ENTRY),     // Question help text       \r
+    STRING_TOKEN (STR_ORDER_ATTEMPT_ENTRY),     // Question prompt text\r
+    STRING_TOKEN (STR_ORDER_ATTEMPT_ENTRY),     // Question help text\r
     0,                                          // Question flag\r
     EFI_IFR_UNIQUE_SET,                         // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET\r
     EFI_IFR_NUMERIC_SIZE_1,                     // Data type of Question value\r
     ISCSI_MAX_ATTEMPTS_NUM,                     // Maximum container\r
-    OptionsOpCodeHandle,                        // Option Opcode list                        \r
-    NULL                                        // Default Opcode is NULL                               \r
+    OptionsOpCodeHandle,                        // Option Opcode list\r
+    NULL                                        // Default Opcode is NULL\r
     );\r
 \r
 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
-             );             \r
+             );\r
 \r
 Error:\r
   HiiFreeOpCodeHandle (StartOpCodeHandle);\r
-  HiiFreeOpCodeHandle (EndOpCodeHandle);  \r
+  HiiFreeOpCodeHandle (EndOpCodeHandle);\r
   if (OptionsOpCodeHandle != NULL) {\r
     HiiFreeOpCodeHandle (OptionsOpCodeHandle);\r
   }\r
@@ -1393,9 +2603,8 @@ Error:
   return Status;\r
 }\r
 \r
-\r
 /**\r
-  Callback function when user presses "Commit Changes and Exit" in Change Attempt Order.\r
+  Callback function when user presses "Commit Changes and Exit" in Change Attempt Order or Change Attempt Order by Keyword.\r
 \r
   @param[in]  IfrNvData          The IFR nv data.\r
 \r
@@ -1410,18 +2619,18 @@ IScsiConfigOrderAttempts (
   IN ISCSI_CONFIG_IFR_NVDATA  *IfrNvData\r
   )\r
 {\r
-  EFI_STATUS                  Status;\r
-  UINTN                       Index;\r
-  UINTN                       Indexj;\r
-  UINT8                       AttemptConfigIndex;\r
-  ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;\r
-  UINT8                       *AttemptConfigOrder;\r
-  UINT8                       *AttemptConfigOrderTmp;\r
-  UINTN                       AttemptConfigOrderSize;\r
+  EFI_STATUS                   Status;\r
+  UINTN                        Index;\r
+  UINTN                        Indexj;\r
+  UINT8                        AttemptConfigIndex;\r
+  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptConfigData;\r
+  UINT8                        *AttemptConfigOrder;\r
+  UINT8                        *AttemptConfigOrderTmp;\r
+  UINTN                        AttemptConfigOrderSize;\r
 \r
   AttemptConfigOrder = IScsiGetVariableAndSize (\r
                          L"AttemptOrder",\r
-                         &mVendorGuid,\r
+                         &gIScsiConfigGuid,\r
                          &AttemptConfigOrderSize\r
                          );\r
   if (AttemptConfigOrder == NULL) {\r
@@ -1471,7 +2680,7 @@ IScsiConfigOrderAttempts (
   //\r
   // Adjust the attempt order in NVR.\r
   //\r
-  for (; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {\r
+  for ( ; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {\r
     for (Indexj = 0; Indexj < AttemptConfigOrderSize / sizeof (UINT8); Indexj++) {\r
       if (AttemptConfigOrder[Indexj] != 0) {\r
         AttemptConfigOrderTmp[Index] = AttemptConfigOrder[Indexj];\r
@@ -1483,8 +2692,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
@@ -1498,7 +2707,6 @@ Exit:
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Callback function when a user presses "Attempt *" or when a user selects a NIC to\r
   create the new attempt.\r
@@ -1511,40 +2719,43 @@ Exit:
   @retval EFI_OUT_OF_RESOURCES   Does not have sufficient resources to finish this\r
                                  operation.\r
   @retval EFI_NOT_FOUND          Cannot find the corresponding variable.\r
+  @retval EFI_UNSUPPORTED        Can not create more attempts.\r
   @retval EFI_SUCCESS            The operation is completed successfully.\r
 \r
 **/\r
 EFI_STATUS\r
 IScsiConfigProcessDefault (\r
-  IN  EFI_QUESTION_ID              KeyValue,\r
-  IN  ISCSI_CONFIG_IFR_NVDATA      *IfrNvData\r
+  IN  EFI_QUESTION_ID          KeyValue,\r
+  IN  ISCSI_CONFIG_IFR_NVDATA  *IfrNvData\r
   )\r
 {\r
-  BOOLEAN                     NewAttempt;\r
-  ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;\r
-  ISCSI_SESSION_CONFIG_NVDATA *ConfigData;\r
-  UINT8                       CurrentAttemptConfigIndex;\r
-  ISCSI_NIC_INFO              *NicInfo;\r
-  UINT8                       NicIndex;\r
-  CHAR16                      MacString[ISCSI_MAX_MAC_STRING_LEN];\r
-  UINT8                       *AttemptConfigOrder;\r
-  UINTN                       AttemptConfigOrderSize;\r
-  UINTN                       TotalNumber;\r
-  UINT8                       *AttemptOrderTmp;\r
-  UINTN                       Index;\r
-  EFI_STATUS                  Status;\r
-\r
+  BOOLEAN                      NewAttempt;\r
+  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptConfigData;\r
+  UINT8                        CurrentAttemptConfigIndex;\r
+  ISCSI_NIC_INFO               *NicInfo;\r
+  UINT8                        NicIndex;\r
+  CHAR16                       MacString[ISCSI_MAX_MAC_STRING_LEN];\r
+  UINT8                        *AttemptConfigOrder;\r
+  UINTN                        AttemptConfigOrderSize;\r
+  UINTN                        Index;\r
+  EFI_INPUT_KEY                Key;\r
+\r
+  AttemptConfigData = NULL;\r
+  //\r
+  // Is User creating a new attempt?\r
+  //\r
   NewAttempt = FALSE;\r
 \r
   if ((KeyValue >= KEY_MAC_ENTRY_BASE) &&\r
-      (KeyValue <= (UINT16) (mPrivate->MaxNic + KEY_MAC_ENTRY_BASE))) {\r
+      (KeyValue <= (UINT16)(mPrivate->MaxNic + KEY_MAC_ENTRY_BASE)))\r
+  {\r
     //\r
     // User has pressed "Add an Attempt" and then selects a NIC.\r
     //\r
     NewAttempt = TRUE;\r
   } else if ((KeyValue >= KEY_ATTEMPT_ENTRY_BASE) &&\r
-             (KeyValue < (ISCSI_MAX_ATTEMPTS_NUM + KEY_ATTEMPT_ENTRY_BASE))) {\r
-\r
+             (KeyValue < (ISCSI_MAX_ATTEMPTS_NUM + KEY_ATTEMPT_ENTRY_BASE)))\r
+  {\r
     //\r
     // User has pressed "Attempt *".\r
     //\r
@@ -1560,98 +2771,58 @@ IScsiConfigProcessDefault (
     //\r
     // Determine which NIC user has selected for the new created attempt.\r
     //\r
-    NicIndex = (UINT8) (KeyValue - KEY_MAC_ENTRY_BASE);\r
-    NicInfo = IScsiGetNicInfoByIndex (NicIndex);\r
+    NicIndex = (UINT8)(KeyValue - KEY_MAC_ENTRY_BASE);\r
+    NicInfo  = IScsiGetNicInfoByIndex (NicIndex);\r
     if (NicInfo == NULL) {\r
       return EFI_NOT_FOUND;\r
     }\r
-    \r
-    //\r
-    // Create the new attempt and save to NVR.\r
-    //\r
-\r
-    AttemptConfigData = AllocateZeroPool (sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA));\r
-    if (AttemptConfigData == NULL) {\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-\r
-    ConfigData                    = &AttemptConfigData->SessionConfigData;\r
-    ConfigData->TargetPort        = ISCSI_WELL_KNOWN_PORT;\r
-    ConfigData->ConnectTimeout    = CONNECT_DEFAULT_TIMEOUT;\r
-    ConfigData->ConnectRetryCount = CONNECT_MIN_RETRY;\r
-\r
-    AttemptConfigData->AuthenticationType           = ISCSI_AUTH_TYPE_CHAP;\r
-    AttemptConfigData->AuthConfigData.CHAP.CHAPType = ISCSI_CHAP_UNI;\r
 \r
     //\r
-    // Get current order number for this attempt.\r
+    // Create an attempt following the initialized attempt order.\r
     //\r
     AttemptConfigOrder = IScsiGetVariableAndSize (\r
-                           L"AttemptOrder",\r
-                           &mVendorGuid,\r
+                           L"InitialAttemptOrder",\r
+                           &gIScsiConfigGuid,\r
                            &AttemptConfigOrderSize\r
                            );\r
 \r
-    TotalNumber = AttemptConfigOrderSize / sizeof (UINT8);\r
-\r
     if (AttemptConfigOrder == NULL) {\r
-      CurrentAttemptConfigIndex = 1;\r
-    } else {\r
-      //\r
-      // Get the max attempt config index.\r
-      //\r
-      CurrentAttemptConfigIndex = AttemptConfigOrder[0];\r
-      for (Index = 1; Index < TotalNumber; Index++) {\r
-        if (CurrentAttemptConfigIndex < AttemptConfigOrder[Index]) {\r
-          CurrentAttemptConfigIndex = AttemptConfigOrder[Index];\r
-        }\r
-      }\r
-\r
-      CurrentAttemptConfigIndex++;\r
+      return EFI_NOT_FOUND;\r
     }\r
 \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
-      FreePool (AttemptConfigData);\r
-      if (AttemptConfigOrder != NULL) {\r
-        FreePool (AttemptConfigOrder);\r
+    for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {\r
+      UnicodeSPrint (\r
+        mPrivate->PortString,\r
+        (UINTN)ISCSI_NAME_IFR_MAX_SIZE,\r
+        L"Attempt %d",\r
+        (UINTN)AttemptConfigOrder[Index]\r
+        );\r
+      GetVariable2 (\r
+        mPrivate->PortString,\r
+        &gEfiIScsiInitiatorNameProtocolGuid,\r
+        (VOID **)&AttemptConfigData,\r
+        NULL\r
+        );\r
+      if ((AttemptConfigData == NULL) || (AttemptConfigData->Actived == ISCSI_ACTIVE_ENABLED)) {\r
+        continue;\r
       }\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
 \r
-    if (AttemptConfigOrder != NULL) {\r
-      CopyMem (AttemptOrderTmp, AttemptConfigOrder, AttemptConfigOrderSize);\r
-      FreePool (AttemptConfigOrder);      \r
+      break;\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
+    if (Index > PcdGet8 (PcdMaxIScsiAttemptNumber)) {\r
+      CreatePopUp (\r
+        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+        &Key,\r
+        L"Can not create more attempts, Please configure the PcdMaxIScsiAttemptNumber if needed!",\r
+        NULL\r
+        );\r
+      return EFI_UNSUPPORTED;\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
+    if (AttemptConfigOrder != NULL) {\r
+      FreePool (AttemptConfigOrder);\r
+    }\r
 \r
     //\r
     // Record the MAC info in Config Data.\r
@@ -1663,22 +2834,24 @@ IScsiConfigProcessDefault (
       MacString\r
       );\r
 \r
-    UnicodeStrToAsciiStr (MacString, AttemptConfigData->MacString);\r
+    ASSERT (AttemptConfigData != NULL);\r
+    UnicodeStrToAsciiStrS (MacString, AttemptConfigData->MacString, sizeof (AttemptConfigData->MacString));\r
     AttemptConfigData->NicIndex = NicIndex;\r
+    AttemptConfigData->Actived  = ISCSI_ACTIVE_ENABLED;\r
 \r
     //\r
     // Generate OUI-format ISID based on MAC address.\r
     //\r
     CopyMem (AttemptConfigData->SessionConfigData.IsId, &NicInfo->PermanentAddress, 6);\r
-    AttemptConfigData->SessionConfigData.IsId[0] = \r
-      (UINT8) (AttemptConfigData->SessionConfigData.IsId[0] & 0x3F);\r
+    AttemptConfigData->SessionConfigData.IsId[0] =\r
+      (UINT8)(AttemptConfigData->SessionConfigData.IsId[0] & 0x3F);\r
 \r
     //\r
     // Add the help info for the new attempt.\r
     //\r
     UnicodeSPrint (\r
       mPrivate->PortString,\r
-      (UINTN) ISCSI_NAME_IFR_MAX_SIZE,\r
+      (UINTN)ISCSI_NAME_IFR_MAX_SIZE,\r
       L"MAC: %s, PFA: Bus %d | Dev %d | Func %d",\r
       MacString,\r
       NicInfo->BusNumber,\r
@@ -1686,34 +2859,22 @@ IScsiConfigProcessDefault (
       NicInfo->FunctionNumber\r
       );\r
 \r
-    AttemptConfigData->AttemptTitleHelpToken  = HiiSetString (\r
-                                                  mCallbackInfo->RegisteredHandle,\r
-                                                  0,\r
-                                                  mPrivate->PortString,\r
-                                                  NULL\r
-                                                  );\r
+    AttemptConfigData->AttemptTitleHelpToken = HiiSetString (\r
+                                                 mCallbackInfo->RegisteredHandle,\r
+                                                 0,\r
+                                                 mPrivate->PortString,\r
+                                                 NULL\r
+                                                 );\r
     if (AttemptConfigData->AttemptTitleHelpToken == 0) {\r
       FreePool (AttemptConfigData);\r
-      return EFI_INVALID_PARAMETER;\r
+      return EFI_OUT_OF_RESOURCES;\r
     }\r
-\r
-    //\r
-    // Set the attempt name to default.\r
-    //\r
-    UnicodeSPrint (\r
-      mPrivate->PortString,\r
-      (UINTN) 128,\r
-      L"%d",\r
-      (UINTN) AttemptConfigData->AttemptConfigIndex\r
-      );\r
-    UnicodeStrToAsciiStr (mPrivate->PortString, AttemptConfigData->AttemptName);\r
-\r
   } else {\r
     //\r
     // Determine which Attempt user has selected to configure.\r
     // Get the attempt configuration data.\r
     //\r
-    CurrentAttemptConfigIndex = (UINT8) (KeyValue - KEY_ATTEMPT_ENTRY_BASE);\r
+    CurrentAttemptConfigIndex = (UINT8)(KeyValue - KEY_ATTEMPT_ENTRY_BASE);\r
 \r
     AttemptConfigData = IScsiConfigGetAttemptByConfigIndex (CurrentAttemptConfigIndex);\r
     if (AttemptConfigData == NULL) {\r
@@ -1731,19 +2892,19 @@ IScsiConfigProcessDefault (
     ZeroMem (IfrNvData->ReverseCHAPName, sizeof (IfrNvData->ReverseCHAPName));\r
     ZeroMem (IfrNvData->ReverseCHAPSecret, sizeof (IfrNvData->ReverseCHAPSecret));\r
   }\r
-  \r
+\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
-\r
 /**\r
-   \r
+\r
   This function allows the caller to request the current\r
   configuration for one or more named elements. The resulting\r
   string is in <ConfigAltResp> format. Also, any and all alternative\r
@@ -1772,7 +2933,7 @@ IScsiConfigProcessDefault (
                          to the most recent "&" before the first\r
                          failing name / value pair (or the beginning\r
                          of the string if the failure is in the first\r
-                         name / value pair) if the request was not successful.                        \r
+                         name / value pair) if the request was not successful.\r
 \r
   @param[out] Results    A null-terminated Unicode string in\r
                          <ConfigAltResp> format which has all values\r
@@ -1793,7 +2954,7 @@ IScsiConfigProcessDefault (
                                   would result in this type of\r
                                   error. In this case, the\r
                                   Progress parameter would be\r
-                                  set to NULL. \r
+                                  set to NULL.\r
 \r
   @retval EFI_NOT_FOUND           Routing data doesn't match any\r
                                   known driver. Progress set to the\r
@@ -1816,28 +2977,28 @@ IScsiConfigProcessDefault (
 EFI_STATUS\r
 EFIAPI\r
 IScsiFormExtractConfig (\r
-  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
-  IN  CONST EFI_STRING                       Request,\r
-  OUT EFI_STRING                             *Progress,\r
-  OUT EFI_STRING                             *Results\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,\r
+  IN  CONST EFI_STRING                      Request,\r
+  OUT EFI_STRING                            *Progress,\r
+  OUT EFI_STRING                            *Results\r
   )\r
 {\r
-  EFI_STATUS                       Status;\r
-  CHAR8                            *InitiatorName;\r
-  UINTN                            BufferSize;\r
-  ISCSI_CONFIG_IFR_NVDATA          *IfrNvData;\r
-  ISCSI_FORM_CALLBACK_INFO         *Private;\r
-  EFI_STRING                       ConfigRequestHdr;\r
-  EFI_STRING                       ConfigRequest;\r
-  BOOLEAN                          AllocatedRequest;\r
-  UINTN                            Size;\r
-\r
-  if (This == NULL || Progress == NULL || Results == NULL) {\r
+  EFI_STATUS                Status;\r
+  CHAR8                     *InitiatorName;\r
+  UINTN                     BufferSize;\r
+  ISCSI_CONFIG_IFR_NVDATA   *IfrNvData;\r
+  ISCSI_FORM_CALLBACK_INFO  *Private;\r
+  EFI_STRING                ConfigRequestHdr;\r
+  EFI_STRING                ConfigRequest;\r
+  BOOLEAN                   AllocatedRequest;\r
+  UINTN                     Size;\r
+\r
+  if ((This == NULL) || (Progress == NULL) || (Results == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\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
@@ -1846,34 +3007,43 @@ IScsiFormExtractConfig (
   AllocatedRequest = FALSE;\r
   Size             = 0;\r
 \r
-  Private = ISCSI_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This);\r
+  Private   = ISCSI_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This);\r
   IfrNvData = AllocateZeroPool (sizeof (ISCSI_CONFIG_IFR_NVDATA));\r
   if (IfrNvData == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  \r
+\r
   if (Private->Current != NULL) {\r
     IScsiConvertAttemptConfigDataToIfrNvData (Private->Current, IfrNvData);\r
   }\r
 \r
+  //\r
+  // Extract all AttemptConfigData to Keyword storage of IfrNvData.\r
+  //\r
+  IScsiConvertAttemptConfigDataToIfrNvDataByKeyword (IfrNvData);\r
+\r
   BufferSize    = ISCSI_NAME_MAX_SIZE;\r
-  InitiatorName = (CHAR8 *) AllocateZeroPool (BufferSize);\r
+  InitiatorName = (CHAR8 *)AllocateZeroPool (BufferSize);\r
   if (InitiatorName == NULL) {\r
     FreePool (IfrNvData);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-    \r
+\r
   Status = gIScsiInitiatorName.Get (&gIScsiInitiatorName, &BufferSize, InitiatorName);\r
   if (EFI_ERROR (Status)) {\r
     IfrNvData->InitiatorName[0] = L'\0';\r
   } else {\r
-    AsciiStrToUnicodeStr (InitiatorName, IfrNvData->InitiatorName);\r
+    AsciiStrToUnicodeStrS (\r
+      InitiatorName,\r
+      IfrNvData->InitiatorName,\r
+      sizeof (IfrNvData->InitiatorName) / sizeof (IfrNvData->InitiatorName[0])\r
+      );\r
   }\r
 \r
   //\r
   // Convert buffer data to <ConfigResp> by helper function BlockToConfig().\r
   //\r
-  BufferSize = sizeof (ISCSI_CONFIG_IFR_NVDATA);\r
+  BufferSize    = sizeof (ISCSI_CONFIG_IFR_NVDATA);\r
   ConfigRequest = Request;\r
   if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
     //\r
@@ -1881,10 +3051,15 @@ 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
-    Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
-    ConfigRequest = AllocateZeroPool (Size);\r
-    ASSERT (ConfigRequest != NULL);\r
+    ConfigRequestHdr = HiiConstructConfigHdr (&gIScsiConfigGuid, mVendorStorageName, Private->DriverHandle);\r
+    Size             = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
+    ConfigRequest    = AllocateZeroPool (Size);\r
+    if (ConfigRequest == NULL) {\r
+      FreePool (IfrNvData);\r
+      FreePool (InitiatorName);\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
     AllocatedRequest = TRUE;\r
     UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
     FreePool (ConfigRequestHdr);\r
@@ -1893,7 +3068,7 @@ IScsiFormExtractConfig (
   Status = gHiiConfigRouting->BlockToConfig (\r
                                 gHiiConfigRouting,\r
                                 ConfigRequest,\r
-                                (UINT8 *) IfrNvData,\r
+                                (UINT8 *)IfrNvData,\r
                                 BufferSize,\r
                                 Results,\r
                                 Progress\r
@@ -1908,6 +3083,7 @@ IScsiFormExtractConfig (
     FreePool (ConfigRequest);\r
     ConfigRequest = NULL;\r
   }\r
+\r
   //\r
   // Set Progress string to the original request string.\r
   //\r
@@ -1920,9 +3096,8 @@ IScsiFormExtractConfig (
   return Status;\r
 }\r
 \r
-\r
 /**\r
-   \r
+\r
   This function applies changes in a driver's configuration.\r
   Input is a Configuration, which has the routing data for this\r
   driver followed by name / value configuration pairs. The driver\r
@@ -1935,8 +3110,8 @@ IScsiFormExtractConfig (
   @param[in]  This           Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
 \r
   @param[in]  Configuration  A null-terminated Unicode string in\r
-                             <ConfigString> format. \r
-  \r
+                             <ConfigString> format.\r
+\r
   @param[out] Progress       A pointer to a string filled in with the\r
                              offset of the most recent '&' before the\r
                              first failing name / value pair (or the\r
@@ -1947,16 +3122,16 @@ IScsiFormExtractConfig (
 \r
   @retval EFI_SUCCESS             The results have been distributed or are\r
                                   awaiting distribution.\r
-  \r
+\r
   @retval EFI_OUT_OF_RESOURCES    Not enough memory to store the\r
                                   parts of the results that must be\r
                                   stored awaiting possible future\r
                                   protocols.\r
-  \r
+\r
   @retval EFI_INVALID_PARAMETERS  Passing in a NULL for the\r
                                   Results parameter would result\r
                                   in this type of error.\r
-  \r
+\r
   @retval EFI_NOT_FOUND           Target for the specified routing data\r
                                   was not found.\r
 \r
@@ -1964,31 +3139,224 @@ IScsiFormExtractConfig (
 EFI_STATUS\r
 EFIAPI\r
 IScsiFormRouteConfig (\r
-  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
-  IN  CONST EFI_STRING                       Configuration,\r
-  OUT EFI_STRING                             *Progress\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,\r
+  IN  CONST EFI_STRING                      Configuration,\r
+  OUT EFI_STRING                            *Progress\r
   )\r
 {\r
-  if (This == NULL || Configuration == NULL || Progress == NULL) {\r
+  EFI_STATUS                   Status;\r
+  ISCSI_CONFIG_IFR_NVDATA      *IfrNvData;\r
+  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptConfigData;\r
+  LIST_ENTRY                   *Entry;\r
+  LIST_ENTRY                   *NextEntry;\r
+  ISCSI_NIC_INFO               *NicInfo;\r
+  EFI_INPUT_KEY                Key;\r
+  CHAR16                       MacString[ISCSI_MAX_MAC_STRING_LEN];\r
+  CHAR8                        *InitiatorName;\r
+  UINT8                        *AttemptList;\r
+  UINTN                        BufferSize;\r
+  UINTN                        OffSet;\r
+  UINTN                        Index;\r
+  UINTN                        Index2;\r
+\r
+  Index       = 0;\r
+  Index2      = 0;\r
+  NicInfo     = NULL;\r
+  AttemptList = NULL;\r
+  Status      = EFI_SUCCESS;\r
+\r
+  if ((This == NULL) || (Configuration == NULL) || (Progress == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  //\r
-  // 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
-    *Progress = Configuration;\r
-    return EFI_NOT_FOUND;\r
+  //\r
+  // Check routing data in <ConfigHdr>.\r
+  // Note: if only one Storage is used, then this checking could be skipped.\r
+  //\r
+  if (!HiiIsConfigHdrMatch (Configuration, &gIScsiConfigGuid, mVendorStorageName)) {\r
+    *Progress = Configuration;\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  IfrNvData = AllocateZeroPool (sizeof (ISCSI_CONFIG_IFR_NVDATA));\r
+  if (IfrNvData == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  BufferSize    = ISCSI_NAME_MAX_SIZE;\r
+  InitiatorName = (CHAR8 *)AllocateZeroPool (BufferSize);\r
+  if (InitiatorName == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Exit;\r
+  }\r
+\r
+  //\r
+  // Convert <ConfigResp> to buffer data by helper function ConfigToBlock().\r
+  //\r
+  BufferSize = sizeof (ISCSI_CONFIG_IFR_NVDATA);\r
+  Status     = gHiiConfigRouting->ConfigToBlock (\r
+                                    gHiiConfigRouting,\r
+                                    Configuration,\r
+                                    (UINT8 *)IfrNvData,\r
+                                    &BufferSize,\r
+                                    Progress\r
+                                    );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Exit;\r
+  }\r
+\r
+  if (IfrNvData->InitiatorName[0] != L'\0') {\r
+    UnicodeStrToAsciiStrS (IfrNvData->InitiatorName, InitiatorName, ISCSI_NAME_MAX_SIZE);\r
+    BufferSize = AsciiStrSize (InitiatorName);\r
+\r
+    Status = gIScsiInitiatorName.Set (&gIScsiInitiatorName, &BufferSize, InitiatorName);\r
+    if (EFI_ERROR (Status)) {\r
+      CreatePopUp (\r
+        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+        &Key,\r
+        L"Invalid iSCSI Name!",\r
+        NULL\r
+        );\r
+      goto Exit;\r
+    }\r
+  } else {\r
+    Status = IScsiGetValue (Configuration, L"&OFFSET=", &OffSet);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Exit;\r
+    }\r
+\r
+    if (OffSet >= ATTEMPT_MAC_ADDR_VAR_OFFSET) {\r
+      Status = gIScsiInitiatorName.Get (&gIScsiInitiatorName, &BufferSize, InitiatorName);\r
+      if (EFI_ERROR (Status)) {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &Key,\r
+          L"Error: please configure iSCSI initiator name first!",\r
+          NULL\r
+          );\r
+        goto Exit;\r
+      }\r
+    } else {\r
+      goto Exit;\r
+    }\r
+\r
+    if (IfrNvData->ISCSIAddAttemptList[0] != L'\0') {\r
+      Status = IScsiGetAttemptIndexList (IfrNvData->ISCSIAddAttemptList, IfrNvData->AddAttemptList, TRUE);\r
+      if (EFI_ERROR (Status)) {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &Key,\r
+          L"Error: The add attempt list is invalid",\r
+          NULL\r
+          );\r
+        goto Exit;\r
+      }\r
+\r
+      Status = IScsiConfigAddAttemptsByKeywords (IfrNvData->AddAttemptList);\r
+      if (EFI_ERROR (Status)) {\r
+        goto Exit;\r
+      }\r
+    } else if (IfrNvData->ISCSIDeleteAttemptList[0] != L'\0') {\r
+      AttemptList = (UINT8 *)AllocateZeroPool ((ISCSI_MAX_ATTEMPTS_NUM + 1) * sizeof (UINT8));\r
+      if (AttemptList == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Exit;\r
+      }\r
+\r
+      Status = IScsiGetAttemptIndexList (IfrNvData->ISCSIDeleteAttemptList, AttemptList, FALSE);\r
+      if (EFI_ERROR (Status)) {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &Key,\r
+          L"Error: The delete attempt list is invalid",\r
+          NULL\r
+          );\r
+        goto Exit;\r
+      }\r
+\r
+      //\r
+      // Mark the attempt which will be delete in the global list.\r
+      //\r
+      NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &mPrivate->AttemptConfigs) {\r
+        AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);\r
+        while (AttemptList[Index] != 0) {\r
+          if (AttemptConfigData->AttemptConfigIndex == AttemptList[Index]) {\r
+            IfrNvData->DeleteAttemptList[Index2] = 1;\r
+            break;\r
+          }\r
+\r
+          Index++;\r
+        }\r
+\r
+        Index2++;\r
+        Index = 0;\r
+      }\r
+\r
+      Status = IScsiConfigDeleteAttempts (IfrNvData);\r
+      if (EFI_ERROR (Status)) {\r
+        goto Exit;\r
+      }\r
+\r
+      FreePool (AttemptList);\r
+    } else if (IfrNvData->ISCSIAttemptOrder[0] != L'\0') {\r
+      Status = IScsiGetAttemptIndexList (IfrNvData->ISCSIAttemptOrder, IfrNvData->DynamicOrderedList, FALSE);\r
+      if (EFI_ERROR (Status)) {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &Key,\r
+          L"Error: The new attempt order list is invalid",\r
+          NULL\r
+          );\r
+        goto Exit;\r
+      }\r
+\r
+      Status = IScsiConfigOrderAttempts (IfrNvData);\r
+      if (EFI_ERROR (Status)) {\r
+        goto Exit;\r
+      }\r
+    } else if (IfrNvData->ISCSIMacAddr[0] != L'\0') {\r
+      NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {\r
+        NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);\r
+        IScsiMacAddrToStr (\r
+          &NicInfo->PermanentAddress,\r
+          NicInfo->HwAddressSize,\r
+          NicInfo->VlanId,\r
+          MacString\r
+          );\r
+        if (!StrCmp (MacString, IfrNvData->ISCSIMacAddr)) {\r
+          mPrivate->CurrentNic = NicInfo->NicIndex;\r
+          break;\r
+        }\r
+      }\r
+\r
+      if ((NicInfo == NULL) || (NicInfo->NicIndex == 0)) {\r
+        Status = EFI_NOT_FOUND;\r
+        goto Exit;\r
+      }\r
+    } else {\r
+      Status = IScsiConvertlfrNvDataToAttemptConfigDataByKeyword (IfrNvData, OffSet);\r
+      if (EFI_ERROR (Status)) {\r
+        goto Exit;\r
+      }\r
+    }\r
+  }\r
+\r
+  IScsiConfigUpdateAttempt ();\r
+\r
+Exit:\r
+  if (InitiatorName != NULL) {\r
+    FreePool (InitiatorName);\r
+  }\r
+\r
+  if (IfrNvData != NULL) {\r
+    FreePool (IfrNvData);\r
   }\r
 \r
-  *Progress = Configuration + StrLen (Configuration);\r
-  return EFI_SUCCESS;\r
+  return Status;\r
 }\r
 \r
-\r
 /**\r
-   \r
+\r
   This function is called to provide results data to the driver.\r
   This data consists of a unique key that is used to identify\r
   which data is either being passed back or being asked for.\r
@@ -1997,7 +3365,7 @@ IScsiFormRouteConfig (
   @param[in]       Action        Specifies the type of action taken by the browser.\r
   @param[in]       QuestionId    A unique value which is sent to the original\r
                                  exporting driver so that it can identify the type\r
-                                 of data to expect. The format of the data tends to \r
+                                 of data to expect. The format of the data tends to\r
                                  vary based on the opcode that generated the callback.\r
   @param[in]       Type          The type of value for the question.\r
   @param[in, out]  Value         A pointer to the data being sent to the original\r
@@ -2015,28 +3383,30 @@ IScsiFormRouteConfig (
 EFI_STATUS\r
 EFIAPI\r
 IScsiFormCallback (\r
-  IN CONST  EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
-  IN        EFI_BROWSER_ACTION               Action,\r
-  IN        EFI_QUESTION_ID                  QuestionId,\r
-  IN        UINT8                            Type,\r
-  IN OUT    EFI_IFR_TYPE_VALUE               *Value,\r
-  OUT       EFI_BROWSER_ACTION_REQUEST       *ActionRequest\r
+  IN CONST  EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,\r
+  IN        EFI_BROWSER_ACTION              Action,\r
+  IN        EFI_QUESTION_ID                 QuestionId,\r
+  IN        UINT8                           Type,\r
+  IN OUT    EFI_IFR_TYPE_VALUE              *Value,\r
+  OUT       EFI_BROWSER_ACTION_REQUEST      *ActionRequest\r
   )\r
 {\r
-  ISCSI_FORM_CALLBACK_INFO    *Private;\r
-  UINTN                       BufferSize;\r
-  CHAR8                       *IScsiName;\r
-  CHAR8                       IpString[IP_STR_MAX_SIZE];\r
-  CHAR8                       LunString[ISCSI_LUN_STR_MAX_LEN];\r
-  UINT64                      Lun;\r
-  EFI_IP_ADDRESS              HostIp;\r
-  EFI_IP_ADDRESS              SubnetMask;\r
-  EFI_IP_ADDRESS              Gateway;\r
-  ISCSI_CONFIG_IFR_NVDATA     *IfrNvData;\r
-  ISCSI_CONFIG_IFR_NVDATA     OldIfrNvData;\r
-  EFI_STATUS                  Status;\r
-  CHAR16                      AttemptName[ATTEMPT_NAME_SIZE + 4];\r
-  EFI_INPUT_KEY               Key;\r
+  ISCSI_FORM_CALLBACK_INFO  *Private;\r
+  UINTN                     BufferSize;\r
+  CHAR8                     *IScsiName;\r
+  CHAR8                     IpString[ISCSI_NAME_MAX_SIZE];\r
+  CHAR8                     LunString[ISCSI_LUN_STR_MAX_LEN];\r
+  UINT64                    Lun;\r
+  EFI_IP_ADDRESS            HostIp;\r
+  EFI_IP_ADDRESS            SubnetMask;\r
+  EFI_IP_ADDRESS            Gateway;\r
+  ISCSI_CONFIG_IFR_NVDATA   *IfrNvData;\r
+  ISCSI_CONFIG_IFR_NVDATA   OldIfrNvData;\r
+  EFI_STATUS                Status;\r
+  EFI_INPUT_KEY             Key;\r
+  ISCSI_NIC_INFO            *NicInfo;\r
+\r
+  NicInfo = NULL;\r
 \r
   if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action == EFI_BROWSER_ACTION_FORM_CLOSE)) {\r
     //\r
@@ -2045,346 +3415,383 @@ 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
+  if ((Value == NULL) || (ActionRequest == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\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
+  Private = ISCSI_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This);\r
 \r
-    Status = EFI_SUCCESS;\r
+  //\r
+  // Retrieve uncommitted data from Browser\r
+  //\r
 \r
-    ZeroMem (&OldIfrNvData, BufferSize);\r
+  BufferSize = sizeof (ISCSI_CONFIG_IFR_NVDATA);\r
+  IfrNvData  = AllocateZeroPool (BufferSize);\r
+  if (IfrNvData == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
 \r
-    HiiGetBrowserData (NULL, NULL, BufferSize, (UINT8 *) IfrNvData);\r
+  IScsiName = (CHAR8 *)AllocateZeroPool (ISCSI_NAME_MAX_SIZE);\r
+  if (IScsiName == NULL) {\r
+    FreePool (IfrNvData);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
 \r
-    CopyMem (&OldIfrNvData, IfrNvData, BufferSize);\r
+  Status = EFI_SUCCESS;\r
 \r
-    switch (QuestionId) {\r
-    case KEY_INITIATOR_NAME:\r
-      UnicodeStrToAsciiStr (IfrNvData->InitiatorName, IScsiName);\r
-      BufferSize  = AsciiStrSize (IScsiName);\r
+  ZeroMem (&OldIfrNvData, BufferSize);\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
+  HiiGetBrowserData (NULL, NULL, BufferSize, (UINT8 *)IfrNvData);\r
 \r
-      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
-      break;\r
+  CopyMem (&OldIfrNvData, IfrNvData, BufferSize);\r
 \r
-    case KEY_ADD_ATTEMPT:\r
-      Status = IScsiConfigAddAttempt ();\r
-      break;\r
+  if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
+    switch (QuestionId) {\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"Error: please configure iSCSI initiator name first!",\r
+            NULL\r
+            );\r
+          break;\r
+        }\r
 \r
-    case KEY_DELETE_ATTEMPT:\r
-      CopyMem (\r
-        OldIfrNvData.DeleteAttemptList,\r
-        IfrNvData->DeleteAttemptList,\r
-        sizeof (IfrNvData->DeleteAttemptList)\r
-        );\r
-      Status = IScsiConfigDisplayDeleteAttempts (IfrNvData);\r
-      break;\r
+        Status = IScsiConfigAddAttempt ();\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
+      case KEY_DELETE_ATTEMPT:\r
+        CopyMem (\r
+          OldIfrNvData.DeleteAttemptList,\r
+          IfrNvData->DeleteAttemptList,\r
+          sizeof (IfrNvData->DeleteAttemptList)\r
+          );\r
+        Status = IScsiConfigDisplayDeleteAttempts (IfrNvData);\r
         break;\r
-      }\r
 \r
-      IScsiConfigUpdateAttempt ();\r
-      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
-      break;\r
+      case KEY_ORDER_ATTEMPT_CONFIG:\r
+        //\r
+        // Order the attempt according to user input.\r
+        //\r
+        CopyMem (\r
+          OldIfrNvData.DynamicOrderedList,\r
+          IfrNvData->DynamicOrderedList,\r
+          sizeof (IfrNvData->DynamicOrderedList)\r
+          );\r
+        IScsiConfigDisplayOrderAttempts ();\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
+      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
+        UnicodeStrToAsciiStrS (IfrNvData->InitiatorName, IScsiName, ISCSI_NAME_MAX_SIZE);\r
+        BufferSize = AsciiStrSize (IScsiName);\r
 \r
-    case KEY_ORDER_ATTEMPT_CONFIG:\r
-      //\r
-      // Order the attempt according to user input.\r
-      //\r
-      CopyMem (\r
-        OldIfrNvData.DynamicOrderedList,\r
-        IfrNvData->DynamicOrderedList,\r
-        sizeof (IfrNvData->DynamicOrderedList)\r
-        );\r
-      IScsiConfigDisplayOrderAttempts ();\r
-      break;\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
-    case KEY_SAVE_ORDER_CHANGES:\r
-      //\r
-      // Sync the Attempt Order to NVR.\r
-      //\r
-      Status = IScsiConfigOrderAttempts (IfrNvData);\r
-      if (EFI_ERROR (Status)) {\r
+        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;\r
         break;\r
-      }\r
 \r
-      IScsiConfigUpdateAttempt ();\r
-      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
-      break;\r
+      case KEY_SAVE_ATTEMPT_CONFIG:\r
+        Status = IScsiConvertIfrNvDataToAttemptConfigData (IfrNvData, Private->Current);\r
+        if (EFI_ERROR (Status)) {\r
+          break;\r
+        }\r
 \r
-    case KEY_IGNORE_ORDER_CHANGES:\r
-      CopyMem (\r
-        IfrNvData->DynamicOrderedList,\r
-        OldIfrNvData.DynamicOrderedList,\r
-        sizeof (IfrNvData->DynamicOrderedList)\r
-        );\r
-      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
-      break;\r
+        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_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
-      }\r
+      case KEY_SAVE_ORDER_CHANGES:\r
+        //\r
+        // Sync the Attempt Order to NVR.\r
+        //\r
+        Status = IScsiConfigOrderAttempts (IfrNvData);\r
+        if (EFI_ERROR (Status)) {\r
+          break;\r
+        }\r
 \r
-      UnicodeStrToAsciiStr (IfrNvData->AttemptName, Private->Current->AttemptName);\r
+        IScsiConfigUpdateAttempt ();\r
+        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
+        break;\r
 \r
-      IScsiConfigUpdateAttempt ();\r
+      case KEY_IGNORE_ORDER_CHANGES:\r
+        CopyMem (\r
+          IfrNvData->DynamicOrderedList,\r
+          OldIfrNvData.DynamicOrderedList,\r
+          sizeof (IfrNvData->DynamicOrderedList)\r
+          );\r
+        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
+        break;\r
 \r
-      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
-      break;\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
-    case KEY_IP_MODE:\r
-      switch (Value->u8) {\r
-      case IP_MODE_IP6:\r
-        ZeroMem (IfrNvData->TargetIp, sizeof (IfrNvData->TargetIp));\r
-        IScsiIpToStr (&Private->Current->SessionConfigData.TargetIp, TRUE, IfrNvData->TargetIp);\r
-        Private->Current->AutoConfigureMode = 0;\r
+        IScsiConfigUpdateAttempt ();\r
+        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
         break;\r
 \r
-      case IP_MODE_IP4:\r
-        ZeroMem (IfrNvData->TargetIp, sizeof (IfrNvData->TargetIp));\r
-        IScsiIpToStr (&Private->Current->SessionConfigData.TargetIp, FALSE, IfrNvData->TargetIp);\r
-        Private->Current->AutoConfigureMode = 0;\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_FORM_DISCARD_EXIT;\r
         break;\r
-      }\r
 \r
-      break;\r
+      case KEY_IP_MODE:\r
+        switch (Value->u8) {\r
+          case IP_MODE_IP6:\r
+            NicInfo = IScsiGetNicInfoByIndex (Private->Current->NicIndex);\r
+            if (NicInfo == NULL) {\r
+              break;\r
+            }\r
+\r
+            if (!NicInfo->Ipv6Available) {\r
+              //\r
+              // Current NIC doesn't Support IPv6, hence use IPv4.\r
+              //\r
+              IfrNvData->IpMode = IP_MODE_IP4;\r
+\r
+              CreatePopUp (\r
+                EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+                &Key,\r
+                L"Current NIC doesn't Support IPv6!",\r
+                NULL\r
+                );\r
+            }\r
+\r
+          case IP_MODE_IP4:\r
+            ZeroMem (IfrNvData->LocalIp, sizeof (IfrNvData->LocalIp));\r
+            ZeroMem (IfrNvData->SubnetMask, sizeof (IfrNvData->SubnetMask));\r
+            ZeroMem (IfrNvData->Gateway, sizeof (IfrNvData->Gateway));\r
+            ZeroMem (IfrNvData->TargetIp, sizeof (IfrNvData->TargetIp));\r
+            Private->Current->AutoConfigureMode = 0;\r
+            ZeroMem (&Private->Current->SessionConfigData.LocalIp, sizeof (EFI_IP_ADDRESS));\r
+            ZeroMem (&Private->Current->SessionConfigData.SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
+            ZeroMem (&Private->Current->SessionConfigData.Gateway, sizeof (EFI_IP_ADDRESS));\r
+            ZeroMem (&Private->Current->SessionConfigData.TargetIp, sizeof (EFI_IP_ADDRESS));\r
+\r
+            break;\r
+        }\r
 \r
-    case KEY_LOCAL_IP:\r
-      Status = NetLibStrToIp4 (IfrNvData->LocalIp, &HostIp.v4);\r
-      if (EFI_ERROR (Status) || !NetIp4IsUnicast (NTOHL (HostIp.Addr[0]), 0)) {\r
-        CreatePopUp (\r
-          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
-          &Key,\r
-          L"Invalid IP address!",\r
-          NULL\r
-          ); \r
-        \r
-        Status = EFI_INVALID_PARAMETER;\r
-      } else {\r
-        CopyMem (&Private->Current->SessionConfigData.LocalIp, &HostIp.v4, sizeof (HostIp.v4));\r
-      }\r
+        break;\r
 \r
-      break;\r
+      case KEY_LOCAL_IP:\r
+        Status = NetLibStrToIp4 (IfrNvData->LocalIp, &HostIp.v4);\r
+        if (EFI_ERROR (Status) ||\r
+            ((Private->Current->SessionConfigData.SubnetMask.Addr[0] != 0) &&\r
+             !NetIp4IsUnicast (NTOHL (HostIp.Addr[0]), NTOHL (*(UINT32 *)Private->Current->SessionConfigData.SubnetMask.Addr))))\r
+        {\r
+          CreatePopUp (\r
+            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+            &Key,\r
+            L"Invalid IP address!",\r
+            NULL\r
+            );\r
 \r
-    case KEY_SUBNET_MASK:\r
-      Status = NetLibStrToIp4 (IfrNvData->SubnetMask, &SubnetMask.v4);\r
-      if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (IScsiGetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) {\r
-        CreatePopUp (\r
-          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
-          &Key,\r
-          L"Invalid Subnet Mask!",\r
-          NULL\r
-          ); \r
-        \r
-        Status = EFI_INVALID_PARAMETER;\r
-      } else {\r
-        CopyMem (&Private->Current->SessionConfigData.SubnetMask, &SubnetMask.v4, sizeof (SubnetMask.v4));\r
-      }\r
+          Status = EFI_INVALID_PARAMETER;\r
+        } else {\r
+          CopyMem (&Private->Current->SessionConfigData.LocalIp, &HostIp.v4, sizeof (HostIp.v4));\r
+        }\r
 \r
-      break;\r
+        break;\r
 \r
-    case KEY_GATE_WAY:\r
-      Status = NetLibStrToIp4 (IfrNvData->Gateway, &Gateway.v4);\r
-      if (EFI_ERROR (Status) || ((Gateway.Addr[0] != 0) && !NetIp4IsUnicast (NTOHL (Gateway.Addr[0]), 0))) {\r
-        CreatePopUp (\r
-          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
-          &Key,\r
-          L"Invalid Gateway!",\r
-          NULL\r
-          );       \r
-        Status = EFI_INVALID_PARAMETER;\r
-      } else {\r
-        CopyMem (&Private->Current->SessionConfigData.Gateway, &Gateway.v4, sizeof (Gateway.v4));\r
-      }\r
+      case KEY_SUBNET_MASK:\r
+        Status = NetLibStrToIp4 (IfrNvData->SubnetMask, &SubnetMask.v4);\r
+        if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (IScsiGetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) {\r
+          CreatePopUp (\r
+            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+            &Key,\r
+            L"Invalid Subnet Mask!",\r
+            NULL\r
+            );\r
 \r
-      break;\r
+          Status = EFI_INVALID_PARAMETER;\r
+        } else {\r
+          CopyMem (&Private->Current->SessionConfigData.SubnetMask, &SubnetMask.v4, sizeof (SubnetMask.v4));\r
+        }\r
 \r
-    case KEY_TARGET_IP:\r
-      UnicodeStrToAsciiStr (IfrNvData->TargetIp, IpString);\r
-      Status = IScsiAsciiStrToIp (IpString, IfrNvData->IpMode, &HostIp);\r
-      if (EFI_ERROR (Status) || !IpIsUnicast (&HostIp, IfrNvData->IpMode)) {\r
-        CreatePopUp (\r
-          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
-          &Key,\r
-          L"Invalid IP address!",\r
-          NULL\r
-          );       \r
-        Status = EFI_INVALID_PARAMETER;\r
-      } else {\r
-        CopyMem (&Private->Current->SessionConfigData.TargetIp, &HostIp, sizeof (HostIp));\r
-      }\r
+        break;\r
 \r
-      break;\r
+      case KEY_GATE_WAY:\r
+        Status = NetLibStrToIp4 (IfrNvData->Gateway, &Gateway.v4);\r
+        if (EFI_ERROR (Status) ||\r
+            ((Gateway.Addr[0] != 0) &&\r
+             (Private->Current->SessionConfigData.SubnetMask.Addr[0] != 0) &&\r
+             !NetIp4IsUnicast (NTOHL (Gateway.Addr[0]), NTOHL (*(UINT32 *)Private->Current->SessionConfigData.SubnetMask.Addr))))\r
+        {\r
+          CreatePopUp (\r
+            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+            &Key,\r
+            L"Invalid Gateway!",\r
+            NULL\r
+            );\r
+          Status = EFI_INVALID_PARAMETER;\r
+        } else {\r
+          CopyMem (&Private->Current->SessionConfigData.Gateway, &Gateway.v4, sizeof (Gateway.v4));\r
+        }\r
 \r
-    case KEY_TARGET_NAME:\r
-      UnicodeStrToAsciiStr (IfrNvData->TargetName, IScsiName);\r
-      Status = IScsiNormalizeName (IScsiName, AsciiStrLen (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
-      } else {\r
-        AsciiStrCpy (Private->Current->SessionConfigData.TargetName, IScsiName);\r
-      }\r
+        break;\r
 \r
-      break;\r
+      case KEY_TARGET_IP:\r
+        UnicodeStrToAsciiStrS (IfrNvData->TargetIp, IpString, sizeof (IpString));\r
+        Status = IScsiAsciiStrToIp (IpString, IfrNvData->IpMode, &HostIp);\r
+        if (EFI_ERROR (Status) || !IpIsUnicast (&HostIp, IfrNvData->IpMode)) {\r
+          //\r
+          // The target is expressed in URL format or an invalid Ip address, just save.\r
+          //\r
+          Private->Current->SessionConfigData.DnsMode = TRUE;\r
+          ZeroMem (&Private->Current->SessionConfigData.TargetIp, sizeof (Private->Current->SessionConfigData.TargetIp));\r
+          UnicodeStrToAsciiStrS (IfrNvData->TargetIp, Private->Current->SessionConfigData.TargetUrl, ISCSI_NAME_MAX_SIZE);\r
+        } else {\r
+          Private->Current->SessionConfigData.DnsMode = FALSE;\r
+          CopyMem (&Private->Current->SessionConfigData.TargetIp, &HostIp, sizeof (HostIp));\r
+        }\r
 \r
-    case KEY_DHCP_ENABLE:\r
-      if (IfrNvData->InitiatorInfoFromDhcp == 0) {\r
-        IfrNvData->TargetInfoFromDhcp = 0;\r
-      }\r
+        break;\r
 \r
-      break;\r
+      case KEY_TARGET_NAME:\r
+        UnicodeStrToAsciiStrS (IfrNvData->TargetName, IScsiName, ISCSI_NAME_MAX_SIZE);\r
+        Status = IScsiNormalizeName (IScsiName, AsciiStrLen (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
+        } else {\r
+          AsciiStrCpyS (Private->Current->SessionConfigData.TargetName, ISCSI_NAME_MAX_SIZE, IScsiName);\r
+        }\r
 \r
-    case KEY_BOOT_LUN:\r
-      UnicodeStrToAsciiStr (IfrNvData->BootLun, LunString);\r
-      Status = IScsiAsciiStrToLun (LunString, (UINT8 *) &Lun);\r
-      if (EFI_ERROR (Status)) {\r
-        CreatePopUp (\r
-          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
-          &Key,\r
-          L"Invalid LUN string!",\r
-          NULL\r
-          );       \r
-      } else {\r
-        CopyMem (Private->Current->SessionConfigData.BootLun, &Lun, sizeof (Lun));\r
-      }\r
+        break;\r
 \r
-      break;\r
+      case KEY_DHCP_ENABLE:\r
+        if (IfrNvData->InitiatorInfoFromDhcp == 0) {\r
+          IfrNvData->TargetInfoFromDhcp = 0;\r
+        }\r
 \r
-    case KEY_AUTH_TYPE:\r
-      switch (Value->u8) {\r
-      case ISCSI_AUTH_TYPE_CHAP:\r
-        IfrNvData->CHAPType = ISCSI_CHAP_UNI;\r
-        break;\r
-      default:\r
         break;\r
-      }\r
 \r
-      break;\r
+      case KEY_BOOT_LUN:\r
+        UnicodeStrToAsciiStrS (IfrNvData->BootLun, LunString, sizeof (LunString));\r
+        Status = IScsiAsciiStrToLun (LunString, (UINT8 *)&Lun);\r
+        if (EFI_ERROR (Status)) {\r
+          CreatePopUp (\r
+            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+            &Key,\r
+            L"Invalid LUN string!",\r
+            NULL\r
+            );\r
+        } else {\r
+          CopyMem (Private->Current->SessionConfigData.BootLun, &Lun, sizeof (Lun));\r
+        }\r
 \r
-    case KEY_CHAP_NAME:\r
-      UnicodeStrToAsciiStr (\r
-        IfrNvData->CHAPName,\r
-        Private->Current->AuthConfigData.CHAP.CHAPName\r
-        );\r
-      break;\r
+        break;\r
 \r
-    case KEY_CHAP_SECRET:\r
-      UnicodeStrToAsciiStr (\r
-        IfrNvData->CHAPSecret,\r
-        Private->Current->AuthConfigData.CHAP.CHAPSecret\r
-        );\r
-      break;\r
+      case KEY_AUTH_TYPE:\r
+        switch (Value->u8) {\r
+          case ISCSI_AUTH_TYPE_CHAP:\r
+            IfrNvData->CHAPType = ISCSI_CHAP_UNI;\r
+            break;\r
+          default:\r
+            break;\r
+        }\r
 \r
-    case KEY_REVERSE_CHAP_NAME:\r
-      UnicodeStrToAsciiStr (\r
-        IfrNvData->ReverseCHAPName,\r
-        Private->Current->AuthConfigData.CHAP.ReverseCHAPName\r
-        );\r
-      break;\r
+        break;\r
 \r
-    case KEY_REVERSE_CHAP_SECRET:\r
-      UnicodeStrToAsciiStr (\r
-        IfrNvData->ReverseCHAPSecret,\r
-        Private->Current->AuthConfigData.CHAP.ReverseCHAPSecret\r
-        );\r
-      break;\r
+      case KEY_CHAP_NAME:\r
+        UnicodeStrToAsciiStrS (\r
+          IfrNvData->CHAPName,\r
+          Private->Current->AuthConfigData.CHAP.CHAPName,\r
+          sizeof (Private->Current->AuthConfigData.CHAP.CHAPName)\r
+          );\r
+        break;\r
 \r
-    case KEY_CONFIG_ISID:\r
-      IScsiParseIsIdFromString (IfrNvData->IsId, Private->Current->SessionConfigData.IsId);\r
-      IScsiConvertIsIdToString (IfrNvData->IsId, Private->Current->SessionConfigData.IsId);\r
+      case KEY_CHAP_SECRET:\r
+        UnicodeStrToAsciiStrS (\r
+          IfrNvData->CHAPSecret,\r
+          Private->Current->AuthConfigData.CHAP.CHAPSecret,\r
+          sizeof (Private->Current->AuthConfigData.CHAP.CHAPSecret)\r
+          );\r
+        break;\r
 \r
-      break;\r
+      case KEY_REVERSE_CHAP_NAME:\r
+        UnicodeStrToAsciiStrS (\r
+          IfrNvData->ReverseCHAPName,\r
+          Private->Current->AuthConfigData.CHAP.ReverseCHAPName,\r
+          sizeof (Private->Current->AuthConfigData.CHAP.ReverseCHAPName)\r
+          );\r
+        break;\r
 \r
-    case KEY_SAVE_ATTEMPT_CONFIG:\r
-      Status = IScsiConvertIfrNvDataToAttemptConfigData (IfrNvData, Private->Current);\r
-      if (EFI_ERROR (Status)) {\r
+      case KEY_REVERSE_CHAP_SECRET:\r
+        UnicodeStrToAsciiStrS (\r
+          IfrNvData->ReverseCHAPSecret,\r
+          Private->Current->AuthConfigData.CHAP.ReverseCHAPSecret,\r
+          sizeof (Private->Current->AuthConfigData.CHAP.ReverseCHAPSecret)\r
+          );\r
         break;\r
-      }\r
 \r
-      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
-      break;\r
+      case KEY_CONFIG_ISID:\r
+        IScsiParseIsIdFromString (IfrNvData->IsId, Private->Current->SessionConfigData.IsId);\r
+        IScsiConvertIsIdToString (IfrNvData->IsId, Private->Current->SessionConfigData.IsId);\r
 \r
-    default:\r
-      Status = IScsiConfigProcessDefault (QuestionId, IfrNvData);\r
-      break;\r
-    }\r
+        break;\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
+      default:\r
+        break;\r
     }\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
-}\r
+  FreePool (IfrNvData);\r
+  FreePool (IScsiName);\r
 \r
+  return Status;\r
+}\r
 \r
 /**\r
   Initialize the iSCSI configuration form.\r
@@ -2400,16 +3807,16 @@ IScsiConfigFormInit (
   IN EFI_HANDLE  DriverBindingHandle\r
   )\r
 {\r
-  EFI_STATUS                  Status;\r
-  ISCSI_FORM_CALLBACK_INFO    *CallbackInfo;\r
+  EFI_STATUS                Status;\r
+  ISCSI_FORM_CALLBACK_INFO  *CallbackInfo;\r
 \r
-  CallbackInfo = (ISCSI_FORM_CALLBACK_INFO *) AllocateZeroPool (sizeof (ISCSI_FORM_CALLBACK_INFO));\r
+  CallbackInfo = (ISCSI_FORM_CALLBACK_INFO *)AllocateZeroPool (sizeof (ISCSI_FORM_CALLBACK_INFO));\r
   if (CallbackInfo == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  CallbackInfo->Signature   = ISCSI_FORM_CALLBACK_INFO_SIGNATURE;\r
-  CallbackInfo->Current     = NULL;\r
+  CallbackInfo->Signature = ISCSI_FORM_CALLBACK_INFO_SIGNATURE;\r
+  CallbackInfo->Current   = NULL;\r
 \r
   CallbackInfo->ConfigAccess.ExtractConfig = IScsiFormExtractConfig;\r
   CallbackInfo->ConfigAccess.RouteConfig   = IScsiFormRouteConfig;\r
@@ -2427,12 +3834,12 @@ IScsiConfigFormInit (
                   NULL\r
                   );\r
   ASSERT_EFI_ERROR (Status);\r
-  \r
+\r
   //\r
   // Publish our HII data.\r
   //\r
   CallbackInfo->RegisteredHandle = HiiAddPackages (\r
-                                     &mVendorGuid,\r
+                                     &gIScsiConfigGuid,\r
                                      CallbackInfo->DriverHandle,\r
                                      IScsiDxeStrings,\r
                                      IScsiConfigVfrBin,\r
@@ -2440,14 +3847,14 @@ IScsiConfigFormInit (
                                      );\r
   if (CallbackInfo->RegisteredHandle == NULL) {\r
     gBS->UninstallMultipleProtocolInterfaces (\r
-           &CallbackInfo->DriverHandle,\r
+           CallbackInfo->DriverHandle,\r
            &gEfiDevicePathProtocolGuid,\r
            &mIScsiHiiVendorDevicePath,\r
            &gEfiHiiConfigAccessProtocolGuid,\r
            &CallbackInfo->ConfigAccess,\r
            NULL\r
            );\r
-    FreePool(CallbackInfo);\r
+    FreePool (CallbackInfo);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
@@ -2456,7 +3863,6 @@ IScsiConfigFormInit (
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   Unload the iSCSI configuration form, this includes: delete all the iSCSI\r
   configuration entries, uninstall the form callback protocol, and\r
@@ -2473,13 +3879,13 @@ IScsiConfigFormUnload (
   IN EFI_HANDLE  DriverBindingHandle\r
   )\r
 {\r
-  ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;\r
-  ISCSI_NIC_INFO              *NicInfo;\r
-  LIST_ENTRY                  *Entry;\r
-  EFI_STATUS                  Status;\r
+  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptConfigData;\r
+  ISCSI_NIC_INFO               *NicInfo;\r
+  LIST_ENTRY                   *Entry;\r
+  EFI_STATUS                   Status;\r
 \r
   while (!IsListEmpty (&mPrivate->AttemptConfigs)) {\r
-    Entry = NetListRemoveHead (&mPrivate->AttemptConfigs);\r
+    Entry             = NetListRemoveHead (&mPrivate->AttemptConfigs);\r
     AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);\r
     FreePool (AttemptConfigData);\r
     mPrivate->AttemptCount--;\r
@@ -2488,7 +3894,7 @@ IScsiConfigFormUnload (
   ASSERT (mPrivate->AttemptCount == 0);\r
 \r
   while (!IsListEmpty (&mPrivate->NicInfoList)) {\r
-    Entry = NetListRemoveHead (&mPrivate->NicInfoList);\r
+    Entry   = NetListRemoveHead (&mPrivate->NicInfoList);\r
     NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);\r
     FreePool (NicInfo);\r
     mPrivate->NicCount--;\r