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