2 Miscellaneous routines for iSCSI driver.
4 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
11 GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 IScsiHexString
[] = "0123456789ABCDEFabcdef";
14 Removes (trims) specified leading and trailing characters from a string.
16 @param[in, out] Str Pointer to the null-terminated string to be trimmed.
17 On return, Str will hold the trimmed string.
19 @param[in] CharC Character will be trimmed from str.
36 // Trim off the leading and trailing characters c
38 for (Pointer1
= Str
; (*Pointer1
!= 0) && (*Pointer1
== CharC
); Pointer1
++) {
42 if (Pointer2
== Pointer1
) {
43 while (*Pointer1
!= 0) {
48 while (*Pointer1
!= 0) {
49 *Pointer2
= *Pointer1
;
57 for (Pointer1
= Str
+ StrLen (Str
) - 1; Pointer1
>= Str
&& *Pointer1
== CharC
; Pointer1
--) {
60 if (Pointer1
!= Str
+ StrLen (Str
) - 1) {
66 Calculate the prefix length of the IPv4 subnet mask.
68 @param[in] SubnetMask The IPv4 subnet mask.
70 @return The prefix length of the subnet mask.
71 @retval 0 Other errors as indicated.
75 IScsiGetSubnetMaskPrefixLength (
76 IN EFI_IPv4_ADDRESS
*SubnetMask
83 // The SubnetMask is in network byte order.
85 ReverseMask
= (SubnetMask
->Addr
[0] << 24) | (SubnetMask
->Addr
[1] << 16) | (SubnetMask
->Addr
[2] << 8) | (SubnetMask
->Addr
[3]);
90 ReverseMask
= ~ReverseMask
;
92 if ((ReverseMask
& (ReverseMask
+ 1)) != 0) {
98 while (ReverseMask
!= 0) {
99 ReverseMask
= ReverseMask
>> 1;
103 return (UINT8
)(32 - Len
);
107 Convert the hexadecimal encoded LUN string into the 64-bit LUN.
109 @param[in] Str The hexadecimal encoded LUN string.
110 @param[out] Lun Storage to return the 64-bit LUN.
112 @retval EFI_SUCCESS The 64-bit LUN is stored in Lun.
113 @retval EFI_INVALID_PARAMETER The string is malformatted.
122 UINTN Index
, IndexValue
, IndexNum
, SizeStr
;
129 ZeroMem ((UINT8
*)Value
, sizeof (Value
));
130 SizeStr
= AsciiStrLen (Str
);
134 for (Index
= 0; Index
< SizeStr
; Index
++) {
135 TemStr
[0] = Str
[Index
];
136 TemValue
= (UINT8
)AsciiStrHexToUint64 (TemStr
);
137 if ((TemValue
== 0) && (TemStr
[0] != '0')) {
138 if ((TemStr
[0] != '-') || (IndexNum
== 0)) {
142 return EFI_INVALID_PARAMETER
;
146 if ((TemValue
== 0) && (TemStr
[0] == '-')) {
150 if (++IndexValue
>= 4) {
154 return EFI_INVALID_PARAMETER
;
158 // Restart str index for the next lun value.
164 if (++IndexNum
> 4) {
166 // Each Lun Str can't exceed size 4, because it will be as UINT16 value.
168 return EFI_INVALID_PARAMETER
;
172 // Combine UINT16 value.
174 Value
[IndexValue
] = (UINT16
)((Value
[IndexValue
] << 4) + TemValue
);
177 for (Index
= 0; Index
<= IndexValue
; Index
++) {
178 *((UINT16
*)&Lun
[Index
* 2]) = HTONS (Value
[Index
]);
185 Convert the 64-bit LUN into the hexadecimal encoded LUN string.
187 @param[in] Lun The 64-bit LUN.
188 @param[out] Str The storage to return the hexadecimal encoded LUN string.
192 IScsiLunToUnicodeStr (
202 for (Index
= 0; Index
< 4; Index
++) {
203 if ((Lun
[2 * Index
] | Lun
[2 * Index
+ 1]) == 0) {
204 CopyMem (TempStr
, L
"0-", sizeof (L
"0-"));
206 TempStr
[0] = (CHAR16
)IScsiHexString
[Lun
[2 * Index
] >> 4];
207 TempStr
[1] = (CHAR16
)IScsiHexString
[Lun
[2 * Index
] & 0x0F];
208 TempStr
[2] = (CHAR16
)IScsiHexString
[Lun
[2 * Index
+ 1] >> 4];
209 TempStr
[3] = (CHAR16
)IScsiHexString
[Lun
[2 * Index
+ 1] & 0x0F];
213 IScsiStrTrim (TempStr
, L
'0');
216 TempStr
+= StrLen (TempStr
);
220 // Remove the last '-'
222 ASSERT (StrLen (Str
) >= 1);
223 Str
[StrLen (Str
) - 1] = 0;
225 for (Index
= StrLen (Str
) - 1; Index
> 1; Index
= Index
- 2) {
226 if ((Str
[Index
] == L
'0') && (Str
[Index
- 1] == L
'-')) {
235 Convert the formatted IP address into the binary IP address.
237 @param[in] Str The UNICODE string.
238 @param[in] IpMode Indicates whether the IP address is v4 or v6.
239 @param[out] Ip The storage to return the ASCII string.
241 @retval EFI_SUCCESS The binary IP address is returned in Ip.
242 @retval EFI_INVALID_PARAMETER The IP string is malformatted or IpMode is
250 OUT EFI_IP_ADDRESS
*Ip
255 if ((IpMode
== IP_MODE_IP4
) || (IpMode
== IP_MODE_AUTOCONFIG_IP4
)) {
256 return NetLibAsciiStrToIp4 (Str
, &Ip
->v4
);
257 } else if ((IpMode
== IP_MODE_IP6
) || (IpMode
== IP_MODE_AUTOCONFIG_IP6
)) {
258 return NetLibAsciiStrToIp6 (Str
, &Ip
->v6
);
259 } else if (IpMode
== IP_MODE_AUTOCONFIG
) {
260 Status
= NetLibAsciiStrToIp4 (Str
, &Ip
->v4
);
261 if (!EFI_ERROR (Status
)) {
265 return NetLibAsciiStrToIp6 (Str
, &Ip
->v6
);
268 return EFI_INVALID_PARAMETER
;
272 Convert the mac address into a hexadecimal encoded "-" separated string.
274 @param[in] Mac The mac address.
275 @param[in] Len Length in bytes of the mac address.
276 @param[in] VlanId VLAN ID of the network device.
277 @param[out] Str The storage to return the mac string.
282 IN EFI_MAC_ADDRESS
*Mac
,
291 for (Index
= 0; Index
< Len
; Index
++) {
292 Str
[3 * Index
] = (CHAR16
)IScsiHexString
[(Mac
->Addr
[Index
] >> 4) & 0x0F];
293 Str
[3 * Index
+ 1] = (CHAR16
)IScsiHexString
[Mac
->Addr
[Index
] & 0x0F];
294 Str
[3 * Index
+ 2] = L
':';
297 String
= &Str
[3 * Index
- 1];
299 String
+= UnicodeSPrint (String
, 6 * sizeof (CHAR16
), L
"\\%04x", (UINTN
)VlanId
);
306 Convert the binary encoded buffer into a hexadecimal encoded string.
308 @param[in] BinBuffer The buffer containing the binary data.
309 @param[in] BinLength Length of the binary buffer.
310 @param[in, out] HexStr Pointer to the string.
311 @param[in, out] HexLength The length of the string.
313 @retval EFI_SUCCESS The binary data is converted to the hexadecimal string
314 and the length of the string is updated.
315 @retval EFI_BUFFER_TOO_SMALL The string is too small.
316 @retval EFI_BAD_BUFFER_SIZE BinLength is too large for hex encoding.
317 @retval EFI_INVALID_PARAMETER The IP string is malformatted.
324 IN OUT CHAR8
*HexStr
,
325 IN OUT UINT32
*HexLength
329 UINT32 HexLengthProvided
;
332 if ((HexStr
== NULL
) || (BinBuffer
== NULL
) || (BinLength
== 0)) {
333 return EFI_INVALID_PARAMETER
;
337 // Safely calculate: HexLengthMin := BinLength * 2 + 3.
339 if (RETURN_ERROR (SafeUint32Mult (BinLength
, 2, &HexLengthMin
)) ||
340 RETURN_ERROR (SafeUint32Add (HexLengthMin
, 3, &HexLengthMin
)))
342 return EFI_BAD_BUFFER_SIZE
;
345 HexLengthProvided
= *HexLength
;
346 *HexLength
= HexLengthMin
;
347 if (HexLengthProvided
< HexLengthMin
) {
348 return EFI_BUFFER_TOO_SMALL
;
352 // Prefix for Hex String.
357 for (Index
= 0; Index
< BinLength
; Index
++) {
358 HexStr
[Index
* 2 + 2] = IScsiHexString
[BinBuffer
[Index
] >> 4];
359 HexStr
[Index
* 2 + 3] = IScsiHexString
[BinBuffer
[Index
] & 0xf];
362 HexStr
[Index
* 2 + 2] = '\0';
368 Convert the hexadecimal string into a binary encoded buffer.
370 @param[in, out] BinBuffer The binary buffer.
371 @param[in, out] BinLength Length of the binary buffer.
372 @param[in] HexStr The hexadecimal string.
374 @retval EFI_SUCCESS The hexadecimal string is converted into a
375 binary encoded buffer.
376 @retval EFI_INVALID_PARAMETER Invalid hex encoding found in HexStr.
377 @retval EFI_BAD_BUFFER_SIZE The length of HexStr is too large for decoding:
378 the decoded size cannot be expressed in
380 @retval EFI_BUFFER_TOO_SMALL The binary buffer is too small to hold the
385 IN OUT UINT8
*BinBuffer
,
386 IN OUT UINT32
*BinLength
,
391 UINT32 BinLengthProvided
;
397 ZeroMem (TemStr
, sizeof (TemStr
));
400 // Find out how many hex characters the string has.
402 if ((HexStr
[0] == '0') && ((HexStr
[1] == 'x') || (HexStr
[1] == 'X'))) {
406 Length
= AsciiStrLen (HexStr
);
409 // Reject an empty hex string; reject a stray nibble.
411 if ((Length
== 0) || (Length
% 2 != 0)) {
412 return EFI_INVALID_PARAMETER
;
416 // Check if the caller provides enough room for the decoded blob.
418 BinLengthMin
= Length
/ 2;
419 if (BinLengthMin
> MAX_UINT32
) {
420 return EFI_BAD_BUFFER_SIZE
;
423 BinLengthProvided
= *BinLength
;
424 *BinLength
= (UINT32
)BinLengthMin
;
425 if (BinLengthProvided
< BinLengthMin
) {
426 return EFI_BUFFER_TOO_SMALL
;
429 for (Index
= 0; Index
< Length
; Index
++) {
430 TemStr
[0] = HexStr
[Index
];
431 Digit
= (UINT8
)AsciiStrHexToUint64 (TemStr
);
432 if ((Digit
== 0) && (TemStr
[0] != '0')) {
436 return EFI_INVALID_PARAMETER
;
439 if ((Index
& 1) == 0) {
440 BinBuffer
[Index
/2] = Digit
;
442 BinBuffer
[Index
/2] = (UINT8
)((BinBuffer
[Index
/2] << 4) + Digit
);
450 Convert the decimal-constant string or hex-constant string into a numerical value.
452 @param[in] Str String in decimal or hex.
454 @return The numerical value.
462 if ((Str
[0] == '0') && ((Str
[1] == 'x') || (Str
[1] == 'X'))) {
465 return AsciiStrHexToUintn (Str
);
468 return AsciiStrDecimalToUintn (Str
);
472 Generate random numbers.
474 @param[in, out] Rand The buffer to contain random numbers.
475 @param[in] RandLength The length of the Rand buffer.
486 while (RandLength
> 0) {
487 Random
= NET_RANDOM (NetRandomInitSeed ());
488 *Rand
++ = (UINT8
)(Random
);
494 Check whether UNDI protocol supports IPv6.
496 @param[in] ControllerHandle Controller handle.
497 @param[in] Image Handle of the image.
498 @param[out] Ipv6Support TRUE if UNDI supports IPv6.
500 @retval EFI_SUCCESS Get the result whether UNDI supports IPv6 by NII or AIP protocol successfully.
501 @retval EFI_NOT_FOUND Don't know whether UNDI supports IPv6 since NII or AIP is not available.
505 IScsiCheckIpv6Support (
506 IN EFI_HANDLE ControllerHandle
,
508 OUT BOOLEAN
*Ipv6Support
512 EFI_ADAPTER_INFORMATION_PROTOCOL
*Aip
;
514 EFI_GUID
*InfoTypesBuffer
;
515 UINTN InfoTypeBufferCount
;
521 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL
*Nii
;
523 ASSERT (Ipv6Support
!= NULL
);
526 // Check whether the UNDI supports IPv6 by NII protocol.
528 Status
= gBS
->OpenProtocol (
530 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
534 EFI_OPEN_PROTOCOL_GET_PROTOCOL
536 if (Status
== EFI_SUCCESS
) {
537 *Ipv6Support
= Nii
->Ipv6Supported
;
542 // Get the NIC handle by SNP protocol.
544 Handle
= NetLibGetSnpHandle (ControllerHandle
, NULL
);
545 if (Handle
== NULL
) {
546 return EFI_NOT_FOUND
;
550 Status
= gBS
->HandleProtocol (
552 &gEfiAdapterInformationProtocolGuid
,
555 if (EFI_ERROR (Status
) || (Aip
== NULL
)) {
556 return EFI_NOT_FOUND
;
559 InfoTypesBuffer
= NULL
;
560 InfoTypeBufferCount
= 0;
561 Status
= Aip
->GetSupportedTypes (Aip
, &InfoTypesBuffer
, &InfoTypeBufferCount
);
562 if (EFI_ERROR (Status
) || (InfoTypesBuffer
== NULL
)) {
563 FreePool (InfoTypesBuffer
);
564 return EFI_NOT_FOUND
;
568 for (TypeIndex
= 0; TypeIndex
< InfoTypeBufferCount
; TypeIndex
++) {
569 if (CompareGuid (&InfoTypesBuffer
[TypeIndex
], &gEfiAdapterInfoUndiIpv6SupportGuid
)) {
575 FreePool (InfoTypesBuffer
);
577 return EFI_NOT_FOUND
;
581 // We now have adapter information block.
585 Status
= Aip
->GetInformation (Aip
, &gEfiAdapterInfoUndiIpv6SupportGuid
, &InfoBlock
, &InfoBlockSize
);
586 if (EFI_ERROR (Status
) || (InfoBlock
== NULL
)) {
587 FreePool (InfoBlock
);
588 return EFI_NOT_FOUND
;
591 *Ipv6Support
= ((EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT
*)InfoBlock
)->Ipv6Support
;
592 FreePool (InfoBlock
);
598 Record the NIC info in global structure.
600 @param[in] Controller The handle of the controller.
601 @param[in] Image Handle of the image.
603 @retval EFI_SUCCESS The operation is completed.
604 @retval EFI_OUT_OF_RESOURCES Do not have sufficient resources to finish this
610 IN EFI_HANDLE Controller
,
615 ISCSI_NIC_INFO
*NicInfo
;
617 EFI_MAC_ADDRESS MacAddr
;
622 // Get MAC address of this network device.
624 Status
= NetLibGetMacAddress (Controller
, &MacAddr
, &HwAddressSize
);
625 if (EFI_ERROR (Status
)) {
630 // Get VLAN ID of this network device.
632 VlanId
= NetLibGetVlanId (Controller
);
635 // Check whether the NIC info already exists. Return directly if so.
637 NET_LIST_FOR_EACH (Entry
, &mPrivate
->NicInfoList
) {
638 NicInfo
= NET_LIST_USER_STRUCT (Entry
, ISCSI_NIC_INFO
, Link
);
639 if ((NicInfo
->HwAddressSize
== HwAddressSize
) &&
640 (CompareMem (&NicInfo
->PermanentAddress
, MacAddr
.Addr
, HwAddressSize
) == 0) &&
641 (NicInfo
->VlanId
== VlanId
))
643 mPrivate
->CurrentNic
= NicInfo
->NicIndex
;
646 // Set IPv6 available flag.
648 Status
= IScsiCheckIpv6Support (Controller
, Image
, &NicInfo
->Ipv6Available
);
649 if (EFI_ERROR (Status
)) {
651 // Fail to get the data whether UNDI supports IPv6.
652 // Set default value to TRUE.
654 NicInfo
->Ipv6Available
= TRUE
;
660 if (mPrivate
->MaxNic
< NicInfo
->NicIndex
) {
661 mPrivate
->MaxNic
= NicInfo
->NicIndex
;
666 // Record the NIC info in private structure.
668 NicInfo
= AllocateZeroPool (sizeof (ISCSI_NIC_INFO
));
669 if (NicInfo
== NULL
) {
670 return EFI_OUT_OF_RESOURCES
;
673 CopyMem (&NicInfo
->PermanentAddress
, MacAddr
.Addr
, HwAddressSize
);
674 NicInfo
->HwAddressSize
= (UINT32
)HwAddressSize
;
675 NicInfo
->VlanId
= VlanId
;
676 NicInfo
->NicIndex
= (UINT8
)(mPrivate
->MaxNic
+ 1);
677 mPrivate
->MaxNic
= NicInfo
->NicIndex
;
680 // Set IPv6 available flag.
682 Status
= IScsiCheckIpv6Support (Controller
, Image
, &NicInfo
->Ipv6Available
);
683 if (EFI_ERROR (Status
)) {
685 // Fail to get the data whether UNDI supports IPv6.
686 // Set default value to TRUE.
688 NicInfo
->Ipv6Available
= TRUE
;
692 // Get the PCI location.
694 IScsiGetNICPciLocation (
697 &NicInfo
->DeviceNumber
,
698 &NicInfo
->FunctionNumber
701 InsertTailList (&mPrivate
->NicInfoList
, &NicInfo
->Link
);
702 mPrivate
->NicCount
++;
704 mPrivate
->CurrentNic
= NicInfo
->NicIndex
;
709 Delete the recorded NIC info from global structure. Also delete corresponding
712 @param[in] Controller The handle of the controller.
714 @retval EFI_SUCCESS The operation is completed.
715 @retval EFI_NOT_FOUND The NIC info to be deleted is not recorded.
720 IN EFI_HANDLE Controller
724 ISCSI_NIC_INFO
*NicInfo
;
726 LIST_ENTRY
*NextEntry
;
727 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
728 ISCSI_NIC_INFO
*ThisNic
;
729 EFI_MAC_ADDRESS MacAddr
;
734 // Get MAC address of this network device.
736 Status
= NetLibGetMacAddress (Controller
, &MacAddr
, &HwAddressSize
);
737 if (EFI_ERROR (Status
)) {
742 // Get VLAN ID of this network device.
744 VlanId
= NetLibGetVlanId (Controller
);
747 // Check whether the NIC information exists.
751 NET_LIST_FOR_EACH (Entry
, &mPrivate
->NicInfoList
) {
752 NicInfo
= NET_LIST_USER_STRUCT (Entry
, ISCSI_NIC_INFO
, Link
);
753 if ((NicInfo
->HwAddressSize
== HwAddressSize
) &&
754 (CompareMem (&NicInfo
->PermanentAddress
, MacAddr
.Addr
, HwAddressSize
) == 0) &&
755 (NicInfo
->VlanId
== VlanId
))
762 if (ThisNic
== NULL
) {
763 return EFI_NOT_FOUND
;
766 mPrivate
->CurrentNic
= ThisNic
->NicIndex
;
768 RemoveEntryList (&ThisNic
->Link
);
770 mPrivate
->NicCount
--;
773 // Remove all attempts related to this NIC.
775 NET_LIST_FOR_EACH_SAFE (Entry
, NextEntry
, &mPrivate
->AttemptConfigs
) {
776 AttemptConfigData
= NET_LIST_USER_STRUCT (Entry
, ISCSI_ATTEMPT_CONFIG_NVDATA
, Link
);
777 if (AttemptConfigData
->NicIndex
== mPrivate
->CurrentNic
) {
778 RemoveEntryList (&AttemptConfigData
->Link
);
779 mPrivate
->AttemptCount
--;
781 if ((AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED_FOR_MPIO
) && (mPrivate
->MpioCount
> 0)) {
782 if (--mPrivate
->MpioCount
== 0) {
783 mPrivate
->EnableMpio
= FALSE
;
786 if ((AttemptConfigData
->AuthenticationType
== ISCSI_AUTH_TYPE_KRB
) && (mPrivate
->Krb5MpioCount
> 0)) {
787 mPrivate
->Krb5MpioCount
--;
789 } else if ((AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED
) && (mPrivate
->SinglePathCount
> 0)) {
790 mPrivate
->SinglePathCount
--;
792 if (mPrivate
->ValidSinglePathCount
> 0) {
793 mPrivate
->ValidSinglePathCount
--;
797 FreePool (AttemptConfigData
);
805 Create and initialize the Attempts.
807 @param[in] AttemptNum The number of Attempts will be created.
809 @retval EFI_SUCCESS The Attempts have been created successfully.
810 @retval Others Failed to create the Attempt.
814 IScsiCreateAttempts (
818 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
819 ISCSI_SESSION_CONFIG_NVDATA
*ConfigData
;
820 UINT8
*AttemptConfigOrder
;
821 UINTN AttemptConfigOrderSize
;
822 UINT8
*AttemptOrderTmp
;
827 for (Index
= 1; Index
<= AttemptNum
; Index
++) {
829 // Get the initialized attempt order. This is used to essure creating attempts by order.
831 AttemptConfigOrder
= IScsiGetVariableAndSize (
832 L
"InitialAttemptOrder",
834 &AttemptConfigOrderSize
836 TotalNumber
= AttemptConfigOrderSize
/ sizeof (UINT8
);
837 if (TotalNumber
== AttemptNum
) {
838 Status
= EFI_SUCCESS
;
845 // Append the new created attempt to the end.
847 AttemptOrderTmp
= AllocateZeroPool (TotalNumber
* sizeof (UINT8
));
848 if (AttemptOrderTmp
== NULL
) {
849 if (AttemptConfigOrder
!= NULL
) {
850 FreePool (AttemptConfigOrder
);
853 return EFI_OUT_OF_RESOURCES
;
856 if (AttemptConfigOrder
!= NULL
) {
857 CopyMem (AttemptOrderTmp
, AttemptConfigOrder
, AttemptConfigOrderSize
);
858 FreePool (AttemptConfigOrder
);
861 AttemptOrderTmp
[TotalNumber
- 1] = Index
;
862 AttemptConfigOrder
= AttemptOrderTmp
;
863 AttemptConfigOrderSize
= TotalNumber
* sizeof (UINT8
);
865 Status
= gRT
->SetVariable (
866 L
"InitialAttemptOrder",
868 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
869 AttemptConfigOrderSize
,
872 FreePool (AttemptConfigOrder
);
873 if (EFI_ERROR (Status
)) {
876 "%a: Failed to set 'InitialAttemptOrder' with Guid (%g): "
886 // Create new Attempt
888 AttemptConfigData
= AllocateZeroPool (sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
));
889 if (AttemptConfigData
== NULL
) {
890 return EFI_OUT_OF_RESOURCES
;
893 ConfigData
= &AttemptConfigData
->SessionConfigData
;
894 ConfigData
->TargetPort
= ISCSI_WELL_KNOWN_PORT
;
895 ConfigData
->ConnectTimeout
= CONNECT_DEFAULT_TIMEOUT
;
896 ConfigData
->ConnectRetryCount
= CONNECT_MIN_RETRY
;
898 AttemptConfigData
->AuthenticationType
= ISCSI_AUTH_TYPE_CHAP
;
899 AttemptConfigData
->AuthConfigData
.CHAP
.CHAPType
= ISCSI_CHAP_UNI
;
901 // Configure the Attempt index and set variable.
903 AttemptConfigData
->AttemptConfigIndex
= Index
;
906 // Set the attempt name according to the order.
909 mPrivate
->PortString
,
910 (UINTN
)ISCSI_NAME_IFR_MAX_SIZE
,
912 (UINTN
)AttemptConfigData
->AttemptConfigIndex
914 UnicodeStrToAsciiStrS (mPrivate
->PortString
, AttemptConfigData
->AttemptName
, ATTEMPT_NAME_SIZE
);
916 Status
= gRT
->SetVariable (
917 mPrivate
->PortString
,
918 &gEfiIScsiInitiatorNameProtocolGuid
,
919 ISCSI_CONFIG_VAR_ATTR
,
920 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
923 FreePool (AttemptConfigData
);
924 if (EFI_ERROR (Status
)) {
927 "%a: Failed to set variable (mPrivate->PortString) with Guid (%g): "
930 &gEfiIScsiInitiatorNameProtocolGuid
,
941 Create the iSCSI configuration Keywords for each attempt. You can find the keywords
942 defined in the "x-UEFI-ns" namespace (http://www.uefi.org/confignamespace).
944 @param[in] KeywordNum The number Sets of Keywords will be created.
946 @retval EFI_SUCCESS The operation is completed.
947 @retval Others Failed to create the Keywords.
951 IScsiCreateKeywords (
955 VOID
*StartOpCodeHandle
;
956 EFI_IFR_GUID_LABEL
*StartLabel
;
957 VOID
*EndOpCodeHandle
;
958 EFI_IFR_GUID_LABEL
*EndLabel
;
960 EFI_STRING_ID StringToken
;
962 CHAR16 KeywordId
[32];
965 Status
= IScsiCreateOpCode (
972 if (EFI_ERROR (Status
)) {
973 return EFI_OUT_OF_RESOURCES
;
976 for (Index
= 1; Index
<= KeywordNum
; Index
++) {
978 // Create iSCSIAttemptName Keyword.
980 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_ATTEMPTT_NAME_PROMPT%d", Index
);
981 StringToken
= HiiSetString (
982 mCallbackInfo
->RegisteredHandle
,
987 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIAttemptName:%d", Index
);
988 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
989 HiiCreateStringOpCode (
991 (EFI_QUESTION_ID
)(ATTEMPT_ATTEMPT_NAME_QUESTION_ID
+ (Index
- 1)),
992 CONFIGURATION_VARSTORE_ID
,
993 (UINT16
)(ATTEMPT_ATTEMPT_NAME_VAR_OFFSET
+ ATTEMPT_NAME_SIZE
* (Index
- 1) * sizeof (CHAR16
)),
996 EFI_IFR_FLAG_READ_ONLY
,
1004 // Create iSCSIBootEnable Keyword.
1006 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_MODE_PROMPT%d", Index
);
1007 StringToken
= HiiSetString (
1008 mCallbackInfo
->RegisteredHandle
,
1013 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIBootEnable:%d", Index
);
1014 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1015 HiiCreateNumericOpCode (
1017 (EFI_QUESTION_ID
)(ATTEMPT_BOOTENABLE_QUESTION_ID
+ (Index
- 1)),
1018 CONFIGURATION_VARSTORE_ID
,
1019 (UINT16
)(ATTEMPT_BOOTENABLE_VAR_OFFSET
+ (Index
- 1)),
1023 EFI_IFR_NUMERIC_SIZE_1
,
1031 // Create iSCSIIpAddressType Keyword.
1033 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_IP_MODE_PROMPT%d", Index
);
1034 StringToken
= HiiSetString (
1035 mCallbackInfo
->RegisteredHandle
,
1040 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIIpAddressType:%d", Index
);
1041 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1042 HiiCreateNumericOpCode (
1044 (EFI_QUESTION_ID
)(ATTEMPT_ADDRESS_TYPE_QUESTION_ID
+ (Index
- 1)),
1045 CONFIGURATION_VARSTORE_ID
,
1046 (UINT16
)(ATTEMPT_ADDRESS_TYPE_VAR_OFFSET
+ (Index
- 1)),
1050 EFI_IFR_NUMERIC_SIZE_1
,
1058 // Create iSCSIConnectRetry Keyword.
1060 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CONNECT_RETRY_PROMPT%d", Index
);
1061 StringToken
= HiiSetString (
1062 mCallbackInfo
->RegisteredHandle
,
1067 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIConnectRetry:%d", Index
);
1068 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1069 HiiCreateNumericOpCode (
1071 (EFI_QUESTION_ID
)(ATTEMPT_CONNECT_RETRY_QUESTION_ID
+ (Index
- 1)),
1072 CONFIGURATION_VARSTORE_ID
,
1073 (UINT16
)(ATTEMPT_CONNECT_RETRY_VAR_OFFSET
+ (Index
- 1)),
1077 EFI_IFR_NUMERIC_SIZE_1
,
1085 // Create iSCSIConnectTimeout Keyword.
1087 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CONNECT_TIMEOUT_PROMPT%d", Index
);
1088 StringToken
= HiiSetString (
1089 mCallbackInfo
->RegisteredHandle
,
1094 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIConnectTimeout:%d", Index
);
1095 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1096 HiiCreateNumericOpCode (
1098 (EFI_QUESTION_ID
)(ATTEMPT_CONNECT_TIMEOUT_QUESTION_ID
+ (Index
- 1)),
1099 CONFIGURATION_VARSTORE_ID
,
1100 (UINT16
)(ATTEMPT_CONNECT_TIMEOUT_VAR_OFFSET
+ 2 * (Index
- 1)),
1104 EFI_IFR_NUMERIC_SIZE_2
,
1105 CONNECT_MIN_TIMEOUT
,
1106 CONNECT_MAX_TIMEOUT
,
1112 // Create ISID Keyword.
1114 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_ISID_PROMPT%d", Index
);
1115 StringToken
= HiiSetString (
1116 mCallbackInfo
->RegisteredHandle
,
1121 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIISID:%d", Index
);
1122 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1123 HiiCreateStringOpCode (
1125 (EFI_QUESTION_ID
)(ATTEMPT_ISID_QUESTION_ID
+ (Index
- 1)),
1126 CONFIGURATION_VARSTORE_ID
,
1127 (UINT16
)(ATTEMPT_ISID_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1129 STRING_TOKEN (STR_ISCSI_ISID_HELP
),
1132 ISID_CONFIGURABLE_MIN_LEN
,
1133 ISID_CONFIGURABLE_STORAGE
,
1138 // Create iSCSIInitiatorInfoViaDHCP Keyword.
1140 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_INITIATOR_VIA_DHCP_PROMPT%d", Index
);
1141 StringToken
= HiiSetString (
1142 mCallbackInfo
->RegisteredHandle
,
1147 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIInitiatorInfoViaDHCP:%d", Index
);
1148 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1149 HiiCreateNumericOpCode (
1151 (EFI_QUESTION_ID
)(ATTEMPT_INITIATOR_VIA_DHCP_QUESTION_ID
+ (Index
- 1)),
1152 CONFIGURATION_VARSTORE_ID
,
1153 (UINT16
)(ATTEMPT_INITIATOR_VIA_DHCP_VAR_OFFSET
+ (Index
- 1)),
1165 // Create iSCSIInitiatorIpAddress Keyword.
1167 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_INITIATOR_IP_ADDRESS_PROMPT%d", Index
);
1168 StringToken
= HiiSetString (
1169 mCallbackInfo
->RegisteredHandle
,
1174 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIInitiatorIpAddress:%d", Index
);
1175 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1176 HiiCreateStringOpCode (
1178 (EFI_QUESTION_ID
)(ATTEMPT_INITIATOR_IP_ADDRESS_QUESTION_ID
+ (Index
- 1)),
1179 CONFIGURATION_VARSTORE_ID
,
1180 (UINT16
)(ATTEMPT_INITIATOR_IP_ADDRESS_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1191 // Create iSCSIInitiatorNetmask Keyword.
1193 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_INITIATOR_NET_MASK_PROMPT%d", Index
);
1194 StringToken
= HiiSetString (
1195 mCallbackInfo
->RegisteredHandle
,
1200 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIInitiatorNetmask:%d", Index
);
1201 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1202 HiiCreateStringOpCode (
1204 (EFI_QUESTION_ID
)(ATTEMPT_INITIATOR_NET_MASK_QUESTION_ID
+ (Index
- 1)),
1205 CONFIGURATION_VARSTORE_ID
,
1206 (UINT16
)(ATTEMPT_INITIATOR_NET_MASK_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1217 // Create iSCSIInitiatorGateway Keyword.
1219 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_INITIATOR_GATE_PROMPT%d", Index
);
1220 StringToken
= HiiSetString (
1221 mCallbackInfo
->RegisteredHandle
,
1226 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIInitiatorGateway:%d", Index
);
1227 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1228 HiiCreateStringOpCode (
1230 (EFI_QUESTION_ID
)(ATTEMPT_INITIATOR_GATE_WAY_QUESTION_ID
+ (Index
- 1)),
1231 CONFIGURATION_VARSTORE_ID
,
1232 (UINT16
)(ATTEMPT_INITIATOR_GATE_WAY_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1243 // Create iSCSITargetInfoViaDHCP Keyword.
1245 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_TARGET_VIA_DHCP_PROMPT%d", Index
);
1246 StringToken
= HiiSetString (
1247 mCallbackInfo
->RegisteredHandle
,
1252 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSITargetInfoViaDHCP:%d", Index
);
1253 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1254 HiiCreateNumericOpCode (
1256 (EFI_QUESTION_ID
)(ATTEMPT_TARGET_VIA_DHCP_QUESTION_ID
+ (Index
- 1)),
1257 CONFIGURATION_VARSTORE_ID
,
1258 (UINT16
)(ATTEMPT_TARGET_VIA_DHCP_VAR_OFFSET
+ (Index
- 1)),
1270 // Create iSCSITargetTcpPort Keyword.
1272 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_TARGET_TCP_PORT_PROMPT%d", Index
);
1273 StringToken
= HiiSetString (
1274 mCallbackInfo
->RegisteredHandle
,
1279 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSITargetTcpPort:%d", Index
);
1280 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1281 HiiCreateNumericOpCode (
1283 (EFI_QUESTION_ID
)(ATTEMPT_TARGET_TCP_PORT_QUESTION_ID
+ (Index
- 1)),
1284 CONFIGURATION_VARSTORE_ID
,
1285 (UINT16
)(ATTEMPT_TARGET_TCP_PORT_VAR_OFFSET
+ 2 * (Index
- 1)),
1289 EFI_IFR_NUMERIC_SIZE_2
,
1290 TARGET_PORT_MIN_NUM
,
1291 TARGET_PORT_MAX_NUM
,
1297 // Create iSCSITargetName Keyword.
1299 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_TARGET_NAME_PROMPT%d", Index
);
1300 StringToken
= HiiSetString (
1301 mCallbackInfo
->RegisteredHandle
,
1306 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSITargetName:%d", Index
);
1307 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1308 HiiCreateStringOpCode (
1310 (EFI_QUESTION_ID
)(ATTEMPT_TARGET_NAME_QUESTION_ID
+ (Index
- 1)),
1311 CONFIGURATION_VARSTORE_ID
,
1312 (UINT16
)(ATTEMPT_TARGET_NAME_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1317 ISCSI_NAME_IFR_MIN_SIZE
,
1318 ISCSI_NAME_IFR_MAX_SIZE
,
1323 // Create iSCSITargetIpAddress Keyword.
1325 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_TARGET_IP_ADDRESS_PROMPT%d", Index
);
1326 StringToken
= HiiSetString (
1327 mCallbackInfo
->RegisteredHandle
,
1332 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSITargetIpAddress:%d", Index
);
1333 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1334 HiiCreateStringOpCode (
1336 (EFI_QUESTION_ID
)(ATTEMPT_TARGET_IP_ADDRESS_QUESTION_ID
+ (Index
- 1)),
1337 CONFIGURATION_VARSTORE_ID
,
1338 (UINT16
)(ATTEMPT_TARGET_IP_ADDRESS_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1349 // Create iSCSILUN Keyword.
1351 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_LUN_PROMPT%d", Index
);
1352 StringToken
= HiiSetString (
1353 mCallbackInfo
->RegisteredHandle
,
1358 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSILUN:%d", Index
);
1359 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1360 HiiCreateStringOpCode (
1362 (EFI_QUESTION_ID
)(ATTEMPT_LUN_QUESTION_ID
+ (Index
- 1)),
1363 CONFIGURATION_VARSTORE_ID
,
1364 (UINT16
)(ATTEMPT_LUN_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1375 // Create iSCSIAuthenticationMethod Keyword.
1377 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_AUTHENTICATION_METHOD_PROMPT%d", Index
);
1378 StringToken
= HiiSetString (
1379 mCallbackInfo
->RegisteredHandle
,
1384 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIAuthenticationMethod:%d", Index
);
1385 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1386 HiiCreateNumericOpCode (
1388 (EFI_QUESTION_ID
)(ATTEMPT_AUTHENTICATION_METHOD_QUESTION_ID
+ (Index
- 1)),
1389 CONFIGURATION_VARSTORE_ID
,
1390 (UINT16
)(ATTEMPT_AUTHENTICATION_METHOD_VAR_OFFSET
+ (Index
- 1)),
1402 // Create iSCSIChapType Keyword.
1404 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHARTYPE_PROMPT%d", Index
);
1405 StringToken
= HiiSetString (
1406 mCallbackInfo
->RegisteredHandle
,
1411 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIChapType:%d", Index
);
1412 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1413 HiiCreateNumericOpCode (
1415 (EFI_QUESTION_ID
)(ATTEMPT_CHARTYPE_QUESTION_ID
+ (Index
- 1)),
1416 CONFIGURATION_VARSTORE_ID
,
1417 (UINT16
)(ATTEMPT_CHARTYPE_VAR_OFFSET
+ (Index
- 1)),
1429 // Create iSCSIChapUsername Keyword.
1431 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHAR_USER_NAME_PROMPT%d", Index
);
1432 StringToken
= HiiSetString (
1433 mCallbackInfo
->RegisteredHandle
,
1438 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIChapUsername:%d", Index
);
1439 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1440 HiiCreateStringOpCode (
1442 (EFI_QUESTION_ID
)(ATTEMPT_CHAR_USER_NAME_QUESTION_ID
+ (Index
- 1)),
1443 CONFIGURATION_VARSTORE_ID
,
1444 (UINT16
)(ATTEMPT_CHAR_USER_NAME_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1450 ISCSI_CHAP_NAME_MAX_LEN
,
1455 // Create iSCSIChapSecret Keyword.
1457 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHAR_SECRET_PROMPT%d", Index
);
1458 StringToken
= HiiSetString (
1459 mCallbackInfo
->RegisteredHandle
,
1464 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIChapSecret:%d", Index
);
1465 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1466 HiiCreateStringOpCode (
1468 (EFI_QUESTION_ID
)(ATTEMPT_CHAR_SECRET_QUESTION_ID
+ (Index
- 1)),
1469 CONFIGURATION_VARSTORE_ID
,
1470 (UINT16
)(ATTEMPT_CHAR_SECRET_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1475 ISCSI_CHAP_SECRET_MIN_LEN
,
1476 ISCSI_CHAP_SECRET_MAX_LEN
,
1481 // Create iSCSIReverseChapUsername Keyword.
1483 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHAR_REVERSE_USER_NAME_PROMPT%d", Index
);
1484 StringToken
= HiiSetString (
1485 mCallbackInfo
->RegisteredHandle
,
1490 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIReverseChapUsername:%d", Index
);
1491 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1492 HiiCreateStringOpCode (
1494 (EFI_QUESTION_ID
)(ATTEMPT_CHAR_REVERSE_USER_NAME_QUESTION_ID
+ (Index
- 1)),
1495 CONFIGURATION_VARSTORE_ID
,
1496 (UINT16
)(ATTEMPT_CHAR_REVERSE_USER_NAME_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1502 ISCSI_CHAP_NAME_MAX_LEN
,
1507 // Create iSCSIReverseChapSecret Keyword.
1509 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHAR_REVERSE_SECRET_PROMPT%d", Index
);
1510 StringToken
= HiiSetString (
1511 mCallbackInfo
->RegisteredHandle
,
1516 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIReverseChapSecret:%d", Index
);
1517 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1518 HiiCreateStringOpCode (
1520 (EFI_QUESTION_ID
)(ATTEMPT_CHAR_REVERSE_SECRET_QUESTION_ID
+ (Index
- 1)),
1521 CONFIGURATION_VARSTORE_ID
,
1522 (UINT16
)(ATTEMPT_CHAR_REVERSE_SECRET_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1527 ISCSI_CHAP_SECRET_MIN_LEN
,
1528 ISCSI_CHAP_SECRET_MAX_LEN
,
1533 Status
= HiiUpdateForm (
1534 mCallbackInfo
->RegisteredHandle
, // HII handle
1535 &gIScsiConfigGuid
, // Formset GUID
1536 FORMID_ATTEMPT_FORM
, // Form ID
1537 StartOpCodeHandle
, // Label for where to insert opcodes
1538 EndOpCodeHandle
// Replace data
1541 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1542 HiiFreeOpCodeHandle (EndOpCodeHandle
);
1549 Free the attempt configure data variable.
1553 IScsiCleanAttemptVariable (
1557 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
1558 UINT8
*AttemptConfigOrder
;
1559 UINTN AttemptConfigOrderSize
;
1563 // Get the initialized attempt order.
1565 AttemptConfigOrder
= IScsiGetVariableAndSize (
1566 L
"InitialAttemptOrder",
1568 &AttemptConfigOrderSize
1570 if ((AttemptConfigOrder
== NULL
) || (AttemptConfigOrderSize
== 0)) {
1574 for (Index
= 1; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
1576 mPrivate
->PortString
,
1577 (UINTN
)ISCSI_NAME_IFR_MAX_SIZE
,
1583 mPrivate
->PortString
,
1584 &gEfiIScsiInitiatorNameProtocolGuid
,
1585 (VOID
**)&AttemptConfigData
,
1589 if (AttemptConfigData
!= NULL
) {
1591 mPrivate
->PortString
,
1592 &gEfiIScsiInitiatorNameProtocolGuid
,
1604 Get the recorded NIC info from global structure by the Index.
1606 @param[in] NicIndex The index indicates the position of NIC info.
1608 @return Pointer to the NIC info, or NULL if not found.
1612 IScsiGetNicInfoByIndex (
1617 ISCSI_NIC_INFO
*NicInfo
;
1619 NET_LIST_FOR_EACH (Entry
, &mPrivate
->NicInfoList
) {
1620 NicInfo
= NET_LIST_USER_STRUCT (Entry
, ISCSI_NIC_INFO
, Link
);
1621 if (NicInfo
->NicIndex
== NicIndex
) {
1630 Get the NIC's PCI location and return it according to the composited
1631 format defined in iSCSI Boot Firmware Table.
1633 @param[in] Controller The handle of the controller.
1634 @param[out] Bus The bus number.
1635 @param[out] Device The device number.
1636 @param[out] Function The function number.
1638 @return The composited representation of the NIC PCI location.
1642 IScsiGetNICPciLocation (
1643 IN EFI_HANDLE Controller
,
1650 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1651 EFI_HANDLE PciIoHandle
;
1652 EFI_PCI_IO_PROTOCOL
*PciIo
;
1655 Status
= gBS
->HandleProtocol (
1657 &gEfiDevicePathProtocolGuid
,
1658 (VOID
**)&DevicePath
1660 if (EFI_ERROR (Status
)) {
1664 Status
= gBS
->LocateDevicePath (
1665 &gEfiPciIoProtocolGuid
,
1669 if (EFI_ERROR (Status
)) {
1673 Status
= gBS
->HandleProtocol (PciIoHandle
, &gEfiPciIoProtocolGuid
, (VOID
**)&PciIo
);
1674 if (EFI_ERROR (Status
)) {
1678 Status
= PciIo
->GetLocation (PciIo
, &Segment
, Bus
, Device
, Function
);
1679 if (EFI_ERROR (Status
)) {
1683 return (UINT16
)((*Bus
<< 8) | (*Device
<< 3) | *Function
);
1687 Read the EFI variable (VendorGuid/Name) and return a dynamically allocated
1688 buffer, and the size of the buffer. If failure, return NULL.
1690 @param[in] Name String part of EFI variable name.
1691 @param[in] VendorGuid GUID part of EFI variable name.
1692 @param[out] VariableSize Returns the size of the EFI variable that was read.
1694 @return Dynamically allocated memory that contains a copy of the EFI variable.
1695 @return Caller is responsible freeing the buffer.
1696 @retval NULL Variable was not read.
1700 IScsiGetVariableAndSize (
1702 IN EFI_GUID
*VendorGuid
,
1703 OUT UINTN
*VariableSize
1713 // Pass in a zero size buffer to find the required buffer size.
1716 Status
= gRT
->GetVariable (Name
, VendorGuid
, NULL
, &BufferSize
, Buffer
);
1717 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1719 // Allocate the buffer to return
1721 Buffer
= AllocateZeroPool (BufferSize
);
1722 if (Buffer
== NULL
) {
1727 // Read variable into the allocated buffer.
1729 Status
= gRT
->GetVariable (Name
, VendorGuid
, NULL
, &BufferSize
, Buffer
);
1730 if (EFI_ERROR (Status
)) {
1735 *VariableSize
= BufferSize
;
1740 Create the iSCSI driver data.
1742 @param[in] Image The handle of the driver image.
1743 @param[in] Controller The handle of the controller.
1745 @return The iSCSI driver data created.
1746 @retval NULL Other errors as indicated.
1750 IScsiCreateDriverData (
1751 IN EFI_HANDLE Image
,
1752 IN EFI_HANDLE Controller
1755 ISCSI_DRIVER_DATA
*Private
;
1758 Private
= AllocateZeroPool (sizeof (ISCSI_DRIVER_DATA
));
1759 if (Private
== NULL
) {
1763 Private
->Signature
= ISCSI_DRIVER_DATA_SIGNATURE
;
1764 Private
->Image
= Image
;
1765 Private
->Controller
= Controller
;
1766 Private
->Session
= NULL
;
1769 // Create an event to be signaled when the BS to RT transition is triggerd so
1770 // as to abort the iSCSI session.
1772 Status
= gBS
->CreateEventEx (
1775 IScsiOnExitBootService
,
1777 &gEfiEventExitBootServicesGuid
,
1778 &Private
->ExitBootServiceEvent
1780 if (EFI_ERROR (Status
)) {
1785 Private
->ExtScsiPassThruHandle
= NULL
;
1786 CopyMem (&Private
->IScsiExtScsiPassThru
, &gIScsiExtScsiPassThruProtocolTemplate
, sizeof (EFI_EXT_SCSI_PASS_THRU_PROTOCOL
));
1789 // 0 is designated to the TargetId, so use another value for the AdapterId.
1791 Private
->ExtScsiPassThruMode
.AdapterId
= 2;
1792 Private
->ExtScsiPassThruMode
.Attributes
= EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL
| EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL
;
1793 Private
->ExtScsiPassThruMode
.IoAlign
= 4;
1794 Private
->IScsiExtScsiPassThru
.Mode
= &Private
->ExtScsiPassThruMode
;
1800 Clean the iSCSI driver data.
1802 @param[in] Private The iSCSI driver data.
1804 @retval EFI_SUCCESS The clean operation is successful.
1805 @retval Others Other errors as indicated.
1809 IScsiCleanDriverData (
1810 IN ISCSI_DRIVER_DATA
*Private
1815 Status
= EFI_SUCCESS
;
1817 if (Private
->DevicePath
!= NULL
) {
1818 Status
= gBS
->UninstallProtocolInterface (
1819 Private
->ExtScsiPassThruHandle
,
1820 &gEfiDevicePathProtocolGuid
,
1823 if (EFI_ERROR (Status
)) {
1827 FreePool (Private
->DevicePath
);
1830 if (Private
->ExtScsiPassThruHandle
!= NULL
) {
1831 Status
= gBS
->UninstallProtocolInterface (
1832 Private
->ExtScsiPassThruHandle
,
1833 &gEfiExtScsiPassThruProtocolGuid
,
1834 &Private
->IScsiExtScsiPassThru
1836 if (!EFI_ERROR (Status
)) {
1837 mPrivate
->OneSessionEstablished
= FALSE
;
1842 if (Private
->ExitBootServiceEvent
!= NULL
) {
1843 gBS
->CloseEvent (Private
->ExitBootServiceEvent
);
1846 mCallbackInfo
->Current
= NULL
;
1853 Check wheather the Controller handle is configured to use DHCP protocol.
1855 @param[in] Controller The handle of the controller.
1856 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
1858 @retval TRUE The handle of the controller need the Dhcp protocol.
1859 @retval FALSE The handle of the controller does not need the Dhcp protocol.
1863 IScsiDhcpIsConfigured (
1864 IN EFI_HANDLE Controller
,
1868 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptTmp
;
1869 UINT8
*AttemptConfigOrder
;
1870 UINTN AttemptConfigOrderSize
;
1873 EFI_MAC_ADDRESS MacAddr
;
1874 UINTN HwAddressSize
;
1876 CHAR16 MacString
[ISCSI_MAX_MAC_STRING_LEN
];
1877 CHAR16 AttemptMacString
[ISCSI_MAX_MAC_STRING_LEN
];
1878 CHAR16 AttemptName
[ISCSI_NAME_IFR_MAX_SIZE
];
1880 AttemptConfigOrder
= IScsiGetVariableAndSize (
1883 &AttemptConfigOrderSize
1885 if ((AttemptConfigOrder
== NULL
) || (AttemptConfigOrderSize
== 0)) {
1890 // Get MAC address of this network device.
1892 Status
= NetLibGetMacAddress (Controller
, &MacAddr
, &HwAddressSize
);
1893 if (EFI_ERROR (Status
)) {
1898 // Get VLAN ID of this network device.
1900 VlanId
= NetLibGetVlanId (Controller
);
1901 IScsiMacAddrToStr (&MacAddr
, (UINT32
)HwAddressSize
, VlanId
, MacString
);
1903 for (Index
= 0; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
1908 (UINTN
)AttemptConfigOrder
[Index
]
1910 Status
= GetVariable2 (
1912 &gEfiIScsiInitiatorNameProtocolGuid
,
1913 (VOID
**)&AttemptTmp
,
1916 if ((AttemptTmp
== NULL
) || EFI_ERROR (Status
)) {
1920 ASSERT (AttemptConfigOrder
[Index
] == AttemptTmp
->AttemptConfigIndex
);
1922 if (AttemptTmp
->SessionConfigData
.Enabled
== ISCSI_DISABLED
) {
1923 FreePool (AttemptTmp
);
1927 if ((AttemptTmp
->SessionConfigData
.IpMode
!= IP_MODE_AUTOCONFIG
) &&
1928 (AttemptTmp
->SessionConfigData
.IpMode
!= ((IpVersion
== IP_VERSION_4
) ? IP_MODE_IP4
: IP_MODE_IP6
)))
1930 FreePool (AttemptTmp
);
1934 AsciiStrToUnicodeStrS (AttemptTmp
->MacString
, AttemptMacString
, sizeof (AttemptMacString
) / sizeof (AttemptMacString
[0]));
1936 if ((AttemptTmp
->Actived
== ISCSI_ACTIVE_DISABLED
) || StrCmp (MacString
, AttemptMacString
)) {
1940 if ((AttemptTmp
->SessionConfigData
.IpMode
== IP_MODE_AUTOCONFIG
) ||
1941 (AttemptTmp
->SessionConfigData
.InitiatorInfoFromDhcp
== TRUE
) ||
1942 (AttemptTmp
->SessionConfigData
.TargetInfoFromDhcp
== TRUE
))
1944 FreePool (AttemptTmp
);
1945 FreePool (AttemptConfigOrder
);
1949 FreePool (AttemptTmp
);
1952 FreePool (AttemptConfigOrder
);
1957 Check whether the Controller handle is configured to use DNS protocol.
1959 @param[in] Controller The handle of the controller.
1961 @retval TRUE The handle of the controller need the Dns protocol.
1962 @retval FALSE The handle of the controller does not need the Dns protocol.
1966 IScsiDnsIsConfigured (
1967 IN EFI_HANDLE Controller
1970 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptTmp
;
1971 UINT8
*AttemptConfigOrder
;
1972 UINTN AttemptConfigOrderSize
;
1975 EFI_MAC_ADDRESS MacAddr
;
1976 UINTN HwAddressSize
;
1978 CHAR16 AttemptMacString
[ISCSI_MAX_MAC_STRING_LEN
];
1979 CHAR16 MacString
[ISCSI_MAX_MAC_STRING_LEN
];
1980 CHAR16 AttemptName
[ISCSI_NAME_IFR_MAX_SIZE
];
1982 AttemptConfigOrder
= IScsiGetVariableAndSize (
1985 &AttemptConfigOrderSize
1987 if ((AttemptConfigOrder
== NULL
) || (AttemptConfigOrderSize
== 0)) {
1992 // Get MAC address of this network device.
1994 Status
= NetLibGetMacAddress (Controller
, &MacAddr
, &HwAddressSize
);
1995 if (EFI_ERROR (Status
)) {
2000 // Get VLAN ID of this network device.
2002 VlanId
= NetLibGetVlanId (Controller
);
2003 IScsiMacAddrToStr (&MacAddr
, (UINT32
)HwAddressSize
, VlanId
, MacString
);
2005 for (Index
= 0; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
2010 (UINTN
)AttemptConfigOrder
[Index
]
2013 Status
= GetVariable2 (
2015 &gEfiIScsiInitiatorNameProtocolGuid
,
2016 (VOID
**)&AttemptTmp
,
2019 if ((AttemptTmp
== NULL
) || EFI_ERROR (Status
)) {
2023 ASSERT (AttemptConfigOrder
[Index
] == AttemptTmp
->AttemptConfigIndex
);
2025 AsciiStrToUnicodeStrS (AttemptTmp
->MacString
, AttemptMacString
, sizeof (AttemptMacString
) / sizeof (AttemptMacString
[0]));
2027 if ((AttemptTmp
->SessionConfigData
.Enabled
== ISCSI_DISABLED
) || StrCmp (MacString
, AttemptMacString
)) {
2028 FreePool (AttemptTmp
);
2032 if (AttemptTmp
->SessionConfigData
.DnsMode
|| AttemptTmp
->SessionConfigData
.TargetInfoFromDhcp
) {
2033 FreePool (AttemptTmp
);
2034 FreePool (AttemptConfigOrder
);
2037 FreePool (AttemptTmp
);
2042 FreePool (AttemptConfigOrder
);
2047 Get the various configuration data.
2049 @param[in] Private The iSCSI driver data.
2051 @retval EFI_SUCCESS The configuration data is retrieved.
2052 @retval EFI_NOT_FOUND This iSCSI driver is not configured yet.
2053 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
2057 IScsiGetConfigData (
2058 IN ISCSI_DRIVER_DATA
*Private
2062 CHAR16 MacString
[ISCSI_MAX_MAC_STRING_LEN
];
2063 CHAR16 AttemptMacString
[ISCSI_MAX_MAC_STRING_LEN
];
2065 ISCSI_NIC_INFO
*NicInfo
;
2066 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
2067 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptTmp
;
2068 UINT8
*AttemptConfigOrder
;
2069 UINTN AttemptConfigOrderSize
;
2070 CHAR16 IScsiMode
[64];
2074 // There should be at least one attempt configured.
2076 AttemptConfigOrder
= IScsiGetVariableAndSize (
2079 &AttemptConfigOrderSize
2081 if ((AttemptConfigOrder
== NULL
) || (AttemptConfigOrderSize
== 0)) {
2082 return EFI_NOT_FOUND
;
2086 // Get the iSCSI Initiator Name.
2088 mPrivate
->InitiatorNameLength
= ISCSI_NAME_MAX_SIZE
;
2089 Status
= gIScsiInitiatorName
.Get (
2090 &gIScsiInitiatorName
,
2091 &mPrivate
->InitiatorNameLength
,
2092 mPrivate
->InitiatorName
2094 if (EFI_ERROR (Status
)) {
2099 // Get the normal configuration.
2101 for (Index
= 0; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
2103 // Check whether the attempt exists in AttemptConfig.
2105 AttemptTmp
= IScsiConfigGetAttemptByConfigIndex (AttemptConfigOrder
[Index
]);
2106 if ((AttemptTmp
!= NULL
) && (AttemptTmp
->SessionConfigData
.Enabled
== ISCSI_DISABLED
)) {
2108 } else if ((AttemptTmp
!= NULL
) && (AttemptTmp
->SessionConfigData
.Enabled
!= ISCSI_DISABLED
)) {
2110 // Check the autoconfig path to see whether it should be retried.
2112 if ((AttemptTmp
->SessionConfigData
.IpMode
== IP_MODE_AUTOCONFIG
) &&
2113 !AttemptTmp
->AutoConfigureSuccess
)
2115 if (mPrivate
->Ipv6Flag
&&
2116 (AttemptTmp
->AutoConfigureMode
== IP_MODE_AUTOCONFIG_IP6
))
2119 // Autoconfigure for IP6 already attempted but failed. Do not try again.
2122 } else if (!mPrivate
->Ipv6Flag
&&
2123 (AttemptTmp
->AutoConfigureMode
== IP_MODE_AUTOCONFIG_IP4
))
2126 // Autoconfigure for IP4 already attempted but failed. Do not try again.
2131 // Try another approach for this autoconfigure path.
2133 AttemptTmp
->AutoConfigureMode
=
2134 (UINT8
)(mPrivate
->Ipv6Flag
? IP_MODE_AUTOCONFIG_IP6
: IP_MODE_AUTOCONFIG_IP4
);
2135 AttemptTmp
->SessionConfigData
.InitiatorInfoFromDhcp
= TRUE
;
2136 AttemptTmp
->SessionConfigData
.TargetInfoFromDhcp
= TRUE
;
2137 AttemptTmp
->DhcpSuccess
= FALSE
;
2140 // Get some information from the dhcp server.
2142 if (!mPrivate
->Ipv6Flag
) {
2143 Status
= IScsiDoDhcp (Private
->Image
, Private
->Controller
, AttemptTmp
);
2144 if (!EFI_ERROR (Status
)) {
2145 AttemptTmp
->DhcpSuccess
= TRUE
;
2148 Status
= IScsiDoDhcp6 (Private
->Image
, Private
->Controller
, AttemptTmp
);
2149 if (!EFI_ERROR (Status
)) {
2150 AttemptTmp
->DhcpSuccess
= TRUE
;
2155 // Refresh the state of this attempt to NVR.
2158 mPrivate
->PortString
,
2159 (UINTN
)ISCSI_NAME_IFR_MAX_SIZE
,
2161 (UINTN
)AttemptTmp
->AttemptConfigIndex
2165 mPrivate
->PortString
,
2166 &gEfiIScsiInitiatorNameProtocolGuid
,
2167 ISCSI_CONFIG_VAR_ATTR
,
2168 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
2174 } else if (AttemptTmp
->SessionConfigData
.InitiatorInfoFromDhcp
&&
2175 !AttemptTmp
->ValidPath
&&
2176 (AttemptTmp
->NicIndex
== mPrivate
->CurrentNic
))
2179 // If the attempt associates with the current NIC, we can
2180 // get DHCP information for already added, but failed, attempt.
2182 AttemptTmp
->DhcpSuccess
= FALSE
;
2183 if (!mPrivate
->Ipv6Flag
&& (AttemptTmp
->SessionConfigData
.IpMode
== IP_MODE_IP4
)) {
2184 Status
= IScsiDoDhcp (Private
->Image
, Private
->Controller
, AttemptTmp
);
2185 if (!EFI_ERROR (Status
)) {
2186 AttemptTmp
->DhcpSuccess
= TRUE
;
2188 } else if (mPrivate
->Ipv6Flag
&& (AttemptTmp
->SessionConfigData
.IpMode
== IP_MODE_IP6
)) {
2189 Status
= IScsiDoDhcp6 (Private
->Image
, Private
->Controller
, AttemptTmp
);
2190 if (!EFI_ERROR (Status
)) {
2191 AttemptTmp
->DhcpSuccess
= TRUE
;
2196 // Refresh the state of this attempt to NVR.
2199 mPrivate
->PortString
,
2200 (UINTN
)ISCSI_NAME_IFR_MAX_SIZE
,
2202 (UINTN
)AttemptTmp
->AttemptConfigIndex
2206 mPrivate
->PortString
,
2207 &gEfiIScsiInitiatorNameProtocolGuid
,
2208 ISCSI_CONFIG_VAR_ATTR
,
2209 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
2220 // This attempt does not exist in AttemptConfig. Try to add a new one.
2223 NicInfo
= IScsiGetNicInfoByIndex (mPrivate
->CurrentNic
);
2224 ASSERT (NicInfo
!= NULL
);
2225 IScsiMacAddrToStr (&NicInfo
->PermanentAddress
, NicInfo
->HwAddressSize
, NicInfo
->VlanId
, MacString
);
2227 mPrivate
->PortString
,
2228 (UINTN
)ISCSI_NAME_IFR_MAX_SIZE
,
2230 (UINTN
)AttemptConfigOrder
[Index
]
2234 mPrivate
->PortString
,
2235 &gEfiIScsiInitiatorNameProtocolGuid
,
2236 (VOID
**)&AttemptConfigData
,
2239 AsciiStrToUnicodeStrS (AttemptConfigData
->MacString
, AttemptMacString
, sizeof (AttemptMacString
) / sizeof (AttemptMacString
[0]));
2241 if ((AttemptConfigData
== NULL
) || (AttemptConfigData
->Actived
== ISCSI_ACTIVE_DISABLED
) ||
2242 StrCmp (MacString
, AttemptMacString
))
2247 ASSERT (AttemptConfigOrder
[Index
] == AttemptConfigData
->AttemptConfigIndex
);
2249 AttemptConfigData
->NicIndex
= NicInfo
->NicIndex
;
2250 AttemptConfigData
->DhcpSuccess
= FALSE
;
2251 AttemptConfigData
->ValidiBFTPath
= (BOOLEAN
)(mPrivate
->EnableMpio
? TRUE
: FALSE
);
2252 AttemptConfigData
->ValidPath
= FALSE
;
2254 if (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_AUTOCONFIG
) {
2255 AttemptConfigData
->SessionConfigData
.InitiatorInfoFromDhcp
= TRUE
;
2256 AttemptConfigData
->SessionConfigData
.TargetInfoFromDhcp
= TRUE
;
2258 AttemptConfigData
->AutoConfigureMode
=
2259 (UINT8
)(mPrivate
->Ipv6Flag
? IP_MODE_AUTOCONFIG_IP6
: IP_MODE_AUTOCONFIG_IP4
);
2260 AttemptConfigData
->AutoConfigureSuccess
= FALSE
;
2264 // Get some information from dhcp server.
2266 if ((AttemptConfigData
->SessionConfigData
.Enabled
!= ISCSI_DISABLED
) &&
2267 AttemptConfigData
->SessionConfigData
.InitiatorInfoFromDhcp
)
2269 if (!mPrivate
->Ipv6Flag
&&
2270 ((AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_IP4
) ||
2271 (AttemptConfigData
->AutoConfigureMode
== IP_MODE_AUTOCONFIG_IP4
)))
2273 Status
= IScsiDoDhcp (Private
->Image
, Private
->Controller
, AttemptConfigData
);
2274 if (!EFI_ERROR (Status
)) {
2275 AttemptConfigData
->DhcpSuccess
= TRUE
;
2277 } else if (mPrivate
->Ipv6Flag
&&
2278 ((AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_IP6
) ||
2279 (AttemptConfigData
->AutoConfigureMode
== IP_MODE_AUTOCONFIG_IP6
)))
2281 Status
= IScsiDoDhcp6 (Private
->Image
, Private
->Controller
, AttemptConfigData
);
2282 if (!EFI_ERROR (Status
)) {
2283 AttemptConfigData
->DhcpSuccess
= TRUE
;
2288 // Refresh the state of this attempt to NVR.
2291 mPrivate
->PortString
,
2292 (UINTN
)ISCSI_NAME_IFR_MAX_SIZE
,
2294 (UINTN
)AttemptConfigData
->AttemptConfigIndex
2298 mPrivate
->PortString
,
2299 &gEfiIScsiInitiatorNameProtocolGuid
,
2300 ISCSI_CONFIG_VAR_ATTR
,
2301 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
2307 // Update Attempt Help Info.
2310 if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_DISABLED
) {
2311 UnicodeSPrint (IScsiMode
, 64, L
"Disabled");
2312 } else if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED
) {
2313 UnicodeSPrint (IScsiMode
, 64, L
"Enabled");
2314 } else if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED_FOR_MPIO
) {
2315 UnicodeSPrint (IScsiMode
, 64, L
"Enabled for MPIO");
2318 if (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_IP4
) {
2319 UnicodeSPrint (IpMode
, 64, L
"IP4");
2320 } else if (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_IP6
) {
2321 UnicodeSPrint (IpMode
, 64, L
"IP6");
2322 } else if (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_AUTOCONFIG
) {
2323 UnicodeSPrint (IpMode
, 64, L
"Autoconfigure");
2327 mPrivate
->PortString
,
2328 (UINTN
)ISCSI_NAME_IFR_MAX_SIZE
,
2329 L
"MAC: %s, PFA: Bus %d | Dev %d | Func %d, iSCSI mode: %s, IP version: %s",
2332 NicInfo
->DeviceNumber
,
2333 NicInfo
->FunctionNumber
,
2338 AttemptConfigData
->AttemptTitleHelpToken
= HiiSetString (
2339 mCallbackInfo
->RegisteredHandle
,
2341 mPrivate
->PortString
,
2344 if (AttemptConfigData
->AttemptTitleHelpToken
== 0) {
2345 return EFI_OUT_OF_RESOURCES
;
2349 // Record the attempt in global link list.
2351 InsertTailList (&mPrivate
->AttemptConfigs
, &AttemptConfigData
->Link
);
2352 mPrivate
->AttemptCount
++;
2354 if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED_FOR_MPIO
) {
2355 mPrivate
->MpioCount
++;
2356 mPrivate
->EnableMpio
= TRUE
;
2358 if (AttemptConfigData
->AuthenticationType
== ISCSI_AUTH_TYPE_KRB
) {
2359 mPrivate
->Krb5MpioCount
++;
2361 } else if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED
) {
2362 mPrivate
->SinglePathCount
++;
2367 // Reorder the AttemptConfig by the configured order.
2369 for (Index
= 0; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
2370 AttemptConfigData
= IScsiConfigGetAttemptByConfigIndex (AttemptConfigOrder
[Index
]);
2371 if (AttemptConfigData
== NULL
) {
2375 RemoveEntryList (&AttemptConfigData
->Link
);
2376 InsertTailList (&mPrivate
->AttemptConfigs
, &AttemptConfigData
->Link
);
2380 // Update the Main Form.
2382 IScsiConfigUpdateAttempt ();
2384 FreePool (AttemptConfigOrder
);
2387 // There should be at least one attempt configuration.
2389 if (!mPrivate
->EnableMpio
) {
2390 if (mPrivate
->SinglePathCount
== 0) {
2391 return EFI_NOT_FOUND
;
2394 mPrivate
->ValidSinglePathCount
= mPrivate
->SinglePathCount
;
2401 Get the device path of the iSCSI tcp connection and update it.
2403 @param Session The iSCSI session.
2405 @return The updated device path.
2406 @retval NULL Other errors as indicated.
2409 EFI_DEVICE_PATH_PROTOCOL
*
2410 IScsiGetTcpConnDevicePath (
2411 IN ISCSI_SESSION
*Session
2414 ISCSI_CONNECTION
*Conn
;
2415 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
2417 EFI_DEV_PATH
*DPathNode
;
2420 if (Session
->State
!= SESSION_STATE_LOGGED_IN
) {
2424 Conn
= NET_LIST_USER_STRUCT_S (
2425 Session
->Conns
.ForwardLink
,
2428 ISCSI_CONNECTION_SIGNATURE
2431 Status
= gBS
->HandleProtocol (
2433 &gEfiDevicePathProtocolGuid
,
2434 (VOID
**)&DevicePath
2436 if (EFI_ERROR (Status
)) {
2443 DevicePath
= DuplicateDevicePath (DevicePath
);
2444 if (DevicePath
== NULL
) {
2448 DPathNode
= (EFI_DEV_PATH
*)DevicePath
;
2450 while (!IsDevicePathEnd (&DPathNode
->DevPath
)) {
2451 if (DevicePathType (&DPathNode
->DevPath
) == MESSAGING_DEVICE_PATH
) {
2452 if (!Conn
->Ipv6Flag
&& (DevicePathSubType (&DPathNode
->DevPath
) == MSG_IPv4_DP
)) {
2453 DPathNode
->Ipv4
.LocalPort
= 0;
2455 DPathNode
->Ipv4
.StaticIpAddress
=
2456 (BOOLEAN
)(!Session
->ConfigData
->SessionConfigData
.InitiatorInfoFromDhcp
);
2459 // Add a judgement here to support previous versions of IPv4_DEVICE_PATH.
2460 // In previous versions of IPv4_DEVICE_PATH, GatewayIpAddress and SubnetMask
2462 // In new version of IPv4_DEVICE_PATH, structure length is 27.
2465 PathLen
= DevicePathNodeLength (&DPathNode
->Ipv4
);
2467 if (PathLen
== IP4_NODE_LEN_NEW_VERSIONS
) {
2469 &DPathNode
->Ipv4
.GatewayIpAddress
,
2470 &Session
->ConfigData
->SessionConfigData
.Gateway
2474 &DPathNode
->Ipv4
.SubnetMask
,
2475 &Session
->ConfigData
->SessionConfigData
.SubnetMask
2480 } else if (Conn
->Ipv6Flag
&& (DevicePathSubType (&DPathNode
->DevPath
) == MSG_IPv6_DP
)) {
2481 DPathNode
->Ipv6
.LocalPort
= 0;
2484 // Add a judgement here to support previous versions of IPv6_DEVICE_PATH.
2485 // In previous versions of IPv6_DEVICE_PATH, IpAddressOrigin, PrefixLength
2486 // and GatewayIpAddress do not exist.
2487 // In new version of IPv6_DEVICE_PATH, structure length is 60, while in
2488 // old versions, the length is 43.
2491 PathLen
= DevicePathNodeLength (&DPathNode
->Ipv6
);
2493 if (PathLen
== IP6_NODE_LEN_NEW_VERSIONS
) {
2494 DPathNode
->Ipv6
.IpAddressOrigin
= 0;
2495 DPathNode
->Ipv6
.PrefixLength
= IP6_PREFIX_LENGTH
;
2496 ZeroMem (&DPathNode
->Ipv6
.GatewayIpAddress
, sizeof (EFI_IPv6_ADDRESS
));
2497 } else if (PathLen
== IP6_NODE_LEN_OLD_VERSIONS
) {
2499 // StaticIPAddress is a field in old versions of IPv6_DEVICE_PATH, while ignored in new
2500 // version. Set StaticIPAddress through its' offset in old IPv6_DEVICE_PATH.
2502 *((UINT8
*)(&DPathNode
->Ipv6
) + IP6_OLD_IPADDRESS_OFFSET
) =
2503 (BOOLEAN
)(!Session
->ConfigData
->SessionConfigData
.InitiatorInfoFromDhcp
);
2510 DPathNode
= (EFI_DEV_PATH
*)NextDevicePathNode (&DPathNode
->DevPath
);
2517 Abort the session when the transition from BS to RT is initiated.
2519 @param[in] Event The event signaled.
2520 @param[in] Context The iSCSI driver data.
2525 IScsiOnExitBootService (
2530 ISCSI_DRIVER_DATA
*Private
;
2532 Private
= (ISCSI_DRIVER_DATA
*)Context
;
2534 gBS
->CloseEvent (Private
->ExitBootServiceEvent
);
2535 Private
->ExitBootServiceEvent
= NULL
;
2537 if (Private
->Session
!= NULL
) {
2538 IScsiSessionAbort (Private
->Session
);
2543 Tests whether a controller handle is being managed by IScsi driver.
2545 This function tests whether the driver specified by DriverBindingHandle is
2546 currently managing the controller specified by ControllerHandle. This test
2547 is performed by evaluating if the protocol specified by ProtocolGuid is
2548 present on ControllerHandle and is was opened by DriverBindingHandle and Nic
2549 Device handle with an attribute of EFI_OPEN_PROTOCOL_BY_DRIVER.
2550 If ProtocolGuid is NULL, then ASSERT().
2552 @param ControllerHandle A handle for a controller to test.
2553 @param DriverBindingHandle Specifies the driver binding handle for the
2555 @param ProtocolGuid Specifies the protocol that the driver specified
2556 by DriverBindingHandle opens in its Start()
2559 @retval EFI_SUCCESS ControllerHandle is managed by the driver
2560 specified by DriverBindingHandle.
2561 @retval EFI_UNSUPPORTED ControllerHandle is not managed by the driver
2562 specified by DriverBindingHandle.
2567 IScsiTestManagedDevice (
2568 IN EFI_HANDLE ControllerHandle
,
2569 IN EFI_HANDLE DriverBindingHandle
,
2570 IN EFI_GUID
*ProtocolGuid
2574 VOID
*ManagedInterface
;
2575 EFI_HANDLE NicControllerHandle
;
2577 ASSERT (ProtocolGuid
!= NULL
);
2579 NicControllerHandle
= NetLibGetNicHandle (ControllerHandle
, ProtocolGuid
);
2580 if (NicControllerHandle
== NULL
) {
2581 return EFI_UNSUPPORTED
;
2584 Status
= gBS
->OpenProtocol (
2586 (EFI_GUID
*)ProtocolGuid
,
2588 DriverBindingHandle
,
2589 NicControllerHandle
,
2590 EFI_OPEN_PROTOCOL_BY_DRIVER
2592 if (!EFI_ERROR (Status
)) {
2593 gBS
->CloseProtocol (
2595 (EFI_GUID
*)ProtocolGuid
,
2596 DriverBindingHandle
,
2599 return EFI_UNSUPPORTED
;
2602 if (Status
!= EFI_ALREADY_STARTED
) {
2603 return EFI_UNSUPPORTED
;