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