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_INVALID_PARAMETER The IP string is malformatted.
326 IN OUT CHAR8
*HexStr
,
327 IN OUT UINT32
*HexLength
332 if ((HexStr
== NULL
) || (BinBuffer
== NULL
) || (BinLength
== 0)) {
333 return EFI_INVALID_PARAMETER
;
336 if (((*HexLength
) - 3) < BinLength
* 2) {
337 *HexLength
= BinLength
* 2 + 3;
338 return EFI_BUFFER_TOO_SMALL
;
341 *HexLength
= BinLength
* 2 + 3;
343 // Prefix for Hex String.
348 for (Index
= 0; Index
< BinLength
; Index
++) {
349 HexStr
[Index
* 2 + 2] = IScsiHexString
[BinBuffer
[Index
] >> 4];
350 HexStr
[Index
* 2 + 3] = IScsiHexString
[BinBuffer
[Index
] & 0xf];
353 HexStr
[Index
* 2 + 2] = '\0';
360 Convert the hexadecimal string into a binary encoded buffer.
362 @param[in, out] BinBuffer The binary buffer.
363 @param[in, out] BinLength Length of the binary buffer.
364 @param[in] HexStr The hexadecimal string.
366 @retval EFI_SUCCESS The hexadecimal string is converted into a binary
368 @retval EFI_BUFFER_TOO_SMALL The binary buffer is too small to hold the converted data.
373 IN OUT UINT8
*BinBuffer
,
374 IN OUT UINT32
*BinLength
,
383 ZeroMem (TemStr
, sizeof (TemStr
));
386 // Find out how many hex characters the string has.
388 if ((HexStr
[0] == '0') && ((HexStr
[1] == 'x') || (HexStr
[1] == 'X'))) {
392 Length
= AsciiStrLen (HexStr
);
394 for (Index
= 0; Index
< Length
; Index
++) {
395 TemStr
[0] = HexStr
[Index
];
396 Digit
= (UINT8
) AsciiStrHexToUint64 (TemStr
);
397 if (Digit
== 0 && TemStr
[0] != '0') {
403 if ((Index
& 1) == 0) {
404 BinBuffer
[Index
/2] = Digit
;
406 BinBuffer
[Index
/2] = (UINT8
) ((BinBuffer
[Index
/2] << 4) + Digit
);
410 *BinLength
= (UINT32
) ((Index
+ 1)/2);
417 Convert the decimal-constant string or hex-constant string into a numerical value.
419 @param[in] Str String in decimal or hex.
421 @return The numerical value.
429 if ((Str
[0] == '0') && ((Str
[1] == 'x') || (Str
[1] == 'X'))) {
432 return AsciiStrHexToUintn (Str
);
435 return AsciiStrDecimalToUintn (Str
);
440 Generate random numbers.
442 @param[in, out] Rand The buffer to contain random numbers.
443 @param[in] RandLength The length of the Rand buffer.
454 while (RandLength
> 0) {
455 Random
= NET_RANDOM (NetRandomInitSeed ());
456 *Rand
++ = (UINT8
) (Random
);
463 Check whether UNDI protocol supports IPv6.
465 @param[in] ControllerHandle Controller handle.
466 @param[in] Image Handle of the image.
467 @param[out] Ipv6Support TRUE if UNDI supports IPv6.
469 @retval EFI_SUCCESS Get the result whether UNDI supports IPv6 by NII or AIP protocol successfully.
470 @retval EFI_NOT_FOUND Don't know whether UNDI supports IPv6 since NII or AIP is not available.
474 IScsiCheckIpv6Support (
475 IN EFI_HANDLE ControllerHandle
,
477 OUT BOOLEAN
*Ipv6Support
481 EFI_ADAPTER_INFORMATION_PROTOCOL
*Aip
;
483 EFI_GUID
*InfoTypesBuffer
;
484 UINTN InfoTypeBufferCount
;
490 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL
*Nii
;
492 ASSERT (Ipv6Support
!= NULL
);
495 // Check whether the UNDI supports IPv6 by NII protocol.
497 Status
= gBS
->OpenProtocol (
499 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
503 EFI_OPEN_PROTOCOL_GET_PROTOCOL
505 if (Status
== EFI_SUCCESS
) {
506 *Ipv6Support
= Nii
->Ipv6Supported
;
511 // Get the NIC handle by SNP protocol.
513 Handle
= NetLibGetSnpHandle (ControllerHandle
, NULL
);
514 if (Handle
== NULL
) {
515 return EFI_NOT_FOUND
;
519 Status
= gBS
->HandleProtocol (
521 &gEfiAdapterInformationProtocolGuid
,
524 if (EFI_ERROR (Status
) || Aip
== NULL
) {
525 return EFI_NOT_FOUND
;
528 InfoTypesBuffer
= NULL
;
529 InfoTypeBufferCount
= 0;
530 Status
= Aip
->GetSupportedTypes (Aip
, &InfoTypesBuffer
, &InfoTypeBufferCount
);
531 if (EFI_ERROR (Status
) || InfoTypesBuffer
== NULL
) {
532 FreePool (InfoTypesBuffer
);
533 return EFI_NOT_FOUND
;
537 for (TypeIndex
= 0; TypeIndex
< InfoTypeBufferCount
; TypeIndex
++) {
538 if (CompareGuid (&InfoTypesBuffer
[TypeIndex
], &gEfiAdapterInfoUndiIpv6SupportGuid
)) {
544 FreePool (InfoTypesBuffer
);
546 return EFI_NOT_FOUND
;
550 // We now have adapter information block.
554 Status
= Aip
->GetInformation (Aip
, &gEfiAdapterInfoUndiIpv6SupportGuid
, &InfoBlock
, &InfoBlockSize
);
555 if (EFI_ERROR (Status
) || InfoBlock
== NULL
) {
556 FreePool (InfoBlock
);
557 return EFI_NOT_FOUND
;
560 *Ipv6Support
= ((EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT
*) InfoBlock
)->Ipv6Support
;
561 FreePool (InfoBlock
);
567 Record the NIC info in global structure.
569 @param[in] Controller The handle of the controller.
570 @param[in] Image Handle of the image.
572 @retval EFI_SUCCESS The operation is completed.
573 @retval EFI_OUT_OF_RESOURCES Do not have sufficient resources to finish this
579 IN EFI_HANDLE Controller
,
584 ISCSI_NIC_INFO
*NicInfo
;
586 EFI_MAC_ADDRESS MacAddr
;
591 // Get MAC address of this network device.
593 Status
= NetLibGetMacAddress (Controller
, &MacAddr
, &HwAddressSize
);
594 if (EFI_ERROR (Status
)) {
599 // Get VLAN ID of this network device.
601 VlanId
= NetLibGetVlanId (Controller
);
604 // Check whether the NIC info already exists. Return directly if so.
606 NET_LIST_FOR_EACH (Entry
, &mPrivate
->NicInfoList
) {
607 NicInfo
= NET_LIST_USER_STRUCT (Entry
, ISCSI_NIC_INFO
, Link
);
608 if (NicInfo
->HwAddressSize
== HwAddressSize
&&
609 CompareMem (&NicInfo
->PermanentAddress
, MacAddr
.Addr
, HwAddressSize
) == 0 &&
610 NicInfo
->VlanId
== VlanId
) {
611 mPrivate
->CurrentNic
= NicInfo
->NicIndex
;
614 // Set IPv6 available flag.
616 Status
= IScsiCheckIpv6Support (Controller
, Image
, &NicInfo
->Ipv6Available
);
617 if (EFI_ERROR (Status
)) {
619 // Fail to get the data whether UNDI supports IPv6.
620 // Set default value to TRUE.
622 NicInfo
->Ipv6Available
= TRUE
;
628 if (mPrivate
->MaxNic
< NicInfo
->NicIndex
) {
629 mPrivate
->MaxNic
= NicInfo
->NicIndex
;
634 // Record the NIC info in private structure.
636 NicInfo
= AllocateZeroPool (sizeof (ISCSI_NIC_INFO
));
637 if (NicInfo
== NULL
) {
638 return EFI_OUT_OF_RESOURCES
;
641 CopyMem (&NicInfo
->PermanentAddress
, MacAddr
.Addr
, HwAddressSize
);
642 NicInfo
->HwAddressSize
= (UINT32
) HwAddressSize
;
643 NicInfo
->VlanId
= VlanId
;
644 NicInfo
->NicIndex
= (UINT8
) (mPrivate
->MaxNic
+ 1);
645 mPrivate
->MaxNic
= NicInfo
->NicIndex
;
648 // Set IPv6 available flag.
650 Status
= IScsiCheckIpv6Support (Controller
, Image
, &NicInfo
->Ipv6Available
);
651 if (EFI_ERROR (Status
)) {
653 // Fail to get the data whether UNDI supports IPv6.
654 // Set default value to TRUE.
656 NicInfo
->Ipv6Available
= TRUE
;
660 // Get the PCI location.
662 IScsiGetNICPciLocation (
665 &NicInfo
->DeviceNumber
,
666 &NicInfo
->FunctionNumber
669 InsertTailList (&mPrivate
->NicInfoList
, &NicInfo
->Link
);
670 mPrivate
->NicCount
++;
672 mPrivate
->CurrentNic
= NicInfo
->NicIndex
;
678 Delete the recorded NIC info from global structure. Also delete corresponding
681 @param[in] Controller The handle of the controller.
683 @retval EFI_SUCCESS The operation is completed.
684 @retval EFI_NOT_FOUND The NIC info to be deleted is not recorded.
689 IN EFI_HANDLE Controller
693 ISCSI_NIC_INFO
*NicInfo
;
695 LIST_ENTRY
*NextEntry
;
696 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
697 ISCSI_NIC_INFO
*ThisNic
;
698 EFI_MAC_ADDRESS MacAddr
;
703 // Get MAC address of this network device.
705 Status
= NetLibGetMacAddress (Controller
, &MacAddr
, &HwAddressSize
);
706 if (EFI_ERROR (Status
)) {
711 // Get VLAN ID of this network device.
713 VlanId
= NetLibGetVlanId (Controller
);
716 // Check whether the NIC information exists.
720 NET_LIST_FOR_EACH (Entry
, &mPrivate
->NicInfoList
) {
721 NicInfo
= NET_LIST_USER_STRUCT (Entry
, ISCSI_NIC_INFO
, Link
);
722 if (NicInfo
->HwAddressSize
== HwAddressSize
&&
723 CompareMem (&NicInfo
->PermanentAddress
, MacAddr
.Addr
, HwAddressSize
) == 0 &&
724 NicInfo
->VlanId
== VlanId
) {
731 if (ThisNic
== NULL
) {
732 return EFI_NOT_FOUND
;
735 mPrivate
->CurrentNic
= ThisNic
->NicIndex
;
737 RemoveEntryList (&ThisNic
->Link
);
739 mPrivate
->NicCount
--;
742 // Remove all attempts related to this NIC.
744 NET_LIST_FOR_EACH_SAFE (Entry
, NextEntry
, &mPrivate
->AttemptConfigs
) {
745 AttemptConfigData
= NET_LIST_USER_STRUCT (Entry
, ISCSI_ATTEMPT_CONFIG_NVDATA
, Link
);
746 if (AttemptConfigData
->NicIndex
== mPrivate
->CurrentNic
) {
747 RemoveEntryList (&AttemptConfigData
->Link
);
748 mPrivate
->AttemptCount
--;
750 if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED_FOR_MPIO
&& mPrivate
->MpioCount
> 0) {
751 if (--mPrivate
->MpioCount
== 0) {
752 mPrivate
->EnableMpio
= FALSE
;
755 if (AttemptConfigData
->AuthenticationType
== ISCSI_AUTH_TYPE_KRB
&& mPrivate
->Krb5MpioCount
> 0) {
756 mPrivate
->Krb5MpioCount
--;
759 } else if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED
&& mPrivate
->SinglePathCount
> 0) {
760 mPrivate
->SinglePathCount
--;
762 if (mPrivate
->ValidSinglePathCount
> 0) {
763 mPrivate
->ValidSinglePathCount
--;
767 FreePool (AttemptConfigData
);
775 Create and initialize the Attempts.
777 @param[in] AttemptNum The number of Attempts will be created.
779 @retval EFI_SUCCESS The Attempts have been created successfully.
780 @retval Others Failed to create the Attempt.
784 IScsiCreateAttempts (
788 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
789 ISCSI_SESSION_CONFIG_NVDATA
*ConfigData
;
790 UINT8
*AttemptConfigOrder
;
791 UINTN AttemptConfigOrderSize
;
792 UINT8
*AttemptOrderTmp
;
797 for (Index
= 1; Index
<= AttemptNum
; Index
++) {
799 // Get the initialized attempt order. This is used to essure creating attempts by order.
801 AttemptConfigOrder
= IScsiGetVariableAndSize (
802 L
"InitialAttemptOrder",
804 &AttemptConfigOrderSize
806 TotalNumber
= AttemptConfigOrderSize
/ sizeof (UINT8
);
807 if (TotalNumber
== AttemptNum
) {
808 Status
= EFI_SUCCESS
;
814 // Append the new created attempt to the end.
816 AttemptOrderTmp
= AllocateZeroPool (TotalNumber
* sizeof (UINT8
));
817 if (AttemptOrderTmp
== NULL
) {
818 if (AttemptConfigOrder
!= NULL
) {
819 FreePool (AttemptConfigOrder
);
821 return EFI_OUT_OF_RESOURCES
;
824 if (AttemptConfigOrder
!= NULL
) {
825 CopyMem (AttemptOrderTmp
, AttemptConfigOrder
, AttemptConfigOrderSize
);
826 FreePool (AttemptConfigOrder
);
829 AttemptOrderTmp
[TotalNumber
- 1] = Index
;
830 AttemptConfigOrder
= AttemptOrderTmp
;
831 AttemptConfigOrderSize
= TotalNumber
* sizeof (UINT8
);
833 Status
= gRT
->SetVariable (
834 L
"InitialAttemptOrder",
836 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
837 AttemptConfigOrderSize
,
840 FreePool (AttemptConfigOrder
);
841 if (EFI_ERROR (Status
)) {
843 "%a: Failed to set 'InitialAttemptOrder' with Guid (%g): "
845 __FUNCTION__
, &gIScsiConfigGuid
, Status
));
850 // Create new Attempt
852 AttemptConfigData
= AllocateZeroPool (sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
));
853 if (AttemptConfigData
== NULL
) {
854 return EFI_OUT_OF_RESOURCES
;
856 ConfigData
= &AttemptConfigData
->SessionConfigData
;
857 ConfigData
->TargetPort
= ISCSI_WELL_KNOWN_PORT
;
858 ConfigData
->ConnectTimeout
= CONNECT_DEFAULT_TIMEOUT
;
859 ConfigData
->ConnectRetryCount
= CONNECT_MIN_RETRY
;
861 AttemptConfigData
->AuthenticationType
= ISCSI_AUTH_TYPE_CHAP
;
862 AttemptConfigData
->AuthConfigData
.CHAP
.CHAPType
= ISCSI_CHAP_UNI
;
864 // Configure the Attempt index and set variable.
866 AttemptConfigData
->AttemptConfigIndex
= Index
;
869 // Set the attempt name according to the order.
872 mPrivate
->PortString
,
873 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
875 (UINTN
) AttemptConfigData
->AttemptConfigIndex
877 UnicodeStrToAsciiStrS (mPrivate
->PortString
, AttemptConfigData
->AttemptName
, ATTEMPT_NAME_SIZE
);
879 Status
= gRT
->SetVariable (
880 mPrivate
->PortString
,
881 &gEfiIScsiInitiatorNameProtocolGuid
,
882 ISCSI_CONFIG_VAR_ATTR
,
883 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
886 FreePool (AttemptConfigData
);
887 if (EFI_ERROR (Status
)) {
889 "%a: Failed to set variable (mPrivate->PortString) with Guid (%g): "
891 __FUNCTION__
, &gEfiIScsiInitiatorNameProtocolGuid
, Status
));
900 Create the iSCSI configuration Keywords for each attempt. You can find the keywords
901 defined in the "x-UEFI-ns" namespace (http://www.uefi.org/confignamespace).
903 @param[in] KeywordNum The number Sets of Keywords will be created.
905 @retval EFI_SUCCESS The operation is completed.
906 @retval Others Failed to create the Keywords.
910 IScsiCreateKeywords (
914 VOID
*StartOpCodeHandle
;
915 EFI_IFR_GUID_LABEL
*StartLabel
;
916 VOID
*EndOpCodeHandle
;
917 EFI_IFR_GUID_LABEL
*EndLabel
;
919 EFI_STRING_ID StringToken
;
921 CHAR16 KeywordId
[32];
924 Status
= IScsiCreateOpCode (
931 if (EFI_ERROR (Status
)) {
932 return EFI_OUT_OF_RESOURCES
;
935 for (Index
= 1; Index
<= KeywordNum
; Index
++) {
937 // Create iSCSIAttemptName Keyword.
939 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_ATTEMPTT_NAME_PROMPT%d", Index
);
940 StringToken
= HiiSetString (
941 mCallbackInfo
->RegisteredHandle
,
946 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIAttemptName:%d", Index
);
947 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
948 HiiCreateStringOpCode (
950 (EFI_QUESTION_ID
) (ATTEMPT_ATTEMPT_NAME_QUESTION_ID
+ (Index
- 1)),
951 CONFIGURATION_VARSTORE_ID
,
952 (UINT16
) (ATTEMPT_ATTEMPT_NAME_VAR_OFFSET
+ ATTEMPT_NAME_SIZE
* (Index
- 1) * sizeof (CHAR16
)),
955 EFI_IFR_FLAG_READ_ONLY
,
963 // Create iSCSIBootEnable Keyword.
965 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_MODE_PROMPT%d", Index
);
966 StringToken
= HiiSetString (
967 mCallbackInfo
->RegisteredHandle
,
972 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIBootEnable:%d", Index
);
973 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
974 HiiCreateNumericOpCode (
976 (EFI_QUESTION_ID
) (ATTEMPT_BOOTENABLE_QUESTION_ID
+ (Index
- 1)),
977 CONFIGURATION_VARSTORE_ID
,
978 (UINT16
) (ATTEMPT_BOOTENABLE_VAR_OFFSET
+ (Index
- 1)),
982 EFI_IFR_NUMERIC_SIZE_1
,
990 // Create iSCSIIpAddressType Keyword.
992 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_IP_MODE_PROMPT%d", Index
);
993 StringToken
= HiiSetString (
994 mCallbackInfo
->RegisteredHandle
,
999 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIIpAddressType:%d", Index
);
1000 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1001 HiiCreateNumericOpCode (
1003 (EFI_QUESTION_ID
) (ATTEMPT_ADDRESS_TYPE_QUESTION_ID
+ (Index
- 1)),
1004 CONFIGURATION_VARSTORE_ID
,
1005 (UINT16
) (ATTEMPT_ADDRESS_TYPE_VAR_OFFSET
+ (Index
- 1)),
1009 EFI_IFR_NUMERIC_SIZE_1
,
1017 // Create iSCSIConnectRetry Keyword.
1019 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CONNECT_RETRY_PROMPT%d", Index
);
1020 StringToken
= HiiSetString (
1021 mCallbackInfo
->RegisteredHandle
,
1026 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIConnectRetry:%d", Index
);
1027 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1028 HiiCreateNumericOpCode (
1030 (EFI_QUESTION_ID
) (ATTEMPT_CONNECT_RETRY_QUESTION_ID
+ (Index
- 1)),
1031 CONFIGURATION_VARSTORE_ID
,
1032 (UINT16
) (ATTEMPT_CONNECT_RETRY_VAR_OFFSET
+ (Index
- 1)),
1036 EFI_IFR_NUMERIC_SIZE_1
,
1044 // Create iSCSIConnectTimeout Keyword.
1046 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CONNECT_TIMEOUT_PROMPT%d", Index
);
1047 StringToken
= HiiSetString (
1048 mCallbackInfo
->RegisteredHandle
,
1053 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIConnectTimeout:%d", Index
);
1054 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1055 HiiCreateNumericOpCode (
1057 (EFI_QUESTION_ID
) (ATTEMPT_CONNECT_TIMEOUT_QUESTION_ID
+ (Index
- 1)),
1058 CONFIGURATION_VARSTORE_ID
,
1059 (UINT16
) (ATTEMPT_CONNECT_TIMEOUT_VAR_OFFSET
+ 2 * (Index
- 1)),
1063 EFI_IFR_NUMERIC_SIZE_2
,
1064 CONNECT_MIN_TIMEOUT
,
1065 CONNECT_MAX_TIMEOUT
,
1071 // Create ISID Keyword.
1073 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_ISID_PROMPT%d", Index
);
1074 StringToken
= HiiSetString (
1075 mCallbackInfo
->RegisteredHandle
,
1080 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIISID:%d", Index
);
1081 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1082 HiiCreateStringOpCode (
1084 (EFI_QUESTION_ID
) (ATTEMPT_ISID_QUESTION_ID
+ (Index
- 1)),
1085 CONFIGURATION_VARSTORE_ID
,
1086 (UINT16
) (ATTEMPT_ISID_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1088 STRING_TOKEN (STR_ISCSI_ISID_HELP
),
1091 ISID_CONFIGURABLE_MIN_LEN
,
1092 ISID_CONFIGURABLE_STORAGE
,
1097 // Create iSCSIInitiatorInfoViaDHCP Keyword.
1099 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_INITIATOR_VIA_DHCP_PROMPT%d", Index
);
1100 StringToken
= HiiSetString (
1101 mCallbackInfo
->RegisteredHandle
,
1106 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIInitiatorInfoViaDHCP:%d", Index
);
1107 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1108 HiiCreateNumericOpCode (
1110 (EFI_QUESTION_ID
) (ATTEMPT_INITIATOR_VIA_DHCP_QUESTION_ID
+ (Index
- 1)),
1111 CONFIGURATION_VARSTORE_ID
,
1112 (UINT16
) (ATTEMPT_INITIATOR_VIA_DHCP_VAR_OFFSET
+ (Index
- 1)),
1124 // Create iSCSIInitiatorIpAddress Keyword.
1126 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_INITIATOR_IP_ADDRESS_PROMPT%d", Index
);
1127 StringToken
= HiiSetString (
1128 mCallbackInfo
->RegisteredHandle
,
1133 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIInitiatorIpAddress:%d", Index
);
1134 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1135 HiiCreateStringOpCode (
1137 (EFI_QUESTION_ID
) (ATTEMPT_INITIATOR_IP_ADDRESS_QUESTION_ID
+ (Index
- 1)),
1138 CONFIGURATION_VARSTORE_ID
,
1139 (UINT16
) (ATTEMPT_INITIATOR_IP_ADDRESS_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1150 // Create iSCSIInitiatorNetmask Keyword.
1152 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_INITIATOR_NET_MASK_PROMPT%d", Index
);
1153 StringToken
= HiiSetString (
1154 mCallbackInfo
->RegisteredHandle
,
1159 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIInitiatorNetmask:%d", Index
);
1160 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1161 HiiCreateStringOpCode (
1163 (EFI_QUESTION_ID
) (ATTEMPT_INITIATOR_NET_MASK_QUESTION_ID
+ (Index
- 1)),
1164 CONFIGURATION_VARSTORE_ID
,
1165 (UINT16
) (ATTEMPT_INITIATOR_NET_MASK_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1176 // Create iSCSIInitiatorGateway Keyword.
1178 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_INITIATOR_GATE_PROMPT%d", Index
);
1179 StringToken
= HiiSetString (
1180 mCallbackInfo
->RegisteredHandle
,
1185 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIInitiatorGateway:%d", Index
);
1186 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1187 HiiCreateStringOpCode (
1189 (EFI_QUESTION_ID
) (ATTEMPT_INITIATOR_GATE_WAY_QUESTION_ID
+ (Index
- 1)),
1190 CONFIGURATION_VARSTORE_ID
,
1191 (UINT16
) (ATTEMPT_INITIATOR_GATE_WAY_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1202 // Create iSCSITargetInfoViaDHCP Keyword.
1204 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_TARGET_VIA_DHCP_PROMPT%d", Index
);
1205 StringToken
= HiiSetString (
1206 mCallbackInfo
->RegisteredHandle
,
1211 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSITargetInfoViaDHCP:%d", Index
);
1212 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1213 HiiCreateNumericOpCode (
1215 (EFI_QUESTION_ID
) (ATTEMPT_TARGET_VIA_DHCP_QUESTION_ID
+ (Index
- 1)),
1216 CONFIGURATION_VARSTORE_ID
,
1217 (UINT16
) (ATTEMPT_TARGET_VIA_DHCP_VAR_OFFSET
+ (Index
- 1)),
1229 // Create iSCSITargetTcpPort Keyword.
1231 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_TARGET_TCP_PORT_PROMPT%d", Index
);
1232 StringToken
= HiiSetString (
1233 mCallbackInfo
->RegisteredHandle
,
1238 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSITargetTcpPort:%d", Index
);
1239 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1240 HiiCreateNumericOpCode (
1242 (EFI_QUESTION_ID
) (ATTEMPT_TARGET_TCP_PORT_QUESTION_ID
+ (Index
- 1)),
1243 CONFIGURATION_VARSTORE_ID
,
1244 (UINT16
) (ATTEMPT_TARGET_TCP_PORT_VAR_OFFSET
+ 2 * (Index
- 1)),
1248 EFI_IFR_NUMERIC_SIZE_2
,
1249 TARGET_PORT_MIN_NUM
,
1250 TARGET_PORT_MAX_NUM
,
1256 // Create iSCSITargetName Keyword.
1258 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_TARGET_NAME_PROMPT%d", Index
);
1259 StringToken
= HiiSetString (
1260 mCallbackInfo
->RegisteredHandle
,
1265 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSITargetName:%d", Index
);
1266 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1267 HiiCreateStringOpCode (
1269 (EFI_QUESTION_ID
) (ATTEMPT_TARGET_NAME_QUESTION_ID
+ (Index
- 1)),
1270 CONFIGURATION_VARSTORE_ID
,
1271 (UINT16
) (ATTEMPT_TARGET_NAME_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1276 ISCSI_NAME_IFR_MIN_SIZE
,
1277 ISCSI_NAME_IFR_MAX_SIZE
,
1282 // Create iSCSITargetIpAddress Keyword.
1284 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_TARGET_IP_ADDRESS_PROMPT%d", Index
);
1285 StringToken
= HiiSetString (
1286 mCallbackInfo
->RegisteredHandle
,
1291 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSITargetIpAddress:%d", Index
);
1292 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1293 HiiCreateStringOpCode (
1295 (EFI_QUESTION_ID
) (ATTEMPT_TARGET_IP_ADDRESS_QUESTION_ID
+ (Index
- 1)),
1296 CONFIGURATION_VARSTORE_ID
,
1297 (UINT16
) (ATTEMPT_TARGET_IP_ADDRESS_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1308 // Create iSCSILUN Keyword.
1310 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_LUN_PROMPT%d", Index
);
1311 StringToken
= HiiSetString (
1312 mCallbackInfo
->RegisteredHandle
,
1317 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSILUN:%d", Index
);
1318 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1319 HiiCreateStringOpCode (
1321 (EFI_QUESTION_ID
) (ATTEMPT_LUN_QUESTION_ID
+ (Index
- 1)),
1322 CONFIGURATION_VARSTORE_ID
,
1323 (UINT16
) (ATTEMPT_LUN_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1334 // Create iSCSIAuthenticationMethod Keyword.
1336 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_AUTHENTICATION_METHOD_PROMPT%d", Index
);
1337 StringToken
= HiiSetString (
1338 mCallbackInfo
->RegisteredHandle
,
1343 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIAuthenticationMethod:%d", Index
);
1344 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1345 HiiCreateNumericOpCode (
1347 (EFI_QUESTION_ID
) (ATTEMPT_AUTHENTICATION_METHOD_QUESTION_ID
+ (Index
- 1)),
1348 CONFIGURATION_VARSTORE_ID
,
1349 (UINT16
) (ATTEMPT_AUTHENTICATION_METHOD_VAR_OFFSET
+ (Index
- 1)),
1361 // Create iSCSIChapType Keyword.
1363 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHARTYPE_PROMPT%d", Index
);
1364 StringToken
= HiiSetString (
1365 mCallbackInfo
->RegisteredHandle
,
1370 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIChapType:%d", Index
);
1371 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1372 HiiCreateNumericOpCode (
1374 (EFI_QUESTION_ID
) (ATTEMPT_CHARTYPE_QUESTION_ID
+ (Index
- 1)),
1375 CONFIGURATION_VARSTORE_ID
,
1376 (UINT16
) (ATTEMPT_CHARTYPE_VAR_OFFSET
+ (Index
- 1)),
1388 // Create iSCSIChapUsername Keyword.
1390 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHAR_USER_NAME_PROMPT%d", Index
);
1391 StringToken
= HiiSetString (
1392 mCallbackInfo
->RegisteredHandle
,
1397 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIChapUsername:%d", Index
);
1398 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1399 HiiCreateStringOpCode (
1401 (EFI_QUESTION_ID
) (ATTEMPT_CHAR_USER_NAME_QUESTION_ID
+ (Index
- 1)),
1402 CONFIGURATION_VARSTORE_ID
,
1403 (UINT16
) (ATTEMPT_CHAR_USER_NAME_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1409 ISCSI_CHAP_NAME_MAX_LEN
,
1414 // Create iSCSIChapSecret Keyword.
1416 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHAR_SECRET_PROMPT%d", Index
);
1417 StringToken
= HiiSetString (
1418 mCallbackInfo
->RegisteredHandle
,
1423 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIChapSecret:%d", Index
);
1424 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1425 HiiCreateStringOpCode (
1427 (EFI_QUESTION_ID
) (ATTEMPT_CHAR_SECRET_QUESTION_ID
+ (Index
- 1)),
1428 CONFIGURATION_VARSTORE_ID
,
1429 (UINT16
) (ATTEMPT_CHAR_SECRET_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1434 ISCSI_CHAP_SECRET_MIN_LEN
,
1435 ISCSI_CHAP_SECRET_MAX_LEN
,
1440 // Create iSCSIReverseChapUsername Keyword.
1442 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHAR_REVERSE_USER_NAME_PROMPT%d", Index
);
1443 StringToken
= HiiSetString (
1444 mCallbackInfo
->RegisteredHandle
,
1449 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIReverseChapUsername:%d", Index
);
1450 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1451 HiiCreateStringOpCode (
1453 (EFI_QUESTION_ID
) (ATTEMPT_CHAR_REVERSE_USER_NAME_QUESTION_ID
+ (Index
- 1)),
1454 CONFIGURATION_VARSTORE_ID
,
1455 (UINT16
) (ATTEMPT_CHAR_REVERSE_USER_NAME_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1461 ISCSI_CHAP_NAME_MAX_LEN
,
1466 // Create iSCSIReverseChapSecret Keyword.
1468 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHAR_REVERSE_SECRET_PROMPT%d", Index
);
1469 StringToken
= HiiSetString (
1470 mCallbackInfo
->RegisteredHandle
,
1475 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIReverseChapSecret:%d", Index
);
1476 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1477 HiiCreateStringOpCode (
1479 (EFI_QUESTION_ID
) (ATTEMPT_CHAR_REVERSE_SECRET_QUESTION_ID
+ (Index
- 1)),
1480 CONFIGURATION_VARSTORE_ID
,
1481 (UINT16
) (ATTEMPT_CHAR_REVERSE_SECRET_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1486 ISCSI_CHAP_SECRET_MIN_LEN
,
1487 ISCSI_CHAP_SECRET_MAX_LEN
,
1492 Status
= HiiUpdateForm (
1493 mCallbackInfo
->RegisteredHandle
, // HII handle
1494 &gIScsiConfigGuid
, // Formset GUID
1495 FORMID_ATTEMPT_FORM
, // Form ID
1496 StartOpCodeHandle
, // Label for where to insert opcodes
1497 EndOpCodeHandle
// Replace data
1500 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1501 HiiFreeOpCodeHandle (EndOpCodeHandle
);
1508 Free the attempt configure data variable.
1512 IScsiCleanAttemptVariable (
1516 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
1517 UINT8
*AttemptConfigOrder
;
1518 UINTN AttemptConfigOrderSize
;
1522 // Get the initialized attempt order.
1524 AttemptConfigOrder
= IScsiGetVariableAndSize (
1525 L
"InitialAttemptOrder",
1527 &AttemptConfigOrderSize
1529 if (AttemptConfigOrder
== NULL
|| AttemptConfigOrderSize
== 0) {
1533 for (Index
= 1; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
1535 mPrivate
->PortString
,
1536 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
1542 mPrivate
->PortString
,
1543 &gEfiIScsiInitiatorNameProtocolGuid
,
1544 (VOID
**)&AttemptConfigData
,
1548 if (AttemptConfigData
!= NULL
) {
1550 mPrivate
->PortString
,
1551 &gEfiIScsiInitiatorNameProtocolGuid
,
1562 Get the recorded NIC info from global structure by the Index.
1564 @param[in] NicIndex The index indicates the position of NIC info.
1566 @return Pointer to the NIC info, or NULL if not found.
1570 IScsiGetNicInfoByIndex (
1575 ISCSI_NIC_INFO
*NicInfo
;
1577 NET_LIST_FOR_EACH (Entry
, &mPrivate
->NicInfoList
) {
1578 NicInfo
= NET_LIST_USER_STRUCT (Entry
, ISCSI_NIC_INFO
, Link
);
1579 if (NicInfo
->NicIndex
== NicIndex
) {
1589 Get the NIC's PCI location and return it according to the composited
1590 format defined in iSCSI Boot Firmware Table.
1592 @param[in] Controller The handle of the controller.
1593 @param[out] Bus The bus number.
1594 @param[out] Device The device number.
1595 @param[out] Function The function number.
1597 @return The composited representation of the NIC PCI location.
1601 IScsiGetNICPciLocation (
1602 IN EFI_HANDLE Controller
,
1609 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1610 EFI_HANDLE PciIoHandle
;
1611 EFI_PCI_IO_PROTOCOL
*PciIo
;
1614 Status
= gBS
->HandleProtocol (
1616 &gEfiDevicePathProtocolGuid
,
1617 (VOID
**) &DevicePath
1619 if (EFI_ERROR (Status
)) {
1623 Status
= gBS
->LocateDevicePath (
1624 &gEfiPciIoProtocolGuid
,
1628 if (EFI_ERROR (Status
)) {
1632 Status
= gBS
->HandleProtocol (PciIoHandle
, &gEfiPciIoProtocolGuid
, (VOID
**) &PciIo
);
1633 if (EFI_ERROR (Status
)) {
1637 Status
= PciIo
->GetLocation (PciIo
, &Segment
, Bus
, Device
, Function
);
1638 if (EFI_ERROR (Status
)) {
1642 return (UINT16
) ((*Bus
<< 8) | (*Device
<< 3) | *Function
);
1647 Read the EFI variable (VendorGuid/Name) and return a dynamically allocated
1648 buffer, and the size of the buffer. If failure, return NULL.
1650 @param[in] Name String part of EFI variable name.
1651 @param[in] VendorGuid GUID part of EFI variable name.
1652 @param[out] VariableSize Returns the size of the EFI variable that was read.
1654 @return Dynamically allocated memory that contains a copy of the EFI variable.
1655 @return Caller is responsible freeing the buffer.
1656 @retval NULL Variable was not read.
1660 IScsiGetVariableAndSize (
1662 IN EFI_GUID
*VendorGuid
,
1663 OUT UINTN
*VariableSize
1673 // Pass in a zero size buffer to find the required buffer size.
1676 Status
= gRT
->GetVariable (Name
, VendorGuid
, NULL
, &BufferSize
, Buffer
);
1677 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1679 // Allocate the buffer to return
1681 Buffer
= AllocateZeroPool (BufferSize
);
1682 if (Buffer
== NULL
) {
1686 // Read variable into the allocated buffer.
1688 Status
= gRT
->GetVariable (Name
, VendorGuid
, NULL
, &BufferSize
, Buffer
);
1689 if (EFI_ERROR (Status
)) {
1694 *VariableSize
= BufferSize
;
1700 Create the iSCSI driver data.
1702 @param[in] Image The handle of the driver image.
1703 @param[in] Controller The handle of the controller.
1705 @return The iSCSI driver data created.
1706 @retval NULL Other errors as indicated.
1710 IScsiCreateDriverData (
1711 IN EFI_HANDLE Image
,
1712 IN EFI_HANDLE Controller
1715 ISCSI_DRIVER_DATA
*Private
;
1718 Private
= AllocateZeroPool (sizeof (ISCSI_DRIVER_DATA
));
1719 if (Private
== NULL
) {
1723 Private
->Signature
= ISCSI_DRIVER_DATA_SIGNATURE
;
1724 Private
->Image
= Image
;
1725 Private
->Controller
= Controller
;
1726 Private
->Session
= NULL
;
1729 // Create an event to be signaled when the BS to RT transition is triggerd so
1730 // as to abort the iSCSI session.
1732 Status
= gBS
->CreateEventEx (
1735 IScsiOnExitBootService
,
1737 &gEfiEventExitBootServicesGuid
,
1738 &Private
->ExitBootServiceEvent
1740 if (EFI_ERROR (Status
)) {
1745 Private
->ExtScsiPassThruHandle
= NULL
;
1746 CopyMem(&Private
->IScsiExtScsiPassThru
, &gIScsiExtScsiPassThruProtocolTemplate
, sizeof(EFI_EXT_SCSI_PASS_THRU_PROTOCOL
));
1749 // 0 is designated to the TargetId, so use another value for the AdapterId.
1751 Private
->ExtScsiPassThruMode
.AdapterId
= 2;
1752 Private
->ExtScsiPassThruMode
.Attributes
= EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL
| EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL
;
1753 Private
->ExtScsiPassThruMode
.IoAlign
= 4;
1754 Private
->IScsiExtScsiPassThru
.Mode
= &Private
->ExtScsiPassThruMode
;
1761 Clean the iSCSI driver data.
1763 @param[in] Private The iSCSI driver data.
1765 @retval EFI_SUCCESS The clean operation is successful.
1766 @retval Others Other errors as indicated.
1770 IScsiCleanDriverData (
1771 IN ISCSI_DRIVER_DATA
*Private
1776 Status
= EFI_SUCCESS
;
1778 if (Private
->DevicePath
!= NULL
) {
1779 Status
= gBS
->UninstallProtocolInterface (
1780 Private
->ExtScsiPassThruHandle
,
1781 &gEfiDevicePathProtocolGuid
,
1784 if (EFI_ERROR (Status
)) {
1788 FreePool (Private
->DevicePath
);
1791 if (Private
->ExtScsiPassThruHandle
!= NULL
) {
1792 Status
= gBS
->UninstallProtocolInterface (
1793 Private
->ExtScsiPassThruHandle
,
1794 &gEfiExtScsiPassThruProtocolGuid
,
1795 &Private
->IScsiExtScsiPassThru
1797 if (!EFI_ERROR (Status
)) {
1798 mPrivate
->OneSessionEstablished
= FALSE
;
1803 if (Private
->ExitBootServiceEvent
!= NULL
) {
1804 gBS
->CloseEvent (Private
->ExitBootServiceEvent
);
1807 mCallbackInfo
->Current
= NULL
;
1814 Check wheather the Controller handle is configured to use DHCP protocol.
1816 @param[in] Controller The handle of the controller.
1817 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
1819 @retval TRUE The handle of the controller need the Dhcp protocol.
1820 @retval FALSE The handle of the controller does not need the Dhcp protocol.
1824 IScsiDhcpIsConfigured (
1825 IN EFI_HANDLE Controller
,
1829 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptTmp
;
1830 UINT8
*AttemptConfigOrder
;
1831 UINTN AttemptConfigOrderSize
;
1834 EFI_MAC_ADDRESS MacAddr
;
1835 UINTN HwAddressSize
;
1837 CHAR16 MacString
[ISCSI_MAX_MAC_STRING_LEN
];
1838 CHAR16 AttemptMacString
[ISCSI_MAX_MAC_STRING_LEN
];
1839 CHAR16 AttemptName
[ISCSI_NAME_IFR_MAX_SIZE
];
1841 AttemptConfigOrder
= IScsiGetVariableAndSize (
1844 &AttemptConfigOrderSize
1846 if (AttemptConfigOrder
== NULL
|| AttemptConfigOrderSize
== 0) {
1851 // Get MAC address of this network device.
1853 Status
= NetLibGetMacAddress (Controller
, &MacAddr
, &HwAddressSize
);
1854 if(EFI_ERROR (Status
)) {
1858 // Get VLAN ID of this network device.
1860 VlanId
= NetLibGetVlanId (Controller
);
1861 IScsiMacAddrToStr (&MacAddr
, (UINT32
) HwAddressSize
, VlanId
, MacString
);
1863 for (Index
= 0; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
1868 (UINTN
) AttemptConfigOrder
[Index
]
1870 Status
= GetVariable2 (
1872 &gEfiIScsiInitiatorNameProtocolGuid
,
1873 (VOID
**)&AttemptTmp
,
1876 if(AttemptTmp
== NULL
|| EFI_ERROR (Status
)) {
1880 ASSERT (AttemptConfigOrder
[Index
] == AttemptTmp
->AttemptConfigIndex
);
1882 if (AttemptTmp
->SessionConfigData
.Enabled
== ISCSI_DISABLED
) {
1883 FreePool (AttemptTmp
);
1887 if (AttemptTmp
->SessionConfigData
.IpMode
!= IP_MODE_AUTOCONFIG
&&
1888 AttemptTmp
->SessionConfigData
.IpMode
!= ((IpVersion
== IP_VERSION_4
) ? IP_MODE_IP4
: IP_MODE_IP6
)) {
1889 FreePool (AttemptTmp
);
1893 AsciiStrToUnicodeStrS (AttemptTmp
->MacString
, AttemptMacString
, sizeof (AttemptMacString
) / sizeof (AttemptMacString
[0]));
1895 if (AttemptTmp
->Actived
== ISCSI_ACTIVE_DISABLED
|| StrCmp (MacString
, AttemptMacString
)) {
1899 if(AttemptTmp
->SessionConfigData
.IpMode
== IP_MODE_AUTOCONFIG
||
1900 AttemptTmp
->SessionConfigData
.InitiatorInfoFromDhcp
== TRUE
||
1901 AttemptTmp
->SessionConfigData
.TargetInfoFromDhcp
== TRUE
) {
1902 FreePool (AttemptTmp
);
1903 FreePool (AttemptConfigOrder
);
1907 FreePool (AttemptTmp
);
1910 FreePool (AttemptConfigOrder
);
1915 Check whether the Controller handle is configured to use DNS protocol.
1917 @param[in] Controller The handle of the controller.
1919 @retval TRUE The handle of the controller need the Dns protocol.
1920 @retval FALSE The handle of the controller does not need the Dns protocol.
1924 IScsiDnsIsConfigured (
1925 IN EFI_HANDLE Controller
1928 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptTmp
;
1929 UINT8
*AttemptConfigOrder
;
1930 UINTN AttemptConfigOrderSize
;
1933 EFI_MAC_ADDRESS MacAddr
;
1934 UINTN HwAddressSize
;
1936 CHAR16 AttemptMacString
[ISCSI_MAX_MAC_STRING_LEN
];
1937 CHAR16 MacString
[ISCSI_MAX_MAC_STRING_LEN
];
1938 CHAR16 AttemptName
[ISCSI_NAME_IFR_MAX_SIZE
];
1940 AttemptConfigOrder
= IScsiGetVariableAndSize (
1943 &AttemptConfigOrderSize
1945 if (AttemptConfigOrder
== NULL
|| AttemptConfigOrderSize
== 0) {
1950 // Get MAC address of this network device.
1952 Status
= NetLibGetMacAddress (Controller
, &MacAddr
, &HwAddressSize
);
1953 if(EFI_ERROR (Status
)) {
1957 // Get VLAN ID of this network device.
1959 VlanId
= NetLibGetVlanId (Controller
);
1960 IScsiMacAddrToStr (&MacAddr
, (UINT32
) HwAddressSize
, VlanId
, MacString
);
1962 for (Index
= 0; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
1967 (UINTN
) AttemptConfigOrder
[Index
]
1970 Status
= GetVariable2 (
1972 &gEfiIScsiInitiatorNameProtocolGuid
,
1973 (VOID
**)&AttemptTmp
,
1976 if(AttemptTmp
== NULL
|| EFI_ERROR (Status
)) {
1980 ASSERT (AttemptConfigOrder
[Index
] == AttemptTmp
->AttemptConfigIndex
);
1982 AsciiStrToUnicodeStrS (AttemptTmp
->MacString
, AttemptMacString
, sizeof (AttemptMacString
) / sizeof (AttemptMacString
[0]));
1984 if (AttemptTmp
->SessionConfigData
.Enabled
== ISCSI_DISABLED
|| StrCmp (MacString
, AttemptMacString
)) {
1985 FreePool (AttemptTmp
);
1989 if (AttemptTmp
->SessionConfigData
.DnsMode
|| AttemptTmp
->SessionConfigData
.TargetInfoFromDhcp
) {
1990 FreePool (AttemptTmp
);
1991 FreePool (AttemptConfigOrder
);
1994 FreePool (AttemptTmp
);
2000 FreePool (AttemptConfigOrder
);
2006 Get the various configuration data.
2008 @param[in] Private The iSCSI driver data.
2010 @retval EFI_SUCCESS The configuration data is retrieved.
2011 @retval EFI_NOT_FOUND This iSCSI driver is not configured yet.
2012 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
2016 IScsiGetConfigData (
2017 IN ISCSI_DRIVER_DATA
*Private
2021 CHAR16 MacString
[ISCSI_MAX_MAC_STRING_LEN
];
2022 CHAR16 AttemptMacString
[ISCSI_MAX_MAC_STRING_LEN
];
2024 ISCSI_NIC_INFO
*NicInfo
;
2025 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
2026 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptTmp
;
2027 UINT8
*AttemptConfigOrder
;
2028 UINTN AttemptConfigOrderSize
;
2029 CHAR16 IScsiMode
[64];
2033 // There should be at least one attempt configured.
2035 AttemptConfigOrder
= IScsiGetVariableAndSize (
2038 &AttemptConfigOrderSize
2040 if (AttemptConfigOrder
== NULL
|| AttemptConfigOrderSize
== 0) {
2041 return EFI_NOT_FOUND
;
2045 // Get the iSCSI Initiator Name.
2047 mPrivate
->InitiatorNameLength
= ISCSI_NAME_MAX_SIZE
;
2048 Status
= gIScsiInitiatorName
.Get (
2049 &gIScsiInitiatorName
,
2050 &mPrivate
->InitiatorNameLength
,
2051 mPrivate
->InitiatorName
2053 if (EFI_ERROR (Status
)) {
2058 // Get the normal configuration.
2060 for (Index
= 0; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
2063 // Check whether the attempt exists in AttemptConfig.
2065 AttemptTmp
= IScsiConfigGetAttemptByConfigIndex (AttemptConfigOrder
[Index
]);
2066 if (AttemptTmp
!= NULL
&& AttemptTmp
->SessionConfigData
.Enabled
== ISCSI_DISABLED
) {
2068 } else if (AttemptTmp
!= NULL
&& AttemptTmp
->SessionConfigData
.Enabled
!= ISCSI_DISABLED
) {
2070 // Check the autoconfig path to see whether it should be retried.
2072 if (AttemptTmp
->SessionConfigData
.IpMode
== IP_MODE_AUTOCONFIG
&&
2073 !AttemptTmp
->AutoConfigureSuccess
) {
2074 if (mPrivate
->Ipv6Flag
&&
2075 AttemptTmp
->AutoConfigureMode
== IP_MODE_AUTOCONFIG_IP6
) {
2077 // Autoconfigure for IP6 already attempted but failed. Do not try again.
2080 } else if (!mPrivate
->Ipv6Flag
&&
2081 AttemptTmp
->AutoConfigureMode
== IP_MODE_AUTOCONFIG_IP4
) {
2083 // Autoconfigure for IP4 already attempted but failed. Do not try again.
2088 // Try another approach for this autoconfigure path.
2090 AttemptTmp
->AutoConfigureMode
=
2091 (UINT8
) (mPrivate
->Ipv6Flag
? IP_MODE_AUTOCONFIG_IP6
: IP_MODE_AUTOCONFIG_IP4
);
2092 AttemptTmp
->SessionConfigData
.InitiatorInfoFromDhcp
= TRUE
;
2093 AttemptTmp
->SessionConfigData
.TargetInfoFromDhcp
= TRUE
;
2094 AttemptTmp
->DhcpSuccess
= FALSE
;
2097 // Get some information from the dhcp server.
2099 if (!mPrivate
->Ipv6Flag
) {
2100 Status
= IScsiDoDhcp (Private
->Image
, Private
->Controller
, AttemptTmp
);
2101 if (!EFI_ERROR (Status
)) {
2102 AttemptTmp
->DhcpSuccess
= TRUE
;
2105 Status
= IScsiDoDhcp6 (Private
->Image
, Private
->Controller
, AttemptTmp
);
2106 if (!EFI_ERROR (Status
)) {
2107 AttemptTmp
->DhcpSuccess
= TRUE
;
2112 // Refresh the state of this attempt to NVR.
2115 mPrivate
->PortString
,
2116 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2118 (UINTN
) AttemptTmp
->AttemptConfigIndex
2122 mPrivate
->PortString
,
2123 &gEfiIScsiInitiatorNameProtocolGuid
,
2124 ISCSI_CONFIG_VAR_ATTR
,
2125 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
2131 } else if (AttemptTmp
->SessionConfigData
.InitiatorInfoFromDhcp
&&
2132 !AttemptTmp
->ValidPath
&&
2133 AttemptTmp
->NicIndex
== mPrivate
->CurrentNic
) {
2135 // If the attempt associates with the current NIC, we can
2136 // get DHCP information for already added, but failed, attempt.
2138 AttemptTmp
->DhcpSuccess
= FALSE
;
2139 if (!mPrivate
->Ipv6Flag
&& (AttemptTmp
->SessionConfigData
.IpMode
== IP_MODE_IP4
)) {
2140 Status
= IScsiDoDhcp (Private
->Image
, Private
->Controller
, AttemptTmp
);
2141 if (!EFI_ERROR (Status
)) {
2142 AttemptTmp
->DhcpSuccess
= TRUE
;
2144 } else if (mPrivate
->Ipv6Flag
&& (AttemptTmp
->SessionConfigData
.IpMode
== IP_MODE_IP6
)) {
2145 Status
= IScsiDoDhcp6 (Private
->Image
, Private
->Controller
, AttemptTmp
);
2146 if (!EFI_ERROR (Status
)) {
2147 AttemptTmp
->DhcpSuccess
= TRUE
;
2152 // Refresh the state of this attempt to NVR.
2155 mPrivate
->PortString
,
2156 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2158 (UINTN
) AttemptTmp
->AttemptConfigIndex
2162 mPrivate
->PortString
,
2163 &gEfiIScsiInitiatorNameProtocolGuid
,
2164 ISCSI_CONFIG_VAR_ATTR
,
2165 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
2177 // This attempt does not exist in AttemptConfig. Try to add a new one.
2180 NicInfo
= IScsiGetNicInfoByIndex (mPrivate
->CurrentNic
);
2181 ASSERT (NicInfo
!= NULL
);
2182 IScsiMacAddrToStr (&NicInfo
->PermanentAddress
, NicInfo
->HwAddressSize
, NicInfo
->VlanId
, MacString
);
2184 mPrivate
->PortString
,
2185 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2187 (UINTN
) AttemptConfigOrder
[Index
]
2191 mPrivate
->PortString
,
2192 &gEfiIScsiInitiatorNameProtocolGuid
,
2193 (VOID
**)&AttemptConfigData
,
2196 AsciiStrToUnicodeStrS (AttemptConfigData
->MacString
, AttemptMacString
, sizeof (AttemptMacString
) / sizeof (AttemptMacString
[0]));
2198 if (AttemptConfigData
== NULL
|| AttemptConfigData
->Actived
== ISCSI_ACTIVE_DISABLED
||
2199 StrCmp (MacString
, AttemptMacString
)) {
2203 ASSERT (AttemptConfigOrder
[Index
] == AttemptConfigData
->AttemptConfigIndex
);
2205 AttemptConfigData
->NicIndex
= NicInfo
->NicIndex
;
2206 AttemptConfigData
->DhcpSuccess
= FALSE
;
2207 AttemptConfigData
->ValidiBFTPath
= (BOOLEAN
) (mPrivate
->EnableMpio
? TRUE
: FALSE
);
2208 AttemptConfigData
->ValidPath
= FALSE
;
2210 if (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_AUTOCONFIG
) {
2211 AttemptConfigData
->SessionConfigData
.InitiatorInfoFromDhcp
= TRUE
;
2212 AttemptConfigData
->SessionConfigData
.TargetInfoFromDhcp
= TRUE
;
2214 AttemptConfigData
->AutoConfigureMode
=
2215 (UINT8
) (mPrivate
->Ipv6Flag
? IP_MODE_AUTOCONFIG_IP6
: IP_MODE_AUTOCONFIG_IP4
);
2216 AttemptConfigData
->AutoConfigureSuccess
= FALSE
;
2220 // Get some information from dhcp server.
2222 if (AttemptConfigData
->SessionConfigData
.Enabled
!= ISCSI_DISABLED
&&
2223 AttemptConfigData
->SessionConfigData
.InitiatorInfoFromDhcp
) {
2225 if (!mPrivate
->Ipv6Flag
&&
2226 (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_IP4
||
2227 AttemptConfigData
->AutoConfigureMode
== IP_MODE_AUTOCONFIG_IP4
)) {
2228 Status
= IScsiDoDhcp (Private
->Image
, Private
->Controller
, AttemptConfigData
);
2229 if (!EFI_ERROR (Status
)) {
2230 AttemptConfigData
->DhcpSuccess
= TRUE
;
2232 } else if (mPrivate
->Ipv6Flag
&&
2233 (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_IP6
||
2234 AttemptConfigData
->AutoConfigureMode
== IP_MODE_AUTOCONFIG_IP6
)) {
2235 Status
= IScsiDoDhcp6 (Private
->Image
, Private
->Controller
, AttemptConfigData
);
2236 if (!EFI_ERROR (Status
)) {
2237 AttemptConfigData
->DhcpSuccess
= TRUE
;
2242 // Refresh the state of this attempt to NVR.
2245 mPrivate
->PortString
,
2246 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2248 (UINTN
) AttemptConfigData
->AttemptConfigIndex
2252 mPrivate
->PortString
,
2253 &gEfiIScsiInitiatorNameProtocolGuid
,
2254 ISCSI_CONFIG_VAR_ATTR
,
2255 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
2261 // Update Attempt Help Info.
2264 if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_DISABLED
) {
2265 UnicodeSPrint (IScsiMode
, 64, L
"Disabled");
2266 } else if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED
) {
2267 UnicodeSPrint (IScsiMode
, 64, L
"Enabled");
2268 } else if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED_FOR_MPIO
) {
2269 UnicodeSPrint (IScsiMode
, 64, L
"Enabled for MPIO");
2272 if (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_IP4
) {
2273 UnicodeSPrint (IpMode
, 64, L
"IP4");
2274 } else if (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_IP6
) {
2275 UnicodeSPrint (IpMode
, 64, L
"IP6");
2276 } else if (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_AUTOCONFIG
) {
2277 UnicodeSPrint (IpMode
, 64, L
"Autoconfigure");
2281 mPrivate
->PortString
,
2282 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2283 L
"MAC: %s, PFA: Bus %d | Dev %d | Func %d, iSCSI mode: %s, IP version: %s",
2286 NicInfo
->DeviceNumber
,
2287 NicInfo
->FunctionNumber
,
2292 AttemptConfigData
->AttemptTitleHelpToken
= HiiSetString (
2293 mCallbackInfo
->RegisteredHandle
,
2295 mPrivate
->PortString
,
2298 if (AttemptConfigData
->AttemptTitleHelpToken
== 0) {
2299 return EFI_OUT_OF_RESOURCES
;
2303 // Record the attempt in global link list.
2305 InsertTailList (&mPrivate
->AttemptConfigs
, &AttemptConfigData
->Link
);
2306 mPrivate
->AttemptCount
++;
2308 if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED_FOR_MPIO
) {
2309 mPrivate
->MpioCount
++;
2310 mPrivate
->EnableMpio
= TRUE
;
2312 if (AttemptConfigData
->AuthenticationType
== ISCSI_AUTH_TYPE_KRB
) {
2313 mPrivate
->Krb5MpioCount
++;
2315 } else if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED
) {
2316 mPrivate
->SinglePathCount
++;
2321 // Reorder the AttemptConfig by the configured order.
2323 for (Index
= 0; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
2324 AttemptConfigData
= IScsiConfigGetAttemptByConfigIndex (AttemptConfigOrder
[Index
]);
2325 if (AttemptConfigData
== NULL
) {
2329 RemoveEntryList (&AttemptConfigData
->Link
);
2330 InsertTailList (&mPrivate
->AttemptConfigs
, &AttemptConfigData
->Link
);
2334 // Update the Main Form.
2336 IScsiConfigUpdateAttempt ();
2338 FreePool (AttemptConfigOrder
);
2341 // There should be at least one attempt configuration.
2343 if (!mPrivate
->EnableMpio
) {
2344 if (mPrivate
->SinglePathCount
== 0) {
2345 return EFI_NOT_FOUND
;
2347 mPrivate
->ValidSinglePathCount
= mPrivate
->SinglePathCount
;
2355 Get the device path of the iSCSI tcp connection and update it.
2357 @param Session The iSCSI session.
2359 @return The updated device path.
2360 @retval NULL Other errors as indicated.
2363 EFI_DEVICE_PATH_PROTOCOL
*
2364 IScsiGetTcpConnDevicePath (
2365 IN ISCSI_SESSION
*Session
2368 ISCSI_CONNECTION
*Conn
;
2369 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
2371 EFI_DEV_PATH
*DPathNode
;
2374 if (Session
->State
!= SESSION_STATE_LOGGED_IN
) {
2378 Conn
= NET_LIST_USER_STRUCT_S (
2379 Session
->Conns
.ForwardLink
,
2382 ISCSI_CONNECTION_SIGNATURE
2385 Status
= gBS
->HandleProtocol (
2387 &gEfiDevicePathProtocolGuid
,
2388 (VOID
**) &DevicePath
2390 if (EFI_ERROR (Status
)) {
2396 DevicePath
= DuplicateDevicePath (DevicePath
);
2397 if (DevicePath
== NULL
) {
2401 DPathNode
= (EFI_DEV_PATH
*) DevicePath
;
2403 while (!IsDevicePathEnd (&DPathNode
->DevPath
)) {
2404 if (DevicePathType (&DPathNode
->DevPath
) == MESSAGING_DEVICE_PATH
) {
2405 if (!Conn
->Ipv6Flag
&& DevicePathSubType (&DPathNode
->DevPath
) == MSG_IPv4_DP
) {
2406 DPathNode
->Ipv4
.LocalPort
= 0;
2408 DPathNode
->Ipv4
.StaticIpAddress
=
2409 (BOOLEAN
) (!Session
->ConfigData
->SessionConfigData
.InitiatorInfoFromDhcp
);
2412 // Add a judgement here to support previous versions of IPv4_DEVICE_PATH.
2413 // In previous versions of IPv4_DEVICE_PATH, GatewayIpAddress and SubnetMask
2415 // In new version of IPv4_DEVICE_PATH, structure length is 27.
2418 PathLen
= DevicePathNodeLength (&DPathNode
->Ipv4
);
2420 if (PathLen
== IP4_NODE_LEN_NEW_VERSIONS
) {
2423 &DPathNode
->Ipv4
.GatewayIpAddress
,
2424 &Session
->ConfigData
->SessionConfigData
.Gateway
2428 &DPathNode
->Ipv4
.SubnetMask
,
2429 &Session
->ConfigData
->SessionConfigData
.SubnetMask
2434 } else if (Conn
->Ipv6Flag
&& DevicePathSubType (&DPathNode
->DevPath
) == MSG_IPv6_DP
) {
2435 DPathNode
->Ipv6
.LocalPort
= 0;
2438 // Add a judgement here to support previous versions of IPv6_DEVICE_PATH.
2439 // In previous versions of IPv6_DEVICE_PATH, IpAddressOrigin, PrefixLength
2440 // and GatewayIpAddress do not exist.
2441 // In new version of IPv6_DEVICE_PATH, structure length is 60, while in
2442 // old versions, the length is 43.
2445 PathLen
= DevicePathNodeLength (&DPathNode
->Ipv6
);
2447 if (PathLen
== IP6_NODE_LEN_NEW_VERSIONS
) {
2449 DPathNode
->Ipv6
.IpAddressOrigin
= 0;
2450 DPathNode
->Ipv6
.PrefixLength
= IP6_PREFIX_LENGTH
;
2451 ZeroMem (&DPathNode
->Ipv6
.GatewayIpAddress
, sizeof (EFI_IPv6_ADDRESS
));
2453 else if (PathLen
== IP6_NODE_LEN_OLD_VERSIONS
) {
2456 // StaticIPAddress is a field in old versions of IPv6_DEVICE_PATH, while ignored in new
2457 // version. Set StaticIPAddress through its' offset in old IPv6_DEVICE_PATH.
2459 *((UINT8
*)(&DPathNode
->Ipv6
) + IP6_OLD_IPADDRESS_OFFSET
) =
2460 (BOOLEAN
) (!Session
->ConfigData
->SessionConfigData
.InitiatorInfoFromDhcp
);
2467 DPathNode
= (EFI_DEV_PATH
*) NextDevicePathNode (&DPathNode
->DevPath
);
2475 Abort the session when the transition from BS to RT is initiated.
2477 @param[in] Event The event signaled.
2478 @param[in] Context The iSCSI driver data.
2483 IScsiOnExitBootService (
2488 ISCSI_DRIVER_DATA
*Private
;
2490 Private
= (ISCSI_DRIVER_DATA
*) Context
;
2492 gBS
->CloseEvent (Private
->ExitBootServiceEvent
);
2493 Private
->ExitBootServiceEvent
= NULL
;
2495 if (Private
->Session
!= NULL
) {
2496 IScsiSessionAbort (Private
->Session
);
2501 Tests whether a controller handle is being managed by IScsi driver.
2503 This function tests whether the driver specified by DriverBindingHandle is
2504 currently managing the controller specified by ControllerHandle. This test
2505 is performed by evaluating if the protocol specified by ProtocolGuid is
2506 present on ControllerHandle and is was opened by DriverBindingHandle and Nic
2507 Device handle with an attribute of EFI_OPEN_PROTOCOL_BY_DRIVER.
2508 If ProtocolGuid is NULL, then ASSERT().
2510 @param ControllerHandle A handle for a controller to test.
2511 @param DriverBindingHandle Specifies the driver binding handle for the
2513 @param ProtocolGuid Specifies the protocol that the driver specified
2514 by DriverBindingHandle opens in its Start()
2517 @retval EFI_SUCCESS ControllerHandle is managed by the driver
2518 specified by DriverBindingHandle.
2519 @retval EFI_UNSUPPORTED ControllerHandle is not managed by the driver
2520 specified by DriverBindingHandle.
2525 IScsiTestManagedDevice (
2526 IN EFI_HANDLE ControllerHandle
,
2527 IN EFI_HANDLE DriverBindingHandle
,
2528 IN EFI_GUID
*ProtocolGuid
2532 VOID
*ManagedInterface
;
2533 EFI_HANDLE NicControllerHandle
;
2535 ASSERT (ProtocolGuid
!= NULL
);
2537 NicControllerHandle
= NetLibGetNicHandle (ControllerHandle
, ProtocolGuid
);
2538 if (NicControllerHandle
== NULL
) {
2539 return EFI_UNSUPPORTED
;
2542 Status
= gBS
->OpenProtocol (
2544 (EFI_GUID
*) ProtocolGuid
,
2546 DriverBindingHandle
,
2547 NicControllerHandle
,
2548 EFI_OPEN_PROTOCOL_BY_DRIVER
2550 if (!EFI_ERROR (Status
)) {
2551 gBS
->CloseProtocol (
2553 (EFI_GUID
*) ProtocolGuid
,
2554 DriverBindingHandle
,
2557 return EFI_UNSUPPORTED
;
2560 if (Status
!= EFI_ALREADY_STARTED
) {
2561 return EFI_UNSUPPORTED
;