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