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