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
)) {
849 "%a: Failed to set 'InitialAttemptOrder' with Guid (%g): "
851 __FUNCTION__
, &gIScsiConfigGuid
, Status
));
856 // Create new Attempt
858 AttemptConfigData
= AllocateZeroPool (sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
));
859 if (AttemptConfigData
== NULL
) {
860 return EFI_OUT_OF_RESOURCES
;
862 ConfigData
= &AttemptConfigData
->SessionConfigData
;
863 ConfigData
->TargetPort
= ISCSI_WELL_KNOWN_PORT
;
864 ConfigData
->ConnectTimeout
= CONNECT_DEFAULT_TIMEOUT
;
865 ConfigData
->ConnectRetryCount
= CONNECT_MIN_RETRY
;
867 AttemptConfigData
->AuthenticationType
= ISCSI_AUTH_TYPE_CHAP
;
868 AttemptConfigData
->AuthConfigData
.CHAP
.CHAPType
= ISCSI_CHAP_UNI
;
870 // Configure the Attempt index and set variable.
872 AttemptConfigData
->AttemptConfigIndex
= Index
;
875 // Set the attempt name according to the order.
878 mPrivate
->PortString
,
879 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
881 (UINTN
) AttemptConfigData
->AttemptConfigIndex
883 UnicodeStrToAsciiStrS (mPrivate
->PortString
, AttemptConfigData
->AttemptName
, ATTEMPT_NAME_SIZE
);
885 Status
= gRT
->SetVariable (
886 mPrivate
->PortString
,
887 &gEfiIScsiInitiatorNameProtocolGuid
,
888 ISCSI_CONFIG_VAR_ATTR
,
889 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
892 FreePool (AttemptConfigData
);
893 if (EFI_ERROR (Status
)) {
895 "%a: Failed to set variable (mPrivate->PortString) with Guid (%g): "
897 __FUNCTION__
, &gEfiIScsiInitiatorNameProtocolGuid
, Status
));
906 Create the iSCSI configuration Keywords for each attempt. You can find the keywords
907 defined in the "x-UEFI-ns" namespace (http://www.uefi.org/confignamespace).
909 @param[in] KeywordNum The number Sets of Keywords will be created.
911 @retval EFI_SUCCESS The operation is completed.
912 @retval Others Failed to create the Keywords.
916 IScsiCreateKeywords (
920 VOID
*StartOpCodeHandle
;
921 EFI_IFR_GUID_LABEL
*StartLabel
;
922 VOID
*EndOpCodeHandle
;
923 EFI_IFR_GUID_LABEL
*EndLabel
;
925 EFI_STRING_ID StringToken
;
927 CHAR16 KeywordId
[32];
930 Status
= IScsiCreateOpCode (
937 if (EFI_ERROR (Status
)) {
938 return EFI_OUT_OF_RESOURCES
;
941 for (Index
= 1; Index
<= KeywordNum
; Index
++) {
943 // Create iSCSIAttemptName Keyword.
945 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_ATTEMPTT_NAME_PROMPT%d", Index
);
946 StringToken
= HiiSetString (
947 mCallbackInfo
->RegisteredHandle
,
952 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIAttemptName:%d", Index
);
953 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
954 HiiCreateStringOpCode (
956 (EFI_QUESTION_ID
) (ATTEMPT_ATTEMPT_NAME_QUESTION_ID
+ (Index
- 1)),
957 CONFIGURATION_VARSTORE_ID
,
958 (UINT16
) (ATTEMPT_ATTEMPT_NAME_VAR_OFFSET
+ ATTEMPT_NAME_SIZE
* (Index
- 1) * sizeof (CHAR16
)),
961 EFI_IFR_FLAG_READ_ONLY
,
969 // Create iSCSIBootEnable Keyword.
971 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_MODE_PROMPT%d", Index
);
972 StringToken
= HiiSetString (
973 mCallbackInfo
->RegisteredHandle
,
978 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIBootEnable:%d", Index
);
979 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
980 HiiCreateNumericOpCode (
982 (EFI_QUESTION_ID
) (ATTEMPT_BOOTENABLE_QUESTION_ID
+ (Index
- 1)),
983 CONFIGURATION_VARSTORE_ID
,
984 (UINT16
) (ATTEMPT_BOOTENABLE_VAR_OFFSET
+ (Index
- 1)),
988 EFI_IFR_NUMERIC_SIZE_1
,
996 // Create iSCSIIpAddressType Keyword.
998 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_IP_MODE_PROMPT%d", Index
);
999 StringToken
= HiiSetString (
1000 mCallbackInfo
->RegisteredHandle
,
1005 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIIpAddressType:%d", Index
);
1006 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1007 HiiCreateNumericOpCode (
1009 (EFI_QUESTION_ID
) (ATTEMPT_ADDRESS_TYPE_QUESTION_ID
+ (Index
- 1)),
1010 CONFIGURATION_VARSTORE_ID
,
1011 (UINT16
) (ATTEMPT_ADDRESS_TYPE_VAR_OFFSET
+ (Index
- 1)),
1015 EFI_IFR_NUMERIC_SIZE_1
,
1023 // Create iSCSIConnectRetry Keyword.
1025 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CONNECT_RETRY_PROMPT%d", Index
);
1026 StringToken
= HiiSetString (
1027 mCallbackInfo
->RegisteredHandle
,
1032 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIConnectRetry:%d", Index
);
1033 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1034 HiiCreateNumericOpCode (
1036 (EFI_QUESTION_ID
) (ATTEMPT_CONNECT_RETRY_QUESTION_ID
+ (Index
- 1)),
1037 CONFIGURATION_VARSTORE_ID
,
1038 (UINT16
) (ATTEMPT_CONNECT_RETRY_VAR_OFFSET
+ (Index
- 1)),
1042 EFI_IFR_NUMERIC_SIZE_1
,
1050 // Create iSCSIConnectTimeout Keyword.
1052 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CONNECT_TIMEOUT_PROMPT%d", Index
);
1053 StringToken
= HiiSetString (
1054 mCallbackInfo
->RegisteredHandle
,
1059 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIConnectTimeout:%d", Index
);
1060 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1061 HiiCreateNumericOpCode (
1063 (EFI_QUESTION_ID
) (ATTEMPT_CONNECT_TIMEOUT_QUESTION_ID
+ (Index
- 1)),
1064 CONFIGURATION_VARSTORE_ID
,
1065 (UINT16
) (ATTEMPT_CONNECT_TIMEOUT_VAR_OFFSET
+ 2 * (Index
- 1)),
1069 EFI_IFR_NUMERIC_SIZE_2
,
1070 CONNECT_MIN_TIMEOUT
,
1071 CONNECT_MAX_TIMEOUT
,
1077 // Create ISID Keyword.
1079 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_ISID_PROMPT%d", Index
);
1080 StringToken
= HiiSetString (
1081 mCallbackInfo
->RegisteredHandle
,
1086 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIISID:%d", Index
);
1087 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1088 HiiCreateStringOpCode (
1090 (EFI_QUESTION_ID
) (ATTEMPT_ISID_QUESTION_ID
+ (Index
- 1)),
1091 CONFIGURATION_VARSTORE_ID
,
1092 (UINT16
) (ATTEMPT_ISID_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1094 STRING_TOKEN (STR_ISCSI_ISID_HELP
),
1097 ISID_CONFIGURABLE_MIN_LEN
,
1098 ISID_CONFIGURABLE_STORAGE
,
1103 // Create iSCSIInitiatorInfoViaDHCP Keyword.
1105 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_INITIATOR_VIA_DHCP_PROMPT%d", Index
);
1106 StringToken
= HiiSetString (
1107 mCallbackInfo
->RegisteredHandle
,
1112 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIInitiatorInfoViaDHCP:%d", Index
);
1113 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1114 HiiCreateNumericOpCode (
1116 (EFI_QUESTION_ID
) (ATTEMPT_INITIATOR_VIA_DHCP_QUESTION_ID
+ (Index
- 1)),
1117 CONFIGURATION_VARSTORE_ID
,
1118 (UINT16
) (ATTEMPT_INITIATOR_VIA_DHCP_VAR_OFFSET
+ (Index
- 1)),
1130 // Create iSCSIInitiatorIpAddress Keyword.
1132 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_INITIATOR_IP_ADDRESS_PROMPT%d", Index
);
1133 StringToken
= HiiSetString (
1134 mCallbackInfo
->RegisteredHandle
,
1139 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIInitiatorIpAddress:%d", Index
);
1140 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1141 HiiCreateStringOpCode (
1143 (EFI_QUESTION_ID
) (ATTEMPT_INITIATOR_IP_ADDRESS_QUESTION_ID
+ (Index
- 1)),
1144 CONFIGURATION_VARSTORE_ID
,
1145 (UINT16
) (ATTEMPT_INITIATOR_IP_ADDRESS_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1156 // Create iSCSIInitiatorNetmask Keyword.
1158 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_INITIATOR_NET_MASK_PROMPT%d", Index
);
1159 StringToken
= HiiSetString (
1160 mCallbackInfo
->RegisteredHandle
,
1165 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIInitiatorNetmask:%d", Index
);
1166 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1167 HiiCreateStringOpCode (
1169 (EFI_QUESTION_ID
) (ATTEMPT_INITIATOR_NET_MASK_QUESTION_ID
+ (Index
- 1)),
1170 CONFIGURATION_VARSTORE_ID
,
1171 (UINT16
) (ATTEMPT_INITIATOR_NET_MASK_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1182 // Create iSCSIInitiatorGateway Keyword.
1184 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_INITIATOR_GATE_PROMPT%d", Index
);
1185 StringToken
= HiiSetString (
1186 mCallbackInfo
->RegisteredHandle
,
1191 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIInitiatorGateway:%d", Index
);
1192 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1193 HiiCreateStringOpCode (
1195 (EFI_QUESTION_ID
) (ATTEMPT_INITIATOR_GATE_WAY_QUESTION_ID
+ (Index
- 1)),
1196 CONFIGURATION_VARSTORE_ID
,
1197 (UINT16
) (ATTEMPT_INITIATOR_GATE_WAY_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1208 // Create iSCSITargetInfoViaDHCP Keyword.
1210 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_TARGET_VIA_DHCP_PROMPT%d", Index
);
1211 StringToken
= HiiSetString (
1212 mCallbackInfo
->RegisteredHandle
,
1217 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSITargetInfoViaDHCP:%d", Index
);
1218 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1219 HiiCreateNumericOpCode (
1221 (EFI_QUESTION_ID
) (ATTEMPT_TARGET_VIA_DHCP_QUESTION_ID
+ (Index
- 1)),
1222 CONFIGURATION_VARSTORE_ID
,
1223 (UINT16
) (ATTEMPT_TARGET_VIA_DHCP_VAR_OFFSET
+ (Index
- 1)),
1235 // Create iSCSITargetTcpPort Keyword.
1237 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_TARGET_TCP_PORT_PROMPT%d", Index
);
1238 StringToken
= HiiSetString (
1239 mCallbackInfo
->RegisteredHandle
,
1244 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSITargetTcpPort:%d", Index
);
1245 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1246 HiiCreateNumericOpCode (
1248 (EFI_QUESTION_ID
) (ATTEMPT_TARGET_TCP_PORT_QUESTION_ID
+ (Index
- 1)),
1249 CONFIGURATION_VARSTORE_ID
,
1250 (UINT16
) (ATTEMPT_TARGET_TCP_PORT_VAR_OFFSET
+ 2 * (Index
- 1)),
1254 EFI_IFR_NUMERIC_SIZE_2
,
1255 TARGET_PORT_MIN_NUM
,
1256 TARGET_PORT_MAX_NUM
,
1262 // Create iSCSITargetName Keyword.
1264 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_TARGET_NAME_PROMPT%d", Index
);
1265 StringToken
= HiiSetString (
1266 mCallbackInfo
->RegisteredHandle
,
1271 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSITargetName:%d", Index
);
1272 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1273 HiiCreateStringOpCode (
1275 (EFI_QUESTION_ID
) (ATTEMPT_TARGET_NAME_QUESTION_ID
+ (Index
- 1)),
1276 CONFIGURATION_VARSTORE_ID
,
1277 (UINT16
) (ATTEMPT_TARGET_NAME_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1282 ISCSI_NAME_IFR_MIN_SIZE
,
1283 ISCSI_NAME_IFR_MAX_SIZE
,
1288 // Create iSCSITargetIpAddress Keyword.
1290 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_TARGET_IP_ADDRESS_PROMPT%d", Index
);
1291 StringToken
= HiiSetString (
1292 mCallbackInfo
->RegisteredHandle
,
1297 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSITargetIpAddress:%d", Index
);
1298 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1299 HiiCreateStringOpCode (
1301 (EFI_QUESTION_ID
) (ATTEMPT_TARGET_IP_ADDRESS_QUESTION_ID
+ (Index
- 1)),
1302 CONFIGURATION_VARSTORE_ID
,
1303 (UINT16
) (ATTEMPT_TARGET_IP_ADDRESS_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1314 // Create iSCSILUN Keyword.
1316 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_LUN_PROMPT%d", Index
);
1317 StringToken
= HiiSetString (
1318 mCallbackInfo
->RegisteredHandle
,
1323 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSILUN:%d", Index
);
1324 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1325 HiiCreateStringOpCode (
1327 (EFI_QUESTION_ID
) (ATTEMPT_LUN_QUESTION_ID
+ (Index
- 1)),
1328 CONFIGURATION_VARSTORE_ID
,
1329 (UINT16
) (ATTEMPT_LUN_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1340 // Create iSCSIAuthenticationMethod Keyword.
1342 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_AUTHENTICATION_METHOD_PROMPT%d", Index
);
1343 StringToken
= HiiSetString (
1344 mCallbackInfo
->RegisteredHandle
,
1349 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIAuthenticationMethod:%d", Index
);
1350 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1351 HiiCreateNumericOpCode (
1353 (EFI_QUESTION_ID
) (ATTEMPT_AUTHENTICATION_METHOD_QUESTION_ID
+ (Index
- 1)),
1354 CONFIGURATION_VARSTORE_ID
,
1355 (UINT16
) (ATTEMPT_AUTHENTICATION_METHOD_VAR_OFFSET
+ (Index
- 1)),
1367 // Create iSCSIChapType Keyword.
1369 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHARTYPE_PROMPT%d", Index
);
1370 StringToken
= HiiSetString (
1371 mCallbackInfo
->RegisteredHandle
,
1376 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIChapType:%d", Index
);
1377 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1378 HiiCreateNumericOpCode (
1380 (EFI_QUESTION_ID
) (ATTEMPT_CHARTYPE_QUESTION_ID
+ (Index
- 1)),
1381 CONFIGURATION_VARSTORE_ID
,
1382 (UINT16
) (ATTEMPT_CHARTYPE_VAR_OFFSET
+ (Index
- 1)),
1394 // Create iSCSIChapUsername Keyword.
1396 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHAR_USER_NAME_PROMPT%d", Index
);
1397 StringToken
= HiiSetString (
1398 mCallbackInfo
->RegisteredHandle
,
1403 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIChapUsername:%d", Index
);
1404 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1405 HiiCreateStringOpCode (
1407 (EFI_QUESTION_ID
) (ATTEMPT_CHAR_USER_NAME_QUESTION_ID
+ (Index
- 1)),
1408 CONFIGURATION_VARSTORE_ID
,
1409 (UINT16
) (ATTEMPT_CHAR_USER_NAME_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1415 ISCSI_CHAP_NAME_MAX_LEN
,
1420 // Create iSCSIChapSecret Keyword.
1422 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHAR_SECRET_PROMPT%d", Index
);
1423 StringToken
= HiiSetString (
1424 mCallbackInfo
->RegisteredHandle
,
1429 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIChapSecret:%d", Index
);
1430 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1431 HiiCreateStringOpCode (
1433 (EFI_QUESTION_ID
) (ATTEMPT_CHAR_SECRET_QUESTION_ID
+ (Index
- 1)),
1434 CONFIGURATION_VARSTORE_ID
,
1435 (UINT16
) (ATTEMPT_CHAR_SECRET_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1440 ISCSI_CHAP_SECRET_MIN_LEN
,
1441 ISCSI_CHAP_SECRET_MAX_LEN
,
1446 // Create iSCSIReverseChapUsername Keyword.
1448 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHAR_REVERSE_USER_NAME_PROMPT%d", Index
);
1449 StringToken
= HiiSetString (
1450 mCallbackInfo
->RegisteredHandle
,
1455 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIReverseChapUsername:%d", Index
);
1456 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1457 HiiCreateStringOpCode (
1459 (EFI_QUESTION_ID
) (ATTEMPT_CHAR_REVERSE_USER_NAME_QUESTION_ID
+ (Index
- 1)),
1460 CONFIGURATION_VARSTORE_ID
,
1461 (UINT16
) (ATTEMPT_CHAR_REVERSE_USER_NAME_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1467 ISCSI_CHAP_NAME_MAX_LEN
,
1472 // Create iSCSIReverseChapSecret Keyword.
1474 UnicodeSPrint (StringId
, sizeof (StringId
), L
"STR_ISCSI_CHAR_REVERSE_SECRET_PROMPT%d", Index
);
1475 StringToken
= HiiSetString (
1476 mCallbackInfo
->RegisteredHandle
,
1481 UnicodeSPrint (KeywordId
, sizeof (KeywordId
), L
"iSCSIReverseChapSecret:%d", Index
);
1482 HiiSetString (mCallbackInfo
->RegisteredHandle
, StringToken
, KeywordId
, "x-UEFI-ns");
1483 HiiCreateStringOpCode (
1485 (EFI_QUESTION_ID
) (ATTEMPT_CHAR_REVERSE_SECRET_QUESTION_ID
+ (Index
- 1)),
1486 CONFIGURATION_VARSTORE_ID
,
1487 (UINT16
) (ATTEMPT_CHAR_REVERSE_SECRET_VAR_OFFSET
+ sizeof (KEYWORD_STR
) * (Index
- 1)),
1492 ISCSI_CHAP_SECRET_MIN_LEN
,
1493 ISCSI_CHAP_SECRET_MAX_LEN
,
1498 Status
= HiiUpdateForm (
1499 mCallbackInfo
->RegisteredHandle
, // HII handle
1500 &gIScsiConfigGuid
, // Formset GUID
1501 FORMID_ATTEMPT_FORM
, // Form ID
1502 StartOpCodeHandle
, // Label for where to insert opcodes
1503 EndOpCodeHandle
// Replace data
1506 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1507 HiiFreeOpCodeHandle (EndOpCodeHandle
);
1514 Free the attempt configure data variable.
1518 IScsiCleanAttemptVariable (
1522 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
1523 UINT8
*AttemptConfigOrder
;
1524 UINTN AttemptConfigOrderSize
;
1528 // Get the initialized attempt order.
1530 AttemptConfigOrder
= IScsiGetVariableAndSize (
1531 L
"InitialAttemptOrder",
1533 &AttemptConfigOrderSize
1535 if (AttemptConfigOrder
== NULL
|| AttemptConfigOrderSize
== 0) {
1539 for (Index
= 1; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
1541 mPrivate
->PortString
,
1542 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
1548 mPrivate
->PortString
,
1549 &gEfiIScsiInitiatorNameProtocolGuid
,
1550 (VOID
**)&AttemptConfigData
,
1554 if (AttemptConfigData
!= NULL
) {
1556 mPrivate
->PortString
,
1557 &gEfiIScsiInitiatorNameProtocolGuid
,
1568 Get the recorded NIC info from global structure by the Index.
1570 @param[in] NicIndex The index indicates the position of NIC info.
1572 @return Pointer to the NIC info, or NULL if not found.
1576 IScsiGetNicInfoByIndex (
1581 ISCSI_NIC_INFO
*NicInfo
;
1583 NET_LIST_FOR_EACH (Entry
, &mPrivate
->NicInfoList
) {
1584 NicInfo
= NET_LIST_USER_STRUCT (Entry
, ISCSI_NIC_INFO
, Link
);
1585 if (NicInfo
->NicIndex
== NicIndex
) {
1595 Get the NIC's PCI location and return it according to the composited
1596 format defined in iSCSI Boot Firmware Table.
1598 @param[in] Controller The handle of the controller.
1599 @param[out] Bus The bus number.
1600 @param[out] Device The device number.
1601 @param[out] Function The function number.
1603 @return The composited representation of the NIC PCI location.
1607 IScsiGetNICPciLocation (
1608 IN EFI_HANDLE Controller
,
1615 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1616 EFI_HANDLE PciIoHandle
;
1617 EFI_PCI_IO_PROTOCOL
*PciIo
;
1620 Status
= gBS
->HandleProtocol (
1622 &gEfiDevicePathProtocolGuid
,
1623 (VOID
**) &DevicePath
1625 if (EFI_ERROR (Status
)) {
1629 Status
= gBS
->LocateDevicePath (
1630 &gEfiPciIoProtocolGuid
,
1634 if (EFI_ERROR (Status
)) {
1638 Status
= gBS
->HandleProtocol (PciIoHandle
, &gEfiPciIoProtocolGuid
, (VOID
**) &PciIo
);
1639 if (EFI_ERROR (Status
)) {
1643 Status
= PciIo
->GetLocation (PciIo
, &Segment
, Bus
, Device
, Function
);
1644 if (EFI_ERROR (Status
)) {
1648 return (UINT16
) ((*Bus
<< 8) | (*Device
<< 3) | *Function
);
1653 Read the EFI variable (VendorGuid/Name) and return a dynamically allocated
1654 buffer, and the size of the buffer. If failure, return NULL.
1656 @param[in] Name String part of EFI variable name.
1657 @param[in] VendorGuid GUID part of EFI variable name.
1658 @param[out] VariableSize Returns the size of the EFI variable that was read.
1660 @return Dynamically allocated memory that contains a copy of the EFI variable.
1661 @return Caller is responsible freeing the buffer.
1662 @retval NULL Variable was not read.
1666 IScsiGetVariableAndSize (
1668 IN EFI_GUID
*VendorGuid
,
1669 OUT UINTN
*VariableSize
1679 // Pass in a zero size buffer to find the required buffer size.
1682 Status
= gRT
->GetVariable (Name
, VendorGuid
, NULL
, &BufferSize
, Buffer
);
1683 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1685 // Allocate the buffer to return
1687 Buffer
= AllocateZeroPool (BufferSize
);
1688 if (Buffer
== NULL
) {
1692 // Read variable into the allocated buffer.
1694 Status
= gRT
->GetVariable (Name
, VendorGuid
, NULL
, &BufferSize
, Buffer
);
1695 if (EFI_ERROR (Status
)) {
1700 *VariableSize
= BufferSize
;
1706 Create the iSCSI driver data.
1708 @param[in] Image The handle of the driver image.
1709 @param[in] Controller The handle of the controller.
1711 @return The iSCSI driver data created.
1712 @retval NULL Other errors as indicated.
1716 IScsiCreateDriverData (
1717 IN EFI_HANDLE Image
,
1718 IN EFI_HANDLE Controller
1721 ISCSI_DRIVER_DATA
*Private
;
1724 Private
= AllocateZeroPool (sizeof (ISCSI_DRIVER_DATA
));
1725 if (Private
== NULL
) {
1729 Private
->Signature
= ISCSI_DRIVER_DATA_SIGNATURE
;
1730 Private
->Image
= Image
;
1731 Private
->Controller
= Controller
;
1732 Private
->Session
= NULL
;
1735 // Create an event to be signaled when the BS to RT transition is triggerd so
1736 // as to abort the iSCSI session.
1738 Status
= gBS
->CreateEventEx (
1741 IScsiOnExitBootService
,
1743 &gEfiEventExitBootServicesGuid
,
1744 &Private
->ExitBootServiceEvent
1746 if (EFI_ERROR (Status
)) {
1751 Private
->ExtScsiPassThruHandle
= NULL
;
1752 CopyMem(&Private
->IScsiExtScsiPassThru
, &gIScsiExtScsiPassThruProtocolTemplate
, sizeof(EFI_EXT_SCSI_PASS_THRU_PROTOCOL
));
1755 // 0 is designated to the TargetId, so use another value for the AdapterId.
1757 Private
->ExtScsiPassThruMode
.AdapterId
= 2;
1758 Private
->ExtScsiPassThruMode
.Attributes
= EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL
| EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL
;
1759 Private
->ExtScsiPassThruMode
.IoAlign
= 4;
1760 Private
->IScsiExtScsiPassThru
.Mode
= &Private
->ExtScsiPassThruMode
;
1767 Clean the iSCSI driver data.
1769 @param[in] Private The iSCSI driver data.
1771 @retval EFI_SUCCESS The clean operation is successful.
1772 @retval Others Other errors as indicated.
1776 IScsiCleanDriverData (
1777 IN ISCSI_DRIVER_DATA
*Private
1782 Status
= EFI_SUCCESS
;
1784 if (Private
->DevicePath
!= NULL
) {
1785 Status
= gBS
->UninstallProtocolInterface (
1786 Private
->ExtScsiPassThruHandle
,
1787 &gEfiDevicePathProtocolGuid
,
1790 if (EFI_ERROR (Status
)) {
1794 FreePool (Private
->DevicePath
);
1797 if (Private
->ExtScsiPassThruHandle
!= NULL
) {
1798 Status
= gBS
->UninstallProtocolInterface (
1799 Private
->ExtScsiPassThruHandle
,
1800 &gEfiExtScsiPassThruProtocolGuid
,
1801 &Private
->IScsiExtScsiPassThru
1803 if (!EFI_ERROR (Status
)) {
1804 mPrivate
->OneSessionEstablished
= FALSE
;
1809 if (Private
->ExitBootServiceEvent
!= NULL
) {
1810 gBS
->CloseEvent (Private
->ExitBootServiceEvent
);
1813 mCallbackInfo
->Current
= NULL
;
1820 Check wheather the Controller handle is configured to use DHCP protocol.
1822 @param[in] Controller The handle of the controller.
1823 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
1825 @retval TRUE The handle of the controller need the Dhcp protocol.
1826 @retval FALSE The handle of the controller does not need the Dhcp protocol.
1830 IScsiDhcpIsConfigured (
1831 IN EFI_HANDLE Controller
,
1835 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptTmp
;
1836 UINT8
*AttemptConfigOrder
;
1837 UINTN AttemptConfigOrderSize
;
1840 EFI_MAC_ADDRESS MacAddr
;
1841 UINTN HwAddressSize
;
1843 CHAR16 MacString
[ISCSI_MAX_MAC_STRING_LEN
];
1844 CHAR16 AttemptMacString
[ISCSI_MAX_MAC_STRING_LEN
];
1845 CHAR16 AttemptName
[ISCSI_NAME_IFR_MAX_SIZE
];
1847 AttemptConfigOrder
= IScsiGetVariableAndSize (
1850 &AttemptConfigOrderSize
1852 if (AttemptConfigOrder
== NULL
|| AttemptConfigOrderSize
== 0) {
1857 // Get MAC address of this network device.
1859 Status
= NetLibGetMacAddress (Controller
, &MacAddr
, &HwAddressSize
);
1860 if(EFI_ERROR (Status
)) {
1864 // Get VLAN ID of this network device.
1866 VlanId
= NetLibGetVlanId (Controller
);
1867 IScsiMacAddrToStr (&MacAddr
, (UINT32
) HwAddressSize
, VlanId
, MacString
);
1869 for (Index
= 0; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
1874 (UINTN
) AttemptConfigOrder
[Index
]
1876 Status
= GetVariable2 (
1878 &gEfiIScsiInitiatorNameProtocolGuid
,
1879 (VOID
**)&AttemptTmp
,
1882 if(AttemptTmp
== NULL
|| EFI_ERROR (Status
)) {
1886 ASSERT (AttemptConfigOrder
[Index
] == AttemptTmp
->AttemptConfigIndex
);
1888 if (AttemptTmp
->SessionConfigData
.Enabled
== ISCSI_DISABLED
) {
1889 FreePool (AttemptTmp
);
1893 if (AttemptTmp
->SessionConfigData
.IpMode
!= IP_MODE_AUTOCONFIG
&&
1894 AttemptTmp
->SessionConfigData
.IpMode
!= ((IpVersion
== IP_VERSION_4
) ? IP_MODE_IP4
: IP_MODE_IP6
)) {
1895 FreePool (AttemptTmp
);
1899 AsciiStrToUnicodeStrS (AttemptTmp
->MacString
, AttemptMacString
, sizeof (AttemptMacString
) / sizeof (AttemptMacString
[0]));
1901 if (AttemptTmp
->Actived
== ISCSI_ACTIVE_DISABLED
|| StrCmp (MacString
, AttemptMacString
)) {
1905 if(AttemptTmp
->SessionConfigData
.IpMode
== IP_MODE_AUTOCONFIG
||
1906 AttemptTmp
->SessionConfigData
.InitiatorInfoFromDhcp
== TRUE
||
1907 AttemptTmp
->SessionConfigData
.TargetInfoFromDhcp
== TRUE
) {
1908 FreePool (AttemptTmp
);
1909 FreePool (AttemptConfigOrder
);
1913 FreePool (AttemptTmp
);
1916 FreePool (AttemptConfigOrder
);
1921 Check whether the Controller handle is configured to use DNS protocol.
1923 @param[in] Controller The handle of the controller.
1925 @retval TRUE The handle of the controller need the Dns protocol.
1926 @retval FALSE The handle of the controller does not need the Dns protocol.
1930 IScsiDnsIsConfigured (
1931 IN EFI_HANDLE Controller
1934 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptTmp
;
1935 UINT8
*AttemptConfigOrder
;
1936 UINTN AttemptConfigOrderSize
;
1939 EFI_MAC_ADDRESS MacAddr
;
1940 UINTN HwAddressSize
;
1942 CHAR16 AttemptMacString
[ISCSI_MAX_MAC_STRING_LEN
];
1943 CHAR16 MacString
[ISCSI_MAX_MAC_STRING_LEN
];
1944 CHAR16 AttemptName
[ISCSI_NAME_IFR_MAX_SIZE
];
1946 AttemptConfigOrder
= IScsiGetVariableAndSize (
1949 &AttemptConfigOrderSize
1951 if (AttemptConfigOrder
== NULL
|| AttemptConfigOrderSize
== 0) {
1956 // Get MAC address of this network device.
1958 Status
= NetLibGetMacAddress (Controller
, &MacAddr
, &HwAddressSize
);
1959 if(EFI_ERROR (Status
)) {
1963 // Get VLAN ID of this network device.
1965 VlanId
= NetLibGetVlanId (Controller
);
1966 IScsiMacAddrToStr (&MacAddr
, (UINT32
) HwAddressSize
, VlanId
, MacString
);
1968 for (Index
= 0; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
1973 (UINTN
) AttemptConfigOrder
[Index
]
1976 Status
= GetVariable2 (
1978 &gEfiIScsiInitiatorNameProtocolGuid
,
1979 (VOID
**)&AttemptTmp
,
1982 if(AttemptTmp
== NULL
|| EFI_ERROR (Status
)) {
1986 ASSERT (AttemptConfigOrder
[Index
] == AttemptTmp
->AttemptConfigIndex
);
1988 AsciiStrToUnicodeStrS (AttemptTmp
->MacString
, AttemptMacString
, sizeof (AttemptMacString
) / sizeof (AttemptMacString
[0]));
1990 if (AttemptTmp
->SessionConfigData
.Enabled
== ISCSI_DISABLED
|| StrCmp (MacString
, AttemptMacString
)) {
1991 FreePool (AttemptTmp
);
1995 if (AttemptTmp
->SessionConfigData
.DnsMode
|| AttemptTmp
->SessionConfigData
.TargetInfoFromDhcp
) {
1996 FreePool (AttemptTmp
);
1997 FreePool (AttemptConfigOrder
);
2000 FreePool (AttemptTmp
);
2006 FreePool (AttemptConfigOrder
);
2012 Get the various configuration data.
2014 @param[in] Private The iSCSI driver data.
2016 @retval EFI_SUCCESS The configuration data is retrieved.
2017 @retval EFI_NOT_FOUND This iSCSI driver is not configured yet.
2018 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
2022 IScsiGetConfigData (
2023 IN ISCSI_DRIVER_DATA
*Private
2027 CHAR16 MacString
[ISCSI_MAX_MAC_STRING_LEN
];
2028 CHAR16 AttemptMacString
[ISCSI_MAX_MAC_STRING_LEN
];
2030 ISCSI_NIC_INFO
*NicInfo
;
2031 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptConfigData
;
2032 ISCSI_ATTEMPT_CONFIG_NVDATA
*AttemptTmp
;
2033 UINT8
*AttemptConfigOrder
;
2034 UINTN AttemptConfigOrderSize
;
2035 CHAR16 IScsiMode
[64];
2039 // There should be at least one attempt configured.
2041 AttemptConfigOrder
= IScsiGetVariableAndSize (
2044 &AttemptConfigOrderSize
2046 if (AttemptConfigOrder
== NULL
|| AttemptConfigOrderSize
== 0) {
2047 return EFI_NOT_FOUND
;
2051 // Get the iSCSI Initiator Name.
2053 mPrivate
->InitiatorNameLength
= ISCSI_NAME_MAX_SIZE
;
2054 Status
= gIScsiInitiatorName
.Get (
2055 &gIScsiInitiatorName
,
2056 &mPrivate
->InitiatorNameLength
,
2057 mPrivate
->InitiatorName
2059 if (EFI_ERROR (Status
)) {
2064 // Get the normal configuration.
2066 for (Index
= 0; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
2069 // Check whether the attempt exists in AttemptConfig.
2071 AttemptTmp
= IScsiConfigGetAttemptByConfigIndex (AttemptConfigOrder
[Index
]);
2072 if (AttemptTmp
!= NULL
&& AttemptTmp
->SessionConfigData
.Enabled
== ISCSI_DISABLED
) {
2074 } else if (AttemptTmp
!= NULL
&& AttemptTmp
->SessionConfigData
.Enabled
!= ISCSI_DISABLED
) {
2076 // Check the autoconfig path to see whether it should be retried.
2078 if (AttemptTmp
->SessionConfigData
.IpMode
== IP_MODE_AUTOCONFIG
&&
2079 !AttemptTmp
->AutoConfigureSuccess
) {
2080 if (mPrivate
->Ipv6Flag
&&
2081 AttemptTmp
->AutoConfigureMode
== IP_MODE_AUTOCONFIG_IP6
) {
2083 // Autoconfigure for IP6 already attempted but failed. Do not try again.
2086 } else if (!mPrivate
->Ipv6Flag
&&
2087 AttemptTmp
->AutoConfigureMode
== IP_MODE_AUTOCONFIG_IP4
) {
2089 // Autoconfigure for IP4 already attempted but failed. Do not try again.
2094 // Try another approach for this autoconfigure path.
2096 AttemptTmp
->AutoConfigureMode
=
2097 (UINT8
) (mPrivate
->Ipv6Flag
? IP_MODE_AUTOCONFIG_IP6
: IP_MODE_AUTOCONFIG_IP4
);
2098 AttemptTmp
->SessionConfigData
.InitiatorInfoFromDhcp
= TRUE
;
2099 AttemptTmp
->SessionConfigData
.TargetInfoFromDhcp
= TRUE
;
2100 AttemptTmp
->DhcpSuccess
= FALSE
;
2103 // Get some information from the dhcp server.
2105 if (!mPrivate
->Ipv6Flag
) {
2106 Status
= IScsiDoDhcp (Private
->Image
, Private
->Controller
, AttemptTmp
);
2107 if (!EFI_ERROR (Status
)) {
2108 AttemptTmp
->DhcpSuccess
= TRUE
;
2111 Status
= IScsiDoDhcp6 (Private
->Image
, Private
->Controller
, AttemptTmp
);
2112 if (!EFI_ERROR (Status
)) {
2113 AttemptTmp
->DhcpSuccess
= TRUE
;
2118 // Refresh the state of this attempt to NVR.
2121 mPrivate
->PortString
,
2122 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2124 (UINTN
) AttemptTmp
->AttemptConfigIndex
2128 mPrivate
->PortString
,
2129 &gEfiIScsiInitiatorNameProtocolGuid
,
2130 ISCSI_CONFIG_VAR_ATTR
,
2131 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
2137 } else if (AttemptTmp
->SessionConfigData
.InitiatorInfoFromDhcp
&&
2138 !AttemptTmp
->ValidPath
&&
2139 AttemptTmp
->NicIndex
== mPrivate
->CurrentNic
) {
2141 // If the attempt associates with the current NIC, we can
2142 // get DHCP information for already added, but failed, attempt.
2144 AttemptTmp
->DhcpSuccess
= FALSE
;
2145 if (!mPrivate
->Ipv6Flag
&& (AttemptTmp
->SessionConfigData
.IpMode
== IP_MODE_IP4
)) {
2146 Status
= IScsiDoDhcp (Private
->Image
, Private
->Controller
, AttemptTmp
);
2147 if (!EFI_ERROR (Status
)) {
2148 AttemptTmp
->DhcpSuccess
= TRUE
;
2150 } else if (mPrivate
->Ipv6Flag
&& (AttemptTmp
->SessionConfigData
.IpMode
== IP_MODE_IP6
)) {
2151 Status
= IScsiDoDhcp6 (Private
->Image
, Private
->Controller
, AttemptTmp
);
2152 if (!EFI_ERROR (Status
)) {
2153 AttemptTmp
->DhcpSuccess
= TRUE
;
2158 // Refresh the state of this attempt to NVR.
2161 mPrivate
->PortString
,
2162 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2164 (UINTN
) AttemptTmp
->AttemptConfigIndex
2168 mPrivate
->PortString
,
2169 &gEfiIScsiInitiatorNameProtocolGuid
,
2170 ISCSI_CONFIG_VAR_ATTR
,
2171 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
2183 // This attempt does not exist in AttemptConfig. Try to add a new one.
2186 NicInfo
= IScsiGetNicInfoByIndex (mPrivate
->CurrentNic
);
2187 ASSERT (NicInfo
!= NULL
);
2188 IScsiMacAddrToStr (&NicInfo
->PermanentAddress
, NicInfo
->HwAddressSize
, NicInfo
->VlanId
, MacString
);
2190 mPrivate
->PortString
,
2191 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2193 (UINTN
) AttemptConfigOrder
[Index
]
2197 mPrivate
->PortString
,
2198 &gEfiIScsiInitiatorNameProtocolGuid
,
2199 (VOID
**)&AttemptConfigData
,
2202 AsciiStrToUnicodeStrS (AttemptConfigData
->MacString
, AttemptMacString
, sizeof (AttemptMacString
) / sizeof (AttemptMacString
[0]));
2204 if (AttemptConfigData
== NULL
|| AttemptConfigData
->Actived
== ISCSI_ACTIVE_DISABLED
||
2205 StrCmp (MacString
, AttemptMacString
)) {
2209 ASSERT (AttemptConfigOrder
[Index
] == AttemptConfigData
->AttemptConfigIndex
);
2211 AttemptConfigData
->NicIndex
= NicInfo
->NicIndex
;
2212 AttemptConfigData
->DhcpSuccess
= FALSE
;
2213 AttemptConfigData
->ValidiBFTPath
= (BOOLEAN
) (mPrivate
->EnableMpio
? TRUE
: FALSE
);
2214 AttemptConfigData
->ValidPath
= FALSE
;
2216 if (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_AUTOCONFIG
) {
2217 AttemptConfigData
->SessionConfigData
.InitiatorInfoFromDhcp
= TRUE
;
2218 AttemptConfigData
->SessionConfigData
.TargetInfoFromDhcp
= TRUE
;
2220 AttemptConfigData
->AutoConfigureMode
=
2221 (UINT8
) (mPrivate
->Ipv6Flag
? IP_MODE_AUTOCONFIG_IP6
: IP_MODE_AUTOCONFIG_IP4
);
2222 AttemptConfigData
->AutoConfigureSuccess
= FALSE
;
2226 // Get some information from dhcp server.
2228 if (AttemptConfigData
->SessionConfigData
.Enabled
!= ISCSI_DISABLED
&&
2229 AttemptConfigData
->SessionConfigData
.InitiatorInfoFromDhcp
) {
2231 if (!mPrivate
->Ipv6Flag
&&
2232 (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_IP4
||
2233 AttemptConfigData
->AutoConfigureMode
== IP_MODE_AUTOCONFIG_IP4
)) {
2234 Status
= IScsiDoDhcp (Private
->Image
, Private
->Controller
, AttemptConfigData
);
2235 if (!EFI_ERROR (Status
)) {
2236 AttemptConfigData
->DhcpSuccess
= TRUE
;
2238 } else if (mPrivate
->Ipv6Flag
&&
2239 (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_IP6
||
2240 AttemptConfigData
->AutoConfigureMode
== IP_MODE_AUTOCONFIG_IP6
)) {
2241 Status
= IScsiDoDhcp6 (Private
->Image
, Private
->Controller
, AttemptConfigData
);
2242 if (!EFI_ERROR (Status
)) {
2243 AttemptConfigData
->DhcpSuccess
= TRUE
;
2248 // Refresh the state of this attempt to NVR.
2251 mPrivate
->PortString
,
2252 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2254 (UINTN
) AttemptConfigData
->AttemptConfigIndex
2258 mPrivate
->PortString
,
2259 &gEfiIScsiInitiatorNameProtocolGuid
,
2260 ISCSI_CONFIG_VAR_ATTR
,
2261 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA
),
2267 // Update Attempt Help Info.
2270 if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_DISABLED
) {
2271 UnicodeSPrint (IScsiMode
, 64, L
"Disabled");
2272 } else if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED
) {
2273 UnicodeSPrint (IScsiMode
, 64, L
"Enabled");
2274 } else if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED_FOR_MPIO
) {
2275 UnicodeSPrint (IScsiMode
, 64, L
"Enabled for MPIO");
2278 if (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_IP4
) {
2279 UnicodeSPrint (IpMode
, 64, L
"IP4");
2280 } else if (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_IP6
) {
2281 UnicodeSPrint (IpMode
, 64, L
"IP6");
2282 } else if (AttemptConfigData
->SessionConfigData
.IpMode
== IP_MODE_AUTOCONFIG
) {
2283 UnicodeSPrint (IpMode
, 64, L
"Autoconfigure");
2287 mPrivate
->PortString
,
2288 (UINTN
) ISCSI_NAME_IFR_MAX_SIZE
,
2289 L
"MAC: %s, PFA: Bus %d | Dev %d | Func %d, iSCSI mode: %s, IP version: %s",
2292 NicInfo
->DeviceNumber
,
2293 NicInfo
->FunctionNumber
,
2298 AttemptConfigData
->AttemptTitleHelpToken
= HiiSetString (
2299 mCallbackInfo
->RegisteredHandle
,
2301 mPrivate
->PortString
,
2304 if (AttemptConfigData
->AttemptTitleHelpToken
== 0) {
2305 return EFI_OUT_OF_RESOURCES
;
2309 // Record the attempt in global link list.
2311 InsertTailList (&mPrivate
->AttemptConfigs
, &AttemptConfigData
->Link
);
2312 mPrivate
->AttemptCount
++;
2314 if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED_FOR_MPIO
) {
2315 mPrivate
->MpioCount
++;
2316 mPrivate
->EnableMpio
= TRUE
;
2318 if (AttemptConfigData
->AuthenticationType
== ISCSI_AUTH_TYPE_KRB
) {
2319 mPrivate
->Krb5MpioCount
++;
2321 } else if (AttemptConfigData
->SessionConfigData
.Enabled
== ISCSI_ENABLED
) {
2322 mPrivate
->SinglePathCount
++;
2327 // Reorder the AttemptConfig by the configured order.
2329 for (Index
= 0; Index
< AttemptConfigOrderSize
/ sizeof (UINT8
); Index
++) {
2330 AttemptConfigData
= IScsiConfigGetAttemptByConfigIndex (AttemptConfigOrder
[Index
]);
2331 if (AttemptConfigData
== NULL
) {
2335 RemoveEntryList (&AttemptConfigData
->Link
);
2336 InsertTailList (&mPrivate
->AttemptConfigs
, &AttemptConfigData
->Link
);
2340 // Update the Main Form.
2342 IScsiConfigUpdateAttempt ();
2344 FreePool (AttemptConfigOrder
);
2347 // There should be at least one attempt configuration.
2349 if (!mPrivate
->EnableMpio
) {
2350 if (mPrivate
->SinglePathCount
== 0) {
2351 return EFI_NOT_FOUND
;
2353 mPrivate
->ValidSinglePathCount
= mPrivate
->SinglePathCount
;
2361 Get the device path of the iSCSI tcp connection and update it.
2363 @param Session The iSCSI session.
2365 @return The updated device path.
2366 @retval NULL Other errors as indicated.
2369 EFI_DEVICE_PATH_PROTOCOL
*
2370 IScsiGetTcpConnDevicePath (
2371 IN ISCSI_SESSION
*Session
2374 ISCSI_CONNECTION
*Conn
;
2375 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
2377 EFI_DEV_PATH
*DPathNode
;
2380 if (Session
->State
!= SESSION_STATE_LOGGED_IN
) {
2384 Conn
= NET_LIST_USER_STRUCT_S (
2385 Session
->Conns
.ForwardLink
,
2388 ISCSI_CONNECTION_SIGNATURE
2391 Status
= gBS
->HandleProtocol (
2393 &gEfiDevicePathProtocolGuid
,
2394 (VOID
**) &DevicePath
2396 if (EFI_ERROR (Status
)) {
2402 DevicePath
= DuplicateDevicePath (DevicePath
);
2403 if (DevicePath
== NULL
) {
2407 DPathNode
= (EFI_DEV_PATH
*) DevicePath
;
2409 while (!IsDevicePathEnd (&DPathNode
->DevPath
)) {
2410 if (DevicePathType (&DPathNode
->DevPath
) == MESSAGING_DEVICE_PATH
) {
2411 if (!Conn
->Ipv6Flag
&& DevicePathSubType (&DPathNode
->DevPath
) == MSG_IPv4_DP
) {
2412 DPathNode
->Ipv4
.LocalPort
= 0;
2414 DPathNode
->Ipv4
.StaticIpAddress
=
2415 (BOOLEAN
) (!Session
->ConfigData
->SessionConfigData
.InitiatorInfoFromDhcp
);
2418 // Add a judgement here to support previous versions of IPv4_DEVICE_PATH.
2419 // In previous versions of IPv4_DEVICE_PATH, GatewayIpAddress and SubnetMask
2421 // In new version of IPv4_DEVICE_PATH, structcure length is 27.
2424 PathLen
= DevicePathNodeLength (&DPathNode
->Ipv4
);
2426 if (PathLen
== IP4_NODE_LEN_NEW_VERSIONS
) {
2429 &DPathNode
->Ipv4
.GatewayIpAddress
,
2430 &Session
->ConfigData
->SessionConfigData
.Gateway
2434 &DPathNode
->Ipv4
.SubnetMask
,
2435 &Session
->ConfigData
->SessionConfigData
.SubnetMask
2440 } else if (Conn
->Ipv6Flag
&& DevicePathSubType (&DPathNode
->DevPath
) == MSG_IPv6_DP
) {
2441 DPathNode
->Ipv6
.LocalPort
= 0;
2444 // Add a judgement here to support previous versions of IPv6_DEVICE_PATH.
2445 // In previous versions of IPv6_DEVICE_PATH, IpAddressOrigin, PrefixLength
2446 // and GatewayIpAddress do not exist.
2447 // In new version of IPv6_DEVICE_PATH, structure length is 60, while in
2448 // old versions, the length is 43.
2451 PathLen
= DevicePathNodeLength (&DPathNode
->Ipv6
);
2453 if (PathLen
== IP6_NODE_LEN_NEW_VERSIONS
) {
2455 DPathNode
->Ipv6
.IpAddressOrigin
= 0;
2456 DPathNode
->Ipv6
.PrefixLength
= IP6_PREFIX_LENGTH
;
2457 ZeroMem (&DPathNode
->Ipv6
.GatewayIpAddress
, sizeof (EFI_IPv6_ADDRESS
));
2459 else if (PathLen
== IP6_NODE_LEN_OLD_VERSIONS
) {
2462 // StaticIPAddress is a field in old versions of IPv6_DEVICE_PATH, while ignored in new
2463 // version. Set StaticIPAddress through its' offset in old IPv6_DEVICE_PATH.
2465 *((UINT8
*)(&DPathNode
->Ipv6
) + IP6_OLD_IPADDRESS_OFFSET
) =
2466 (BOOLEAN
) (!Session
->ConfigData
->SessionConfigData
.InitiatorInfoFromDhcp
);
2473 DPathNode
= (EFI_DEV_PATH
*) NextDevicePathNode (&DPathNode
->DevPath
);
2481 Abort the session when the transition from BS to RT is initiated.
2483 @param[in] Event The event signaled.
2484 @param[in] Context The iSCSI driver data.
2489 IScsiOnExitBootService (
2494 ISCSI_DRIVER_DATA
*Private
;
2496 Private
= (ISCSI_DRIVER_DATA
*) Context
;
2498 gBS
->CloseEvent (Private
->ExitBootServiceEvent
);
2499 Private
->ExitBootServiceEvent
= NULL
;
2501 if (Private
->Session
!= NULL
) {
2502 IScsiSessionAbort (Private
->Session
);
2507 Tests whether a controller handle is being managed by IScsi driver.
2509 This function tests whether the driver specified by DriverBindingHandle is
2510 currently managing the controller specified by ControllerHandle. This test
2511 is performed by evaluating if the the protocol specified by ProtocolGuid is
2512 present on ControllerHandle and is was opened by DriverBindingHandle and Nic
2513 Device handle with an attribute of EFI_OPEN_PROTOCOL_BY_DRIVER.
2514 If ProtocolGuid is NULL, then ASSERT().
2516 @param ControllerHandle A handle for a controller to test.
2517 @param DriverBindingHandle Specifies the driver binding handle for the
2519 @param ProtocolGuid Specifies the protocol that the driver specified
2520 by DriverBindingHandle opens in its Start()
2523 @retval EFI_SUCCESS ControllerHandle is managed by the driver
2524 specified by DriverBindingHandle.
2525 @retval EFI_UNSUPPORTED ControllerHandle is not managed by the driver
2526 specified by DriverBindingHandle.
2531 IScsiTestManagedDevice (
2532 IN EFI_HANDLE ControllerHandle
,
2533 IN EFI_HANDLE DriverBindingHandle
,
2534 IN EFI_GUID
*ProtocolGuid
2538 VOID
*ManagedInterface
;
2539 EFI_HANDLE NicControllerHandle
;
2541 ASSERT (ProtocolGuid
!= NULL
);
2543 NicControllerHandle
= NetLibGetNicHandle (ControllerHandle
, ProtocolGuid
);
2544 if (NicControllerHandle
== NULL
) {
2545 return EFI_UNSUPPORTED
;
2548 Status
= gBS
->OpenProtocol (
2550 (EFI_GUID
*) ProtocolGuid
,
2552 DriverBindingHandle
,
2553 NicControllerHandle
,
2554 EFI_OPEN_PROTOCOL_BY_DRIVER
2556 if (!EFI_ERROR (Status
)) {
2557 gBS
->CloseProtocol (
2559 (EFI_GUID
*) ProtocolGuid
,
2560 DriverBindingHandle
,
2563 return EFI_UNSUPPORTED
;
2566 if (Status
!= EFI_ALREADY_STARTED
) {
2567 return EFI_UNSUPPORTED
;