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