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