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_BUFFER_TOO_SMALL The binary buffer is too small to hold the
385 IN OUT UINT8
*BinBuffer
,
386 IN OUT UINT32
*BinLength
,
395 ZeroMem (TemStr
, sizeof (TemStr
));
398 // Find out how many hex characters the string has.
400 if ((HexStr
[0] == '0') && ((HexStr
[1] == 'x') || (HexStr
[1] == 'X'))) {
404 Length
= AsciiStrLen (HexStr
);
407 // Reject an empty hex string; reject a stray nibble.
409 if (Length
== 0 || Length
% 2 != 0) {
410 return EFI_INVALID_PARAMETER
;
413 for (Index
= 0; Index
< Length
; Index
++) {
414 TemStr
[0] = HexStr
[Index
];
415 Digit
= (UINT8
) AsciiStrHexToUint64 (TemStr
);
416 if (Digit
== 0 && TemStr
[0] != '0') {
420 return EFI_INVALID_PARAMETER
;
422 if ((Index
& 1) == 0) {
423 BinBuffer
[Index
/2] = Digit
;
425 BinBuffer
[Index
/2] = (UINT8
) ((BinBuffer
[Index
/2] << 4) + Digit
);
429 *BinLength
= (UINT32
) ((Index
+ 1)/2);
436 Convert the decimal-constant string or hex-constant string into a numerical value.
438 @param[in] Str String in decimal or hex.
440 @return The numerical value.
448 if ((Str
[0] == '0') && ((Str
[1] == 'x') || (Str
[1] == 'X'))) {
451 return AsciiStrHexToUintn (Str
);
454 return AsciiStrDecimalToUintn (Str
);
459 Generate random numbers.
461 @param[in, out] Rand The buffer to contain random numbers.
462 @param[in] RandLength The length of the Rand buffer.
473 while (RandLength
> 0) {
474 Random
= NET_RANDOM (NetRandomInitSeed ());
475 *Rand
++ = (UINT8
) (Random
);
482 Check whether UNDI protocol supports IPv6.
484 @param[in] ControllerHandle Controller handle.
485 @param[in] Image Handle of the image.
486 @param[out] Ipv6Support TRUE if UNDI supports IPv6.
488 @retval EFI_SUCCESS Get the result whether UNDI supports IPv6 by NII or AIP protocol successfully.
489 @retval EFI_NOT_FOUND Don't know whether UNDI supports IPv6 since NII or AIP is not available.
493 IScsiCheckIpv6Support (
494 IN EFI_HANDLE ControllerHandle
,
496 OUT BOOLEAN
*Ipv6Support
500 EFI_ADAPTER_INFORMATION_PROTOCOL
*Aip
;
502 EFI_GUID
*InfoTypesBuffer
;
503 UINTN InfoTypeBufferCount
;
509 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL
*Nii
;
511 ASSERT (Ipv6Support
!= NULL
);
514 // Check whether the UNDI supports IPv6 by NII protocol.
516 Status
= gBS
->OpenProtocol (
518 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
522 EFI_OPEN_PROTOCOL_GET_PROTOCOL
524 if (Status
== EFI_SUCCESS
) {
525 *Ipv6Support
= Nii
->Ipv6Supported
;
530 // Get the NIC handle by SNP protocol.
532 Handle
= NetLibGetSnpHandle (ControllerHandle
, NULL
);
533 if (Handle
== NULL
) {
534 return EFI_NOT_FOUND
;
538 Status
= gBS
->HandleProtocol (
540 &gEfiAdapterInformationProtocolGuid
,
543 if (EFI_ERROR (Status
) || Aip
== NULL
) {
544 return EFI_NOT_FOUND
;
547 InfoTypesBuffer
= NULL
;
548 InfoTypeBufferCount
= 0;
549 Status
= Aip
->GetSupportedTypes (Aip
, &InfoTypesBuffer
, &InfoTypeBufferCount
);
550 if (EFI_ERROR (Status
) || InfoTypesBuffer
== NULL
) {
551 FreePool (InfoTypesBuffer
);
552 return EFI_NOT_FOUND
;
556 for (TypeIndex
= 0; TypeIndex
< InfoTypeBufferCount
; TypeIndex
++) {
557 if (CompareGuid (&InfoTypesBuffer
[TypeIndex
], &gEfiAdapterInfoUndiIpv6SupportGuid
)) {
563 FreePool (InfoTypesBuffer
);
565 return EFI_NOT_FOUND
;
569 // We now have adapter information block.
573 Status
= Aip
->GetInformation (Aip
, &gEfiAdapterInfoUndiIpv6SupportGuid
, &InfoBlock
, &InfoBlockSize
);
574 if (EFI_ERROR (Status
) || InfoBlock
== NULL
) {
575 FreePool (InfoBlock
);
576 return EFI_NOT_FOUND
;
579 *Ipv6Support
= ((EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT
*) InfoBlock
)->Ipv6Support
;
580 FreePool (InfoBlock
);
586 Record the NIC info in global structure.
588 @param[in] Controller The handle of the controller.
589 @param[in] Image Handle of the image.
591 @retval EFI_SUCCESS The operation is completed.
592 @retval EFI_OUT_OF_RESOURCES Do not have sufficient resources to finish this
598 IN EFI_HANDLE Controller
,
603 ISCSI_NIC_INFO
*NicInfo
;
605 EFI_MAC_ADDRESS MacAddr
;
610 // Get MAC address of this network device.
612 Status
= NetLibGetMacAddress (Controller
, &MacAddr
, &HwAddressSize
);
613 if (EFI_ERROR (Status
)) {
618 // Get VLAN ID of this network device.
620 VlanId
= NetLibGetVlanId (Controller
);
623 // Check whether the NIC info already exists. Return directly if so.
625 NET_LIST_FOR_EACH (Entry
, &mPrivate
->NicInfoList
) {
626 NicInfo
= NET_LIST_USER_STRUCT (Entry
, ISCSI_NIC_INFO
, Link
);
627 if (NicInfo
->HwAddressSize
== HwAddressSize
&&
628 CompareMem (&NicInfo
->PermanentAddress
, MacAddr
.Addr
, HwAddressSize
) == 0 &&
629 NicInfo
->VlanId
== VlanId
) {
630 mPrivate
->CurrentNic
= NicInfo
->NicIndex
;
633 // Set IPv6 available flag.
635 Status
= IScsiCheckIpv6Support (Controller
, Image
, &NicInfo
->Ipv6Available
);
636 if (EFI_ERROR (Status
)) {
638 // Fail to get the data whether UNDI supports IPv6.
639 // Set default value to TRUE.
641 NicInfo
->Ipv6Available
= TRUE
;
647 if (mPrivate
->MaxNic
< NicInfo
->NicIndex
) {
648 mPrivate
->MaxNic
= NicInfo
->NicIndex
;
653 // Record the NIC info in private structure.
655 NicInfo
= AllocateZeroPool (sizeof (ISCSI_NIC_INFO
));
656 if (NicInfo
== NULL
) {
657 return EFI_OUT_OF_RESOURCES
;
660 CopyMem (&NicInfo
->PermanentAddress
, MacAddr
.Addr
, HwAddressSize
);
661 NicInfo
->HwAddressSize
= (UINT32
) HwAddressSize
;
662 NicInfo
->VlanId
= VlanId
;
663 NicInfo
->NicIndex
= (UINT8
) (mPrivate
->MaxNic
+ 1);
664 mPrivate
->MaxNic
= NicInfo
->NicIndex
;
667 // Set IPv6 available flag.
669 Status
= IScsiCheckIpv6Support (Controller
, Image
, &NicInfo
->Ipv6Available
);
670 if (EFI_ERROR (Status
)) {
672 // Fail to get the data whether UNDI supports IPv6.
673 // Set default value to TRUE.
675 NicInfo
->Ipv6Available
= TRUE
;
679 // Get the PCI location.
681 IScsiGetNICPciLocation (
684 &NicInfo
->DeviceNumber
,
685 &NicInfo
->FunctionNumber
688 InsertTailList (&mPrivate
->NicInfoList
, &NicInfo
->Link
);
689 mPrivate
->NicCount
++;
691 mPrivate
->CurrentNic
= NicInfo
->NicIndex
;
697 Delete the recorded NIC info from global structure. Also delete corresponding
700 @param[in] Controller The handle of the controller.
702 @retval EFI_SUCCESS The operation is completed.
703 @retval EFI_NOT_FOUND The NIC info to be deleted is not recorded.
708 IN EFI_HANDLE Controller
712 ISCSI_NIC_INFO
*NicInfo
;
714 LIST_ENTRY
*NextEntry
;
715 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
716 ISCSI_NIC_INFO
*ThisNic
;
717 EFI_MAC_ADDRESS MacAddr
;
722 // Get MAC address of this network device.
724 Status
= NetLibGetMacAddress (Controller
, &MacAddr
, &HwAddressSize
);
725 if (EFI_ERROR (Status
)) {
730 // Get VLAN ID of this network device.
732 VlanId
= NetLibGetVlanId (Controller
);
735 // Check whether the NIC information exists.
739 NET_LIST_FOR_EACH (Entry
, &mPrivate
->NicInfoList
) {
740 NicInfo
= NET_LIST_USER_STRUCT (Entry
, ISCSI_NIC_INFO
, Link
);
741 if (NicInfo
->HwAddressSize
== HwAddressSize
&&
742 CompareMem (&NicInfo
->PermanentAddress
, MacAddr
.Addr
, HwAddressSize
) == 0 &&
743 NicInfo
->VlanId
== VlanId
) {
750 if (ThisNic
== NULL
) {
751 return EFI_NOT_FOUND
;
754 mPrivate
->CurrentNic
= ThisNic
->NicIndex
;
756 RemoveEntryList (&ThisNic
->Link
);
758 mPrivate
->NicCount
--;
761 // Remove all attempts related to this NIC.
763 NET_LIST_FOR_EACH_SAFE (Entry
, NextEntry
, &mPrivate
->AttemptConfigs
) {
764 AttemptConfigData
= NET_LIST_USER_STRUCT (Entry
, ISCSI_ATTEMPT_CONFIG_NVDATA
, Link
);
765 if (AttemptConfigData
->NicIndex
== mPrivate
->CurrentNic
) {
766 RemoveEntryList (&AttemptConfigData
->Link
);
767 mPrivate
->AttemptCount
--;
769 if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED_FOR_MPIO
&& mPrivate
->MpioCount
> 0) {
770 if (--mPrivate
->MpioCount
== 0) {
771 mPrivate
->EnableMpio
= FALSE
;
774 if (AttemptConfigData
->AuthenticationType
== ISCSI_AUTH_TYPE_KRB
&& mPrivate
->Krb5MpioCount
> 0) {
775 mPrivate
->Krb5MpioCount
--;
778 } else if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED
&& mPrivate
->SinglePathCount
> 0) {
779 mPrivate
->SinglePathCount
--;
781 if (mPrivate
->ValidSinglePathCount
> 0) {
782 mPrivate
->ValidSinglePathCount
--;
786 FreePool (AttemptConfigData
);
794 Create and initialize the Attempts.
796 @param[in] AttemptNum The number of Attempts will be created.
798 @retval EFI_SUCCESS The Attempts have been created successfully.
799 @retval Others Failed to create the Attempt.
803 IScsiCreateAttempts (
807 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
808 ISCSI_SESSION_CONFIG_NVDATA
*ConfigData
;
809 UINT8
*AttemptConfigOrder
;
810 UINTN AttemptConfigOrderSize
;
811 UINT8
*AttemptOrderTmp
;
816 for (Index
= 1; Index
<= AttemptNum
; Index
++) {
818 // Get the initialized attempt order. This is used to essure creating attempts by order.
820 AttemptConfigOrder
= IScsiGetVariableAndSize (
821 L
"InitialAttemptOrder",
823 &AttemptConfigOrderSize
825 TotalNumber
= AttemptConfigOrderSize
/ sizeof (UINT8
);
826 if (TotalNumber
== AttemptNum
) {
827 Status
= EFI_SUCCESS
;
833 // Append the new created attempt to the end.
835 AttemptOrderTmp
= AllocateZeroPool (TotalNumber
* sizeof (UINT8
));
836 if (AttemptOrderTmp
== NULL
) {
837 if (AttemptConfigOrder
!= NULL
) {
838 FreePool (AttemptConfigOrder
);
840 return EFI_OUT_OF_RESOURCES
;
843 if (AttemptConfigOrder
!= NULL
) {
844 CopyMem (AttemptOrderTmp
, AttemptConfigOrder
, AttemptConfigOrderSize
);
845 FreePool (AttemptConfigOrder
);
848 AttemptOrderTmp
[TotalNumber
- 1] = Index
;
849 AttemptConfigOrder
= AttemptOrderTmp
;
850 AttemptConfigOrderSize
= TotalNumber
* sizeof (UINT8
);
852 Status
= gRT
->SetVariable (
853 L
"InitialAttemptOrder",
855 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
856 AttemptConfigOrderSize
,
859 FreePool (AttemptConfigOrder
);
860 if (EFI_ERROR (Status
)) {
862 "%a: Failed to set 'InitialAttemptOrder' with Guid (%g): "
864 __FUNCTION__
, &gIScsiConfigGuid
, Status
));
869 // Create new Attempt
871 AttemptConfigData
= AllocateZeroPool (sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
));
872 if (AttemptConfigData
== NULL
) {
873 return EFI_OUT_OF_RESOURCES
;
875 ConfigData
= &AttemptConfigData
->SessionConfigData
;
876 ConfigData
->TargetPort
= ISCSI_WELL_KNOWN_PORT
;
877 ConfigData
->ConnectTimeout
= CONNECT_DEFAULT_TIMEOUT
;
878 ConfigData
->ConnectRetryCount
= CONNECT_MIN_RETRY
;
880 AttemptConfigData
->AuthenticationType
= ISCSI_AUTH_TYPE_CHAP
;
881 AttemptConfigData
->AuthConfigData
.CHAP
.CHAPType
= ISCSI_CHAP_UNI
;
883 // Configure the Attempt index and set variable.
885 AttemptConfigData
->AttemptConfigIndex
= Index
;
888 // Set the attempt name according to the order.
891 mPrivate
->PortString
,
892 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
894 (UINTN
) AttemptConfigData
->AttemptConfigIndex
896 UnicodeStrToAsciiStrS (mPrivate
->PortString
, AttemptConfigData
->AttemptName
, ATTEMPT_NAME_SIZE
);
898 Status
= gRT
->SetVariable (
899 mPrivate
->PortString
,
900 &gEfiIScsiInitiatorNameProtocolGuid
,
901 ISCSI_CONFIG_VAR_ATTR
,
902 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
905 FreePool (AttemptConfigData
);
906 if (EFI_ERROR (Status
)) {
908 "%a: Failed to set variable (mPrivate->PortString) with Guid (%g): "
910 __FUNCTION__
, &gEfiIScsiInitiatorNameProtocolGuid
, Status
));
919 Create the iSCSI configuration Keywords for each attempt. You can find the keywords
920 defined in the "x-UEFI-ns" namespace (http://www.uefi.org/confignamespace).
922 @param[in] KeywordNum The number Sets of Keywords will be created.
924 @retval EFI_SUCCESS The operation is completed.
925 @retval Others Failed to create the Keywords.
929 IScsiCreateKeywords (
933 VOID
*StartOpCodeHandle
;
934 EFI_IFR_GUID_LABEL
*StartLabel
;
935 VOID
*EndOpCodeHandle
;
936 EFI_IFR_GUID_LABEL
*EndLabel
;
938 EFI_STRING_ID StringToken
;
940 CHAR16 KeywordId
[32];
943 Status
= IScsiCreateOpCode (
950 if (EFI_ERROR (Status
)) {
951 return EFI_OUT_OF_RESOURCES
;
954 for (Index
= 1; Index
<= KeywordNum
; Index
++) {
956 // Create iSCSIAttemptName Keyword.
958 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_ATTEMPTT_NAME_PROMPT%d", Index
);
959 StringToken
= HiiSetString (
960 mCallbackInfo
->RegisteredHandle
,
965 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIAttemptName:%d", Index
);
966 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
967 HiiCreateStringOpCode (
969 (EFI_QUESTION_ID
) (ATTEMPT_ATTEMPT_NAME_QUESTION_ID
+ (Index
- 1)),
970 CONFIGURATION_VARSTORE_ID
,
971 (UINT16
) (ATTEMPT_ATTEMPT_NAME_VAR_OFFSET
+ ATTEMPT_NAME_SIZE
* (Index
- 1) * sizeof (CHAR16
)),
974 EFI_IFR_FLAG_READ_ONLY
,
982 // Create iSCSIBootEnable Keyword.
984 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_MODE_PROMPT%d", Index
);
985 StringToken
= HiiSetString (
986 mCallbackInfo
->RegisteredHandle
,
991 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIBootEnable:%d", Index
);
992 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
993 HiiCreateNumericOpCode (
995 (EFI_QUESTION_ID
) (ATTEMPT_BOOTENABLE_QUESTION_ID
+ (Index
- 1)),
996 CONFIGURATION_VARSTORE_ID
,
997 (UINT16
) (ATTEMPT_BOOTENABLE_VAR_OFFSET
+ (Index
- 1)),
1001 EFI_IFR_NUMERIC_SIZE_1
,
1009 // Create iSCSIIpAddressType Keyword.
1011 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_IP_MODE_PROMPT%d", Index
);
1012 StringToken
= HiiSetString (
1013 mCallbackInfo
->RegisteredHandle
,
1018 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIIpAddressType:%d", Index
);
1019 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1020 HiiCreateNumericOpCode (
1022 (EFI_QUESTION_ID
) (ATTEMPT_ADDRESS_TYPE_QUESTION_ID
+ (Index
- 1)),
1023 CONFIGURATION_VARSTORE_ID
,
1024 (UINT16
) (ATTEMPT_ADDRESS_TYPE_VAR_OFFSET
+ (Index
- 1)),
1028 EFI_IFR_NUMERIC_SIZE_1
,
1036 // Create iSCSIConnectRetry Keyword.
1038 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CONNECT_RETRY_PROMPT%d", Index
);
1039 StringToken
= HiiSetString (
1040 mCallbackInfo
->RegisteredHandle
,
1045 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIConnectRetry:%d", Index
);
1046 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1047 HiiCreateNumericOpCode (
1049 (EFI_QUESTION_ID
) (ATTEMPT_CONNECT_RETRY_QUESTION_ID
+ (Index
- 1)),
1050 CONFIGURATION_VARSTORE_ID
,
1051 (UINT16
) (ATTEMPT_CONNECT_RETRY_VAR_OFFSET
+ (Index
- 1)),
1055 EFI_IFR_NUMERIC_SIZE_1
,
1063 // Create iSCSIConnectTimeout Keyword.
1065 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CONNECT_TIMEOUT_PROMPT%d", Index
);
1066 StringToken
= HiiSetString (
1067 mCallbackInfo
->RegisteredHandle
,
1072 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIConnectTimeout:%d", Index
);
1073 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1074 HiiCreateNumericOpCode (
1076 (EFI_QUESTION_ID
) (ATTEMPT_CONNECT_TIMEOUT_QUESTION_ID
+ (Index
- 1)),
1077 CONFIGURATION_VARSTORE_ID
,
1078 (UINT16
) (ATTEMPT_CONNECT_TIMEOUT_VAR_OFFSET
+ 2 * (Index
- 1)),
1082 EFI_IFR_NUMERIC_SIZE_2
,
1083 CONNECT_MIN_TIMEOUT
,
1084 CONNECT_MAX_TIMEOUT
,
1090 // Create ISID Keyword.
1092 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_ISID_PROMPT%d", Index
);
1093 StringToken
= HiiSetString (
1094 mCallbackInfo
->RegisteredHandle
,
1099 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIISID:%d", Index
);
1100 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1101 HiiCreateStringOpCode (
1103 (EFI_QUESTION_ID
) (ATTEMPT_ISID_QUESTION_ID
+ (Index
- 1)),
1104 CONFIGURATION_VARSTORE_ID
,
1105 (UINT16
) (ATTEMPT_ISID_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1107 STRING_TOKEN (STR_ISCSI_ISID_HELP
),
1110 ISID_CONFIGURABLE_MIN_LEN
,
1111 ISID_CONFIGURABLE_STORAGE
,
1116 // Create iSCSIInitiatorInfoViaDHCP Keyword.
1118 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_INITIATOR_VIA_DHCP_PROMPT%d", Index
);
1119 StringToken
= HiiSetString (
1120 mCallbackInfo
->RegisteredHandle
,
1125 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIInitiatorInfoViaDHCP:%d", Index
);
1126 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1127 HiiCreateNumericOpCode (
1129 (EFI_QUESTION_ID
) (ATTEMPT_INITIATOR_VIA_DHCP_QUESTION_ID
+ (Index
- 1)),
1130 CONFIGURATION_VARSTORE_ID
,
1131 (UINT16
) (ATTEMPT_INITIATOR_VIA_DHCP_VAR_OFFSET
+ (Index
- 1)),
1143 // Create iSCSIInitiatorIpAddress Keyword.
1145 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_INITIATOR_IP_ADDRESS_PROMPT%d", Index
);
1146 StringToken
= HiiSetString (
1147 mCallbackInfo
->RegisteredHandle
,
1152 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIInitiatorIpAddress:%d", Index
);
1153 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1154 HiiCreateStringOpCode (
1156 (EFI_QUESTION_ID
) (ATTEMPT_INITIATOR_IP_ADDRESS_QUESTION_ID
+ (Index
- 1)),
1157 CONFIGURATION_VARSTORE_ID
,
1158 (UINT16
) (ATTEMPT_INITIATOR_IP_ADDRESS_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1169 // Create iSCSIInitiatorNetmask Keyword.
1171 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_INITIATOR_NET_MASK_PROMPT%d", Index
);
1172 StringToken
= HiiSetString (
1173 mCallbackInfo
->RegisteredHandle
,
1178 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIInitiatorNetmask:%d", Index
);
1179 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1180 HiiCreateStringOpCode (
1182 (EFI_QUESTION_ID
) (ATTEMPT_INITIATOR_NET_MASK_QUESTION_ID
+ (Index
- 1)),
1183 CONFIGURATION_VARSTORE_ID
,
1184 (UINT16
) (ATTEMPT_INITIATOR_NET_MASK_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1195 // Create iSCSIInitiatorGateway Keyword.
1197 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_INITIATOR_GATE_PROMPT%d", Index
);
1198 StringToken
= HiiSetString (
1199 mCallbackInfo
->RegisteredHandle
,
1204 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIInitiatorGateway:%d", Index
);
1205 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1206 HiiCreateStringOpCode (
1208 (EFI_QUESTION_ID
) (ATTEMPT_INITIATOR_GATE_WAY_QUESTION_ID
+ (Index
- 1)),
1209 CONFIGURATION_VARSTORE_ID
,
1210 (UINT16
) (ATTEMPT_INITIATOR_GATE_WAY_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1221 // Create iSCSITargetInfoViaDHCP Keyword.
1223 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_TARGET_VIA_DHCP_PROMPT%d", Index
);
1224 StringToken
= HiiSetString (
1225 mCallbackInfo
->RegisteredHandle
,
1230 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSITargetInfoViaDHCP:%d", Index
);
1231 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1232 HiiCreateNumericOpCode (
1234 (EFI_QUESTION_ID
) (ATTEMPT_TARGET_VIA_DHCP_QUESTION_ID
+ (Index
- 1)),
1235 CONFIGURATION_VARSTORE_ID
,
1236 (UINT16
) (ATTEMPT_TARGET_VIA_DHCP_VAR_OFFSET
+ (Index
- 1)),
1248 // Create iSCSITargetTcpPort Keyword.
1250 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_TARGET_TCP_PORT_PROMPT%d", Index
);
1251 StringToken
= HiiSetString (
1252 mCallbackInfo
->RegisteredHandle
,
1257 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSITargetTcpPort:%d", Index
);
1258 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1259 HiiCreateNumericOpCode (
1261 (EFI_QUESTION_ID
) (ATTEMPT_TARGET_TCP_PORT_QUESTION_ID
+ (Index
- 1)),
1262 CONFIGURATION_VARSTORE_ID
,
1263 (UINT16
) (ATTEMPT_TARGET_TCP_PORT_VAR_OFFSET
+ 2 * (Index
- 1)),
1267 EFI_IFR_NUMERIC_SIZE_2
,
1268 TARGET_PORT_MIN_NUM
,
1269 TARGET_PORT_MAX_NUM
,
1275 // Create iSCSITargetName Keyword.
1277 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_TARGET_NAME_PROMPT%d", Index
);
1278 StringToken
= HiiSetString (
1279 mCallbackInfo
->RegisteredHandle
,
1284 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSITargetName:%d", Index
);
1285 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1286 HiiCreateStringOpCode (
1288 (EFI_QUESTION_ID
) (ATTEMPT_TARGET_NAME_QUESTION_ID
+ (Index
- 1)),
1289 CONFIGURATION_VARSTORE_ID
,
1290 (UINT16
) (ATTEMPT_TARGET_NAME_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1295 ISCSI_NAME_IFR_MIN_SIZE
,
1296 ISCSI_NAME_IFR_MAX_SIZE
,
1301 // Create iSCSITargetIpAddress Keyword.
1303 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_TARGET_IP_ADDRESS_PROMPT%d", Index
);
1304 StringToken
= HiiSetString (
1305 mCallbackInfo
->RegisteredHandle
,
1310 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSITargetIpAddress:%d", Index
);
1311 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1312 HiiCreateStringOpCode (
1314 (EFI_QUESTION_ID
) (ATTEMPT_TARGET_IP_ADDRESS_QUESTION_ID
+ (Index
- 1)),
1315 CONFIGURATION_VARSTORE_ID
,
1316 (UINT16
) (ATTEMPT_TARGET_IP_ADDRESS_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1327 // Create iSCSILUN Keyword.
1329 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_LUN_PROMPT%d", Index
);
1330 StringToken
= HiiSetString (
1331 mCallbackInfo
->RegisteredHandle
,
1336 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSILUN:%d", Index
);
1337 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1338 HiiCreateStringOpCode (
1340 (EFI_QUESTION_ID
) (ATTEMPT_LUN_QUESTION_ID
+ (Index
- 1)),
1341 CONFIGURATION_VARSTORE_ID
,
1342 (UINT16
) (ATTEMPT_LUN_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1353 // Create iSCSIAuthenticationMethod Keyword.
1355 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_AUTHENTICATION_METHOD_PROMPT%d", Index
);
1356 StringToken
= HiiSetString (
1357 mCallbackInfo
->RegisteredHandle
,
1362 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIAuthenticationMethod:%d", Index
);
1363 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1364 HiiCreateNumericOpCode (
1366 (EFI_QUESTION_ID
) (ATTEMPT_AUTHENTICATION_METHOD_QUESTION_ID
+ (Index
- 1)),
1367 CONFIGURATION_VARSTORE_ID
,
1368 (UINT16
) (ATTEMPT_AUTHENTICATION_METHOD_VAR_OFFSET
+ (Index
- 1)),
1380 // Create iSCSIChapType Keyword.
1382 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHARTYPE_PROMPT%d", Index
);
1383 StringToken
= HiiSetString (
1384 mCallbackInfo
->RegisteredHandle
,
1389 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIChapType:%d", Index
);
1390 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1391 HiiCreateNumericOpCode (
1393 (EFI_QUESTION_ID
) (ATTEMPT_CHARTYPE_QUESTION_ID
+ (Index
- 1)),
1394 CONFIGURATION_VARSTORE_ID
,
1395 (UINT16
) (ATTEMPT_CHARTYPE_VAR_OFFSET
+ (Index
- 1)),
1407 // Create iSCSIChapUsername Keyword.
1409 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHAR_USER_NAME_PROMPT%d", Index
);
1410 StringToken
= HiiSetString (
1411 mCallbackInfo
->RegisteredHandle
,
1416 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIChapUsername:%d", Index
);
1417 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1418 HiiCreateStringOpCode (
1420 (EFI_QUESTION_ID
) (ATTEMPT_CHAR_USER_NAME_QUESTION_ID
+ (Index
- 1)),
1421 CONFIGURATION_VARSTORE_ID
,
1422 (UINT16
) (ATTEMPT_CHAR_USER_NAME_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1428 ISCSI_CHAP_NAME_MAX_LEN
,
1433 // Create iSCSIChapSecret Keyword.
1435 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHAR_SECRET_PROMPT%d", Index
);
1436 StringToken
= HiiSetString (
1437 mCallbackInfo
->RegisteredHandle
,
1442 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIChapSecret:%d", Index
);
1443 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1444 HiiCreateStringOpCode (
1446 (EFI_QUESTION_ID
) (ATTEMPT_CHAR_SECRET_QUESTION_ID
+ (Index
- 1)),
1447 CONFIGURATION_VARSTORE_ID
,
1448 (UINT16
) (ATTEMPT_CHAR_SECRET_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1453 ISCSI_CHAP_SECRET_MIN_LEN
,
1454 ISCSI_CHAP_SECRET_MAX_LEN
,
1459 // Create iSCSIReverseChapUsername Keyword.
1461 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHAR_REVERSE_USER_NAME_PROMPT%d", Index
);
1462 StringToken
= HiiSetString (
1463 mCallbackInfo
->RegisteredHandle
,
1468 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIReverseChapUsername:%d", Index
);
1469 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1470 HiiCreateStringOpCode (
1472 (EFI_QUESTION_ID
) (ATTEMPT_CHAR_REVERSE_USER_NAME_QUESTION_ID
+ (Index
- 1)),
1473 CONFIGURATION_VARSTORE_ID
,
1474 (UINT16
) (ATTEMPT_CHAR_REVERSE_USER_NAME_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1480 ISCSI_CHAP_NAME_MAX_LEN
,
1485 // Create iSCSIReverseChapSecret Keyword.
1487 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHAR_REVERSE_SECRET_PROMPT%d", Index
);
1488 StringToken
= HiiSetString (
1489 mCallbackInfo
->RegisteredHandle
,
1494 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIReverseChapSecret:%d", Index
);
1495 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1496 HiiCreateStringOpCode (
1498 (EFI_QUESTION_ID
) (ATTEMPT_CHAR_REVERSE_SECRET_QUESTION_ID
+ (Index
- 1)),
1499 CONFIGURATION_VARSTORE_ID
,
1500 (UINT16
) (ATTEMPT_CHAR_REVERSE_SECRET_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1505 ISCSI_CHAP_SECRET_MIN_LEN
,
1506 ISCSI_CHAP_SECRET_MAX_LEN
,
1511 Status
= HiiUpdateForm (
1512 mCallbackInfo
->RegisteredHandle
, // HII handle
1513 &gIScsiConfigGuid
, // Formset GUID
1514 FORMID_ATTEMPT_FORM
, // Form ID
1515 StartOpCodeHandle
, // Label for where to insert opcodes
1516 EndOpCodeHandle
// Replace data
1519 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1520 HiiFreeOpCodeHandle (EndOpCodeHandle
);
1527 Free the attempt configure data variable.
1531 IScsiCleanAttemptVariable (
1535 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
1536 UINT8
*AttemptConfigOrder
;
1537 UINTN AttemptConfigOrderSize
;
1541 // Get the initialized attempt order.
1543 AttemptConfigOrder
= IScsiGetVariableAndSize (
1544 L
"InitialAttemptOrder",
1546 &AttemptConfigOrderSize
1548 if (AttemptConfigOrder
== NULL
|| AttemptConfigOrderSize
== 0) {
1552 for (Index
= 1; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
1554 mPrivate
->PortString
,
1555 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
1561 mPrivate
->PortString
,
1562 &gEfiIScsiInitiatorNameProtocolGuid
,
1563 (VOID
**)&AttemptConfigData
,
1567 if (AttemptConfigData
!= NULL
) {
1569 mPrivate
->PortString
,
1570 &gEfiIScsiInitiatorNameProtocolGuid
,
1581 Get the recorded NIC info from global structure by the Index.
1583 @param[in] NicIndex The index indicates the position of NIC info.
1585 @return Pointer to the NIC info, or NULL if not found.
1589 IScsiGetNicInfoByIndex (
1594 ISCSI_NIC_INFO
*NicInfo
;
1596 NET_LIST_FOR_EACH (Entry
, &mPrivate
->NicInfoList
) {
1597 NicInfo
= NET_LIST_USER_STRUCT (Entry
, ISCSI_NIC_INFO
, Link
);
1598 if (NicInfo
->NicIndex
== NicIndex
) {
1608 Get the NIC's PCI location and return it according to the composited
1609 format defined in iSCSI Boot Firmware Table.
1611 @param[in] Controller The handle of the controller.
1612 @param[out] Bus The bus number.
1613 @param[out] Device The device number.
1614 @param[out] Function The function number.
1616 @return The composited representation of the NIC PCI location.
1620 IScsiGetNICPciLocation (
1621 IN EFI_HANDLE Controller
,
1628 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1629 EFI_HANDLE PciIoHandle
;
1630 EFI_PCI_IO_PROTOCOL
*PciIo
;
1633 Status
= gBS
->HandleProtocol (
1635 &gEfiDevicePathProtocolGuid
,
1636 (VOID
**) &DevicePath
1638 if (EFI_ERROR (Status
)) {
1642 Status
= gBS
->LocateDevicePath (
1643 &gEfiPciIoProtocolGuid
,
1647 if (EFI_ERROR (Status
)) {
1651 Status
= gBS
->HandleProtocol (PciIoHandle
, &gEfiPciIoProtocolGuid
, (VOID
**) &PciIo
);
1652 if (EFI_ERROR (Status
)) {
1656 Status
= PciIo
->GetLocation (PciIo
, &Segment
, Bus
, Device
, Function
);
1657 if (EFI_ERROR (Status
)) {
1661 return (UINT16
) ((*Bus
<< 8) | (*Device
<< 3) | *Function
);
1666 Read the EFI variable (VendorGuid/Name) and return a dynamically allocated
1667 buffer, and the size of the buffer. If failure, return NULL.
1669 @param[in] Name String part of EFI variable name.
1670 @param[in] VendorGuid GUID part of EFI variable name.
1671 @param[out] VariableSize Returns the size of the EFI variable that was read.
1673 @return Dynamically allocated memory that contains a copy of the EFI variable.
1674 @return Caller is responsible freeing the buffer.
1675 @retval NULL Variable was not read.
1679 IScsiGetVariableAndSize (
1681 IN EFI_GUID
*VendorGuid
,
1682 OUT UINTN
*VariableSize
1692 // Pass in a zero size buffer to find the required buffer size.
1695 Status
= gRT
->GetVariable (Name
, VendorGuid
, NULL
, &BufferSize
, Buffer
);
1696 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1698 // Allocate the buffer to return
1700 Buffer
= AllocateZeroPool (BufferSize
);
1701 if (Buffer
== NULL
) {
1705 // Read variable into the allocated buffer.
1707 Status
= gRT
->GetVariable (Name
, VendorGuid
, NULL
, &BufferSize
, Buffer
);
1708 if (EFI_ERROR (Status
)) {
1713 *VariableSize
= BufferSize
;
1719 Create the iSCSI driver data.
1721 @param[in] Image The handle of the driver image.
1722 @param[in] Controller The handle of the controller.
1724 @return The iSCSI driver data created.
1725 @retval NULL Other errors as indicated.
1729 IScsiCreateDriverData (
1730 IN EFI_HANDLE Image
,
1731 IN EFI_HANDLE Controller
1734 ISCSI_DRIVER_DATA
*Private
;
1737 Private
= AllocateZeroPool (sizeof (ISCSI_DRIVER_DATA
));
1738 if (Private
== NULL
) {
1742 Private
->Signature
= ISCSI_DRIVER_DATA_SIGNATURE
;
1743 Private
->Image
= Image
;
1744 Private
->Controller
= Controller
;
1745 Private
->Session
= NULL
;
1748 // Create an event to be signaled when the BS to RT transition is triggerd so
1749 // as to abort the iSCSI session.
1751 Status
= gBS
->CreateEventEx (
1754 IScsiOnExitBootService
,
1756 &gEfiEventExitBootServicesGuid
,
1757 &Private
->ExitBootServiceEvent
1759 if (EFI_ERROR (Status
)) {
1764 Private
->ExtScsiPassThruHandle
= NULL
;
1765 CopyMem(&Private
->IScsiExtScsiPassThru
, &gIScsiExtScsiPassThruProtocolTemplate
, sizeof(EFI_EXT_SCSI_PASS_THRU_PROTOCOL
));
1768 // 0 is designated to the TargetId, so use another value for the AdapterId.
1770 Private
->ExtScsiPassThruMode
.AdapterId
= 2;
1771 Private
->ExtScsiPassThruMode
.Attributes
= EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL
| EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL
;
1772 Private
->ExtScsiPassThruMode
.IoAlign
= 4;
1773 Private
->IScsiExtScsiPassThru
.Mode
= &Private
->ExtScsiPassThruMode
;
1780 Clean the iSCSI driver data.
1782 @param[in] Private The iSCSI driver data.
1784 @retval EFI_SUCCESS The clean operation is successful.
1785 @retval Others Other errors as indicated.
1789 IScsiCleanDriverData (
1790 IN ISCSI_DRIVER_DATA
*Private
1795 Status
= EFI_SUCCESS
;
1797 if (Private
->DevicePath
!= NULL
) {
1798 Status
= gBS
->UninstallProtocolInterface (
1799 Private
->ExtScsiPassThruHandle
,
1800 &gEfiDevicePathProtocolGuid
,
1803 if (EFI_ERROR (Status
)) {
1807 FreePool (Private
->DevicePath
);
1810 if (Private
->ExtScsiPassThruHandle
!= NULL
) {
1811 Status
= gBS
->UninstallProtocolInterface (
1812 Private
->ExtScsiPassThruHandle
,
1813 &gEfiExtScsiPassThruProtocolGuid
,
1814 &Private
->IScsiExtScsiPassThru
1816 if (!EFI_ERROR (Status
)) {
1817 mPrivate
->OneSessionEstablished
= FALSE
;
1822 if (Private
->ExitBootServiceEvent
!= NULL
) {
1823 gBS
->CloseEvent (Private
->ExitBootServiceEvent
);
1826 mCallbackInfo
->Current
= NULL
;
1833 Check wheather the Controller handle is configured to use DHCP protocol.
1835 @param[in] Controller The handle of the controller.
1836 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
1838 @retval TRUE The handle of the controller need the Dhcp protocol.
1839 @retval FALSE The handle of the controller does not need the Dhcp protocol.
1843 IScsiDhcpIsConfigured (
1844 IN EFI_HANDLE Controller
,
1848 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptTmp
;
1849 UINT8
*AttemptConfigOrder
;
1850 UINTN AttemptConfigOrderSize
;
1853 EFI_MAC_ADDRESS MacAddr
;
1854 UINTN HwAddressSize
;
1856 CHAR16 MacString
[ISCSI_MAX_MAC_STRING_LEN
];
1857 CHAR16 AttemptMacString
[ISCSI_MAX_MAC_STRING_LEN
];
1858 CHAR16 AttemptName
[ISCSI_NAME_IFR_MAX_SIZE
];
1860 AttemptConfigOrder
= IScsiGetVariableAndSize (
1863 &AttemptConfigOrderSize
1865 if (AttemptConfigOrder
== NULL
|| AttemptConfigOrderSize
== 0) {
1870 // Get MAC address of this network device.
1872 Status
= NetLibGetMacAddress (Controller
, &MacAddr
, &HwAddressSize
);
1873 if(EFI_ERROR (Status
)) {
1877 // Get VLAN ID of this network device.
1879 VlanId
= NetLibGetVlanId (Controller
);
1880 IScsiMacAddrToStr (&MacAddr
, (UINT32
) HwAddressSize
, VlanId
, MacString
);
1882 for (Index
= 0; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
1887 (UINTN
) AttemptConfigOrder
[Index
]
1889 Status
= GetVariable2 (
1891 &gEfiIScsiInitiatorNameProtocolGuid
,
1892 (VOID
**)&AttemptTmp
,
1895 if(AttemptTmp
== NULL
|| EFI_ERROR (Status
)) {
1899 ASSERT (AttemptConfigOrder
[Index
] == AttemptTmp
->AttemptConfigIndex
);
1901 if (AttemptTmp
->SessionConfigData
.Enabled
== ISCSI_DISABLED
) {
1902 FreePool (AttemptTmp
);
1906 if (AttemptTmp
->SessionConfigData
.IpMode
!= IP_MODE_AUTOCONFIG
&&
1907 AttemptTmp
->SessionConfigData
.IpMode
!= ((IpVersion
== IP_VERSION_4
) ? IP_MODE_IP4
: IP_MODE_IP6
)) {
1908 FreePool (AttemptTmp
);
1912 AsciiStrToUnicodeStrS (AttemptTmp
->MacString
, AttemptMacString
, sizeof (AttemptMacString
) / sizeof (AttemptMacString
[0]));
1914 if (AttemptTmp
->Actived
== ISCSI_ACTIVE_DISABLED
|| StrCmp (MacString
, AttemptMacString
)) {
1918 if(AttemptTmp
->SessionConfigData
.IpMode
== IP_MODE_AUTOCONFIG
||
1919 AttemptTmp
->SessionConfigData
.InitiatorInfoFromDhcp
== TRUE
||
1920 AttemptTmp
->SessionConfigData
.TargetInfoFromDhcp
== TRUE
) {
1921 FreePool (AttemptTmp
);
1922 FreePool (AttemptConfigOrder
);
1926 FreePool (AttemptTmp
);
1929 FreePool (AttemptConfigOrder
);
1934 Check whether the Controller handle is configured to use DNS protocol.
1936 @param[in] Controller The handle of the controller.
1938 @retval TRUE The handle of the controller need the Dns protocol.
1939 @retval FALSE The handle of the controller does not need the Dns protocol.
1943 IScsiDnsIsConfigured (
1944 IN EFI_HANDLE Controller
1947 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptTmp
;
1948 UINT8
*AttemptConfigOrder
;
1949 UINTN AttemptConfigOrderSize
;
1952 EFI_MAC_ADDRESS MacAddr
;
1953 UINTN HwAddressSize
;
1955 CHAR16 AttemptMacString
[ISCSI_MAX_MAC_STRING_LEN
];
1956 CHAR16 MacString
[ISCSI_MAX_MAC_STRING_LEN
];
1957 CHAR16 AttemptName
[ISCSI_NAME_IFR_MAX_SIZE
];
1959 AttemptConfigOrder
= IScsiGetVariableAndSize (
1962 &AttemptConfigOrderSize
1964 if (AttemptConfigOrder
== NULL
|| AttemptConfigOrderSize
== 0) {
1969 // Get MAC address of this network device.
1971 Status
= NetLibGetMacAddress (Controller
, &MacAddr
, &HwAddressSize
);
1972 if(EFI_ERROR (Status
)) {
1976 // Get VLAN ID of this network device.
1978 VlanId
= NetLibGetVlanId (Controller
);
1979 IScsiMacAddrToStr (&MacAddr
, (UINT32
) HwAddressSize
, VlanId
, MacString
);
1981 for (Index
= 0; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
1986 (UINTN
) AttemptConfigOrder
[Index
]
1989 Status
= GetVariable2 (
1991 &gEfiIScsiInitiatorNameProtocolGuid
,
1992 (VOID
**)&AttemptTmp
,
1995 if(AttemptTmp
== NULL
|| EFI_ERROR (Status
)) {
1999 ASSERT (AttemptConfigOrder
[Index
] == AttemptTmp
->AttemptConfigIndex
);
2001 AsciiStrToUnicodeStrS (AttemptTmp
->MacString
, AttemptMacString
, sizeof (AttemptMacString
) / sizeof (AttemptMacString
[0]));
2003 if (AttemptTmp
->SessionConfigData
.Enabled
== ISCSI_DISABLED
|| StrCmp (MacString
, AttemptMacString
)) {
2004 FreePool (AttemptTmp
);
2008 if (AttemptTmp
->SessionConfigData
.DnsMode
|| AttemptTmp
->SessionConfigData
.TargetInfoFromDhcp
) {
2009 FreePool (AttemptTmp
);
2010 FreePool (AttemptConfigOrder
);
2013 FreePool (AttemptTmp
);
2019 FreePool (AttemptConfigOrder
);
2025 Get the various configuration data.
2027 @param[in] Private The iSCSI driver data.
2029 @retval EFI_SUCCESS The configuration data is retrieved.
2030 @retval EFI_NOT_FOUND This iSCSI driver is not configured yet.
2031 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
2035 IScsiGetConfigData (
2036 IN ISCSI_DRIVER_DATA
*Private
2040 CHAR16 MacString
[ISCSI_MAX_MAC_STRING_LEN
];
2041 CHAR16 AttemptMacString
[ISCSI_MAX_MAC_STRING_LEN
];
2043 ISCSI_NIC_INFO
*NicInfo
;
2044 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
2045 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptTmp
;
2046 UINT8
*AttemptConfigOrder
;
2047 UINTN AttemptConfigOrderSize
;
2048 CHAR16 IScsiMode
[64];
2052 // There should be at least one attempt configured.
2054 AttemptConfigOrder
= IScsiGetVariableAndSize (
2057 &AttemptConfigOrderSize
2059 if (AttemptConfigOrder
== NULL
|| AttemptConfigOrderSize
== 0) {
2060 return EFI_NOT_FOUND
;
2064 // Get the iSCSI Initiator Name.
2066 mPrivate
->InitiatorNameLength
= ISCSI_NAME_MAX_SIZE
;
2067 Status
= gIScsiInitiatorName
.Get (
2068 &gIScsiInitiatorName
,
2069 &mPrivate
->InitiatorNameLength
,
2070 mPrivate
->InitiatorName
2072 if (EFI_ERROR (Status
)) {
2077 // Get the normal configuration.
2079 for (Index
= 0; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
2082 // Check whether the attempt exists in AttemptConfig.
2084 AttemptTmp
= IScsiConfigGetAttemptByConfigIndex (AttemptConfigOrder
[Index
]);
2085 if (AttemptTmp
!= NULL
&& AttemptTmp
->SessionConfigData
.Enabled
== ISCSI_DISABLED
) {
2087 } else if (AttemptTmp
!= NULL
&& AttemptTmp
->SessionConfigData
.Enabled
!= ISCSI_DISABLED
) {
2089 // Check the autoconfig path to see whether it should be retried.
2091 if (AttemptTmp
->SessionConfigData
.IpMode
== IP_MODE_AUTOCONFIG
&&
2092 !AttemptTmp
->AutoConfigureSuccess
) {
2093 if (mPrivate
->Ipv6Flag
&&
2094 AttemptTmp
->AutoConfigureMode
== IP_MODE_AUTOCONFIG_IP6
) {
2096 // Autoconfigure for IP6 already attempted but failed. Do not try again.
2099 } else if (!mPrivate
->Ipv6Flag
&&
2100 AttemptTmp
->AutoConfigureMode
== IP_MODE_AUTOCONFIG_IP4
) {
2102 // Autoconfigure for IP4 already attempted but failed. Do not try again.
2107 // Try another approach for this autoconfigure path.
2109 AttemptTmp
->AutoConfigureMode
=
2110 (UINT8
) (mPrivate
->Ipv6Flag
? IP_MODE_AUTOCONFIG_IP6
: IP_MODE_AUTOCONFIG_IP4
);
2111 AttemptTmp
->SessionConfigData
.InitiatorInfoFromDhcp
= TRUE
;
2112 AttemptTmp
->SessionConfigData
.TargetInfoFromDhcp
= TRUE
;
2113 AttemptTmp
->DhcpSuccess
= FALSE
;
2116 // Get some information from the dhcp server.
2118 if (!mPrivate
->Ipv6Flag
) {
2119 Status
= IScsiDoDhcp (Private
->Image
, Private
->Controller
, AttemptTmp
);
2120 if (!EFI_ERROR (Status
)) {
2121 AttemptTmp
->DhcpSuccess
= TRUE
;
2124 Status
= IScsiDoDhcp6 (Private
->Image
, Private
->Controller
, AttemptTmp
);
2125 if (!EFI_ERROR (Status
)) {
2126 AttemptTmp
->DhcpSuccess
= TRUE
;
2131 // Refresh the state of this attempt to NVR.
2134 mPrivate
->PortString
,
2135 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2137 (UINTN
) AttemptTmp
->AttemptConfigIndex
2141 mPrivate
->PortString
,
2142 &gEfiIScsiInitiatorNameProtocolGuid
,
2143 ISCSI_CONFIG_VAR_ATTR
,
2144 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
2150 } else if (AttemptTmp
->SessionConfigData
.InitiatorInfoFromDhcp
&&
2151 !AttemptTmp
->ValidPath
&&
2152 AttemptTmp
->NicIndex
== mPrivate
->CurrentNic
) {
2154 // If the attempt associates with the current NIC, we can
2155 // get DHCP information for already added, but failed, attempt.
2157 AttemptTmp
->DhcpSuccess
= FALSE
;
2158 if (!mPrivate
->Ipv6Flag
&& (AttemptTmp
->SessionConfigData
.IpMode
== IP_MODE_IP4
)) {
2159 Status
= IScsiDoDhcp (Private
->Image
, Private
->Controller
, AttemptTmp
);
2160 if (!EFI_ERROR (Status
)) {
2161 AttemptTmp
->DhcpSuccess
= TRUE
;
2163 } else if (mPrivate
->Ipv6Flag
&& (AttemptTmp
->SessionConfigData
.IpMode
== IP_MODE_IP6
)) {
2164 Status
= IScsiDoDhcp6 (Private
->Image
, Private
->Controller
, AttemptTmp
);
2165 if (!EFI_ERROR (Status
)) {
2166 AttemptTmp
->DhcpSuccess
= TRUE
;
2171 // Refresh the state of this attempt to NVR.
2174 mPrivate
->PortString
,
2175 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2177 (UINTN
) AttemptTmp
->AttemptConfigIndex
2181 mPrivate
->PortString
,
2182 &gEfiIScsiInitiatorNameProtocolGuid
,
2183 ISCSI_CONFIG_VAR_ATTR
,
2184 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
2196 // This attempt does not exist in AttemptConfig. Try to add a new one.
2199 NicInfo
= IScsiGetNicInfoByIndex (mPrivate
->CurrentNic
);
2200 ASSERT (NicInfo
!= NULL
);
2201 IScsiMacAddrToStr (&NicInfo
->PermanentAddress
, NicInfo
->HwAddressSize
, NicInfo
->VlanId
, MacString
);
2203 mPrivate
->PortString
,
2204 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2206 (UINTN
) AttemptConfigOrder
[Index
]
2210 mPrivate
->PortString
,
2211 &gEfiIScsiInitiatorNameProtocolGuid
,
2212 (VOID
**)&AttemptConfigData
,
2215 AsciiStrToUnicodeStrS (AttemptConfigData
->MacString
, AttemptMacString
, sizeof (AttemptMacString
) / sizeof (AttemptMacString
[0]));
2217 if (AttemptConfigData
== NULL
|| AttemptConfigData
->Actived
== ISCSI_ACTIVE_DISABLED
||
2218 StrCmp (MacString
, AttemptMacString
)) {
2222 ASSERT (AttemptConfigOrder
[Index
] == AttemptConfigData
->AttemptConfigIndex
);
2224 AttemptConfigData
->NicIndex
= NicInfo
->NicIndex
;
2225 AttemptConfigData
->DhcpSuccess
= FALSE
;
2226 AttemptConfigData
->ValidiBFTPath
= (BOOLEAN
) (mPrivate
->EnableMpio
? TRUE
: FALSE
);
2227 AttemptConfigData
->ValidPath
= FALSE
;
2229 if (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_AUTOCONFIG
) {
2230 AttemptConfigData
->SessionConfigData
.InitiatorInfoFromDhcp
= TRUE
;
2231 AttemptConfigData
->SessionConfigData
.TargetInfoFromDhcp
= TRUE
;
2233 AttemptConfigData
->AutoConfigureMode
=
2234 (UINT8
) (mPrivate
->Ipv6Flag
? IP_MODE_AUTOCONFIG_IP6
: IP_MODE_AUTOCONFIG_IP4
);
2235 AttemptConfigData
->AutoConfigureSuccess
= FALSE
;
2239 // Get some information from dhcp server.
2241 if (AttemptConfigData
->SessionConfigData
.Enabled
!= ISCSI_DISABLED
&&
2242 AttemptConfigData
->SessionConfigData
.InitiatorInfoFromDhcp
) {
2244 if (!mPrivate
->Ipv6Flag
&&
2245 (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_IP4
||
2246 AttemptConfigData
->AutoConfigureMode
== IP_MODE_AUTOCONFIG_IP4
)) {
2247 Status
= IScsiDoDhcp (Private
->Image
, Private
->Controller
, AttemptConfigData
);
2248 if (!EFI_ERROR (Status
)) {
2249 AttemptConfigData
->DhcpSuccess
= TRUE
;
2251 } else if (mPrivate
->Ipv6Flag
&&
2252 (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_IP6
||
2253 AttemptConfigData
->AutoConfigureMode
== IP_MODE_AUTOCONFIG_IP6
)) {
2254 Status
= IScsiDoDhcp6 (Private
->Image
, Private
->Controller
, AttemptConfigData
);
2255 if (!EFI_ERROR (Status
)) {
2256 AttemptConfigData
->DhcpSuccess
= TRUE
;
2261 // Refresh the state of this attempt to NVR.
2264 mPrivate
->PortString
,
2265 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2267 (UINTN
) AttemptConfigData
->AttemptConfigIndex
2271 mPrivate
->PortString
,
2272 &gEfiIScsiInitiatorNameProtocolGuid
,
2273 ISCSI_CONFIG_VAR_ATTR
,
2274 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
2280 // Update Attempt Help Info.
2283 if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_DISABLED
) {
2284 UnicodeSPrint (IScsiMode
, 64, L
"Disabled");
2285 } else if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED
) {
2286 UnicodeSPrint (IScsiMode
, 64, L
"Enabled");
2287 } else if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED_FOR_MPIO
) {
2288 UnicodeSPrint (IScsiMode
, 64, L
"Enabled for MPIO");
2291 if (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_IP4
) {
2292 UnicodeSPrint (IpMode
, 64, L
"IP4");
2293 } else if (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_IP6
) {
2294 UnicodeSPrint (IpMode
, 64, L
"IP6");
2295 } else if (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_AUTOCONFIG
) {
2296 UnicodeSPrint (IpMode
, 64, L
"Autoconfigure");
2300 mPrivate
->PortString
,
2301 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2302 L
"MAC: %s, PFA: Bus %d | Dev %d | Func %d, iSCSI mode: %s, IP version: %s",
2305 NicInfo
->DeviceNumber
,
2306 NicInfo
->FunctionNumber
,
2311 AttemptConfigData
->AttemptTitleHelpToken
= HiiSetString (
2312 mCallbackInfo
->RegisteredHandle
,
2314 mPrivate
->PortString
,
2317 if (AttemptConfigData
->AttemptTitleHelpToken
== 0) {
2318 return EFI_OUT_OF_RESOURCES
;
2322 // Record the attempt in global link list.
2324 InsertTailList (&mPrivate
->AttemptConfigs
, &AttemptConfigData
->Link
);
2325 mPrivate
->AttemptCount
++;
2327 if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED_FOR_MPIO
) {
2328 mPrivate
->MpioCount
++;
2329 mPrivate
->EnableMpio
= TRUE
;
2331 if (AttemptConfigData
->AuthenticationType
== ISCSI_AUTH_TYPE_KRB
) {
2332 mPrivate
->Krb5MpioCount
++;
2334 } else if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED
) {
2335 mPrivate
->SinglePathCount
++;
2340 // Reorder the AttemptConfig by the configured order.
2342 for (Index
= 0; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
2343 AttemptConfigData
= IScsiConfigGetAttemptByConfigIndex (AttemptConfigOrder
[Index
]);
2344 if (AttemptConfigData
== NULL
) {
2348 RemoveEntryList (&AttemptConfigData
->Link
);
2349 InsertTailList (&mPrivate
->AttemptConfigs
, &AttemptConfigData
->Link
);
2353 // Update the Main Form.
2355 IScsiConfigUpdateAttempt ();
2357 FreePool (AttemptConfigOrder
);
2360 // There should be at least one attempt configuration.
2362 if (!mPrivate
->EnableMpio
) {
2363 if (mPrivate
->SinglePathCount
== 0) {
2364 return EFI_NOT_FOUND
;
2366 mPrivate
->ValidSinglePathCount
= mPrivate
->SinglePathCount
;
2374 Get the device path of the iSCSI tcp connection and update it.
2376 @param Session The iSCSI session.
2378 @return The updated device path.
2379 @retval NULL Other errors as indicated.
2382 EFI_DEVICE_PATH_PROTOCOL
*
2383 IScsiGetTcpConnDevicePath (
2384 IN ISCSI_SESSION
*Session
2387 ISCSI_CONNECTION
*Conn
;
2388 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
2390 EFI_DEV_PATH
*DPathNode
;
2393 if (Session
->State
!= SESSION_STATE_LOGGED_IN
) {
2397 Conn
= NET_LIST_USER_STRUCT_S (
2398 Session
->Conns
.ForwardLink
,
2401 ISCSI_CONNECTION_SIGNATURE
2404 Status
= gBS
->HandleProtocol (
2406 &gEfiDevicePathProtocolGuid
,
2407 (VOID
**) &DevicePath
2409 if (EFI_ERROR (Status
)) {
2415 DevicePath
= DuplicateDevicePath (DevicePath
);
2416 if (DevicePath
== NULL
) {
2420 DPathNode
= (EFI_DEV_PATH
*) DevicePath
;
2422 while (!IsDevicePathEnd (&DPathNode
->DevPath
)) {
2423 if (DevicePathType (&DPathNode
->DevPath
) == MESSAGING_DEVICE_PATH
) {
2424 if (!Conn
->Ipv6Flag
&& DevicePathSubType (&DPathNode
->DevPath
) == MSG_IPv4_DP
) {
2425 DPathNode
->Ipv4
.LocalPort
= 0;
2427 DPathNode
->Ipv4
.StaticIpAddress
=
2428 (BOOLEAN
) (!Session
->ConfigData
->SessionConfigData
.InitiatorInfoFromDhcp
);
2431 // Add a judgement here to support previous versions of IPv4_DEVICE_PATH.
2432 // In previous versions of IPv4_DEVICE_PATH, GatewayIpAddress and SubnetMask
2434 // In new version of IPv4_DEVICE_PATH, structure length is 27.
2437 PathLen
= DevicePathNodeLength (&DPathNode
->Ipv4
);
2439 if (PathLen
== IP4_NODE_LEN_NEW_VERSIONS
) {
2442 &DPathNode
->Ipv4
.GatewayIpAddress
,
2443 &Session
->ConfigData
->SessionConfigData
.Gateway
2447 &DPathNode
->Ipv4
.SubnetMask
,
2448 &Session
->ConfigData
->SessionConfigData
.SubnetMask
2453 } else if (Conn
->Ipv6Flag
&& DevicePathSubType (&DPathNode
->DevPath
) == MSG_IPv6_DP
) {
2454 DPathNode
->Ipv6
.LocalPort
= 0;
2457 // Add a judgement here to support previous versions of IPv6_DEVICE_PATH.
2458 // In previous versions of IPv6_DEVICE_PATH, IpAddressOrigin, PrefixLength
2459 // and GatewayIpAddress do not exist.
2460 // In new version of IPv6_DEVICE_PATH, structure length is 60, while in
2461 // old versions, the length is 43.
2464 PathLen
= DevicePathNodeLength (&DPathNode
->Ipv6
);
2466 if (PathLen
== IP6_NODE_LEN_NEW_VERSIONS
) {
2468 DPathNode
->Ipv6
.IpAddressOrigin
= 0;
2469 DPathNode
->Ipv6
.PrefixLength
= IP6_PREFIX_LENGTH
;
2470 ZeroMem (&DPathNode
->Ipv6
.GatewayIpAddress
, sizeof (EFI_IPv6_ADDRESS
));
2472 else if (PathLen
== IP6_NODE_LEN_OLD_VERSIONS
) {
2475 // StaticIPAddress is a field in old versions of IPv6_DEVICE_PATH, while ignored in new
2476 // version. Set StaticIPAddress through its' offset in old IPv6_DEVICE_PATH.
2478 *((UINT8
*)(&DPathNode
->Ipv6
) + IP6_OLD_IPADDRESS_OFFSET
) =
2479 (BOOLEAN
) (!Session
->ConfigData
->SessionConfigData
.InitiatorInfoFromDhcp
);
2486 DPathNode
= (EFI_DEV_PATH
*) NextDevicePathNode (&DPathNode
->DevPath
);
2494 Abort the session when the transition from BS to RT is initiated.
2496 @param[in] Event The event signaled.
2497 @param[in] Context The iSCSI driver data.
2502 IScsiOnExitBootService (
2507 ISCSI_DRIVER_DATA
*Private
;
2509 Private
= (ISCSI_DRIVER_DATA
*) Context
;
2511 gBS
->CloseEvent (Private
->ExitBootServiceEvent
);
2512 Private
->ExitBootServiceEvent
= NULL
;
2514 if (Private
->Session
!= NULL
) {
2515 IScsiSessionAbort (Private
->Session
);
2520 Tests whether a controller handle is being managed by IScsi driver.
2522 This function tests whether the driver specified by DriverBindingHandle is
2523 currently managing the controller specified by ControllerHandle. This test
2524 is performed by evaluating if the protocol specified by ProtocolGuid is
2525 present on ControllerHandle and is was opened by DriverBindingHandle and Nic
2526 Device handle with an attribute of EFI_OPEN_PROTOCOL_BY_DRIVER.
2527 If ProtocolGuid is NULL, then ASSERT().
2529 @param ControllerHandle A handle for a controller to test.
2530 @param DriverBindingHandle Specifies the driver binding handle for the
2532 @param ProtocolGuid Specifies the protocol that the driver specified
2533 by DriverBindingHandle opens in its Start()
2536 @retval EFI_SUCCESS ControllerHandle is managed by the driver
2537 specified by DriverBindingHandle.
2538 @retval EFI_UNSUPPORTED ControllerHandle is not managed by the driver
2539 specified by DriverBindingHandle.
2544 IScsiTestManagedDevice (
2545 IN EFI_HANDLE ControllerHandle
,
2546 IN EFI_HANDLE DriverBindingHandle
,
2547 IN EFI_GUID
*ProtocolGuid
2551 VOID
*ManagedInterface
;
2552 EFI_HANDLE NicControllerHandle
;
2554 ASSERT (ProtocolGuid
!= NULL
);
2556 NicControllerHandle
= NetLibGetNicHandle (ControllerHandle
, ProtocolGuid
);
2557 if (NicControllerHandle
== NULL
) {
2558 return EFI_UNSUPPORTED
;
2561 Status
= gBS
->OpenProtocol (
2563 (EFI_GUID
*) ProtocolGuid
,
2565 DriverBindingHandle
,
2566 NicControllerHandle
,
2567 EFI_OPEN_PROTOCOL_BY_DRIVER
2569 if (!EFI_ERROR (Status
)) {
2570 gBS
->CloseProtocol (
2572 (EFI_GUID
*) ProtocolGuid
,
2573 DriverBindingHandle
,
2576 return EFI_UNSUPPORTED
;
2579 if (Status
!= EFI_ALREADY_STARTED
) {
2580 return EFI_UNSUPPORTED
;