2 Helper functions for configuring or getting the parameters relating to iSCSI.
4 Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
11 CHAR16 mVendorStorageName
[] = L
"ISCSI_CONFIG_IFR_NVDATA";
12 ISCSI_FORM_CALLBACK_INFO
*mCallbackInfo
= NULL
;
14 HII_VENDOR_DEVICE_PATH mIScsiHiiVendorDevicePath
= {
20 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
21 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
28 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
30 (UINT8
) (END_DEVICE_PATH_LENGTH
),
31 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
38 Convert the IP address into a dotted string.
40 @param[in] Ip The IP address.
41 @param[in] Ipv6Flag Indicates whether the IP address is version 4 or version 6.
42 @param[out] Str The formatted IP string.
47 IN EFI_IP_ADDRESS
*Ip
,
52 EFI_IPv4_ADDRESS
*Ip4
;
53 EFI_IPv6_ADDRESS
*Ip6
;
57 CHAR16 FormatString
[8];
64 (UINTN
) 2 * IP4_STR_MAX_SIZE
,
78 for (Index
= 0; Index
< 15; Index
= Index
+ 2) {
81 Ip6
->Addr
[Index
] == 0 &&
82 Ip6
->Addr
[Index
+ 1] == 0
85 // Deal with the case of ::.
96 while ((Index
< 15) && (Ip6
->Addr
[Index
] == 0) && (Ip6
->Addr
[Index
+ 1] == 0)) {
104 // :: is at the end of the address.
113 if (Ip6
->Addr
[Index
] == 0) {
114 Number
= UnicodeSPrint (Str
, 2 * IP_STR_MAX_SIZE
, L
"%x:", (UINTN
) Ip6
->Addr
[Index
+ 1]);
116 if (Ip6
->Addr
[Index
+ 1] < 0x10) {
117 CopyMem (FormatString
, L
"%x0%x:", StrSize (L
"%x0%x:"));
119 CopyMem (FormatString
, L
"%x%x:", StrSize (L
"%x%x:"));
122 Number
= UnicodeSPrint (
125 (CONST CHAR16
*) FormatString
,
126 (UINTN
) Ip6
->Addr
[Index
],
127 (UINTN
) Ip6
->Addr
[Index
+ 1]
133 if (Index
+ 2 == 16) {
135 if (*(Str
- 1) == L
':') {
143 Check whether the input IP address is valid.
145 @param[in] Ip The IP address.
146 @param[in] IpMode Indicates iSCSI running on IP4 or IP6 stack.
148 @retval TRUE The input IP address is valid.
149 @retval FALSE Otherwise
154 IN EFI_IP_ADDRESS
*Ip
,
158 if (IpMode
== IP_MODE_IP4
) {
159 if (IP4_IS_UNSPECIFIED (NTOHL (Ip
->Addr
[0])) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip
->Addr
[0]))) {
163 } else if (IpMode
== IP_MODE_IP6
) {
164 return NetIp6IsValidUnicast (&Ip
->v6
);
166 DEBUG ((DEBUG_ERROR
, "IpMode %d is invalid when configuring the iSCSI target IP!\n", IpMode
));
172 Parse IsId in string format and convert it to binary.
174 @param[in] String The buffer of the string to be parsed.
175 @param[in, out] IsId The buffer to store IsId.
177 @retval EFI_SUCCESS The operation finished successfully.
178 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
182 IScsiParseIsIdFromString (
183 IN CONST CHAR16
*String
,
191 CHAR16 PortString
[ISCSI_NAME_IFR_MAX_SIZE
];
194 if ((String
== NULL
) || (IsId
== NULL
)) {
195 return EFI_INVALID_PARAMETER
;
198 IsIdStr
= (CHAR16
*) String
;
200 if (StrLen (IsIdStr
) != 6 && StrLen (IsIdStr
) != 12) {
203 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
204 L
"Error! Only last 3 bytes are configurable, please input 6 hex numbers for last 3 bytes only or 12 hex numbers for full SSID!\n"
208 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
214 return EFI_INVALID_PARAMETER
;
217 if (StrLen (IsIdStr
) == 12) {
221 for (Index
= 3; Index
< 6; Index
++) {
222 CopyMem (TempStr
, IsIdStr
, sizeof (TempStr
));
226 // Convert the string to IsId. StrHexToUintn stops at the first character
227 // that is not a valid hex character, '\0' here.
229 NodeVal
= StrHexToUintn (TempStr
);
231 IsId
[Index
] = (UINT8
) NodeVal
;
233 IsIdStr
= IsIdStr
+ 2;
240 Convert IsId from binary to string format.
242 @param[out] String The buffer to store the converted string.
243 @param[in] IsId The buffer to store IsId.
245 @retval EFI_SUCCESS The string converted successfully.
246 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
250 IScsiConvertIsIdToString (
258 if ((String
== NULL
) || (IsId
== NULL
)) {
259 return EFI_INVALID_PARAMETER
;
262 for (Index
= 0; Index
< 6; Index
++) {
263 if (IsId
[Index
] <= 0xF) {
264 Number
= UnicodeSPrint (
266 2 * ISID_CONFIGURABLE_STORAGE
,
271 Number
= UnicodeSPrint (
273 2 * ISID_CONFIGURABLE_STORAGE
,
280 String
= String
+ Number
;
289 Get the Offset value specified by the input String.
291 @param[in] Configuration A null-terminated Unicode string in
292 <ConfigString> format.
293 @param[in] String The string is "&OFFSET=".
294 @param[out] Value The Offset value.
296 @retval EFI_OUT_OF_RESOURCES Insufficient resources to store neccessary
298 @retval EFI_SUCCESS Value of <Number> is outputted in Number
304 IN CONST EFI_STRING Configuration
,
324 StringPtr
= StrStr (Configuration
, String
);
325 ASSERT(StringPtr
!= NULL
);
326 StringPtr
+= StrLen (String
);
329 while (*StringPtr
!= L
'\0' && *StringPtr
!= L
'&') {
332 Length
= StringPtr
- TmpPtr
;
335 Str
= AllocateZeroPool (Len
* sizeof (CHAR16
));
337 Status
= EFI_OUT_OF_RESOURCES
;
341 CopyMem (Str
, TmpPtr
, Len
* sizeof (CHAR16
));
342 *(Str
+ Length
) = L
'\0';
345 Buf
= (UINT8
*) AllocateZeroPool (Len
);
347 Status
= EFI_OUT_OF_RESOURCES
;
351 ZeroMem (TmpStr
, sizeof (TmpStr
));
352 for (Index
= 0; Index
< Length
; Index
++) {
353 TmpStr
[0] = Str
[Length
- Index
- 1];
354 DigitUint8
= (UINT8
) StrHexToUint64 (TmpStr
);
355 if ((Index
& 1) == 0) {
356 Buf
[Index
/2] = DigitUint8
;
358 Buf
[Index
/2] = (UINT8
) ((DigitUint8
<< 4) + Buf
[Index
/2]);
366 (((Length
+ 1) / 2) < sizeof (UINTN
)) ? ((Length
+ 1) / 2) : sizeof (UINTN
)
370 Status
= EFI_SUCCESS
;
381 Get the attempt config data from global structure by the ConfigIndex.
383 @param[in] AttemptConfigIndex The unique index indicates the attempt.
385 @return Pointer to the attempt config data.
386 @retval NULL The attempt configuration data cannot be found.
389 ISCSI_ATTEMPT_CONFIG_NVDATA
*
390 IScsiConfigGetAttemptByConfigIndex (
391 IN UINT8 AttemptConfigIndex
395 ISCSI_ATTEMPT_CONFIG_NVDATA
*Attempt
;
397 NET_LIST_FOR_EACH (Entry
, &mPrivate
->AttemptConfigs
) {
398 Attempt
= NET_LIST_USER_STRUCT (Entry
, ISCSI_ATTEMPT_CONFIG_NVDATA
, Link
);
399 if (Attempt
->AttemptConfigIndex
== AttemptConfigIndex
) {
409 Get the existing attempt config data from global structure by the NicIndex.
411 @param[in] NewAttempt The created new attempt
412 @param[in] IScsiMode The IScsi Mode of the new attempt, Enabled or
415 @return Pointer to the existing attempt config data which
416 has the same NICIndex as the new created attempt.
417 @retval NULL The attempt with NicIndex does not exist.
420 ISCSI_ATTEMPT_CONFIG_NVDATA
*
421 IScsiConfigGetAttemptByNic (
422 IN ISCSI_ATTEMPT_CONFIG_NVDATA
*NewAttempt
,
427 ISCSI_ATTEMPT_CONFIG_NVDATA
*Attempt
;
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
) {
441 Extract the Index of the attempt list.
443 @param[in] AttemptNameList The Name list of the Attempts.
444 @param[out] AttemptIndexList The Index list of the Attempts.
445 @param[in] IsAddAttempts If TRUE, Indicates add one or more attempts.
446 If FALSE, Indicates delete attempts or change attempt order.
448 @retval EFI_SUCCESS The Attempt list is valid.
449 @retval EFI_INVALID_PARAMETERS The Attempt List is invalid.
453 IScsiGetAttemptIndexList (
454 IN CHAR16
*AttemptNameList
,
455 OUT UINT8
*AttemptIndexList
,
456 IN BOOLEAN IsAddAttempts
459 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
467 if ((AttemptNameList
== NULL
) || (*AttemptNameList
== L
'\0')) {
468 return EFI_INVALID_PARAMETER
;
471 AttemptStr
= AttemptNameList
;
472 Len
= StrLen (L
"attempt:");
474 while (*AttemptStr
!= L
'\0') {
475 AttemptStr
= StrStr (AttemptStr
, L
"attempt:");
476 if (AttemptStr
== NULL
) {
477 return EFI_INVALID_PARAMETER
;
480 AttemptIndex
= (UINT8
)(*AttemptStr
- L
'0');
481 AttemptConfigData
= IScsiConfigGetAttemptByConfigIndex (AttemptIndex
);
483 if ((AttemptConfigData
!= NULL
) || ((AttemptIndex
) > PcdGet8 (PcdMaxIScsiAttemptNumber
))) {
484 return EFI_INVALID_PARAMETER
;
487 if (AttemptConfigData
== NULL
) {
488 return EFI_INVALID_PARAMETER
;
492 AttemptIndexList
[Index
] = AttemptIndex
;
500 Convert the iSCSI configuration data into the IFR data.
502 @param[in] Attempt The iSCSI attempt config data.
503 @param[in, out] IfrNvData The IFR nv data.
507 IScsiConvertAttemptConfigDataToIfrNvData (
508 IN ISCSI_ATTEMPT_CONFIG_NVDATA
*Attempt
,
509 IN OUT ISCSI_CONFIG_IFR_NVDATA
*IfrNvData
512 ISCSI_SESSION_CONFIG_NVDATA
*SessionConfigData
;
513 ISCSI_CHAP_AUTH_CONFIG_NVDATA
*AuthConfigData
;
518 // Normal session configuration parameters.
520 SessionConfigData
= &Attempt
->SessionConfigData
;
521 IfrNvData
->Enabled
= SessionConfigData
->Enabled
;
522 IfrNvData
->IpMode
= SessionConfigData
->IpMode
;
523 DnsMode
= SessionConfigData
->DnsMode
;
525 IfrNvData
->InitiatorInfoFromDhcp
= SessionConfigData
->InitiatorInfoFromDhcp
;
526 IfrNvData
->TargetInfoFromDhcp
= SessionConfigData
->TargetInfoFromDhcp
;
527 IfrNvData
->TargetPort
= SessionConfigData
->TargetPort
;
529 if (IfrNvData
->IpMode
== IP_MODE_IP4
) {
530 CopyMem (&Ip
.v4
, &SessionConfigData
->LocalIp
, sizeof (EFI_IPv4_ADDRESS
));
531 IScsiIpToStr (&Ip
, FALSE
, IfrNvData
->LocalIp
);
532 CopyMem (&Ip
.v4
, &SessionConfigData
->SubnetMask
, sizeof (EFI_IPv4_ADDRESS
));
533 IScsiIpToStr (&Ip
, FALSE
, IfrNvData
->SubnetMask
);
534 CopyMem (&Ip
.v4
, &SessionConfigData
->Gateway
, sizeof (EFI_IPv4_ADDRESS
));
535 IScsiIpToStr (&Ip
, FALSE
, IfrNvData
->Gateway
);
536 ZeroMem (IfrNvData
->TargetIp
, sizeof (IfrNvData
->TargetIp
));
537 if (SessionConfigData
->TargetIp
.v4
.Addr
[0] != '\0') {
538 CopyMem (&Ip
.v4
, &SessionConfigData
->TargetIp
, sizeof (EFI_IPv4_ADDRESS
));
539 IScsiIpToStr (&Ip
, FALSE
, IfrNvData
->TargetIp
);
542 } else if (IfrNvData
->IpMode
== IP_MODE_IP6
) {
543 ZeroMem (IfrNvData
->TargetIp
, sizeof (IfrNvData
->TargetIp
));
544 if (SessionConfigData
->TargetIp
.v6
.Addr
[0] != '\0') {
545 IP6_COPY_ADDRESS (&Ip
.v6
, &SessionConfigData
->TargetIp
);
546 IScsiIpToStr (&Ip
, TRUE
, IfrNvData
->TargetIp
);
550 AsciiStrToUnicodeStrS (
551 SessionConfigData
->TargetName
,
552 IfrNvData
->TargetName
,
553 sizeof (IfrNvData
->TargetName
) / sizeof (IfrNvData
->TargetName
[0])
557 AsciiStrToUnicodeStrS (
558 SessionConfigData
->TargetUrl
,
560 sizeof (IfrNvData
->TargetIp
) / sizeof (IfrNvData
->TargetIp
[0])
564 IScsiLunToUnicodeStr (SessionConfigData
->BootLun
, IfrNvData
->BootLun
);
565 IScsiConvertIsIdToString (IfrNvData
->IsId
, SessionConfigData
->IsId
);
567 IfrNvData
->ConnectRetryCount
= SessionConfigData
->ConnectRetryCount
;
568 IfrNvData
->ConnectTimeout
= SessionConfigData
->ConnectTimeout
;
571 // Authentication parameters.
573 IfrNvData
->AuthenticationType
= Attempt
->AuthenticationType
;
575 if (IfrNvData
->AuthenticationType
== ISCSI_AUTH_TYPE_CHAP
) {
576 AuthConfigData
= &Attempt
->AuthConfigData
.CHAP
;
577 IfrNvData
->CHAPType
= AuthConfigData
->CHAPType
;
578 AsciiStrToUnicodeStrS (
579 AuthConfigData
->CHAPName
,
581 sizeof (IfrNvData
->CHAPName
) / sizeof (IfrNvData
->CHAPName
[0])
583 AsciiStrToUnicodeStrS (
584 AuthConfigData
->CHAPSecret
,
585 IfrNvData
->CHAPSecret
,
586 sizeof (IfrNvData
->CHAPSecret
) / sizeof (IfrNvData
->CHAPSecret
[0])
588 AsciiStrToUnicodeStrS (
589 AuthConfigData
->ReverseCHAPName
,
590 IfrNvData
->ReverseCHAPName
,
591 sizeof (IfrNvData
->ReverseCHAPName
) / sizeof (IfrNvData
->ReverseCHAPName
[0])
593 AsciiStrToUnicodeStrS (
594 AuthConfigData
->ReverseCHAPSecret
,
595 IfrNvData
->ReverseCHAPSecret
,
596 sizeof (IfrNvData
->ReverseCHAPSecret
) / sizeof (IfrNvData
->ReverseCHAPSecret
[0])
603 AsciiStrToUnicodeStrS (
604 Attempt
->AttemptName
,
605 IfrNvData
->AttemptName
,
606 sizeof (IfrNvData
->AttemptName
) / sizeof (IfrNvData
->AttemptName
[0])
611 Convert the iSCSI configuration data into the IFR data Which will be used
612 to extract the iSCSI Keyword configuration in <ConfigAltResp> format.
614 @param[in, out] IfrNvData The IFR nv data.
619 IScsiConvertAttemptConfigDataToIfrNvDataByKeyword (
620 IN OUT ISCSI_CONFIG_IFR_NVDATA
*IfrNvData
624 ISCSI_ATTEMPT_CONFIG_NVDATA
*Attempt
;
625 ISCSI_SESSION_CONFIG_NVDATA
*SessionConfigData
;
626 ISCSI_CHAP_AUTH_CONFIG_NVDATA
*AuthConfigData
;
627 CHAR16 AttemptNameList
[ATTEMPT_NAME_LIST_SIZE
];
628 ISCSI_NIC_INFO
*NicInfo
;
629 CHAR16 MacString
[ISCSI_MAX_MAC_STRING_LEN
];
635 ZeroMem (AttemptNameList
, sizeof (AttemptNameList
));
637 if ((mPrivate
!= NULL
) && (mPrivate
->AttemptCount
!= 0)) {
638 NET_LIST_FOR_EACH (Entry
, &mPrivate
->AttemptConfigs
) {
639 Attempt
= NET_LIST_USER_STRUCT (Entry
, ISCSI_ATTEMPT_CONFIG_NVDATA
, Link
);
641 // Normal session configuration parameters.
643 SessionConfigData
= &Attempt
->SessionConfigData
;
645 ASSERT ((Attempt
->AttemptConfigIndex
> 0) && (Attempt
->AttemptConfigIndex
<= FixedPcdGet8 (PcdMaxIScsiAttemptNumber
)));
646 Index
= Attempt
->AttemptConfigIndex
- 1;
649 // Save the attempt to AttemptNameList as Attempt:1 Attempt:2
651 AsciiStrToUnicodeStrS (
652 Attempt
->AttemptName
,
653 AttemptNameList
+ StrLen (AttemptNameList
),
654 ATTEMPT_NAME_LIST_SIZE
- StrLen (AttemptNameList
)
657 StringLen
= StrLen (AttemptNameList
);
658 ASSERT (StringLen
> 2);
659 *(AttemptNameList
+ StringLen
- 2) = L
':';
660 *(AttemptNameList
+ StringLen
) = L
' ';
662 AsciiStrToUnicodeStrS (
663 Attempt
->AttemptName
,
664 IfrNvData
->ISCSIAttemptName
+ ATTEMPT_NAME_SIZE
* Index
,
665 ATTEMPT_NAME_LIST_SIZE
- ATTEMPT_NAME_SIZE
* Index
668 IfrNvData
->ISCSIBootEnableList
[Index
] = SessionConfigData
->Enabled
;
669 IfrNvData
->ISCSIIpAddressTypeList
[Index
] = SessionConfigData
->IpMode
;
671 IfrNvData
->ISCSIInitiatorInfoViaDHCP
[Index
] = SessionConfigData
->InitiatorInfoFromDhcp
;
672 IfrNvData
->ISCSITargetInfoViaDHCP
[Index
] = SessionConfigData
->TargetInfoFromDhcp
;
673 IfrNvData
->ISCSIConnectRetry
[Index
] = SessionConfigData
->ConnectRetryCount
;
674 IfrNvData
->ISCSIConnectTimeout
[Index
] = SessionConfigData
->ConnectTimeout
;
675 IfrNvData
->ISCSITargetTcpPort
[Index
] = SessionConfigData
->TargetPort
;
677 if (SessionConfigData
->IpMode
== IP_MODE_IP4
) {
678 CopyMem (&Ip
.v4
, &SessionConfigData
->LocalIp
, sizeof (EFI_IPv4_ADDRESS
));
679 IScsiIpToStr (&Ip
, FALSE
, IfrNvData
->Keyword
[Index
].ISCSIInitiatorIpAddress
);
680 CopyMem (&Ip
.v4
, &SessionConfigData
->SubnetMask
, sizeof (EFI_IPv4_ADDRESS
));
681 IScsiIpToStr (&Ip
, FALSE
, IfrNvData
->Keyword
[Index
].ISCSIInitiatorNetmask
);
682 CopyMem (&Ip
.v4
, &SessionConfigData
->Gateway
, sizeof (EFI_IPv4_ADDRESS
));
683 IScsiIpToStr (&Ip
, FALSE
, IfrNvData
->Keyword
[Index
].ISCSIInitiatorGateway
);
684 if (SessionConfigData
->TargetIp
.v4
.Addr
[0] != '\0') {
685 CopyMem (&Ip
.v4
, &SessionConfigData
->TargetIp
, sizeof (EFI_IPv4_ADDRESS
));
686 IScsiIpToStr (&Ip
, FALSE
, IfrNvData
->Keyword
[Index
].ISCSITargetIpAddress
);
688 } else if (SessionConfigData
->IpMode
== IP_MODE_IP6
) {
689 ZeroMem (IfrNvData
->Keyword
[Index
].ISCSITargetIpAddress
, sizeof (IfrNvData
->TargetIp
));
690 if (SessionConfigData
->TargetIp
.v6
.Addr
[0] != '\0') {
691 IP6_COPY_ADDRESS (&Ip
.v6
, &SessionConfigData
->TargetIp
);
692 IScsiIpToStr (&Ip
, TRUE
, IfrNvData
->Keyword
[Index
].ISCSITargetIpAddress
);
696 AsciiStrToUnicodeStrS (
697 SessionConfigData
->TargetName
,
698 IfrNvData
->Keyword
[Index
].ISCSITargetName
,
702 if (SessionConfigData
->DnsMode
) {
703 AsciiStrToUnicodeStrS (
704 SessionConfigData
->TargetUrl
,
705 IfrNvData
->Keyword
[Index
].ISCSITargetIpAddress
,
706 sizeof (IfrNvData
->Keyword
[Index
].ISCSITargetIpAddress
) / sizeof (IfrNvData
->Keyword
[Index
].ISCSITargetIpAddress
[0])
710 IScsiLunToUnicodeStr (SessionConfigData
->BootLun
, IfrNvData
->Keyword
[Index
].ISCSILun
);
711 IScsiConvertIsIdToString (IfrNvData
->Keyword
[Index
].ISCSIIsId
, SessionConfigData
->IsId
);
713 IfrNvData
->ISCSIAuthenticationMethod
[Index
] = Attempt
->AuthenticationType
;
715 if (Attempt
->AuthenticationType
== ISCSI_AUTH_TYPE_CHAP
) {
716 AuthConfigData
= &Attempt
->AuthConfigData
.CHAP
;
717 IfrNvData
->ISCSIChapType
[Index
] = AuthConfigData
->CHAPType
;
718 AsciiStrToUnicodeStrS (
719 AuthConfigData
->CHAPName
,
720 IfrNvData
->Keyword
[Index
].ISCSIChapUsername
,
721 ISCSI_CHAP_NAME_STORAGE
724 AsciiStrToUnicodeStrS (
725 AuthConfigData
->CHAPSecret
,
726 IfrNvData
->Keyword
[Index
].ISCSIChapSecret
,
727 ISCSI_CHAP_SECRET_STORAGE
730 AsciiStrToUnicodeStrS (
731 AuthConfigData
->ReverseCHAPName
,
732 IfrNvData
->Keyword
[Index
].ISCSIReverseChapUsername
,
733 ISCSI_CHAP_NAME_STORAGE
736 AsciiStrToUnicodeStrS (
737 AuthConfigData
->ReverseCHAPSecret
,
738 IfrNvData
->Keyword
[Index
].ISCSIReverseChapSecret
,
739 ISCSI_CHAP_SECRET_STORAGE
743 CopyMem(IfrNvData
->ISCSIDisplayAttemptList
, AttemptNameList
, ATTEMPT_NAME_LIST_SIZE
);
745 ZeroMem (IfrNvData
->ISCSIMacAddr
, sizeof (IfrNvData
->ISCSIMacAddr
));
746 NET_LIST_FOR_EACH (Entry
, &mPrivate
->NicInfoList
) {
747 NicInfo
= NET_LIST_USER_STRUCT (Entry
, ISCSI_NIC_INFO
, Link
);
749 &NicInfo
->PermanentAddress
,
750 NicInfo
->HwAddressSize
,
755 IfrNvData
->ISCSIMacAddr
+ StrLen (IfrNvData
->ISCSIMacAddr
),
757 StrLen (MacString
) * sizeof (CHAR16
)
760 *(IfrNvData
->ISCSIMacAddr
+ StrLen (IfrNvData
->ISCSIMacAddr
)) = L
'/';
763 StringLen
= StrLen (IfrNvData
->ISCSIMacAddr
);
765 *(IfrNvData
->ISCSIMacAddr
+ StringLen
- 1) = L
'\0';
771 Convert the IFR data to iSCSI configuration data.
773 @param[in] IfrNvData Point to ISCSI_CONFIG_IFR_NVDATA.
774 @param[in, out] Attempt The iSCSI attempt config data.
776 @retval EFI_INVALID_PARAMETER Any input or configured parameter is invalid.
777 @retval EFI_NOT_FOUND Cannot find the corresponding variable.
778 @retval EFI_OUT_OF_RESOURCES The operation is failed due to lack of resources.
779 @retval EFI_ABORTED The operation is aborted.
780 @retval EFI_SUCCESS The operation is completed successfully.
784 IScsiConvertIfrNvDataToAttemptConfigData (
785 IN ISCSI_CONFIG_IFR_NVDATA
*IfrNvData
,
786 IN OUT ISCSI_ATTEMPT_CONFIG_NVDATA
*Attempt
789 EFI_IP_ADDRESS HostIp
;
790 EFI_IP_ADDRESS SubnetMask
;
791 EFI_IP_ADDRESS Gateway
;
793 CHAR16
*AttemptName1
;
794 CHAR16
*AttemptName2
;
795 ISCSI_ATTEMPT_CONFIG_NVDATA
*ExistAttempt
;
796 ISCSI_ATTEMPT_CONFIG_NVDATA
*SameNicAttempt
;
797 CHAR16 IScsiMode
[64];
799 ISCSI_NIC_INFO
*NicInfo
;
801 UINT8
*AttemptConfigOrder
;
802 UINTN AttemptConfigOrderSize
;
803 UINT8
*AttemptOrderTmp
;
807 if (IfrNvData
== NULL
|| Attempt
== NULL
) {
808 return EFI_INVALID_PARAMETER
;
812 // Update those fields which don't have INTERACTIVE attribute.
814 Attempt
->SessionConfigData
.ConnectRetryCount
= IfrNvData
->ConnectRetryCount
;
815 Attempt
->SessionConfigData
.ConnectTimeout
= IfrNvData
->ConnectTimeout
;
816 Attempt
->SessionConfigData
.IpMode
= IfrNvData
->IpMode
;
818 if (IfrNvData
->IpMode
< IP_MODE_AUTOCONFIG
) {
819 Attempt
->SessionConfigData
.InitiatorInfoFromDhcp
= IfrNvData
->InitiatorInfoFromDhcp
;
820 Attempt
->SessionConfigData
.TargetPort
= IfrNvData
->TargetPort
;
822 if (Attempt
->SessionConfigData
.TargetPort
== 0) {
823 Attempt
->SessionConfigData
.TargetPort
= ISCSI_WELL_KNOWN_PORT
;
826 Attempt
->SessionConfigData
.TargetInfoFromDhcp
= IfrNvData
->TargetInfoFromDhcp
;
829 Attempt
->AuthenticationType
= IfrNvData
->AuthenticationType
;
831 if (Attempt
->AuthenticationType
== ISCSI_AUTH_TYPE_CHAP
) {
832 Attempt
->AuthConfigData
.CHAP
.CHAPType
= IfrNvData
->CHAPType
;
836 // Only do full parameter validation if iSCSI is enabled on this device.
838 if (IfrNvData
->Enabled
!= ISCSI_DISABLED
) {
839 if (Attempt
->SessionConfigData
.ConnectTimeout
< CONNECT_MIN_TIMEOUT
) {
841 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
843 L
"Connection Establishing Timeout is less than minimum value 100ms.",
847 return EFI_INVALID_PARAMETER
;
851 // Validate the address configuration of the Initiator if DHCP isn't
854 if (!Attempt
->SessionConfigData
.InitiatorInfoFromDhcp
) {
855 CopyMem (&HostIp
.v4
, &Attempt
->SessionConfigData
.LocalIp
, sizeof (HostIp
.v4
));
856 CopyMem (&SubnetMask
.v4
, &Attempt
->SessionConfigData
.SubnetMask
, sizeof (SubnetMask
.v4
));
857 CopyMem (&Gateway
.v4
, &Attempt
->SessionConfigData
.Gateway
, sizeof (Gateway
.v4
));
859 if ((Gateway
.Addr
[0] != 0)) {
860 if (SubnetMask
.Addr
[0] == 0) {
862 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
864 L
"Gateway address is set but subnet mask is zero.",
868 return EFI_INVALID_PARAMETER
;
869 } else if (!IP4_NET_EQUAL (HostIp
.Addr
[0], Gateway
.Addr
[0], SubnetMask
.Addr
[0])) {
871 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
873 L
"Local IP and Gateway are not in the same subnet.",
877 return EFI_INVALID_PARAMETER
;
882 // Validate target configuration if DHCP isn't deployed.
884 if (!Attempt
->SessionConfigData
.TargetInfoFromDhcp
&& Attempt
->SessionConfigData
.IpMode
< IP_MODE_AUTOCONFIG
) {
885 if (!Attempt
->SessionConfigData
.DnsMode
) {
886 if (!IpIsUnicast (&Attempt
->SessionConfigData
.TargetIp
, IfrNvData
->IpMode
)) {
888 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
890 L
"Target IP is invalid!",
893 return EFI_INVALID_PARAMETER
;
896 if (Attempt
->SessionConfigData
.TargetUrl
[0] == '\0') {
898 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
900 L
"iSCSI target Url should not be NULL!",
903 return EFI_INVALID_PARAMETER
;
908 // Validate iSCSI target name configuration again:
909 // The format of iSCSI target name is already verified in IScsiFormCallback() when
910 // user input the name; here we only check the case user does not input the name.
912 if (Attempt
->SessionConfigData
.TargetName
[0] == '\0') {
914 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
916 L
"iSCSI target name is NULL!",
919 return EFI_INVALID_PARAMETER
;
924 // Validate the authentication info.
926 if (IfrNvData
->AuthenticationType
== ISCSI_AUTH_TYPE_CHAP
) {
927 if ((IfrNvData
->CHAPName
[0] == '\0') || (IfrNvData
->CHAPSecret
[0] == '\0')) {
929 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
931 L
"CHAP Name or CHAP Secret is invalid!",
935 return EFI_INVALID_PARAMETER
;
938 if ((IfrNvData
->CHAPType
== ISCSI_CHAP_MUTUAL
) &&
939 ((IfrNvData
->ReverseCHAPName
[0] == '\0') || (IfrNvData
->ReverseCHAPSecret
[0] == '\0'))
942 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
944 L
"Reverse CHAP Name or Reverse CHAP Secret is invalid!",
947 return EFI_INVALID_PARAMETER
;
952 // Check whether this attempt uses NIC which is already used by existing attempt.
954 SameNicAttempt
= IScsiConfigGetAttemptByNic (Attempt
, IfrNvData
->Enabled
);
955 if (SameNicAttempt
!= NULL
) {
956 AttemptName1
= (CHAR16
*) AllocateZeroPool (ATTEMPT_NAME_SIZE
* sizeof (CHAR16
));
957 if (AttemptName1
== NULL
) {
958 return EFI_OUT_OF_RESOURCES
;
961 AttemptName2
= (CHAR16
*) AllocateZeroPool (ATTEMPT_NAME_SIZE
* sizeof (CHAR16
));
962 if (AttemptName2
== NULL
) {
963 FreePool (AttemptName1
);
964 return EFI_OUT_OF_RESOURCES
;
967 AsciiStrToUnicodeStrS (Attempt
->AttemptName
, AttemptName1
, ATTEMPT_NAME_SIZE
);
968 AsciiStrToUnicodeStrS (SameNicAttempt
->AttemptName
, AttemptName2
, ATTEMPT_NAME_SIZE
);
971 mPrivate
->PortString
,
972 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
973 L
"Warning! Attempt \"%s\" uses same NIC as Attempt \"%s\".",
979 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
981 mPrivate
->PortString
,
985 FreePool (AttemptName1
);
986 FreePool (AttemptName2
);
991 // Update the iSCSI Mode data and record it in attempt help info.
993 if (IfrNvData
->Enabled
== ISCSI_DISABLED
) {
994 UnicodeSPrint (IScsiMode
, 64, L
"Disabled");
995 } else if (IfrNvData
->Enabled
== ISCSI_ENABLED
) {
996 UnicodeSPrint (IScsiMode
, 64, L
"Enabled");
997 } else if (IfrNvData
->Enabled
== ISCSI_ENABLED_FOR_MPIO
) {
998 UnicodeSPrint (IScsiMode
, 64, L
"Enabled for MPIO");
1001 if (IfrNvData
->IpMode
== IP_MODE_IP4
) {
1002 UnicodeSPrint (IpMode
, 64, L
"IP4");
1003 } else if (IfrNvData
->IpMode
== IP_MODE_IP6
) {
1004 UnicodeSPrint (IpMode
, 64, L
"IP6");
1005 } else if (IfrNvData
->IpMode
== IP_MODE_AUTOCONFIG
) {
1006 UnicodeSPrint (IpMode
, 64, L
"Autoconfigure");
1009 NicInfo
= IScsiGetNicInfoByIndex (Attempt
->NicIndex
);
1010 if (NicInfo
== NULL
) {
1011 return EFI_NOT_FOUND
;
1014 MacString
= (CHAR16
*) AllocateZeroPool (ISCSI_MAX_MAC_STRING_LEN
* sizeof (CHAR16
));
1015 if (MacString
== NULL
) {
1016 return EFI_OUT_OF_RESOURCES
;
1019 AsciiStrToUnicodeStrS (Attempt
->MacString
, MacString
, ISCSI_MAX_MAC_STRING_LEN
);
1022 mPrivate
->PortString
,
1023 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
1024 L
"MAC: %s, PFA: Bus %d | Dev %d | Func %d, iSCSI mode: %s, IP version: %s",
1027 NicInfo
->DeviceNumber
,
1028 NicInfo
->FunctionNumber
,
1033 Attempt
->AttemptTitleHelpToken
= HiiSetString (
1034 mCallbackInfo
->RegisteredHandle
,
1035 Attempt
->AttemptTitleHelpToken
,
1036 mPrivate
->PortString
,
1039 if (Attempt
->AttemptTitleHelpToken
== 0) {
1040 FreePool (MacString
);
1041 return EFI_OUT_OF_RESOURCES
;
1045 // Check whether this attempt is an existing one.
1047 ExistAttempt
= IScsiConfigGetAttemptByConfigIndex (Attempt
->AttemptConfigIndex
);
1048 if (ExistAttempt
!= NULL
) {
1049 ASSERT (ExistAttempt
== Attempt
);
1051 if (IfrNvData
->Enabled
== ISCSI_DISABLED
&&
1052 Attempt
->SessionConfigData
.Enabled
!= ISCSI_DISABLED
) {
1055 // User updates the Attempt from "Enabled"/"Enabled for MPIO" to "Disabled".
1057 if (Attempt
->SessionConfigData
.Enabled
== ISCSI_ENABLED_FOR_MPIO
) {
1058 if (mPrivate
->MpioCount
< 1) {
1062 if (--mPrivate
->MpioCount
== 0) {
1063 mPrivate
->EnableMpio
= FALSE
;
1065 } else if (Attempt
->SessionConfigData
.Enabled
== ISCSI_ENABLED
) {
1066 if (mPrivate
->SinglePathCount
< 1) {
1069 mPrivate
->SinglePathCount
--;
1072 } else if (IfrNvData
->Enabled
== ISCSI_ENABLED_FOR_MPIO
&&
1073 Attempt
->SessionConfigData
.Enabled
== ISCSI_ENABLED
) {
1075 // User updates the Attempt from "Enabled" to "Enabled for MPIO".
1077 if (mPrivate
->SinglePathCount
< 1) {
1081 mPrivate
->EnableMpio
= TRUE
;
1082 mPrivate
->MpioCount
++;
1083 mPrivate
->SinglePathCount
--;
1085 } else if (IfrNvData
->Enabled
== ISCSI_ENABLED
&&
1086 Attempt
->SessionConfigData
.Enabled
== ISCSI_ENABLED_FOR_MPIO
) {
1088 // User updates the Attempt from "Enabled for MPIO" to "Enabled".
1090 if (mPrivate
->MpioCount
< 1) {
1094 if (--mPrivate
->MpioCount
== 0) {
1095 mPrivate
->EnableMpio
= FALSE
;
1097 mPrivate
->SinglePathCount
++;
1099 } else if (IfrNvData
->Enabled
!= ISCSI_DISABLED
&&
1100 Attempt
->SessionConfigData
.Enabled
== ISCSI_DISABLED
) {
1102 // User updates the Attempt from "Disabled" to "Enabled"/"Enabled for MPIO".
1104 if (IfrNvData
->Enabled
== ISCSI_ENABLED_FOR_MPIO
) {
1105 mPrivate
->EnableMpio
= TRUE
;
1106 mPrivate
->MpioCount
++;
1108 } else if (IfrNvData
->Enabled
== ISCSI_ENABLED
) {
1109 mPrivate
->SinglePathCount
++;
1113 } else if (ExistAttempt
== NULL
) {
1115 // When a new attempt is created, pointer of the attempt is saved to
1116 // mCallbackInfo->Current in IScsiConfigProcessDefault. If input Attempt
1117 // does not match any existing attempt, it should be a new created attempt.
1118 // Save it to system now.
1122 // Save current order number for this attempt.
1124 AttemptConfigOrder
= IScsiGetVariableAndSize (
1127 &AttemptConfigOrderSize
1130 TotalNumber
= AttemptConfigOrderSize
/ sizeof (UINT8
);
1134 // Append the new created attempt order to the end.
1136 AttemptOrderTmp
= AllocateZeroPool (TotalNumber
* sizeof (UINT8
));
1137 if (AttemptOrderTmp
== NULL
) {
1138 if (AttemptConfigOrder
!= NULL
) {
1139 FreePool (AttemptConfigOrder
);
1141 return EFI_OUT_OF_RESOURCES
;
1144 if (AttemptConfigOrder
!= NULL
) {
1145 CopyMem (AttemptOrderTmp
, AttemptConfigOrder
, AttemptConfigOrderSize
);
1146 FreePool (AttemptConfigOrder
);
1149 AttemptOrderTmp
[TotalNumber
- 1] = Attempt
->AttemptConfigIndex
;
1150 AttemptConfigOrder
= AttemptOrderTmp
;
1151 AttemptConfigOrderSize
= TotalNumber
* sizeof (UINT8
);
1153 Status
= gRT
->SetVariable (
1156 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
1157 AttemptConfigOrderSize
,
1160 FreePool (AttemptConfigOrder
);
1161 if (EFI_ERROR (Status
)) {
1166 // Insert new created attempt to array.
1168 InsertTailList (&mPrivate
->AttemptConfigs
, &Attempt
->Link
);
1169 mPrivate
->AttemptCount
++;
1171 if (IfrNvData
->Enabled
== ISCSI_ENABLED_FOR_MPIO
) {
1173 // This new Attempt is enabled for MPIO; enable the multipath mode.
1175 mPrivate
->EnableMpio
= TRUE
;
1176 mPrivate
->MpioCount
++;
1177 } else if (IfrNvData
->Enabled
== ISCSI_ENABLED
) {
1178 mPrivate
->SinglePathCount
++;
1181 IScsiConfigUpdateAttempt ();
1183 Attempt
->SessionConfigData
.Enabled
= IfrNvData
->Enabled
;
1186 // Record the user configuration information in NVR.
1188 UnicodeSPrint (mPrivate
->PortString
, (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
, L
"Attempt %d", Attempt
->AttemptConfigIndex
);
1190 FreePool (MacString
);
1192 return gRT
->SetVariable (
1193 mPrivate
->PortString
,
1194 &gEfiIScsiInitiatorNameProtocolGuid
,
1195 ISCSI_CONFIG_VAR_ATTR
,
1196 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
1202 Convert the IFR data configured by keyword to iSCSI configuration data.
1204 @param[in] IfrNvData Point to ISCSI_CONFIG_IFR_NVDATA.
1205 @param[in] OffSet The offset of the variable to the configuration structure.
1207 @retval EFI_INVALID_PARAMETER Any input or configured parameter is invalid.
1208 @retval EFI_SUCCESS The operation is completed successfully.
1212 IScsiConvertlfrNvDataToAttemptConfigDataByKeyword (
1213 IN ISCSI_CONFIG_IFR_NVDATA
*IfrNvData
,
1217 ISCSI_ATTEMPT_CONFIG_NVDATA
*Attempt
;
1220 UINT8 ChapSecretLen
;
1221 UINT8 ReverseChapSecretLen
;
1222 CHAR16
*AttemptName1
;
1223 CHAR16
*AttemptName2
;
1224 ISCSI_ATTEMPT_CONFIG_NVDATA
*SameNicAttempt
;
1225 CHAR8 LunString
[ISCSI_LUN_STR_MAX_LEN
];
1226 CHAR8 IScsiName
[ISCSI_NAME_MAX_SIZE
];
1227 CHAR8 IpString
[IP_STR_MAX_SIZE
];
1228 EFI_IP_ADDRESS HostIp
;
1229 EFI_IP_ADDRESS SubnetMask
;
1230 EFI_IP_ADDRESS Gateway
;
1236 ZeroMem (IScsiName
, sizeof (IScsiName
));
1238 if (OffSet
< ATTEMPT_BOOTENABLE_VAR_OFFSET
) {
1241 } else if ((OffSet
>= ATTEMPT_BOOTENABLE_VAR_OFFSET
) && (OffSet
< ATTEMPT_ADDRESS_TYPE_VAR_OFFSET
)) {
1242 AttemptIndex
= (UINT8
) ((OffSet
- ATTEMPT_BOOTENABLE_VAR_OFFSET
) + 1);
1243 Attempt
= IScsiConfigGetAttemptByConfigIndex (AttemptIndex
);
1244 if (Attempt
== NULL
) {
1245 return EFI_INVALID_PARAMETER
;
1247 IfrNvData
->Enabled
= IfrNvData
->ISCSIBootEnableList
[AttemptIndex
- 1];
1249 // Validate the configuration of attempt.
1251 if (IfrNvData
->Enabled
!= ISCSI_DISABLED
) {
1253 // Check whether this attempt uses NIC which is already used by existing attempt.
1255 SameNicAttempt
= IScsiConfigGetAttemptByNic (Attempt
, IfrNvData
->Enabled
);
1256 if (SameNicAttempt
!= NULL
) {
1257 AttemptName1
= (CHAR16
*) AllocateZeroPool (ATTEMPT_NAME_SIZE
* sizeof (CHAR16
));
1258 if (AttemptName1
== NULL
) {
1259 return EFI_OUT_OF_RESOURCES
;
1262 AttemptName2
= (CHAR16
*) AllocateZeroPool (ATTEMPT_NAME_SIZE
* sizeof (CHAR16
));
1263 if (AttemptName2
== NULL
) {
1264 FreePool (AttemptName1
);
1265 return EFI_OUT_OF_RESOURCES
;
1268 AsciiStrToUnicodeStrS (Attempt
->AttemptName
, AttemptName1
, ATTEMPT_NAME_SIZE
);
1269 AsciiStrToUnicodeStrS (SameNicAttempt
->AttemptName
, AttemptName2
, ATTEMPT_NAME_SIZE
);
1272 mPrivate
->PortString
,
1273 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
1274 L
"Warning! \"%s\" uses same NIC as Attempt \"%s\".",
1280 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1282 mPrivate
->PortString
,
1286 FreePool (AttemptName1
);
1287 FreePool (AttemptName2
);
1291 if (IfrNvData
->Enabled
== ISCSI_DISABLED
&&
1292 Attempt
->SessionConfigData
.Enabled
!= ISCSI_DISABLED
) {
1295 // User updates the Attempt from "Enabled"/"Enabled for MPIO" to "Disabled".
1297 if (Attempt
->SessionConfigData
.Enabled
== ISCSI_ENABLED_FOR_MPIO
) {
1298 if (mPrivate
->MpioCount
< 1) {
1302 if (--mPrivate
->MpioCount
== 0) {
1303 mPrivate
->EnableMpio
= FALSE
;
1305 } else if (Attempt
->SessionConfigData
.Enabled
== ISCSI_ENABLED
) {
1306 if (mPrivate
->SinglePathCount
< 1) {
1309 mPrivate
->SinglePathCount
--;
1312 } else if (IfrNvData
->Enabled
== ISCSI_ENABLED_FOR_MPIO
&&
1313 Attempt
->SessionConfigData
.Enabled
== ISCSI_ENABLED
) {
1315 // User updates the Attempt from "Enabled" to "Enabled for MPIO".
1317 if (mPrivate
->SinglePathCount
< 1) {
1321 mPrivate
->EnableMpio
= TRUE
;
1322 mPrivate
->MpioCount
++;
1323 mPrivate
->SinglePathCount
--;
1325 } else if (IfrNvData
->Enabled
== ISCSI_ENABLED
&&
1326 Attempt
->SessionConfigData
.Enabled
== ISCSI_ENABLED_FOR_MPIO
) {
1328 // User updates the Attempt from "Enabled for MPIO" to "Enabled".
1330 if (mPrivate
->MpioCount
< 1) {
1334 if (--mPrivate
->MpioCount
== 0) {
1335 mPrivate
->EnableMpio
= FALSE
;
1337 mPrivate
->SinglePathCount
++;
1339 } else if (IfrNvData
->Enabled
!= ISCSI_DISABLED
&&
1340 Attempt
->SessionConfigData
.Enabled
== ISCSI_DISABLED
) {
1342 // User updates the Attempt from "Disabled" to "Enabled"/"Enabled for MPIO".
1344 if (IfrNvData
->Enabled
== ISCSI_ENABLED_FOR_MPIO
) {
1345 mPrivate
->EnableMpio
= TRUE
;
1346 mPrivate
->MpioCount
++;
1348 } else if (IfrNvData
->Enabled
== ISCSI_ENABLED
) {
1349 mPrivate
->SinglePathCount
++;
1352 Attempt
->SessionConfigData
.Enabled
= IfrNvData
->Enabled
;
1354 } else if ((OffSet
>= ATTEMPT_ADDRESS_TYPE_VAR_OFFSET
) && (OffSet
< ATTEMPT_CONNECT_RETRY_VAR_OFFSET
)) {
1355 AttemptIndex
= (UINT8
) ((OffSet
- ATTEMPT_ADDRESS_TYPE_VAR_OFFSET
) + 1);
1356 Attempt
= IScsiConfigGetAttemptByConfigIndex (AttemptIndex
);
1357 if (Attempt
== NULL
) {
1358 return EFI_INVALID_PARAMETER
;
1360 Attempt
->SessionConfigData
.IpMode
= IfrNvData
->ISCSIIpAddressTypeList
[AttemptIndex
- 1];
1361 if (Attempt
->SessionConfigData
.IpMode
< IP_MODE_AUTOCONFIG
) {
1362 Attempt
->AutoConfigureMode
= 0;
1365 } else if ((OffSet
>= ATTEMPT_CONNECT_RETRY_VAR_OFFSET
) && (OffSet
< ATTEMPT_CONNECT_TIMEOUT_VAR_OFFSET
)) {
1366 AttemptIndex
= (UINT8
) ((OffSet
- ATTEMPT_CONNECT_RETRY_VAR_OFFSET
) + 1);
1367 Attempt
= IScsiConfigGetAttemptByConfigIndex (AttemptIndex
);
1368 if (Attempt
== NULL
) {
1369 return EFI_INVALID_PARAMETER
;
1372 if (IfrNvData
->ISCSIConnectRetry
[AttemptIndex
- 1] > CONNECT_MAX_RETRY
) {
1374 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1376 L
"The minimum value is 0 and the maximum is 16. 0 means no retry.",
1379 return EFI_INVALID_PARAMETER
;
1381 Attempt
->SessionConfigData
.ConnectRetryCount
= IfrNvData
->ISCSIConnectRetry
[AttemptIndex
- 1];
1383 } else if ((OffSet
>= ATTEMPT_CONNECT_TIMEOUT_VAR_OFFSET
) && (OffSet
< ATTEMPT_INITIATOR_VIA_DHCP_VAR_OFFSET
)) {
1384 AttemptIndex
= (UINT8
) ((OffSet
- ATTEMPT_CONNECT_TIMEOUT_VAR_OFFSET
) / 2 + 1);
1385 Attempt
= IScsiConfigGetAttemptByConfigIndex (AttemptIndex
);
1386 if (Attempt
== NULL
) {
1387 return EFI_INVALID_PARAMETER
;
1390 if ((IfrNvData
->ISCSIConnectTimeout
[AttemptIndex
- 1] < CONNECT_MIN_TIMEOUT
) ||
1391 (IfrNvData
->ISCSIConnectTimeout
[AttemptIndex
- 1] > CONNECT_MAX_TIMEOUT
)) {
1393 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1395 L
"The minimum value is 100 milliseconds and the maximum is 20 seconds.",
1398 return EFI_INVALID_PARAMETER
;
1401 Attempt
->SessionConfigData
.ConnectTimeout
= IfrNvData
->ISCSIConnectTimeout
[AttemptIndex
- 1];
1402 if (Attempt
->SessionConfigData
.ConnectTimeout
== 0) {
1403 Attempt
->SessionConfigData
.ConnectTimeout
= CONNECT_DEFAULT_TIMEOUT
;
1406 } else if ((OffSet
>= ATTEMPT_INITIATOR_VIA_DHCP_VAR_OFFSET
) && (OffSet
< ATTEMPT_TARGET_VIA_DHCP_VAR_OFFSET
)) {
1407 AttemptIndex
= (UINT8
) ((OffSet
- ATTEMPT_INITIATOR_VIA_DHCP_VAR_OFFSET
) + 1);
1408 Attempt
= IScsiConfigGetAttemptByConfigIndex (AttemptIndex
);
1409 if (Attempt
== NULL
) {
1410 return EFI_INVALID_PARAMETER
;
1412 Attempt
->SessionConfigData
.InitiatorInfoFromDhcp
= IfrNvData
->ISCSIInitiatorInfoViaDHCP
[AttemptIndex
- 1];
1414 } else if ((OffSet
>= ATTEMPT_TARGET_VIA_DHCP_VAR_OFFSET
) && (OffSet
< ATTEMPT_TARGET_TCP_PORT_VAR_OFFSET
)) {
1415 AttemptIndex
= (UINT8
) ((OffSet
- ATTEMPT_TARGET_VIA_DHCP_VAR_OFFSET
) + 1);
1416 Attempt
= IScsiConfigGetAttemptByConfigIndex (AttemptIndex
);
1417 if (Attempt
== NULL
) {
1418 return EFI_INVALID_PARAMETER
;
1421 if ((Attempt
->SessionConfigData
.IpMode
< IP_MODE_AUTOCONFIG
) && (Attempt
->SessionConfigData
.InitiatorInfoFromDhcp
)) {
1422 Attempt
->SessionConfigData
.TargetInfoFromDhcp
= IfrNvData
->ISCSITargetInfoViaDHCP
[AttemptIndex
- 1];
1425 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1427 L
"Invalid Configuration, Check value of IpMode or Enable DHCP!",
1430 return EFI_INVALID_PARAMETER
;
1433 } else if ((OffSet
>= ATTEMPT_TARGET_TCP_PORT_VAR_OFFSET
) && (OffSet
< ATTEMPT_AUTHENTICATION_METHOD_VAR_OFFSET
)) {
1434 AttemptIndex
= (UINT8
) ((OffSet
- ATTEMPT_TARGET_TCP_PORT_VAR_OFFSET
) / 2 + 1);
1435 Attempt
= IScsiConfigGetAttemptByConfigIndex (AttemptIndex
);
1436 if (Attempt
== NULL
) {
1437 return EFI_INVALID_PARAMETER
;
1439 if ((Attempt
->SessionConfigData
.IpMode
< IP_MODE_AUTOCONFIG
) && (!Attempt
->SessionConfigData
.TargetInfoFromDhcp
)) {
1440 Attempt
->SessionConfigData
.TargetPort
= IfrNvData
->ISCSITargetTcpPort
[AttemptIndex
- 1];
1441 if (Attempt
->SessionConfigData
.TargetPort
== 0) {
1442 Attempt
->SessionConfigData
.TargetPort
= ISCSI_WELL_KNOWN_PORT
;
1446 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1448 L
"Invalid Configuration, Check value of IpMode or Target Via DHCP!",
1451 return EFI_INVALID_PARAMETER
;
1454 } else if ((OffSet
>= ATTEMPT_AUTHENTICATION_METHOD_VAR_OFFSET
) && (OffSet
< ATTEMPT_CHARTYPE_VAR_OFFSET
)) {
1455 AttemptIndex
= (UINT8
) ((OffSet
- ATTEMPT_AUTHENTICATION_METHOD_VAR_OFFSET
) + 1);
1456 Attempt
= IScsiConfigGetAttemptByConfigIndex (AttemptIndex
);
1457 if (Attempt
== NULL
) {
1458 return EFI_INVALID_PARAMETER
;
1461 Attempt
->AuthenticationType
= IfrNvData
->ISCSIAuthenticationMethod
[AttemptIndex
- 1];
1463 } else if ((OffSet
>= ATTEMPT_CHARTYPE_VAR_OFFSET
) && (OffSet
< ATTEMPT_ISID_VAR_OFFSET
)) {
1464 AttemptIndex
= (UINT8
) ((OffSet
- ATTEMPT_CHARTYPE_VAR_OFFSET
) + 1);
1465 Attempt
= IScsiConfigGetAttemptByConfigIndex (AttemptIndex
);
1466 if (Attempt
== NULL
) {
1467 return EFI_INVALID_PARAMETER
;
1469 if (Attempt
->AuthenticationType
== ISCSI_AUTH_TYPE_CHAP
) {
1470 Attempt
->AuthConfigData
.CHAP
.CHAPType
= IfrNvData
->ISCSIChapType
[AttemptIndex
- 1];
1473 } else if (OffSet
>= ATTEMPT_ISID_VAR_OFFSET
) {
1474 Index
= (UINT8
) ((OffSet
- ATTEMPT_ISID_VAR_OFFSET
) / sizeof (KEYWORD_STR
));
1475 AttemptIndex
= Index
+ 1;
1476 Attempt
= IScsiConfigGetAttemptByConfigIndex (AttemptIndex
);
1477 if (Attempt
== NULL
) {
1478 return EFI_INVALID_PARAMETER
;
1481 OffSet
= OffSet
- Index
* sizeof (KEYWORD_STR
);
1483 if ((OffSet
>= ATTEMPT_ISID_VAR_OFFSET
) && (OffSet
< ATTEMPT_INITIATOR_IP_ADDRESS_VAR_OFFSET
)) {
1484 IScsiParseIsIdFromString (IfrNvData
->Keyword
[Index
].ISCSIIsId
, Attempt
->SessionConfigData
.IsId
);
1486 } else if ((OffSet
>= ATTEMPT_INITIATOR_IP_ADDRESS_VAR_OFFSET
) && (OffSet
< ATTEMPT_INITIATOR_NET_MASK_VAR_OFFSET
)) {
1487 if ((Attempt
->SessionConfigData
.IpMode
== IP_MODE_IP4
) && (!Attempt
->SessionConfigData
.InitiatorInfoFromDhcp
)) {
1491 Status
= NetLibStrToIp4 (IfrNvData
->Keyword
[Index
].ISCSIInitiatorIpAddress
, &HostIp
.v4
);
1492 if (EFI_ERROR (Status
) || ((Attempt
->SessionConfigData
.SubnetMask
.Addr
[0] != 0) &&
1493 !NetIp4IsUnicast (NTOHL (HostIp
.Addr
[0]), NTOHL(*(UINT32
*)Attempt
->SessionConfigData
.SubnetMask
.Addr
)))) {
1495 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1497 L
"Invalid IP address!",
1500 return EFI_INVALID_PARAMETER
;
1502 CopyMem (&Attempt
->SessionConfigData
.LocalIp
, &HostIp
.v4
, sizeof (HostIp
.v4
));
1506 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1508 L
"Invalid Configuration, Check value of IpMode or Enable DHCP!",
1511 return EFI_INVALID_PARAMETER
;
1514 } else if ((OffSet
>= ATTEMPT_INITIATOR_NET_MASK_VAR_OFFSET
) && (OffSet
< ATTEMPT_INITIATOR_GATE_WAY_VAR_OFFSET
)) {
1515 if ((Attempt
->SessionConfigData
.IpMode
== IP_MODE_IP4
) && (!Attempt
->SessionConfigData
.InitiatorInfoFromDhcp
)) {
1516 Status
= NetLibStrToIp4 (IfrNvData
->Keyword
[Index
].ISCSIInitiatorNetmask
, &SubnetMask
.v4
);
1517 if (EFI_ERROR (Status
) || ((SubnetMask
.Addr
[0] != 0) && (IScsiGetSubnetMaskPrefixLength (&SubnetMask
.v4
) == 0))) {
1519 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1521 L
"Invalid Subnet Mask!",
1524 return EFI_INVALID_PARAMETER
;
1526 CopyMem (&Attempt
->SessionConfigData
.SubnetMask
, &SubnetMask
.v4
, sizeof (SubnetMask
.v4
));
1530 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1532 L
"Invalid Configuration, Check value of IpMode or Enable DHCP!",
1535 return EFI_INVALID_PARAMETER
;
1538 } else if ((OffSet
>= ATTEMPT_INITIATOR_GATE_WAY_VAR_OFFSET
) && (OffSet
< ATTEMPT_TARGET_NAME_VAR_OFFSET
)) {
1539 if ((Attempt
->SessionConfigData
.IpMode
== IP_MODE_IP4
) && (!Attempt
->SessionConfigData
.InitiatorInfoFromDhcp
)) {
1540 Status
= NetLibStrToIp4 (IfrNvData
->Keyword
[Index
].ISCSIInitiatorGateway
, &Gateway
.v4
);
1541 if (EFI_ERROR (Status
) ||
1542 ((Gateway
.Addr
[0] != 0) && (Attempt
->SessionConfigData
.SubnetMask
.Addr
[0] != 0) &&
1543 !NetIp4IsUnicast (NTOHL (Gateway
.Addr
[0]), NTOHL(*(UINT32
*)Attempt
->SessionConfigData
.SubnetMask
.Addr
)))) {
1545 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1547 L
"Invalid Gateway!",
1550 return EFI_INVALID_PARAMETER
;
1552 CopyMem (&Attempt
->SessionConfigData
.Gateway
, &Gateway
.v4
, sizeof (Gateway
.v4
));
1556 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1558 L
"Invalid Configuration, Check value of IpMode or Enable DHCP!",
1561 return EFI_INVALID_PARAMETER
;
1564 } else if ((OffSet
>= ATTEMPT_TARGET_NAME_VAR_OFFSET
) && (OffSet
< ATTEMPT_TARGET_IP_ADDRESS_VAR_OFFSET
)) {
1565 if ((Attempt
->SessionConfigData
.IpMode
< IP_MODE_AUTOCONFIG
) && (!Attempt
->SessionConfigData
.TargetInfoFromDhcp
)) {
1566 UnicodeStrToAsciiStrS (IfrNvData
->Keyword
[Index
].ISCSITargetName
, IScsiName
, ISCSI_NAME_MAX_SIZE
);
1567 Status
= IScsiNormalizeName (IScsiName
, AsciiStrLen (IScsiName
));
1568 if (EFI_ERROR (Status
)) {
1570 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1572 L
"Invalid iSCSI Name!",
1576 AsciiStrCpyS (Attempt
->SessionConfigData
.TargetName
, ISCSI_NAME_MAX_SIZE
, IScsiName
);
1578 if (Attempt
->SessionConfigData
.Enabled
!= ISCSI_DISABLED
) {
1579 if (Attempt
->SessionConfigData
.TargetName
[0] == L
'\0') {
1581 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1583 L
"iSCSI target name is NULL!",
1586 return EFI_INVALID_PARAMETER
;
1591 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1593 L
"Invalid Configuration, Check value of IpMode or Target Via DHCP!",
1596 return EFI_INVALID_PARAMETER
;
1599 } else if ((OffSet
>= ATTEMPT_TARGET_IP_ADDRESS_VAR_OFFSET
) && (OffSet
< ATTEMPT_LUN_VAR_OFFSET
)) {
1600 if ((Attempt
->SessionConfigData
.IpMode
< IP_MODE_AUTOCONFIG
) && (!Attempt
->SessionConfigData
.TargetInfoFromDhcp
)) {
1601 UnicodeStrToAsciiStrS (IfrNvData
->Keyword
[Index
].ISCSITargetIpAddress
, IpString
, sizeof (IpString
));
1602 Status
= IScsiAsciiStrToIp (IpString
, Attempt
->SessionConfigData
.IpMode
, &HostIp
);
1603 if (EFI_ERROR (Status
) || !IpIsUnicast (&HostIp
, Attempt
->SessionConfigData
.IpMode
)) {
1604 Attempt
->SessionConfigData
.DnsMode
= TRUE
;
1605 ZeroMem (&Attempt
->SessionConfigData
.TargetIp
, sizeof (Attempt
->SessionConfigData
.TargetIp
));
1606 UnicodeStrToAsciiStrS (IfrNvData
->Keyword
[Index
].ISCSITargetIpAddress
, Attempt
->SessionConfigData
.TargetUrl
, ISCSI_NAME_MAX_SIZE
);
1608 Attempt
->SessionConfigData
.DnsMode
= FALSE
;
1609 CopyMem (&Attempt
->SessionConfigData
.TargetIp
, &HostIp
, sizeof (HostIp
));
1613 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1615 L
"Invalid Configuration, Check value of IpMode or Target Via DHCP!",
1618 return EFI_INVALID_PARAMETER
;
1621 } else if ((OffSet
>= ATTEMPT_LUN_VAR_OFFSET
) && (OffSet
< ATTEMPT_CHAR_USER_NAME_VAR_OFFSET
)) {
1622 if ((Attempt
->SessionConfigData
.IpMode
< IP_MODE_AUTOCONFIG
) && (Attempt
->SessionConfigData
.TargetInfoFromDhcp
== 0)) {
1626 UnicodeStrToAsciiStrS (IfrNvData
->Keyword
[Index
].ISCSILun
, LunString
, ISCSI_LUN_STR_MAX_LEN
);
1627 Status
= IScsiAsciiStrToLun (LunString
, (UINT8
*) &Lun
);
1628 if (EFI_ERROR (Status
)) {
1630 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1632 L
"Invalid LUN string, Examples are: 4752-3A4F-6b7e-2F99, 6734-9-156f-127, 4186-9!",
1636 CopyMem (&Attempt
->SessionConfigData
.BootLun
, &Lun
, sizeof (Lun
));
1640 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1642 L
"Invalid Configuration, Check value of IpMode or Target Via DHCP!",
1645 return EFI_INVALID_PARAMETER
;
1648 } else if ((OffSet
>= ATTEMPT_CHAR_USER_NAME_VAR_OFFSET
) && (OffSet
< ATTEMPT_CHAR_SECRET_VAR_OFFSET
)) {
1649 if (Attempt
->AuthenticationType
== ISCSI_AUTH_TYPE_CHAP
) {
1650 UnicodeStrToAsciiStrS (
1651 IfrNvData
->Keyword
[Index
].ISCSIChapUsername
,
1652 Attempt
->AuthConfigData
.CHAP
.CHAPName
,
1653 ISCSI_CHAP_NAME_STORAGE
1656 if (Attempt
->SessionConfigData
.Enabled
!= ISCSI_DISABLED
) {
1657 if (IfrNvData
->Keyword
[Index
].ISCSIChapUsername
[0] == L
'\0') {
1659 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1661 L
"CHAP Name is invalid!",
1664 return EFI_INVALID_PARAMETER
;
1669 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1671 L
"Invalid Configuration, Check value of AuthenticationType!",
1674 return EFI_INVALID_PARAMETER
;
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
);
1680 UnicodeStrToAsciiStrS (
1681 IfrNvData
->Keyword
[Index
].ISCSIChapSecret
,
1682 Attempt
->AuthConfigData
.CHAP
.CHAPSecret
,
1683 ISCSI_CHAP_SECRET_STORAGE
1686 if (Attempt
->SessionConfigData
.Enabled
!= ISCSI_DISABLED
) {
1687 if ((ChapSecretLen
< ISCSI_CHAP_SECRET_MIN_LEN
) || (ChapSecretLen
> ISCSI_CHAP_SECRET_MAX_LEN
)) {
1689 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1691 L
"The Chap Secret minimum length is 12 bytes and the maximum length is 16 bytes.",
1694 return EFI_INVALID_PARAMETER
;
1699 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1701 L
"Invalid Configuration, Check value of AuthenticationType!",
1704 return EFI_INVALID_PARAMETER
;
1707 } else if ((OffSet
>= ATTEMPT_CHAR_REVERSE_USER_NAME_VAR_OFFSET
) && (OffSet
< ATTEMPT_CHAR_REVERSE_SECRET_VAR_OFFSET
)) {
1708 if (Attempt
->AuthConfigData
.CHAP
.CHAPType
== ISCSI_CHAP_MUTUAL
) {
1709 UnicodeStrToAsciiStrS (
1710 IfrNvData
->Keyword
[Index
].ISCSIReverseChapUsername
,
1711 Attempt
->AuthConfigData
.CHAP
.ReverseCHAPName
,
1712 ISCSI_CHAP_NAME_STORAGE
1714 if (Attempt
->SessionConfigData
.Enabled
!= ISCSI_DISABLED
) {
1715 if (IfrNvData
->Keyword
[Index
].ISCSIReverseChapUsername
[0] == L
'\0') {
1717 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1719 L
"Reverse CHAP Name is invalid!",
1722 return EFI_INVALID_PARAMETER
;
1727 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1729 L
"Invalid Configuration, Check value of AuthenticationType or Chap Type!",
1732 return EFI_INVALID_PARAMETER
;
1735 } else if (OffSet
>= ATTEMPT_CHAR_REVERSE_SECRET_VAR_OFFSET
) {
1736 if (Attempt
->AuthConfigData
.CHAP
.CHAPType
== ISCSI_CHAP_MUTUAL
) {
1737 ReverseChapSecretLen
= (UINT8
)StrLen (IfrNvData
->Keyword
[Index
].ISCSIReverseChapSecret
);
1738 UnicodeStrToAsciiStrS (
1739 IfrNvData
->Keyword
[Index
].ISCSIReverseChapSecret
,
1740 Attempt
->AuthConfigData
.CHAP
.ReverseCHAPSecret
,
1741 ISCSI_CHAP_SECRET_STORAGE
1744 if (Attempt
->SessionConfigData
.Enabled
!= ISCSI_DISABLED
) {
1745 if ((ReverseChapSecretLen
< ISCSI_CHAP_SECRET_MIN_LEN
) || (ReverseChapSecretLen
> ISCSI_CHAP_SECRET_MAX_LEN
)) {
1747 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1749 L
"The Reverse CHAP Secret minimum length is 12 bytes and the maximum length is 16 bytes.",
1752 return EFI_INVALID_PARAMETER
;
1757 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1759 L
"Invalid Configuration, Check value of AuthenticationType or Chap Type!",
1762 return EFI_INVALID_PARAMETER
;
1770 // Record the user configuration information in NVR.
1772 ASSERT (Attempt
!= NULL
);
1773 UnicodeSPrint (mPrivate
->PortString
, (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
, L
"Attempt %d", Attempt
->AttemptConfigIndex
);
1774 return gRT
->SetVariable (
1775 mPrivate
->PortString
,
1776 &gEfiIScsiInitiatorNameProtocolGuid
,
1777 ISCSI_CONFIG_VAR_ATTR
,
1778 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
1785 Create Hii Extend Label OpCode as the start opcode and end opcode. It is
1788 @param[in] StartLabelNumber The number of start label.
1789 @param[out] StartOpCodeHandle Points to the start opcode handle.
1790 @param[out] StartLabel Points to the created start opcode.
1791 @param[out] EndOpCodeHandle Points to the end opcode handle.
1792 @param[out] EndLabel Points to the created end opcode.
1794 @retval EFI_OUT_OF_RESOURCES Do not have sufficient resource to finish this
1796 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1797 @retval EFI_SUCCESS The operation is completed successfully.
1802 IN UINT16 StartLabelNumber
,
1803 OUT VOID
**StartOpCodeHandle
,
1804 OUT EFI_IFR_GUID_LABEL
**StartLabel
,
1805 OUT VOID
**EndOpCodeHandle
,
1806 OUT EFI_IFR_GUID_LABEL
**EndLabel
1810 EFI_IFR_GUID_LABEL
*InternalStartLabel
;
1811 EFI_IFR_GUID_LABEL
*InternalEndLabel
;
1813 if (StartOpCodeHandle
== NULL
|| StartLabel
== NULL
|| EndOpCodeHandle
== NULL
|| EndLabel
== NULL
) {
1814 return EFI_INVALID_PARAMETER
;
1817 *StartOpCodeHandle
= NULL
;
1818 *EndOpCodeHandle
= NULL
;
1819 Status
= EFI_OUT_OF_RESOURCES
;
1822 // Initialize the container for dynamic opcodes.
1824 *StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1825 if (*StartOpCodeHandle
== NULL
) {
1829 *EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
1830 if (*EndOpCodeHandle
== NULL
) {
1835 // Create Hii Extend Label OpCode as the start opcode.
1837 InternalStartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
1841 sizeof (EFI_IFR_GUID_LABEL
)
1843 if (InternalStartLabel
== NULL
) {
1847 InternalStartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1848 InternalStartLabel
->Number
= StartLabelNumber
;
1851 // Create Hii Extend Label OpCode as the end opcode.
1853 InternalEndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
1857 sizeof (EFI_IFR_GUID_LABEL
)
1859 if (InternalEndLabel
== NULL
) {
1863 InternalEndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1864 InternalEndLabel
->Number
= LABEL_END
;
1866 *StartLabel
= InternalStartLabel
;
1867 *EndLabel
= InternalEndLabel
;
1873 if (*StartOpCodeHandle
!= NULL
) {
1874 HiiFreeOpCodeHandle (*StartOpCodeHandle
);
1877 if (*EndOpCodeHandle
!= NULL
) {
1878 HiiFreeOpCodeHandle (*EndOpCodeHandle
);
1884 Update the MAIN form to display the configured attempts.
1888 IScsiConfigUpdateAttempt (
1893 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
1894 VOID
*StartOpCodeHandle
;
1895 EFI_IFR_GUID_LABEL
*StartLabel
;
1896 VOID
*EndOpCodeHandle
;
1897 EFI_IFR_GUID_LABEL
*EndLabel
;
1900 Status
= IScsiCreateOpCode (
1901 ATTEMPT_ENTRY_LABEL
,
1907 if (EFI_ERROR (Status
)) {
1911 NET_LIST_FOR_EACH (Entry
, &mPrivate
->AttemptConfigs
) {
1912 AttemptConfigData
= NET_LIST_USER_STRUCT (Entry
, ISCSI_ATTEMPT_CONFIG_NVDATA
, Link
);
1913 if (AttemptConfigData
->Actived
== ISCSI_ACTIVE_ENABLED
) {
1915 // Update Attempt Help Info.
1917 UnicodeSPrint (mPrivate
->PortString
, (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
, L
"Attempt %d", (UINTN
) AttemptConfigData
->AttemptConfigIndex
);
1918 AttemptConfigData
->AttemptTitleToken
= HiiSetString (
1919 mCallbackInfo
->RegisteredHandle
,
1921 mPrivate
->PortString
,
1924 if (AttemptConfigData
->AttemptTitleToken
== 0) {
1928 HiiCreateGotoOpCode (
1929 StartOpCodeHandle
, // Container for dynamic created opcodes
1930 FORMID_ATTEMPT_FORM
, // Form ID
1931 AttemptConfigData
->AttemptTitleToken
, // Prompt text
1932 AttemptConfigData
->AttemptTitleHelpToken
, // Help text
1933 EFI_IFR_FLAG_CALLBACK
, // Question flag
1934 (UINT16
) (KEY_ATTEMPT_ENTRY_BASE
+ AttemptConfigData
->AttemptConfigIndex
) // Question ID
1940 mCallbackInfo
->RegisteredHandle
, // HII handle
1941 &gIScsiConfigGuid
, // Formset GUID
1942 FORMID_MAIN_FORM
, // Form ID
1943 StartOpCodeHandle
, // Label for where to insert opcodes
1944 EndOpCodeHandle
// Replace data
1947 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1948 HiiFreeOpCodeHandle (EndOpCodeHandle
);
1952 Callback function when user presses "Add an Attempt".
1954 @retval EFI_OUT_OF_RESOURCES Does not have sufficient resources to finish this
1956 @retval EFI_SUCCESS The operation is completed successfully.
1960 IScsiConfigAddAttempt (
1965 ISCSI_NIC_INFO
*NicInfo
;
1966 EFI_STRING_ID PortTitleToken
;
1967 EFI_STRING_ID PortTitleHelpToken
;
1968 CHAR16 MacString
[ISCSI_MAX_MAC_STRING_LEN
];
1970 VOID
*StartOpCodeHandle
;
1971 EFI_IFR_GUID_LABEL
*StartLabel
;
1972 VOID
*EndOpCodeHandle
;
1973 EFI_IFR_GUID_LABEL
*EndLabel
;
1975 Status
= IScsiCreateOpCode (
1982 if (EFI_ERROR (Status
)) {
1987 // Ask user to select a MAC for this attempt.
1989 NET_LIST_FOR_EACH (Entry
, &mPrivate
->NicInfoList
) {
1990 NicInfo
= NET_LIST_USER_STRUCT (Entry
, ISCSI_NIC_INFO
, Link
);
1992 &NicInfo
->PermanentAddress
,
1993 NicInfo
->HwAddressSize
,
1998 UnicodeSPrint (mPrivate
->PortString
, (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
, L
"MAC %s", MacString
);
1999 PortTitleToken
= HiiSetString (
2000 mCallbackInfo
->RegisteredHandle
,
2002 mPrivate
->PortString
,
2005 if (PortTitleToken
== 0) {
2006 Status
= EFI_INVALID_PARAMETER
;
2011 mPrivate
->PortString
,
2012 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2013 L
"PFA: Bus %d | Dev %d | Func %d",
2015 NicInfo
->DeviceNumber
,
2016 NicInfo
->FunctionNumber
2018 PortTitleHelpToken
= HiiSetString (mCallbackInfo
->RegisteredHandle
, 0, mPrivate
->PortString
, NULL
);
2019 if (PortTitleHelpToken
== 0) {
2020 Status
= EFI_INVALID_PARAMETER
;
2024 HiiCreateGotoOpCode (
2025 StartOpCodeHandle
, // Container for dynamic created opcodes
2026 FORMID_ATTEMPT_FORM
,
2029 EFI_IFR_FLAG_CALLBACK
, // Question flag
2030 (UINT16
) (KEY_MAC_ENTRY_BASE
+ NicInfo
->NicIndex
)
2034 Status
= HiiUpdateForm (
2035 mCallbackInfo
->RegisteredHandle
, // HII handle
2036 &gIScsiConfigGuid
, // Formset GUID
2037 FORMID_MAC_FORM
, // Form ID
2038 StartOpCodeHandle
, // Label for where to insert opcodes
2039 EndOpCodeHandle
// Replace data
2043 HiiFreeOpCodeHandle (StartOpCodeHandle
);
2044 HiiFreeOpCodeHandle (EndOpCodeHandle
);
2050 Add the attempts by keyword 'iSCSIAddAttempts', you can use this keyword with
2051 value 'attempt:1 attempt:2' etc to add one or more attempts once. This is different
2052 with IScsiConfigAddAttempt function which is used to add attempt by UI configuration.
2054 @param[in] AttemptList The new attempt List will be added.
2056 @retval EFI_SUCCESS The operation to add attempt list successfully.
2057 @retval EFI_INVALID_PARAMETER Any parameter is invalid.
2058 @retval EFI_NOT_FOUND Cannot find the corresponding variable.
2059 @retval EFI_OUT_OF_RESOURCES Fail to finish the operation due to lack of
2064 IScsiConfigAddAttemptsByKeywords (
2065 IN UINT8
*AttemptList
2072 UINT8
*AttemptConfigOrder
;
2073 UINTN AttemptConfigOrderSize
;
2074 UINT8
*AttemptConfigOrderTmp
;
2075 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
2076 ISCSI_NIC_INFO
*NicInfo
;
2077 CHAR16 MacString
[ISCSI_MAX_MAC_STRING_LEN
];
2078 CHAR16 IScsiMode
[64];
2082 Nic
= mPrivate
->CurrentNic
;
2083 NicInfo
= IScsiGetNicInfoByIndex (Nic
);
2084 if (NicInfo
== NULL
) {
2085 return EFI_NOT_FOUND
;
2089 // The MAC info will be recorded in Config Data.
2092 &NicInfo
->PermanentAddress
,
2093 NicInfo
->HwAddressSize
,
2098 for (Index
= 0; Index
< PcdGet8 (PcdMaxIScsiAttemptNumber
); Index
++) {
2099 if (AttemptList
[Index
] == 0) {
2106 Number
= AttemptList
[Index
];
2109 mPrivate
->PortString
,
2110 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2116 mPrivate
->PortString
,
2117 &gEfiIScsiInitiatorNameProtocolGuid
,
2118 (VOID
**)&AttemptConfigData
,
2121 if (AttemptConfigData
== NULL
|| AttemptConfigData
->Actived
== ISCSI_ACTIVE_ENABLED
) {
2122 return EFI_INVALID_PARAMETER
;
2125 AttemptConfigData
->Actived
= ISCSI_ACTIVE_ENABLED
;
2126 AttemptConfigData
->NicIndex
= NicInfo
->NicIndex
;
2127 UnicodeStrToAsciiStrS (MacString
, AttemptConfigData
->MacString
, ISCSI_MAX_MAC_STRING_LEN
);
2130 // Generate OUI-format ISID based on MAC address.
2132 CopyMem (AttemptConfigData
->SessionConfigData
.IsId
, &NicInfo
->PermanentAddress
, 6);
2133 AttemptConfigData
->SessionConfigData
.IsId
[0] =
2134 (UINT8
) (AttemptConfigData
->SessionConfigData
.IsId
[0] & 0x3F);
2137 // Configure the iSCSI Mode and IpMode to default.
2138 // Add Attempt Help Info.
2140 UnicodeSPrint (IScsiMode
, 64, L
"Disabled");
2141 UnicodeSPrint (IpMode
, 64, L
"IP4");
2143 mPrivate
->PortString
,
2144 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2145 L
"MAC: %s, PFA: Bus %d | Dev %d | Func %d, iSCSI mode: %s, IP version: %s",
2148 NicInfo
->DeviceNumber
,
2149 NicInfo
->FunctionNumber
,
2154 AttemptConfigData
->AttemptTitleHelpToken
= HiiSetString (
2155 mCallbackInfo
->RegisteredHandle
,
2157 mPrivate
->PortString
,
2160 if (AttemptConfigData
->AttemptTitleHelpToken
== 0) {
2161 return EFI_OUT_OF_RESOURCES
;
2165 // Get current Attempt order and number.
2167 AttemptConfigOrder
= IScsiGetVariableAndSize (
2170 &AttemptConfigOrderSize
2172 TotalNumber
= AttemptConfigOrderSize
/ sizeof (UINT8
);
2176 // Append the new created attempt order to the end.
2178 AttemptConfigOrderTmp
= AllocateZeroPool (TotalNumber
* sizeof (UINT8
));
2179 if (AttemptConfigOrderTmp
== NULL
) {
2180 if (AttemptConfigOrder
!= NULL
) {
2181 FreePool (AttemptConfigOrder
);
2183 return EFI_OUT_OF_RESOURCES
;
2185 if (AttemptConfigOrder
!= NULL
) {
2186 CopyMem (AttemptConfigOrderTmp
, AttemptConfigOrder
, AttemptConfigOrderSize
);
2187 FreePool (AttemptConfigOrder
);
2190 AttemptConfigOrderTmp
[TotalNumber
- 1] = Number
;
2191 AttemptConfigOrder
= AttemptConfigOrderTmp
;
2192 AttemptConfigOrderSize
= TotalNumber
* sizeof (UINT8
);
2194 Status
= gRT
->SetVariable (
2197 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
2198 AttemptConfigOrderSize
,
2201 FreePool (AttemptConfigOrder
);
2202 if (EFI_ERROR (Status
)) {
2207 // Record the attempt in global link list.
2209 InsertTailList (&mPrivate
->AttemptConfigs
, &AttemptConfigData
->Link
);
2210 mPrivate
->AttemptCount
++;
2211 UnicodeSPrint (mPrivate
->PortString
, (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
, L
"Attempt %d", AttemptConfigData
->AttemptConfigIndex
);
2213 mPrivate
->PortString
,
2214 &gEfiIScsiInitiatorNameProtocolGuid
,
2215 ISCSI_CONFIG_VAR_ATTR
,
2216 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
2226 Callback function when user presses "Commit Changes and Exit" in Delete Attempts or Delete Attempts by Keyword.
2228 @param[in] IfrNvData The IFR NV data.
2230 @retval EFI_NOT_FOUND Cannot find the corresponding variable.
2231 @retval EFI_SUCCESS The operation is completed successfully.
2232 @retval EFI_ABOTRED This operation is aborted cause of error
2234 @retval EFI_OUT_OF_RESOURCES Fail to finish the operation due to lack of
2239 IScsiConfigDeleteAttempts (
2240 IN ISCSI_CONFIG_IFR_NVDATA
*IfrNvData
2246 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
2247 UINT8
*AttemptConfigOrder
;
2248 UINTN AttemptConfigOrderSize
;
2249 UINT8
*AttemptNewOrder
;
2250 UINT8 AttemptConfigIndex
;
2255 LIST_ENTRY
*NextEntry
;
2256 ISCSI_SESSION_CONFIG_NVDATA
*ConfigData
;
2260 AttemptConfigOrder
= IScsiGetVariableAndSize (
2263 &AttemptConfigOrderSize
2265 if ((AttemptConfigOrder
== NULL
) || (AttemptConfigOrderSize
== 0)) {
2266 return EFI_NOT_FOUND
;
2269 AttemptNewOrder
= AllocateZeroPool (AttemptConfigOrderSize
);
2270 if (AttemptNewOrder
== NULL
) {
2271 Status
= EFI_OUT_OF_RESOURCES
;
2275 Total
= AttemptConfigOrderSize
/ sizeof (UINT8
);
2278 NET_LIST_FOR_EACH_SAFE (Entry
, NextEntry
, &mPrivate
->AttemptConfigs
) {
2279 if (IfrNvData
->DeleteAttemptList
[Index
] == 0) {
2285 // Delete the attempt.
2288 AttemptConfigData
= NET_LIST_USER_STRUCT (Entry
, ISCSI_ATTEMPT_CONFIG_NVDATA
, Link
);
2291 // Remove this attempt from UI configured attempt list.
2293 RemoveEntryList (&AttemptConfigData
->Link
);
2294 mPrivate
->AttemptCount
--;
2296 if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED_FOR_MPIO
) {
2297 if (mPrivate
->MpioCount
< 1) {
2298 Status
= EFI_ABORTED
;
2303 // No more attempt is enabled for MPIO. Transit the iSCSI mode to single path.
2305 if (--mPrivate
->MpioCount
== 0) {
2306 mPrivate
->EnableMpio
= FALSE
;
2308 } else if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED
) {
2309 if (mPrivate
->SinglePathCount
< 1) {
2310 Status
= EFI_ABORTED
;
2314 mPrivate
->SinglePathCount
--;
2317 AttemptConfigIndex
= AttemptConfigData
->AttemptConfigIndex
;
2318 FreePool (AttemptConfigData
);
2321 // Create a new Attempt
2323 AttemptConfigData
= AllocateZeroPool (sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
));
2324 if (AttemptConfigData
== NULL
) {
2325 return EFI_OUT_OF_RESOURCES
;
2327 ConfigData
= &AttemptConfigData
->SessionConfigData
;
2328 ConfigData
->TargetPort
= ISCSI_WELL_KNOWN_PORT
;
2329 ConfigData
->ConnectTimeout
= CONNECT_DEFAULT_TIMEOUT
;
2330 ConfigData
->ConnectRetryCount
= CONNECT_MIN_RETRY
;
2332 AttemptConfigData
->AuthenticationType
= ISCSI_AUTH_TYPE_CHAP
;
2333 AttemptConfigData
->AuthConfigData
.CHAP
.CHAPType
= ISCSI_CHAP_UNI
;
2335 // Configure the Attempt index and set variable.
2337 AttemptConfigData
->AttemptConfigIndex
= AttemptConfigIndex
;
2340 // Set the attempt name to default.
2343 mPrivate
->PortString
,
2344 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2346 (UINTN
) AttemptConfigData
->AttemptConfigIndex
2348 UnicodeStrToAsciiStrS (mPrivate
->PortString
, AttemptConfigData
->AttemptName
, ATTEMPT_NAME_SIZE
);
2350 mPrivate
->PortString
,
2351 &gEfiIScsiInitiatorNameProtocolGuid
,
2352 ISCSI_CONFIG_VAR_ATTR
,
2353 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
2358 // Mark the attempt order in NVR to be deleted - 0.
2360 for (NewIndex
= 0; NewIndex
< Total
; NewIndex
++) {
2361 if (AttemptConfigOrder
[NewIndex
] == AttemptConfigData
->AttemptConfigIndex
) {
2362 AttemptConfigOrder
[NewIndex
] = 0;
2368 if (mCallbackInfo
->Current
== AttemptConfigData
) {
2369 mCallbackInfo
->Current
= NULL
;
2371 FreePool (AttemptConfigData
);
2374 // Check next Attempt.
2380 // Construct AttemptNewOrder.
2382 for (Index
= 0, NewIndex
= 0; Index
< Total
; Index
++) {
2383 if (AttemptConfigOrder
[Index
] != 0) {
2384 AttemptNewOrder
[NewIndex
] = AttemptConfigOrder
[Index
];
2389 Attribute
= EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
;
2392 // Update AttemptOrder in NVR.
2394 Status
= gRT
->SetVariable (
2398 NewTotal
* sizeof (UINT8
),
2403 if (AttemptConfigOrder
!= NULL
) {
2404 FreePool (AttemptConfigOrder
);
2407 if (AttemptNewOrder
!= NULL
) {
2408 FreePool (AttemptNewOrder
);
2416 Callback function when user presses "Delete Attempts".
2418 @param[in] IfrNvData The IFR nv data.
2420 @retval EFI_INVALID_PARAMETER Any parameter is invalid.
2421 @retval EFI_BUFFER_TOO_SMALL The buffer in UpdateData is too small.
2422 @retval EFI_SUCCESS The operation is completed successfully.
2426 IScsiConfigDisplayDeleteAttempts (
2427 IN ISCSI_CONFIG_IFR_NVDATA
*IfrNvData
2431 UINT8
*AttemptConfigOrder
;
2432 UINTN AttemptConfigOrderSize
;
2434 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
2436 VOID
*StartOpCodeHandle
;
2437 EFI_IFR_GUID_LABEL
*StartLabel
;
2438 VOID
*EndOpCodeHandle
;
2439 EFI_IFR_GUID_LABEL
*EndLabel
;
2442 Status
= IScsiCreateOpCode (
2449 if (EFI_ERROR (Status
)) {
2453 AttemptConfigOrder
= IScsiGetVariableAndSize (
2456 &AttemptConfigOrderSize
2458 if (AttemptConfigOrder
!= NULL
) {
2460 // Create the check box opcode to be deleted.
2464 NET_LIST_FOR_EACH (Entry
, &mPrivate
->AttemptConfigs
) {
2465 AttemptConfigData
= NET_LIST_USER_STRUCT (Entry
, ISCSI_ATTEMPT_CONFIG_NVDATA
, Link
);
2466 IfrNvData
->DeleteAttemptList
[Index
] = 0x00;
2468 HiiCreateCheckBoxOpCode(
2470 (EFI_QUESTION_ID
) (ATTEMPT_DEL_QUESTION_ID
+ Index
),
2471 CONFIGURATION_VARSTORE_ID
,
2472 (UINT16
) (ATTEMPT_DEL_VAR_OFFSET
+ Index
),
2473 AttemptConfigData
->AttemptTitleToken
,
2474 AttemptConfigData
->AttemptTitleHelpToken
,
2482 if (Index
== ISCSI_MAX_ATTEMPTS_NUM
) {
2487 FreePool (AttemptConfigOrder
);
2490 Status
= HiiUpdateForm (
2491 mCallbackInfo
->RegisteredHandle
, // HII handle
2492 &gIScsiConfigGuid
, // Formset GUID
2493 FORMID_DELETE_FORM
, // Form ID
2494 StartOpCodeHandle
, // Label for where to insert opcodes
2495 EndOpCodeHandle
// Replace data
2498 HiiFreeOpCodeHandle (StartOpCodeHandle
);
2499 HiiFreeOpCodeHandle (EndOpCodeHandle
);
2506 Callback function when user presses "Change Attempt Order".
2508 @retval EFI_INVALID_PARAMETER Any parameter is invalid.
2509 @retval EFI_OUT_OF_RESOURCES Does not have sufficient resources to finish this
2511 @retval EFI_SUCCESS The operation is completed successfully.
2515 IScsiConfigDisplayOrderAttempts (
2522 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
2523 VOID
*StartOpCodeHandle
;
2524 EFI_IFR_GUID_LABEL
*StartLabel
;
2525 VOID
*EndOpCodeHandle
;
2526 EFI_IFR_GUID_LABEL
*EndLabel
;
2527 VOID
*OptionsOpCodeHandle
;
2529 Status
= IScsiCreateOpCode (
2536 if (EFI_ERROR (Status
)) {
2539 ASSERT (StartOpCodeHandle
!= NULL
);
2541 OptionsOpCodeHandle
= NULL
;
2544 // If no attempt to be ordered, update the original form and exit.
2546 if (mPrivate
->AttemptCount
== 0) {
2551 // Create Option OpCode.
2553 OptionsOpCodeHandle
= HiiAllocateOpCodeHandle ();
2554 if (OptionsOpCodeHandle
== NULL
) {
2555 Status
= EFI_OUT_OF_RESOURCES
;
2561 NET_LIST_FOR_EACH (Entry
, &mPrivate
->AttemptConfigs
) {
2562 AttemptConfigData
= NET_LIST_USER_STRUCT (Entry
, ISCSI_ATTEMPT_CONFIG_NVDATA
, Link
);
2563 HiiCreateOneOfOptionOpCode (
2564 OptionsOpCodeHandle
,
2565 AttemptConfigData
->AttemptTitleToken
,
2567 EFI_IFR_NUMERIC_SIZE_1
,
2568 AttemptConfigData
->AttemptConfigIndex
2573 ASSERT (Index
== mPrivate
->AttemptCount
);
2575 HiiCreateOrderedListOpCode (
2576 StartOpCodeHandle
, // Container for dynamic created opcodes
2577 DYNAMIC_ORDERED_LIST_QUESTION_ID
, // Question ID
2578 CONFIGURATION_VARSTORE_ID
, // VarStore ID
2579 DYNAMIC_ORDERED_LIST_VAR_OFFSET
, // Offset in Buffer Storage
2580 STRING_TOKEN (STR_ORDER_ATTEMPT_ENTRY
), // Question prompt text
2581 STRING_TOKEN (STR_ORDER_ATTEMPT_ENTRY
), // Question help text
2583 EFI_IFR_UNIQUE_SET
, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET
2584 EFI_IFR_NUMERIC_SIZE_1
, // Data type of Question value
2585 ISCSI_MAX_ATTEMPTS_NUM
, // Maximum container
2586 OptionsOpCodeHandle
, // Option Opcode list
2587 NULL
// Default Opcode is NULL
2591 Status
= HiiUpdateForm (
2592 mCallbackInfo
->RegisteredHandle
, // HII handle
2593 &gIScsiConfigGuid
, // Formset GUID
2594 FORMID_ORDER_FORM
, // Form ID
2595 StartOpCodeHandle
, // Label for where to insert opcodes
2596 EndOpCodeHandle
// Replace data
2600 HiiFreeOpCodeHandle (StartOpCodeHandle
);
2601 HiiFreeOpCodeHandle (EndOpCodeHandle
);
2602 if (OptionsOpCodeHandle
!= NULL
) {
2603 HiiFreeOpCodeHandle (OptionsOpCodeHandle
);
2610 Callback function when user presses "Commit Changes and Exit" in Change Attempt Order or Change Attempt Order by Keyword.
2612 @param[in] IfrNvData The IFR nv data.
2614 @retval EFI_OUT_OF_RESOURCES Does not have sufficient resources to finish this
2616 @retval EFI_NOT_FOUND Cannot find the corresponding variable.
2617 @retval EFI_SUCCESS The operation is completed successfully.
2621 IScsiConfigOrderAttempts (
2622 IN ISCSI_CONFIG_IFR_NVDATA
*IfrNvData
2628 UINT8 AttemptConfigIndex
;
2629 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
2630 UINT8
*AttemptConfigOrder
;
2631 UINT8
*AttemptConfigOrderTmp
;
2632 UINTN AttemptConfigOrderSize
;
2634 AttemptConfigOrder
= IScsiGetVariableAndSize (
2637 &AttemptConfigOrderSize
2639 if (AttemptConfigOrder
== NULL
) {
2640 return EFI_NOT_FOUND
;
2643 AttemptConfigOrderTmp
= AllocateZeroPool (AttemptConfigOrderSize
);
2644 if (AttemptConfigOrderTmp
== NULL
) {
2645 Status
= EFI_OUT_OF_RESOURCES
;
2649 for (Index
= 0; Index
< ISCSI_MAX_ATTEMPTS_NUM
; Index
++) {
2651 // The real content ends with 0.
2653 if (IfrNvData
->DynamicOrderedList
[Index
] == 0) {
2657 AttemptConfigIndex
= IfrNvData
->DynamicOrderedList
[Index
];
2658 AttemptConfigData
= IScsiConfigGetAttemptByConfigIndex (AttemptConfigIndex
);
2659 if (AttemptConfigData
== NULL
) {
2660 Status
= EFI_NOT_FOUND
;
2665 // Reorder the Attempt List.
2667 RemoveEntryList (&AttemptConfigData
->Link
);
2668 InsertTailList (&mPrivate
->AttemptConfigs
, &AttemptConfigData
->Link
);
2670 AttemptConfigOrderTmp
[Index
] = AttemptConfigIndex
;
2673 // Mark it to be deleted - 0.
2675 for (Indexj
= 0; Indexj
< AttemptConfigOrderSize
/ sizeof (UINT8
); Indexj
++) {
2676 if (AttemptConfigOrder
[Indexj
] == AttemptConfigIndex
) {
2677 AttemptConfigOrder
[Indexj
] = 0;
2684 // Adjust the attempt order in NVR.
2686 for (; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
2687 for (Indexj
= 0; Indexj
< AttemptConfigOrderSize
/ sizeof (UINT8
); Indexj
++) {
2688 if (AttemptConfigOrder
[Indexj
] != 0) {
2689 AttemptConfigOrderTmp
[Index
] = AttemptConfigOrder
[Indexj
];
2690 AttemptConfigOrder
[Indexj
] = 0;
2696 Status
= gRT
->SetVariable (
2699 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
2700 AttemptConfigOrderSize
,
2701 AttemptConfigOrderTmp
2705 if (AttemptConfigOrderTmp
!= NULL
) {
2706 FreePool (AttemptConfigOrderTmp
);
2709 FreePool (AttemptConfigOrder
);
2715 Callback function when a user presses "Attempt *" or when a user selects a NIC to
2716 create the new attempt.
2718 @param[in] KeyValue A unique value which is sent to the original
2719 exporting driver so that it can identify the type
2721 @param[in] IfrNvData The IFR nv data.
2723 @retval EFI_OUT_OF_RESOURCES Does not have sufficient resources to finish this
2725 @retval EFI_NOT_FOUND Cannot find the corresponding variable.
2726 @retval EFI_UNSUPPORTED Can not create more attempts.
2727 @retval EFI_SUCCESS The operation is completed successfully.
2731 IScsiConfigProcessDefault (
2732 IN EFI_QUESTION_ID KeyValue
,
2733 IN ISCSI_CONFIG_IFR_NVDATA
*IfrNvData
2737 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
2738 UINT8 CurrentAttemptConfigIndex
;
2739 ISCSI_NIC_INFO
*NicInfo
;
2741 CHAR16 MacString
[ISCSI_MAX_MAC_STRING_LEN
];
2742 UINT8
*AttemptConfigOrder
;
2743 UINTN AttemptConfigOrderSize
;
2747 AttemptConfigData
= NULL
;
2749 // Is User creating a new attempt?
2753 if ((KeyValue
>= KEY_MAC_ENTRY_BASE
) &&
2754 (KeyValue
<= (UINT16
) (mPrivate
->MaxNic
+ KEY_MAC_ENTRY_BASE
))) {
2756 // User has pressed "Add an Attempt" and then selects a NIC.
2759 } else if ((KeyValue
>= KEY_ATTEMPT_ENTRY_BASE
) &&
2760 (KeyValue
< (ISCSI_MAX_ATTEMPTS_NUM
+ KEY_ATTEMPT_ENTRY_BASE
))) {
2763 // User has pressed "Attempt *".
2768 // Don't process anything.
2775 // Determine which NIC user has selected for the new created attempt.
2777 NicIndex
= (UINT8
) (KeyValue
- KEY_MAC_ENTRY_BASE
);
2778 NicInfo
= IScsiGetNicInfoByIndex (NicIndex
);
2779 if (NicInfo
== NULL
) {
2780 return EFI_NOT_FOUND
;
2784 // Create an attempt following the initialized attempt order.
2786 AttemptConfigOrder
= IScsiGetVariableAndSize (
2787 L
"InitialAttemptOrder",
2789 &AttemptConfigOrderSize
2792 if (AttemptConfigOrder
== NULL
) {
2793 return EFI_NOT_FOUND
;
2796 for (Index
= 0; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
2798 mPrivate
->PortString
,
2799 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2801 (UINTN
) AttemptConfigOrder
[Index
]
2804 mPrivate
->PortString
,
2805 &gEfiIScsiInitiatorNameProtocolGuid
,
2806 (VOID
**)&AttemptConfigData
,
2809 if (AttemptConfigData
== NULL
|| AttemptConfigData
->Actived
== ISCSI_ACTIVE_ENABLED
) {
2816 if (Index
> PcdGet8 (PcdMaxIScsiAttemptNumber
)) {
2818 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2820 L
"Can not create more attempts, Please configure the PcdMaxIScsiAttemptNumber if needed!",
2823 return EFI_UNSUPPORTED
;
2826 if (AttemptConfigOrder
!= NULL
) {
2827 FreePool (AttemptConfigOrder
);
2831 // Record the MAC info in Config Data.
2834 &NicInfo
->PermanentAddress
,
2835 NicInfo
->HwAddressSize
,
2840 ASSERT (AttemptConfigData
!= NULL
);
2841 UnicodeStrToAsciiStrS (MacString
, AttemptConfigData
->MacString
, sizeof (AttemptConfigData
->MacString
));
2842 AttemptConfigData
->NicIndex
= NicIndex
;
2843 AttemptConfigData
->Actived
= ISCSI_ACTIVE_ENABLED
;
2846 // Generate OUI-format ISID based on MAC address.
2848 CopyMem (AttemptConfigData
->SessionConfigData
.IsId
, &NicInfo
->PermanentAddress
, 6);
2849 AttemptConfigData
->SessionConfigData
.IsId
[0] =
2850 (UINT8
) (AttemptConfigData
->SessionConfigData
.IsId
[0] & 0x3F);
2853 // Add the help info for the new attempt.
2856 mPrivate
->PortString
,
2857 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2858 L
"MAC: %s, PFA: Bus %d | Dev %d | Func %d",
2861 NicInfo
->DeviceNumber
,
2862 NicInfo
->FunctionNumber
2865 AttemptConfigData
->AttemptTitleHelpToken
= HiiSetString (
2866 mCallbackInfo
->RegisteredHandle
,
2868 mPrivate
->PortString
,
2871 if (AttemptConfigData
->AttemptTitleHelpToken
== 0) {
2872 FreePool (AttemptConfigData
);
2873 return EFI_OUT_OF_RESOURCES
;
2878 // Determine which Attempt user has selected to configure.
2879 // Get the attempt configuration data.
2881 CurrentAttemptConfigIndex
= (UINT8
) (KeyValue
- KEY_ATTEMPT_ENTRY_BASE
);
2883 AttemptConfigData
= IScsiConfigGetAttemptByConfigIndex (CurrentAttemptConfigIndex
);
2884 if (AttemptConfigData
== NULL
) {
2885 DEBUG ((DEBUG_ERROR
, "Corresponding configuration data can not be retrieved!\n"));
2886 return EFI_NOT_FOUND
;
2891 // Clear the old IFR data to avoid sharing it with other attempts.
2893 if (IfrNvData
->AuthenticationType
== ISCSI_AUTH_TYPE_CHAP
) {
2894 ZeroMem (IfrNvData
->CHAPName
, sizeof (IfrNvData
->CHAPName
));
2895 ZeroMem (IfrNvData
->CHAPSecret
, sizeof (IfrNvData
->CHAPSecret
));
2896 ZeroMem (IfrNvData
->ReverseCHAPName
, sizeof (IfrNvData
->ReverseCHAPName
));
2897 ZeroMem (IfrNvData
->ReverseCHAPSecret
, sizeof (IfrNvData
->ReverseCHAPSecret
));
2900 IScsiConvertAttemptConfigDataToIfrNvData (AttemptConfigData
, IfrNvData
);
2903 // Update current attempt to be a new created attempt or an existing attempt.
2905 mCallbackInfo
->Current
= AttemptConfigData
;
2913 This function allows the caller to request the current
2914 configuration for one or more named elements. The resulting
2915 string is in <ConfigAltResp> format. Also, any and all alternative
2916 configuration strings shall be appended to the end of the
2917 current configuration string. If they are, they must appear
2918 after the current configuration. They must contain the same
2919 routing (GUID, NAME, PATH) as the current configuration string.
2920 They must have an additional description indicating the type of
2921 alternative configuration the string represents,
2922 "ALTCFG=<StringToken>". That <StringToken> (when
2923 converted from Hex UNICODE to binary) is a reference to a
2924 string in the associated string pack.
2926 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
2928 @param[in] Request A null-terminated Unicode string in
2929 <ConfigRequest> format. Note that this
2930 includes the routing information as well as
2931 the configurable name / value pairs. It is
2932 invalid for this string to be in
2933 <MultiConfigRequest> format.
2935 @param[out] Progress On return, points to a character in the
2936 Request string. Points to the string's null
2937 terminator if request was successful. Points
2938 to the most recent "&" before the first
2939 failing name / value pair (or the beginning
2940 of the string if the failure is in the first
2941 name / value pair) if the request was not successful.
2943 @param[out] Results A null-terminated Unicode string in
2944 <ConfigAltResp> format which has all values
2945 filled in for the names in the Request string.
2946 String to be allocated by the called function.
2948 @retval EFI_SUCCESS The Results string is filled with the
2949 values corresponding to all requested
2952 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
2953 parts of the results that must be
2954 stored awaiting possible future
2957 @retval EFI_INVALID_PARAMETER For example, passing in a NULL
2958 for the Request parameter
2959 would result in this type of
2960 error. In this case, the
2961 Progress parameter would be
2964 @retval EFI_NOT_FOUND Routing data doesn't match any
2965 known driver. Progress set to the
2966 first character in the routing header.
2967 Note: There is no requirement that the
2968 driver validate the routing data. It
2969 must skip the <ConfigHdr> in order to
2972 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
2973 to most recent "&" before the
2974 error or the beginning of the
2977 @retval EFI_INVALID_PARAMETER Unknown name. Progress points
2978 to the & before the name in
2984 IScsiFormExtractConfig (
2985 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
2986 IN CONST EFI_STRING Request
,
2987 OUT EFI_STRING
*Progress
,
2988 OUT EFI_STRING
*Results
2992 CHAR8
*InitiatorName
;
2994 ISCSI_CONFIG_IFR_NVDATA
*IfrNvData
;
2995 ISCSI_FORM_CALLBACK_INFO
*Private
;
2996 EFI_STRING ConfigRequestHdr
;
2997 EFI_STRING ConfigRequest
;
2998 BOOLEAN AllocatedRequest
;
3001 if (This
== NULL
|| Progress
== NULL
|| Results
== NULL
) {
3002 return EFI_INVALID_PARAMETER
;
3005 *Progress
= Request
;
3006 if ((Request
!= NULL
) && !HiiIsConfigHdrMatch (Request
, &gIScsiConfigGuid
, mVendorStorageName
)) {
3007 return EFI_NOT_FOUND
;
3010 ConfigRequestHdr
= NULL
;
3011 ConfigRequest
= NULL
;
3012 AllocatedRequest
= FALSE
;
3015 Private
= ISCSI_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This
);
3016 IfrNvData
= AllocateZeroPool (sizeof (ISCSI_CONFIG_IFR_NVDATA
));
3017 if (IfrNvData
== NULL
) {
3018 return EFI_OUT_OF_RESOURCES
;
3022 if (Private
->Current
!= NULL
) {
3023 IScsiConvertAttemptConfigDataToIfrNvData (Private
->Current
, IfrNvData
);
3027 // Extract all AttemptConfigData to Keyword stroage of IfrNvData.
3029 IScsiConvertAttemptConfigDataToIfrNvDataByKeyword (IfrNvData
);
3031 BufferSize
= ISCSI_NAME_MAX_SIZE
;
3032 InitiatorName
= (CHAR8
*) AllocateZeroPool (BufferSize
);
3033 if (InitiatorName
== NULL
) {
3034 FreePool (IfrNvData
);
3035 return EFI_OUT_OF_RESOURCES
;
3038 Status
= gIScsiInitiatorName
.Get (&gIScsiInitiatorName
, &BufferSize
, InitiatorName
);
3039 if (EFI_ERROR (Status
)) {
3040 IfrNvData
->InitiatorName
[0] = L
'\0';
3042 AsciiStrToUnicodeStrS (
3044 IfrNvData
->InitiatorName
,
3045 sizeof (IfrNvData
->InitiatorName
) / sizeof (IfrNvData
->InitiatorName
[0])
3050 // Convert buffer data to <ConfigResp> by helper function BlockToConfig().
3052 BufferSize
= sizeof (ISCSI_CONFIG_IFR_NVDATA
);
3053 ConfigRequest
= Request
;
3054 if ((Request
== NULL
) || (StrStr (Request
, L
"OFFSET") == NULL
)) {
3056 // Request has no request element, construct full request string.
3057 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
3058 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
3060 ConfigRequestHdr
= HiiConstructConfigHdr (&gIScsiConfigGuid
, mVendorStorageName
, Private
->DriverHandle
);
3061 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
3062 ConfigRequest
= AllocateZeroPool (Size
);
3063 if (ConfigRequest
== NULL
) {
3064 FreePool (IfrNvData
);
3065 FreePool (InitiatorName
);
3066 return EFI_OUT_OF_RESOURCES
;
3068 AllocatedRequest
= TRUE
;
3069 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
3070 FreePool (ConfigRequestHdr
);
3073 Status
= gHiiConfigRouting
->BlockToConfig (
3076 (UINT8
*) IfrNvData
,
3081 FreePool (IfrNvData
);
3082 FreePool (InitiatorName
);
3085 // Free the allocated config request string.
3087 if (AllocatedRequest
) {
3088 FreePool (ConfigRequest
);
3089 ConfigRequest
= NULL
;
3092 // Set Progress string to the original request string.
3094 if (Request
== NULL
) {
3096 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
3097 *Progress
= Request
+ StrLen (Request
);
3106 This function applies changes in a driver's configuration.
3107 Input is a Configuration, which has the routing data for this
3108 driver followed by name / value configuration pairs. The driver
3109 must apply those pairs to its configurable storage. If the
3110 driver's configuration is stored in a linear block of data
3111 and the driver's name / value pairs are in <BlockConfig>
3112 format, it may use the ConfigToBlock helper function (above) to
3115 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
3117 @param[in] Configuration A null-terminated Unicode string in
3118 <ConfigString> format.
3120 @param[out] Progress A pointer to a string filled in with the
3121 offset of the most recent '&' before the
3122 first failing name / value pair (or the
3123 beginning of the string if the failure
3124 is in the first name / value pair) or
3125 the terminating NULL if all was
3128 @retval EFI_SUCCESS The results have been distributed or are
3129 awaiting distribution.
3131 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
3132 parts of the results that must be
3133 stored awaiting possible future
3136 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
3137 Results parameter would result
3138 in this type of error.
3140 @retval EFI_NOT_FOUND Target for the specified routing data
3146 IScsiFormRouteConfig (
3147 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
3148 IN CONST EFI_STRING Configuration
,
3149 OUT EFI_STRING
*Progress
3153 ISCSI_CONFIG_IFR_NVDATA
*IfrNvData
;
3154 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
3156 LIST_ENTRY
*NextEntry
;
3157 ISCSI_NIC_INFO
*NicInfo
;
3159 CHAR16 MacString
[ISCSI_MAX_MAC_STRING_LEN
];
3160 CHAR8
*InitiatorName
;
3171 Status
= EFI_SUCCESS
;
3173 if (This
== NULL
|| Configuration
== NULL
|| Progress
== NULL
) {
3174 return EFI_INVALID_PARAMETER
;
3178 // Check routing data in <ConfigHdr>.
3179 // Note: if only one Storage is used, then this checking could be skipped.
3181 if (!HiiIsConfigHdrMatch (Configuration
, &gIScsiConfigGuid
, mVendorStorageName
)) {
3182 *Progress
= Configuration
;
3183 return EFI_NOT_FOUND
;
3186 IfrNvData
= AllocateZeroPool (sizeof (ISCSI_CONFIG_IFR_NVDATA
));
3187 if (IfrNvData
== NULL
) {
3188 return EFI_OUT_OF_RESOURCES
;
3191 BufferSize
= ISCSI_NAME_MAX_SIZE
;
3192 InitiatorName
= (CHAR8
*) AllocateZeroPool (BufferSize
);
3193 if (InitiatorName
== NULL
) {
3194 Status
= EFI_OUT_OF_RESOURCES
;
3199 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock().
3201 BufferSize
= sizeof (ISCSI_CONFIG_IFR_NVDATA
);
3202 Status
= gHiiConfigRouting
->ConfigToBlock (
3205 (UINT8
*) IfrNvData
,
3209 if (EFI_ERROR (Status
)) {
3213 if (IfrNvData
->InitiatorName
[0] != L
'\0') {
3214 UnicodeStrToAsciiStrS (IfrNvData
->InitiatorName
, InitiatorName
, ISCSI_NAME_MAX_SIZE
);
3215 BufferSize
= AsciiStrSize (InitiatorName
);
3217 Status
= gIScsiInitiatorName
.Set (&gIScsiInitiatorName
, &BufferSize
, InitiatorName
);
3218 if (EFI_ERROR (Status
)) {
3220 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
3222 L
"Invalid iSCSI Name!",
3228 Status
= IScsiGetValue (Configuration
, L
"&OFFSET=", &OffSet
);
3229 if (EFI_ERROR (Status
)) {
3233 if (OffSet
>= ATTEMPT_MAC_ADDR_VAR_OFFSET
) {
3234 Status
= gIScsiInitiatorName
.Get (&gIScsiInitiatorName
, &BufferSize
, InitiatorName
);
3235 if (EFI_ERROR (Status
)) {
3237 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
3239 L
"Error: please configure iSCSI initiator name first!",
3248 if (IfrNvData
->ISCSIAddAttemptList
[0] != L
'\0') {
3249 Status
=IScsiGetAttemptIndexList (IfrNvData
->ISCSIAddAttemptList
, IfrNvData
->AddAttemptList
, TRUE
);
3250 if (EFI_ERROR (Status
)) {
3252 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
3254 L
"Error: The add attempt list is invalid",
3260 Status
= IScsiConfigAddAttemptsByKeywords (IfrNvData
->AddAttemptList
);
3261 if (EFI_ERROR (Status
)) {
3265 } else if (IfrNvData
->ISCSIDeleteAttemptList
[0] != L
'\0') {
3266 AttemptList
=(UINT8
*) AllocateZeroPool ((ISCSI_MAX_ATTEMPTS_NUM
+ 1) * sizeof (UINT8
));
3267 if (AttemptList
== NULL
) {
3268 Status
= EFI_OUT_OF_RESOURCES
;
3271 Status
= IScsiGetAttemptIndexList (IfrNvData
->ISCSIDeleteAttemptList
, AttemptList
, FALSE
);
3272 if (EFI_ERROR (Status
)) {
3274 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
3276 L
"Error: The delete attempt list is invalid",
3283 // Mark the attempt which will be delete in the global list.
3285 NET_LIST_FOR_EACH_SAFE (Entry
, NextEntry
, &mPrivate
->AttemptConfigs
) {
3286 AttemptConfigData
= NET_LIST_USER_STRUCT (Entry
, ISCSI_ATTEMPT_CONFIG_NVDATA
, Link
);
3287 while (AttemptList
[Index
] != 0) {
3288 if (AttemptConfigData
->AttemptConfigIndex
== AttemptList
[Index
]) {
3289 IfrNvData
->DeleteAttemptList
[Index2
] = 1;
3298 Status
= IScsiConfigDeleteAttempts (IfrNvData
);
3299 if (EFI_ERROR (Status
)) {
3303 FreePool (AttemptList
);
3305 } else if (IfrNvData
->ISCSIAttemptOrder
[0] != L
'\0') {
3306 Status
= IScsiGetAttemptIndexList (IfrNvData
->ISCSIAttemptOrder
, IfrNvData
->DynamicOrderedList
, FALSE
);
3307 if (EFI_ERROR (Status
)) {
3309 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
3311 L
"Error: The new attempt order list is invalid",
3317 Status
= IScsiConfigOrderAttempts (IfrNvData
);
3318 if (EFI_ERROR (Status
)) {
3322 } else if (IfrNvData
->ISCSIMacAddr
[0] != L
'\0') {
3323 NET_LIST_FOR_EACH (Entry
, &mPrivate
->NicInfoList
) {
3324 NicInfo
= NET_LIST_USER_STRUCT (Entry
, ISCSI_NIC_INFO
, Link
);
3326 &NicInfo
->PermanentAddress
,
3327 NicInfo
->HwAddressSize
,
3331 if (!StrCmp(MacString
, IfrNvData
->ISCSIMacAddr
)) {
3332 mPrivate
->CurrentNic
= NicInfo
->NicIndex
;
3337 if ((NicInfo
== NULL
) || (NicInfo
->NicIndex
== 0)) {
3338 Status
= EFI_NOT_FOUND
;
3343 Status
= IScsiConvertlfrNvDataToAttemptConfigDataByKeyword (IfrNvData
, OffSet
);
3344 if (EFI_ERROR (Status
)) {
3350 IScsiConfigUpdateAttempt ();
3353 if (InitiatorName
!= NULL
) {
3354 FreePool (InitiatorName
);
3357 if (IfrNvData
!= NULL
) {
3358 FreePool (IfrNvData
);
3366 This function is called to provide results data to the driver.
3367 This data consists of a unique key that is used to identify
3368 which data is either being passed back or being asked for.
3370 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
3371 @param[in] Action Specifies the type of action taken by the browser.
3372 @param[in] QuestionId A unique value which is sent to the original
3373 exporting driver so that it can identify the type
3374 of data to expect. The format of the data tends to
3375 vary based on the opcode that generated the callback.
3376 @param[in] Type The type of value for the question.
3377 @param[in, out] Value A pointer to the data being sent to the original
3379 @param[out] ActionRequest On return, points to the action requested by the
3382 @retval EFI_SUCCESS The callback successfully handled the action.
3383 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
3384 variable and its data.
3385 @retval EFI_DEVICE_ERROR The variable could not be saved.
3386 @retval EFI_UNSUPPORTED The specified Action is not supported by the
3392 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
3393 IN EFI_BROWSER_ACTION Action
,
3394 IN EFI_QUESTION_ID QuestionId
,
3396 IN OUT EFI_IFR_TYPE_VALUE
*Value
,
3397 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
3400 ISCSI_FORM_CALLBACK_INFO
*Private
;
3403 CHAR8 IpString
[ISCSI_NAME_MAX_SIZE
];
3404 CHAR8 LunString
[ISCSI_LUN_STR_MAX_LEN
];
3406 EFI_IP_ADDRESS HostIp
;
3407 EFI_IP_ADDRESS SubnetMask
;
3408 EFI_IP_ADDRESS Gateway
;
3409 ISCSI_CONFIG_IFR_NVDATA
*IfrNvData
;
3410 ISCSI_CONFIG_IFR_NVDATA OldIfrNvData
;
3413 ISCSI_NIC_INFO
*NicInfo
;
3417 if ((Action
== EFI_BROWSER_ACTION_FORM_OPEN
) || (Action
== EFI_BROWSER_ACTION_FORM_CLOSE
)) {
3419 // Do nothing for UEFI OPEN/CLOSE Action
3424 if ((Action
!= EFI_BROWSER_ACTION_CHANGING
) && (Action
!= EFI_BROWSER_ACTION_CHANGED
)) {
3426 // All other type return unsupported.
3428 return EFI_UNSUPPORTED
;
3431 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
3432 return EFI_INVALID_PARAMETER
;
3435 Private
= ISCSI_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This
);
3438 // Retrieve uncommitted data from Browser
3441 BufferSize
= sizeof (ISCSI_CONFIG_IFR_NVDATA
);
3442 IfrNvData
= AllocateZeroPool (BufferSize
);
3443 if (IfrNvData
== NULL
) {
3444 return EFI_OUT_OF_RESOURCES
;
3447 IScsiName
= (CHAR8
*) AllocateZeroPool (ISCSI_NAME_MAX_SIZE
);
3448 if (IScsiName
== NULL
) {
3449 FreePool (IfrNvData
);
3450 return EFI_OUT_OF_RESOURCES
;
3453 Status
= EFI_SUCCESS
;
3455 ZeroMem (&OldIfrNvData
, BufferSize
);
3457 HiiGetBrowserData (NULL
, NULL
, BufferSize
, (UINT8
*) IfrNvData
);
3459 CopyMem (&OldIfrNvData
, IfrNvData
, BufferSize
);
3461 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
3462 switch (QuestionId
) {
3463 case KEY_ADD_ATTEMPT
:
3465 // Check whether iSCSI initiator name is configured already.
3467 mPrivate
->InitiatorNameLength
= ISCSI_NAME_MAX_SIZE
;
3468 Status
= gIScsiInitiatorName
.Get (
3469 &gIScsiInitiatorName
,
3470 &mPrivate
->InitiatorNameLength
,
3471 mPrivate
->InitiatorName
3473 if (EFI_ERROR (Status
)) {
3475 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
3477 L
"Error: please configure iSCSI initiator name first!",
3483 Status
= IScsiConfigAddAttempt ();
3486 case KEY_DELETE_ATTEMPT
:
3488 OldIfrNvData
.DeleteAttemptList
,
3489 IfrNvData
->DeleteAttemptList
,
3490 sizeof (IfrNvData
->DeleteAttemptList
)
3492 Status
= IScsiConfigDisplayDeleteAttempts (IfrNvData
);
3495 case KEY_ORDER_ATTEMPT_CONFIG
:
3497 // Order the attempt according to user input.
3500 OldIfrNvData
.DynamicOrderedList
,
3501 IfrNvData
->DynamicOrderedList
,
3502 sizeof (IfrNvData
->DynamicOrderedList
)
3504 IScsiConfigDisplayOrderAttempts ();
3508 Status
= IScsiConfigProcessDefault (QuestionId
, IfrNvData
);
3511 } else if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
3512 switch (QuestionId
) {
3513 case KEY_INITIATOR_NAME
:
3514 UnicodeStrToAsciiStrS (IfrNvData
->InitiatorName
, IScsiName
, ISCSI_NAME_MAX_SIZE
);
3515 BufferSize
= AsciiStrSize (IScsiName
);
3517 Status
= gIScsiInitiatorName
.Set (&gIScsiInitiatorName
, &BufferSize
, IScsiName
);
3518 if (EFI_ERROR (Status
)) {
3520 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
3522 L
"Invalid iSCSI Name!",
3527 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
;
3530 case KEY_SAVE_ATTEMPT_CONFIG
:
3531 Status
= IScsiConvertIfrNvDataToAttemptConfigData (IfrNvData
, Private
->Current
);
3532 if (EFI_ERROR (Status
)) {
3536 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
;
3539 case KEY_SAVE_ORDER_CHANGES
:
3541 // Sync the Attempt Order to NVR.
3543 Status
= IScsiConfigOrderAttempts (IfrNvData
);
3544 if (EFI_ERROR (Status
)) {
3548 IScsiConfigUpdateAttempt ();
3549 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
;
3552 case KEY_IGNORE_ORDER_CHANGES
:
3554 IfrNvData
->DynamicOrderedList
,
3555 OldIfrNvData
.DynamicOrderedList
,
3556 sizeof (IfrNvData
->DynamicOrderedList
)
3558 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
3561 case KEY_SAVE_DELETE_ATTEMPT
:
3563 // Delete the Attempt Order from NVR
3565 Status
= IScsiConfigDeleteAttempts (IfrNvData
);
3566 if (EFI_ERROR (Status
)) {
3570 IScsiConfigUpdateAttempt ();
3571 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
;
3574 case KEY_IGNORE_DELETE_ATTEMPT
:
3576 IfrNvData
->DeleteAttemptList
,
3577 OldIfrNvData
.DeleteAttemptList
,
3578 sizeof (IfrNvData
->DeleteAttemptList
)
3580 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
3584 switch (Value
->u8
) {
3586 NicInfo
= IScsiGetNicInfoByIndex (Private
->Current
->NicIndex
);
3587 if(NicInfo
== NULL
) {
3591 if(!NicInfo
->Ipv6Available
) {
3593 // Current NIC doesn't Support IPv6, hence use IPv4.
3595 IfrNvData
->IpMode
= IP_MODE_IP4
;
3598 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
3600 L
"Current NIC doesn't Support IPv6!",
3606 ZeroMem (IfrNvData
->LocalIp
, sizeof (IfrNvData
->LocalIp
));
3607 ZeroMem (IfrNvData
->SubnetMask
, sizeof (IfrNvData
->SubnetMask
));
3608 ZeroMem (IfrNvData
->Gateway
, sizeof (IfrNvData
->Gateway
));
3609 ZeroMem (IfrNvData
->TargetIp
, sizeof (IfrNvData
->TargetIp
));
3610 Private
->Current
->AutoConfigureMode
= 0;
3611 ZeroMem (&Private
->Current
->SessionConfigData
.LocalIp
, sizeof (EFI_IP_ADDRESS
));
3612 ZeroMem (&Private
->Current
->SessionConfigData
.SubnetMask
, sizeof (EFI_IPv4_ADDRESS
));
3613 ZeroMem (&Private
->Current
->SessionConfigData
.Gateway
, sizeof (EFI_IP_ADDRESS
));
3614 ZeroMem (&Private
->Current
->SessionConfigData
.TargetIp
, sizeof (EFI_IP_ADDRESS
));
3622 Status
= NetLibStrToIp4 (IfrNvData
->LocalIp
, &HostIp
.v4
);
3623 if (EFI_ERROR (Status
) ||
3624 ((Private
->Current
->SessionConfigData
.SubnetMask
.Addr
[0] != 0) &&
3625 !NetIp4IsUnicast (NTOHL (HostIp
.Addr
[0]), NTOHL(*(UINT32
*)Private
->Current
->SessionConfigData
.SubnetMask
.Addr
)))) {
3627 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
3629 L
"Invalid IP address!",
3633 Status
= EFI_INVALID_PARAMETER
;
3635 CopyMem (&Private
->Current
->SessionConfigData
.LocalIp
, &HostIp
.v4
, sizeof (HostIp
.v4
));
3640 case KEY_SUBNET_MASK
:
3641 Status
= NetLibStrToIp4 (IfrNvData
->SubnetMask
, &SubnetMask
.v4
);
3642 if (EFI_ERROR (Status
) || ((SubnetMask
.Addr
[0] != 0) && (IScsiGetSubnetMaskPrefixLength (&SubnetMask
.v4
) == 0))) {
3644 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
3646 L
"Invalid Subnet Mask!",
3650 Status
= EFI_INVALID_PARAMETER
;
3652 CopyMem (&Private
->Current
->SessionConfigData
.SubnetMask
, &SubnetMask
.v4
, sizeof (SubnetMask
.v4
));
3658 Status
= NetLibStrToIp4 (IfrNvData
->Gateway
, &Gateway
.v4
);
3659 if (EFI_ERROR (Status
) ||
3660 ((Gateway
.Addr
[0] != 0) &&
3661 (Private
->Current
->SessionConfigData
.SubnetMask
.Addr
[0] != 0) &&
3662 !NetIp4IsUnicast (NTOHL (Gateway
.Addr
[0]), NTOHL(*(UINT32
*)Private
->Current
->SessionConfigData
.SubnetMask
.Addr
)))) {
3664 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
3666 L
"Invalid Gateway!",
3669 Status
= EFI_INVALID_PARAMETER
;
3671 CopyMem (&Private
->Current
->SessionConfigData
.Gateway
, &Gateway
.v4
, sizeof (Gateway
.v4
));
3677 UnicodeStrToAsciiStrS (IfrNvData
->TargetIp
, IpString
, sizeof (IpString
));
3678 Status
= IScsiAsciiStrToIp (IpString
, IfrNvData
->IpMode
, &HostIp
);
3679 if (EFI_ERROR (Status
) || !IpIsUnicast (&HostIp
, IfrNvData
->IpMode
)) {
3681 // The target is expressed in URL format or an invalid Ip address, just save.
3683 Private
->Current
->SessionConfigData
.DnsMode
= TRUE
;
3684 ZeroMem (&Private
->Current
->SessionConfigData
.TargetIp
, sizeof (Private
->Current
->SessionConfigData
.TargetIp
));
3685 UnicodeStrToAsciiStrS (IfrNvData
->TargetIp
, Private
->Current
->SessionConfigData
.TargetUrl
, ISCSI_NAME_MAX_SIZE
);
3687 Private
->Current
->SessionConfigData
.DnsMode
= FALSE
;
3688 CopyMem (&Private
->Current
->SessionConfigData
.TargetIp
, &HostIp
, sizeof (HostIp
));
3693 case KEY_TARGET_NAME
:
3694 UnicodeStrToAsciiStrS (IfrNvData
->TargetName
, IScsiName
, ISCSI_NAME_MAX_SIZE
);
3695 Status
= IScsiNormalizeName (IScsiName
, AsciiStrLen (IScsiName
));
3696 if (EFI_ERROR (Status
)) {
3698 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
3700 L
"Invalid iSCSI Name!",
3704 AsciiStrCpyS (Private
->Current
->SessionConfigData
.TargetName
, ISCSI_NAME_MAX_SIZE
, IScsiName
);
3709 case KEY_DHCP_ENABLE
:
3710 if (IfrNvData
->InitiatorInfoFromDhcp
== 0) {
3711 IfrNvData
->TargetInfoFromDhcp
= 0;
3717 UnicodeStrToAsciiStrS (IfrNvData
->BootLun
, LunString
, sizeof (LunString
));
3718 Status
= IScsiAsciiStrToLun (LunString
, (UINT8
*) &Lun
);
3719 if (EFI_ERROR (Status
)) {
3721 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
3723 L
"Invalid LUN string!",
3727 CopyMem (Private
->Current
->SessionConfigData
.BootLun
, &Lun
, sizeof (Lun
));
3733 switch (Value
->u8
) {
3734 case ISCSI_AUTH_TYPE_CHAP
:
3735 IfrNvData
->CHAPType
= ISCSI_CHAP_UNI
;
3744 UnicodeStrToAsciiStrS (
3745 IfrNvData
->CHAPName
,
3746 Private
->Current
->AuthConfigData
.CHAP
.CHAPName
,
3747 sizeof (Private
->Current
->AuthConfigData
.CHAP
.CHAPName
)
3751 case KEY_CHAP_SECRET
:
3752 UnicodeStrToAsciiStrS (
3753 IfrNvData
->CHAPSecret
,
3754 Private
->Current
->AuthConfigData
.CHAP
.CHAPSecret
,
3755 sizeof (Private
->Current
->AuthConfigData
.CHAP
.CHAPSecret
)
3759 case KEY_REVERSE_CHAP_NAME
:
3760 UnicodeStrToAsciiStrS (
3761 IfrNvData
->ReverseCHAPName
,
3762 Private
->Current
->AuthConfigData
.CHAP
.ReverseCHAPName
,
3763 sizeof (Private
->Current
->AuthConfigData
.CHAP
.ReverseCHAPName
)
3767 case KEY_REVERSE_CHAP_SECRET
:
3768 UnicodeStrToAsciiStrS (
3769 IfrNvData
->ReverseCHAPSecret
,
3770 Private
->Current
->AuthConfigData
.CHAP
.ReverseCHAPSecret
,
3771 sizeof (Private
->Current
->AuthConfigData
.CHAP
.ReverseCHAPSecret
)
3775 case KEY_CONFIG_ISID
:
3776 IScsiParseIsIdFromString (IfrNvData
->IsId
, Private
->Current
->SessionConfigData
.IsId
);
3777 IScsiConvertIsIdToString (IfrNvData
->IsId
, Private
->Current
->SessionConfigData
.IsId
);
3786 if (!EFI_ERROR (Status
)) {
3788 // Pass changed uncommitted data back to Form Browser.
3790 BufferSize
= sizeof (ISCSI_CONFIG_IFR_NVDATA
);
3791 HiiSetBrowserData (NULL
, NULL
, BufferSize
, (UINT8
*) IfrNvData
, NULL
);
3794 FreePool (IfrNvData
);
3795 FreePool (IScsiName
);
3802 Initialize the iSCSI configuration form.
3804 @param[in] DriverBindingHandle The iSCSI driverbinding handle.
3806 @retval EFI_SUCCESS The iSCSI configuration form is initialized.
3807 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
3811 IScsiConfigFormInit (
3812 IN EFI_HANDLE DriverBindingHandle
3816 ISCSI_FORM_CALLBACK_INFO
*CallbackInfo
;
3818 CallbackInfo
= (ISCSI_FORM_CALLBACK_INFO
*) AllocateZeroPool (sizeof (ISCSI_FORM_CALLBACK_INFO
));
3819 if (CallbackInfo
== NULL
) {
3820 return EFI_OUT_OF_RESOURCES
;
3823 CallbackInfo
->Signature
= ISCSI_FORM_CALLBACK_INFO_SIGNATURE
;
3824 CallbackInfo
->Current
= NULL
;
3826 CallbackInfo
->ConfigAccess
.ExtractConfig
= IScsiFormExtractConfig
;
3827 CallbackInfo
->ConfigAccess
.RouteConfig
= IScsiFormRouteConfig
;
3828 CallbackInfo
->ConfigAccess
.Callback
= IScsiFormCallback
;
3831 // Install Device Path Protocol and Config Access protocol to driver handle.
3833 Status
= gBS
->InstallMultipleProtocolInterfaces (
3834 &CallbackInfo
->DriverHandle
,
3835 &gEfiDevicePathProtocolGuid
,
3836 &mIScsiHiiVendorDevicePath
,
3837 &gEfiHiiConfigAccessProtocolGuid
,
3838 &CallbackInfo
->ConfigAccess
,
3841 ASSERT_EFI_ERROR (Status
);
3844 // Publish our HII data.
3846 CallbackInfo
->RegisteredHandle
= HiiAddPackages (
3848 CallbackInfo
->DriverHandle
,
3853 if (CallbackInfo
->RegisteredHandle
== NULL
) {
3854 gBS
->UninstallMultipleProtocolInterfaces (
3855 CallbackInfo
->DriverHandle
,
3856 &gEfiDevicePathProtocolGuid
,
3857 &mIScsiHiiVendorDevicePath
,
3858 &gEfiHiiConfigAccessProtocolGuid
,
3859 &CallbackInfo
->ConfigAccess
,
3862 FreePool(CallbackInfo
);
3863 return EFI_OUT_OF_RESOURCES
;
3866 mCallbackInfo
= CallbackInfo
;
3873 Unload the iSCSI configuration form, this includes: delete all the iSCSI
3874 configuration entries, uninstall the form callback protocol, and
3875 free the resources used.
3877 @param[in] DriverBindingHandle The iSCSI driverbinding handle.
3879 @retval EFI_SUCCESS The iSCSI configuration form is unloaded.
3880 @retval Others Failed to unload the form.
3884 IScsiConfigFormUnload (
3885 IN EFI_HANDLE DriverBindingHandle
3888 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
3889 ISCSI_NIC_INFO
*NicInfo
;
3893 while (!IsListEmpty (&mPrivate
->AttemptConfigs
)) {
3894 Entry
= NetListRemoveHead (&mPrivate
->AttemptConfigs
);
3895 AttemptConfigData
= NET_LIST_USER_STRUCT (Entry
, ISCSI_ATTEMPT_CONFIG_NVDATA
, Link
);
3896 FreePool (AttemptConfigData
);
3897 mPrivate
->AttemptCount
--;
3900 ASSERT (mPrivate
->AttemptCount
== 0);
3902 while (!IsListEmpty (&mPrivate
->NicInfoList
)) {
3903 Entry
= NetListRemoveHead (&mPrivate
->NicInfoList
);
3904 NicInfo
= NET_LIST_USER_STRUCT (Entry
, ISCSI_NIC_INFO
, Link
);
3906 mPrivate
->NicCount
--;
3909 ASSERT (mPrivate
->NicCount
== 0);
3911 FreePool (mPrivate
);
3915 // Remove HII package list.
3917 HiiRemovePackages (mCallbackInfo
->RegisteredHandle
);
3920 // Uninstall Device Path Protocol and Config Access protocol.
3922 Status
= gBS
->UninstallMultipleProtocolInterfaces (
3923 mCallbackInfo
->DriverHandle
,
3924 &gEfiDevicePathProtocolGuid
,
3925 &mIScsiHiiVendorDevicePath
,
3926 &gEfiHiiConfigAccessProtocolGuid
,
3927 &mCallbackInfo
->ConfigAccess
,
3931 FreePool (mCallbackInfo
);