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