2 Miscellaneous routines for iSCSI driver.
4 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "IScsiImpl.h"
17 GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 IScsiHexString
[] = "0123456789ABCDEFabcdef";
20 Removes (trims) specified leading and trailing characters from a string.
22 @param[in, out] Str Pointer to the null-terminated string to be trimmed.
23 On return, Str will hold the trimmed string.
25 @param[in] CharC Character will be trimmed from str.
42 // Trim off the leading and trailing characters c
44 for (Pointer1
= Str
; (*Pointer1
!= 0) && (*Pointer1
== CharC
); Pointer1
++) {
49 if (Pointer2
== Pointer1
) {
50 while (*Pointer1
!= 0) {
55 while (*Pointer1
!= 0) {
56 *Pointer2
= *Pointer1
;
64 for (Pointer1
= Str
+ StrLen(Str
) - 1; Pointer1
>= Str
&& *Pointer1
== CharC
; Pointer1
--) {
67 if (Pointer1
!= Str
+ StrLen(Str
) - 1) {
73 Calculate the prefix length of the IPv4 subnet mask.
75 @param[in] SubnetMask The IPv4 subnet mask.
77 @return The prefix length of the subnet mask.
78 @retval 0 Other errors as indicated.
82 IScsiGetSubnetMaskPrefixLength (
83 IN EFI_IPv4_ADDRESS
*SubnetMask
90 // The SubnetMask is in network byte order.
92 ReverseMask
= (SubnetMask
->Addr
[0] << 24) | (SubnetMask
->Addr
[1] << 16) | (SubnetMask
->Addr
[2] << 8) | (SubnetMask
->Addr
[3]);
97 ReverseMask
= ~ReverseMask
;
99 if ((ReverseMask
& (ReverseMask
+ 1)) != 0) {
105 while (ReverseMask
!= 0) {
106 ReverseMask
= ReverseMask
>> 1;
110 return (UINT8
) (32 - Len
);
115 Convert the hexadecimal encoded LUN string into the 64-bit LUN.
117 @param[in] Str The hexadecimal encoded LUN string.
118 @param[out] Lun Storage to return the 64-bit LUN.
120 @retval EFI_SUCCESS The 64-bit LUN is stored in Lun.
121 @retval EFI_INVALID_PARAMETER The string is malformatted.
130 UINTN Index
, IndexValue
, IndexNum
, SizeStr
;
137 ZeroMem ((UINT8
*) Value
, sizeof (Value
));
138 SizeStr
= AsciiStrLen (Str
);
142 for (Index
= 0; Index
< SizeStr
; Index
++) {
143 TemStr
[0] = Str
[Index
];
144 TemValue
= (UINT8
) AsciiStrHexToUint64 (TemStr
);
145 if (TemValue
== 0 && TemStr
[0] != '0') {
146 if ((TemStr
[0] != '-') || (IndexNum
== 0)) {
150 return EFI_INVALID_PARAMETER
;
154 if ((TemValue
== 0) && (TemStr
[0] == '-')) {
158 if (++IndexValue
>= 4) {
162 return EFI_INVALID_PARAMETER
;
165 // Restart str index for the next lun value.
171 if (++IndexNum
> 4) {
173 // Each Lun Str can't exceed size 4, because it will be as UINT16 value.
175 return EFI_INVALID_PARAMETER
;
179 // Combine UINT16 value.
181 Value
[IndexValue
] = (UINT16
) ((Value
[IndexValue
] << 4) + TemValue
);
184 for (Index
= 0; Index
<= IndexValue
; Index
++) {
185 *((UINT16
*) &Lun
[Index
* 2]) = HTONS (Value
[Index
]);
192 Convert the 64-bit LUN into the hexadecimal encoded LUN string.
194 @param[in] Lun The 64-bit LUN.
195 @param[out] Str The storage to return the hexadecimal encoded LUN string.
199 IScsiLunToUnicodeStr (
209 for (Index
= 0; Index
< 4; Index
++) {
211 if ((Lun
[2 * Index
] | Lun
[2 * Index
+ 1]) == 0) {
212 CopyMem (TempStr
, L
"0-", sizeof (L
"0-"));
214 TempStr
[0] = (CHAR16
) IScsiHexString
[Lun
[2 * Index
] >> 4];
215 TempStr
[1] = (CHAR16
) IScsiHexString
[Lun
[2 * Index
] & 0x0F];
216 TempStr
[2] = (CHAR16
) IScsiHexString
[Lun
[2 * Index
+ 1] >> 4];
217 TempStr
[3] = (CHAR16
) IScsiHexString
[Lun
[2 * Index
+ 1] & 0x0F];
221 IScsiStrTrim (TempStr
, L
'0');
224 TempStr
+= StrLen (TempStr
);
227 // Remove the last '-'
229 ASSERT (StrLen(Str
) >= 1);
230 Str
[StrLen (Str
) - 1] = 0;
232 for (Index
= StrLen (Str
) - 1; Index
> 1; Index
= Index
- 2) {
233 if ((Str
[Index
] == L
'0') && (Str
[Index
- 1] == L
'-')) {
242 Convert the formatted IP address into the binary IP address.
244 @param[in] Str The UNICODE string.
245 @param[in] IpMode Indicates whether the IP address is v4 or v6.
246 @param[out] Ip The storage to return the ASCII string.
248 @retval EFI_SUCCESS The binary IP address is returned in Ip.
249 @retval EFI_INVALID_PARAMETER The IP string is malformatted or IpMode is
257 OUT EFI_IP_ADDRESS
*Ip
262 if (IpMode
== IP_MODE_IP4
|| IpMode
== IP_MODE_AUTOCONFIG_IP4
) {
263 return NetLibAsciiStrToIp4 (Str
, &Ip
->v4
);
265 } else if (IpMode
== IP_MODE_IP6
|| IpMode
== IP_MODE_AUTOCONFIG_IP6
) {
266 return NetLibAsciiStrToIp6 (Str
, &Ip
->v6
);
268 } else if (IpMode
== IP_MODE_AUTOCONFIG
) {
269 Status
= NetLibAsciiStrToIp4 (Str
, &Ip
->v4
);
270 if (!EFI_ERROR (Status
)) {
273 return NetLibAsciiStrToIp6 (Str
, &Ip
->v6
);
277 return EFI_INVALID_PARAMETER
;
281 Convert the mac address into a hexadecimal encoded "-" seperated string.
283 @param[in] Mac The mac address.
284 @param[in] Len Length in bytes of the mac address.
285 @param[in] VlanId VLAN ID of the network device.
286 @param[out] Str The storage to return the mac string.
291 IN EFI_MAC_ADDRESS
*Mac
,
300 for (Index
= 0; Index
< Len
; Index
++) {
301 Str
[3 * Index
] = (CHAR16
) IScsiHexString
[(Mac
->Addr
[Index
] >> 4) & 0x0F];
302 Str
[3 * Index
+ 1] = (CHAR16
) IScsiHexString
[Mac
->Addr
[Index
] & 0x0F];
303 Str
[3 * Index
+ 2] = L
':';
306 String
= &Str
[3 * Index
- 1] ;
308 String
+= UnicodeSPrint (String
, 6 * sizeof (CHAR16
), L
"\\%04x", (UINTN
) VlanId
);
315 Convert the binary encoded buffer into a hexadecimal encoded string.
317 @param[in] BinBuffer The buffer containing the binary data.
318 @param[in] BinLength Length of the binary buffer.
319 @param[in, out] HexStr Pointer to the string.
320 @param[in, out] HexLength The length of the string.
322 @retval EFI_SUCCESS The binary data is converted to the hexadecimal string
323 and the length of the string is updated.
324 @retval EFI_BUFFER_TOO_SMALL The string is too small.
325 @retval EFI_INVALID_PARAMETER The IP string is malformatted.
332 IN OUT CHAR8
*HexStr
,
333 IN OUT UINT32
*HexLength
338 if ((HexStr
== NULL
) || (BinBuffer
== NULL
) || (BinLength
== 0)) {
339 return EFI_INVALID_PARAMETER
;
342 if (((*HexLength
) - 3) < BinLength
* 2) {
343 *HexLength
= BinLength
* 2 + 3;
344 return EFI_BUFFER_TOO_SMALL
;
347 *HexLength
= BinLength
* 2 + 3;
349 // Prefix for Hex String.
354 for (Index
= 0; Index
< BinLength
; Index
++) {
355 HexStr
[Index
* 2 + 2] = IScsiHexString
[BinBuffer
[Index
] >> 4];
356 HexStr
[Index
* 2 + 3] = IScsiHexString
[BinBuffer
[Index
] & 0xf];
359 HexStr
[Index
* 2 + 2] = '\0';
366 Convert the hexadecimal string into a binary encoded buffer.
368 @param[in, out] BinBuffer The binary buffer.
369 @param[in, out] BinLength Length of the binary buffer.
370 @param[in] HexStr The hexadecimal string.
372 @retval EFI_SUCCESS The hexadecimal string is converted into a binary
374 @retval EFI_BUFFER_TOO_SMALL The binary buffer is too small to hold the converted data.
379 IN OUT UINT8
*BinBuffer
,
380 IN OUT UINT32
*BinLength
,
389 ZeroMem (TemStr
, sizeof (TemStr
));
392 // Find out how many hex characters the string has.
394 if ((HexStr
[0] == '0') && ((HexStr
[1] == 'x') || (HexStr
[1] == 'X'))) {
398 Length
= AsciiStrLen (HexStr
);
400 for (Index
= 0; Index
< Length
; Index
++) {
401 TemStr
[0] = HexStr
[Index
];
402 Digit
= (UINT8
) AsciiStrHexToUint64 (TemStr
);
403 if (Digit
== 0 && TemStr
[0] != '0') {
409 if ((Index
& 1) == 0) {
410 BinBuffer
[Index
/2] = Digit
;
412 BinBuffer
[Index
/2] = (UINT8
) ((BinBuffer
[Index
/2] << 4) + Digit
);
416 *BinLength
= (UINT32
) ((Index
+ 1)/2);
423 Convert the decimal-constant string or hex-constant string into a numerical value.
425 @param[in] Str String in decimal or hex.
427 @return The numerical value.
435 if ((Str
[0] == '0') && ((Str
[1] == 'x') || (Str
[1] == 'X'))) {
438 return AsciiStrHexToUintn (Str
);
441 return AsciiStrDecimalToUintn (Str
);
446 Generate random numbers.
448 @param[in, out] Rand The buffer to contain random numbers.
449 @param[in] RandLength The length of the Rand buffer.
460 while (RandLength
> 0) {
461 Random
= NET_RANDOM (NetRandomInitSeed ());
462 *Rand
++ = (UINT8
) (Random
);
469 Check whether UNDI protocol supports IPv6.
471 @param[in] ControllerHandle Controller handle.
472 @param[in] Image Handle of the image.
473 @param[out] Ipv6Support TRUE if UNDI supports IPv6.
475 @retval EFI_SUCCESS Get the result whether UNDI supports IPv6 by NII or AIP protocol successfully.
476 @retval EFI_NOT_FOUND Don't know whether UNDI supports IPv6 since NII or AIP is not available.
480 IScsiCheckIpv6Support (
481 IN EFI_HANDLE ControllerHandle
,
483 OUT BOOLEAN
*Ipv6Support
487 EFI_ADAPTER_INFORMATION_PROTOCOL
*Aip
;
489 EFI_GUID
*InfoTypesBuffer
;
490 UINTN InfoTypeBufferCount
;
496 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL
*Nii
;
498 ASSERT (Ipv6Support
!= NULL
);
501 // Check whether the UNDI supports IPv6 by NII protocol.
503 Status
= gBS
->OpenProtocol (
505 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
509 EFI_OPEN_PROTOCOL_GET_PROTOCOL
511 if (Status
== EFI_SUCCESS
) {
512 *Ipv6Support
= Nii
->Ipv6Supported
;
517 // Get the NIC handle by SNP protocol.
519 Handle
= NetLibGetSnpHandle (ControllerHandle
, NULL
);
520 if (Handle
== NULL
) {
521 return EFI_NOT_FOUND
;
525 Status
= gBS
->HandleProtocol (
527 &gEfiAdapterInformationProtocolGuid
,
530 if (EFI_ERROR (Status
) || Aip
== NULL
) {
531 return EFI_NOT_FOUND
;
534 InfoTypesBuffer
= NULL
;
535 InfoTypeBufferCount
= 0;
536 Status
= Aip
->GetSupportedTypes (Aip
, &InfoTypesBuffer
, &InfoTypeBufferCount
);
537 if (EFI_ERROR (Status
) || InfoTypesBuffer
== NULL
) {
538 FreePool (InfoTypesBuffer
);
539 return EFI_NOT_FOUND
;
543 for (TypeIndex
= 0; TypeIndex
< InfoTypeBufferCount
; TypeIndex
++) {
544 if (CompareGuid (&InfoTypesBuffer
[TypeIndex
], &gEfiAdapterInfoUndiIpv6SupportGuid
)) {
550 FreePool (InfoTypesBuffer
);
552 return EFI_NOT_FOUND
;
556 // We now have adapter information block.
560 Status
= Aip
->GetInformation (Aip
, &gEfiAdapterInfoUndiIpv6SupportGuid
, &InfoBlock
, &InfoBlockSize
);
561 if (EFI_ERROR (Status
) || InfoBlock
== NULL
) {
562 FreePool (InfoBlock
);
563 return EFI_NOT_FOUND
;
566 *Ipv6Support
= ((EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT
*) InfoBlock
)->Ipv6Support
;
567 FreePool (InfoBlock
);
573 Record the NIC info in global structure.
575 @param[in] Controller The handle of the controller.
576 @param[in] Image Handle of the image.
578 @retval EFI_SUCCESS The operation is completed.
579 @retval EFI_OUT_OF_RESOURCES Do not have sufficient resources to finish this
585 IN EFI_HANDLE Controller
,
590 ISCSI_NIC_INFO
*NicInfo
;
592 EFI_MAC_ADDRESS MacAddr
;
597 // Get MAC address of this network device.
599 Status
= NetLibGetMacAddress (Controller
, &MacAddr
, &HwAddressSize
);
600 if (EFI_ERROR (Status
)) {
605 // Get VLAN ID of this network device.
607 VlanId
= NetLibGetVlanId (Controller
);
610 // Check whether the NIC info already exists. Return directly if so.
612 NET_LIST_FOR_EACH (Entry
, &mPrivate
->NicInfoList
) {
613 NicInfo
= NET_LIST_USER_STRUCT (Entry
, ISCSI_NIC_INFO
, Link
);
614 if (NicInfo
->HwAddressSize
== HwAddressSize
&&
615 CompareMem (&NicInfo
->PermanentAddress
, MacAddr
.Addr
, HwAddressSize
) == 0 &&
616 NicInfo
->VlanId
== VlanId
) {
617 mPrivate
->CurrentNic
= NicInfo
->NicIndex
;
620 // Set IPv6 available flag.
622 Status
= IScsiCheckIpv6Support (Controller
, Image
, &NicInfo
->Ipv6Available
);
623 if (EFI_ERROR (Status
)) {
625 // Fail to get the data whether UNDI supports IPv6.
626 // Set default value to TRUE.
628 NicInfo
->Ipv6Available
= TRUE
;
634 if (mPrivate
->MaxNic
< NicInfo
->NicIndex
) {
635 mPrivate
->MaxNic
= NicInfo
->NicIndex
;
640 // Record the NIC info in private structure.
642 NicInfo
= AllocateZeroPool (sizeof (ISCSI_NIC_INFO
));
643 if (NicInfo
== NULL
) {
644 return EFI_OUT_OF_RESOURCES
;
647 CopyMem (&NicInfo
->PermanentAddress
, MacAddr
.Addr
, HwAddressSize
);
648 NicInfo
->HwAddressSize
= (UINT32
) HwAddressSize
;
649 NicInfo
->VlanId
= VlanId
;
650 NicInfo
->NicIndex
= (UINT8
) (mPrivate
->MaxNic
+ 1);
651 mPrivate
->MaxNic
= NicInfo
->NicIndex
;
654 // Set IPv6 available flag.
656 Status
= IScsiCheckIpv6Support (Controller
, Image
, &NicInfo
->Ipv6Available
);
657 if (EFI_ERROR (Status
)) {
659 // Fail to get the data whether UNDI supports IPv6.
660 // Set default value to TRUE.
662 NicInfo
->Ipv6Available
= TRUE
;
666 // Get the PCI location.
668 IScsiGetNICPciLocation (
671 &NicInfo
->DeviceNumber
,
672 &NicInfo
->FunctionNumber
675 InsertTailList (&mPrivate
->NicInfoList
, &NicInfo
->Link
);
676 mPrivate
->NicCount
++;
678 mPrivate
->CurrentNic
= NicInfo
->NicIndex
;
684 Delete the recorded NIC info from global structure. Also delete corresponding
687 @param[in] Controller The handle of the controller.
689 @retval EFI_SUCCESS The operation is completed.
690 @retval EFI_NOT_FOUND The NIC info to be deleted is not recorded.
695 IN EFI_HANDLE Controller
699 ISCSI_NIC_INFO
*NicInfo
;
701 LIST_ENTRY
*NextEntry
;
702 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
703 ISCSI_NIC_INFO
*ThisNic
;
704 EFI_MAC_ADDRESS MacAddr
;
709 // Get MAC address of this network device.
711 Status
= NetLibGetMacAddress (Controller
, &MacAddr
, &HwAddressSize
);
712 if (EFI_ERROR (Status
)) {
717 // Get VLAN ID of this network device.
719 VlanId
= NetLibGetVlanId (Controller
);
722 // Check whether the NIC information exists.
726 NET_LIST_FOR_EACH (Entry
, &mPrivate
->NicInfoList
) {
727 NicInfo
= NET_LIST_USER_STRUCT (Entry
, ISCSI_NIC_INFO
, Link
);
728 if (NicInfo
->HwAddressSize
== HwAddressSize
&&
729 CompareMem (&NicInfo
->PermanentAddress
, MacAddr
.Addr
, HwAddressSize
) == 0 &&
730 NicInfo
->VlanId
== VlanId
) {
737 if (ThisNic
== NULL
) {
738 return EFI_NOT_FOUND
;
741 mPrivate
->CurrentNic
= ThisNic
->NicIndex
;
743 RemoveEntryList (&ThisNic
->Link
);
745 mPrivate
->NicCount
--;
748 // Remove all attempts related to this NIC.
750 NET_LIST_FOR_EACH_SAFE (Entry
, NextEntry
, &mPrivate
->AttemptConfigs
) {
751 AttemptConfigData
= NET_LIST_USER_STRUCT (Entry
, ISCSI_ATTEMPT_CONFIG_NVDATA
, Link
);
752 if (AttemptConfigData
->NicIndex
== mPrivate
->CurrentNic
) {
753 RemoveEntryList (&AttemptConfigData
->Link
);
754 mPrivate
->AttemptCount
--;
756 if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED_FOR_MPIO
&& mPrivate
->MpioCount
> 0) {
757 if (--mPrivate
->MpioCount
== 0) {
758 mPrivate
->EnableMpio
= FALSE
;
761 if (AttemptConfigData
->AuthenticationType
== ISCSI_AUTH_TYPE_KRB
&& mPrivate
->Krb5MpioCount
> 0) {
762 mPrivate
->Krb5MpioCount
--;
765 } else if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED
&& mPrivate
->SinglePathCount
> 0) {
766 mPrivate
->SinglePathCount
--;
768 if (mPrivate
->ValidSinglePathCount
> 0) {
769 mPrivate
->ValidSinglePathCount
--;
773 FreePool (AttemptConfigData
);
781 Create and initialize the Attempts.
783 @param[in] AttemptNum The number of Attempts will be created.
785 @retval EFI_SUCCESS The Attempts have been created successfully.
786 @retval Others Failed to create the Attempt.
790 IScsiCreateAttempts (
794 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
795 ISCSI_SESSION_CONFIG_NVDATA
*ConfigData
;
796 UINT8
*AttemptConfigOrder
;
797 UINTN AttemptConfigOrderSize
;
798 UINT8
*AttemptOrderTmp
;
803 for (Index
= 1; Index
<= AttemptNum
; Index
++) {
805 // Get the initialized attempt order. This is used to essure creating attempts by order.
807 AttemptConfigOrder
= IScsiGetVariableAndSize (
808 L
"InitialAttemptOrder",
810 &AttemptConfigOrderSize
812 TotalNumber
= AttemptConfigOrderSize
/ sizeof (UINT8
);
813 if (TotalNumber
== AttemptNum
) {
814 Status
= EFI_SUCCESS
;
820 // Append the new created attempt to the end.
822 AttemptOrderTmp
= AllocateZeroPool (TotalNumber
* sizeof (UINT8
));
823 if (AttemptOrderTmp
== NULL
) {
824 if (AttemptConfigOrder
!= NULL
) {
825 FreePool (AttemptConfigOrder
);
827 return EFI_OUT_OF_RESOURCES
;
830 if (AttemptConfigOrder
!= NULL
) {
831 CopyMem (AttemptOrderTmp
, AttemptConfigOrder
, AttemptConfigOrderSize
);
832 FreePool (AttemptConfigOrder
);
835 AttemptOrderTmp
[TotalNumber
- 1] = Index
;
836 AttemptConfigOrder
= AttemptOrderTmp
;
837 AttemptConfigOrderSize
= TotalNumber
* sizeof (UINT8
);
839 Status
= gRT
->SetVariable (
840 L
"InitialAttemptOrder",
842 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
843 AttemptConfigOrderSize
,
846 FreePool (AttemptConfigOrder
);
847 if (EFI_ERROR (Status
)) {
852 // Create new Attempt
854 AttemptConfigData
= AllocateZeroPool (sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
));
855 if (AttemptConfigData
== NULL
) {
856 return EFI_OUT_OF_RESOURCES
;
858 ConfigData
= &AttemptConfigData
->SessionConfigData
;
859 ConfigData
->TargetPort
= ISCSI_WELL_KNOWN_PORT
;
860 ConfigData
->ConnectTimeout
= CONNECT_DEFAULT_TIMEOUT
;
861 ConfigData
->ConnectRetryCount
= CONNECT_MIN_RETRY
;
863 AttemptConfigData
->AuthenticationType
= ISCSI_AUTH_TYPE_CHAP
;
864 AttemptConfigData
->AuthConfigData
.CHAP
.CHAPType
= ISCSI_CHAP_UNI
;
866 // Configure the Attempt index and set variable.
868 AttemptConfigData
->AttemptConfigIndex
= Index
;
871 // Set the attempt name according to the order.
874 mPrivate
->PortString
,
875 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
877 (UINTN
) AttemptConfigData
->AttemptConfigIndex
879 UnicodeStrToAsciiStrS (mPrivate
->PortString
, AttemptConfigData
->AttemptName
, ATTEMPT_NAME_SIZE
);
881 Status
= gRT
->SetVariable (
882 mPrivate
->PortString
,
883 &gEfiIScsiInitiatorNameProtocolGuid
,
884 ISCSI_CONFIG_VAR_ATTR
,
885 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
888 FreePool (AttemptConfigData
);
889 if (EFI_ERROR (Status
)) {
898 Create the iSCSI configuration Keywords for each attempt. You can find the keywords
899 defined in the "x-UEFI-ns" namespace (http://www.uefi.org/confignamespace).
901 @param[in] KeywordNum The number Sets of Keywords will be created.
903 @retval EFI_SUCCESS The operation is completed.
904 @retval Others Failed to create the Keywords.
908 IScsiCreateKeywords (
912 VOID
*StartOpCodeHandle
;
913 EFI_IFR_GUID_LABEL
*StartLabel
;
914 VOID
*EndOpCodeHandle
;
915 EFI_IFR_GUID_LABEL
*EndLabel
;
917 EFI_STRING_ID StringToken
;
919 CHAR16 KeywordId
[32];
922 Status
= IScsiCreateOpCode (
929 if (EFI_ERROR (Status
)) {
930 return EFI_OUT_OF_RESOURCES
;
933 for (Index
= 1; Index
<= KeywordNum
; Index
++) {
935 // Create iSCSIAttemptName Keyword.
937 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_ATTEMPTT_NAME_PROMPT%d", Index
);
938 StringToken
= HiiSetString (
939 mCallbackInfo
->RegisteredHandle
,
944 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIAttemptName:%d", Index
);
945 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
946 HiiCreateStringOpCode (
948 (EFI_QUESTION_ID
) (ATTEMPT_ATTEMPT_NAME_QUESTION_ID
+ (Index
- 1)),
949 CONFIGURATION_VARSTORE_ID
,
950 (UINT16
) (ATTEMPT_ATTEMPT_NAME_VAR_OFFSET
+ ATTEMPT_NAME_SIZE
* (Index
- 1) * sizeof (CHAR16
)),
953 EFI_IFR_FLAG_READ_ONLY
,
961 // Create iSCSIBootEnable Keyword.
963 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_MODE_PROMPT%d", Index
);
964 StringToken
= HiiSetString (
965 mCallbackInfo
->RegisteredHandle
,
970 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIBootEnable:%d", Index
);
971 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
972 HiiCreateNumericOpCode (
974 (EFI_QUESTION_ID
) (ATTEMPT_BOOTENABLE_QUESTION_ID
+ (Index
- 1)),
975 CONFIGURATION_VARSTORE_ID
,
976 (UINT16
) (ATTEMPT_BOOTENABLE_VAR_OFFSET
+ (Index
- 1)),
980 EFI_IFR_NUMERIC_SIZE_1
,
988 // Create iSCSIIpAddressType Keyword.
990 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_IP_MODE_PROMPT%d", Index
);
991 StringToken
= HiiSetString (
992 mCallbackInfo
->RegisteredHandle
,
997 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIIpAddressType:%d", Index
);
998 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
999 HiiCreateNumericOpCode (
1001 (EFI_QUESTION_ID
) (ATTEMPT_ADDRESS_TYPE_QUESTION_ID
+ (Index
- 1)),
1002 CONFIGURATION_VARSTORE_ID
,
1003 (UINT16
) (ATTEMPT_ADDRESS_TYPE_VAR_OFFSET
+ (Index
- 1)),
1007 EFI_IFR_NUMERIC_SIZE_1
,
1015 // Create iSCSIConnectRetry Keyword.
1017 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CONNECT_RETRY_PROMPT%d", Index
);
1018 StringToken
= HiiSetString (
1019 mCallbackInfo
->RegisteredHandle
,
1024 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIConnectRetry:%d", Index
);
1025 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1026 HiiCreateNumericOpCode (
1028 (EFI_QUESTION_ID
) (ATTEMPT_CONNECT_RETRY_QUESTION_ID
+ (Index
- 1)),
1029 CONFIGURATION_VARSTORE_ID
,
1030 (UINT16
) (ATTEMPT_CONNECT_RETRY_VAR_OFFSET
+ (Index
- 1)),
1034 EFI_IFR_NUMERIC_SIZE_1
,
1042 // Create iSCSIConnectTimeout Keyword.
1044 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CONNECT_TIMEOUT_PROMPT%d", Index
);
1045 StringToken
= HiiSetString (
1046 mCallbackInfo
->RegisteredHandle
,
1051 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIConnectTimeout:%d", Index
);
1052 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1053 HiiCreateNumericOpCode (
1055 (EFI_QUESTION_ID
) (ATTEMPT_CONNECT_TIMEOUT_QUESTION_ID
+ (Index
- 1)),
1056 CONFIGURATION_VARSTORE_ID
,
1057 (UINT16
) (ATTEMPT_CONNECT_TIMEOUT_VAR_OFFSET
+ 2 * (Index
- 1)),
1061 EFI_IFR_NUMERIC_SIZE_2
,
1062 CONNECT_MIN_TIMEOUT
,
1063 CONNECT_MAX_TIMEOUT
,
1069 // Create ISID Keyword.
1071 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_ISID_PROMPT%d", Index
);
1072 StringToken
= HiiSetString (
1073 mCallbackInfo
->RegisteredHandle
,
1078 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIISID:%d", Index
);
1079 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1080 HiiCreateStringOpCode (
1082 (EFI_QUESTION_ID
) (ATTEMPT_ISID_QUESTION_ID
+ (Index
- 1)),
1083 CONFIGURATION_VARSTORE_ID
,
1084 (UINT16
) (ATTEMPT_ISID_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1086 STRING_TOKEN (STR_ISCSI_ISID_HELP
),
1089 ISID_CONFIGURABLE_MIN_LEN
,
1090 ISID_CONFIGURABLE_STORAGE
,
1095 // Create iSCSIInitiatorInfoViaDHCP Keyword.
1097 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_INITIATOR_VIA_DHCP_PROMPT%d", Index
);
1098 StringToken
= HiiSetString (
1099 mCallbackInfo
->RegisteredHandle
,
1104 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIInitiatorInfoViaDHCP:%d", Index
);
1105 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1106 HiiCreateNumericOpCode (
1108 (EFI_QUESTION_ID
) (ATTEMPT_INITIATOR_VIA_DHCP_QUESTION_ID
+ (Index
- 1)),
1109 CONFIGURATION_VARSTORE_ID
,
1110 (UINT16
) (ATTEMPT_INITIATOR_VIA_DHCP_VAR_OFFSET
+ (Index
- 1)),
1122 // Create iSCSIInitiatorIpAddress Keyword.
1124 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_INITIATOR_IP_ADDRESS_PROMPT%d", Index
);
1125 StringToken
= HiiSetString (
1126 mCallbackInfo
->RegisteredHandle
,
1131 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIInitiatorIpAddress:%d", Index
);
1132 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1133 HiiCreateStringOpCode (
1135 (EFI_QUESTION_ID
) (ATTEMPT_INITIATOR_IP_ADDRESS_QUESTION_ID
+ (Index
- 1)),
1136 CONFIGURATION_VARSTORE_ID
,
1137 (UINT16
) (ATTEMPT_INITIATOR_IP_ADDRESS_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1148 // Create iSCSIInitiatorNetmask Keyword.
1150 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_INITIATOR_NET_MASK_PROMPT%d", Index
);
1151 StringToken
= HiiSetString (
1152 mCallbackInfo
->RegisteredHandle
,
1157 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIInitiatorNetmask:%d", Index
);
1158 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1159 HiiCreateStringOpCode (
1161 (EFI_QUESTION_ID
) (ATTEMPT_INITIATOR_NET_MASK_QUESTION_ID
+ (Index
- 1)),
1162 CONFIGURATION_VARSTORE_ID
,
1163 (UINT16
) (ATTEMPT_INITIATOR_NET_MASK_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1174 // Create iSCSIInitiatorGateway Keyword.
1176 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_INITIATOR_GATE_PROMPT%d", Index
);
1177 StringToken
= HiiSetString (
1178 mCallbackInfo
->RegisteredHandle
,
1183 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIInitiatorGateway:%d", Index
);
1184 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1185 HiiCreateStringOpCode (
1187 (EFI_QUESTION_ID
) (ATTEMPT_INITIATOR_GATE_WAY_QUESTION_ID
+ (Index
- 1)),
1188 CONFIGURATION_VARSTORE_ID
,
1189 (UINT16
) (ATTEMPT_INITIATOR_GATE_WAY_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1200 // Create iSCSITargetInfoViaDHCP Keyword.
1202 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_TARGET_VIA_DHCP_PROMPT%d", Index
);
1203 StringToken
= HiiSetString (
1204 mCallbackInfo
->RegisteredHandle
,
1209 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSITargetInfoViaDHCP:%d", Index
);
1210 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1211 HiiCreateNumericOpCode (
1213 (EFI_QUESTION_ID
) (ATTEMPT_TARGET_VIA_DHCP_QUESTION_ID
+ (Index
- 1)),
1214 CONFIGURATION_VARSTORE_ID
,
1215 (UINT16
) (ATTEMPT_TARGET_VIA_DHCP_VAR_OFFSET
+ (Index
- 1)),
1227 // Create iSCSITargetTcpPort Keyword.
1229 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_TARGET_TCP_PORT_PROMPT%d", Index
);
1230 StringToken
= HiiSetString (
1231 mCallbackInfo
->RegisteredHandle
,
1236 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSITargetTcpPort:%d", Index
);
1237 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1238 HiiCreateNumericOpCode (
1240 (EFI_QUESTION_ID
) (ATTEMPT_TARGET_TCP_PORT_QUESTION_ID
+ (Index
- 1)),
1241 CONFIGURATION_VARSTORE_ID
,
1242 (UINT16
) (ATTEMPT_TARGET_TCP_PORT_VAR_OFFSET
+ 2 * (Index
- 1)),
1246 EFI_IFR_NUMERIC_SIZE_2
,
1247 TARGET_PORT_MIN_NUM
,
1248 TARGET_PORT_MAX_NUM
,
1254 // Create iSCSITargetName Keyword.
1256 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_TARGET_NAME_PROMPT%d", Index
);
1257 StringToken
= HiiSetString (
1258 mCallbackInfo
->RegisteredHandle
,
1263 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSITargetName:%d", Index
);
1264 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1265 HiiCreateStringOpCode (
1267 (EFI_QUESTION_ID
) (ATTEMPT_TARGET_NAME_QUESTION_ID
+ (Index
- 1)),
1268 CONFIGURATION_VARSTORE_ID
,
1269 (UINT16
) (ATTEMPT_TARGET_NAME_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1274 ISCSI_NAME_IFR_MIN_SIZE
,
1275 ISCSI_NAME_IFR_MAX_SIZE
,
1280 // Create iSCSITargetIpAddress Keyword.
1282 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_TARGET_IP_ADDRESS_PROMPT%d", Index
);
1283 StringToken
= HiiSetString (
1284 mCallbackInfo
->RegisteredHandle
,
1289 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSITargetIpAddress:%d", Index
);
1290 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1291 HiiCreateStringOpCode (
1293 (EFI_QUESTION_ID
) (ATTEMPT_TARGET_IP_ADDRESS_QUESTION_ID
+ (Index
- 1)),
1294 CONFIGURATION_VARSTORE_ID
,
1295 (UINT16
) (ATTEMPT_TARGET_IP_ADDRESS_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1306 // Create iSCSILUN Keyword.
1308 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_LUN_PROMPT%d", Index
);
1309 StringToken
= HiiSetString (
1310 mCallbackInfo
->RegisteredHandle
,
1315 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSILUN:%d", Index
);
1316 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1317 HiiCreateStringOpCode (
1319 (EFI_QUESTION_ID
) (ATTEMPT_LUN_QUESTION_ID
+ (Index
- 1)),
1320 CONFIGURATION_VARSTORE_ID
,
1321 (UINT16
) (ATTEMPT_LUN_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1332 // Create iSCSIAuthenticationMethod Keyword.
1334 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_AUTHENTICATION_METHOD_PROMPT%d", Index
);
1335 StringToken
= HiiSetString (
1336 mCallbackInfo
->RegisteredHandle
,
1341 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIAuthenticationMethod:%d", Index
);
1342 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1343 HiiCreateNumericOpCode (
1345 (EFI_QUESTION_ID
) (ATTEMPT_AUTHENTICATION_METHOD_QUESTION_ID
+ (Index
- 1)),
1346 CONFIGURATION_VARSTORE_ID
,
1347 (UINT16
) (ATTEMPT_AUTHENTICATION_METHOD_VAR_OFFSET
+ (Index
- 1)),
1359 // Create iSCSIChapType Keyword.
1361 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHARTYPE_PROMPT%d", Index
);
1362 StringToken
= HiiSetString (
1363 mCallbackInfo
->RegisteredHandle
,
1368 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIChapType:%d", Index
);
1369 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1370 HiiCreateNumericOpCode (
1372 (EFI_QUESTION_ID
) (ATTEMPT_CHARTYPE_QUESTION_ID
+ (Index
- 1)),
1373 CONFIGURATION_VARSTORE_ID
,
1374 (UINT16
) (ATTEMPT_CHARTYPE_VAR_OFFSET
+ (Index
- 1)),
1386 // Create iSCSIChapUsername Keyword.
1388 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHAR_USER_NAME_PROMPT%d", Index
);
1389 StringToken
= HiiSetString (
1390 mCallbackInfo
->RegisteredHandle
,
1395 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIChapUsername:%d", Index
);
1396 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1397 HiiCreateStringOpCode (
1399 (EFI_QUESTION_ID
) (ATTEMPT_CHAR_USER_NAME_QUESTION_ID
+ (Index
- 1)),
1400 CONFIGURATION_VARSTORE_ID
,
1401 (UINT16
) (ATTEMPT_CHAR_USER_NAME_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1407 ISCSI_CHAP_NAME_MAX_LEN
,
1412 // Create iSCSIChapSecret Keyword.
1414 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHAR_SECRET_PROMPT%d", Index
);
1415 StringToken
= HiiSetString (
1416 mCallbackInfo
->RegisteredHandle
,
1421 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIChapSecret:%d", Index
);
1422 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1423 HiiCreateStringOpCode (
1425 (EFI_QUESTION_ID
) (ATTEMPT_CHAR_SECRET_QUESTION_ID
+ (Index
- 1)),
1426 CONFIGURATION_VARSTORE_ID
,
1427 (UINT16
) (ATTEMPT_CHAR_SECRET_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1432 ISCSI_CHAP_SECRET_MIN_LEN
,
1433 ISCSI_CHAP_SECRET_MAX_LEN
,
1438 // Create iSCSIReverseChapUsername Keyword.
1440 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHAR_REVERSE_USER_NAME_PROMPT%d", Index
);
1441 StringToken
= HiiSetString (
1442 mCallbackInfo
->RegisteredHandle
,
1447 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIReverseChapUsername:%d", Index
);
1448 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1449 HiiCreateStringOpCode (
1451 (EFI_QUESTION_ID
) (ATTEMPT_CHAR_REVERSE_USER_NAME_QUESTION_ID
+ (Index
- 1)),
1452 CONFIGURATION_VARSTORE_ID
,
1453 (UINT16
) (ATTEMPT_CHAR_REVERSE_USER_NAME_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1459 ISCSI_CHAP_NAME_MAX_LEN
,
1464 // Create iSCSIReverseChapSecret Keyword.
1466 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHAR_REVERSE_SECRET_PROMPT%d", Index
);
1467 StringToken
= HiiSetString (
1468 mCallbackInfo
->RegisteredHandle
,
1473 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIReverseChapSecret:%d", Index
);
1474 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1475 HiiCreateStringOpCode (
1477 (EFI_QUESTION_ID
) (ATTEMPT_CHAR_REVERSE_SECRET_QUESTION_ID
+ (Index
- 1)),
1478 CONFIGURATION_VARSTORE_ID
,
1479 (UINT16
) (ATTEMPT_CHAR_REVERSE_SECRET_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1484 ISCSI_CHAP_SECRET_MIN_LEN
,
1485 ISCSI_CHAP_SECRET_MAX_LEN
,
1490 Status
= HiiUpdateForm (
1491 mCallbackInfo
->RegisteredHandle
, // HII handle
1492 &gIScsiConfigGuid
, // Formset GUID
1493 FORMID_ATTEMPT_FORM
, // Form ID
1494 StartOpCodeHandle
, // Label for where to insert opcodes
1495 EndOpCodeHandle
// Replace data
1498 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1499 HiiFreeOpCodeHandle (EndOpCodeHandle
);
1506 Free the attempt configure data variable.
1510 IScsiCleanAttemptVariable (
1514 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
1515 UINT8
*AttemptConfigOrder
;
1516 UINTN AttemptConfigOrderSize
;
1520 // Get the initialized attempt order.
1522 AttemptConfigOrder
= IScsiGetVariableAndSize (
1523 L
"InitialAttemptOrder",
1525 &AttemptConfigOrderSize
1527 if (AttemptConfigOrder
== NULL
|| AttemptConfigOrderSize
== 0) {
1531 for (Index
= 1; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
1533 mPrivate
->PortString
,
1534 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
1540 mPrivate
->PortString
,
1541 &gEfiIScsiInitiatorNameProtocolGuid
,
1542 (VOID
**)&AttemptConfigData
,
1546 if (AttemptConfigData
!= NULL
) {
1548 mPrivate
->PortString
,
1549 &gEfiIScsiInitiatorNameProtocolGuid
,
1560 Get the recorded NIC info from global structure by the Index.
1562 @param[in] NicIndex The index indicates the position of NIC info.
1564 @return Pointer to the NIC info, or NULL if not found.
1568 IScsiGetNicInfoByIndex (
1573 ISCSI_NIC_INFO
*NicInfo
;
1575 NET_LIST_FOR_EACH (Entry
, &mPrivate
->NicInfoList
) {
1576 NicInfo
= NET_LIST_USER_STRUCT (Entry
, ISCSI_NIC_INFO
, Link
);
1577 if (NicInfo
->NicIndex
== NicIndex
) {
1587 Get the NIC's PCI location and return it according to the composited
1588 format defined in iSCSI Boot Firmware Table.
1590 @param[in] Controller The handle of the controller.
1591 @param[out] Bus The bus number.
1592 @param[out] Device The device number.
1593 @param[out] Function The function number.
1595 @return The composited representation of the NIC PCI location.
1599 IScsiGetNICPciLocation (
1600 IN EFI_HANDLE Controller
,
1607 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1608 EFI_HANDLE PciIoHandle
;
1609 EFI_PCI_IO_PROTOCOL
*PciIo
;
1612 Status
= gBS
->HandleProtocol (
1614 &gEfiDevicePathProtocolGuid
,
1615 (VOID
**) &DevicePath
1617 if (EFI_ERROR (Status
)) {
1621 Status
= gBS
->LocateDevicePath (
1622 &gEfiPciIoProtocolGuid
,
1626 if (EFI_ERROR (Status
)) {
1630 Status
= gBS
->HandleProtocol (PciIoHandle
, &gEfiPciIoProtocolGuid
, (VOID
**) &PciIo
);
1631 if (EFI_ERROR (Status
)) {
1635 Status
= PciIo
->GetLocation (PciIo
, &Segment
, Bus
, Device
, Function
);
1636 if (EFI_ERROR (Status
)) {
1640 return (UINT16
) ((*Bus
<< 8) | (*Device
<< 3) | *Function
);
1645 Read the EFI variable (VendorGuid/Name) and return a dynamically allocated
1646 buffer, and the size of the buffer. If failure, return NULL.
1648 @param[in] Name String part of EFI variable name.
1649 @param[in] VendorGuid GUID part of EFI variable name.
1650 @param[out] VariableSize Returns the size of the EFI variable that was read.
1652 @return Dynamically allocated memory that contains a copy of the EFI variable.
1653 @return Caller is responsible freeing the buffer.
1654 @retval NULL Variable was not read.
1658 IScsiGetVariableAndSize (
1660 IN EFI_GUID
*VendorGuid
,
1661 OUT UINTN
*VariableSize
1671 // Pass in a zero size buffer to find the required buffer size.
1674 Status
= gRT
->GetVariable (Name
, VendorGuid
, NULL
, &BufferSize
, Buffer
);
1675 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1677 // Allocate the buffer to return
1679 Buffer
= AllocateZeroPool (BufferSize
);
1680 if (Buffer
== NULL
) {
1684 // Read variable into the allocated buffer.
1686 Status
= gRT
->GetVariable (Name
, VendorGuid
, NULL
, &BufferSize
, Buffer
);
1687 if (EFI_ERROR (Status
)) {
1692 *VariableSize
= BufferSize
;
1698 Create the iSCSI driver data.
1700 @param[in] Image The handle of the driver image.
1701 @param[in] Controller The handle of the controller.
1703 @return The iSCSI driver data created.
1704 @retval NULL Other errors as indicated.
1708 IScsiCreateDriverData (
1709 IN EFI_HANDLE Image
,
1710 IN EFI_HANDLE Controller
1713 ISCSI_DRIVER_DATA
*Private
;
1716 Private
= AllocateZeroPool (sizeof (ISCSI_DRIVER_DATA
));
1717 if (Private
== NULL
) {
1721 Private
->Signature
= ISCSI_DRIVER_DATA_SIGNATURE
;
1722 Private
->Image
= Image
;
1723 Private
->Controller
= Controller
;
1724 Private
->Session
= NULL
;
1727 // Create an event to be signaled when the BS to RT transition is triggerd so
1728 // as to abort the iSCSI session.
1730 Status
= gBS
->CreateEventEx (
1733 IScsiOnExitBootService
,
1735 &gEfiEventExitBootServicesGuid
,
1736 &Private
->ExitBootServiceEvent
1738 if (EFI_ERROR (Status
)) {
1743 Private
->ExtScsiPassThruHandle
= NULL
;
1744 CopyMem(&Private
->IScsiExtScsiPassThru
, &gIScsiExtScsiPassThruProtocolTemplate
, sizeof(EFI_EXT_SCSI_PASS_THRU_PROTOCOL
));
1747 // 0 is designated to the TargetId, so use another value for the AdapterId.
1749 Private
->ExtScsiPassThruMode
.AdapterId
= 2;
1750 Private
->ExtScsiPassThruMode
.Attributes
= EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL
| EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL
;
1751 Private
->ExtScsiPassThruMode
.IoAlign
= 4;
1752 Private
->IScsiExtScsiPassThru
.Mode
= &Private
->ExtScsiPassThruMode
;
1759 Clean the iSCSI driver data.
1761 @param[in] Private The iSCSI driver data.
1763 @retval EFI_SUCCESS The clean operation is successful.
1764 @retval Others Other errors as indicated.
1768 IScsiCleanDriverData (
1769 IN ISCSI_DRIVER_DATA
*Private
1774 Status
= EFI_SUCCESS
;
1776 if (Private
->DevicePath
!= NULL
) {
1777 Status
= gBS
->UninstallProtocolInterface (
1778 Private
->ExtScsiPassThruHandle
,
1779 &gEfiDevicePathProtocolGuid
,
1782 if (EFI_ERROR (Status
)) {
1786 FreePool (Private
->DevicePath
);
1789 if (Private
->ExtScsiPassThruHandle
!= NULL
) {
1790 Status
= gBS
->UninstallProtocolInterface (
1791 Private
->ExtScsiPassThruHandle
,
1792 &gEfiExtScsiPassThruProtocolGuid
,
1793 &Private
->IScsiExtScsiPassThru
1795 if (!EFI_ERROR (Status
)) {
1796 mPrivate
->OneSessionEstablished
= FALSE
;
1801 if (Private
->ExitBootServiceEvent
!= NULL
) {
1802 gBS
->CloseEvent (Private
->ExitBootServiceEvent
);
1805 mCallbackInfo
->Current
= NULL
;
1812 Check wheather the Controller handle is configured to use DHCP protocol.
1814 @param[in] Controller The handle of the controller.
1815 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
1817 @retval TRUE The handle of the controller need the Dhcp protocol.
1818 @retval FALSE The handle of the controller does not need the Dhcp protocol.
1822 IScsiDhcpIsConfigured (
1823 IN EFI_HANDLE Controller
,
1827 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptTmp
;
1828 UINT8
*AttemptConfigOrder
;
1829 UINTN AttemptConfigOrderSize
;
1832 EFI_MAC_ADDRESS MacAddr
;
1833 UINTN HwAddressSize
;
1835 CHAR16 MacString
[ISCSI_MAX_MAC_STRING_LEN
];
1836 CHAR16 AttemptMacString
[ISCSI_MAX_MAC_STRING_LEN
];
1837 CHAR16 AttemptName
[ISCSI_NAME_IFR_MAX_SIZE
];
1839 AttemptConfigOrder
= IScsiGetVariableAndSize (
1842 &AttemptConfigOrderSize
1844 if (AttemptConfigOrder
== NULL
|| AttemptConfigOrderSize
== 0) {
1849 // Get MAC address of this network device.
1851 Status
= NetLibGetMacAddress (Controller
, &MacAddr
, &HwAddressSize
);
1852 if(EFI_ERROR (Status
)) {
1856 // Get VLAN ID of this network device.
1858 VlanId
= NetLibGetVlanId (Controller
);
1859 IScsiMacAddrToStr (&MacAddr
, (UINT32
) HwAddressSize
, VlanId
, MacString
);
1861 for (Index
= 0; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
1866 (UINTN
) AttemptConfigOrder
[Index
]
1868 Status
= GetVariable2 (
1870 &gEfiIScsiInitiatorNameProtocolGuid
,
1871 (VOID
**)&AttemptTmp
,
1874 if(AttemptTmp
== NULL
|| EFI_ERROR (Status
)) {
1878 ASSERT (AttemptConfigOrder
[Index
] == AttemptTmp
->AttemptConfigIndex
);
1880 if (AttemptTmp
->SessionConfigData
.Enabled
== ISCSI_DISABLED
) {
1881 FreePool (AttemptTmp
);
1885 if (AttemptTmp
->SessionConfigData
.IpMode
!= IP_MODE_AUTOCONFIG
&&
1886 AttemptTmp
->SessionConfigData
.IpMode
!= ((IpVersion
== IP_VERSION_4
) ? IP_MODE_IP4
: IP_MODE_IP6
)) {
1887 FreePool (AttemptTmp
);
1891 AsciiStrToUnicodeStrS (AttemptTmp
->MacString
, AttemptMacString
, sizeof (AttemptMacString
) / sizeof (AttemptMacString
[0]));
1893 if (AttemptTmp
->Actived
== ISCSI_ACTIVE_DISABLED
|| StrCmp (MacString
, AttemptMacString
)) {
1897 if(AttemptTmp
->SessionConfigData
.IpMode
== IP_MODE_AUTOCONFIG
||
1898 AttemptTmp
->SessionConfigData
.InitiatorInfoFromDhcp
== TRUE
||
1899 AttemptTmp
->SessionConfigData
.TargetInfoFromDhcp
== TRUE
) {
1900 FreePool (AttemptTmp
);
1901 FreePool (AttemptConfigOrder
);
1905 FreePool (AttemptTmp
);
1908 FreePool (AttemptConfigOrder
);
1913 Check whether the Controller handle is configured to use DNS protocol.
1915 @param[in] Controller The handle of the controller.
1917 @retval TRUE The handle of the controller need the Dns protocol.
1918 @retval FALSE The handle of the controller does not need the Dns protocol.
1922 IScsiDnsIsConfigured (
1923 IN EFI_HANDLE Controller
1926 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptTmp
;
1927 UINT8
*AttemptConfigOrder
;
1928 UINTN AttemptConfigOrderSize
;
1931 EFI_MAC_ADDRESS MacAddr
;
1932 UINTN HwAddressSize
;
1934 CHAR16 AttemptMacString
[ISCSI_MAX_MAC_STRING_LEN
];
1935 CHAR16 MacString
[ISCSI_MAX_MAC_STRING_LEN
];
1936 CHAR16 AttemptName
[ISCSI_NAME_IFR_MAX_SIZE
];
1938 AttemptConfigOrder
= IScsiGetVariableAndSize (
1941 &AttemptConfigOrderSize
1943 if (AttemptConfigOrder
== NULL
|| AttemptConfigOrderSize
== 0) {
1948 // Get MAC address of this network device.
1950 Status
= NetLibGetMacAddress (Controller
, &MacAddr
, &HwAddressSize
);
1951 if(EFI_ERROR (Status
)) {
1955 // Get VLAN ID of this network device.
1957 VlanId
= NetLibGetVlanId (Controller
);
1958 IScsiMacAddrToStr (&MacAddr
, (UINT32
) HwAddressSize
, VlanId
, MacString
);
1960 for (Index
= 0; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
1965 (UINTN
) AttemptConfigOrder
[Index
]
1968 Status
= GetVariable2 (
1970 &gEfiIScsiInitiatorNameProtocolGuid
,
1971 (VOID
**)&AttemptTmp
,
1974 if(AttemptTmp
== NULL
|| EFI_ERROR (Status
)) {
1978 ASSERT (AttemptConfigOrder
[Index
] == AttemptTmp
->AttemptConfigIndex
);
1980 AsciiStrToUnicodeStrS (AttemptTmp
->MacString
, AttemptMacString
, sizeof (AttemptMacString
) / sizeof (AttemptMacString
[0]));
1982 if (AttemptTmp
->SessionConfigData
.Enabled
== ISCSI_DISABLED
|| StrCmp (MacString
, AttemptMacString
)) {
1983 FreePool (AttemptTmp
);
1987 if (AttemptTmp
->SessionConfigData
.DnsMode
|| AttemptTmp
->SessionConfigData
.TargetInfoFromDhcp
) {
1988 FreePool (AttemptTmp
);
1989 FreePool (AttemptConfigOrder
);
1992 FreePool (AttemptTmp
);
1998 FreePool (AttemptConfigOrder
);
2004 Get the various configuration data.
2006 @param[in] Private The iSCSI driver data.
2008 @retval EFI_SUCCESS The configuration data is retrieved.
2009 @retval EFI_NOT_FOUND This iSCSI driver is not configured yet.
2010 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
2014 IScsiGetConfigData (
2015 IN ISCSI_DRIVER_DATA
*Private
2019 CHAR16 MacString
[ISCSI_MAX_MAC_STRING_LEN
];
2020 CHAR16 AttemptMacString
[ISCSI_MAX_MAC_STRING_LEN
];
2022 ISCSI_NIC_INFO
*NicInfo
;
2023 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
2024 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptTmp
;
2025 UINT8
*AttemptConfigOrder
;
2026 UINTN AttemptConfigOrderSize
;
2027 CHAR16 IScsiMode
[64];
2031 // There should be at least one attempt configured.
2033 AttemptConfigOrder
= IScsiGetVariableAndSize (
2036 &AttemptConfigOrderSize
2038 if (AttemptConfigOrder
== NULL
|| AttemptConfigOrderSize
== 0) {
2039 return EFI_NOT_FOUND
;
2043 // Get the iSCSI Initiator Name.
2045 mPrivate
->InitiatorNameLength
= ISCSI_NAME_MAX_SIZE
;
2046 Status
= gIScsiInitiatorName
.Get (
2047 &gIScsiInitiatorName
,
2048 &mPrivate
->InitiatorNameLength
,
2049 mPrivate
->InitiatorName
2051 if (EFI_ERROR (Status
)) {
2056 // Get the normal configuration.
2058 for (Index
= 0; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
2061 // Check whether the attempt exists in AttemptConfig.
2063 AttemptTmp
= IScsiConfigGetAttemptByConfigIndex (AttemptConfigOrder
[Index
]);
2064 if (AttemptTmp
!= NULL
&& AttemptTmp
->SessionConfigData
.Enabled
== ISCSI_DISABLED
) {
2066 } else if (AttemptTmp
!= NULL
&& AttemptTmp
->SessionConfigData
.Enabled
!= ISCSI_DISABLED
) {
2068 // Check the autoconfig path to see whether it should be retried.
2070 if (AttemptTmp
->SessionConfigData
.IpMode
== IP_MODE_AUTOCONFIG
&&
2071 !AttemptTmp
->AutoConfigureSuccess
) {
2072 if (mPrivate
->Ipv6Flag
&&
2073 AttemptTmp
->AutoConfigureMode
== IP_MODE_AUTOCONFIG_IP6
) {
2075 // Autoconfigure for IP6 already attempted but failed. Do not try again.
2078 } else if (!mPrivate
->Ipv6Flag
&&
2079 AttemptTmp
->AutoConfigureMode
== IP_MODE_AUTOCONFIG_IP4
) {
2081 // Autoconfigure for IP4 already attempted but failed. Do not try again.
2086 // Try another approach for this autoconfigure path.
2088 AttemptTmp
->AutoConfigureMode
=
2089 (UINT8
) (mPrivate
->Ipv6Flag
? IP_MODE_AUTOCONFIG_IP6
: IP_MODE_AUTOCONFIG_IP4
);
2090 AttemptTmp
->SessionConfigData
.InitiatorInfoFromDhcp
= TRUE
;
2091 AttemptTmp
->SessionConfigData
.TargetInfoFromDhcp
= TRUE
;
2092 AttemptTmp
->DhcpSuccess
= FALSE
;
2095 // Get some information from the dhcp server.
2097 if (!mPrivate
->Ipv6Flag
) {
2098 Status
= IScsiDoDhcp (Private
->Image
, Private
->Controller
, AttemptTmp
);
2099 if (!EFI_ERROR (Status
)) {
2100 AttemptTmp
->DhcpSuccess
= TRUE
;
2103 Status
= IScsiDoDhcp6 (Private
->Image
, Private
->Controller
, AttemptTmp
);
2104 if (!EFI_ERROR (Status
)) {
2105 AttemptTmp
->DhcpSuccess
= TRUE
;
2110 // Refresh the state of this attempt to NVR.
2113 mPrivate
->PortString
,
2114 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2116 (UINTN
) AttemptTmp
->AttemptConfigIndex
2120 mPrivate
->PortString
,
2121 &gEfiIScsiInitiatorNameProtocolGuid
,
2122 ISCSI_CONFIG_VAR_ATTR
,
2123 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
2129 } else if (AttemptTmp
->SessionConfigData
.InitiatorInfoFromDhcp
&&
2130 !AttemptTmp
->ValidPath
&&
2131 AttemptTmp
->NicIndex
== mPrivate
->CurrentNic
) {
2133 // If the attempt associates with the current NIC, we can
2134 // get DHCP information for already added, but failed, attempt.
2136 AttemptTmp
->DhcpSuccess
= FALSE
;
2137 if (!mPrivate
->Ipv6Flag
&& (AttemptTmp
->SessionConfigData
.IpMode
== IP_MODE_IP4
)) {
2138 Status
= IScsiDoDhcp (Private
->Image
, Private
->Controller
, AttemptTmp
);
2139 if (!EFI_ERROR (Status
)) {
2140 AttemptTmp
->DhcpSuccess
= TRUE
;
2142 } else if (mPrivate
->Ipv6Flag
&& (AttemptTmp
->SessionConfigData
.IpMode
== IP_MODE_IP6
)) {
2143 Status
= IScsiDoDhcp6 (Private
->Image
, Private
->Controller
, AttemptTmp
);
2144 if (!EFI_ERROR (Status
)) {
2145 AttemptTmp
->DhcpSuccess
= TRUE
;
2150 // Refresh the state of this attempt to NVR.
2153 mPrivate
->PortString
,
2154 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2156 (UINTN
) AttemptTmp
->AttemptConfigIndex
2160 mPrivate
->PortString
,
2161 &gEfiIScsiInitiatorNameProtocolGuid
,
2162 ISCSI_CONFIG_VAR_ATTR
,
2163 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
2175 // This attempt does not exist in AttemptConfig. Try to add a new one.
2178 NicInfo
= IScsiGetNicInfoByIndex (mPrivate
->CurrentNic
);
2179 ASSERT (NicInfo
!= NULL
);
2180 IScsiMacAddrToStr (&NicInfo
->PermanentAddress
, NicInfo
->HwAddressSize
, NicInfo
->VlanId
, MacString
);
2182 mPrivate
->PortString
,
2183 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2185 (UINTN
) AttemptConfigOrder
[Index
]
2189 mPrivate
->PortString
,
2190 &gEfiIScsiInitiatorNameProtocolGuid
,
2191 (VOID
**)&AttemptConfigData
,
2194 AsciiStrToUnicodeStrS (AttemptConfigData
->MacString
, AttemptMacString
, sizeof (AttemptMacString
) / sizeof (AttemptMacString
[0]));
2196 if (AttemptConfigData
== NULL
|| AttemptConfigData
->Actived
== ISCSI_ACTIVE_DISABLED
||
2197 StrCmp (MacString
, AttemptMacString
)) {
2201 ASSERT (AttemptConfigOrder
[Index
] == AttemptConfigData
->AttemptConfigIndex
);
2203 AttemptConfigData
->NicIndex
= NicInfo
->NicIndex
;
2204 AttemptConfigData
->DhcpSuccess
= FALSE
;
2205 AttemptConfigData
->ValidiBFTPath
= (BOOLEAN
) (mPrivate
->EnableMpio
? TRUE
: FALSE
);
2206 AttemptConfigData
->ValidPath
= FALSE
;
2208 if (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_AUTOCONFIG
) {
2209 AttemptConfigData
->SessionConfigData
.InitiatorInfoFromDhcp
= TRUE
;
2210 AttemptConfigData
->SessionConfigData
.TargetInfoFromDhcp
= TRUE
;
2212 AttemptConfigData
->AutoConfigureMode
=
2213 (UINT8
) (mPrivate
->Ipv6Flag
? IP_MODE_AUTOCONFIG_IP6
: IP_MODE_AUTOCONFIG_IP4
);
2214 AttemptConfigData
->AutoConfigureSuccess
= FALSE
;
2218 // Get some information from dhcp server.
2220 if (AttemptConfigData
->SessionConfigData
.Enabled
!= ISCSI_DISABLED
&&
2221 AttemptConfigData
->SessionConfigData
.InitiatorInfoFromDhcp
) {
2223 if (!mPrivate
->Ipv6Flag
&&
2224 (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_IP4
||
2225 AttemptConfigData
->AutoConfigureMode
== IP_MODE_AUTOCONFIG_IP4
)) {
2226 Status
= IScsiDoDhcp (Private
->Image
, Private
->Controller
, AttemptConfigData
);
2227 if (!EFI_ERROR (Status
)) {
2228 AttemptConfigData
->DhcpSuccess
= TRUE
;
2230 } else if (mPrivate
->Ipv6Flag
&&
2231 (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_IP6
||
2232 AttemptConfigData
->AutoConfigureMode
== IP_MODE_AUTOCONFIG_IP6
)) {
2233 Status
= IScsiDoDhcp6 (Private
->Image
, Private
->Controller
, AttemptConfigData
);
2234 if (!EFI_ERROR (Status
)) {
2235 AttemptConfigData
->DhcpSuccess
= TRUE
;
2240 // Refresh the state of this attempt to NVR.
2243 mPrivate
->PortString
,
2244 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2246 (UINTN
) AttemptConfigData
->AttemptConfigIndex
2250 mPrivate
->PortString
,
2251 &gEfiIScsiInitiatorNameProtocolGuid
,
2252 ISCSI_CONFIG_VAR_ATTR
,
2253 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
2259 // Update Attempt Help Info.
2262 if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_DISABLED
) {
2263 UnicodeSPrint (IScsiMode
, 64, L
"Disabled");
2264 } else if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED
) {
2265 UnicodeSPrint (IScsiMode
, 64, L
"Enabled");
2266 } else if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED_FOR_MPIO
) {
2267 UnicodeSPrint (IScsiMode
, 64, L
"Enabled for MPIO");
2270 if (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_IP4
) {
2271 UnicodeSPrint (IpMode
, 64, L
"IP4");
2272 } else if (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_IP6
) {
2273 UnicodeSPrint (IpMode
, 64, L
"IP6");
2274 } else if (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_AUTOCONFIG
) {
2275 UnicodeSPrint (IpMode
, 64, L
"Autoconfigure");
2279 mPrivate
->PortString
,
2280 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2281 L
"MAC: %s, PFA: Bus %d | Dev %d | Func %d, iSCSI mode: %s, IP version: %s",
2284 NicInfo
->DeviceNumber
,
2285 NicInfo
->FunctionNumber
,
2290 AttemptConfigData
->AttemptTitleHelpToken
= HiiSetString (
2291 mCallbackInfo
->RegisteredHandle
,
2293 mPrivate
->PortString
,
2296 if (AttemptConfigData
->AttemptTitleHelpToken
== 0) {
2297 return EFI_OUT_OF_RESOURCES
;
2301 // Record the attempt in global link list.
2303 InsertTailList (&mPrivate
->AttemptConfigs
, &AttemptConfigData
->Link
);
2304 mPrivate
->AttemptCount
++;
2306 if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED_FOR_MPIO
) {
2307 mPrivate
->MpioCount
++;
2308 mPrivate
->EnableMpio
= TRUE
;
2310 if (AttemptConfigData
->AuthenticationType
== ISCSI_AUTH_TYPE_KRB
) {
2311 mPrivate
->Krb5MpioCount
++;
2313 } else if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED
) {
2314 mPrivate
->SinglePathCount
++;
2319 // Reorder the AttemptConfig by the configured order.
2321 for (Index
= 0; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
2322 AttemptConfigData
= IScsiConfigGetAttemptByConfigIndex (AttemptConfigOrder
[Index
]);
2323 if (AttemptConfigData
== NULL
) {
2327 RemoveEntryList (&AttemptConfigData
->Link
);
2328 InsertTailList (&mPrivate
->AttemptConfigs
, &AttemptConfigData
->Link
);
2332 // Update the Main Form.
2334 IScsiConfigUpdateAttempt ();
2336 FreePool (AttemptConfigOrder
);
2339 // There should be at least one attempt configuration.
2341 if (!mPrivate
->EnableMpio
) {
2342 if (mPrivate
->SinglePathCount
== 0) {
2343 return EFI_NOT_FOUND
;
2345 mPrivate
->ValidSinglePathCount
= mPrivate
->SinglePathCount
;
2353 Get the device path of the iSCSI tcp connection and update it.
2355 @param Session The iSCSI session.
2357 @return The updated device path.
2358 @retval NULL Other errors as indicated.
2361 EFI_DEVICE_PATH_PROTOCOL
*
2362 IScsiGetTcpConnDevicePath (
2363 IN ISCSI_SESSION
*Session
2366 ISCSI_CONNECTION
*Conn
;
2367 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
2369 EFI_DEV_PATH
*DPathNode
;
2372 if (Session
->State
!= SESSION_STATE_LOGGED_IN
) {
2376 Conn
= NET_LIST_USER_STRUCT_S (
2377 Session
->Conns
.ForwardLink
,
2380 ISCSI_CONNECTION_SIGNATURE
2383 Status
= gBS
->HandleProtocol (
2385 &gEfiDevicePathProtocolGuid
,
2386 (VOID
**) &DevicePath
2388 if (EFI_ERROR (Status
)) {
2394 DevicePath
= DuplicateDevicePath (DevicePath
);
2395 if (DevicePath
== NULL
) {
2399 DPathNode
= (EFI_DEV_PATH
*) DevicePath
;
2401 while (!IsDevicePathEnd (&DPathNode
->DevPath
)) {
2402 if (DevicePathType (&DPathNode
->DevPath
) == MESSAGING_DEVICE_PATH
) {
2403 if (!Conn
->Ipv6Flag
&& DevicePathSubType (&DPathNode
->DevPath
) == MSG_IPv4_DP
) {
2404 DPathNode
->Ipv4
.LocalPort
= 0;
2406 DPathNode
->Ipv4
.StaticIpAddress
=
2407 (BOOLEAN
) (!Session
->ConfigData
->SessionConfigData
.InitiatorInfoFromDhcp
);
2410 // Add a judgement here to support previous versions of IPv4_DEVICE_PATH.
2411 // In previous versions of IPv4_DEVICE_PATH, GatewayIpAddress and SubnetMask
2413 // In new version of IPv4_DEVICE_PATH, structcure length is 27.
2416 PathLen
= DevicePathNodeLength (&DPathNode
->Ipv4
);
2418 if (PathLen
== IP4_NODE_LEN_NEW_VERSIONS
) {
2421 &DPathNode
->Ipv4
.GatewayIpAddress
,
2422 &Session
->ConfigData
->SessionConfigData
.Gateway
2426 &DPathNode
->Ipv4
.SubnetMask
,
2427 &Session
->ConfigData
->SessionConfigData
.SubnetMask
2432 } else if (Conn
->Ipv6Flag
&& DevicePathSubType (&DPathNode
->DevPath
) == MSG_IPv6_DP
) {
2433 DPathNode
->Ipv6
.LocalPort
= 0;
2436 // Add a judgement here to support previous versions of IPv6_DEVICE_PATH.
2437 // In previous versions of IPv6_DEVICE_PATH, IpAddressOrigin, PrefixLength
2438 // and GatewayIpAddress do not exist.
2439 // In new version of IPv6_DEVICE_PATH, structure length is 60, while in
2440 // old versions, the length is 43.
2443 PathLen
= DevicePathNodeLength (&DPathNode
->Ipv6
);
2445 if (PathLen
== IP6_NODE_LEN_NEW_VERSIONS
) {
2447 DPathNode
->Ipv6
.IpAddressOrigin
= 0;
2448 DPathNode
->Ipv6
.PrefixLength
= IP6_PREFIX_LENGTH
;
2449 ZeroMem (&DPathNode
->Ipv6
.GatewayIpAddress
, sizeof (EFI_IPv6_ADDRESS
));
2451 else if (PathLen
== IP6_NODE_LEN_OLD_VERSIONS
) {
2454 // StaticIPAddress is a field in old versions of IPv6_DEVICE_PATH, while ignored in new
2455 // version. Set StaticIPAddress through its' offset in old IPv6_DEVICE_PATH.
2457 *((UINT8
*)(&DPathNode
->Ipv6
) + IP6_OLD_IPADDRESS_OFFSET
) =
2458 (BOOLEAN
) (!Session
->ConfigData
->SessionConfigData
.InitiatorInfoFromDhcp
);
2465 DPathNode
= (EFI_DEV_PATH
*) NextDevicePathNode (&DPathNode
->DevPath
);
2473 Abort the session when the transition from BS to RT is initiated.
2475 @param[in] Event The event signaled.
2476 @param[in] Context The iSCSI driver data.
2481 IScsiOnExitBootService (
2486 ISCSI_DRIVER_DATA
*Private
;
2488 Private
= (ISCSI_DRIVER_DATA
*) Context
;
2490 gBS
->CloseEvent (Private
->ExitBootServiceEvent
);
2491 Private
->ExitBootServiceEvent
= NULL
;
2493 if (Private
->Session
!= NULL
) {
2494 IScsiSessionAbort (Private
->Session
);
2499 Tests whether a controller handle is being managed by IScsi driver.
2501 This function tests whether the driver specified by DriverBindingHandle is
2502 currently managing the controller specified by ControllerHandle. This test
2503 is performed by evaluating if the the protocol specified by ProtocolGuid is
2504 present on ControllerHandle and is was opened by DriverBindingHandle and Nic
2505 Device handle with an attribute of EFI_OPEN_PROTOCOL_BY_DRIVER.
2506 If ProtocolGuid is NULL, then ASSERT().
2508 @param ControllerHandle A handle for a controller to test.
2509 @param DriverBindingHandle Specifies the driver binding handle for the
2511 @param ProtocolGuid Specifies the protocol that the driver specified
2512 by DriverBindingHandle opens in its Start()
2515 @retval EFI_SUCCESS ControllerHandle is managed by the driver
2516 specified by DriverBindingHandle.
2517 @retval EFI_UNSUPPORTED ControllerHandle is not managed by the driver
2518 specified by DriverBindingHandle.
2523 IScsiTestManagedDevice (
2524 IN EFI_HANDLE ControllerHandle
,
2525 IN EFI_HANDLE DriverBindingHandle
,
2526 IN EFI_GUID
*ProtocolGuid
2530 VOID
*ManagedInterface
;
2531 EFI_HANDLE NicControllerHandle
;
2533 ASSERT (ProtocolGuid
!= NULL
);
2535 NicControllerHandle
= NetLibGetNicHandle (ControllerHandle
, ProtocolGuid
);
2536 if (NicControllerHandle
== NULL
) {
2537 return EFI_UNSUPPORTED
;
2540 Status
= gBS
->OpenProtocol (
2542 (EFI_GUID
*) ProtocolGuid
,
2544 DriverBindingHandle
,
2545 NicControllerHandle
,
2546 EFI_OPEN_PROTOCOL_BY_DRIVER
2548 if (!EFI_ERROR (Status
)) {
2549 gBS
->CloseProtocol (
2551 (EFI_GUID
*) ProtocolGuid
,
2552 DriverBindingHandle
,
2555 return EFI_UNSUPPORTED
;
2558 if (Status
!= EFI_ALREADY_STARTED
) {
2559 return EFI_UNSUPPORTED
;