]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/IScsiDxe/IScsiConfig.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / NetworkPkg / IScsiDxe / IScsiConfig.c
CommitLineData
4c5a5e0c 1/** @file\r
2 Helper functions for configuring or getting the parameters relating to iSCSI.\r
3\r
af82ca45 4Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>\r
ecf98fbc 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
4c5a5e0c 6\r
7**/\r
8\r
9#include "IScsiImpl.h"\r
10\r
d1050b9d
MK
11CHAR16 mVendorStorageName[] = L"ISCSI_CONFIG_IFR_NVDATA";\r
12ISCSI_FORM_CALLBACK_INFO *mCallbackInfo = NULL;\r
4c5a5e0c 13\r
14HII_VENDOR_DEVICE_PATH mIScsiHiiVendorDevicePath = {\r
15 {\r
16 {\r
17 HARDWARE_DEVICE_PATH,\r
18 HW_VENDOR_DP,\r
19 {\r
d1050b9d
MK
20 (UINT8)(sizeof (VENDOR_DEVICE_PATH)),\r
21 (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
4c5a5e0c 22 }\r
23 },\r
9bdc6592 24 ISCSI_CONFIG_GUID\r
4c5a5e0c 25 },\r
26 {\r
27 END_DEVICE_PATH_TYPE,\r
28 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
f75a7f56 29 {\r
d1050b9d
MK
30 (UINT8)(END_DEVICE_PATH_LENGTH),\r
31 (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)\r
4c5a5e0c 32 }\r
33 }\r
34};\r
35\r
4c5a5e0c 36/**\r
37 Convert the IP address into a dotted string.\r
38\r
39 @param[in] Ip The IP address.\r
40 @param[in] Ipv6Flag Indicates whether the IP address is version 4 or version 6.\r
41 @param[out] Str The formatted IP string.\r
42\r
43**/\r
44VOID\r
45IScsiIpToStr (\r
d1050b9d
MK
46 IN EFI_IP_ADDRESS *Ip,\r
47 IN BOOLEAN Ipv6Flag,\r
48 OUT CHAR16 *Str\r
4c5a5e0c 49 )\r
50{\r
d1050b9d
MK
51 EFI_IPv4_ADDRESS *Ip4;\r
52 EFI_IPv6_ADDRESS *Ip6;\r
53 UINTN Index;\r
54 BOOLEAN Short;\r
55 UINTN Number;\r
56 CHAR16 FormatString[8];\r
4c5a5e0c 57\r
58 if (!Ipv6Flag) {\r
59 Ip4 = &Ip->v4;\r
60\r
61 UnicodeSPrint (\r
62 Str,\r
d1050b9d 63 (UINTN)2 * IP4_STR_MAX_SIZE,\r
4c5a5e0c 64 L"%d.%d.%d.%d",\r
d1050b9d
MK
65 (UINTN)Ip4->Addr[0],\r
66 (UINTN)Ip4->Addr[1],\r
67 (UINTN)Ip4->Addr[2],\r
68 (UINTN)Ip4->Addr[3]\r
4c5a5e0c 69 );\r
70\r
d1050b9d 71 return;\r
4c5a5e0c 72 }\r
73\r
74 Ip6 = &Ip->v6;\r
75 Short = FALSE;\r
76\r
77 for (Index = 0; Index < 15; Index = Index + 2) {\r
78 if (!Short &&\r
d1050b9d
MK
79 (Index % 2 == 0) &&\r
80 (Ip6->Addr[Index] == 0) &&\r
81 (Ip6->Addr[Index + 1] == 0)\r
82 )\r
83 {\r
4c5a5e0c 84 //\r
85 // Deal with the case of ::.\r
86 //\r
87 if (Index == 0) {\r
88 *Str = L':';\r
89 *(Str + 1) = L':';\r
90 Str = Str + 2;\r
91 } else {\r
d1050b9d
MK
92 *Str = L':';\r
93 Str = Str + 1;\r
4c5a5e0c 94 }\r
95\r
96 while ((Index < 15) && (Ip6->Addr[Index] == 0) && (Ip6->Addr[Index + 1] == 0)) {\r
97 Index = Index + 2;\r
98 }\r
99\r
100 Short = TRUE;\r
101\r
102 if (Index == 16) {\r
103 //\r
104 // :: is at the end of the address.\r
105 //\r
106 *Str = L'\0';\r
107 break;\r
108 }\r
109 }\r
110\r
111 ASSERT (Index < 15);\r
112\r
113 if (Ip6->Addr[Index] == 0) {\r
d1050b9d 114 Number = UnicodeSPrint (Str, 2 * IP_STR_MAX_SIZE, L"%x:", (UINTN)Ip6->Addr[Index + 1]);\r
4c5a5e0c 115 } else {\r
116 if (Ip6->Addr[Index + 1] < 0x10) {\r
117 CopyMem (FormatString, L"%x0%x:", StrSize (L"%x0%x:"));\r
118 } else {\r
119 CopyMem (FormatString, L"%x%x:", StrSize (L"%x%x:"));\r
120 }\r
121\r
122 Number = UnicodeSPrint (\r
123 Str,\r
124 2 * IP_STR_MAX_SIZE,\r
d1050b9d
MK
125 (CONST CHAR16 *)FormatString,\r
126 (UINTN)Ip6->Addr[Index],\r
127 (UINTN)Ip6->Addr[Index + 1]\r
4c5a5e0c 128 );\r
129 }\r
130\r
131 Str = Str + Number;\r
132\r
133 if (Index + 2 == 16) {\r
134 *Str = L'\0';\r
135 if (*(Str - 1) == L':') {\r
136 *(Str - 1) = L'\0';\r
137 }\r
138 }\r
139 }\r
140}\r
141\r
142/**\r
143 Check whether the input IP address is valid.\r
144\r
145 @param[in] Ip The IP address.\r
146 @param[in] IpMode Indicates iSCSI running on IP4 or IP6 stack.\r
147\r
148 @retval TRUE The input IP address is valid.\r
149 @retval FALSE Otherwise\r
150\r
151**/\r
152BOOLEAN\r
153IpIsUnicast (\r
d1050b9d 154 IN EFI_IP_ADDRESS *Ip,\r
4c5a5e0c 155 IN UINT8 IpMode\r
156 )\r
157{\r
158 if (IpMode == IP_MODE_IP4) {\r
d1050b9d 159 if (IP4_IS_UNSPECIFIED (NTOHL (Ip->Addr[0])) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip->Addr[0]))) {\r
6c12fe63
FS
160 return FALSE;\r
161 }\r
d1050b9d 162\r
6c12fe63 163 return TRUE;\r
4c5a5e0c 164 } else if (IpMode == IP_MODE_IP6) {\r
165 return NetIp6IsValidUnicast (&Ip->v6);\r
166 } else {\r
167 DEBUG ((DEBUG_ERROR, "IpMode %d is invalid when configuring the iSCSI target IP!\n", IpMode));\r
168 return FALSE;\r
169 }\r
170}\r
171\r
172/**\r
173 Parse IsId in string format and convert it to binary.\r
174\r
175 @param[in] String The buffer of the string to be parsed.\r
176 @param[in, out] IsId The buffer to store IsId.\r
177\r
178 @retval EFI_SUCCESS The operation finished successfully.\r
179 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
180\r
181**/\r
182EFI_STATUS\r
183IScsiParseIsIdFromString (\r
d1050b9d
MK
184 IN CONST CHAR16 *String,\r
185 IN OUT UINT8 *IsId\r
4c5a5e0c 186 )\r
187{\r
d1050b9d
MK
188 UINT8 Index;\r
189 CHAR16 *IsIdStr;\r
190 CHAR16 TempStr[3];\r
191 UINTN NodeVal;\r
192 CHAR16 PortString[ISCSI_NAME_IFR_MAX_SIZE];\r
193 EFI_INPUT_KEY Key;\r
4c5a5e0c 194\r
195 if ((String == NULL) || (IsId == NULL)) {\r
196 return EFI_INVALID_PARAMETER;\r
197 }\r
198\r
d1050b9d 199 IsIdStr = (CHAR16 *)String;\r
4c5a5e0c 200\r
d1050b9d 201 if ((StrLen (IsIdStr) != 6) && (StrLen (IsIdStr) != 12)) {\r
4c5a5e0c 202 UnicodeSPrint (\r
203 PortString,\r
d1050b9d 204 (UINTN)ISCSI_NAME_IFR_MAX_SIZE,\r
41c9011c 205 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
4c5a5e0c 206 );\r
207\r
208 CreatePopUp (\r
209 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
210 &Key,\r
211 PortString,\r
212 NULL\r
213 );\r
214\r
215 return EFI_INVALID_PARAMETER;\r
216 }\r
217\r
41c9011c
FS
218 if (StrLen (IsIdStr) == 12) {\r
219 IsIdStr += 6;\r
220 }\r
221\r
4c5a5e0c 222 for (Index = 3; Index < 6; Index++) {\r
223 CopyMem (TempStr, IsIdStr, sizeof (TempStr));\r
224 TempStr[2] = L'\0';\r
225\r
226 //\r
227 // Convert the string to IsId. StrHexToUintn stops at the first character\r
228 // that is not a valid hex character, '\0' here.\r
229 //\r
230 NodeVal = StrHexToUintn (TempStr);\r
231\r
d1050b9d 232 IsId[Index] = (UINT8)NodeVal;\r
4c5a5e0c 233\r
234 IsIdStr = IsIdStr + 2;\r
235 }\r
236\r
237 return EFI_SUCCESS;\r
238}\r
239\r
240/**\r
241 Convert IsId from binary to string format.\r
242\r
243 @param[out] String The buffer to store the converted string.\r
244 @param[in] IsId The buffer to store IsId.\r
245\r
246 @retval EFI_SUCCESS The string converted successfully.\r
247 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
248\r
249**/\r
250EFI_STATUS\r
251IScsiConvertIsIdToString (\r
d1050b9d
MK
252 OUT CHAR16 *String,\r
253 IN UINT8 *IsId\r
4c5a5e0c 254 )\r
255{\r
d1050b9d
MK
256 UINT8 Index;\r
257 UINTN Number;\r
4c5a5e0c 258\r
259 if ((String == NULL) || (IsId == NULL)) {\r
260 return EFI_INVALID_PARAMETER;\r
261 }\r
262\r
263 for (Index = 0; Index < 6; Index++) {\r
264 if (IsId[Index] <= 0xF) {\r
265 Number = UnicodeSPrint (\r
266 String,\r
267 2 * ISID_CONFIGURABLE_STORAGE,\r
268 L"0%X",\r
d1050b9d 269 (UINTN)IsId[Index]\r
4c5a5e0c 270 );\r
271 } else {\r
272 Number = UnicodeSPrint (\r
273 String,\r
274 2 * ISID_CONFIGURABLE_STORAGE,\r
275 L"%X",\r
d1050b9d 276 (UINTN)IsId[Index]\r
4c5a5e0c 277 );\r
4c5a5e0c 278 }\r
279\r
280 String = String + Number;\r
281 }\r
282\r
283 *String = L'\0';\r
284\r
285 return EFI_SUCCESS;\r
286}\r
287\r
8d1f5e04
ZL
288/**\r
289 Get the Offset value specified by the input String.\r
290\r
291 @param[in] Configuration A null-terminated Unicode string in\r
292 <ConfigString> format.\r
293 @param[in] String The string is "&OFFSET=".\r
294 @param[out] Value The Offset value.\r
295\r
efb56593 296 @retval EFI_OUT_OF_RESOURCES Insufficient resources to store necessary\r
8d1f5e04
ZL
297 structures.\r
298 @retval EFI_SUCCESS Value of <Number> is outputted in Number\r
299 successfully.\r
300\r
301**/\r
302EFI_STATUS\r
303IScsiGetValue (\r
d1050b9d
MK
304 IN CONST EFI_STRING Configuration,\r
305 IN CHAR16 *String,\r
306 OUT UINTN *Value\r
8d1f5e04
ZL
307 )\r
308{\r
d1050b9d
MK
309 CHAR16 *StringPtr;\r
310 CHAR16 *TmpPtr;\r
311 CHAR16 *Str;\r
312 CHAR16 TmpStr[2];\r
313 UINTN Length;\r
314 UINTN Len;\r
315 UINTN Index;\r
316 UINT8 *Buf;\r
317 UINT8 DigitUint8;\r
318 EFI_STATUS Status;\r
8d1f5e04
ZL
319\r
320 //\r
321 // Get Value.\r
322 //\r
d1050b9d 323 Buf = NULL;\r
8d1f5e04 324 StringPtr = StrStr (Configuration, String);\r
d1050b9d 325 ASSERT (StringPtr != NULL);\r
8d1f5e04 326 StringPtr += StrLen (String);\r
d1050b9d 327 TmpPtr = StringPtr;\r
8d1f5e04
ZL
328\r
329 while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
d1050b9d 330 StringPtr++;\r
8d1f5e04 331 }\r
d1050b9d 332\r
8d1f5e04 333 Length = StringPtr - TmpPtr;\r
d1050b9d 334 Len = Length + 1;\r
8d1f5e04
ZL
335\r
336 Str = AllocateZeroPool (Len * sizeof (CHAR16));\r
337 if (Str == NULL) {\r
338 Status = EFI_OUT_OF_RESOURCES;\r
339 goto Exit;\r
340 }\r
341\r
342 CopyMem (Str, TmpPtr, Len * sizeof (CHAR16));\r
343 *(Str + Length) = L'\0';\r
344\r
345 Len = (Len + 1) / 2;\r
d1050b9d 346 Buf = (UINT8 *)AllocateZeroPool (Len);\r
8d1f5e04
ZL
347 if (Buf == NULL) {\r
348 Status = EFI_OUT_OF_RESOURCES;\r
349 goto Exit;\r
350 }\r
351\r
352 ZeroMem (TmpStr, sizeof (TmpStr));\r
d1050b9d
MK
353 for (Index = 0; Index < Length; Index++) {\r
354 TmpStr[0] = Str[Length - Index - 1];\r
355 DigitUint8 = (UINT8)StrHexToUint64 (TmpStr);\r
8d1f5e04 356 if ((Index & 1) == 0) {\r
d1050b9d 357 Buf[Index/2] = DigitUint8;\r
8d1f5e04 358 } else {\r
d1050b9d 359 Buf[Index/2] = (UINT8)((DigitUint8 << 4) + Buf[Index/2]);\r
8d1f5e04
ZL
360 }\r
361 }\r
362\r
363 *Value = 0;\r
364 CopyMem (\r
365 Value,\r
366 Buf,\r
367 (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)\r
368 );\r
369\r
370 FreePool (Buf);\r
371 Status = EFI_SUCCESS;\r
372\r
373Exit:\r
374 if (Str != NULL) {\r
375 FreePool (Str);\r
376 }\r
377\r
378 return Status;\r
379}\r
380\r
4c5a5e0c 381/**\r
382 Get the attempt config data from global structure by the ConfigIndex.\r
383\r
384 @param[in] AttemptConfigIndex The unique index indicates the attempt.\r
385\r
386 @return Pointer to the attempt config data.\r
387 @retval NULL The attempt configuration data cannot be found.\r
388\r
389**/\r
390ISCSI_ATTEMPT_CONFIG_NVDATA *\r
391IScsiConfigGetAttemptByConfigIndex (\r
d1050b9d 392 IN UINT8 AttemptConfigIndex\r
4c5a5e0c 393 )\r
394{\r
395 LIST_ENTRY *Entry;\r
396 ISCSI_ATTEMPT_CONFIG_NVDATA *Attempt;\r
397\r
398 NET_LIST_FOR_EACH (Entry, &mPrivate->AttemptConfigs) {\r
399 Attempt = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);\r
400 if (Attempt->AttemptConfigIndex == AttemptConfigIndex) {\r
401 return Attempt;\r
402 }\r
403 }\r
404\r
405 return NULL;\r
406}\r
407\r
4c5a5e0c 408/**\r
409 Get the existing attempt config data from global structure by the NicIndex.\r
410\r
411 @param[in] NewAttempt The created new attempt\r
412 @param[in] IScsiMode The IScsi Mode of the new attempt, Enabled or\r
413 Enabled for MPIO.\r
414\r
415 @return Pointer to the existing attempt config data which\r
416 has the same NICIndex as the new created attempt.\r
417 @retval NULL The attempt with NicIndex does not exist.\r
418\r
419**/\r
420ISCSI_ATTEMPT_CONFIG_NVDATA *\r
421IScsiConfigGetAttemptByNic (\r
d1050b9d
MK
422 IN ISCSI_ATTEMPT_CONFIG_NVDATA *NewAttempt,\r
423 IN UINT8 IScsiMode\r
4c5a5e0c 424 )\r
425{\r
426 LIST_ENTRY *Entry;\r
427 ISCSI_ATTEMPT_CONFIG_NVDATA *Attempt;\r
428\r
429 NET_LIST_FOR_EACH (Entry, &mPrivate->AttemptConfigs) {\r
430 Attempt = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);\r
d1050b9d
MK
431 if ((Attempt != NewAttempt) && (Attempt->NicIndex == NewAttempt->NicIndex) &&\r
432 (Attempt->SessionConfigData.Enabled == IScsiMode))\r
433 {\r
4c5a5e0c 434 return Attempt;\r
435 }\r
436 }\r
437\r
438 return NULL;\r
439}\r
440\r
8d1f5e04
ZL
441/**\r
442 Extract the Index of the attempt list.\r
443\r
444 @param[in] AttemptNameList The Name list of the Attempts.\r
445 @param[out] AttemptIndexList The Index list of the Attempts.\r
446 @param[in] IsAddAttempts If TRUE, Indicates add one or more attempts.\r
447 If FALSE, Indicates delete attempts or change attempt order.\r
448\r
449 @retval EFI_SUCCESS The Attempt list is valid.\r
450 @retval EFI_INVALID_PARAMETERS The Attempt List is invalid.\r
451\r
452**/\r
453EFI_STATUS\r
454IScsiGetAttemptIndexList (\r
d1050b9d
MK
455 IN CHAR16 *AttemptNameList,\r
456 OUT UINT8 *AttemptIndexList,\r
457 IN BOOLEAN IsAddAttempts\r
458 )\r
8d1f5e04 459{\r
d1050b9d
MK
460 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;\r
461 CHAR16 *AttemptStr;\r
462 UINT8 AttemptIndex;\r
463 UINTN Len;\r
464 UINTN Index;\r
8d1f5e04
ZL
465\r
466 Index = 0;\r
467\r
468 if ((AttemptNameList == NULL) || (*AttemptNameList == L'\0')) {\r
469 return EFI_INVALID_PARAMETER;\r
470 }\r
471\r
472 AttemptStr = AttemptNameList;\r
d1050b9d 473 Len = StrLen (L"attempt:");\r
8d1f5e04
ZL
474\r
475 while (*AttemptStr != L'\0') {\r
476 AttemptStr = StrStr (AttemptStr, L"attempt:");\r
477 if (AttemptStr == NULL) {\r
478 return EFI_INVALID_PARAMETER;\r
479 }\r
d1050b9d
MK
480\r
481 AttemptStr += Len;\r
482 AttemptIndex = (UINT8)(*AttemptStr - L'0');\r
483 AttemptConfigData = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);\r
8d1f5e04
ZL
484 if (IsAddAttempts) {\r
485 if ((AttemptConfigData != NULL) || ((AttemptIndex) > PcdGet8 (PcdMaxIScsiAttemptNumber))) {\r
486 return EFI_INVALID_PARAMETER;\r
487 }\r
488 } else {\r
489 if (AttemptConfigData == NULL) {\r
490 return EFI_INVALID_PARAMETER;\r
491 }\r
492 }\r
493\r
494 AttemptIndexList[Index] = AttemptIndex;\r
d1050b9d 495 Index++;\r
8d1f5e04
ZL
496 AttemptStr += 2;\r
497 }\r
d1050b9d 498\r
8d1f5e04
ZL
499 return EFI_SUCCESS;\r
500}\r
4c5a5e0c 501\r
502/**\r
503 Convert the iSCSI configuration data into the IFR data.\r
504\r
505 @param[in] Attempt The iSCSI attempt config data.\r
506 @param[in, out] IfrNvData The IFR nv data.\r
507\r
508**/\r
509VOID\r
510IScsiConvertAttemptConfigDataToIfrNvData (\r
511 IN ISCSI_ATTEMPT_CONFIG_NVDATA *Attempt,\r
512 IN OUT ISCSI_CONFIG_IFR_NVDATA *IfrNvData\r
513 )\r
514{\r
d1050b9d
MK
515 ISCSI_SESSION_CONFIG_NVDATA *SessionConfigData;\r
516 ISCSI_CHAP_AUTH_CONFIG_NVDATA *AuthConfigData;\r
517 EFI_IP_ADDRESS Ip;\r
518 BOOLEAN DnsMode;\r
4c5a5e0c 519\r
520 //\r
521 // Normal session configuration parameters.\r
522 //\r
d1050b9d
MK
523 SessionConfigData = &Attempt->SessionConfigData;\r
524 IfrNvData->Enabled = SessionConfigData->Enabled;\r
525 IfrNvData->IpMode = SessionConfigData->IpMode;\r
526 DnsMode = SessionConfigData->DnsMode;\r
4c5a5e0c 527\r
d1050b9d
MK
528 IfrNvData->InitiatorInfoFromDhcp = SessionConfigData->InitiatorInfoFromDhcp;\r
529 IfrNvData->TargetInfoFromDhcp = SessionConfigData->TargetInfoFromDhcp;\r
530 IfrNvData->TargetPort = SessionConfigData->TargetPort;\r
4c5a5e0c 531\r
532 if (IfrNvData->IpMode == IP_MODE_IP4) {\r
533 CopyMem (&Ip.v4, &SessionConfigData->LocalIp, sizeof (EFI_IPv4_ADDRESS));\r
534 IScsiIpToStr (&Ip, FALSE, IfrNvData->LocalIp);\r
535 CopyMem (&Ip.v4, &SessionConfigData->SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
536 IScsiIpToStr (&Ip, FALSE, IfrNvData->SubnetMask);\r
537 CopyMem (&Ip.v4, &SessionConfigData->Gateway, sizeof (EFI_IPv4_ADDRESS));\r
538 IScsiIpToStr (&Ip, FALSE, IfrNvData->Gateway);\r
5e146cd9 539 ZeroMem (IfrNvData->TargetIp, sizeof (IfrNvData->TargetIp));\r
eabc6e59
ZL
540 if (SessionConfigData->TargetIp.v4.Addr[0] != '\0') {\r
541 CopyMem (&Ip.v4, &SessionConfigData->TargetIp, sizeof (EFI_IPv4_ADDRESS));\r
542 IScsiIpToStr (&Ip, FALSE, IfrNvData->TargetIp);\r
543 }\r
4c5a5e0c 544 } else if (IfrNvData->IpMode == IP_MODE_IP6) {\r
545 ZeroMem (IfrNvData->TargetIp, sizeof (IfrNvData->TargetIp));\r
eabc6e59
ZL
546 if (SessionConfigData->TargetIp.v6.Addr[0] != '\0') {\r
547 IP6_COPY_ADDRESS (&Ip.v6, &SessionConfigData->TargetIp);\r
548 IScsiIpToStr (&Ip, TRUE, IfrNvData->TargetIp);\r
549 }\r
4c5a5e0c 550 }\r
551\r
b9679cd7
SZ
552 AsciiStrToUnicodeStrS (\r
553 SessionConfigData->TargetName,\r
554 IfrNvData->TargetName,\r
555 sizeof (IfrNvData->TargetName) / sizeof (IfrNvData->TargetName[0])\r
556 );\r
eabc6e59
ZL
557\r
558 if (DnsMode) {\r
559 AsciiStrToUnicodeStrS (\r
560 SessionConfigData->TargetUrl,\r
561 IfrNvData->TargetIp,\r
562 sizeof (IfrNvData->TargetIp) / sizeof (IfrNvData->TargetIp[0])\r
563 );\r
564 }\r
565\r
4c5a5e0c 566 IScsiLunToUnicodeStr (SessionConfigData->BootLun, IfrNvData->BootLun);\r
567 IScsiConvertIsIdToString (IfrNvData->IsId, SessionConfigData->IsId);\r
568\r
569 IfrNvData->ConnectRetryCount = SessionConfigData->ConnectRetryCount;\r
570 IfrNvData->ConnectTimeout = SessionConfigData->ConnectTimeout;\r
571\r
572 //\r
573 // Authentication parameters.\r
574 //\r
575 IfrNvData->AuthenticationType = Attempt->AuthenticationType;\r
576\r
577 if (IfrNvData->AuthenticationType == ISCSI_AUTH_TYPE_CHAP) {\r
578 AuthConfigData = &Attempt->AuthConfigData.CHAP;\r
579 IfrNvData->CHAPType = AuthConfigData->CHAPType;\r
b9679cd7
SZ
580 AsciiStrToUnicodeStrS (\r
581 AuthConfigData->CHAPName,\r
582 IfrNvData->CHAPName,\r
583 sizeof (IfrNvData->CHAPName) / sizeof (IfrNvData->CHAPName[0])\r
584 );\r
585 AsciiStrToUnicodeStrS (\r
586 AuthConfigData->CHAPSecret,\r
587 IfrNvData->CHAPSecret,\r
588 sizeof (IfrNvData->CHAPSecret) / sizeof (IfrNvData->CHAPSecret[0])\r
589 );\r
590 AsciiStrToUnicodeStrS (\r
591 AuthConfigData->ReverseCHAPName,\r
592 IfrNvData->ReverseCHAPName,\r
593 sizeof (IfrNvData->ReverseCHAPName) / sizeof (IfrNvData->ReverseCHAPName[0])\r
594 );\r
595 AsciiStrToUnicodeStrS (\r
596 AuthConfigData->ReverseCHAPSecret,\r
597 IfrNvData->ReverseCHAPSecret,\r
598 sizeof (IfrNvData->ReverseCHAPSecret) / sizeof (IfrNvData->ReverseCHAPSecret[0])\r
599 );\r
4c5a5e0c 600 }\r
601\r
602 //\r
603 // Other parameters.\r
604 //\r
b9679cd7
SZ
605 AsciiStrToUnicodeStrS (\r
606 Attempt->AttemptName,\r
607 IfrNvData->AttemptName,\r
608 sizeof (IfrNvData->AttemptName) / sizeof (IfrNvData->AttemptName[0])\r
609 );\r
4c5a5e0c 610}\r
611\r
8d1f5e04
ZL
612/**\r
613 Convert the iSCSI configuration data into the IFR data Which will be used\r
614 to extract the iSCSI Keyword configuration in <ConfigAltResp> format.\r
615\r
616 @param[in, out] IfrNvData The IFR nv data.\r
617\r
618**/\r
619VOID\r
620EFIAPI\r
621IScsiConvertAttemptConfigDataToIfrNvDataByKeyword (\r
622 IN OUT ISCSI_CONFIG_IFR_NVDATA *IfrNvData\r
623 )\r
624{\r
d1050b9d
MK
625 LIST_ENTRY *Entry;\r
626 ISCSI_ATTEMPT_CONFIG_NVDATA *Attempt;\r
627 ISCSI_SESSION_CONFIG_NVDATA *SessionConfigData;\r
628 ISCSI_CHAP_AUTH_CONFIG_NVDATA *AuthConfigData;\r
629 CHAR16 AttemptNameList[ATTEMPT_NAME_LIST_SIZE];\r
630 ISCSI_NIC_INFO *NicInfo;\r
631 CHAR16 MacString[ISCSI_MAX_MAC_STRING_LEN];\r
632 EFI_IP_ADDRESS Ip;\r
633 UINTN Index;\r
634 UINTN StringLen;\r
8d1f5e04 635\r
12b04866 636 NicInfo = NULL;\r
8d1f5e04
ZL
637 ZeroMem (AttemptNameList, sizeof (AttemptNameList));\r
638\r
2fd40fa5
ZL
639 if ((mPrivate != NULL) && (mPrivate->AttemptCount != 0)) {\r
640 NET_LIST_FOR_EACH (Entry, &mPrivate->AttemptConfigs) {\r
641 Attempt = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);\r
642 //\r
643 // Normal session configuration parameters.\r
644 //\r
d1050b9d 645 SessionConfigData = &Attempt->SessionConfigData;\r
8d1f5e04 646\r
2fd40fa5 647 ASSERT ((Attempt->AttemptConfigIndex > 0) && (Attempt->AttemptConfigIndex <= FixedPcdGet8 (PcdMaxIScsiAttemptNumber)));\r
d1050b9d 648 Index = Attempt->AttemptConfigIndex - 1;\r
8d1f5e04 649\r
2fd40fa5
ZL
650 //\r
651 // Save the attempt to AttemptNameList as Attempt:1 Attempt:2\r
652 //\r
653 AsciiStrToUnicodeStrS (\r
654 Attempt->AttemptName,\r
655 AttemptNameList + StrLen (AttemptNameList),\r
656 ATTEMPT_NAME_LIST_SIZE - StrLen (AttemptNameList)\r
d1050b9d 657 );\r
8d1f5e04 658\r
2fd40fa5
ZL
659 StringLen = StrLen (AttemptNameList);\r
660 ASSERT (StringLen > 2);\r
661 *(AttemptNameList + StringLen - 2) = L':';\r
662 *(AttemptNameList + StringLen) = L' ';\r
8d1f5e04 663\r
2fd40fa5
ZL
664 AsciiStrToUnicodeStrS (\r
665 Attempt->AttemptName,\r
666 IfrNvData->ISCSIAttemptName + ATTEMPT_NAME_SIZE * Index,\r
667 ATTEMPT_NAME_LIST_SIZE - ATTEMPT_NAME_SIZE * Index\r
d1050b9d 668 );\r
8d1f5e04 669\r
d1050b9d
MK
670 IfrNvData->ISCSIBootEnableList[Index] = SessionConfigData->Enabled;\r
671 IfrNvData->ISCSIIpAddressTypeList[Index] = SessionConfigData->IpMode;\r
2fd40fa5 672\r
d1050b9d
MK
673 IfrNvData->ISCSIInitiatorInfoViaDHCP[Index] = SessionConfigData->InitiatorInfoFromDhcp;\r
674 IfrNvData->ISCSITargetInfoViaDHCP[Index] = SessionConfigData->TargetInfoFromDhcp;\r
675 IfrNvData->ISCSIConnectRetry[Index] = SessionConfigData->ConnectRetryCount;\r
676 IfrNvData->ISCSIConnectTimeout[Index] = SessionConfigData->ConnectTimeout;\r
677 IfrNvData->ISCSITargetTcpPort[Index] = SessionConfigData->TargetPort;\r
2fd40fa5
ZL
678\r
679 if (SessionConfigData->IpMode == IP_MODE_IP4) {\r
680 CopyMem (&Ip.v4, &SessionConfigData->LocalIp, sizeof (EFI_IPv4_ADDRESS));\r
681 IScsiIpToStr (&Ip, FALSE, IfrNvData->Keyword[Index].ISCSIInitiatorIpAddress);\r
682 CopyMem (&Ip.v4, &SessionConfigData->SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
683 IScsiIpToStr (&Ip, FALSE, IfrNvData->Keyword[Index].ISCSIInitiatorNetmask);\r
684 CopyMem (&Ip.v4, &SessionConfigData->Gateway, sizeof (EFI_IPv4_ADDRESS));\r
685 IScsiIpToStr (&Ip, FALSE, IfrNvData->Keyword[Index].ISCSIInitiatorGateway);\r
686 if (SessionConfigData->TargetIp.v4.Addr[0] != '\0') {\r
687 CopyMem (&Ip.v4, &SessionConfigData->TargetIp, sizeof (EFI_IPv4_ADDRESS));\r
688 IScsiIpToStr (&Ip, FALSE, IfrNvData->Keyword[Index].ISCSITargetIpAddress);\r
689 }\r
690 } else if (SessionConfigData->IpMode == IP_MODE_IP6) {\r
691 ZeroMem (IfrNvData->Keyword[Index].ISCSITargetIpAddress, sizeof (IfrNvData->TargetIp));\r
692 if (SessionConfigData->TargetIp.v6.Addr[0] != '\0') {\r
693 IP6_COPY_ADDRESS (&Ip.v6, &SessionConfigData->TargetIp);\r
694 IScsiIpToStr (&Ip, TRUE, IfrNvData->Keyword[Index].ISCSITargetIpAddress);\r
695 }\r
696 }\r
697\r
8d1f5e04 698 AsciiStrToUnicodeStrS (\r
2fd40fa5
ZL
699 SessionConfigData->TargetName,\r
700 IfrNvData->Keyword[Index].ISCSITargetName,\r
701 ISCSI_NAME_MAX_SIZE\r
8d1f5e04 702 );\r
8d1f5e04 703\r
2fd40fa5
ZL
704 if (SessionConfigData->DnsMode) {\r
705 AsciiStrToUnicodeStrS (\r
706 SessionConfigData->TargetUrl,\r
12b04866
ZL
707 IfrNvData->Keyword[Index].ISCSITargetIpAddress,\r
708 sizeof (IfrNvData->Keyword[Index].ISCSITargetIpAddress) / sizeof (IfrNvData->Keyword[Index].ISCSITargetIpAddress[0])\r
2fd40fa5
ZL
709 );\r
710 }\r
8d1f5e04 711\r
2fd40fa5
ZL
712 IScsiLunToUnicodeStr (SessionConfigData->BootLun, IfrNvData->Keyword[Index].ISCSILun);\r
713 IScsiConvertIsIdToString (IfrNvData->Keyword[Index].ISCSIIsId, SessionConfigData->IsId);\r
8d1f5e04 714\r
d1050b9d 715 IfrNvData->ISCSIAuthenticationMethod[Index] = Attempt->AuthenticationType;\r
8d1f5e04 716\r
2fd40fa5 717 if (Attempt->AuthenticationType == ISCSI_AUTH_TYPE_CHAP) {\r
d1050b9d 718 AuthConfigData = &Attempt->AuthConfigData.CHAP;\r
2fd40fa5
ZL
719 IfrNvData->ISCSIChapType[Index] = AuthConfigData->CHAPType;\r
720 AsciiStrToUnicodeStrS (\r
721 AuthConfigData->CHAPName,\r
722 IfrNvData->Keyword[Index].ISCSIChapUsername,\r
723 ISCSI_CHAP_NAME_STORAGE\r
724 );\r
8d1f5e04 725\r
2fd40fa5
ZL
726 AsciiStrToUnicodeStrS (\r
727 AuthConfigData->CHAPSecret,\r
728 IfrNvData->Keyword[Index].ISCSIChapSecret,\r
729 ISCSI_CHAP_SECRET_STORAGE\r
730 );\r
8d1f5e04 731\r
2fd40fa5
ZL
732 AsciiStrToUnicodeStrS (\r
733 AuthConfigData->ReverseCHAPName,\r
734 IfrNvData->Keyword[Index].ISCSIReverseChapUsername,\r
735 ISCSI_CHAP_NAME_STORAGE\r
736 );\r
737\r
738 AsciiStrToUnicodeStrS (\r
739 AuthConfigData->ReverseCHAPSecret,\r
740 IfrNvData->Keyword[Index].ISCSIReverseChapSecret,\r
741 ISCSI_CHAP_SECRET_STORAGE\r
742 );\r
743 }\r
8d1f5e04 744 }\r
d1050b9d 745 CopyMem (IfrNvData->ISCSIDisplayAttemptList, AttemptNameList, ATTEMPT_NAME_LIST_SIZE);\r
12b04866 746\r
fbfe6420 747 ZeroMem (IfrNvData->ISCSIMacAddr, sizeof (IfrNvData->ISCSIMacAddr));\r
b28bf414
ZL
748 NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {\r
749 NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);\r
750 IScsiMacAddrToStr (\r
fbfe6420
FS
751 &NicInfo->PermanentAddress,\r
752 NicInfo->HwAddressSize,\r
753 NicInfo->VlanId,\r
754 MacString\r
755 );\r
b28bf414
ZL
756 CopyMem (\r
757 IfrNvData->ISCSIMacAddr + StrLen (IfrNvData->ISCSIMacAddr),\r
758 MacString,\r
759 StrLen (MacString) * sizeof (CHAR16)\r
760 );\r
12b04866 761\r
b28bf414 762 *(IfrNvData->ISCSIMacAddr + StrLen (IfrNvData->ISCSIMacAddr)) = L'/';\r
fbfe6420 763 }\r
b68c7931
HW
764\r
765 StringLen = StrLen (IfrNvData->ISCSIMacAddr);\r
766 if (StringLen > 0) {\r
767 *(IfrNvData->ISCSIMacAddr + StringLen - 1) = L'\0';\r
fbfe6420 768 }\r
b28bf414 769 }\r
8d1f5e04
ZL
770}\r
771\r
4c5a5e0c 772/**\r
773 Convert the IFR data to iSCSI configuration data.\r
774\r
c0d494b5 775 @param[in] IfrNvData Point to ISCSI_CONFIG_IFR_NVDATA.\r
4c5a5e0c 776 @param[in, out] Attempt The iSCSI attempt config data.\r
777\r
778 @retval EFI_INVALID_PARAMETER Any input or configured parameter is invalid.\r
779 @retval EFI_NOT_FOUND Cannot find the corresponding variable.\r
c0d494b5 780 @retval EFI_OUT_OF_RESOURCES The operation is failed due to lack of resources.\r
781 @retval EFI_ABORTED The operation is aborted.\r
4c5a5e0c 782 @retval EFI_SUCCESS The operation is completed successfully.\r
783\r
784**/\r
785EFI_STATUS\r
786IScsiConvertIfrNvDataToAttemptConfigData (\r
787 IN ISCSI_CONFIG_IFR_NVDATA *IfrNvData,\r
788 IN OUT ISCSI_ATTEMPT_CONFIG_NVDATA *Attempt\r
789 )\r
790{\r
d1050b9d
MK
791 EFI_IP_ADDRESS HostIp;\r
792 EFI_IP_ADDRESS SubnetMask;\r
793 EFI_IP_ADDRESS Gateway;\r
794 CHAR16 *MacString;\r
795 CHAR16 *AttemptName1;\r
796 CHAR16 *AttemptName2;\r
797 ISCSI_ATTEMPT_CONFIG_NVDATA *ExistAttempt;\r
798 ISCSI_ATTEMPT_CONFIG_NVDATA *SameNicAttempt;\r
799 CHAR16 IScsiMode[64];\r
800 CHAR16 IpMode[64];\r
801 ISCSI_NIC_INFO *NicInfo;\r
802 EFI_INPUT_KEY Key;\r
803 UINT8 *AttemptConfigOrder;\r
804 UINTN AttemptConfigOrderSize;\r
805 UINT8 *AttemptOrderTmp;\r
806 UINTN TotalNumber;\r
807 EFI_STATUS Status;\r
808\r
809 if ((IfrNvData == NULL) || (Attempt == NULL)) {\r
4c5a5e0c 810 return EFI_INVALID_PARAMETER;\r
811 }\r
812\r
813 //\r
814 // Update those fields which don't have INTERACTIVE attribute.\r
815 //\r
d1050b9d
MK
816 Attempt->SessionConfigData.ConnectRetryCount = IfrNvData->ConnectRetryCount;\r
817 Attempt->SessionConfigData.ConnectTimeout = IfrNvData->ConnectTimeout;\r
818 Attempt->SessionConfigData.IpMode = IfrNvData->IpMode;\r
4c5a5e0c 819\r
820 if (IfrNvData->IpMode < IP_MODE_AUTOCONFIG) {\r
821 Attempt->SessionConfigData.InitiatorInfoFromDhcp = IfrNvData->InitiatorInfoFromDhcp;\r
822 Attempt->SessionConfigData.TargetPort = IfrNvData->TargetPort;\r
823\r
824 if (Attempt->SessionConfigData.TargetPort == 0) {\r
825 Attempt->SessionConfigData.TargetPort = ISCSI_WELL_KNOWN_PORT;\r
826 }\r
827\r
828 Attempt->SessionConfigData.TargetInfoFromDhcp = IfrNvData->TargetInfoFromDhcp;\r
829 }\r
830\r
831 Attempt->AuthenticationType = IfrNvData->AuthenticationType;\r
832\r
833 if (Attempt->AuthenticationType == ISCSI_AUTH_TYPE_CHAP) {\r
834 Attempt->AuthConfigData.CHAP.CHAPType = IfrNvData->CHAPType;\r
835 }\r
836\r
837 //\r
838 // Only do full parameter validation if iSCSI is enabled on this device.\r
839 //\r
840 if (IfrNvData->Enabled != ISCSI_DISABLED) {\r
841 if (Attempt->SessionConfigData.ConnectTimeout < CONNECT_MIN_TIMEOUT) {\r
842 CreatePopUp (\r
843 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
844 &Key,\r
845 L"Connection Establishing Timeout is less than minimum value 100ms.",\r
846 NULL\r
847 );\r
8d1f5e04 848\r
4c5a5e0c 849 return EFI_INVALID_PARAMETER;\r
850 }\r
851\r
852 //\r
853 // Validate the address configuration of the Initiator if DHCP isn't\r
854 // deployed.\r
855 //\r
856 if (!Attempt->SessionConfigData.InitiatorInfoFromDhcp) {\r
857 CopyMem (&HostIp.v4, &Attempt->SessionConfigData.LocalIp, sizeof (HostIp.v4));\r
858 CopyMem (&SubnetMask.v4, &Attempt->SessionConfigData.SubnetMask, sizeof (SubnetMask.v4));\r
859 CopyMem (&Gateway.v4, &Attempt->SessionConfigData.Gateway, sizeof (Gateway.v4));\r
860\r
861 if ((Gateway.Addr[0] != 0)) {\r
862 if (SubnetMask.Addr[0] == 0) {\r
863 CreatePopUp (\r
864 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
865 &Key,\r
866 L"Gateway address is set but subnet mask is zero.",\r
867 NULL\r
868 );\r
8d1f5e04 869\r
4c5a5e0c 870 return EFI_INVALID_PARAMETER;\r
871 } else if (!IP4_NET_EQUAL (HostIp.Addr[0], Gateway.Addr[0], SubnetMask.Addr[0])) {\r
872 CreatePopUp (\r
873 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
874 &Key,\r
875 L"Local IP and Gateway are not in the same subnet.",\r
876 NULL\r
877 );\r
8d1f5e04 878\r
4c5a5e0c 879 return EFI_INVALID_PARAMETER;\r
880 }\r
881 }\r
882 }\r
d1050b9d 883\r
4c5a5e0c 884 //\r
885 // Validate target configuration if DHCP isn't deployed.\r
886 //\r
d1050b9d 887 if (!Attempt->SessionConfigData.TargetInfoFromDhcp && (Attempt->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG)) {\r
eabc6e59
ZL
888 if (!Attempt->SessionConfigData.DnsMode) {\r
889 if (!IpIsUnicast (&Attempt->SessionConfigData.TargetIp, IfrNvData->IpMode)) {\r
890 CreatePopUp (\r
891 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
892 &Key,\r
893 L"Target IP is invalid!",\r
894 NULL\r
895 );\r
896 return EFI_INVALID_PARAMETER;\r
897 }\r
898 } else {\r
899 if (Attempt->SessionConfigData.TargetUrl[0] == '\0') {\r
900 CreatePopUp (\r
901 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
902 &Key,\r
903 L"iSCSI target Url should not be NULL!",\r
904 NULL\r
905 );\r
906 return EFI_INVALID_PARAMETER;\r
907 }\r
4c5a5e0c 908 }\r
b2220321
YT
909\r
910 //\r
911 // Validate iSCSI target name configuration again:\r
912 // The format of iSCSI target name is already verified in IScsiFormCallback() when\r
913 // user input the name; here we only check the case user does not input the name.\r
914 //\r
915 if (Attempt->SessionConfigData.TargetName[0] == '\0') {\r
916 CreatePopUp (\r
917 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
918 &Key,\r
919 L"iSCSI target name is NULL!",\r
920 NULL\r
921 );\r
922 return EFI_INVALID_PARAMETER;\r
923 }\r
4c5a5e0c 924 }\r
b2220321 925\r
4c5a5e0c 926 //\r
927 // Validate the authentication info.\r
928 //\r
929 if (IfrNvData->AuthenticationType == ISCSI_AUTH_TYPE_CHAP) {\r
930 if ((IfrNvData->CHAPName[0] == '\0') || (IfrNvData->CHAPSecret[0] == '\0')) {\r
931 CreatePopUp (\r
932 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
933 &Key,\r
934 L"CHAP Name or CHAP Secret is invalid!",\r
935 NULL\r
936 );\r
f75a7f56 937\r
4c5a5e0c 938 return EFI_INVALID_PARAMETER;\r
939 }\r
940\r
941 if ((IfrNvData->CHAPType == ISCSI_CHAP_MUTUAL) &&\r
942 ((IfrNvData->ReverseCHAPName[0] == '\0') || (IfrNvData->ReverseCHAPSecret[0] == '\0'))\r
d1050b9d
MK
943 )\r
944 {\r
4c5a5e0c 945 CreatePopUp (\r
946 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
947 &Key,\r
948 L"Reverse CHAP Name or Reverse CHAP Secret is invalid!",\r
949 NULL\r
f75a7f56 950 );\r
4c5a5e0c 951 return EFI_INVALID_PARAMETER;\r
952 }\r
953 }\r
954\r
955 //\r
956 // Check whether this attempt uses NIC which is already used by existing attempt.\r
957 //\r
958 SameNicAttempt = IScsiConfigGetAttemptByNic (Attempt, IfrNvData->Enabled);\r
959 if (SameNicAttempt != NULL) {\r
d1050b9d 960 AttemptName1 = (CHAR16 *)AllocateZeroPool (ATTEMPT_NAME_SIZE * sizeof (CHAR16));\r
4c5a5e0c 961 if (AttemptName1 == NULL) {\r
962 return EFI_OUT_OF_RESOURCES;\r
963 }\r
964\r
d1050b9d 965 AttemptName2 = (CHAR16 *)AllocateZeroPool (ATTEMPT_NAME_SIZE * sizeof (CHAR16));\r
4c5a5e0c 966 if (AttemptName2 == NULL) {\r
967 FreePool (AttemptName1);\r
968 return EFI_OUT_OF_RESOURCES;\r
f75a7f56 969 }\r
4c5a5e0c 970\r
8d1f5e04
ZL
971 AsciiStrToUnicodeStrS (Attempt->AttemptName, AttemptName1, ATTEMPT_NAME_SIZE);\r
972 AsciiStrToUnicodeStrS (SameNicAttempt->AttemptName, AttemptName2, ATTEMPT_NAME_SIZE);\r
4c5a5e0c 973\r
974 UnicodeSPrint (\r
975 mPrivate->PortString,\r
d1050b9d 976 (UINTN)ISCSI_NAME_IFR_MAX_SIZE,\r
4c5a5e0c 977 L"Warning! Attempt \"%s\" uses same NIC as Attempt \"%s\".",\r
978 AttemptName1,\r
979 AttemptName2\r
980 );\r
981\r
982 CreatePopUp (\r
983 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
984 &Key,\r
985 mPrivate->PortString,\r
986 NULL\r
f75a7f56 987 );\r
4c5a5e0c 988\r
989 FreePool (AttemptName1);\r
990 FreePool (AttemptName2);\r
991 }\r
992 }\r
993\r
c0d494b5 994 //\r
995 // Update the iSCSI Mode data and record it in attempt help info.\r
996 //\r
c0d494b5 997 if (IfrNvData->Enabled == ISCSI_DISABLED) {\r
998 UnicodeSPrint (IScsiMode, 64, L"Disabled");\r
999 } else if (IfrNvData->Enabled == ISCSI_ENABLED) {\r
1000 UnicodeSPrint (IScsiMode, 64, L"Enabled");\r
1001 } else if (IfrNvData->Enabled == ISCSI_ENABLED_FOR_MPIO) {\r
1002 UnicodeSPrint (IScsiMode, 64, L"Enabled for MPIO");\r
1003 }\r
1004\r
1005 if (IfrNvData->IpMode == IP_MODE_IP4) {\r
1006 UnicodeSPrint (IpMode, 64, L"IP4");\r
1007 } else if (IfrNvData->IpMode == IP_MODE_IP6) {\r
1008 UnicodeSPrint (IpMode, 64, L"IP6");\r
1009 } else if (IfrNvData->IpMode == IP_MODE_AUTOCONFIG) {\r
1010 UnicodeSPrint (IpMode, 64, L"Autoconfigure");\r
1011 }\r
1012\r
1013 NicInfo = IScsiGetNicInfoByIndex (Attempt->NicIndex);\r
1014 if (NicInfo == NULL) {\r
1015 return EFI_NOT_FOUND;\r
1016 }\r
1017\r
d1050b9d 1018 MacString = (CHAR16 *)AllocateZeroPool (ISCSI_MAX_MAC_STRING_LEN * sizeof (CHAR16));\r
c0d494b5 1019 if (MacString == NULL) {\r
1020 return EFI_OUT_OF_RESOURCES;\r
1021 }\r
1022\r
b522ca0c 1023 AsciiStrToUnicodeStrS (Attempt->MacString, MacString, ISCSI_MAX_MAC_STRING_LEN);\r
c0d494b5 1024\r
1025 UnicodeSPrint (\r
1026 mPrivate->PortString,\r
d1050b9d 1027 (UINTN)ISCSI_NAME_IFR_MAX_SIZE,\r
c0d494b5 1028 L"MAC: %s, PFA: Bus %d | Dev %d | Func %d, iSCSI mode: %s, IP version: %s",\r
1029 MacString,\r
1030 NicInfo->BusNumber,\r
1031 NicInfo->DeviceNumber,\r
1032 NicInfo->FunctionNumber,\r
1033 IScsiMode,\r
1034 IpMode\r
1035 );\r
1036\r
1037 Attempt->AttemptTitleHelpToken = HiiSetString (\r
1038 mCallbackInfo->RegisteredHandle,\r
1039 Attempt->AttemptTitleHelpToken,\r
1040 mPrivate->PortString,\r
1041 NULL\r
1042 );\r
1043 if (Attempt->AttemptTitleHelpToken == 0) {\r
1044 FreePool (MacString);\r
1045 return EFI_OUT_OF_RESOURCES;\r
1046 }\r
1047\r
4c5a5e0c 1048 //\r
1049 // Check whether this attempt is an existing one.\r
1050 //\r
1051 ExistAttempt = IScsiConfigGetAttemptByConfigIndex (Attempt->AttemptConfigIndex);\r
1052 if (ExistAttempt != NULL) {\r
1053 ASSERT (ExistAttempt == Attempt);\r
1054\r
d1050b9d
MK
1055 if ((IfrNvData->Enabled == ISCSI_DISABLED) &&\r
1056 (Attempt->SessionConfigData.Enabled != ISCSI_DISABLED))\r
1057 {\r
4c5a5e0c 1058 //\r
1059 // User updates the Attempt from "Enabled"/"Enabled for MPIO" to "Disabled".\r
1060 //\r
1061 if (Attempt->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO) {\r
1062 if (mPrivate->MpioCount < 1) {\r
1063 return EFI_ABORTED;\r
1064 }\r
1065\r
1066 if (--mPrivate->MpioCount == 0) {\r
1067 mPrivate->EnableMpio = FALSE;\r
1068 }\r
1069 } else if (Attempt->SessionConfigData.Enabled == ISCSI_ENABLED) {\r
1070 if (mPrivate->SinglePathCount < 1) {\r
1071 return EFI_ABORTED;\r
1072 }\r
d1050b9d 1073\r
4c5a5e0c 1074 mPrivate->SinglePathCount--;\r
1075 }\r
d1050b9d
MK
1076 } else if ((IfrNvData->Enabled == ISCSI_ENABLED_FOR_MPIO) &&\r
1077 (Attempt->SessionConfigData.Enabled == ISCSI_ENABLED))\r
1078 {\r
4c5a5e0c 1079 //\r
1080 // User updates the Attempt from "Enabled" to "Enabled for MPIO".\r
1081 //\r
1082 if (mPrivate->SinglePathCount < 1) {\r
1083 return EFI_ABORTED;\r
1084 }\r
1085\r
1086 mPrivate->EnableMpio = TRUE;\r
1087 mPrivate->MpioCount++;\r
1088 mPrivate->SinglePathCount--;\r
d1050b9d
MK
1089 } else if ((IfrNvData->Enabled == ISCSI_ENABLED) &&\r
1090 (Attempt->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO))\r
1091 {\r
4c5a5e0c 1092 //\r
1093 // User updates the Attempt from "Enabled for MPIO" to "Enabled".\r
1094 //\r
1095 if (mPrivate->MpioCount < 1) {\r
1096 return EFI_ABORTED;\r
1097 }\r
1098\r
1099 if (--mPrivate->MpioCount == 0) {\r
1100 mPrivate->EnableMpio = FALSE;\r
1101 }\r
4c5a5e0c 1102\r
d1050b9d
MK
1103 mPrivate->SinglePathCount++;\r
1104 } else if ((IfrNvData->Enabled != ISCSI_DISABLED) &&\r
1105 (Attempt->SessionConfigData.Enabled == ISCSI_DISABLED))\r
1106 {\r
4c5a5e0c 1107 //\r
1108 // User updates the Attempt from "Disabled" to "Enabled"/"Enabled for MPIO".\r
1109 //\r
1110 if (IfrNvData->Enabled == ISCSI_ENABLED_FOR_MPIO) {\r
1111 mPrivate->EnableMpio = TRUE;\r
1112 mPrivate->MpioCount++;\r
4c5a5e0c 1113 } else if (IfrNvData->Enabled == ISCSI_ENABLED) {\r
1114 mPrivate->SinglePathCount++;\r
1115 }\r
1116 }\r
c0d494b5 1117 } else if (ExistAttempt == NULL) {\r
1118 //\r
1119 // When a new attempt is created, pointer of the attempt is saved to\r
8d1f5e04
ZL
1120 // mCallbackInfo->Current in IScsiConfigProcessDefault. If input Attempt\r
1121 // does not match any existing attempt, it should be a new created attempt.\r
1122 // Save it to system now.\r
1123 //\r
c0d494b5 1124\r
1125 //\r
1126 // Save current order number for this attempt.\r
1127 //\r
1128 AttemptConfigOrder = IScsiGetVariableAndSize (\r
1129 L"AttemptOrder",\r
9bdc6592 1130 &gIScsiConfigGuid,\r
c0d494b5 1131 &AttemptConfigOrderSize\r
1132 );\r
1133\r
1134 TotalNumber = AttemptConfigOrderSize / sizeof (UINT8);\r
1135 TotalNumber++;\r
1136\r
1137 //\r
1138 // Append the new created attempt order to the end.\r
1139 //\r
1140 AttemptOrderTmp = AllocateZeroPool (TotalNumber * sizeof (UINT8));\r
1141 if (AttemptOrderTmp == NULL) {\r
1142 if (AttemptConfigOrder != NULL) {\r
1143 FreePool (AttemptConfigOrder);\r
1144 }\r
d1050b9d 1145\r
c0d494b5 1146 return EFI_OUT_OF_RESOURCES;\r
1147 }\r
1148\r
1149 if (AttemptConfigOrder != NULL) {\r
1150 CopyMem (AttemptOrderTmp, AttemptConfigOrder, AttemptConfigOrderSize);\r
1151 FreePool (AttemptConfigOrder);\r
1152 }\r
1153\r
1154 AttemptOrderTmp[TotalNumber - 1] = Attempt->AttemptConfigIndex;\r
1155 AttemptConfigOrder = AttemptOrderTmp;\r
1156 AttemptConfigOrderSize = TotalNumber * sizeof (UINT8);\r
1157\r
1158 Status = gRT->SetVariable (\r
1159 L"AttemptOrder",\r
9bdc6592 1160 &gIScsiConfigGuid,\r
9c12f2d7 1161 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
c0d494b5 1162 AttemptConfigOrderSize,\r
1163 AttemptConfigOrder\r
1164 );\r
1165 FreePool (AttemptConfigOrder);\r
1166 if (EFI_ERROR (Status)) {\r
1167 return Status;\r
1168 }\r
1169\r
1170 //\r
1171 // Insert new created attempt to array.\r
1172 //\r
1173 InsertTailList (&mPrivate->AttemptConfigs, &Attempt->Link);\r
1174 mPrivate->AttemptCount++;\r
c0d494b5 1175\r
4c5a5e0c 1176 if (IfrNvData->Enabled == ISCSI_ENABLED_FOR_MPIO) {\r
1177 //\r
1178 // This new Attempt is enabled for MPIO; enable the multipath mode.\r
1179 //\r
1180 mPrivate->EnableMpio = TRUE;\r
1181 mPrivate->MpioCount++;\r
1182 } else if (IfrNvData->Enabled == ISCSI_ENABLED) {\r
1183 mPrivate->SinglePathCount++;\r
1184 }\r
4c5a5e0c 1185\r
c0d494b5 1186 IScsiConfigUpdateAttempt ();\r
4c5a5e0c 1187 }\r
d1050b9d 1188\r
8d1f5e04 1189 Attempt->SessionConfigData.Enabled = IfrNvData->Enabled;\r
4c5a5e0c 1190\r
1191 //\r
1192 // Record the user configuration information in NVR.\r
1193 //\r
d1050b9d 1194 UnicodeSPrint (mPrivate->PortString, (UINTN)ISCSI_NAME_IFR_MAX_SIZE, L"Attempt %d", Attempt->AttemptConfigIndex);\r
4c5a5e0c 1195\r
1196 FreePool (MacString);\r
1197\r
1198 return gRT->SetVariable (\r
1199 mPrivate->PortString,\r
1200 &gEfiIScsiInitiatorNameProtocolGuid,\r
1201 ISCSI_CONFIG_VAR_ATTR,\r
1202 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),\r
1203 Attempt\r
1204 );\r
1205}\r
1206\r
1207/**\r
8d1f5e04 1208 Convert the IFR data configured by keyword to iSCSI configuration data.\r
4c5a5e0c 1209\r
8d1f5e04
ZL
1210 @param[in] IfrNvData Point to ISCSI_CONFIG_IFR_NVDATA.\r
1211 @param[in] OffSet The offset of the variable to the configuration structure.\r
4c5a5e0c 1212\r
8d1f5e04 1213 @retval EFI_INVALID_PARAMETER Any input or configured parameter is invalid.\r
4c5a5e0c 1214 @retval EFI_SUCCESS The operation is completed successfully.\r
1215\r
1216**/\r
1217EFI_STATUS\r
8d1f5e04 1218IScsiConvertlfrNvDataToAttemptConfigDataByKeyword (\r
d1050b9d
MK
1219 IN ISCSI_CONFIG_IFR_NVDATA *IfrNvData,\r
1220 IN UINTN OffSet\r
4c5a5e0c 1221 )\r
1222{\r
d1050b9d
MK
1223 ISCSI_ATTEMPT_CONFIG_NVDATA *Attempt;\r
1224 UINT8 AttemptIndex;\r
1225 UINT8 Index;\r
1226 UINT8 ChapSecretLen;\r
1227 UINT8 ReverseChapSecretLen;\r
1228 CHAR16 *AttemptName1;\r
1229 CHAR16 *AttemptName2;\r
1230 ISCSI_ATTEMPT_CONFIG_NVDATA *SameNicAttempt;\r
1231 CHAR8 LunString[ISCSI_LUN_STR_MAX_LEN];\r
1232 CHAR8 IScsiName[ISCSI_NAME_MAX_SIZE];\r
1233 CHAR8 IpString[IP_STR_MAX_SIZE];\r
1234 EFI_IP_ADDRESS HostIp;\r
1235 EFI_IP_ADDRESS SubnetMask;\r
1236 EFI_IP_ADDRESS Gateway;\r
1237 EFI_INPUT_KEY Key;\r
1238 UINT64 Lun;\r
1239 EFI_STATUS Status;\r
4c5a5e0c 1240\r
2fd40fa5 1241 Attempt = NULL;\r
8d1f5e04 1242 ZeroMem (IScsiName, sizeof (IScsiName));\r
4c5a5e0c 1243\r
8d1f5e04
ZL
1244 if (OffSet < ATTEMPT_BOOTENABLE_VAR_OFFSET) {\r
1245 return EFI_SUCCESS;\r
8d1f5e04 1246 } else if ((OffSet >= ATTEMPT_BOOTENABLE_VAR_OFFSET) && (OffSet < ATTEMPT_ADDRESS_TYPE_VAR_OFFSET)) {\r
d1050b9d
MK
1247 AttemptIndex = (UINT8)((OffSet - ATTEMPT_BOOTENABLE_VAR_OFFSET) + 1);\r
1248 Attempt = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);\r
8d1f5e04
ZL
1249 if (Attempt == NULL) {\r
1250 return EFI_INVALID_PARAMETER;\r
1251 }\r
d1050b9d 1252\r
8d1f5e04
ZL
1253 IfrNvData->Enabled = IfrNvData->ISCSIBootEnableList[AttemptIndex - 1];\r
1254 //\r
1255 // Validate the configuration of attempt.\r
1256 //\r
1257 if (IfrNvData->Enabled != ISCSI_DISABLED) {\r
1258 //\r
1259 // Check whether this attempt uses NIC which is already used by existing attempt.\r
1260 //\r
1261 SameNicAttempt = IScsiConfigGetAttemptByNic (Attempt, IfrNvData->Enabled);\r
1262 if (SameNicAttempt != NULL) {\r
d1050b9d 1263 AttemptName1 = (CHAR16 *)AllocateZeroPool (ATTEMPT_NAME_SIZE * sizeof (CHAR16));\r
8d1f5e04
ZL
1264 if (AttemptName1 == NULL) {\r
1265 return EFI_OUT_OF_RESOURCES;\r
1266 }\r
4c5a5e0c 1267\r
d1050b9d 1268 AttemptName2 = (CHAR16 *)AllocateZeroPool (ATTEMPT_NAME_SIZE * sizeof (CHAR16));\r
8d1f5e04
ZL
1269 if (AttemptName2 == NULL) {\r
1270 FreePool (AttemptName1);\r
1271 return EFI_OUT_OF_RESOURCES;\r
1272 }\r
4c5a5e0c 1273\r
8d1f5e04
ZL
1274 AsciiStrToUnicodeStrS (Attempt->AttemptName, AttemptName1, ATTEMPT_NAME_SIZE);\r
1275 AsciiStrToUnicodeStrS (SameNicAttempt->AttemptName, AttemptName2, ATTEMPT_NAME_SIZE);\r
4c5a5e0c 1276\r
8d1f5e04
ZL
1277 UnicodeSPrint (\r
1278 mPrivate->PortString,\r
d1050b9d 1279 (UINTN)ISCSI_NAME_IFR_MAX_SIZE,\r
8d1f5e04
ZL
1280 L"Warning! \"%s\" uses same NIC as Attempt \"%s\".",\r
1281 AttemptName1,\r
1282 AttemptName2\r
1283 );\r
4c5a5e0c 1284\r
8d1f5e04
ZL
1285 CreatePopUp (\r
1286 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1287 &Key,\r
1288 mPrivate->PortString,\r
1289 NULL\r
1290 );\r
4c5a5e0c 1291\r
8d1f5e04
ZL
1292 FreePool (AttemptName1);\r
1293 FreePool (AttemptName2);\r
1294 }\r
1295 }\r
4c5a5e0c 1296\r
d1050b9d
MK
1297 if ((IfrNvData->Enabled == ISCSI_DISABLED) &&\r
1298 (Attempt->SessionConfigData.Enabled != ISCSI_DISABLED))\r
1299 {\r
8d1f5e04
ZL
1300 //\r
1301 // User updates the Attempt from "Enabled"/"Enabled for MPIO" to "Disabled".\r
1302 //\r
1303 if (Attempt->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO) {\r
1304 if (mPrivate->MpioCount < 1) {\r
1305 return EFI_ABORTED;\r
1306 }\r
4c5a5e0c 1307\r
8d1f5e04
ZL
1308 if (--mPrivate->MpioCount == 0) {\r
1309 mPrivate->EnableMpio = FALSE;\r
1310 }\r
1311 } else if (Attempt->SessionConfigData.Enabled == ISCSI_ENABLED) {\r
1312 if (mPrivate->SinglePathCount < 1) {\r
1313 return EFI_ABORTED;\r
1314 }\r
d1050b9d 1315\r
8d1f5e04
ZL
1316 mPrivate->SinglePathCount--;\r
1317 }\r
d1050b9d
MK
1318 } else if ((IfrNvData->Enabled == ISCSI_ENABLED_FOR_MPIO) &&\r
1319 (Attempt->SessionConfigData.Enabled == ISCSI_ENABLED))\r
1320 {\r
8d1f5e04
ZL
1321 //\r
1322 // User updates the Attempt from "Enabled" to "Enabled for MPIO".\r
1323 //\r
1324 if (mPrivate->SinglePathCount < 1) {\r
1325 return EFI_ABORTED;\r
1326 }\r
1327\r
1328 mPrivate->EnableMpio = TRUE;\r
1329 mPrivate->MpioCount++;\r
1330 mPrivate->SinglePathCount--;\r
d1050b9d
MK
1331 } else if ((IfrNvData->Enabled == ISCSI_ENABLED) &&\r
1332 (Attempt->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO))\r
1333 {\r
8d1f5e04
ZL
1334 //\r
1335 // User updates the Attempt from "Enabled for MPIO" to "Enabled".\r
1336 //\r
1337 if (mPrivate->MpioCount < 1) {\r
1338 return EFI_ABORTED;\r
1339 }\r
1340\r
1341 if (--mPrivate->MpioCount == 0) {\r
1342 mPrivate->EnableMpio = FALSE;\r
1343 }\r
8d1f5e04 1344\r
d1050b9d
MK
1345 mPrivate->SinglePathCount++;\r
1346 } else if ((IfrNvData->Enabled != ISCSI_DISABLED) &&\r
1347 (Attempt->SessionConfigData.Enabled == ISCSI_DISABLED))\r
1348 {\r
8d1f5e04
ZL
1349 //\r
1350 // User updates the Attempt from "Disabled" to "Enabled"/"Enabled for MPIO".\r
1351 //\r
1352 if (IfrNvData->Enabled == ISCSI_ENABLED_FOR_MPIO) {\r
1353 mPrivate->EnableMpio = TRUE;\r
1354 mPrivate->MpioCount++;\r
8d1f5e04
ZL
1355 } else if (IfrNvData->Enabled == ISCSI_ENABLED) {\r
1356 mPrivate->SinglePathCount++;\r
1357 }\r
1358 }\r
8d1f5e04 1359\r
d1050b9d 1360 Attempt->SessionConfigData.Enabled = IfrNvData->Enabled;\r
8d1f5e04 1361 } else if ((OffSet >= ATTEMPT_ADDRESS_TYPE_VAR_OFFSET) && (OffSet < ATTEMPT_CONNECT_RETRY_VAR_OFFSET)) {\r
d1050b9d
MK
1362 AttemptIndex = (UINT8)((OffSet - ATTEMPT_ADDRESS_TYPE_VAR_OFFSET) + 1);\r
1363 Attempt = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);\r
8d1f5e04
ZL
1364 if (Attempt == NULL) {\r
1365 return EFI_INVALID_PARAMETER;\r
1366 }\r
d1050b9d 1367\r
8d1f5e04
ZL
1368 Attempt->SessionConfigData.IpMode = IfrNvData->ISCSIIpAddressTypeList[AttemptIndex - 1];\r
1369 if (Attempt->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG) {\r
1370 Attempt->AutoConfigureMode = 0;\r
1371 }\r
8d1f5e04 1372 } else if ((OffSet >= ATTEMPT_CONNECT_RETRY_VAR_OFFSET) && (OffSet < ATTEMPT_CONNECT_TIMEOUT_VAR_OFFSET)) {\r
d1050b9d
MK
1373 AttemptIndex = (UINT8)((OffSet - ATTEMPT_CONNECT_RETRY_VAR_OFFSET) + 1);\r
1374 Attempt = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);\r
8d1f5e04
ZL
1375 if (Attempt == NULL) {\r
1376 return EFI_INVALID_PARAMETER;\r
1377 }\r
12b04866
ZL
1378\r
1379 if (IfrNvData->ISCSIConnectRetry[AttemptIndex - 1] > CONNECT_MAX_RETRY) {\r
1380 CreatePopUp (\r
d1050b9d
MK
1381 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1382 &Key,\r
1383 L"The minimum value is 0 and the maximum is 16. 0 means no retry.",\r
1384 NULL\r
1385 );\r
12b04866 1386 return EFI_INVALID_PARAMETER;\r
8d1f5e04
ZL
1387 }\r
1388\r
d1050b9d 1389 Attempt->SessionConfigData.ConnectRetryCount = IfrNvData->ISCSIConnectRetry[AttemptIndex - 1];\r
8d1f5e04 1390 } else if ((OffSet >= ATTEMPT_CONNECT_TIMEOUT_VAR_OFFSET) && (OffSet < ATTEMPT_INITIATOR_VIA_DHCP_VAR_OFFSET)) {\r
d1050b9d
MK
1391 AttemptIndex = (UINT8)((OffSet - ATTEMPT_CONNECT_TIMEOUT_VAR_OFFSET) / 2 + 1);\r
1392 Attempt = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);\r
8d1f5e04
ZL
1393 if (Attempt == NULL) {\r
1394 return EFI_INVALID_PARAMETER;\r
1395 }\r
12b04866
ZL
1396\r
1397 if ((IfrNvData->ISCSIConnectTimeout[AttemptIndex - 1] < CONNECT_MIN_TIMEOUT) ||\r
d1050b9d
MK
1398 (IfrNvData->ISCSIConnectTimeout[AttemptIndex - 1] > CONNECT_MAX_TIMEOUT))\r
1399 {\r
12b04866
ZL
1400 CreatePopUp (\r
1401 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1402 &Key,\r
1403 L"The minimum value is 100 milliseconds and the maximum is 20 seconds.",\r
1404 NULL\r
1405 );\r
1406 return EFI_INVALID_PARAMETER;\r
1407 }\r
1408\r
8d1f5e04
ZL
1409 Attempt->SessionConfigData.ConnectTimeout = IfrNvData->ISCSIConnectTimeout[AttemptIndex - 1];\r
1410 if (Attempt->SessionConfigData.ConnectTimeout == 0) {\r
1411 Attempt->SessionConfigData.ConnectTimeout = CONNECT_DEFAULT_TIMEOUT;\r
1412 }\r
8d1f5e04 1413 } else if ((OffSet >= ATTEMPT_INITIATOR_VIA_DHCP_VAR_OFFSET) && (OffSet < ATTEMPT_TARGET_VIA_DHCP_VAR_OFFSET)) {\r
d1050b9d
MK
1414 AttemptIndex = (UINT8)((OffSet - ATTEMPT_INITIATOR_VIA_DHCP_VAR_OFFSET) + 1);\r
1415 Attempt = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);\r
8d1f5e04
ZL
1416 if (Attempt == NULL) {\r
1417 return EFI_INVALID_PARAMETER;\r
1418 }\r
8d1f5e04 1419\r
d1050b9d 1420 Attempt->SessionConfigData.InitiatorInfoFromDhcp = IfrNvData->ISCSIInitiatorInfoViaDHCP[AttemptIndex - 1];\r
8d1f5e04 1421 } else if ((OffSet >= ATTEMPT_TARGET_VIA_DHCP_VAR_OFFSET) && (OffSet < ATTEMPT_TARGET_TCP_PORT_VAR_OFFSET)) {\r
d1050b9d
MK
1422 AttemptIndex = (UINT8)((OffSet - ATTEMPT_TARGET_VIA_DHCP_VAR_OFFSET) + 1);\r
1423 Attempt = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);\r
8d1f5e04
ZL
1424 if (Attempt == NULL) {\r
1425 return EFI_INVALID_PARAMETER;\r
1426 }\r
1427\r
1428 if ((Attempt->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG) && (Attempt->SessionConfigData.InitiatorInfoFromDhcp)) {\r
1429 Attempt->SessionConfigData.TargetInfoFromDhcp = IfrNvData->ISCSITargetInfoViaDHCP[AttemptIndex - 1];\r
1430 } else {\r
1431 CreatePopUp (\r
1432 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1433 &Key,\r
1434 L"Invalid Configuration, Check value of IpMode or Enable DHCP!",\r
1435 NULL\r
1436 );\r
1437 return EFI_INVALID_PARAMETER;\r
1438 }\r
8d1f5e04 1439 } else if ((OffSet >= ATTEMPT_TARGET_TCP_PORT_VAR_OFFSET) && (OffSet < ATTEMPT_AUTHENTICATION_METHOD_VAR_OFFSET)) {\r
d1050b9d
MK
1440 AttemptIndex = (UINT8)((OffSet - ATTEMPT_TARGET_TCP_PORT_VAR_OFFSET) / 2 + 1);\r
1441 Attempt = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);\r
8d1f5e04
ZL
1442 if (Attempt == NULL) {\r
1443 return EFI_INVALID_PARAMETER;\r
1444 }\r
d1050b9d 1445\r
8d1f5e04
ZL
1446 if ((Attempt->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG) && (!Attempt->SessionConfigData.TargetInfoFromDhcp)) {\r
1447 Attempt->SessionConfigData.TargetPort = IfrNvData->ISCSITargetTcpPort[AttemptIndex - 1];\r
1448 if (Attempt->SessionConfigData.TargetPort == 0) {\r
1449 Attempt->SessionConfigData.TargetPort = ISCSI_WELL_KNOWN_PORT;\r
1450 }\r
1451 } else {\r
1452 CreatePopUp (\r
1453 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1454 &Key,\r
1455 L"Invalid Configuration, Check value of IpMode or Target Via DHCP!",\r
1456 NULL\r
1457 );\r
1458 return EFI_INVALID_PARAMETER;\r
1459 }\r
8d1f5e04 1460 } else if ((OffSet >= ATTEMPT_AUTHENTICATION_METHOD_VAR_OFFSET) && (OffSet < ATTEMPT_CHARTYPE_VAR_OFFSET)) {\r
d1050b9d
MK
1461 AttemptIndex = (UINT8)((OffSet - ATTEMPT_AUTHENTICATION_METHOD_VAR_OFFSET) + 1);\r
1462 Attempt = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);\r
8d1f5e04
ZL
1463 if (Attempt == NULL) {\r
1464 return EFI_INVALID_PARAMETER;\r
1465 }\r
1466\r
1467 Attempt->AuthenticationType = IfrNvData->ISCSIAuthenticationMethod[AttemptIndex - 1];\r
8d1f5e04 1468 } else if ((OffSet >= ATTEMPT_CHARTYPE_VAR_OFFSET) && (OffSet < ATTEMPT_ISID_VAR_OFFSET)) {\r
d1050b9d
MK
1469 AttemptIndex = (UINT8)((OffSet - ATTEMPT_CHARTYPE_VAR_OFFSET) + 1);\r
1470 Attempt = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);\r
8d1f5e04
ZL
1471 if (Attempt == NULL) {\r
1472 return EFI_INVALID_PARAMETER;\r
1473 }\r
d1050b9d 1474\r
8d1f5e04
ZL
1475 if (Attempt->AuthenticationType == ISCSI_AUTH_TYPE_CHAP) {\r
1476 Attempt->AuthConfigData.CHAP.CHAPType = IfrNvData->ISCSIChapType[AttemptIndex - 1];\r
1477 }\r
8d1f5e04 1478 } else if (OffSet >= ATTEMPT_ISID_VAR_OFFSET) {\r
d1050b9d 1479 Index = (UINT8)((OffSet - ATTEMPT_ISID_VAR_OFFSET) / sizeof (KEYWORD_STR));\r
8d1f5e04 1480 AttemptIndex = Index + 1;\r
d1050b9d 1481 Attempt = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);\r
8d1f5e04
ZL
1482 if (Attempt == NULL) {\r
1483 return EFI_INVALID_PARAMETER;\r
1484 }\r
1485\r
1486 OffSet = OffSet - Index * sizeof (KEYWORD_STR);\r
1487\r
1488 if ((OffSet >= ATTEMPT_ISID_VAR_OFFSET) && (OffSet < ATTEMPT_INITIATOR_IP_ADDRESS_VAR_OFFSET)) {\r
1489 IScsiParseIsIdFromString (IfrNvData->Keyword[Index].ISCSIIsId, Attempt->SessionConfigData.IsId);\r
d1050b9d 1490 } else if ((OffSet >= ATTEMPT_INITIATOR_IP_ADDRESS_VAR_OFFSET) && (OffSet < ATTEMPT_INITIATOR_NET_MASK_VAR_OFFSET)) {\r
8d1f5e04
ZL
1491 if ((Attempt->SessionConfigData.IpMode == IP_MODE_IP4) && (!Attempt->SessionConfigData.InitiatorInfoFromDhcp)) {\r
1492 //\r
1493 // Config Local ip\r
1494 //\r
1495 Status = NetLibStrToIp4 (IfrNvData->Keyword[Index].ISCSIInitiatorIpAddress, &HostIp.v4);\r
1496 if (EFI_ERROR (Status) || ((Attempt->SessionConfigData.SubnetMask.Addr[0] != 0) &&\r
d1050b9d
MK
1497 !NetIp4IsUnicast (NTOHL (HostIp.Addr[0]), NTOHL (*(UINT32 *)Attempt->SessionConfigData.SubnetMask.Addr))))\r
1498 {\r
8d1f5e04
ZL
1499 CreatePopUp (\r
1500 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1501 &Key,\r
1502 L"Invalid IP address!",\r
1503 NULL\r
1504 );\r
1505 return EFI_INVALID_PARAMETER;\r
1506 } else {\r
1507 CopyMem (&Attempt->SessionConfigData.LocalIp, &HostIp.v4, sizeof (HostIp.v4));\r
1508 }\r
1509 } else {\r
1510 CreatePopUp (\r
1511 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1512 &Key,\r
1513 L"Invalid Configuration, Check value of IpMode or Enable DHCP!",\r
1514 NULL\r
1515 );\r
1516 return EFI_INVALID_PARAMETER;\r
1517 }\r
8d1f5e04
ZL
1518 } else if ((OffSet >= ATTEMPT_INITIATOR_NET_MASK_VAR_OFFSET) && (OffSet < ATTEMPT_INITIATOR_GATE_WAY_VAR_OFFSET)) {\r
1519 if ((Attempt->SessionConfigData.IpMode == IP_MODE_IP4) && (!Attempt->SessionConfigData.InitiatorInfoFromDhcp)) {\r
1520 Status = NetLibStrToIp4 (IfrNvData->Keyword[Index].ISCSIInitiatorNetmask, &SubnetMask.v4);\r
1521 if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (IScsiGetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) {\r
1522 CreatePopUp (\r
1523 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1524 &Key,\r
1525 L"Invalid Subnet Mask!",\r
1526 NULL\r
1527 );\r
1528 return EFI_INVALID_PARAMETER;\r
1529 } else {\r
1530 CopyMem (&Attempt->SessionConfigData.SubnetMask, &SubnetMask.v4, sizeof (SubnetMask.v4));\r
1531 }\r
1532 } else {\r
1533 CreatePopUp (\r
1534 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1535 &Key,\r
1536 L"Invalid Configuration, Check value of IpMode or Enable DHCP!",\r
1537 NULL\r
1538 );\r
1539 return EFI_INVALID_PARAMETER;\r
1540 }\r
8d1f5e04
ZL
1541 } else if ((OffSet >= ATTEMPT_INITIATOR_GATE_WAY_VAR_OFFSET) && (OffSet < ATTEMPT_TARGET_NAME_VAR_OFFSET)) {\r
1542 if ((Attempt->SessionConfigData.IpMode == IP_MODE_IP4) && (!Attempt->SessionConfigData.InitiatorInfoFromDhcp)) {\r
1543 Status = NetLibStrToIp4 (IfrNvData->Keyword[Index].ISCSIInitiatorGateway, &Gateway.v4);\r
1544 if (EFI_ERROR (Status) ||\r
d1050b9d
MK
1545 ((Gateway.Addr[0] != 0) && (Attempt->SessionConfigData.SubnetMask.Addr[0] != 0) &&\r
1546 !NetIp4IsUnicast (NTOHL (Gateway.Addr[0]), NTOHL (*(UINT32 *)Attempt->SessionConfigData.SubnetMask.Addr))))\r
1547 {\r
8d1f5e04
ZL
1548 CreatePopUp (\r
1549 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1550 &Key,\r
1551 L"Invalid Gateway!",\r
1552 NULL\r
1553 );\r
1554 return EFI_INVALID_PARAMETER;\r
1555 } else {\r
1556 CopyMem (&Attempt->SessionConfigData.Gateway, &Gateway.v4, sizeof (Gateway.v4));\r
1557 }\r
1558 } else {\r
1559 CreatePopUp (\r
1560 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1561 &Key,\r
1562 L"Invalid Configuration, Check value of IpMode or Enable DHCP!",\r
1563 NULL\r
1564 );\r
1565 return EFI_INVALID_PARAMETER;\r
1566 }\r
8d1f5e04
ZL
1567 } else if ((OffSet >= ATTEMPT_TARGET_NAME_VAR_OFFSET) && (OffSet < ATTEMPT_TARGET_IP_ADDRESS_VAR_OFFSET)) {\r
1568 if ((Attempt->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG) && (!Attempt->SessionConfigData.TargetInfoFromDhcp)) {\r
1569 UnicodeStrToAsciiStrS (IfrNvData->Keyword[Index].ISCSITargetName, IScsiName, ISCSI_NAME_MAX_SIZE);\r
1570 Status = IScsiNormalizeName (IScsiName, AsciiStrLen (IScsiName));\r
1571 if (EFI_ERROR (Status)) {\r
1572 CreatePopUp (\r
1573 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1574 &Key,\r
1575 L"Invalid iSCSI Name!",\r
1576 NULL\r
1577 );\r
1578 } else {\r
1579 AsciiStrCpyS (Attempt->SessionConfigData.TargetName, ISCSI_NAME_MAX_SIZE, IScsiName);\r
1580 }\r
d1050b9d 1581\r
8d1f5e04
ZL
1582 if (Attempt->SessionConfigData.Enabled != ISCSI_DISABLED) {\r
1583 if (Attempt->SessionConfigData.TargetName[0] == L'\0') {\r
1584 CreatePopUp (\r
1585 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1586 &Key,\r
1587 L"iSCSI target name is NULL!",\r
1588 NULL\r
1589 );\r
1590 return EFI_INVALID_PARAMETER;\r
1591 }\r
1592 }\r
1593 } else {\r
1594 CreatePopUp (\r
1595 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1596 &Key,\r
1597 L"Invalid Configuration, Check value of IpMode or Target Via DHCP!",\r
1598 NULL\r
1599 );\r
1600 return EFI_INVALID_PARAMETER;\r
1601 }\r
8d1f5e04
ZL
1602 } else if ((OffSet >= ATTEMPT_TARGET_IP_ADDRESS_VAR_OFFSET) && (OffSet < ATTEMPT_LUN_VAR_OFFSET)) {\r
1603 if ((Attempt->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG) && (!Attempt->SessionConfigData.TargetInfoFromDhcp)) {\r
1604 UnicodeStrToAsciiStrS (IfrNvData->Keyword[Index].ISCSITargetIpAddress, IpString, sizeof (IpString));\r
1605 Status = IScsiAsciiStrToIp (IpString, Attempt->SessionConfigData.IpMode, &HostIp);\r
1606 if (EFI_ERROR (Status) || !IpIsUnicast (&HostIp, Attempt->SessionConfigData.IpMode)) {\r
1607 Attempt->SessionConfigData.DnsMode = TRUE;\r
1608 ZeroMem (&Attempt->SessionConfigData.TargetIp, sizeof (Attempt->SessionConfigData.TargetIp));\r
1609 UnicodeStrToAsciiStrS (IfrNvData->Keyword[Index].ISCSITargetIpAddress, Attempt->SessionConfigData.TargetUrl, ISCSI_NAME_MAX_SIZE);\r
1610 } else {\r
1611 Attempt->SessionConfigData.DnsMode = FALSE;\r
1612 CopyMem (&Attempt->SessionConfigData.TargetIp, &HostIp, sizeof (HostIp));\r
1613 }\r
1614 } else {\r
1615 CreatePopUp (\r
1616 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1617 &Key,\r
1618 L"Invalid Configuration, Check value of IpMode or Target Via DHCP!",\r
1619 NULL\r
1620 );\r
1621 return EFI_INVALID_PARAMETER;\r
1622 }\r
8d1f5e04
ZL
1623 } else if ((OffSet >= ATTEMPT_LUN_VAR_OFFSET) && (OffSet < ATTEMPT_CHAR_USER_NAME_VAR_OFFSET)) {\r
1624 if ((Attempt->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG) && (Attempt->SessionConfigData.TargetInfoFromDhcp == 0)) {\r
1625 //\r
1626 // Config LUN.\r
1627 //\r
1628 UnicodeStrToAsciiStrS (IfrNvData->Keyword[Index].ISCSILun, LunString, ISCSI_LUN_STR_MAX_LEN);\r
d1050b9d 1629 Status = IScsiAsciiStrToLun (LunString, (UINT8 *)&Lun);\r
8d1f5e04
ZL
1630 if (EFI_ERROR (Status)) {\r
1631 CreatePopUp (\r
1632 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1633 &Key,\r
1634 L"Invalid LUN string, Examples are: 4752-3A4F-6b7e-2F99, 6734-9-156f-127, 4186-9!",\r
1635 NULL\r
1636 );\r
1637 } else {\r
1638 CopyMem (&Attempt->SessionConfigData.BootLun, &Lun, sizeof (Lun));\r
1639 }\r
1640 } else {\r
1641 CreatePopUp (\r
1642 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1643 &Key,\r
1644 L"Invalid Configuration, Check value of IpMode or Target Via DHCP!",\r
1645 NULL\r
1646 );\r
1647 return EFI_INVALID_PARAMETER;\r
1648 }\r
8d1f5e04
ZL
1649 } else if ((OffSet >= ATTEMPT_CHAR_USER_NAME_VAR_OFFSET) && (OffSet < ATTEMPT_CHAR_SECRET_VAR_OFFSET)) {\r
1650 if (Attempt->AuthenticationType == ISCSI_AUTH_TYPE_CHAP) {\r
1651 UnicodeStrToAsciiStrS (\r
1652 IfrNvData->Keyword[Index].ISCSIChapUsername,\r
1653 Attempt->AuthConfigData.CHAP.CHAPName,\r
1654 ISCSI_CHAP_NAME_STORAGE\r
1655 );\r
1656\r
1657 if (Attempt->SessionConfigData.Enabled != ISCSI_DISABLED) {\r
12b04866 1658 if (IfrNvData->Keyword[Index].ISCSIChapUsername[0] == L'\0') {\r
8d1f5e04
ZL
1659 CreatePopUp (\r
1660 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1661 &Key,\r
1662 L"CHAP Name is invalid!",\r
1663 NULL\r
1664 );\r
1665 return EFI_INVALID_PARAMETER;\r
1666 }\r
1667 }\r
1668 } else {\r
1669 CreatePopUp (\r
1670 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1671 &Key,\r
1672 L"Invalid Configuration, Check value of AuthenticationType!",\r
1673 NULL\r
1674 );\r
1675 return EFI_INVALID_PARAMETER;\r
1676 }\r
8d1f5e04
ZL
1677 } else if ((OffSet >= ATTEMPT_CHAR_SECRET_VAR_OFFSET) && (OffSet < ATTEMPT_CHAR_REVERSE_USER_NAME_VAR_OFFSET)) {\r
1678 if (Attempt->AuthenticationType == ISCSI_AUTH_TYPE_CHAP) {\r
12b04866 1679 ChapSecretLen = (UINT8)StrLen (IfrNvData->Keyword[Index].ISCSIChapSecret);\r
8d1f5e04
ZL
1680 UnicodeStrToAsciiStrS (\r
1681 IfrNvData->Keyword[Index].ISCSIChapSecret,\r
1682 Attempt->AuthConfigData.CHAP.CHAPSecret,\r
1683 ISCSI_CHAP_SECRET_STORAGE\r
1684 );\r
1685\r
1686 if (Attempt->SessionConfigData.Enabled != ISCSI_DISABLED) {\r
12b04866 1687 if ((ChapSecretLen < ISCSI_CHAP_SECRET_MIN_LEN) || (ChapSecretLen > ISCSI_CHAP_SECRET_MAX_LEN)) {\r
8d1f5e04
ZL
1688 CreatePopUp (\r
1689 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1690 &Key,\r
12b04866 1691 L"The Chap Secret minimum length is 12 bytes and the maximum length is 16 bytes.",\r
8d1f5e04
ZL
1692 NULL\r
1693 );\r
1694 return EFI_INVALID_PARAMETER;\r
1695 }\r
1696 }\r
1697 } else {\r
1698 CreatePopUp (\r
1699 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1700 &Key,\r
1701 L"Invalid Configuration, Check value of AuthenticationType!",\r
1702 NULL\r
1703 );\r
1704 return EFI_INVALID_PARAMETER;\r
1705 }\r
8d1f5e04
ZL
1706 } else if ((OffSet >= ATTEMPT_CHAR_REVERSE_USER_NAME_VAR_OFFSET) && (OffSet < ATTEMPT_CHAR_REVERSE_SECRET_VAR_OFFSET)) {\r
1707 if (Attempt->AuthConfigData.CHAP.CHAPType == ISCSI_CHAP_MUTUAL) {\r
1708 UnicodeStrToAsciiStrS (\r
1709 IfrNvData->Keyword[Index].ISCSIReverseChapUsername,\r
1710 Attempt->AuthConfigData.CHAP.ReverseCHAPName,\r
1711 ISCSI_CHAP_NAME_STORAGE\r
1712 );\r
1713 if (Attempt->SessionConfigData.Enabled != ISCSI_DISABLED) {\r
12b04866 1714 if (IfrNvData->Keyword[Index].ISCSIReverseChapUsername[0] == L'\0') {\r
8d1f5e04
ZL
1715 CreatePopUp (\r
1716 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1717 &Key,\r
1718 L"Reverse CHAP Name is invalid!",\r
1719 NULL\r
1720 );\r
1721 return EFI_INVALID_PARAMETER;\r
1722 }\r
1723 }\r
1724 } else {\r
1725 CreatePopUp (\r
1726 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1727 &Key,\r
1728 L"Invalid Configuration, Check value of AuthenticationType or Chap Type!",\r
1729 NULL\r
1730 );\r
1731 return EFI_INVALID_PARAMETER;\r
1732 }\r
8d1f5e04
ZL
1733 } else if (OffSet >= ATTEMPT_CHAR_REVERSE_SECRET_VAR_OFFSET) {\r
1734 if (Attempt->AuthConfigData.CHAP.CHAPType == ISCSI_CHAP_MUTUAL) {\r
12b04866 1735 ReverseChapSecretLen = (UINT8)StrLen (IfrNvData->Keyword[Index].ISCSIReverseChapSecret);\r
8d1f5e04
ZL
1736 UnicodeStrToAsciiStrS (\r
1737 IfrNvData->Keyword[Index].ISCSIReverseChapSecret,\r
1738 Attempt->AuthConfigData.CHAP.ReverseCHAPSecret,\r
1739 ISCSI_CHAP_SECRET_STORAGE\r
1740 );\r
1741\r
1742 if (Attempt->SessionConfigData.Enabled != ISCSI_DISABLED) {\r
12b04866 1743 if ((ReverseChapSecretLen < ISCSI_CHAP_SECRET_MIN_LEN) || (ReverseChapSecretLen > ISCSI_CHAP_SECRET_MAX_LEN)) {\r
8d1f5e04
ZL
1744 CreatePopUp (\r
1745 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1746 &Key,\r
12b04866 1747 L"The Reverse CHAP Secret minimum length is 12 bytes and the maximum length is 16 bytes.",\r
8d1f5e04
ZL
1748 NULL\r
1749 );\r
1750 return EFI_INVALID_PARAMETER;\r
1751 }\r
1752 }\r
1753 } else {\r
1754 CreatePopUp (\r
1755 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1756 &Key,\r
1757 L"Invalid Configuration, Check value of AuthenticationType or Chap Type!",\r
1758 NULL\r
1759 );\r
1760 return EFI_INVALID_PARAMETER;\r
1761 }\r
1762 }\r
1763 }\r
1764\r
8d1f5e04
ZL
1765 //\r
1766 // Record the user configuration information in NVR.\r
1767 //\r
2fd40fa5 1768 ASSERT (Attempt != NULL);\r
d1050b9d 1769 UnicodeSPrint (mPrivate->PortString, (UINTN)ISCSI_NAME_IFR_MAX_SIZE, L"Attempt %d", Attempt->AttemptConfigIndex);\r
8d1f5e04
ZL
1770 return gRT->SetVariable (\r
1771 mPrivate->PortString,\r
1772 &gEfiIScsiInitiatorNameProtocolGuid,\r
1773 ISCSI_CONFIG_VAR_ATTR,\r
1774 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),\r
1775 Attempt\r
1776 );\r
8d1f5e04
ZL
1777}\r
1778\r
1779/**\r
1780 Create Hii Extend Label OpCode as the start opcode and end opcode. It is\r
1781 a help function.\r
1782\r
1783 @param[in] StartLabelNumber The number of start label.\r
1784 @param[out] StartOpCodeHandle Points to the start opcode handle.\r
1785 @param[out] StartLabel Points to the created start opcode.\r
1786 @param[out] EndOpCodeHandle Points to the end opcode handle.\r
1787 @param[out] EndLabel Points to the created end opcode.\r
1788\r
1789 @retval EFI_OUT_OF_RESOURCES Do not have sufficient resource to finish this\r
1790 operation.\r
1791 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
1792 @retval EFI_SUCCESS The operation is completed successfully.\r
1793\r
1794**/\r
1795EFI_STATUS\r
1796IScsiCreateOpCode (\r
d1050b9d
MK
1797 IN UINT16 StartLabelNumber,\r
1798 OUT VOID **StartOpCodeHandle,\r
1799 OUT EFI_IFR_GUID_LABEL **StartLabel,\r
1800 OUT VOID **EndOpCodeHandle,\r
1801 OUT EFI_IFR_GUID_LABEL **EndLabel\r
8d1f5e04
ZL
1802 )\r
1803{\r
d1050b9d
MK
1804 EFI_STATUS Status;\r
1805 EFI_IFR_GUID_LABEL *InternalStartLabel;\r
1806 EFI_IFR_GUID_LABEL *InternalEndLabel;\r
8d1f5e04 1807\r
d1050b9d 1808 if ((StartOpCodeHandle == NULL) || (StartLabel == NULL) || (EndOpCodeHandle == NULL) || (EndLabel == NULL)) {\r
8d1f5e04
ZL
1809 return EFI_INVALID_PARAMETER;\r
1810 }\r
1811\r
1812 *StartOpCodeHandle = NULL;\r
1813 *EndOpCodeHandle = NULL;\r
1814 Status = EFI_OUT_OF_RESOURCES;\r
1815\r
1816 //\r
1817 // Initialize the container for dynamic opcodes.\r
1818 //\r
1819 *StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1820 if (*StartOpCodeHandle == NULL) {\r
1821 return Status;\r
1822 }\r
1823\r
1824 *EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1825 if (*EndOpCodeHandle == NULL) {\r
1826 goto Exit;\r
1827 }\r
1828\r
1829 //\r
1830 // Create Hii Extend Label OpCode as the start opcode.\r
1831 //\r
d1050b9d
MK
1832 InternalStartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (\r
1833 *StartOpCodeHandle,\r
1834 &gEfiIfrTianoGuid,\r
1835 NULL,\r
1836 sizeof (EFI_IFR_GUID_LABEL)\r
1837 );\r
8d1f5e04
ZL
1838 if (InternalStartLabel == NULL) {\r
1839 goto Exit;\r
1840 }\r
1841\r
1842 InternalStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1843 InternalStartLabel->Number = StartLabelNumber;\r
1844\r
1845 //\r
1846 // Create Hii Extend Label OpCode as the end opcode.\r
1847 //\r
d1050b9d
MK
1848 InternalEndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (\r
1849 *EndOpCodeHandle,\r
1850 &gEfiIfrTianoGuid,\r
1851 NULL,\r
1852 sizeof (EFI_IFR_GUID_LABEL)\r
1853 );\r
8d1f5e04
ZL
1854 if (InternalEndLabel == NULL) {\r
1855 goto Exit;\r
1856 }\r
1857\r
1858 InternalEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1859 InternalEndLabel->Number = LABEL_END;\r
1860\r
1861 *StartLabel = InternalStartLabel;\r
1862 *EndLabel = InternalEndLabel;\r
1863\r
1864 return EFI_SUCCESS;\r
1865\r
1866Exit:\r
1867\r
1868 if (*StartOpCodeHandle != NULL) {\r
1869 HiiFreeOpCodeHandle (*StartOpCodeHandle);\r
1870 }\r
1871\r
1872 if (*EndOpCodeHandle != NULL) {\r
1873 HiiFreeOpCodeHandle (*EndOpCodeHandle);\r
1874 }\r
d1050b9d 1875\r
8d1f5e04
ZL
1876 return Status;\r
1877}\r
1878\r
1879/**\r
1880 Update the MAIN form to display the configured attempts.\r
1881\r
1882**/\r
1883VOID\r
1884IScsiConfigUpdateAttempt (\r
1885 VOID\r
1886 )\r
1887{\r
d1050b9d
MK
1888 LIST_ENTRY *Entry;\r
1889 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;\r
1890 VOID *StartOpCodeHandle;\r
1891 EFI_IFR_GUID_LABEL *StartLabel;\r
1892 VOID *EndOpCodeHandle;\r
1893 EFI_IFR_GUID_LABEL *EndLabel;\r
1894 EFI_STATUS Status;\r
8d1f5e04
ZL
1895\r
1896 Status = IScsiCreateOpCode (\r
1897 ATTEMPT_ENTRY_LABEL,\r
1898 &StartOpCodeHandle,\r
1899 &StartLabel,\r
1900 &EndOpCodeHandle,\r
1901 &EndLabel\r
1902 );\r
1903 if (EFI_ERROR (Status)) {\r
d1050b9d 1904 return;\r
8d1f5e04
ZL
1905 }\r
1906\r
1907 NET_LIST_FOR_EACH (Entry, &mPrivate->AttemptConfigs) {\r
1908 AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);\r
1909 if (AttemptConfigData->Actived == ISCSI_ACTIVE_ENABLED) {\r
1910 //\r
1911 // Update Attempt Help Info.\r
1912 //\r
d1050b9d 1913 UnicodeSPrint (mPrivate->PortString, (UINTN)ISCSI_NAME_IFR_MAX_SIZE, L"Attempt %d", (UINTN)AttemptConfigData->AttemptConfigIndex);\r
8d1f5e04
ZL
1914 AttemptConfigData->AttemptTitleToken = HiiSetString (\r
1915 mCallbackInfo->RegisteredHandle,\r
1916 0,\r
1917 mPrivate->PortString,\r
1918 NULL\r
1919 );\r
1920 if (AttemptConfigData->AttemptTitleToken == 0) {\r
d1050b9d 1921 return;\r
8d1f5e04
ZL
1922 }\r
1923\r
1924 HiiCreateGotoOpCode (\r
d1050b9d
MK
1925 StartOpCodeHandle, // Container for dynamic created opcodes\r
1926 FORMID_ATTEMPT_FORM, // Form ID\r
1927 AttemptConfigData->AttemptTitleToken, // Prompt text\r
1928 AttemptConfigData->AttemptTitleHelpToken, // Help text\r
1929 EFI_IFR_FLAG_CALLBACK, // Question flag\r
1930 (UINT16)(KEY_ATTEMPT_ENTRY_BASE + AttemptConfigData->AttemptConfigIndex) // Question ID\r
8d1f5e04
ZL
1931 );\r
1932 }\r
1933 }\r
1934\r
1935 HiiUpdateForm (\r
1936 mCallbackInfo->RegisteredHandle, // HII handle\r
1937 &gIScsiConfigGuid, // Formset GUID\r
1938 FORMID_MAIN_FORM, // Form ID\r
1939 StartOpCodeHandle, // Label for where to insert opcodes\r
1940 EndOpCodeHandle // Replace data\r
d1050b9d 1941 );\r
8d1f5e04
ZL
1942\r
1943 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
1944 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
1945}\r
1946\r
1947/**\r
1948 Callback function when user presses "Add an Attempt".\r
4c5a5e0c 1949\r
1950 @retval EFI_OUT_OF_RESOURCES Does not have sufficient resources to finish this\r
1951 operation.\r
1952 @retval EFI_SUCCESS The operation is completed successfully.\r
1953\r
1954**/\r
1955EFI_STATUS\r
1956IScsiConfigAddAttempt (\r
1957 VOID\r
1958 )\r
1959{\r
d1050b9d
MK
1960 LIST_ENTRY *Entry;\r
1961 ISCSI_NIC_INFO *NicInfo;\r
1962 EFI_STRING_ID PortTitleToken;\r
1963 EFI_STRING_ID PortTitleHelpToken;\r
1964 CHAR16 MacString[ISCSI_MAX_MAC_STRING_LEN];\r
1965 EFI_STATUS Status;\r
1966 VOID *StartOpCodeHandle;\r
1967 EFI_IFR_GUID_LABEL *StartLabel;\r
1968 VOID *EndOpCodeHandle;\r
1969 EFI_IFR_GUID_LABEL *EndLabel;\r
4c5a5e0c 1970\r
1971 Status = IScsiCreateOpCode (\r
1972 MAC_ENTRY_LABEL,\r
1973 &StartOpCodeHandle,\r
1974 &StartLabel,\r
1975 &EndOpCodeHandle,\r
1976 &EndLabel\r
1977 );\r
1978 if (EFI_ERROR (Status)) {\r
1979 return Status;\r
1980 }\r
1981\r
1982 //\r
1983 // Ask user to select a MAC for this attempt.\r
1984 //\r
1985 NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {\r
1986 NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);\r
1987 IScsiMacAddrToStr (\r
1988 &NicInfo->PermanentAddress,\r
1989 NicInfo->HwAddressSize,\r
1990 NicInfo->VlanId,\r
1991 MacString\r
1992 );\r
1993\r
d1050b9d 1994 UnicodeSPrint (mPrivate->PortString, (UINTN)ISCSI_NAME_IFR_MAX_SIZE, L"MAC %s", MacString);\r
4c5a5e0c 1995 PortTitleToken = HiiSetString (\r
1996 mCallbackInfo->RegisteredHandle,\r
1997 0,\r
1998 mPrivate->PortString,\r
1999 NULL\r
2000 );\r
2001 if (PortTitleToken == 0) {\r
2002 Status = EFI_INVALID_PARAMETER;\r
2003 goto Exit;\r
2004 }\r
2005\r
2006 UnicodeSPrint (\r
2007 mPrivate->PortString,\r
d1050b9d 2008 (UINTN)ISCSI_NAME_IFR_MAX_SIZE,\r
4c5a5e0c 2009 L"PFA: Bus %d | Dev %d | Func %d",\r
2010 NicInfo->BusNumber,\r
2011 NicInfo->DeviceNumber,\r
2012 NicInfo->FunctionNumber\r
2013 );\r
2014 PortTitleHelpToken = HiiSetString (mCallbackInfo->RegisteredHandle, 0, mPrivate->PortString, NULL);\r
2015 if (PortTitleHelpToken == 0) {\r
2016 Status = EFI_INVALID_PARAMETER;\r
f75a7f56 2017 goto Exit;\r
4c5a5e0c 2018 }\r
2019\r
2020 HiiCreateGotoOpCode (\r
2021 StartOpCodeHandle, // Container for dynamic created opcodes\r
2022 FORMID_ATTEMPT_FORM,\r
2023 PortTitleToken,\r
2024 PortTitleHelpToken,\r
2025 EFI_IFR_FLAG_CALLBACK, // Question flag\r
d1050b9d 2026 (UINT16)(KEY_MAC_ENTRY_BASE + NicInfo->NicIndex)\r
4c5a5e0c 2027 );\r
2028 }\r
2029\r
2030 Status = HiiUpdateForm (\r
2031 mCallbackInfo->RegisteredHandle, // HII handle\r
9bdc6592 2032 &gIScsiConfigGuid, // Formset GUID\r
4c5a5e0c 2033 FORMID_MAC_FORM, // Form ID\r
2034 StartOpCodeHandle, // Label for where to insert opcodes\r
2035 EndOpCodeHandle // Replace data\r
2036 );\r
2037\r
2038Exit:\r
2039 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
2040 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
f75a7f56 2041\r
4c5a5e0c 2042 return Status;\r
2043}\r
2044\r
4c5a5e0c 2045/**\r
8d1f5e04
ZL
2046 Add the attempts by keyword 'iSCSIAddAttempts', you can use this keyword with\r
2047 value 'attempt:1 attempt:2' etc to add one or more attempts once. This is different\r
f75a7f56 2048 with IScsiConfigAddAttempt function which is used to add attempt by UI configuration.\r
8d1f5e04
ZL
2049\r
2050 @param[in] AttemptList The new attempt List will be added.\r
2051\r
2052 @retval EFI_SUCCESS The operation to add attempt list successfully.\r
2053 @retval EFI_INVALID_PARAMETER Any parameter is invalid.\r
2054 @retval EFI_NOT_FOUND Cannot find the corresponding variable.\r
2055 @retval EFI_OUT_OF_RESOURCES Fail to finish the operation due to lack of\r
2056 resources.\r
4c5a5e0c 2057\r
2058**/\r
8d1f5e04
ZL
2059EFI_STATUS\r
2060IScsiConfigAddAttemptsByKeywords (\r
d1050b9d 2061 IN UINT8 *AttemptList\r
4c5a5e0c 2062 )\r
2063{\r
d1050b9d
MK
2064 UINT8 Index;\r
2065 UINT8 Number;\r
2066 UINTN TotalNumber;\r
2067 UINT8 Nic;\r
2068 UINT8 *AttemptConfigOrder;\r
2069 UINTN AttemptConfigOrderSize;\r
2070 UINT8 *AttemptConfigOrderTmp;\r
2071 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;\r
2072 ISCSI_NIC_INFO *NicInfo;\r
2073 CHAR16 MacString[ISCSI_MAX_MAC_STRING_LEN];\r
2074 CHAR16 IScsiMode[64];\r
2075 CHAR16 IpMode[64];\r
2076 EFI_STATUS Status;\r
2077\r
2078 Nic = mPrivate->CurrentNic;\r
8d1f5e04
ZL
2079 NicInfo = IScsiGetNicInfoByIndex (Nic);\r
2080 if (NicInfo == NULL) {\r
2081 return EFI_NOT_FOUND;\r
4c5a5e0c 2082 }\r
2083\r
8d1f5e04
ZL
2084 //\r
2085 // The MAC info will be recorded in Config Data.\r
2086 //\r
2087 IScsiMacAddrToStr (\r
2088 &NicInfo->PermanentAddress,\r
2089 NicInfo->HwAddressSize,\r
2090 NicInfo->VlanId,\r
2091 MacString\r
2092 );\r
2093\r
2094 for (Index = 0; Index < PcdGet8 (PcdMaxIScsiAttemptNumber); Index++) {\r
2095 if (AttemptList[Index] == 0) {\r
2096 continue;\r
2097 }\r
2098\r
2099 //\r
2100 // Add the attempt.\r
2101 //\r
2102 Number = AttemptList[Index];\r
2103\r
2104 UnicodeSPrint (\r
2105 mPrivate->PortString,\r
d1050b9d 2106 (UINTN)ISCSI_NAME_IFR_MAX_SIZE,\r
8d1f5e04
ZL
2107 L"Attempt %d",\r
2108 Number\r
2109 );\r
2110\r
2111 GetVariable2 (\r
d1050b9d
MK
2112 mPrivate->PortString,\r
2113 &gEfiIScsiInitiatorNameProtocolGuid,\r
2114 (VOID **)&AttemptConfigData,\r
2115 NULL\r
2116 );\r
2117 if ((AttemptConfigData == NULL) || (AttemptConfigData->Actived == ISCSI_ACTIVE_ENABLED)) {\r
8d1f5e04
ZL
2118 return EFI_INVALID_PARAMETER;\r
2119 }\r
2120\r
d1050b9d 2121 AttemptConfigData->Actived = ISCSI_ACTIVE_ENABLED;\r
8d1f5e04
ZL
2122 AttemptConfigData->NicIndex = NicInfo->NicIndex;\r
2123 UnicodeStrToAsciiStrS (MacString, AttemptConfigData->MacString, ISCSI_MAX_MAC_STRING_LEN);\r
2124\r
2125 //\r
2126 // Generate OUI-format ISID based on MAC address.\r
2127 //\r
2128 CopyMem (AttemptConfigData->SessionConfigData.IsId, &NicInfo->PermanentAddress, 6);\r
2129 AttemptConfigData->SessionConfigData.IsId[0] =\r
d1050b9d 2130 (UINT8)(AttemptConfigData->SessionConfigData.IsId[0] & 0x3F);\r
8d1f5e04
ZL
2131\r
2132 //\r
2133 // Configure the iSCSI Mode and IpMode to default.\r
2134 // Add Attempt Help Info.\r
2135 //\r
2136 UnicodeSPrint (IScsiMode, 64, L"Disabled");\r
2137 UnicodeSPrint (IpMode, 64, L"IP4");\r
2138 UnicodeSPrint (\r
2139 mPrivate->PortString,\r
d1050b9d 2140 (UINTN)ISCSI_NAME_IFR_MAX_SIZE,\r
8d1f5e04
ZL
2141 L"MAC: %s, PFA: Bus %d | Dev %d | Func %d, iSCSI mode: %s, IP version: %s",\r
2142 MacString,\r
2143 NicInfo->BusNumber,\r
2144 NicInfo->DeviceNumber,\r
2145 NicInfo->FunctionNumber,\r
2146 IScsiMode,\r
2147 IpMode\r
2148 );\r
2149\r
2150 AttemptConfigData->AttemptTitleHelpToken = HiiSetString (\r
2151 mCallbackInfo->RegisteredHandle,\r
2152 0,\r
2153 mPrivate->PortString,\r
2154 NULL\r
2155 );\r
2156 if (AttemptConfigData->AttemptTitleHelpToken == 0) {\r
2157 return EFI_OUT_OF_RESOURCES;\r
2158 }\r
2159\r
2160 //\r
2161 // Get current Attempt order and number.\r
2162 //\r
2163 AttemptConfigOrder = IScsiGetVariableAndSize (\r
2164 L"AttemptOrder",\r
2165 &gIScsiConfigGuid,\r
2166 &AttemptConfigOrderSize\r
2167 );\r
2168 TotalNumber = AttemptConfigOrderSize / sizeof (UINT8);\r
2169 TotalNumber++;\r
2170\r
2171 //\r
2172 // Append the new created attempt order to the end.\r
2173 //\r
2174 AttemptConfigOrderTmp = AllocateZeroPool (TotalNumber * sizeof (UINT8));\r
2175 if (AttemptConfigOrderTmp == NULL) {\r
2176 if (AttemptConfigOrder != NULL) {\r
2177 FreePool (AttemptConfigOrder);\r
2178 }\r
d1050b9d 2179\r
8d1f5e04
ZL
2180 return EFI_OUT_OF_RESOURCES;\r
2181 }\r
d1050b9d 2182\r
8d1f5e04
ZL
2183 if (AttemptConfigOrder != NULL) {\r
2184 CopyMem (AttemptConfigOrderTmp, AttemptConfigOrder, AttemptConfigOrderSize);\r
2185 FreePool (AttemptConfigOrder);\r
2186 }\r
2187\r
2188 AttemptConfigOrderTmp[TotalNumber - 1] = Number;\r
d1050b9d
MK
2189 AttemptConfigOrder = AttemptConfigOrderTmp;\r
2190 AttemptConfigOrderSize = TotalNumber * sizeof (UINT8);\r
4c5a5e0c 2191\r
8d1f5e04
ZL
2192 Status = gRT->SetVariable (\r
2193 L"AttemptOrder",\r
2194 &gIScsiConfigGuid,\r
2195 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
2196 AttemptConfigOrderSize,\r
2197 AttemptConfigOrder\r
2198 );\r
2199 FreePool (AttemptConfigOrder);\r
2200 if (EFI_ERROR (Status)) {\r
2201 return Status;\r
4c5a5e0c 2202 }\r
2203\r
8d1f5e04
ZL
2204 //\r
2205 // Record the attempt in global link list.\r
2206 //\r
2207 InsertTailList (&mPrivate->AttemptConfigs, &AttemptConfigData->Link);\r
2208 mPrivate->AttemptCount++;\r
d1050b9d 2209 UnicodeSPrint (mPrivate->PortString, (UINTN)ISCSI_NAME_IFR_MAX_SIZE, L"Attempt %d", AttemptConfigData->AttemptConfigIndex);\r
8d1f5e04
ZL
2210 gRT->SetVariable (\r
2211 mPrivate->PortString,\r
2212 &gEfiIScsiInitiatorNameProtocolGuid,\r
2213 ISCSI_CONFIG_VAR_ATTR,\r
2214 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),\r
2215 AttemptConfigData\r
2216 );\r
8d1f5e04 2217 }\r
4c5a5e0c 2218\r
8d1f5e04 2219 return EFI_SUCCESS;\r
4c5a5e0c 2220}\r
2221\r
4c5a5e0c 2222/**\r
8d1f5e04 2223 Callback function when user presses "Commit Changes and Exit" in Delete Attempts or Delete Attempts by Keyword.\r
4c5a5e0c 2224\r
2225 @param[in] IfrNvData The IFR NV data.\r
2226\r
2227 @retval EFI_NOT_FOUND Cannot find the corresponding variable.\r
2228 @retval EFI_SUCCESS The operation is completed successfully.\r
efb56593 2229 @retval EFI_ABORTED This operation is aborted cause of error\r
4c5a5e0c 2230 configuration.\r
2231 @retval EFI_OUT_OF_RESOURCES Fail to finish the operation due to lack of\r
2232 resources.\r
2233\r
2234**/\r
2235EFI_STATUS\r
2236IScsiConfigDeleteAttempts (\r
2237 IN ISCSI_CONFIG_IFR_NVDATA *IfrNvData\r
2238 )\r
2239{\r
d1050b9d
MK
2240 EFI_STATUS Status;\r
2241 UINTN Index;\r
2242 UINTN NewIndex;\r
2243 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;\r
2244 UINT8 *AttemptConfigOrder;\r
2245 UINTN AttemptConfigOrderSize;\r
2246 UINT8 *AttemptNewOrder;\r
2247 UINT8 AttemptConfigIndex;\r
2248 UINT32 Attribute;\r
2249 UINTN Total;\r
2250 UINTN NewTotal;\r
2251 LIST_ENTRY *Entry;\r
2252 LIST_ENTRY *NextEntry;\r
2253 ISCSI_SESSION_CONFIG_NVDATA *ConfigData;\r
2254\r
2255 Index = 0;\r
4c5a5e0c 2256\r
2257 AttemptConfigOrder = IScsiGetVariableAndSize (\r
2258 L"AttemptOrder",\r
9bdc6592 2259 &gIScsiConfigGuid,\r
4c5a5e0c 2260 &AttemptConfigOrderSize\r
2261 );\r
2262 if ((AttemptConfigOrder == NULL) || (AttemptConfigOrderSize == 0)) {\r
2263 return EFI_NOT_FOUND;\r
2264 }\r
2265\r
2266 AttemptNewOrder = AllocateZeroPool (AttemptConfigOrderSize);\r
2267 if (AttemptNewOrder == NULL) {\r
c0d494b5 2268 Status = EFI_OUT_OF_RESOURCES;\r
2269 goto Error;\r
4c5a5e0c 2270 }\r
2271\r
2272 Total = AttemptConfigOrderSize / sizeof (UINT8);\r
2273 NewTotal = Total;\r
4c5a5e0c 2274\r
2275 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &mPrivate->AttemptConfigs) {\r
2276 if (IfrNvData->DeleteAttemptList[Index] == 0) {\r
2277 Index++;\r
2278 continue;\r
2279 }\r
2280\r
2281 //\r
2282 // Delete the attempt.\r
2283 //\r
2284\r
2285 AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);\r
4c5a5e0c 2286\r
2287 //\r
2288 // Remove this attempt from UI configured attempt list.\r
2289 //\r
2290 RemoveEntryList (&AttemptConfigData->Link);\r
2291 mPrivate->AttemptCount--;\r
2292\r
2293 if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO) {\r
2294 if (mPrivate->MpioCount < 1) {\r
2295 Status = EFI_ABORTED;\r
2296 goto Error;\r
2297 }\r
2298\r
2299 //\r
2300 // No more attempt is enabled for MPIO. Transit the iSCSI mode to single path.\r
2301 //\r
2302 if (--mPrivate->MpioCount == 0) {\r
2303 mPrivate->EnableMpio = FALSE;\r
2304 }\r
2305 } else if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED) {\r
2306 if (mPrivate->SinglePathCount < 1) {\r
2307 Status = EFI_ABORTED;\r
2308 goto Error;\r
2309 }\r
2310\r
2311 mPrivate->SinglePathCount--;\r
2312 }\r
2313\r
8d1f5e04
ZL
2314 AttemptConfigIndex = AttemptConfigData->AttemptConfigIndex;\r
2315 FreePool (AttemptConfigData);\r
2316\r
2317 //\r
2318 // Create a new Attempt\r
2319 //\r
2320 AttemptConfigData = AllocateZeroPool (sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA));\r
2321 if (AttemptConfigData == NULL) {\r
2322 return EFI_OUT_OF_RESOURCES;\r
2323 }\r
d1050b9d 2324\r
8d1f5e04
ZL
2325 ConfigData = &AttemptConfigData->SessionConfigData;\r
2326 ConfigData->TargetPort = ISCSI_WELL_KNOWN_PORT;\r
2327 ConfigData->ConnectTimeout = CONNECT_DEFAULT_TIMEOUT;\r
2328 ConfigData->ConnectRetryCount = CONNECT_MIN_RETRY;\r
2329\r
2330 AttemptConfigData->AuthenticationType = ISCSI_AUTH_TYPE_CHAP;\r
2331 AttemptConfigData->AuthConfigData.CHAP.CHAPType = ISCSI_CHAP_UNI;\r
2332 //\r
2333 // Configure the Attempt index and set variable.\r
2334 //\r
2335 AttemptConfigData->AttemptConfigIndex = AttemptConfigIndex;\r
4c5a5e0c 2336\r
8d1f5e04
ZL
2337 //\r
2338 // Set the attempt name to default.\r
2339 //\r
4c5a5e0c 2340 UnicodeSPrint (\r
2341 mPrivate->PortString,\r
d1050b9d 2342 (UINTN)ISCSI_NAME_IFR_MAX_SIZE,\r
8d1f5e04 2343 L"Attempt %d",\r
d1050b9d 2344 (UINTN)AttemptConfigData->AttemptConfigIndex\r
4c5a5e0c 2345 );\r
8d1f5e04 2346 UnicodeStrToAsciiStrS (mPrivate->PortString, AttemptConfigData->AttemptName, ATTEMPT_NAME_SIZE);\r
4c5a5e0c 2347 gRT->SetVariable (\r
2348 mPrivate->PortString,\r
2349 &gEfiIScsiInitiatorNameProtocolGuid,\r
8d1f5e04
ZL
2350 ISCSI_CONFIG_VAR_ATTR,\r
2351 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),\r
2352 AttemptConfigData\r
4c5a5e0c 2353 );\r
2354\r
2355 //\r
2356 // Mark the attempt order in NVR to be deleted - 0.\r
2357 //\r
2358 for (NewIndex = 0; NewIndex < Total; NewIndex++) {\r
2359 if (AttemptConfigOrder[NewIndex] == AttemptConfigData->AttemptConfigIndex) {\r
2360 AttemptConfigOrder[NewIndex] = 0;\r
2361 break;\r
2362 }\r
2363 }\r
2364\r
2365 NewTotal--;\r
8d1f5e04
ZL
2366 if (mCallbackInfo->Current == AttemptConfigData) {\r
2367 mCallbackInfo->Current = NULL;\r
2368 }\r
d1050b9d 2369\r
4c5a5e0c 2370 FreePool (AttemptConfigData);\r
2371\r
2372 //\r
2373 // Check next Attempt.\r
2374 //\r
2375 Index++;\r
2376 }\r
2377\r
2378 //\r
2379 // Construct AttemptNewOrder.\r
2380 //\r
2381 for (Index = 0, NewIndex = 0; Index < Total; Index++) {\r
2382 if (AttemptConfigOrder[Index] != 0) {\r
2383 AttemptNewOrder[NewIndex] = AttemptConfigOrder[Index];\r
2384 NewIndex++;\r
2385 }\r
2386 }\r
2387\r
9c12f2d7 2388 Attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE;\r
4c5a5e0c 2389\r
2390 //\r
2391 // Update AttemptOrder in NVR.\r
2392 //\r
2393 Status = gRT->SetVariable (\r
2394 L"AttemptOrder",\r
9bdc6592 2395 &gIScsiConfigGuid,\r
4c5a5e0c 2396 Attribute,\r
2397 NewTotal * sizeof (UINT8),\r
2398 AttemptNewOrder\r
2399 );\r
2400\r
2401Error:\r
c0d494b5 2402 if (AttemptConfigOrder != NULL) {\r
2403 FreePool (AttemptConfigOrder);\r
2404 }\r
2405\r
2406 if (AttemptNewOrder != NULL) {\r
2407 FreePool (AttemptNewOrder);\r
2408 }\r
8d1f5e04 2409\r
4c5a5e0c 2410 return Status;\r
2411}\r
2412\r
4c5a5e0c 2413/**\r
2414 Callback function when user presses "Delete Attempts".\r
2415\r
2416 @param[in] IfrNvData The IFR nv data.\r
2417\r
2418 @retval EFI_INVALID_PARAMETER Any parameter is invalid.\r
2419 @retval EFI_BUFFER_TOO_SMALL The buffer in UpdateData is too small.\r
2420 @retval EFI_SUCCESS The operation is completed successfully.\r
2421\r
2422**/\r
2423EFI_STATUS\r
2424IScsiConfigDisplayDeleteAttempts (\r
2425 IN ISCSI_CONFIG_IFR_NVDATA *IfrNvData\r
2426 )\r
2427{\r
d1050b9d
MK
2428 UINT8 *AttemptConfigOrder;\r
2429 UINTN AttemptConfigOrderSize;\r
2430 LIST_ENTRY *Entry;\r
2431 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;\r
2432 UINT8 Index;\r
2433 VOID *StartOpCodeHandle;\r
2434 EFI_IFR_GUID_LABEL *StartLabel;\r
2435 VOID *EndOpCodeHandle;\r
2436 EFI_IFR_GUID_LABEL *EndLabel;\r
2437 EFI_STATUS Status;\r
4c5a5e0c 2438\r
2439 Status = IScsiCreateOpCode (\r
2440 DELETE_ENTRY_LABEL,\r
2441 &StartOpCodeHandle,\r
2442 &StartLabel,\r
2443 &EndOpCodeHandle,\r
2444 &EndLabel\r
2445 );\r
2446 if (EFI_ERROR (Status)) {\r
2447 return Status;\r
2448 }\r
2449\r
2450 AttemptConfigOrder = IScsiGetVariableAndSize (\r
2451 L"AttemptOrder",\r
9bdc6592 2452 &gIScsiConfigGuid,\r
4c5a5e0c 2453 &AttemptConfigOrderSize\r
2454 );\r
2455 if (AttemptConfigOrder != NULL) {\r
2456 //\r
2457 // Create the check box opcode to be deleted.\r
2458 //\r
2459 Index = 0;\r
2460\r
2461 NET_LIST_FOR_EACH (Entry, &mPrivate->AttemptConfigs) {\r
d1050b9d 2462 AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);\r
4c5a5e0c 2463 IfrNvData->DeleteAttemptList[Index] = 0x00;\r
2464\r
d1050b9d 2465 HiiCreateCheckBoxOpCode (\r
4c5a5e0c 2466 StartOpCodeHandle,\r
d1050b9d 2467 (EFI_QUESTION_ID)(ATTEMPT_DEL_QUESTION_ID + Index),\r
4c5a5e0c 2468 CONFIGURATION_VARSTORE_ID,\r
d1050b9d 2469 (UINT16)(ATTEMPT_DEL_VAR_OFFSET + Index),\r
4c5a5e0c 2470 AttemptConfigData->AttemptTitleToken,\r
2471 AttemptConfigData->AttemptTitleHelpToken,\r
2472 0,\r
2473 0,\r
2474 NULL\r
2475 );\r
2476\r
2477 Index++;\r
2478\r
2479 if (Index == ISCSI_MAX_ATTEMPTS_NUM) {\r
2480 break;\r
2481 }\r
2482 }\r
2483\r
2484 FreePool (AttemptConfigOrder);\r
2485 }\r
2486\r
2487 Status = HiiUpdateForm (\r
2488 mCallbackInfo->RegisteredHandle, // HII handle\r
9bdc6592 2489 &gIScsiConfigGuid, // Formset GUID\r
4c5a5e0c 2490 FORMID_DELETE_FORM, // Form ID\r
2491 StartOpCodeHandle, // Label for where to insert opcodes\r
2492 EndOpCodeHandle // Replace data\r
f75a7f56 2493 );\r
4c5a5e0c 2494\r
2495 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
2496 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
2497\r
2498 return Status;\r
2499}\r
2500\r
4c5a5e0c 2501/**\r
2502 Callback function when user presses "Change Attempt Order".\r
2503\r
2504 @retval EFI_INVALID_PARAMETER Any parameter is invalid.\r
2505 @retval EFI_OUT_OF_RESOURCES Does not have sufficient resources to finish this\r
2506 operation.\r
2507 @retval EFI_SUCCESS The operation is completed successfully.\r
2508\r
2509**/\r
2510EFI_STATUS\r
2511IScsiConfigDisplayOrderAttempts (\r
2512 VOID\r
2513 )\r
2514{\r
d1050b9d
MK
2515 EFI_STATUS Status;\r
2516 UINT8 Index;\r
2517 LIST_ENTRY *Entry;\r
2518 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;\r
2519 VOID *StartOpCodeHandle;\r
2520 EFI_IFR_GUID_LABEL *StartLabel;\r
2521 VOID *EndOpCodeHandle;\r
2522 EFI_IFR_GUID_LABEL *EndLabel;\r
2523 VOID *OptionsOpCodeHandle;\r
f75a7f56 2524\r
4c5a5e0c 2525 Status = IScsiCreateOpCode (\r
2526 ORDER_ENTRY_LABEL,\r
2527 &StartOpCodeHandle,\r
2528 &StartLabel,\r
2529 &EndOpCodeHandle,\r
2530 &EndLabel\r
2531 );\r
2532 if (EFI_ERROR (Status)) {\r
2533 return Status;\r
2534 }\r
d1050b9d 2535\r
7a49cd08 2536 ASSERT (StartOpCodeHandle != NULL);\r
4c5a5e0c 2537\r
2538 OptionsOpCodeHandle = NULL;\r
2539\r
2540 //\r
2541 // If no attempt to be ordered, update the original form and exit.\r
2542 //\r
2543 if (mPrivate->AttemptCount == 0) {\r
2544 goto Exit;\r
2545 }\r
2546\r
2547 //\r
2548 // Create Option OpCode.\r
2549 //\r
2550 OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();\r
2551 if (OptionsOpCodeHandle == NULL) {\r
2552 Status = EFI_OUT_OF_RESOURCES;\r
2553 goto Error;\r
2554 }\r
2555\r
2556 Index = 0;\r
2557\r
2558 NET_LIST_FOR_EACH (Entry, &mPrivate->AttemptConfigs) {\r
2559 AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);\r
2560 HiiCreateOneOfOptionOpCode (\r
2561 OptionsOpCodeHandle,\r
2562 AttemptConfigData->AttemptTitleToken,\r
2563 0,\r
2564 EFI_IFR_NUMERIC_SIZE_1,\r
2565 AttemptConfigData->AttemptConfigIndex\r
2566 );\r
2567 Index++;\r
2568 }\r
2569\r
2570 ASSERT (Index == mPrivate->AttemptCount);\r
2571\r
2572 HiiCreateOrderedListOpCode (\r
2573 StartOpCodeHandle, // Container for dynamic created opcodes\r
2574 DYNAMIC_ORDERED_LIST_QUESTION_ID, // Question ID\r
2575 CONFIGURATION_VARSTORE_ID, // VarStore ID\r
2576 DYNAMIC_ORDERED_LIST_VAR_OFFSET, // Offset in Buffer Storage\r
f75a7f56
LG
2577 STRING_TOKEN (STR_ORDER_ATTEMPT_ENTRY), // Question prompt text\r
2578 STRING_TOKEN (STR_ORDER_ATTEMPT_ENTRY), // Question help text\r
4c5a5e0c 2579 0, // Question flag\r
2580 EFI_IFR_UNIQUE_SET, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET\r
2581 EFI_IFR_NUMERIC_SIZE_1, // Data type of Question value\r
2582 ISCSI_MAX_ATTEMPTS_NUM, // Maximum container\r
f75a7f56
LG
2583 OptionsOpCodeHandle, // Option Opcode list\r
2584 NULL // Default Opcode is NULL\r
4c5a5e0c 2585 );\r
2586\r
2587Exit:\r
2588 Status = HiiUpdateForm (\r
2589 mCallbackInfo->RegisteredHandle, // HII handle\r
9bdc6592 2590 &gIScsiConfigGuid, // Formset GUID\r
4c5a5e0c 2591 FORMID_ORDER_FORM, // Form ID\r
2592 StartOpCodeHandle, // Label for where to insert opcodes\r
2593 EndOpCodeHandle // Replace data\r
f75a7f56 2594 );\r
4c5a5e0c 2595\r
2596Error:\r
2597 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
f75a7f56 2598 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
4c5a5e0c 2599 if (OptionsOpCodeHandle != NULL) {\r
2600 HiiFreeOpCodeHandle (OptionsOpCodeHandle);\r
2601 }\r
2602\r
2603 return Status;\r
2604}\r
2605\r
4c5a5e0c 2606/**\r
8d1f5e04 2607 Callback function when user presses "Commit Changes and Exit" in Change Attempt Order or Change Attempt Order by Keyword.\r
4c5a5e0c 2608\r
2609 @param[in] IfrNvData The IFR nv data.\r
2610\r
2611 @retval EFI_OUT_OF_RESOURCES Does not have sufficient resources to finish this\r
2612 operation.\r
2613 @retval EFI_NOT_FOUND Cannot find the corresponding variable.\r
2614 @retval EFI_SUCCESS The operation is completed successfully.\r
2615\r
2616**/\r
2617EFI_STATUS\r
2618IScsiConfigOrderAttempts (\r
2619 IN ISCSI_CONFIG_IFR_NVDATA *IfrNvData\r
2620 )\r
2621{\r
d1050b9d
MK
2622 EFI_STATUS Status;\r
2623 UINTN Index;\r
2624 UINTN Indexj;\r
2625 UINT8 AttemptConfigIndex;\r
2626 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;\r
2627 UINT8 *AttemptConfigOrder;\r
2628 UINT8 *AttemptConfigOrderTmp;\r
2629 UINTN AttemptConfigOrderSize;\r
4c5a5e0c 2630\r
2631 AttemptConfigOrder = IScsiGetVariableAndSize (\r
2632 L"AttemptOrder",\r
9bdc6592 2633 &gIScsiConfigGuid,\r
4c5a5e0c 2634 &AttemptConfigOrderSize\r
2635 );\r
2636 if (AttemptConfigOrder == NULL) {\r
2637 return EFI_NOT_FOUND;\r
2638 }\r
2639\r
2640 AttemptConfigOrderTmp = AllocateZeroPool (AttemptConfigOrderSize);\r
2641 if (AttemptConfigOrderTmp == NULL) {\r
2642 Status = EFI_OUT_OF_RESOURCES;\r
2643 goto Exit;\r
2644 }\r
2645\r
2646 for (Index = 0; Index < ISCSI_MAX_ATTEMPTS_NUM; Index++) {\r
2647 //\r
2648 // The real content ends with 0.\r
2649 //\r
2650 if (IfrNvData->DynamicOrderedList[Index] == 0) {\r
2651 break;\r
2652 }\r
2653\r
2654 AttemptConfigIndex = IfrNvData->DynamicOrderedList[Index];\r
2655 AttemptConfigData = IScsiConfigGetAttemptByConfigIndex (AttemptConfigIndex);\r
2656 if (AttemptConfigData == NULL) {\r
2657 Status = EFI_NOT_FOUND;\r
2658 goto Exit;\r
2659 }\r
2660\r
2661 //\r
2662 // Reorder the Attempt List.\r
2663 //\r
2664 RemoveEntryList (&AttemptConfigData->Link);\r
2665 InsertTailList (&mPrivate->AttemptConfigs, &AttemptConfigData->Link);\r
2666\r
2667 AttemptConfigOrderTmp[Index] = AttemptConfigIndex;\r
2668\r
2669 //\r
2670 // Mark it to be deleted - 0.\r
2671 //\r
2672 for (Indexj = 0; Indexj < AttemptConfigOrderSize / sizeof (UINT8); Indexj++) {\r
2673 if (AttemptConfigOrder[Indexj] == AttemptConfigIndex) {\r
2674 AttemptConfigOrder[Indexj] = 0;\r
2675 break;\r
2676 }\r
2677 }\r
2678 }\r
2679\r
2680 //\r
2681 // Adjust the attempt order in NVR.\r
2682 //\r
d1050b9d 2683 for ( ; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {\r
4c5a5e0c 2684 for (Indexj = 0; Indexj < AttemptConfigOrderSize / sizeof (UINT8); Indexj++) {\r
2685 if (AttemptConfigOrder[Indexj] != 0) {\r
2686 AttemptConfigOrderTmp[Index] = AttemptConfigOrder[Indexj];\r
2687 AttemptConfigOrder[Indexj] = 0;\r
2688 continue;\r
2689 }\r
2690 }\r
2691 }\r
2692\r
2693 Status = gRT->SetVariable (\r
2694 L"AttemptOrder",\r
9bdc6592 2695 &gIScsiConfigGuid,\r
9c12f2d7 2696 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
4c5a5e0c 2697 AttemptConfigOrderSize,\r
2698 AttemptConfigOrderTmp\r
2699 );\r
2700\r
2701Exit:\r
2702 if (AttemptConfigOrderTmp != NULL) {\r
2703 FreePool (AttemptConfigOrderTmp);\r
2704 }\r
2705\r
2706 FreePool (AttemptConfigOrder);\r
2707 return Status;\r
2708}\r
2709\r
4c5a5e0c 2710/**\r
2711 Callback function when a user presses "Attempt *" or when a user selects a NIC to\r
2712 create the new attempt.\r
2713\r
2714 @param[in] KeyValue A unique value which is sent to the original\r
2715 exporting driver so that it can identify the type\r
2716 of data to expect.\r
2717 @param[in] IfrNvData The IFR nv data.\r
2718\r
2719 @retval EFI_OUT_OF_RESOURCES Does not have sufficient resources to finish this\r
2720 operation.\r
2721 @retval EFI_NOT_FOUND Cannot find the corresponding variable.\r
8d1f5e04 2722 @retval EFI_UNSUPPORTED Can not create more attempts.\r
4c5a5e0c 2723 @retval EFI_SUCCESS The operation is completed successfully.\r
2724\r
2725**/\r
2726EFI_STATUS\r
2727IScsiConfigProcessDefault (\r
d1050b9d
MK
2728 IN EFI_QUESTION_ID KeyValue,\r
2729 IN ISCSI_CONFIG_IFR_NVDATA *IfrNvData\r
4c5a5e0c 2730 )\r
2731{\r
d1050b9d
MK
2732 BOOLEAN NewAttempt;\r
2733 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;\r
2734 UINT8 CurrentAttemptConfigIndex;\r
2735 ISCSI_NIC_INFO *NicInfo;\r
2736 UINT8 NicIndex;\r
2737 CHAR16 MacString[ISCSI_MAX_MAC_STRING_LEN];\r
2738 UINT8 *AttemptConfigOrder;\r
2739 UINTN AttemptConfigOrderSize;\r
2740 UINTN Index;\r
2741 EFI_INPUT_KEY Key;\r
4c5a5e0c 2742\r
2fd40fa5 2743 AttemptConfigData = NULL;\r
c0d494b5 2744 //\r
2745 // Is User creating a new attempt?\r
2746 //\r
4c5a5e0c 2747 NewAttempt = FALSE;\r
2748\r
2749 if ((KeyValue >= KEY_MAC_ENTRY_BASE) &&\r
d1050b9d
MK
2750 (KeyValue <= (UINT16)(mPrivate->MaxNic + KEY_MAC_ENTRY_BASE)))\r
2751 {\r
4c5a5e0c 2752 //\r
2753 // User has pressed "Add an Attempt" and then selects a NIC.\r
2754 //\r
2755 NewAttempt = TRUE;\r
2756 } else if ((KeyValue >= KEY_ATTEMPT_ENTRY_BASE) &&\r
d1050b9d
MK
2757 (KeyValue < (ISCSI_MAX_ATTEMPTS_NUM + KEY_ATTEMPT_ENTRY_BASE)))\r
2758 {\r
4c5a5e0c 2759 //\r
2760 // User has pressed "Attempt *".\r
2761 //\r
2762 NewAttempt = FALSE;\r
2763 } else {\r
2764 //\r
2765 // Don't process anything.\r
2766 //\r
2767 return EFI_SUCCESS;\r
2768 }\r
2769\r
2770 if (NewAttempt) {\r
2771 //\r
2772 // Determine which NIC user has selected for the new created attempt.\r
2773 //\r
d1050b9d
MK
2774 NicIndex = (UINT8)(KeyValue - KEY_MAC_ENTRY_BASE);\r
2775 NicInfo = IScsiGetNicInfoByIndex (NicIndex);\r
4c5a5e0c 2776 if (NicInfo == NULL) {\r
2777 return EFI_NOT_FOUND;\r
2778 }\r
4c5a5e0c 2779\r
2780 //\r
8d1f5e04 2781 // Create an attempt following the initialized attempt order.\r
4c5a5e0c 2782 //\r
2783 AttemptConfigOrder = IScsiGetVariableAndSize (\r
8d1f5e04 2784 L"InitialAttemptOrder",\r
9bdc6592 2785 &gIScsiConfigGuid,\r
4c5a5e0c 2786 &AttemptConfigOrderSize\r
2787 );\r
2788\r
2fd40fa5
ZL
2789 if (AttemptConfigOrder == NULL) {\r
2790 return EFI_NOT_FOUND;\r
2791 }\r
4c5a5e0c 2792\r
2fd40fa5
ZL
2793 for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {\r
2794 UnicodeSPrint (\r
2795 mPrivate->PortString,\r
d1050b9d 2796 (UINTN)ISCSI_NAME_IFR_MAX_SIZE,\r
2fd40fa5 2797 L"Attempt %d",\r
d1050b9d 2798 (UINTN)AttemptConfigOrder[Index]\r
2fd40fa5
ZL
2799 );\r
2800 GetVariable2 (\r
d1050b9d
MK
2801 mPrivate->PortString,\r
2802 &gEfiIScsiInitiatorNameProtocolGuid,\r
2803 (VOID **)&AttemptConfigData,\r
2804 NULL\r
2805 );\r
2806 if ((AttemptConfigData == NULL) || (AttemptConfigData->Actived == ISCSI_ACTIVE_ENABLED)) {\r
2fd40fa5 2807 continue;\r
8d1f5e04 2808 }\r
f75a7f56 2809\r
2fd40fa5
ZL
2810 break;\r
2811 }\r
f75a7f56 2812\r
2fd40fa5
ZL
2813 if (Index > PcdGet8 (PcdMaxIScsiAttemptNumber)) {\r
2814 CreatePopUp (\r
2815 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
2816 &Key,\r
2817 L"Can not create more attempts, Please configure the PcdMaxIScsiAttemptNumber if needed!",\r
2818 NULL\r
2819 );\r
2820 return EFI_UNSUPPORTED;\r
4c5a5e0c 2821 }\r
2822\r
4c5a5e0c 2823 if (AttemptConfigOrder != NULL) {\r
c0d494b5 2824 FreePool (AttemptConfigOrder);\r
4c5a5e0c 2825 }\r
2826\r
4c5a5e0c 2827 //\r
2828 // Record the MAC info in Config Data.\r
2829 //\r
2830 IScsiMacAddrToStr (\r
2831 &NicInfo->PermanentAddress,\r
2832 NicInfo->HwAddressSize,\r
2833 NicInfo->VlanId,\r
2834 MacString\r
2835 );\r
2836\r
2fd40fa5 2837 ASSERT (AttemptConfigData != NULL);\r
b9679cd7 2838 UnicodeStrToAsciiStrS (MacString, AttemptConfigData->MacString, sizeof (AttemptConfigData->MacString));\r
4c5a5e0c 2839 AttemptConfigData->NicIndex = NicIndex;\r
d1050b9d 2840 AttemptConfigData->Actived = ISCSI_ACTIVE_ENABLED;\r
4c5a5e0c 2841\r
2842 //\r
2843 // Generate OUI-format ISID based on MAC address.\r
2844 //\r
2845 CopyMem (AttemptConfigData->SessionConfigData.IsId, &NicInfo->PermanentAddress, 6);\r
f75a7f56 2846 AttemptConfigData->SessionConfigData.IsId[0] =\r
d1050b9d 2847 (UINT8)(AttemptConfigData->SessionConfigData.IsId[0] & 0x3F);\r
4c5a5e0c 2848\r
2849 //\r
2850 // Add the help info for the new attempt.\r
2851 //\r
2852 UnicodeSPrint (\r
2853 mPrivate->PortString,\r
d1050b9d 2854 (UINTN)ISCSI_NAME_IFR_MAX_SIZE,\r
4c5a5e0c 2855 L"MAC: %s, PFA: Bus %d | Dev %d | Func %d",\r
2856 MacString,\r
2857 NicInfo->BusNumber,\r
2858 NicInfo->DeviceNumber,\r
2859 NicInfo->FunctionNumber\r
2860 );\r
2861\r
d1050b9d
MK
2862 AttemptConfigData->AttemptTitleHelpToken = HiiSetString (\r
2863 mCallbackInfo->RegisteredHandle,\r
2864 0,\r
2865 mPrivate->PortString,\r
2866 NULL\r
2867 );\r
4c5a5e0c 2868 if (AttemptConfigData->AttemptTitleHelpToken == 0) {\r
2869 FreePool (AttemptConfigData);\r
8d1f5e04 2870 return EFI_OUT_OF_RESOURCES;\r
4c5a5e0c 2871 }\r
4c5a5e0c 2872 } else {\r
2873 //\r
2874 // Determine which Attempt user has selected to configure.\r
2875 // Get the attempt configuration data.\r
2876 //\r
d1050b9d 2877 CurrentAttemptConfigIndex = (UINT8)(KeyValue - KEY_ATTEMPT_ENTRY_BASE);\r
4c5a5e0c 2878\r
2879 AttemptConfigData = IScsiConfigGetAttemptByConfigIndex (CurrentAttemptConfigIndex);\r
2880 if (AttemptConfigData == NULL) {\r
2881 DEBUG ((DEBUG_ERROR, "Corresponding configuration data can not be retrieved!\n"));\r
2882 return EFI_NOT_FOUND;\r
2883 }\r
2884 }\r
2885\r
2886 //\r
2887 // Clear the old IFR data to avoid sharing it with other attempts.\r
2888 //\r
2889 if (IfrNvData->AuthenticationType == ISCSI_AUTH_TYPE_CHAP) {\r
2890 ZeroMem (IfrNvData->CHAPName, sizeof (IfrNvData->CHAPName));\r
2891 ZeroMem (IfrNvData->CHAPSecret, sizeof (IfrNvData->CHAPSecret));\r
2892 ZeroMem (IfrNvData->ReverseCHAPName, sizeof (IfrNvData->ReverseCHAPName));\r
2893 ZeroMem (IfrNvData->ReverseCHAPSecret, sizeof (IfrNvData->ReverseCHAPSecret));\r
2894 }\r
f75a7f56 2895\r
4c5a5e0c 2896 IScsiConvertAttemptConfigDataToIfrNvData (AttemptConfigData, IfrNvData);\r
2897\r
c0d494b5 2898 //\r
2899 // Update current attempt to be a new created attempt or an existing attempt.\r
2900 //\r
4c5a5e0c 2901 mCallbackInfo->Current = AttemptConfigData;\r
2902\r
4c5a5e0c 2903 return EFI_SUCCESS;\r
2904}\r
2905\r
4c5a5e0c 2906/**\r
f75a7f56 2907\r
4c5a5e0c 2908 This function allows the caller to request the current\r
2909 configuration for one or more named elements. The resulting\r
2910 string is in <ConfigAltResp> format. Also, any and all alternative\r
2911 configuration strings shall be appended to the end of the\r
2912 current configuration string. If they are, they must appear\r
2913 after the current configuration. They must contain the same\r
2914 routing (GUID, NAME, PATH) as the current configuration string.\r
2915 They must have an additional description indicating the type of\r
2916 alternative configuration the string represents,\r
2917 "ALTCFG=<StringToken>". That <StringToken> (when\r
2918 converted from Hex UNICODE to binary) is a reference to a\r
2919 string in the associated string pack.\r
2920\r
2921 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
2922\r
2923 @param[in] Request A null-terminated Unicode string in\r
2924 <ConfigRequest> format. Note that this\r
2925 includes the routing information as well as\r
2926 the configurable name / value pairs. It is\r
2927 invalid for this string to be in\r
2928 <MultiConfigRequest> format.\r
2929\r
2930 @param[out] Progress On return, points to a character in the\r
2931 Request string. Points to the string's null\r
2932 terminator if request was successful. Points\r
2933 to the most recent "&" before the first\r
2934 failing name / value pair (or the beginning\r
2935 of the string if the failure is in the first\r
f75a7f56 2936 name / value pair) if the request was not successful.\r
4c5a5e0c 2937\r
2938 @param[out] Results A null-terminated Unicode string in\r
2939 <ConfigAltResp> format which has all values\r
2940 filled in for the names in the Request string.\r
2941 String to be allocated by the called function.\r
2942\r
2943 @retval EFI_SUCCESS The Results string is filled with the\r
2944 values corresponding to all requested\r
2945 names.\r
2946\r
2947 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
2948 parts of the results that must be\r
2949 stored awaiting possible future\r
2950 protocols.\r
2951\r
2952 @retval EFI_INVALID_PARAMETER For example, passing in a NULL\r
2953 for the Request parameter\r
2954 would result in this type of\r
2955 error. In this case, the\r
2956 Progress parameter would be\r
f75a7f56 2957 set to NULL.\r
4c5a5e0c 2958\r
2959 @retval EFI_NOT_FOUND Routing data doesn't match any\r
2960 known driver. Progress set to the\r
2961 first character in the routing header.\r
2962 Note: There is no requirement that the\r
2963 driver validate the routing data. It\r
2964 must skip the <ConfigHdr> in order to\r
2965 process the names.\r
2966\r
2967 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set\r
2968 to most recent "&" before the\r
2969 error or the beginning of the\r
2970 string.\r
2971\r
2972 @retval EFI_INVALID_PARAMETER Unknown name. Progress points\r
2973 to the & before the name in\r
2974 question.\r
2975\r
2976**/\r
2977EFI_STATUS\r
2978EFIAPI\r
2979IScsiFormExtractConfig (\r
d1050b9d
MK
2980 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
2981 IN CONST EFI_STRING Request,\r
2982 OUT EFI_STRING *Progress,\r
2983 OUT EFI_STRING *Results\r
4c5a5e0c 2984 )\r
2985{\r
d1050b9d
MK
2986 EFI_STATUS Status;\r
2987 CHAR8 *InitiatorName;\r
2988 UINTN BufferSize;\r
2989 ISCSI_CONFIG_IFR_NVDATA *IfrNvData;\r
2990 ISCSI_FORM_CALLBACK_INFO *Private;\r
2991 EFI_STRING ConfigRequestHdr;\r
2992 EFI_STRING ConfigRequest;\r
2993 BOOLEAN AllocatedRequest;\r
2994 UINTN Size;\r
2995\r
2996 if ((This == NULL) || (Progress == NULL) || (Results == NULL)) {\r
4c5a5e0c 2997 return EFI_INVALID_PARAMETER;\r
2998 }\r
2999\r
3000 *Progress = Request;\r
9bdc6592 3001 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gIScsiConfigGuid, mVendorStorageName)) {\r
4c5a5e0c 3002 return EFI_NOT_FOUND;\r
3003 }\r
3004\r
3005 ConfigRequestHdr = NULL;\r
3006 ConfigRequest = NULL;\r
3007 AllocatedRequest = FALSE;\r
3008 Size = 0;\r
3009\r
d1050b9d 3010 Private = ISCSI_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This);\r
4c5a5e0c 3011 IfrNvData = AllocateZeroPool (sizeof (ISCSI_CONFIG_IFR_NVDATA));\r
3012 if (IfrNvData == NULL) {\r
3013 return EFI_OUT_OF_RESOURCES;\r
3014 }\r
8d1f5e04 3015\r
d1050b9d 3016 if (Private->Current != NULL) {\r
4c5a5e0c 3017 IScsiConvertAttemptConfigDataToIfrNvData (Private->Current, IfrNvData);\r
3018 }\r
3019\r
8d1f5e04 3020 //\r
efb56593 3021 // Extract all AttemptConfigData to Keyword storage of IfrNvData.\r
8d1f5e04
ZL
3022 //\r
3023 IScsiConvertAttemptConfigDataToIfrNvDataByKeyword (IfrNvData);\r
3024\r
4c5a5e0c 3025 BufferSize = ISCSI_NAME_MAX_SIZE;\r
d1050b9d 3026 InitiatorName = (CHAR8 *)AllocateZeroPool (BufferSize);\r
4c5a5e0c 3027 if (InitiatorName == NULL) {\r
3028 FreePool (IfrNvData);\r
3029 return EFI_OUT_OF_RESOURCES;\r
3030 }\r
f75a7f56 3031\r
4c5a5e0c 3032 Status = gIScsiInitiatorName.Get (&gIScsiInitiatorName, &BufferSize, InitiatorName);\r
3033 if (EFI_ERROR (Status)) {\r
3034 IfrNvData->InitiatorName[0] = L'\0';\r
3035 } else {\r
b9679cd7
SZ
3036 AsciiStrToUnicodeStrS (\r
3037 InitiatorName,\r
3038 IfrNvData->InitiatorName,\r
3039 sizeof (IfrNvData->InitiatorName) / sizeof (IfrNvData->InitiatorName[0])\r
3040 );\r
4c5a5e0c 3041 }\r
3042\r
3043 //\r
3044 // Convert buffer data to <ConfigResp> by helper function BlockToConfig().\r
3045 //\r
d1050b9d 3046 BufferSize = sizeof (ISCSI_CONFIG_IFR_NVDATA);\r
4c5a5e0c 3047 ConfigRequest = Request;\r
3048 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
3049 //\r
3050 // Request has no request element, construct full request string.\r
3051 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
3052 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
3053 //\r
9bdc6592 3054 ConfigRequestHdr = HiiConstructConfigHdr (&gIScsiConfigGuid, mVendorStorageName, Private->DriverHandle);\r
d1050b9d
MK
3055 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
3056 ConfigRequest = AllocateZeroPool (Size);\r
7c275b3c
ZL
3057 if (ConfigRequest == NULL) {\r
3058 FreePool (IfrNvData);\r
3059 FreePool (InitiatorName);\r
3060 return EFI_OUT_OF_RESOURCES;\r
3061 }\r
d1050b9d 3062\r
4c5a5e0c 3063 AllocatedRequest = TRUE;\r
3064 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
3065 FreePool (ConfigRequestHdr);\r
3066 }\r
3067\r
3068 Status = gHiiConfigRouting->BlockToConfig (\r
3069 gHiiConfigRouting,\r
3070 ConfigRequest,\r
d1050b9d 3071 (UINT8 *)IfrNvData,\r
4c5a5e0c 3072 BufferSize,\r
3073 Results,\r
3074 Progress\r
3075 );\r
3076 FreePool (IfrNvData);\r
3077 FreePool (InitiatorName);\r
3078\r
3079 //\r
3080 // Free the allocated config request string.\r
3081 //\r
3082 if (AllocatedRequest) {\r
3083 FreePool (ConfigRequest);\r
3084 ConfigRequest = NULL;\r
3085 }\r
d1050b9d 3086\r
4c5a5e0c 3087 //\r
3088 // Set Progress string to the original request string.\r
3089 //\r
3090 if (Request == NULL) {\r
3091 *Progress = NULL;\r
3092 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
3093 *Progress = Request + StrLen (Request);\r
3094 }\r
3095\r
3096 return Status;\r
3097}\r
3098\r
4c5a5e0c 3099/**\r
f75a7f56 3100\r
4c5a5e0c 3101 This function applies changes in a driver's configuration.\r
3102 Input is a Configuration, which has the routing data for this\r
3103 driver followed by name / value configuration pairs. The driver\r
3104 must apply those pairs to its configurable storage. If the\r
3105 driver's configuration is stored in a linear block of data\r
3106 and the driver's name / value pairs are in <BlockConfig>\r
3107 format, it may use the ConfigToBlock helper function (above) to\r
3108 simplify the job.\r
3109\r
3110 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
3111\r
3112 @param[in] Configuration A null-terminated Unicode string in\r
f75a7f56
LG
3113 <ConfigString> format.\r
3114\r
4c5a5e0c 3115 @param[out] Progress A pointer to a string filled in with the\r
3116 offset of the most recent '&' before the\r
3117 first failing name / value pair (or the\r
3118 beginning of the string if the failure\r
3119 is in the first name / value pair) or\r
3120 the terminating NULL if all was\r
3121 successful.\r
3122\r
3123 @retval EFI_SUCCESS The results have been distributed or are\r
3124 awaiting distribution.\r
f75a7f56 3125\r
4c5a5e0c 3126 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
3127 parts of the results that must be\r
3128 stored awaiting possible future\r
3129 protocols.\r
f75a7f56 3130\r
4c5a5e0c 3131 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
3132 Results parameter would result\r
3133 in this type of error.\r
f75a7f56 3134\r
4c5a5e0c 3135 @retval EFI_NOT_FOUND Target for the specified routing data\r
3136 was not found.\r
3137\r
3138**/\r
3139EFI_STATUS\r
3140EFIAPI\r
3141IScsiFormRouteConfig (\r
d1050b9d
MK
3142 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
3143 IN CONST EFI_STRING Configuration,\r
3144 OUT EFI_STRING *Progress\r
4c5a5e0c 3145 )\r
3146{\r
d1050b9d
MK
3147 EFI_STATUS Status;\r
3148 ISCSI_CONFIG_IFR_NVDATA *IfrNvData;\r
3149 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;\r
3150 LIST_ENTRY *Entry;\r
3151 LIST_ENTRY *NextEntry;\r
3152 ISCSI_NIC_INFO *NicInfo;\r
3153 EFI_INPUT_KEY Key;\r
3154 CHAR16 MacString[ISCSI_MAX_MAC_STRING_LEN];\r
3155 CHAR8 *InitiatorName;\r
3156 UINT8 *AttemptList;\r
3157 UINTN BufferSize;\r
3158 UINTN OffSet;\r
3159 UINTN Index;\r
3160 UINTN Index2;\r
3161\r
3162 Index = 0;\r
3163 Index2 = 0;\r
3164 NicInfo = NULL;\r
8d1f5e04 3165 AttemptList = NULL;\r
d1050b9d 3166 Status = EFI_SUCCESS;\r
8d1f5e04 3167\r
d1050b9d 3168 if ((This == NULL) || (Configuration == NULL) || (Progress == NULL)) {\r
4c5a5e0c 3169 return EFI_INVALID_PARAMETER;\r
3170 }\r
3171\r
3172 //\r
3173 // Check routing data in <ConfigHdr>.\r
3174 // Note: if only one Storage is used, then this checking could be skipped.\r
3175 //\r
9bdc6592 3176 if (!HiiIsConfigHdrMatch (Configuration, &gIScsiConfigGuid, mVendorStorageName)) {\r
4c5a5e0c 3177 *Progress = Configuration;\r
3178 return EFI_NOT_FOUND;\r
3179 }\r
3180\r
8d1f5e04
ZL
3181 IfrNvData = AllocateZeroPool (sizeof (ISCSI_CONFIG_IFR_NVDATA));\r
3182 if (IfrNvData == NULL) {\r
3183 return EFI_OUT_OF_RESOURCES;\r
3184 }\r
3185\r
3186 BufferSize = ISCSI_NAME_MAX_SIZE;\r
d1050b9d 3187 InitiatorName = (CHAR8 *)AllocateZeroPool (BufferSize);\r
8d1f5e04
ZL
3188 if (InitiatorName == NULL) {\r
3189 Status = EFI_OUT_OF_RESOURCES;\r
3190 goto Exit;\r
3191 }\r
3192\r
3193 //\r
3194 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock().\r
3195 //\r
3196 BufferSize = sizeof (ISCSI_CONFIG_IFR_NVDATA);\r
d1050b9d
MK
3197 Status = gHiiConfigRouting->ConfigToBlock (\r
3198 gHiiConfigRouting,\r
3199 Configuration,\r
3200 (UINT8 *)IfrNvData,\r
3201 &BufferSize,\r
3202 Progress\r
3203 );\r
8d1f5e04
ZL
3204 if (EFI_ERROR (Status)) {\r
3205 goto Exit;\r
3206 }\r
3207\r
3208 if (IfrNvData->InitiatorName[0] != L'\0') {\r
3209 UnicodeStrToAsciiStrS (IfrNvData->InitiatorName, InitiatorName, ISCSI_NAME_MAX_SIZE);\r
d1050b9d 3210 BufferSize = AsciiStrSize (InitiatorName);\r
8d1f5e04 3211\r
d1050b9d 3212 Status = gIScsiInitiatorName.Set (&gIScsiInitiatorName, &BufferSize, InitiatorName);\r
8d1f5e04
ZL
3213 if (EFI_ERROR (Status)) {\r
3214 CreatePopUp (\r
3215 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
3216 &Key,\r
3217 L"Invalid iSCSI Name!",\r
3218 NULL\r
3219 );\r
3220 goto Exit;\r
3221 }\r
3222 } else {\r
2fd40fa5 3223 Status = IScsiGetValue (Configuration, L"&OFFSET=", &OffSet);\r
8d1f5e04 3224 if (EFI_ERROR (Status)) {\r
2fd40fa5
ZL
3225 goto Exit;\r
3226 }\r
3227\r
3228 if (OffSet >= ATTEMPT_MAC_ADDR_VAR_OFFSET) {\r
3229 Status = gIScsiInitiatorName.Get (&gIScsiInitiatorName, &BufferSize, InitiatorName);\r
3230 if (EFI_ERROR (Status)) {\r
3231 CreatePopUp (\r
3232 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
3233 &Key,\r
3234 L"Error: please configure iSCSI initiator name first!",\r
3235 NULL\r
3236 );\r
3237 goto Exit;\r
3238 }\r
3239 } else {\r
8d1f5e04
ZL
3240 goto Exit;\r
3241 }\r
3242\r
3243 if (IfrNvData->ISCSIAddAttemptList[0] != L'\0') {\r
d1050b9d 3244 Status = IScsiGetAttemptIndexList (IfrNvData->ISCSIAddAttemptList, IfrNvData->AddAttemptList, TRUE);\r
8d1f5e04 3245 if (EFI_ERROR (Status)) {\r
d1050b9d
MK
3246 CreatePopUp (\r
3247 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
3248 &Key,\r
3249 L"Error: The add attempt list is invalid",\r
3250 NULL\r
3251 );\r
8d1f5e04
ZL
3252 goto Exit;\r
3253 }\r
3254\r
3255 Status = IScsiConfigAddAttemptsByKeywords (IfrNvData->AddAttemptList);\r
3256 if (EFI_ERROR (Status)) {\r
3257 goto Exit;\r
3258 }\r
8d1f5e04 3259 } else if (IfrNvData->ISCSIDeleteAttemptList[0] != L'\0') {\r
d1050b9d 3260 AttemptList = (UINT8 *)AllocateZeroPool ((ISCSI_MAX_ATTEMPTS_NUM + 1) * sizeof (UINT8));\r
8d1f5e04
ZL
3261 if (AttemptList == NULL) {\r
3262 Status = EFI_OUT_OF_RESOURCES;\r
3263 goto Exit;\r
3264 }\r
d1050b9d 3265\r
8d1f5e04
ZL
3266 Status = IScsiGetAttemptIndexList (IfrNvData->ISCSIDeleteAttemptList, AttemptList, FALSE);\r
3267 if (EFI_ERROR (Status)) {\r
d1050b9d
MK
3268 CreatePopUp (\r
3269 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
3270 &Key,\r
3271 L"Error: The delete attempt list is invalid",\r
3272 NULL\r
3273 );\r
8d1f5e04
ZL
3274 goto Exit;\r
3275 }\r
3276\r
3277 //\r
3278 // Mark the attempt which will be delete in the global list.\r
3279 //\r
3280 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &mPrivate->AttemptConfigs) {\r
3281 AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);\r
3282 while (AttemptList[Index] != 0) {\r
3283 if (AttemptConfigData->AttemptConfigIndex == AttemptList[Index]) {\r
3284 IfrNvData->DeleteAttemptList[Index2] = 1;\r
3285 break;\r
3286 }\r
d1050b9d
MK
3287\r
3288 Index++;\r
8d1f5e04 3289 }\r
d1050b9d
MK
3290\r
3291 Index2++;\r
8d1f5e04
ZL
3292 Index = 0;\r
3293 }\r
3294\r
3295 Status = IScsiConfigDeleteAttempts (IfrNvData);\r
3296 if (EFI_ERROR (Status)) {\r
3297 goto Exit;\r
3298 }\r
3299\r
3300 FreePool (AttemptList);\r
8d1f5e04
ZL
3301 } else if (IfrNvData->ISCSIAttemptOrder[0] != L'\0') {\r
3302 Status = IScsiGetAttemptIndexList (IfrNvData->ISCSIAttemptOrder, IfrNvData->DynamicOrderedList, FALSE);\r
3303 if (EFI_ERROR (Status)) {\r
d1050b9d
MK
3304 CreatePopUp (\r
3305 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
3306 &Key,\r
3307 L"Error: The new attempt order list is invalid",\r
3308 NULL\r
3309 );\r
8d1f5e04
ZL
3310 goto Exit;\r
3311 }\r
3312\r
3313 Status = IScsiConfigOrderAttempts (IfrNvData);\r
3314 if (EFI_ERROR (Status)) {\r
3315 goto Exit;\r
3316 }\r
8d1f5e04
ZL
3317 } else if (IfrNvData->ISCSIMacAddr[0] != L'\0') {\r
3318 NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {\r
3319 NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);\r
3320 IScsiMacAddrToStr (\r
d1050b9d
MK
3321 &NicInfo->PermanentAddress,\r
3322 NicInfo->HwAddressSize,\r
3323 NicInfo->VlanId,\r
3324 MacString\r
3325 );\r
3326 if (!StrCmp (MacString, IfrNvData->ISCSIMacAddr)) {\r
8d1f5e04
ZL
3327 mPrivate->CurrentNic = NicInfo->NicIndex;\r
3328 break;\r
3329 }\r
3330 }\r
3331\r
3332 if ((NicInfo == NULL) || (NicInfo->NicIndex == 0)) {\r
3333 Status = EFI_NOT_FOUND;\r
3334 goto Exit;\r
3335 }\r
8d1f5e04 3336 } else {\r
8d1f5e04
ZL
3337 Status = IScsiConvertlfrNvDataToAttemptConfigDataByKeyword (IfrNvData, OffSet);\r
3338 if (EFI_ERROR (Status)) {\r
3339 goto Exit;\r
3340 }\r
3341 }\r
3342 }\r
3343\r
3344 IScsiConfigUpdateAttempt ();\r
3345\r
8d1f5e04
ZL
3346Exit:\r
3347 if (InitiatorName != NULL) {\r
3348 FreePool (InitiatorName);\r
3349 }\r
4c5a5e0c 3350\r
8d1f5e04
ZL
3351 if (IfrNvData != NULL) {\r
3352 FreePool (IfrNvData);\r
3353 }\r
3354\r
3355 return Status;\r
3356}\r
4c5a5e0c 3357\r
3358/**\r
f75a7f56 3359\r
4c5a5e0c 3360 This function is called to provide results data to the driver.\r
3361 This data consists of a unique key that is used to identify\r
3362 which data is either being passed back or being asked for.\r
3363\r
3364 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
3365 @param[in] Action Specifies the type of action taken by the browser.\r
3366 @param[in] QuestionId A unique value which is sent to the original\r
3367 exporting driver so that it can identify the type\r
f75a7f56 3368 of data to expect. The format of the data tends to\r
4c5a5e0c 3369 vary based on the opcode that generated the callback.\r
3370 @param[in] Type The type of value for the question.\r
3371 @param[in, out] Value A pointer to the data being sent to the original\r
3372 exporting driver.\r
3373 @param[out] ActionRequest On return, points to the action requested by the\r
3374 callback function.\r
3375\r
3376 @retval EFI_SUCCESS The callback successfully handled the action.\r
3377 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
3378 variable and its data.\r
3379 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
3380 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
3381 callback.\r
3382**/\r
3383EFI_STATUS\r
3384EFIAPI\r
3385IScsiFormCallback (\r
d1050b9d
MK
3386 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
3387 IN EFI_BROWSER_ACTION Action,\r
3388 IN EFI_QUESTION_ID QuestionId,\r
3389 IN UINT8 Type,\r
3390 IN OUT EFI_IFR_TYPE_VALUE *Value,\r
3391 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
4c5a5e0c 3392 )\r
3393{\r
d1050b9d
MK
3394 ISCSI_FORM_CALLBACK_INFO *Private;\r
3395 UINTN BufferSize;\r
3396 CHAR8 *IScsiName;\r
3397 CHAR8 IpString[ISCSI_NAME_MAX_SIZE];\r
3398 CHAR8 LunString[ISCSI_LUN_STR_MAX_LEN];\r
3399 UINT64 Lun;\r
3400 EFI_IP_ADDRESS HostIp;\r
3401 EFI_IP_ADDRESS SubnetMask;\r
3402 EFI_IP_ADDRESS Gateway;\r
3403 ISCSI_CONFIG_IFR_NVDATA *IfrNvData;\r
3404 ISCSI_CONFIG_IFR_NVDATA OldIfrNvData;\r
3405 EFI_STATUS Status;\r
3406 EFI_INPUT_KEY Key;\r
3407 ISCSI_NIC_INFO *NicInfo;\r
6b08dd6e
JW
3408\r
3409 NicInfo = NULL;\r
4c5a5e0c 3410\r
3411 if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action == EFI_BROWSER_ACTION_FORM_CLOSE)) {\r
3412 //\r
3413 // Do nothing for UEFI OPEN/CLOSE Action\r
3414 //\r
3415 return EFI_SUCCESS;\r
3416 }\r
3417\r
639a76d1 3418 if ((Action != EFI_BROWSER_ACTION_CHANGING) && (Action != EFI_BROWSER_ACTION_CHANGED)) {\r
4c5a5e0c 3419 //\r
639a76d1 3420 // All other type return unsupported.\r
4c5a5e0c 3421 //\r
639a76d1
ED
3422 return EFI_UNSUPPORTED;\r
3423 }\r
4c5a5e0c 3424\r
639a76d1
ED
3425 if ((Value == NULL) || (ActionRequest == NULL)) {\r
3426 return EFI_INVALID_PARAMETER;\r
3427 }\r
4c5a5e0c 3428\r
639a76d1 3429 Private = ISCSI_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This);\r
f75a7f56 3430\r
639a76d1
ED
3431 //\r
3432 // Retrieve uncommitted data from Browser\r
3433 //\r
f75a7f56 3434\r
639a76d1 3435 BufferSize = sizeof (ISCSI_CONFIG_IFR_NVDATA);\r
d1050b9d 3436 IfrNvData = AllocateZeroPool (BufferSize);\r
639a76d1
ED
3437 if (IfrNvData == NULL) {\r
3438 return EFI_OUT_OF_RESOURCES;\r
3439 }\r
f75a7f56 3440\r
d1050b9d 3441 IScsiName = (CHAR8 *)AllocateZeroPool (ISCSI_NAME_MAX_SIZE);\r
639a76d1
ED
3442 if (IScsiName == NULL) {\r
3443 FreePool (IfrNvData);\r
3444 return EFI_OUT_OF_RESOURCES;\r
3445 }\r
f75a7f56 3446\r
639a76d1 3447 Status = EFI_SUCCESS;\r
f75a7f56 3448\r
639a76d1 3449 ZeroMem (&OldIfrNvData, BufferSize);\r
f75a7f56 3450\r
d1050b9d 3451 HiiGetBrowserData (NULL, NULL, BufferSize, (UINT8 *)IfrNvData);\r
f75a7f56 3452\r
639a76d1 3453 CopyMem (&OldIfrNvData, IfrNvData, BufferSize);\r
4c5a5e0c 3454\r
639a76d1
ED
3455 if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
3456 switch (QuestionId) {\r
d1050b9d
MK
3457 case KEY_ADD_ATTEMPT:\r
3458 //\r
3459 // Check whether iSCSI initiator name is configured already.\r
3460 //\r
3461 mPrivate->InitiatorNameLength = ISCSI_NAME_MAX_SIZE;\r
3462 Status = gIScsiInitiatorName.Get (\r
3463 &gIScsiInitiatorName,\r
3464 &mPrivate->InitiatorNameLength,\r
3465 mPrivate->InitiatorName\r
3466 );\r
3467 if (EFI_ERROR (Status)) {\r
3468 CreatePopUp (\r
3469 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
3470 &Key,\r
3471 L"Error: please configure iSCSI initiator name first!",\r
3472 NULL\r
3473 );\r
3474 break;\r
3475 }\r
f75a7f56 3476\r
d1050b9d
MK
3477 Status = IScsiConfigAddAttempt ();\r
3478 break;\r
4c5a5e0c 3479\r
d1050b9d
MK
3480 case KEY_DELETE_ATTEMPT:\r
3481 CopyMem (\r
3482 OldIfrNvData.DeleteAttemptList,\r
3483 IfrNvData->DeleteAttemptList,\r
3484 sizeof (IfrNvData->DeleteAttemptList)\r
3485 );\r
3486 Status = IScsiConfigDisplayDeleteAttempts (IfrNvData);\r
3487 break;\r
4c5a5e0c 3488\r
d1050b9d
MK
3489 case KEY_ORDER_ATTEMPT_CONFIG:\r
3490 //\r
3491 // Order the attempt according to user input.\r
3492 //\r
3493 CopyMem (\r
3494 OldIfrNvData.DynamicOrderedList,\r
3495 IfrNvData->DynamicOrderedList,\r
3496 sizeof (IfrNvData->DynamicOrderedList)\r
3497 );\r
3498 IScsiConfigDisplayOrderAttempts ();\r
3499 break;\r
f75a7f56 3500\r
d1050b9d
MK
3501 default:\r
3502 Status = IScsiConfigProcessDefault (QuestionId, IfrNvData);\r
3503 break;\r
639a76d1 3504 }\r
f75a7f56 3505 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
4c5a5e0c 3506 switch (QuestionId) {\r
d1050b9d
MK
3507 case KEY_INITIATOR_NAME:\r
3508 UnicodeStrToAsciiStrS (IfrNvData->InitiatorName, IScsiName, ISCSI_NAME_MAX_SIZE);\r
3509 BufferSize = AsciiStrSize (IScsiName);\r
4c5a5e0c 3510\r
d1050b9d
MK
3511 Status = gIScsiInitiatorName.Set (&gIScsiInitiatorName, &BufferSize, IScsiName);\r
3512 if (EFI_ERROR (Status)) {\r
3513 CreatePopUp (\r
3514 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
3515 &Key,\r
3516 L"Invalid iSCSI Name!",\r
3517 NULL\r
3518 );\r
3519 }\r
4c5a5e0c 3520\r
d1050b9d
MK
3521 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;\r
3522 break;\r
f75a7f56 3523\r
d1050b9d
MK
3524 case KEY_SAVE_ATTEMPT_CONFIG:\r
3525 Status = IScsiConvertIfrNvDataToAttemptConfigData (IfrNvData, Private->Current);\r
3526 if (EFI_ERROR (Status)) {\r
3527 break;\r
3528 }\r
3529\r
3530 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
4c5a5e0c 3531 break;\r
4c5a5e0c 3532\r
d1050b9d
MK
3533 case KEY_SAVE_ORDER_CHANGES:\r
3534 //\r
3535 // Sync the Attempt Order to NVR.\r
3536 //\r
3537 Status = IScsiConfigOrderAttempts (IfrNvData);\r
3538 if (EFI_ERROR (Status)) {\r
3539 break;\r
3540 }\r
4c5a5e0c 3541\r
d1050b9d
MK
3542 IScsiConfigUpdateAttempt ();\r
3543 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
4c5a5e0c 3544 break;\r
4c5a5e0c 3545\r
d1050b9d
MK
3546 case KEY_IGNORE_ORDER_CHANGES:\r
3547 CopyMem (\r
3548 IfrNvData->DynamicOrderedList,\r
3549 OldIfrNvData.DynamicOrderedList,\r
3550 sizeof (IfrNvData->DynamicOrderedList)\r
3551 );\r
3552 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
3553 break;\r
4c5a5e0c 3554\r
d1050b9d
MK
3555 case KEY_SAVE_DELETE_ATTEMPT:\r
3556 //\r
3557 // Delete the Attempt Order from NVR\r
3558 //\r
3559 Status = IScsiConfigDeleteAttempts (IfrNvData);\r
3560 if (EFI_ERROR (Status)) {\r
3561 break;\r
3562 }\r
4c5a5e0c 3563\r
d1050b9d
MK
3564 IScsiConfigUpdateAttempt ();\r
3565 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
639a76d1 3566 break;\r
4c5a5e0c 3567\r
d1050b9d
MK
3568 case KEY_IGNORE_DELETE_ATTEMPT:\r
3569 CopyMem (\r
3570 IfrNvData->DeleteAttemptList,\r
3571 OldIfrNvData.DeleteAttemptList,\r
3572 sizeof (IfrNvData->DeleteAttemptList)\r
3573 );\r
3574 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
3575 break;\r
4c5a5e0c 3576\r
d1050b9d
MK
3577 case KEY_IP_MODE:\r
3578 switch (Value->u8) {\r
3579 case IP_MODE_IP6:\r
3580 NicInfo = IScsiGetNicInfoByIndex (Private->Current->NicIndex);\r
3581 if (NicInfo == NULL) {\r
3582 break;\r
3583 }\r
3584\r
3585 if (!NicInfo->Ipv6Available) {\r
3586 //\r
3587 // Current NIC doesn't Support IPv6, hence use IPv4.\r
3588 //\r
3589 IfrNvData->IpMode = IP_MODE_IP4;\r
3590\r
3591 CreatePopUp (\r
3592 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
3593 &Key,\r
3594 L"Current NIC doesn't Support IPv6!",\r
3595 NULL\r
3596 );\r
3597 }\r
3598\r
3599 case IP_MODE_IP4:\r
3600 ZeroMem (IfrNvData->LocalIp, sizeof (IfrNvData->LocalIp));\r
3601 ZeroMem (IfrNvData->SubnetMask, sizeof (IfrNvData->SubnetMask));\r
3602 ZeroMem (IfrNvData->Gateway, sizeof (IfrNvData->Gateway));\r
3603 ZeroMem (IfrNvData->TargetIp, sizeof (IfrNvData->TargetIp));\r
3604 Private->Current->AutoConfigureMode = 0;\r
3605 ZeroMem (&Private->Current->SessionConfigData.LocalIp, sizeof (EFI_IP_ADDRESS));\r
3606 ZeroMem (&Private->Current->SessionConfigData.SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
3607 ZeroMem (&Private->Current->SessionConfigData.Gateway, sizeof (EFI_IP_ADDRESS));\r
3608 ZeroMem (&Private->Current->SessionConfigData.TargetIp, sizeof (EFI_IP_ADDRESS));\r
4c5a5e0c 3609\r
d1050b9d 3610 break;\r
0e7794d3
JW
3611 }\r
3612\r
d1050b9d 3613 break;\r
f75a7f56 3614\r
d1050b9d
MK
3615 case KEY_LOCAL_IP:\r
3616 Status = NetLibStrToIp4 (IfrNvData->LocalIp, &HostIp.v4);\r
3617 if (EFI_ERROR (Status) ||\r
3618 ((Private->Current->SessionConfigData.SubnetMask.Addr[0] != 0) &&\r
3619 !NetIp4IsUnicast (NTOHL (HostIp.Addr[0]), NTOHL (*(UINT32 *)Private->Current->SessionConfigData.SubnetMask.Addr))))\r
3620 {\r
6b08dd6e
JW
3621 CreatePopUp (\r
3622 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
3623 &Key,\r
d1050b9d 3624 L"Invalid IP address!",\r
6b08dd6e
JW
3625 NULL\r
3626 );\r
f75a7f56 3627\r
d1050b9d
MK
3628 Status = EFI_INVALID_PARAMETER;\r
3629 } else {\r
3630 CopyMem (&Private->Current->SessionConfigData.LocalIp, &HostIp.v4, sizeof (HostIp.v4));\r
3631 }\r
f75a7f56 3632\r
4c5a5e0c 3633 break;\r
4c5a5e0c 3634\r
d1050b9d
MK
3635 case KEY_SUBNET_MASK:\r
3636 Status = NetLibStrToIp4 (IfrNvData->SubnetMask, &SubnetMask.v4);\r
3637 if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (IScsiGetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) {\r
3638 CreatePopUp (\r
3639 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
3640 &Key,\r
3641 L"Invalid Subnet Mask!",\r
3642 NULL\r
3643 );\r
4c5a5e0c 3644\r
d1050b9d
MK
3645 Status = EFI_INVALID_PARAMETER;\r
3646 } else {\r
3647 CopyMem (&Private->Current->SessionConfigData.SubnetMask, &SubnetMask.v4, sizeof (SubnetMask.v4));\r
3648 }\r
f75a7f56 3649\r
d1050b9d 3650 break;\r
4c5a5e0c 3651\r
d1050b9d
MK
3652 case KEY_GATE_WAY:\r
3653 Status = NetLibStrToIp4 (IfrNvData->Gateway, &Gateway.v4);\r
3654 if (EFI_ERROR (Status) ||\r
3655 ((Gateway.Addr[0] != 0) &&\r
3656 (Private->Current->SessionConfigData.SubnetMask.Addr[0] != 0) &&\r
3657 !NetIp4IsUnicast (NTOHL (Gateway.Addr[0]), NTOHL (*(UINT32 *)Private->Current->SessionConfigData.SubnetMask.Addr))))\r
3658 {\r
3659 CreatePopUp (\r
3660 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
3661 &Key,\r
3662 L"Invalid Gateway!",\r
3663 NULL\r
3664 );\r
3665 Status = EFI_INVALID_PARAMETER;\r
3666 } else {\r
3667 CopyMem (&Private->Current->SessionConfigData.Gateway, &Gateway.v4, sizeof (Gateway.v4));\r
3668 }\r
4c5a5e0c 3669\r
d1050b9d 3670 break;\r
f75a7f56 3671\r
d1050b9d
MK
3672 case KEY_TARGET_IP:\r
3673 UnicodeStrToAsciiStrS (IfrNvData->TargetIp, IpString, sizeof (IpString));\r
3674 Status = IScsiAsciiStrToIp (IpString, IfrNvData->IpMode, &HostIp);\r
3675 if (EFI_ERROR (Status) || !IpIsUnicast (&HostIp, IfrNvData->IpMode)) {\r
3676 //\r
3677 // The target is expressed in URL format or an invalid Ip address, just save.\r
3678 //\r
3679 Private->Current->SessionConfigData.DnsMode = TRUE;\r
3680 ZeroMem (&Private->Current->SessionConfigData.TargetIp, sizeof (Private->Current->SessionConfigData.TargetIp));\r
3681 UnicodeStrToAsciiStrS (IfrNvData->TargetIp, Private->Current->SessionConfigData.TargetUrl, ISCSI_NAME_MAX_SIZE);\r
3682 } else {\r
3683 Private->Current->SessionConfigData.DnsMode = FALSE;\r
3684 CopyMem (&Private->Current->SessionConfigData.TargetIp, &HostIp, sizeof (HostIp));\r
3685 }\r
4c5a5e0c 3686\r
d1050b9d 3687 break;\r
4c5a5e0c 3688\r
d1050b9d
MK
3689 case KEY_TARGET_NAME:\r
3690 UnicodeStrToAsciiStrS (IfrNvData->TargetName, IScsiName, ISCSI_NAME_MAX_SIZE);\r
3691 Status = IScsiNormalizeName (IScsiName, AsciiStrLen (IScsiName));\r
3692 if (EFI_ERROR (Status)) {\r
3693 CreatePopUp (\r
3694 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
3695 &Key,\r
3696 L"Invalid iSCSI Name!",\r
3697 NULL\r
3698 );\r
3699 } else {\r
3700 AsciiStrCpyS (Private->Current->SessionConfigData.TargetName, ISCSI_NAME_MAX_SIZE, IScsiName);\r
3701 }\r
4c5a5e0c 3702\r
d1050b9d 3703 break;\r
4c5a5e0c 3704\r
d1050b9d
MK
3705 case KEY_DHCP_ENABLE:\r
3706 if (IfrNvData->InitiatorInfoFromDhcp == 0) {\r
3707 IfrNvData->TargetInfoFromDhcp = 0;\r
3708 }\r
4c5a5e0c 3709\r
d1050b9d 3710 break;\r
4c5a5e0c 3711\r
d1050b9d
MK
3712 case KEY_BOOT_LUN:\r
3713 UnicodeStrToAsciiStrS (IfrNvData->BootLun, LunString, sizeof (LunString));\r
3714 Status = IScsiAsciiStrToLun (LunString, (UINT8 *)&Lun);\r
3715 if (EFI_ERROR (Status)) {\r
3716 CreatePopUp (\r
3717 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
3718 &Key,\r
3719 L"Invalid LUN string!",\r
3720 NULL\r
3721 );\r
3722 } else {\r
3723 CopyMem (Private->Current->SessionConfigData.BootLun, &Lun, sizeof (Lun));\r
3724 }\r
4c5a5e0c 3725\r
d1050b9d 3726 break;\r
4c5a5e0c 3727\r
d1050b9d
MK
3728 case KEY_AUTH_TYPE:\r
3729 switch (Value->u8) {\r
3730 case ISCSI_AUTH_TYPE_CHAP:\r
3731 IfrNvData->CHAPType = ISCSI_CHAP_UNI;\r
3732 break;\r
3733 default:\r
3734 break;\r
3735 }\r
4c5a5e0c 3736\r
d1050b9d 3737 break;\r
4c5a5e0c 3738\r
d1050b9d
MK
3739 case KEY_CHAP_NAME:\r
3740 UnicodeStrToAsciiStrS (\r
3741 IfrNvData->CHAPName,\r
3742 Private->Current->AuthConfigData.CHAP.CHAPName,\r
3743 sizeof (Private->Current->AuthConfigData.CHAP.CHAPName)\r
f75a7f56 3744 );\r
4c5a5e0c 3745 break;\r
4c5a5e0c 3746\r
d1050b9d
MK
3747 case KEY_CHAP_SECRET:\r
3748 UnicodeStrToAsciiStrS (\r
3749 IfrNvData->CHAPSecret,\r
3750 Private->Current->AuthConfigData.CHAP.CHAPSecret,\r
3751 sizeof (Private->Current->AuthConfigData.CHAP.CHAPSecret)\r
3752 );\r
3753 break;\r
4c5a5e0c 3754\r
d1050b9d
MK
3755 case KEY_REVERSE_CHAP_NAME:\r
3756 UnicodeStrToAsciiStrS (\r
3757 IfrNvData->ReverseCHAPName,\r
3758 Private->Current->AuthConfigData.CHAP.ReverseCHAPName,\r
3759 sizeof (Private->Current->AuthConfigData.CHAP.ReverseCHAPName)\r
3760 );\r
3761 break;\r
4c5a5e0c 3762\r
d1050b9d
MK
3763 case KEY_REVERSE_CHAP_SECRET:\r
3764 UnicodeStrToAsciiStrS (\r
3765 IfrNvData->ReverseCHAPSecret,\r
3766 Private->Current->AuthConfigData.CHAP.ReverseCHAPSecret,\r
3767 sizeof (Private->Current->AuthConfigData.CHAP.ReverseCHAPSecret)\r
3768 );\r
3769 break;\r
4c5a5e0c 3770\r
d1050b9d
MK
3771 case KEY_CONFIG_ISID:\r
3772 IScsiParseIsIdFromString (IfrNvData->IsId, Private->Current->SessionConfigData.IsId);\r
3773 IScsiConvertIsIdToString (IfrNvData->IsId, Private->Current->SessionConfigData.IsId);\r
4c5a5e0c 3774\r
d1050b9d 3775 break;\r
4c5a5e0c 3776\r
d1050b9d
MK
3777 default:\r
3778 break;\r
4c5a5e0c 3779 }\r
639a76d1 3780 }\r
4c5a5e0c 3781\r
639a76d1
ED
3782 if (!EFI_ERROR (Status)) {\r
3783 //\r
3784 // Pass changed uncommitted data back to Form Browser.\r
3785 //\r
3786 BufferSize = sizeof (ISCSI_CONFIG_IFR_NVDATA);\r
d1050b9d 3787 HiiSetBrowserData (NULL, NULL, BufferSize, (UINT8 *)IfrNvData, NULL);\r
4c5a5e0c 3788 }\r
3789\r
639a76d1
ED
3790 FreePool (IfrNvData);\r
3791 FreePool (IScsiName);\r
3792\r
3793 return Status;\r
4c5a5e0c 3794}\r
3795\r
4c5a5e0c 3796/**\r
3797 Initialize the iSCSI configuration form.\r
3798\r
3799 @param[in] DriverBindingHandle The iSCSI driverbinding handle.\r
3800\r
3801 @retval EFI_SUCCESS The iSCSI configuration form is initialized.\r
3802 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
3803\r
3804**/\r
3805EFI_STATUS\r
3806IScsiConfigFormInit (\r
3807 IN EFI_HANDLE DriverBindingHandle\r
3808 )\r
3809{\r
d1050b9d
MK
3810 EFI_STATUS Status;\r
3811 ISCSI_FORM_CALLBACK_INFO *CallbackInfo;\r
4c5a5e0c 3812\r
d1050b9d 3813 CallbackInfo = (ISCSI_FORM_CALLBACK_INFO *)AllocateZeroPool (sizeof (ISCSI_FORM_CALLBACK_INFO));\r
4c5a5e0c 3814 if (CallbackInfo == NULL) {\r
3815 return EFI_OUT_OF_RESOURCES;\r
3816 }\r
3817\r
d1050b9d
MK
3818 CallbackInfo->Signature = ISCSI_FORM_CALLBACK_INFO_SIGNATURE;\r
3819 CallbackInfo->Current = NULL;\r
4c5a5e0c 3820\r
3821 CallbackInfo->ConfigAccess.ExtractConfig = IScsiFormExtractConfig;\r
3822 CallbackInfo->ConfigAccess.RouteConfig = IScsiFormRouteConfig;\r
3823 CallbackInfo->ConfigAccess.Callback = IScsiFormCallback;\r
3824\r
3825 //\r
3826 // Install Device Path Protocol and Config Access protocol to driver handle.\r
3827 //\r
3828 Status = gBS->InstallMultipleProtocolInterfaces (\r
3829 &CallbackInfo->DriverHandle,\r
3830 &gEfiDevicePathProtocolGuid,\r
3831 &mIScsiHiiVendorDevicePath,\r
3832 &gEfiHiiConfigAccessProtocolGuid,\r
3833 &CallbackInfo->ConfigAccess,\r
3834 NULL\r
3835 );\r
3836 ASSERT_EFI_ERROR (Status);\r
f75a7f56 3837\r
4c5a5e0c 3838 //\r
3839 // Publish our HII data.\r
3840 //\r
3841 CallbackInfo->RegisteredHandle = HiiAddPackages (\r
9bdc6592 3842 &gIScsiConfigGuid,\r
4c5a5e0c 3843 CallbackInfo->DriverHandle,\r
3844 IScsiDxeStrings,\r
3845 IScsiConfigVfrBin,\r
3846 NULL\r
3847 );\r
3848 if (CallbackInfo->RegisteredHandle == NULL) {\r
3849 gBS->UninstallMultipleProtocolInterfaces (\r
bf7249df 3850 CallbackInfo->DriverHandle,\r
4c5a5e0c 3851 &gEfiDevicePathProtocolGuid,\r
3852 &mIScsiHiiVendorDevicePath,\r
3853 &gEfiHiiConfigAccessProtocolGuid,\r
3854 &CallbackInfo->ConfigAccess,\r
3855 NULL\r
3856 );\r
d1050b9d 3857 FreePool (CallbackInfo);\r
4c5a5e0c 3858 return EFI_OUT_OF_RESOURCES;\r
3859 }\r
3860\r
3861 mCallbackInfo = CallbackInfo;\r
3862\r
3863 return EFI_SUCCESS;\r
3864}\r
3865\r
4c5a5e0c 3866/**\r
3867 Unload the iSCSI configuration form, this includes: delete all the iSCSI\r
3868 configuration entries, uninstall the form callback protocol, and\r
3869 free the resources used.\r
3870\r
3871 @param[in] DriverBindingHandle The iSCSI driverbinding handle.\r
3872\r
3873 @retval EFI_SUCCESS The iSCSI configuration form is unloaded.\r
3874 @retval Others Failed to unload the form.\r
3875\r
3876**/\r
3877EFI_STATUS\r
3878IScsiConfigFormUnload (\r
3879 IN EFI_HANDLE DriverBindingHandle\r
3880 )\r
3881{\r
d1050b9d
MK
3882 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;\r
3883 ISCSI_NIC_INFO *NicInfo;\r
3884 LIST_ENTRY *Entry;\r
3885 EFI_STATUS Status;\r
4c5a5e0c 3886\r
3887 while (!IsListEmpty (&mPrivate->AttemptConfigs)) {\r
d1050b9d 3888 Entry = NetListRemoveHead (&mPrivate->AttemptConfigs);\r
4c5a5e0c 3889 AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);\r
3890 FreePool (AttemptConfigData);\r
3891 mPrivate->AttemptCount--;\r
3892 }\r
3893\r
3894 ASSERT (mPrivate->AttemptCount == 0);\r
3895\r
3896 while (!IsListEmpty (&mPrivate->NicInfoList)) {\r
d1050b9d 3897 Entry = NetListRemoveHead (&mPrivate->NicInfoList);\r
4c5a5e0c 3898 NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);\r
3899 FreePool (NicInfo);\r
3900 mPrivate->NicCount--;\r
3901 }\r
3902\r
3903 ASSERT (mPrivate->NicCount == 0);\r
3904\r
3905 FreePool (mPrivate);\r
3906 mPrivate = NULL;\r
3907\r
3908 //\r
3909 // Remove HII package list.\r
3910 //\r
3911 HiiRemovePackages (mCallbackInfo->RegisteredHandle);\r
3912\r
3913 //\r
3914 // Uninstall Device Path Protocol and Config Access protocol.\r
3915 //\r
3916 Status = gBS->UninstallMultipleProtocolInterfaces (\r
3917 mCallbackInfo->DriverHandle,\r
3918 &gEfiDevicePathProtocolGuid,\r
3919 &mIScsiHiiVendorDevicePath,\r
3920 &gEfiHiiConfigAccessProtocolGuid,\r
3921 &mCallbackInfo->ConfigAccess,\r
3922 NULL\r
3923 );\r
3924\r
3925 FreePool (mCallbackInfo);\r
3926\r
3927 return Status;\r
3928}\r