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
++) {
43 if (Pointer2
== Pointer1
) {
44 while (*Pointer1
!= 0) {
49 while (*Pointer1
!= 0) {
50 *Pointer2
= *Pointer1
;
58 for (Pointer1
= Str
+ StrLen(Str
) - 1; Pointer1
>= Str
&& *Pointer1
== CharC
; Pointer1
--) {
61 if (Pointer1
!= Str
+ StrLen(Str
) - 1) {
67 Calculate the prefix length of the IPv4 subnet mask.
69 @param[in] SubnetMask The IPv4 subnet mask.
71 @return The prefix length of the subnet mask.
72 @retval 0 Other errors as indicated.
76 IScsiGetSubnetMaskPrefixLength (
77 IN EFI_IPv4_ADDRESS
*SubnetMask
84 // The SubnetMask is in network byte order.
86 ReverseMask
= (SubnetMask
->Addr
[0] << 24) | (SubnetMask
->Addr
[1] << 16) | (SubnetMask
->Addr
[2] << 8) | (SubnetMask
->Addr
[3]);
91 ReverseMask
= ~ReverseMask
;
93 if ((ReverseMask
& (ReverseMask
+ 1)) != 0) {
99 while (ReverseMask
!= 0) {
100 ReverseMask
= ReverseMask
>> 1;
104 return (UINT8
) (32 - Len
);
109 Convert the hexadecimal encoded LUN string into the 64-bit LUN.
111 @param[in] Str The hexadecimal encoded LUN string.
112 @param[out] Lun Storage to return the 64-bit LUN.
114 @retval EFI_SUCCESS The 64-bit LUN is stored in Lun.
115 @retval EFI_INVALID_PARAMETER The string is malformatted.
124 UINTN Index
, IndexValue
, IndexNum
, SizeStr
;
131 ZeroMem ((UINT8
*) Value
, sizeof (Value
));
132 SizeStr
= AsciiStrLen (Str
);
136 for (Index
= 0; Index
< SizeStr
; Index
++) {
137 TemStr
[0] = Str
[Index
];
138 TemValue
= (UINT8
) AsciiStrHexToUint64 (TemStr
);
139 if (TemValue
== 0 && TemStr
[0] != '0') {
140 if ((TemStr
[0] != '-') || (IndexNum
== 0)) {
144 return EFI_INVALID_PARAMETER
;
148 if ((TemValue
== 0) && (TemStr
[0] == '-')) {
152 if (++IndexValue
>= 4) {
156 return EFI_INVALID_PARAMETER
;
159 // Restart str index for the next lun value.
165 if (++IndexNum
> 4) {
167 // Each Lun Str can't exceed size 4, because it will be as UINT16 value.
169 return EFI_INVALID_PARAMETER
;
173 // Combine UINT16 value.
175 Value
[IndexValue
] = (UINT16
) ((Value
[IndexValue
] << 4) + TemValue
);
178 for (Index
= 0; Index
<= IndexValue
; Index
++) {
179 *((UINT16
*) &Lun
[Index
* 2]) = HTONS (Value
[Index
]);
186 Convert the 64-bit LUN into the hexadecimal encoded LUN string.
188 @param[in] Lun The 64-bit LUN.
189 @param[out] Str The storage to return the hexadecimal encoded LUN string.
193 IScsiLunToUnicodeStr (
203 for (Index
= 0; Index
< 4; Index
++) {
205 if ((Lun
[2 * Index
] | Lun
[2 * Index
+ 1]) == 0) {
206 CopyMem (TempStr
, L
"0-", sizeof (L
"0-"));
208 TempStr
[0] = (CHAR16
) IScsiHexString
[Lun
[2 * Index
] >> 4];
209 TempStr
[1] = (CHAR16
) IScsiHexString
[Lun
[2 * Index
] & 0x0F];
210 TempStr
[2] = (CHAR16
) IScsiHexString
[Lun
[2 * Index
+ 1] >> 4];
211 TempStr
[3] = (CHAR16
) IScsiHexString
[Lun
[2 * Index
+ 1] & 0x0F];
215 IScsiStrTrim (TempStr
, L
'0');
218 TempStr
+= StrLen (TempStr
);
221 // Remove the last '-'
223 ASSERT (StrLen(Str
) >= 1);
224 Str
[StrLen (Str
) - 1] = 0;
226 for (Index
= StrLen (Str
) - 1; Index
> 1; Index
= Index
- 2) {
227 if ((Str
[Index
] == L
'0') && (Str
[Index
- 1] == L
'-')) {
236 Convert the formatted IP address into the binary IP address.
238 @param[in] Str The UNICODE string.
239 @param[in] IpMode Indicates whether the IP address is v4 or v6.
240 @param[out] Ip The storage to return the ASCII string.
242 @retval EFI_SUCCESS The binary IP address is returned in Ip.
243 @retval EFI_INVALID_PARAMETER The IP string is malformatted or IpMode is
251 OUT EFI_IP_ADDRESS
*Ip
256 if (IpMode
== IP_MODE_IP4
|| IpMode
== IP_MODE_AUTOCONFIG_IP4
) {
257 return NetLibAsciiStrToIp4 (Str
, &Ip
->v4
);
259 } else if (IpMode
== IP_MODE_IP6
|| IpMode
== IP_MODE_AUTOCONFIG_IP6
) {
260 return NetLibAsciiStrToIp6 (Str
, &Ip
->v6
);
262 } else if (IpMode
== IP_MODE_AUTOCONFIG
) {
263 Status
= NetLibAsciiStrToIp4 (Str
, &Ip
->v4
);
264 if (!EFI_ERROR (Status
)) {
267 return NetLibAsciiStrToIp6 (Str
, &Ip
->v6
);
271 return EFI_INVALID_PARAMETER
;
275 Convert the mac address into a hexadecimal encoded "-" separated string.
277 @param[in] Mac The mac address.
278 @param[in] Len Length in bytes of the mac address.
279 @param[in] VlanId VLAN ID of the network device.
280 @param[out] Str The storage to return the mac string.
285 IN EFI_MAC_ADDRESS
*Mac
,
294 for (Index
= 0; Index
< Len
; Index
++) {
295 Str
[3 * Index
] = (CHAR16
) IScsiHexString
[(Mac
->Addr
[Index
] >> 4) & 0x0F];
296 Str
[3 * Index
+ 1] = (CHAR16
) IScsiHexString
[Mac
->Addr
[Index
] & 0x0F];
297 Str
[3 * Index
+ 2] = L
':';
300 String
= &Str
[3 * Index
- 1] ;
302 String
+= UnicodeSPrint (String
, 6 * sizeof (CHAR16
), L
"\\%04x", (UINTN
) VlanId
);
309 Convert the binary encoded buffer into a hexadecimal encoded string.
311 @param[in] BinBuffer The buffer containing the binary data.
312 @param[in] BinLength Length of the binary buffer.
313 @param[in, out] HexStr Pointer to the string.
314 @param[in, out] HexLength The length of the string.
316 @retval EFI_SUCCESS The binary data is converted to the hexadecimal string
317 and the length of the string is updated.
318 @retval EFI_BUFFER_TOO_SMALL The string is too small.
319 @retval EFI_BAD_BUFFER_SIZE BinLength is too large for hex encoding.
320 @retval EFI_INVALID_PARAMETER The IP string is malformatted.
327 IN OUT CHAR8
*HexStr
,
328 IN OUT UINT32
*HexLength
332 UINT32 HexLengthProvided
;
335 if ((HexStr
== NULL
) || (BinBuffer
== NULL
) || (BinLength
== 0)) {
336 return EFI_INVALID_PARAMETER
;
340 // Safely calculate: HexLengthMin := BinLength * 2 + 3.
342 if (RETURN_ERROR (SafeUint32Mult (BinLength
, 2, &HexLengthMin
)) ||
343 RETURN_ERROR (SafeUint32Add (HexLengthMin
, 3, &HexLengthMin
))) {
344 return EFI_BAD_BUFFER_SIZE
;
347 HexLengthProvided
= *HexLength
;
348 *HexLength
= HexLengthMin
;
349 if (HexLengthProvided
< HexLengthMin
) {
350 return EFI_BUFFER_TOO_SMALL
;
354 // Prefix for Hex String.
359 for (Index
= 0; Index
< BinLength
; Index
++) {
360 HexStr
[Index
* 2 + 2] = IScsiHexString
[BinBuffer
[Index
] >> 4];
361 HexStr
[Index
* 2 + 3] = IScsiHexString
[BinBuffer
[Index
] & 0xf];
364 HexStr
[Index
* 2 + 2] = '\0';
371 Convert the hexadecimal string into a binary encoded buffer.
373 @param[in, out] BinBuffer The binary buffer.
374 @param[in, out] BinLength Length of the binary buffer.
375 @param[in] HexStr The hexadecimal string.
377 @retval EFI_SUCCESS The hexadecimal string is converted into a
378 binary encoded buffer.
379 @retval EFI_INVALID_PARAMETER Invalid hex encoding found in HexStr.
380 @retval EFI_BAD_BUFFER_SIZE The length of HexStr is too large for decoding:
381 the decoded size cannot be expressed in
383 @retval EFI_BUFFER_TOO_SMALL The binary buffer is too small to hold the
388 IN OUT UINT8
*BinBuffer
,
389 IN OUT UINT32
*BinLength
,
394 UINT32 BinLengthProvided
;
400 ZeroMem (TemStr
, sizeof (TemStr
));
403 // Find out how many hex characters the string has.
405 if ((HexStr
[0] == '0') && ((HexStr
[1] == 'x') || (HexStr
[1] == 'X'))) {
409 Length
= AsciiStrLen (HexStr
);
412 // Reject an empty hex string; reject a stray nibble.
414 if (Length
== 0 || Length
% 2 != 0) {
415 return EFI_INVALID_PARAMETER
;
418 // Check if the caller provides enough room for the decoded blob.
420 BinLengthMin
= Length
/ 2;
421 if (BinLengthMin
> MAX_UINT32
) {
422 return EFI_BAD_BUFFER_SIZE
;
424 BinLengthProvided
= *BinLength
;
425 *BinLength
= (UINT32
)BinLengthMin
;
426 if (BinLengthProvided
< BinLengthMin
) {
427 return EFI_BUFFER_TOO_SMALL
;
430 for (Index
= 0; Index
< Length
; Index
++) {
431 TemStr
[0] = HexStr
[Index
];
432 Digit
= (UINT8
) AsciiStrHexToUint64 (TemStr
);
433 if (Digit
== 0 && TemStr
[0] != '0') {
437 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
);
473 Generate random numbers.
475 @param[in, out] Rand The buffer to contain random numbers.
476 @param[in] RandLength The length of the Rand buffer.
487 while (RandLength
> 0) {
488 Random
= NET_RANDOM (NetRandomInitSeed ());
489 *Rand
++ = (UINT8
) (Random
);
496 Check whether UNDI protocol supports IPv6.
498 @param[in] ControllerHandle Controller handle.
499 @param[in] Image Handle of the image.
500 @param[out] Ipv6Support TRUE if UNDI supports IPv6.
502 @retval EFI_SUCCESS Get the result whether UNDI supports IPv6 by NII or AIP protocol successfully.
503 @retval EFI_NOT_FOUND Don't know whether UNDI supports IPv6 since NII or AIP is not available.
507 IScsiCheckIpv6Support (
508 IN EFI_HANDLE ControllerHandle
,
510 OUT BOOLEAN
*Ipv6Support
514 EFI_ADAPTER_INFORMATION_PROTOCOL
*Aip
;
516 EFI_GUID
*InfoTypesBuffer
;
517 UINTN InfoTypeBufferCount
;
523 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL
*Nii
;
525 ASSERT (Ipv6Support
!= NULL
);
528 // Check whether the UNDI supports IPv6 by NII protocol.
530 Status
= gBS
->OpenProtocol (
532 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
536 EFI_OPEN_PROTOCOL_GET_PROTOCOL
538 if (Status
== EFI_SUCCESS
) {
539 *Ipv6Support
= Nii
->Ipv6Supported
;
544 // Get the NIC handle by SNP protocol.
546 Handle
= NetLibGetSnpHandle (ControllerHandle
, NULL
);
547 if (Handle
== NULL
) {
548 return EFI_NOT_FOUND
;
552 Status
= gBS
->HandleProtocol (
554 &gEfiAdapterInformationProtocolGuid
,
557 if (EFI_ERROR (Status
) || Aip
== NULL
) {
558 return EFI_NOT_FOUND
;
561 InfoTypesBuffer
= NULL
;
562 InfoTypeBufferCount
= 0;
563 Status
= Aip
->GetSupportedTypes (Aip
, &InfoTypesBuffer
, &InfoTypeBufferCount
);
564 if (EFI_ERROR (Status
) || InfoTypesBuffer
== NULL
) {
565 FreePool (InfoTypesBuffer
);
566 return EFI_NOT_FOUND
;
570 for (TypeIndex
= 0; TypeIndex
< InfoTypeBufferCount
; TypeIndex
++) {
571 if (CompareGuid (&InfoTypesBuffer
[TypeIndex
], &gEfiAdapterInfoUndiIpv6SupportGuid
)) {
577 FreePool (InfoTypesBuffer
);
579 return EFI_NOT_FOUND
;
583 // We now have adapter information block.
587 Status
= Aip
->GetInformation (Aip
, &gEfiAdapterInfoUndiIpv6SupportGuid
, &InfoBlock
, &InfoBlockSize
);
588 if (EFI_ERROR (Status
) || InfoBlock
== NULL
) {
589 FreePool (InfoBlock
);
590 return EFI_NOT_FOUND
;
593 *Ipv6Support
= ((EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT
*) InfoBlock
)->Ipv6Support
;
594 FreePool (InfoBlock
);
600 Record the NIC info in global structure.
602 @param[in] Controller The handle of the controller.
603 @param[in] Image Handle of the image.
605 @retval EFI_SUCCESS The operation is completed.
606 @retval EFI_OUT_OF_RESOURCES Do not have sufficient resources to finish this
612 IN EFI_HANDLE Controller
,
617 ISCSI_NIC_INFO
*NicInfo
;
619 EFI_MAC_ADDRESS MacAddr
;
624 // Get MAC address of this network device.
626 Status
= NetLibGetMacAddress (Controller
, &MacAddr
, &HwAddressSize
);
627 if (EFI_ERROR (Status
)) {
632 // Get VLAN ID of this network device.
634 VlanId
= NetLibGetVlanId (Controller
);
637 // Check whether the NIC info already exists. Return directly if so.
639 NET_LIST_FOR_EACH (Entry
, &mPrivate
->NicInfoList
) {
640 NicInfo
= NET_LIST_USER_STRUCT (Entry
, ISCSI_NIC_INFO
, Link
);
641 if (NicInfo
->HwAddressSize
== HwAddressSize
&&
642 CompareMem (&NicInfo
->PermanentAddress
, MacAddr
.Addr
, HwAddressSize
) == 0 &&
643 NicInfo
->VlanId
== VlanId
) {
644 mPrivate
->CurrentNic
= NicInfo
->NicIndex
;
647 // Set IPv6 available flag.
649 Status
= IScsiCheckIpv6Support (Controller
, Image
, &NicInfo
->Ipv6Available
);
650 if (EFI_ERROR (Status
)) {
652 // Fail to get the data whether UNDI supports IPv6.
653 // Set default value to TRUE.
655 NicInfo
->Ipv6Available
= TRUE
;
661 if (mPrivate
->MaxNic
< NicInfo
->NicIndex
) {
662 mPrivate
->MaxNic
= NicInfo
->NicIndex
;
667 // Record the NIC info in private structure.
669 NicInfo
= AllocateZeroPool (sizeof (ISCSI_NIC_INFO
));
670 if (NicInfo
== NULL
) {
671 return EFI_OUT_OF_RESOURCES
;
674 CopyMem (&NicInfo
->PermanentAddress
, MacAddr
.Addr
, HwAddressSize
);
675 NicInfo
->HwAddressSize
= (UINT32
) HwAddressSize
;
676 NicInfo
->VlanId
= VlanId
;
677 NicInfo
->NicIndex
= (UINT8
) (mPrivate
->MaxNic
+ 1);
678 mPrivate
->MaxNic
= NicInfo
->NicIndex
;
681 // Set IPv6 available flag.
683 Status
= IScsiCheckIpv6Support (Controller
, Image
, &NicInfo
->Ipv6Available
);
684 if (EFI_ERROR (Status
)) {
686 // Fail to get the data whether UNDI supports IPv6.
687 // Set default value to TRUE.
689 NicInfo
->Ipv6Available
= TRUE
;
693 // Get the PCI location.
695 IScsiGetNICPciLocation (
698 &NicInfo
->DeviceNumber
,
699 &NicInfo
->FunctionNumber
702 InsertTailList (&mPrivate
->NicInfoList
, &NicInfo
->Link
);
703 mPrivate
->NicCount
++;
705 mPrivate
->CurrentNic
= NicInfo
->NicIndex
;
711 Delete the recorded NIC info from global structure. Also delete corresponding
714 @param[in] Controller The handle of the controller.
716 @retval EFI_SUCCESS The operation is completed.
717 @retval EFI_NOT_FOUND The NIC info to be deleted is not recorded.
722 IN EFI_HANDLE Controller
726 ISCSI_NIC_INFO
*NicInfo
;
728 LIST_ENTRY
*NextEntry
;
729 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
730 ISCSI_NIC_INFO
*ThisNic
;
731 EFI_MAC_ADDRESS MacAddr
;
736 // Get MAC address of this network device.
738 Status
= NetLibGetMacAddress (Controller
, &MacAddr
, &HwAddressSize
);
739 if (EFI_ERROR (Status
)) {
744 // Get VLAN ID of this network device.
746 VlanId
= NetLibGetVlanId (Controller
);
749 // Check whether the NIC information exists.
753 NET_LIST_FOR_EACH (Entry
, &mPrivate
->NicInfoList
) {
754 NicInfo
= NET_LIST_USER_STRUCT (Entry
, ISCSI_NIC_INFO
, Link
);
755 if (NicInfo
->HwAddressSize
== HwAddressSize
&&
756 CompareMem (&NicInfo
->PermanentAddress
, MacAddr
.Addr
, HwAddressSize
) == 0 &&
757 NicInfo
->VlanId
== VlanId
) {
764 if (ThisNic
== NULL
) {
765 return EFI_NOT_FOUND
;
768 mPrivate
->CurrentNic
= ThisNic
->NicIndex
;
770 RemoveEntryList (&ThisNic
->Link
);
772 mPrivate
->NicCount
--;
775 // Remove all attempts related to this NIC.
777 NET_LIST_FOR_EACH_SAFE (Entry
, NextEntry
, &mPrivate
->AttemptConfigs
) {
778 AttemptConfigData
= NET_LIST_USER_STRUCT (Entry
, ISCSI_ATTEMPT_CONFIG_NVDATA
, Link
);
779 if (AttemptConfigData
->NicIndex
== mPrivate
->CurrentNic
) {
780 RemoveEntryList (&AttemptConfigData
->Link
);
781 mPrivate
->AttemptCount
--;
783 if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED_FOR_MPIO
&& mPrivate
->MpioCount
> 0) {
784 if (--mPrivate
->MpioCount
== 0) {
785 mPrivate
->EnableMpio
= FALSE
;
788 if (AttemptConfigData
->AuthenticationType
== ISCSI_AUTH_TYPE_KRB
&& mPrivate
->Krb5MpioCount
> 0) {
789 mPrivate
->Krb5MpioCount
--;
792 } else if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED
&& mPrivate
->SinglePathCount
> 0) {
793 mPrivate
->SinglePathCount
--;
795 if (mPrivate
->ValidSinglePathCount
> 0) {
796 mPrivate
->ValidSinglePathCount
--;
800 FreePool (AttemptConfigData
);
808 Create and initialize the Attempts.
810 @param[in] AttemptNum The number of Attempts will be created.
812 @retval EFI_SUCCESS The Attempts have been created successfully.
813 @retval Others Failed to create the Attempt.
817 IScsiCreateAttempts (
821 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
822 ISCSI_SESSION_CONFIG_NVDATA
*ConfigData
;
823 UINT8
*AttemptConfigOrder
;
824 UINTN AttemptConfigOrderSize
;
825 UINT8
*AttemptOrderTmp
;
830 for (Index
= 1; Index
<= AttemptNum
; Index
++) {
832 // Get the initialized attempt order. This is used to essure creating attempts by order.
834 AttemptConfigOrder
= IScsiGetVariableAndSize (
835 L
"InitialAttemptOrder",
837 &AttemptConfigOrderSize
839 TotalNumber
= AttemptConfigOrderSize
/ sizeof (UINT8
);
840 if (TotalNumber
== AttemptNum
) {
841 Status
= EFI_SUCCESS
;
847 // Append the new created attempt to the end.
849 AttemptOrderTmp
= AllocateZeroPool (TotalNumber
* sizeof (UINT8
));
850 if (AttemptOrderTmp
== NULL
) {
851 if (AttemptConfigOrder
!= NULL
) {
852 FreePool (AttemptConfigOrder
);
854 return EFI_OUT_OF_RESOURCES
;
857 if (AttemptConfigOrder
!= NULL
) {
858 CopyMem (AttemptOrderTmp
, AttemptConfigOrder
, AttemptConfigOrderSize
);
859 FreePool (AttemptConfigOrder
);
862 AttemptOrderTmp
[TotalNumber
- 1] = Index
;
863 AttemptConfigOrder
= AttemptOrderTmp
;
864 AttemptConfigOrderSize
= TotalNumber
* sizeof (UINT8
);
866 Status
= gRT
->SetVariable (
867 L
"InitialAttemptOrder",
869 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
870 AttemptConfigOrderSize
,
873 FreePool (AttemptConfigOrder
);
874 if (EFI_ERROR (Status
)) {
876 "%a: Failed to set 'InitialAttemptOrder' with Guid (%g): "
878 __FUNCTION__
, &gIScsiConfigGuid
, Status
));
883 // Create new Attempt
885 AttemptConfigData
= AllocateZeroPool (sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
));
886 if (AttemptConfigData
== NULL
) {
887 return EFI_OUT_OF_RESOURCES
;
889 ConfigData
= &AttemptConfigData
->SessionConfigData
;
890 ConfigData
->TargetPort
= ISCSI_WELL_KNOWN_PORT
;
891 ConfigData
->ConnectTimeout
= CONNECT_DEFAULT_TIMEOUT
;
892 ConfigData
->ConnectRetryCount
= CONNECT_MIN_RETRY
;
894 AttemptConfigData
->AuthenticationType
= ISCSI_AUTH_TYPE_CHAP
;
895 AttemptConfigData
->AuthConfigData
.CHAP
.CHAPType
= ISCSI_CHAP_UNI
;
897 // Configure the Attempt index and set variable.
899 AttemptConfigData
->AttemptConfigIndex
= Index
;
902 // Set the attempt name according to the order.
905 mPrivate
->PortString
,
906 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
908 (UINTN
) AttemptConfigData
->AttemptConfigIndex
910 UnicodeStrToAsciiStrS (mPrivate
->PortString
, AttemptConfigData
->AttemptName
, ATTEMPT_NAME_SIZE
);
912 Status
= gRT
->SetVariable (
913 mPrivate
->PortString
,
914 &gEfiIScsiInitiatorNameProtocolGuid
,
915 ISCSI_CONFIG_VAR_ATTR
,
916 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
919 FreePool (AttemptConfigData
);
920 if (EFI_ERROR (Status
)) {
922 "%a: Failed to set variable (mPrivate->PortString) with Guid (%g): "
924 __FUNCTION__
, &gEfiIScsiInitiatorNameProtocolGuid
, Status
));
933 Create the iSCSI configuration Keywords for each attempt. You can find the keywords
934 defined in the "x-UEFI-ns" namespace (http://www.uefi.org/confignamespace).
936 @param[in] KeywordNum The number Sets of Keywords will be created.
938 @retval EFI_SUCCESS The operation is completed.
939 @retval Others Failed to create the Keywords.
943 IScsiCreateKeywords (
947 VOID
*StartOpCodeHandle
;
948 EFI_IFR_GUID_LABEL
*StartLabel
;
949 VOID
*EndOpCodeHandle
;
950 EFI_IFR_GUID_LABEL
*EndLabel
;
952 EFI_STRING_ID StringToken
;
954 CHAR16 KeywordId
[32];
957 Status
= IScsiCreateOpCode (
964 if (EFI_ERROR (Status
)) {
965 return EFI_OUT_OF_RESOURCES
;
968 for (Index
= 1; Index
<= KeywordNum
; Index
++) {
970 // Create iSCSIAttemptName Keyword.
972 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_ATTEMPTT_NAME_PROMPT%d", Index
);
973 StringToken
= HiiSetString (
974 mCallbackInfo
->RegisteredHandle
,
979 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIAttemptName:%d", Index
);
980 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
981 HiiCreateStringOpCode (
983 (EFI_QUESTION_ID
) (ATTEMPT_ATTEMPT_NAME_QUESTION_ID
+ (Index
- 1)),
984 CONFIGURATION_VARSTORE_ID
,
985 (UINT16
) (ATTEMPT_ATTEMPT_NAME_VAR_OFFSET
+ ATTEMPT_NAME_SIZE
* (Index
- 1) * sizeof (CHAR16
)),
988 EFI_IFR_FLAG_READ_ONLY
,
996 // Create iSCSIBootEnable Keyword.
998 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_MODE_PROMPT%d", Index
);
999 StringToken
= HiiSetString (
1000 mCallbackInfo
->RegisteredHandle
,
1005 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIBootEnable:%d", Index
);
1006 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1007 HiiCreateNumericOpCode (
1009 (EFI_QUESTION_ID
) (ATTEMPT_BOOTENABLE_QUESTION_ID
+ (Index
- 1)),
1010 CONFIGURATION_VARSTORE_ID
,
1011 (UINT16
) (ATTEMPT_BOOTENABLE_VAR_OFFSET
+ (Index
- 1)),
1015 EFI_IFR_NUMERIC_SIZE_1
,
1023 // Create iSCSIIpAddressType Keyword.
1025 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_IP_MODE_PROMPT%d", Index
);
1026 StringToken
= HiiSetString (
1027 mCallbackInfo
->RegisteredHandle
,
1032 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIIpAddressType:%d", Index
);
1033 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1034 HiiCreateNumericOpCode (
1036 (EFI_QUESTION_ID
) (ATTEMPT_ADDRESS_TYPE_QUESTION_ID
+ (Index
- 1)),
1037 CONFIGURATION_VARSTORE_ID
,
1038 (UINT16
) (ATTEMPT_ADDRESS_TYPE_VAR_OFFSET
+ (Index
- 1)),
1042 EFI_IFR_NUMERIC_SIZE_1
,
1050 // Create iSCSIConnectRetry Keyword.
1052 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CONNECT_RETRY_PROMPT%d", Index
);
1053 StringToken
= HiiSetString (
1054 mCallbackInfo
->RegisteredHandle
,
1059 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIConnectRetry:%d", Index
);
1060 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1061 HiiCreateNumericOpCode (
1063 (EFI_QUESTION_ID
) (ATTEMPT_CONNECT_RETRY_QUESTION_ID
+ (Index
- 1)),
1064 CONFIGURATION_VARSTORE_ID
,
1065 (UINT16
) (ATTEMPT_CONNECT_RETRY_VAR_OFFSET
+ (Index
- 1)),
1069 EFI_IFR_NUMERIC_SIZE_1
,
1077 // Create iSCSIConnectTimeout Keyword.
1079 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CONNECT_TIMEOUT_PROMPT%d", Index
);
1080 StringToken
= HiiSetString (
1081 mCallbackInfo
->RegisteredHandle
,
1086 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIConnectTimeout:%d", Index
);
1087 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1088 HiiCreateNumericOpCode (
1090 (EFI_QUESTION_ID
) (ATTEMPT_CONNECT_TIMEOUT_QUESTION_ID
+ (Index
- 1)),
1091 CONFIGURATION_VARSTORE_ID
,
1092 (UINT16
) (ATTEMPT_CONNECT_TIMEOUT_VAR_OFFSET
+ 2 * (Index
- 1)),
1096 EFI_IFR_NUMERIC_SIZE_2
,
1097 CONNECT_MIN_TIMEOUT
,
1098 CONNECT_MAX_TIMEOUT
,
1104 // Create ISID Keyword.
1106 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_ISID_PROMPT%d", Index
);
1107 StringToken
= HiiSetString (
1108 mCallbackInfo
->RegisteredHandle
,
1113 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIISID:%d", Index
);
1114 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1115 HiiCreateStringOpCode (
1117 (EFI_QUESTION_ID
) (ATTEMPT_ISID_QUESTION_ID
+ (Index
- 1)),
1118 CONFIGURATION_VARSTORE_ID
,
1119 (UINT16
) (ATTEMPT_ISID_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1121 STRING_TOKEN (STR_ISCSI_ISID_HELP
),
1124 ISID_CONFIGURABLE_MIN_LEN
,
1125 ISID_CONFIGURABLE_STORAGE
,
1130 // Create iSCSIInitiatorInfoViaDHCP Keyword.
1132 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_INITIATOR_VIA_DHCP_PROMPT%d", Index
);
1133 StringToken
= HiiSetString (
1134 mCallbackInfo
->RegisteredHandle
,
1139 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIInitiatorInfoViaDHCP:%d", Index
);
1140 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1141 HiiCreateNumericOpCode (
1143 (EFI_QUESTION_ID
) (ATTEMPT_INITIATOR_VIA_DHCP_QUESTION_ID
+ (Index
- 1)),
1144 CONFIGURATION_VARSTORE_ID
,
1145 (UINT16
) (ATTEMPT_INITIATOR_VIA_DHCP_VAR_OFFSET
+ (Index
- 1)),
1157 // Create iSCSIInitiatorIpAddress Keyword.
1159 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_INITIATOR_IP_ADDRESS_PROMPT%d", Index
);
1160 StringToken
= HiiSetString (
1161 mCallbackInfo
->RegisteredHandle
,
1166 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIInitiatorIpAddress:%d", Index
);
1167 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1168 HiiCreateStringOpCode (
1170 (EFI_QUESTION_ID
) (ATTEMPT_INITIATOR_IP_ADDRESS_QUESTION_ID
+ (Index
- 1)),
1171 CONFIGURATION_VARSTORE_ID
,
1172 (UINT16
) (ATTEMPT_INITIATOR_IP_ADDRESS_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1183 // Create iSCSIInitiatorNetmask Keyword.
1185 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_INITIATOR_NET_MASK_PROMPT%d", Index
);
1186 StringToken
= HiiSetString (
1187 mCallbackInfo
->RegisteredHandle
,
1192 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIInitiatorNetmask:%d", Index
);
1193 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1194 HiiCreateStringOpCode (
1196 (EFI_QUESTION_ID
) (ATTEMPT_INITIATOR_NET_MASK_QUESTION_ID
+ (Index
- 1)),
1197 CONFIGURATION_VARSTORE_ID
,
1198 (UINT16
) (ATTEMPT_INITIATOR_NET_MASK_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1209 // Create iSCSIInitiatorGateway Keyword.
1211 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_INITIATOR_GATE_PROMPT%d", Index
);
1212 StringToken
= HiiSetString (
1213 mCallbackInfo
->RegisteredHandle
,
1218 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIInitiatorGateway:%d", Index
);
1219 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1220 HiiCreateStringOpCode (
1222 (EFI_QUESTION_ID
) (ATTEMPT_INITIATOR_GATE_WAY_QUESTION_ID
+ (Index
- 1)),
1223 CONFIGURATION_VARSTORE_ID
,
1224 (UINT16
) (ATTEMPT_INITIATOR_GATE_WAY_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1235 // Create iSCSITargetInfoViaDHCP Keyword.
1237 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_TARGET_VIA_DHCP_PROMPT%d", Index
);
1238 StringToken
= HiiSetString (
1239 mCallbackInfo
->RegisteredHandle
,
1244 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSITargetInfoViaDHCP:%d", Index
);
1245 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1246 HiiCreateNumericOpCode (
1248 (EFI_QUESTION_ID
) (ATTEMPT_TARGET_VIA_DHCP_QUESTION_ID
+ (Index
- 1)),
1249 CONFIGURATION_VARSTORE_ID
,
1250 (UINT16
) (ATTEMPT_TARGET_VIA_DHCP_VAR_OFFSET
+ (Index
- 1)),
1262 // Create iSCSITargetTcpPort Keyword.
1264 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_TARGET_TCP_PORT_PROMPT%d", Index
);
1265 StringToken
= HiiSetString (
1266 mCallbackInfo
->RegisteredHandle
,
1271 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSITargetTcpPort:%d", Index
);
1272 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1273 HiiCreateNumericOpCode (
1275 (EFI_QUESTION_ID
) (ATTEMPT_TARGET_TCP_PORT_QUESTION_ID
+ (Index
- 1)),
1276 CONFIGURATION_VARSTORE_ID
,
1277 (UINT16
) (ATTEMPT_TARGET_TCP_PORT_VAR_OFFSET
+ 2 * (Index
- 1)),
1281 EFI_IFR_NUMERIC_SIZE_2
,
1282 TARGET_PORT_MIN_NUM
,
1283 TARGET_PORT_MAX_NUM
,
1289 // Create iSCSITargetName Keyword.
1291 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_TARGET_NAME_PROMPT%d", Index
);
1292 StringToken
= HiiSetString (
1293 mCallbackInfo
->RegisteredHandle
,
1298 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSITargetName:%d", Index
);
1299 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1300 HiiCreateStringOpCode (
1302 (EFI_QUESTION_ID
) (ATTEMPT_TARGET_NAME_QUESTION_ID
+ (Index
- 1)),
1303 CONFIGURATION_VARSTORE_ID
,
1304 (UINT16
) (ATTEMPT_TARGET_NAME_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1309 ISCSI_NAME_IFR_MIN_SIZE
,
1310 ISCSI_NAME_IFR_MAX_SIZE
,
1315 // Create iSCSITargetIpAddress Keyword.
1317 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_TARGET_IP_ADDRESS_PROMPT%d", Index
);
1318 StringToken
= HiiSetString (
1319 mCallbackInfo
->RegisteredHandle
,
1324 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSITargetIpAddress:%d", Index
);
1325 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1326 HiiCreateStringOpCode (
1328 (EFI_QUESTION_ID
) (ATTEMPT_TARGET_IP_ADDRESS_QUESTION_ID
+ (Index
- 1)),
1329 CONFIGURATION_VARSTORE_ID
,
1330 (UINT16
) (ATTEMPT_TARGET_IP_ADDRESS_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1341 // Create iSCSILUN Keyword.
1343 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_LUN_PROMPT%d", Index
);
1344 StringToken
= HiiSetString (
1345 mCallbackInfo
->RegisteredHandle
,
1350 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSILUN:%d", Index
);
1351 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1352 HiiCreateStringOpCode (
1354 (EFI_QUESTION_ID
) (ATTEMPT_LUN_QUESTION_ID
+ (Index
- 1)),
1355 CONFIGURATION_VARSTORE_ID
,
1356 (UINT16
) (ATTEMPT_LUN_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1367 // Create iSCSIAuthenticationMethod Keyword.
1369 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_AUTHENTICATION_METHOD_PROMPT%d", Index
);
1370 StringToken
= HiiSetString (
1371 mCallbackInfo
->RegisteredHandle
,
1376 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIAuthenticationMethod:%d", Index
);
1377 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1378 HiiCreateNumericOpCode (
1380 (EFI_QUESTION_ID
) (ATTEMPT_AUTHENTICATION_METHOD_QUESTION_ID
+ (Index
- 1)),
1381 CONFIGURATION_VARSTORE_ID
,
1382 (UINT16
) (ATTEMPT_AUTHENTICATION_METHOD_VAR_OFFSET
+ (Index
- 1)),
1394 // Create iSCSIChapType Keyword.
1396 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHARTYPE_PROMPT%d", Index
);
1397 StringToken
= HiiSetString (
1398 mCallbackInfo
->RegisteredHandle
,
1403 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIChapType:%d", Index
);
1404 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1405 HiiCreateNumericOpCode (
1407 (EFI_QUESTION_ID
) (ATTEMPT_CHARTYPE_QUESTION_ID
+ (Index
- 1)),
1408 CONFIGURATION_VARSTORE_ID
,
1409 (UINT16
) (ATTEMPT_CHARTYPE_VAR_OFFSET
+ (Index
- 1)),
1421 // Create iSCSIChapUsername Keyword.
1423 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHAR_USER_NAME_PROMPT%d", Index
);
1424 StringToken
= HiiSetString (
1425 mCallbackInfo
->RegisteredHandle
,
1430 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIChapUsername:%d", Index
);
1431 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1432 HiiCreateStringOpCode (
1434 (EFI_QUESTION_ID
) (ATTEMPT_CHAR_USER_NAME_QUESTION_ID
+ (Index
- 1)),
1435 CONFIGURATION_VARSTORE_ID
,
1436 (UINT16
) (ATTEMPT_CHAR_USER_NAME_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1442 ISCSI_CHAP_NAME_MAX_LEN
,
1447 // Create iSCSIChapSecret Keyword.
1449 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHAR_SECRET_PROMPT%d", Index
);
1450 StringToken
= HiiSetString (
1451 mCallbackInfo
->RegisteredHandle
,
1456 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIChapSecret:%d", Index
);
1457 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1458 HiiCreateStringOpCode (
1460 (EFI_QUESTION_ID
) (ATTEMPT_CHAR_SECRET_QUESTION_ID
+ (Index
- 1)),
1461 CONFIGURATION_VARSTORE_ID
,
1462 (UINT16
) (ATTEMPT_CHAR_SECRET_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1467 ISCSI_CHAP_SECRET_MIN_LEN
,
1468 ISCSI_CHAP_SECRET_MAX_LEN
,
1473 // Create iSCSIReverseChapUsername Keyword.
1475 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHAR_REVERSE_USER_NAME_PROMPT%d", Index
);
1476 StringToken
= HiiSetString (
1477 mCallbackInfo
->RegisteredHandle
,
1482 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIReverseChapUsername:%d", Index
);
1483 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1484 HiiCreateStringOpCode (
1486 (EFI_QUESTION_ID
) (ATTEMPT_CHAR_REVERSE_USER_NAME_QUESTION_ID
+ (Index
- 1)),
1487 CONFIGURATION_VARSTORE_ID
,
1488 (UINT16
) (ATTEMPT_CHAR_REVERSE_USER_NAME_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1494 ISCSI_CHAP_NAME_MAX_LEN
,
1499 // Create iSCSIReverseChapSecret Keyword.
1501 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHAR_REVERSE_SECRET_PROMPT%d", Index
);
1502 StringToken
= HiiSetString (
1503 mCallbackInfo
->RegisteredHandle
,
1508 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIReverseChapSecret:%d", Index
);
1509 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1510 HiiCreateStringOpCode (
1512 (EFI_QUESTION_ID
) (ATTEMPT_CHAR_REVERSE_SECRET_QUESTION_ID
+ (Index
- 1)),
1513 CONFIGURATION_VARSTORE_ID
,
1514 (UINT16
) (ATTEMPT_CHAR_REVERSE_SECRET_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1519 ISCSI_CHAP_SECRET_MIN_LEN
,
1520 ISCSI_CHAP_SECRET_MAX_LEN
,
1525 Status
= HiiUpdateForm (
1526 mCallbackInfo
->RegisteredHandle
, // HII handle
1527 &gIScsiConfigGuid
, // Formset GUID
1528 FORMID_ATTEMPT_FORM
, // Form ID
1529 StartOpCodeHandle
, // Label for where to insert opcodes
1530 EndOpCodeHandle
// Replace data
1533 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1534 HiiFreeOpCodeHandle (EndOpCodeHandle
);
1541 Free the attempt configure data variable.
1545 IScsiCleanAttemptVariable (
1549 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
1550 UINT8
*AttemptConfigOrder
;
1551 UINTN AttemptConfigOrderSize
;
1555 // Get the initialized attempt order.
1557 AttemptConfigOrder
= IScsiGetVariableAndSize (
1558 L
"InitialAttemptOrder",
1560 &AttemptConfigOrderSize
1562 if (AttemptConfigOrder
== NULL
|| AttemptConfigOrderSize
== 0) {
1566 for (Index
= 1; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
1568 mPrivate
->PortString
,
1569 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
1575 mPrivate
->PortString
,
1576 &gEfiIScsiInitiatorNameProtocolGuid
,
1577 (VOID
**)&AttemptConfigData
,
1581 if (AttemptConfigData
!= NULL
) {
1583 mPrivate
->PortString
,
1584 &gEfiIScsiInitiatorNameProtocolGuid
,
1595 Get the recorded NIC info from global structure by the Index.
1597 @param[in] NicIndex The index indicates the position of NIC info.
1599 @return Pointer to the NIC info, or NULL if not found.
1603 IScsiGetNicInfoByIndex (
1608 ISCSI_NIC_INFO
*NicInfo
;
1610 NET_LIST_FOR_EACH (Entry
, &mPrivate
->NicInfoList
) {
1611 NicInfo
= NET_LIST_USER_STRUCT (Entry
, ISCSI_NIC_INFO
, Link
);
1612 if (NicInfo
->NicIndex
== NicIndex
) {
1622 Get the NIC's PCI location and return it according to the composited
1623 format defined in iSCSI Boot Firmware Table.
1625 @param[in] Controller The handle of the controller.
1626 @param[out] Bus The bus number.
1627 @param[out] Device The device number.
1628 @param[out] Function The function number.
1630 @return The composited representation of the NIC PCI location.
1634 IScsiGetNICPciLocation (
1635 IN EFI_HANDLE Controller
,
1642 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1643 EFI_HANDLE PciIoHandle
;
1644 EFI_PCI_IO_PROTOCOL
*PciIo
;
1647 Status
= gBS
->HandleProtocol (
1649 &gEfiDevicePathProtocolGuid
,
1650 (VOID
**) &DevicePath
1652 if (EFI_ERROR (Status
)) {
1656 Status
= gBS
->LocateDevicePath (
1657 &gEfiPciIoProtocolGuid
,
1661 if (EFI_ERROR (Status
)) {
1665 Status
= gBS
->HandleProtocol (PciIoHandle
, &gEfiPciIoProtocolGuid
, (VOID
**) &PciIo
);
1666 if (EFI_ERROR (Status
)) {
1670 Status
= PciIo
->GetLocation (PciIo
, &Segment
, Bus
, Device
, Function
);
1671 if (EFI_ERROR (Status
)) {
1675 return (UINT16
) ((*Bus
<< 8) | (*Device
<< 3) | *Function
);
1680 Read the EFI variable (VendorGuid/Name) and return a dynamically allocated
1681 buffer, and the size of the buffer. If failure, return NULL.
1683 @param[in] Name String part of EFI variable name.
1684 @param[in] VendorGuid GUID part of EFI variable name.
1685 @param[out] VariableSize Returns the size of the EFI variable that was read.
1687 @return Dynamically allocated memory that contains a copy of the EFI variable.
1688 @return Caller is responsible freeing the buffer.
1689 @retval NULL Variable was not read.
1693 IScsiGetVariableAndSize (
1695 IN EFI_GUID
*VendorGuid
,
1696 OUT UINTN
*VariableSize
1706 // Pass in a zero size buffer to find the required buffer size.
1709 Status
= gRT
->GetVariable (Name
, VendorGuid
, NULL
, &BufferSize
, Buffer
);
1710 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1712 // Allocate the buffer to return
1714 Buffer
= AllocateZeroPool (BufferSize
);
1715 if (Buffer
== NULL
) {
1719 // Read variable into the allocated buffer.
1721 Status
= gRT
->GetVariable (Name
, VendorGuid
, NULL
, &BufferSize
, Buffer
);
1722 if (EFI_ERROR (Status
)) {
1727 *VariableSize
= BufferSize
;
1733 Create the iSCSI driver data.
1735 @param[in] Image The handle of the driver image.
1736 @param[in] Controller The handle of the controller.
1738 @return The iSCSI driver data created.
1739 @retval NULL Other errors as indicated.
1743 IScsiCreateDriverData (
1744 IN EFI_HANDLE Image
,
1745 IN EFI_HANDLE Controller
1748 ISCSI_DRIVER_DATA
*Private
;
1751 Private
= AllocateZeroPool (sizeof (ISCSI_DRIVER_DATA
));
1752 if (Private
== NULL
) {
1756 Private
->Signature
= ISCSI_DRIVER_DATA_SIGNATURE
;
1757 Private
->Image
= Image
;
1758 Private
->Controller
= Controller
;
1759 Private
->Session
= NULL
;
1762 // Create an event to be signaled when the BS to RT transition is triggerd so
1763 // as to abort the iSCSI session.
1765 Status
= gBS
->CreateEventEx (
1768 IScsiOnExitBootService
,
1770 &gEfiEventExitBootServicesGuid
,
1771 &Private
->ExitBootServiceEvent
1773 if (EFI_ERROR (Status
)) {
1778 Private
->ExtScsiPassThruHandle
= NULL
;
1779 CopyMem(&Private
->IScsiExtScsiPassThru
, &gIScsiExtScsiPassThruProtocolTemplate
, sizeof(EFI_EXT_SCSI_PASS_THRU_PROTOCOL
));
1782 // 0 is designated to the TargetId, so use another value for the AdapterId.
1784 Private
->ExtScsiPassThruMode
.AdapterId
= 2;
1785 Private
->ExtScsiPassThruMode
.Attributes
= EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL
| EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL
;
1786 Private
->ExtScsiPassThruMode
.IoAlign
= 4;
1787 Private
->IScsiExtScsiPassThru
.Mode
= &Private
->ExtScsiPassThruMode
;
1794 Clean the iSCSI driver data.
1796 @param[in] Private The iSCSI driver data.
1798 @retval EFI_SUCCESS The clean operation is successful.
1799 @retval Others Other errors as indicated.
1803 IScsiCleanDriverData (
1804 IN ISCSI_DRIVER_DATA
*Private
1809 Status
= EFI_SUCCESS
;
1811 if (Private
->DevicePath
!= NULL
) {
1812 Status
= gBS
->UninstallProtocolInterface (
1813 Private
->ExtScsiPassThruHandle
,
1814 &gEfiDevicePathProtocolGuid
,
1817 if (EFI_ERROR (Status
)) {
1821 FreePool (Private
->DevicePath
);
1824 if (Private
->ExtScsiPassThruHandle
!= NULL
) {
1825 Status
= gBS
->UninstallProtocolInterface (
1826 Private
->ExtScsiPassThruHandle
,
1827 &gEfiExtScsiPassThruProtocolGuid
,
1828 &Private
->IScsiExtScsiPassThru
1830 if (!EFI_ERROR (Status
)) {
1831 mPrivate
->OneSessionEstablished
= FALSE
;
1836 if (Private
->ExitBootServiceEvent
!= NULL
) {
1837 gBS
->CloseEvent (Private
->ExitBootServiceEvent
);
1840 mCallbackInfo
->Current
= NULL
;
1847 Check wheather the Controller handle is configured to use DHCP protocol.
1849 @param[in] Controller The handle of the controller.
1850 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
1852 @retval TRUE The handle of the controller need the Dhcp protocol.
1853 @retval FALSE The handle of the controller does not need the Dhcp protocol.
1857 IScsiDhcpIsConfigured (
1858 IN EFI_HANDLE Controller
,
1862 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptTmp
;
1863 UINT8
*AttemptConfigOrder
;
1864 UINTN AttemptConfigOrderSize
;
1867 EFI_MAC_ADDRESS MacAddr
;
1868 UINTN HwAddressSize
;
1870 CHAR16 MacString
[ISCSI_MAX_MAC_STRING_LEN
];
1871 CHAR16 AttemptMacString
[ISCSI_MAX_MAC_STRING_LEN
];
1872 CHAR16 AttemptName
[ISCSI_NAME_IFR_MAX_SIZE
];
1874 AttemptConfigOrder
= IScsiGetVariableAndSize (
1877 &AttemptConfigOrderSize
1879 if (AttemptConfigOrder
== NULL
|| AttemptConfigOrderSize
== 0) {
1884 // Get MAC address of this network device.
1886 Status
= NetLibGetMacAddress (Controller
, &MacAddr
, &HwAddressSize
);
1887 if(EFI_ERROR (Status
)) {
1891 // Get VLAN ID of this network device.
1893 VlanId
= NetLibGetVlanId (Controller
);
1894 IScsiMacAddrToStr (&MacAddr
, (UINT32
) HwAddressSize
, VlanId
, MacString
);
1896 for (Index
= 0; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
1901 (UINTN
) AttemptConfigOrder
[Index
]
1903 Status
= GetVariable2 (
1905 &gEfiIScsiInitiatorNameProtocolGuid
,
1906 (VOID
**)&AttemptTmp
,
1909 if(AttemptTmp
== NULL
|| EFI_ERROR (Status
)) {
1913 ASSERT (AttemptConfigOrder
[Index
] == AttemptTmp
->AttemptConfigIndex
);
1915 if (AttemptTmp
->SessionConfigData
.Enabled
== ISCSI_DISABLED
) {
1916 FreePool (AttemptTmp
);
1920 if (AttemptTmp
->SessionConfigData
.IpMode
!= IP_MODE_AUTOCONFIG
&&
1921 AttemptTmp
->SessionConfigData
.IpMode
!= ((IpVersion
== IP_VERSION_4
) ? IP_MODE_IP4
: IP_MODE_IP6
)) {
1922 FreePool (AttemptTmp
);
1926 AsciiStrToUnicodeStrS (AttemptTmp
->MacString
, AttemptMacString
, sizeof (AttemptMacString
) / sizeof (AttemptMacString
[0]));
1928 if (AttemptTmp
->Actived
== ISCSI_ACTIVE_DISABLED
|| StrCmp (MacString
, AttemptMacString
)) {
1932 if(AttemptTmp
->SessionConfigData
.IpMode
== IP_MODE_AUTOCONFIG
||
1933 AttemptTmp
->SessionConfigData
.InitiatorInfoFromDhcp
== TRUE
||
1934 AttemptTmp
->SessionConfigData
.TargetInfoFromDhcp
== TRUE
) {
1935 FreePool (AttemptTmp
);
1936 FreePool (AttemptConfigOrder
);
1940 FreePool (AttemptTmp
);
1943 FreePool (AttemptConfigOrder
);
1948 Check whether the Controller handle is configured to use DNS protocol.
1950 @param[in] Controller The handle of the controller.
1952 @retval TRUE The handle of the controller need the Dns protocol.
1953 @retval FALSE The handle of the controller does not need the Dns protocol.
1957 IScsiDnsIsConfigured (
1958 IN EFI_HANDLE Controller
1961 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptTmp
;
1962 UINT8
*AttemptConfigOrder
;
1963 UINTN AttemptConfigOrderSize
;
1966 EFI_MAC_ADDRESS MacAddr
;
1967 UINTN HwAddressSize
;
1969 CHAR16 AttemptMacString
[ISCSI_MAX_MAC_STRING_LEN
];
1970 CHAR16 MacString
[ISCSI_MAX_MAC_STRING_LEN
];
1971 CHAR16 AttemptName
[ISCSI_NAME_IFR_MAX_SIZE
];
1973 AttemptConfigOrder
= IScsiGetVariableAndSize (
1976 &AttemptConfigOrderSize
1978 if (AttemptConfigOrder
== NULL
|| AttemptConfigOrderSize
== 0) {
1983 // Get MAC address of this network device.
1985 Status
= NetLibGetMacAddress (Controller
, &MacAddr
, &HwAddressSize
);
1986 if(EFI_ERROR (Status
)) {
1990 // Get VLAN ID of this network device.
1992 VlanId
= NetLibGetVlanId (Controller
);
1993 IScsiMacAddrToStr (&MacAddr
, (UINT32
) HwAddressSize
, VlanId
, MacString
);
1995 for (Index
= 0; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
2000 (UINTN
) AttemptConfigOrder
[Index
]
2003 Status
= GetVariable2 (
2005 &gEfiIScsiInitiatorNameProtocolGuid
,
2006 (VOID
**)&AttemptTmp
,
2009 if(AttemptTmp
== NULL
|| EFI_ERROR (Status
)) {
2013 ASSERT (AttemptConfigOrder
[Index
] == AttemptTmp
->AttemptConfigIndex
);
2015 AsciiStrToUnicodeStrS (AttemptTmp
->MacString
, AttemptMacString
, sizeof (AttemptMacString
) / sizeof (AttemptMacString
[0]));
2017 if (AttemptTmp
->SessionConfigData
.Enabled
== ISCSI_DISABLED
|| StrCmp (MacString
, AttemptMacString
)) {
2018 FreePool (AttemptTmp
);
2022 if (AttemptTmp
->SessionConfigData
.DnsMode
|| AttemptTmp
->SessionConfigData
.TargetInfoFromDhcp
) {
2023 FreePool (AttemptTmp
);
2024 FreePool (AttemptConfigOrder
);
2027 FreePool (AttemptTmp
);
2033 FreePool (AttemptConfigOrder
);
2039 Get the various configuration data.
2041 @param[in] Private The iSCSI driver data.
2043 @retval EFI_SUCCESS The configuration data is retrieved.
2044 @retval EFI_NOT_FOUND This iSCSI driver is not configured yet.
2045 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
2049 IScsiGetConfigData (
2050 IN ISCSI_DRIVER_DATA
*Private
2054 CHAR16 MacString
[ISCSI_MAX_MAC_STRING_LEN
];
2055 CHAR16 AttemptMacString
[ISCSI_MAX_MAC_STRING_LEN
];
2057 ISCSI_NIC_INFO
*NicInfo
;
2058 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
2059 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptTmp
;
2060 UINT8
*AttemptConfigOrder
;
2061 UINTN AttemptConfigOrderSize
;
2062 CHAR16 IScsiMode
[64];
2066 // There should be at least one attempt configured.
2068 AttemptConfigOrder
= IScsiGetVariableAndSize (
2071 &AttemptConfigOrderSize
2073 if (AttemptConfigOrder
== NULL
|| AttemptConfigOrderSize
== 0) {
2074 return EFI_NOT_FOUND
;
2078 // Get the iSCSI Initiator Name.
2080 mPrivate
->InitiatorNameLength
= ISCSI_NAME_MAX_SIZE
;
2081 Status
= gIScsiInitiatorName
.Get (
2082 &gIScsiInitiatorName
,
2083 &mPrivate
->InitiatorNameLength
,
2084 mPrivate
->InitiatorName
2086 if (EFI_ERROR (Status
)) {
2091 // Get the normal configuration.
2093 for (Index
= 0; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
2096 // Check whether the attempt exists in AttemptConfig.
2098 AttemptTmp
= IScsiConfigGetAttemptByConfigIndex (AttemptConfigOrder
[Index
]);
2099 if (AttemptTmp
!= NULL
&& AttemptTmp
->SessionConfigData
.Enabled
== ISCSI_DISABLED
) {
2101 } else if (AttemptTmp
!= NULL
&& AttemptTmp
->SessionConfigData
.Enabled
!= ISCSI_DISABLED
) {
2103 // Check the autoconfig path to see whether it should be retried.
2105 if (AttemptTmp
->SessionConfigData
.IpMode
== IP_MODE_AUTOCONFIG
&&
2106 !AttemptTmp
->AutoConfigureSuccess
) {
2107 if (mPrivate
->Ipv6Flag
&&
2108 AttemptTmp
->AutoConfigureMode
== IP_MODE_AUTOCONFIG_IP6
) {
2110 // Autoconfigure for IP6 already attempted but failed. Do not try again.
2113 } else if (!mPrivate
->Ipv6Flag
&&
2114 AttemptTmp
->AutoConfigureMode
== IP_MODE_AUTOCONFIG_IP4
) {
2116 // Autoconfigure for IP4 already attempted but failed. Do not try again.
2121 // Try another approach for this autoconfigure path.
2123 AttemptTmp
->AutoConfigureMode
=
2124 (UINT8
) (mPrivate
->Ipv6Flag
? IP_MODE_AUTOCONFIG_IP6
: IP_MODE_AUTOCONFIG_IP4
);
2125 AttemptTmp
->SessionConfigData
.InitiatorInfoFromDhcp
= TRUE
;
2126 AttemptTmp
->SessionConfigData
.TargetInfoFromDhcp
= TRUE
;
2127 AttemptTmp
->DhcpSuccess
= FALSE
;
2130 // Get some information from the dhcp server.
2132 if (!mPrivate
->Ipv6Flag
) {
2133 Status
= IScsiDoDhcp (Private
->Image
, Private
->Controller
, AttemptTmp
);
2134 if (!EFI_ERROR (Status
)) {
2135 AttemptTmp
->DhcpSuccess
= TRUE
;
2138 Status
= IScsiDoDhcp6 (Private
->Image
, Private
->Controller
, AttemptTmp
);
2139 if (!EFI_ERROR (Status
)) {
2140 AttemptTmp
->DhcpSuccess
= TRUE
;
2145 // Refresh the state of this attempt to NVR.
2148 mPrivate
->PortString
,
2149 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2151 (UINTN
) AttemptTmp
->AttemptConfigIndex
2155 mPrivate
->PortString
,
2156 &gEfiIScsiInitiatorNameProtocolGuid
,
2157 ISCSI_CONFIG_VAR_ATTR
,
2158 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
2164 } else if (AttemptTmp
->SessionConfigData
.InitiatorInfoFromDhcp
&&
2165 !AttemptTmp
->ValidPath
&&
2166 AttemptTmp
->NicIndex
== mPrivate
->CurrentNic
) {
2168 // If the attempt associates with the current NIC, we can
2169 // get DHCP information for already added, but failed, attempt.
2171 AttemptTmp
->DhcpSuccess
= FALSE
;
2172 if (!mPrivate
->Ipv6Flag
&& (AttemptTmp
->SessionConfigData
.IpMode
== IP_MODE_IP4
)) {
2173 Status
= IScsiDoDhcp (Private
->Image
, Private
->Controller
, AttemptTmp
);
2174 if (!EFI_ERROR (Status
)) {
2175 AttemptTmp
->DhcpSuccess
= TRUE
;
2177 } else if (mPrivate
->Ipv6Flag
&& (AttemptTmp
->SessionConfigData
.IpMode
== IP_MODE_IP6
)) {
2178 Status
= IScsiDoDhcp6 (Private
->Image
, Private
->Controller
, AttemptTmp
);
2179 if (!EFI_ERROR (Status
)) {
2180 AttemptTmp
->DhcpSuccess
= TRUE
;
2185 // Refresh the state of this attempt to NVR.
2188 mPrivate
->PortString
,
2189 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2191 (UINTN
) AttemptTmp
->AttemptConfigIndex
2195 mPrivate
->PortString
,
2196 &gEfiIScsiInitiatorNameProtocolGuid
,
2197 ISCSI_CONFIG_VAR_ATTR
,
2198 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
2210 // This attempt does not exist in AttemptConfig. Try to add a new one.
2213 NicInfo
= IScsiGetNicInfoByIndex (mPrivate
->CurrentNic
);
2214 ASSERT (NicInfo
!= NULL
);
2215 IScsiMacAddrToStr (&NicInfo
->PermanentAddress
, NicInfo
->HwAddressSize
, NicInfo
->VlanId
, MacString
);
2217 mPrivate
->PortString
,
2218 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2220 (UINTN
) AttemptConfigOrder
[Index
]
2224 mPrivate
->PortString
,
2225 &gEfiIScsiInitiatorNameProtocolGuid
,
2226 (VOID
**)&AttemptConfigData
,
2229 AsciiStrToUnicodeStrS (AttemptConfigData
->MacString
, AttemptMacString
, sizeof (AttemptMacString
) / sizeof (AttemptMacString
[0]));
2231 if (AttemptConfigData
== NULL
|| AttemptConfigData
->Actived
== ISCSI_ACTIVE_DISABLED
||
2232 StrCmp (MacString
, AttemptMacString
)) {
2236 ASSERT (AttemptConfigOrder
[Index
] == AttemptConfigData
->AttemptConfigIndex
);
2238 AttemptConfigData
->NicIndex
= NicInfo
->NicIndex
;
2239 AttemptConfigData
->DhcpSuccess
= FALSE
;
2240 AttemptConfigData
->ValidiBFTPath
= (BOOLEAN
) (mPrivate
->EnableMpio
? TRUE
: FALSE
);
2241 AttemptConfigData
->ValidPath
= FALSE
;
2243 if (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_AUTOCONFIG
) {
2244 AttemptConfigData
->SessionConfigData
.InitiatorInfoFromDhcp
= TRUE
;
2245 AttemptConfigData
->SessionConfigData
.TargetInfoFromDhcp
= TRUE
;
2247 AttemptConfigData
->AutoConfigureMode
=
2248 (UINT8
) (mPrivate
->Ipv6Flag
? IP_MODE_AUTOCONFIG_IP6
: IP_MODE_AUTOCONFIG_IP4
);
2249 AttemptConfigData
->AutoConfigureSuccess
= FALSE
;
2253 // Get some information from dhcp server.
2255 if (AttemptConfigData
->SessionConfigData
.Enabled
!= ISCSI_DISABLED
&&
2256 AttemptConfigData
->SessionConfigData
.InitiatorInfoFromDhcp
) {
2258 if (!mPrivate
->Ipv6Flag
&&
2259 (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_IP4
||
2260 AttemptConfigData
->AutoConfigureMode
== IP_MODE_AUTOCONFIG_IP4
)) {
2261 Status
= IScsiDoDhcp (Private
->Image
, Private
->Controller
, AttemptConfigData
);
2262 if (!EFI_ERROR (Status
)) {
2263 AttemptConfigData
->DhcpSuccess
= TRUE
;
2265 } else if (mPrivate
->Ipv6Flag
&&
2266 (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_IP6
||
2267 AttemptConfigData
->AutoConfigureMode
== IP_MODE_AUTOCONFIG_IP6
)) {
2268 Status
= IScsiDoDhcp6 (Private
->Image
, Private
->Controller
, AttemptConfigData
);
2269 if (!EFI_ERROR (Status
)) {
2270 AttemptConfigData
->DhcpSuccess
= TRUE
;
2275 // Refresh the state of this attempt to NVR.
2278 mPrivate
->PortString
,
2279 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2281 (UINTN
) AttemptConfigData
->AttemptConfigIndex
2285 mPrivate
->PortString
,
2286 &gEfiIScsiInitiatorNameProtocolGuid
,
2287 ISCSI_CONFIG_VAR_ATTR
,
2288 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
2294 // Update Attempt Help Info.
2297 if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_DISABLED
) {
2298 UnicodeSPrint (IScsiMode
, 64, L
"Disabled");
2299 } else if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED
) {
2300 UnicodeSPrint (IScsiMode
, 64, L
"Enabled");
2301 } else if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED_FOR_MPIO
) {
2302 UnicodeSPrint (IScsiMode
, 64, L
"Enabled for MPIO");
2305 if (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_IP4
) {
2306 UnicodeSPrint (IpMode
, 64, L
"IP4");
2307 } else if (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_IP6
) {
2308 UnicodeSPrint (IpMode
, 64, L
"IP6");
2309 } else if (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_AUTOCONFIG
) {
2310 UnicodeSPrint (IpMode
, 64, L
"Autoconfigure");
2314 mPrivate
->PortString
,
2315 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2316 L
"MAC: %s, PFA: Bus %d | Dev %d | Func %d, iSCSI mode: %s, IP version: %s",
2319 NicInfo
->DeviceNumber
,
2320 NicInfo
->FunctionNumber
,
2325 AttemptConfigData
->AttemptTitleHelpToken
= HiiSetString (
2326 mCallbackInfo
->RegisteredHandle
,
2328 mPrivate
->PortString
,
2331 if (AttemptConfigData
->AttemptTitleHelpToken
== 0) {
2332 return EFI_OUT_OF_RESOURCES
;
2336 // Record the attempt in global link list.
2338 InsertTailList (&mPrivate
->AttemptConfigs
, &AttemptConfigData
->Link
);
2339 mPrivate
->AttemptCount
++;
2341 if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED_FOR_MPIO
) {
2342 mPrivate
->MpioCount
++;
2343 mPrivate
->EnableMpio
= TRUE
;
2345 if (AttemptConfigData
->AuthenticationType
== ISCSI_AUTH_TYPE_KRB
) {
2346 mPrivate
->Krb5MpioCount
++;
2348 } else if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED
) {
2349 mPrivate
->SinglePathCount
++;
2354 // Reorder the AttemptConfig by the configured order.
2356 for (Index
= 0; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
2357 AttemptConfigData
= IScsiConfigGetAttemptByConfigIndex (AttemptConfigOrder
[Index
]);
2358 if (AttemptConfigData
== NULL
) {
2362 RemoveEntryList (&AttemptConfigData
->Link
);
2363 InsertTailList (&mPrivate
->AttemptConfigs
, &AttemptConfigData
->Link
);
2367 // Update the Main Form.
2369 IScsiConfigUpdateAttempt ();
2371 FreePool (AttemptConfigOrder
);
2374 // There should be at least one attempt configuration.
2376 if (!mPrivate
->EnableMpio
) {
2377 if (mPrivate
->SinglePathCount
== 0) {
2378 return EFI_NOT_FOUND
;
2380 mPrivate
->ValidSinglePathCount
= mPrivate
->SinglePathCount
;
2388 Get the device path of the iSCSI tcp connection and update it.
2390 @param Session The iSCSI session.
2392 @return The updated device path.
2393 @retval NULL Other errors as indicated.
2396 EFI_DEVICE_PATH_PROTOCOL
*
2397 IScsiGetTcpConnDevicePath (
2398 IN ISCSI_SESSION
*Session
2401 ISCSI_CONNECTION
*Conn
;
2402 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
2404 EFI_DEV_PATH
*DPathNode
;
2407 if (Session
->State
!= SESSION_STATE_LOGGED_IN
) {
2411 Conn
= NET_LIST_USER_STRUCT_S (
2412 Session
->Conns
.ForwardLink
,
2415 ISCSI_CONNECTION_SIGNATURE
2418 Status
= gBS
->HandleProtocol (
2420 &gEfiDevicePathProtocolGuid
,
2421 (VOID
**) &DevicePath
2423 if (EFI_ERROR (Status
)) {
2429 DevicePath
= DuplicateDevicePath (DevicePath
);
2430 if (DevicePath
== NULL
) {
2434 DPathNode
= (EFI_DEV_PATH
*) DevicePath
;
2436 while (!IsDevicePathEnd (&DPathNode
->DevPath
)) {
2437 if (DevicePathType (&DPathNode
->DevPath
) == MESSAGING_DEVICE_PATH
) {
2438 if (!Conn
->Ipv6Flag
&& DevicePathSubType (&DPathNode
->DevPath
) == MSG_IPv4_DP
) {
2439 DPathNode
->Ipv4
.LocalPort
= 0;
2441 DPathNode
->Ipv4
.StaticIpAddress
=
2442 (BOOLEAN
) (!Session
->ConfigData
->SessionConfigData
.InitiatorInfoFromDhcp
);
2445 // Add a judgement here to support previous versions of IPv4_DEVICE_PATH.
2446 // In previous versions of IPv4_DEVICE_PATH, GatewayIpAddress and SubnetMask
2448 // In new version of IPv4_DEVICE_PATH, structure length is 27.
2451 PathLen
= DevicePathNodeLength (&DPathNode
->Ipv4
);
2453 if (PathLen
== IP4_NODE_LEN_NEW_VERSIONS
) {
2456 &DPathNode
->Ipv4
.GatewayIpAddress
,
2457 &Session
->ConfigData
->SessionConfigData
.Gateway
2461 &DPathNode
->Ipv4
.SubnetMask
,
2462 &Session
->ConfigData
->SessionConfigData
.SubnetMask
2467 } else if (Conn
->Ipv6Flag
&& DevicePathSubType (&DPathNode
->DevPath
) == MSG_IPv6_DP
) {
2468 DPathNode
->Ipv6
.LocalPort
= 0;
2471 // Add a judgement here to support previous versions of IPv6_DEVICE_PATH.
2472 // In previous versions of IPv6_DEVICE_PATH, IpAddressOrigin, PrefixLength
2473 // and GatewayIpAddress do not exist.
2474 // In new version of IPv6_DEVICE_PATH, structure length is 60, while in
2475 // old versions, the length is 43.
2478 PathLen
= DevicePathNodeLength (&DPathNode
->Ipv6
);
2480 if (PathLen
== IP6_NODE_LEN_NEW_VERSIONS
) {
2482 DPathNode
->Ipv6
.IpAddressOrigin
= 0;
2483 DPathNode
->Ipv6
.PrefixLength
= IP6_PREFIX_LENGTH
;
2484 ZeroMem (&DPathNode
->Ipv6
.GatewayIpAddress
, sizeof (EFI_IPv6_ADDRESS
));
2486 else if (PathLen
== IP6_NODE_LEN_OLD_VERSIONS
) {
2489 // StaticIPAddress is a field in old versions of IPv6_DEVICE_PATH, while ignored in new
2490 // version. Set StaticIPAddress through its' offset in old IPv6_DEVICE_PATH.
2492 *((UINT8
*)(&DPathNode
->Ipv6
) + IP6_OLD_IPADDRESS_OFFSET
) =
2493 (BOOLEAN
) (!Session
->ConfigData
->SessionConfigData
.InitiatorInfoFromDhcp
);
2500 DPathNode
= (EFI_DEV_PATH
*) NextDevicePathNode (&DPathNode
->DevPath
);
2508 Abort the session when the transition from BS to RT is initiated.
2510 @param[in] Event The event signaled.
2511 @param[in] Context The iSCSI driver data.
2516 IScsiOnExitBootService (
2521 ISCSI_DRIVER_DATA
*Private
;
2523 Private
= (ISCSI_DRIVER_DATA
*) Context
;
2525 gBS
->CloseEvent (Private
->ExitBootServiceEvent
);
2526 Private
->ExitBootServiceEvent
= NULL
;
2528 if (Private
->Session
!= NULL
) {
2529 IScsiSessionAbort (Private
->Session
);
2534 Tests whether a controller handle is being managed by IScsi driver.
2536 This function tests whether the driver specified by DriverBindingHandle is
2537 currently managing the controller specified by ControllerHandle. This test
2538 is performed by evaluating if the protocol specified by ProtocolGuid is
2539 present on ControllerHandle and is was opened by DriverBindingHandle and Nic
2540 Device handle with an attribute of EFI_OPEN_PROTOCOL_BY_DRIVER.
2541 If ProtocolGuid is NULL, then ASSERT().
2543 @param ControllerHandle A handle for a controller to test.
2544 @param DriverBindingHandle Specifies the driver binding handle for the
2546 @param ProtocolGuid Specifies the protocol that the driver specified
2547 by DriverBindingHandle opens in its Start()
2550 @retval EFI_SUCCESS ControllerHandle is managed by the driver
2551 specified by DriverBindingHandle.
2552 @retval EFI_UNSUPPORTED ControllerHandle is not managed by the driver
2553 specified by DriverBindingHandle.
2558 IScsiTestManagedDevice (
2559 IN EFI_HANDLE ControllerHandle
,
2560 IN EFI_HANDLE DriverBindingHandle
,
2561 IN EFI_GUID
*ProtocolGuid
2565 VOID
*ManagedInterface
;
2566 EFI_HANDLE NicControllerHandle
;
2568 ASSERT (ProtocolGuid
!= NULL
);
2570 NicControllerHandle
= NetLibGetNicHandle (ControllerHandle
, ProtocolGuid
);
2571 if (NicControllerHandle
== NULL
) {
2572 return EFI_UNSUPPORTED
;
2575 Status
= gBS
->OpenProtocol (
2577 (EFI_GUID
*) ProtocolGuid
,
2579 DriverBindingHandle
,
2580 NicControllerHandle
,
2581 EFI_OPEN_PROTOCOL_BY_DRIVER
2583 if (!EFI_ERROR (Status
)) {
2584 gBS
->CloseProtocol (
2586 (EFI_GUID
*) ProtocolGuid
,
2587 DriverBindingHandle
,
2590 return EFI_UNSUPPORTED
;
2593 if (Status
!= EFI_ALREADY_STARTED
) {
2594 return EFI_UNSUPPORTED
;