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