From 8873b174c7de6994fcfc1f4d53b1af08841607c4 Mon Sep 17 00:00:00 2001 From: Ye Ting Date: Fri, 18 Dec 2015 06:31:31 +0000 Subject: [PATCH] NetworkPkg: Update iSCSI driver to check existing AIP instances According to UEFI spec, iSCSI HBA must install an AIP instance with network boot information block. This patch updates UEFI iSCSI driver to check whether there are AIP instances installed by iSCSI HBA adapter and if yes, the UEFI iSCSI driver will return EFI_ABORTED in its driver binding Start(). Also the patch introduces a PCD PcdIScsiAIPNetworkBootPolicy for platform owner to define particular policy when the iSCSI HBA will survive and UEFI iSCSI will fail. The default policy is STOP_UEFI_ISCSI_IF_AIP_SUPPORT_OFFLOAD which means that when ISCSI HBA adapter installs an AIP and claims it supports an offload engine for iSCSI boot, the UEFI iSCSI driver will return EFI_ABORTED. The patch V2 adds a new value ALWAYS_USE_UEFI_ISCSI_AND_IGNORE_AIP to PCD PcdIScsiAIPNetworkBootPolicy. This allows the platform to avoid running into buggy IHV drivers that have issue with AIP. It is suggested by El-Haj-Mahmoud,Samer . Cc: El-Haj-Mahmoud Samer Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ye Ting Reviewed-by: Fu siyuan Reviewed-by: Wu Jiaxin Reviewed-by: El-Haj-Mahmoud Samer git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19367 6f19259b-4bc3-4df7-8a09-765794883524 --- NetworkPkg/IScsiDxe/IScsiDriver.c | 151 ++++++++++++++++++++++++++++++ NetworkPkg/IScsiDxe/IScsiDriver.h | 8 ++ NetworkPkg/IScsiDxe/IScsiDxe.inf | 10 +- NetworkPkg/IScsiDxe/IScsiImpl.h | 3 +- NetworkPkg/NetworkPkg.dec | 12 +++ NetworkPkg/NetworkPkg.uni | Bin 3981 -> 11458 bytes 6 files changed, 181 insertions(+), 3 deletions(-) diff --git a/NetworkPkg/IScsiDxe/IScsiDriver.c b/NetworkPkg/IScsiDxe/IScsiDriver.c index 363daadc8f..a7031dfc4e 100644 --- a/NetworkPkg/IScsiDxe/IScsiDriver.c +++ b/NetworkPkg/IScsiDxe/IScsiDriver.c @@ -74,6 +74,142 @@ IScsiIsDevicePathSupported ( return EFI_SUCCESS; } +/** + Check whether an iSCSI HBA adapter already installs an AIP instance with + network boot policy matching the value specified in PcdIScsiAIPNetworkBootPolicy. + If yes, return EFI_SUCCESS. + + @retval EFI_SUCCESS Found an AIP with matching network boot policy. + @retval EFI_NOT_FOUND AIP is unavailable or the network boot policy + not matched. +**/ +EFI_STATUS +IScsiCheckAip ( + ) +{ + UINTN AipHandleCount; + EFI_HANDLE *AipHandleBuffer; + UINTN AipIndex; + EFI_ADAPTER_INFORMATION_PROTOCOL *Aip; + EFI_EXT_SCSI_PASS_THRU_PROTOCOL *ExtScsiPassThru; + EFI_GUID *InfoTypesBuffer; + UINTN InfoTypeBufferCount; + UINTN TypeIndex; + VOID *InfoBlock; + UINTN InfoBlockSize; + BOOLEAN Supported; + EFI_ADAPTER_INFO_NETWORK_BOOT *NetworkBoot; + EFI_STATUS Status; + UINT8 NetworkBootPolicy; + + // + // Check any AIP instances exist in system. + // + AipHandleCount = 0; + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiAdapterInformationProtocolGuid, + NULL, + &AipHandleCount, + &AipHandleBuffer + ); + if (EFI_ERROR (Status) || AipHandleCount == 0) { + return EFI_NOT_FOUND; + } + + InfoBlock = NULL; + + for (AipIndex = 0; AipIndex < AipHandleCount; AipIndex++) { + Status = gBS->HandleProtocol ( + AipHandleBuffer[AipIndex], + &gEfiAdapterInformationProtocolGuid, + (VOID *) &Aip + ); + ASSERT_EFI_ERROR (Status); + ASSERT (Aip != NULL); + + Status = gBS->HandleProtocol ( + AipHandleBuffer[AipIndex], + &gEfiExtScsiPassThruProtocolGuid, + (VOID *) &ExtScsiPassThru + ); + if (EFI_ERROR (Status) || ExtScsiPassThru == NULL) { + continue; + } + + InfoTypesBuffer = NULL; + InfoTypeBufferCount = 0; + Status = Aip->GetSupportedTypes (Aip, &InfoTypesBuffer, &InfoTypeBufferCount); + if (EFI_ERROR (Status) || InfoTypesBuffer == NULL) { + continue; + } + // + // Check whether the AIP instance has Network boot information block. + // + Supported = FALSE; + for (TypeIndex = 0; TypeIndex < InfoTypeBufferCount; TypeIndex++) { + if (CompareGuid (&InfoTypesBuffer[TypeIndex], &gEfiAdapterInfoNetworkBootGuid)) { + Supported = TRUE; + break; + } + } + + FreePool (InfoTypesBuffer); + if (!Supported) { + continue; + } + + // + // We now have network boot information block. + // + InfoBlock = NULL; + InfoBlockSize = 0; + Status = Aip->GetInformation (Aip, &gEfiAdapterInfoNetworkBootGuid, &InfoBlock, &InfoBlockSize); + if (EFI_ERROR (Status) || InfoBlock == NULL) { + continue; + } + + // + // Check whether the network boot policy matches. + // + NetworkBoot = (EFI_ADAPTER_INFO_NETWORK_BOOT *) InfoBlock; + NetworkBootPolicy = PcdGet8 (PcdIScsiAIPNetworkBootPolicy); + + if (NetworkBootPolicy == STOP_UEFI_ISCSI_IF_HBA_INSTALL_AIP) { + Status = EFI_SUCCESS; + goto Exit; + } + if (((NetworkBootPolicy & STOP_UEFI_ISCSI_IF_AIP_SUPPORT_IP4) != 0 && + !NetworkBoot->iScsiIpv4BootCapablity) || + ((NetworkBootPolicy & STOP_UEFI_ISCSI_IF_AIP_SUPPORT_IP6) != 0 && + !NetworkBoot->iScsiIpv6BootCapablity) || + ((NetworkBootPolicy & STOP_UEFI_ISCSI_IF_AIP_SUPPORT_OFFLOAD) != 0 && + !NetworkBoot->OffloadCapability) || + ((NetworkBootPolicy & STOP_UEFI_ISCSI_IF_AIP_SUPPORT_MPIO) != 0 && + !NetworkBoot->iScsiMpioCapability) || + ((NetworkBootPolicy & STOP_UEFI_ISCSI_IF_AIP_CONFIGURED_IP4) != 0 && + !NetworkBoot->iScsiIpv4Boot) || + ((NetworkBootPolicy & STOP_UEFI_ISCSI_IF_AIP_CONFIGURED_IP6) != 0 && + !NetworkBoot->iScsiIpv6Boot)) { + FreePool (InfoBlock); + continue; + } + + Status = EFI_SUCCESS; + goto Exit; + } + + Status = EFI_NOT_FOUND; + +Exit: + if (InfoBlock != NULL) { + FreePool (InfoBlock); + } + if (AipHandleBuffer != NULL) { + FreePool (AipHandleBuffer); + } + return Status; +} /** Tests to see if this driver supports a given controller. This is the worker function for @@ -215,6 +351,7 @@ IScsiStart ( BOOLEAN NeedUpdate; VOID *Interface; EFI_GUID *ProtocolGuid; + UINT8 NetworkBootPolicy; // // Test to see if iSCSI driver supports the given controller. @@ -256,6 +393,20 @@ IScsiStart ( return EFI_UNSUPPORTED; } + NetworkBootPolicy = PcdGet8 (PcdIScsiAIPNetworkBootPolicy); + if (NetworkBootPolicy != ALWAYS_USE_UEFI_ISCSI_AND_IGNORE_AIP) { + // + // Check existing iSCSI AIP. + // + Status = IScsiCheckAip (); + if (!EFI_ERROR (Status)) { + // + // Find iSCSI AIP with specified network boot policy. return EFI_ABORTED. + // + return EFI_ABORTED; + } + } + // // Record the incoming NIC info. // diff --git a/NetworkPkg/IScsiDxe/IScsiDriver.h b/NetworkPkg/IScsiDxe/IScsiDriver.h index 338e3dcf18..9e59b3857e 100644 --- a/NetworkPkg/IScsiDxe/IScsiDriver.h +++ b/NetworkPkg/IScsiDxe/IScsiDriver.h @@ -29,6 +29,14 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #define IP_MODE_AUTOCONFIG_IP4 3 #define IP_MODE_AUTOCONFIG_IP6 4 +#define ALWAYS_USE_UEFI_ISCSI_AND_IGNORE_AIP 0x00 +#define STOP_UEFI_ISCSI_IF_HBA_INSTALL_AIP 0x01 +#define STOP_UEFI_ISCSI_IF_AIP_SUPPORT_IP4 0x02 +#define STOP_UEFI_ISCSI_IF_AIP_SUPPORT_IP6 0x04 +#define STOP_UEFI_ISCSI_IF_AIP_SUPPORT_OFFLOAD 0x08 +#define STOP_UEFI_ISCSI_IF_AIP_SUPPORT_MPIO 0x10 +#define STOP_UEFI_ISCSI_IF_AIP_CONFIGURED_IP4 0x20 +#define STOP_UEFI_ISCSI_IF_AIP_CONFIGURED_IP6 0x40 extern EFI_COMPONENT_NAME2_PROTOCOL gIScsiComponentName2; extern EFI_COMPONENT_NAME_PROTOCOL gIScsiComponentName; diff --git a/NetworkPkg/IScsiDxe/IScsiDxe.inf b/NetworkPkg/IScsiDxe/IScsiDxe.inf index 3e20828c51..89521209b7 100644 --- a/NetworkPkg/IScsiDxe/IScsiDxe.inf +++ b/NetworkPkg/IScsiDxe/IScsiDxe.inf @@ -4,7 +4,7 @@ # The iSCSI driver provides iSCSI service in the preboot environment and supports # booting over iSCSI. # -# Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.
# This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License # which accompanies this distribution. The full text of the license may be found at @@ -106,7 +106,9 @@ ## UNDEFINED # Variable gEfiIScsiInitiatorNameProtocolGuid ## PRODUCES - gEfiAuthenticationInfoProtocolGuid + gEfiAuthenticationInfoProtocolGuid + ## CONSUMES + gEfiAdapterInformationProtocolGuid [Guids] gEfiEventExitBootServicesGuid ## SOMETIMES_CONSUMES ## Event @@ -114,6 +116,7 @@ gEfiAcpiTableGuid ## SOMETIMES_CONSUMES ## SystemTable gEfiAcpi10TableGuid ## SOMETIMES_CONSUMES ## SystemTable gEfiAcpi20TableGuid ## SOMETIMES_CONSUMES ## SystemTable + gEfiAdapterInfoNetworkBootGuid ## SOMETIMES_CONSUMES ## UNDEFINED ## SOMETIMES_PRODUCES ## Variable:L"AttemptOrder" ## SOMETIMES_CONSUMES ## Variable:L"AttemptOrder" @@ -123,6 +126,9 @@ ## SOMETIMES_CONSUMES ## UNDEFINED # HiiSetBrowserData mVendorStorageName ## SOMETIMES_CONSUMES ## HII gIScsiConfigGuid + +[Pcd] + gEfiNetworkPkgTokenSpaceGuid.PcdIScsiAIPNetworkBootPolicy ## CONSUMES [UserExtensions.TianoCore."ExtraFiles"] IScsiDxeExtra.uni diff --git a/NetworkPkg/IScsiDxe/IScsiImpl.h b/NetworkPkg/IScsiDxe/IScsiImpl.h index 7c8eb37842..9941b8c3ea 100644 --- a/NetworkPkg/IScsiDxe/IScsiImpl.h +++ b/NetworkPkg/IScsiDxe/IScsiImpl.h @@ -1,7 +1,7 @@ /** @file The shared head file for iSCSI driver. -Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -32,6 +32,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include #include #include diff --git a/NetworkPkg/NetworkPkg.dec b/NetworkPkg/NetworkPkg.dec index de5dabea36..288d1aad2b 100644 --- a/NetworkPkg/NetworkPkg.dec +++ b/NetworkPkg/NetworkPkg.dec @@ -78,5 +78,17 @@ # @Prompt Type Value of Dhcp6 Unique Identifier (DUID). gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType|4|UINT8|0x10000001 + ## Network boot policy to stop UEFI iSCSI if applicable. + # 0x00 = Always use UEFI iSCSI and ignore AIP. + # 0x01 = Stop UEFI iSCSI if iSCSI HBA adapter produces AIP protocol with Network Boot. + # 0x02 = Stop UEFI iSCSI if iSCSI HBA adapter supports booting from iSCSI IPv4 targets. + # 0x04 = Stop UEFI iSCSI if iSCSI HBA adapter supports booting from iSCSI IPv6 targets. + # 0x08 = Stop UEFI iSCSI if iSCSI HBA adapter supports an offload engine for iSCSI boot. + # 0x10 = Stop UEFI iSCSI if iSCSI HBA adapter supports multipath I/O for iSCSI boot. + # 0x20 = Stop UEFI iSCSI if iSCSI HBA adapter is currently configured to boot from iSCSI IPv4 targets. + # 0x40 = Stop UEFI iSCSI if iSCSI HBA adapter is currently configured to boot from iSCSI IPv6 targets. + # @Prompt Type Value of network boot policy used in iSCSI. + gEfiNetworkPkgTokenSpaceGuid.PcdIScsiAIPNetworkBootPolicy|0x08|UINT8|0x10000007 + [UserExtensions.TianoCore."ExtraFiles"] NetworkPkgExtra.uni diff --git a/NetworkPkg/NetworkPkg.uni b/NetworkPkg/NetworkPkg.uni index a1b0185257eb026da2038b9102ddb1abd561d3cb..7e6dec7f3237b5309b63564b0ee49983e089898c 100644 GIT binary patch literal 11458 zcmd^_YfoE85Qg`2rT&K_@}W?LTS8Dqmvy4!O< z-+-jFeCYd-rb%IX*+3FKyF!i=>P!2QO8wQjI`#}Hc_|X^>bzB>=DC+8 zwyU?qCzV|A7avQm%u!`+-@Dq3S`U&~UyV*bCZ+MLN-F^$A#ncz*fyrNdwqaeF6 zBqUiYg@t(3LK8oD>lMQcW7ThZ#20wCiGCLQbZ|~dnGsasTyO6Sv~t8hA|9`b?hQ7Z zxI8@Cb+0+DxnH@@foTG&Iu|L;!L)s@vL5Mux5GJ0xiGO7q84&6J4=m%Z+Vw1F&vxwdW<;zQ>(pSDE@OQdf1BUBob?>|F#MX0Qk%w36GlRVa+`>8Wes|HAt4#lAT^5-Y8GavW zXANAoIKHN}kDP^=uvK{xiH854dHYdYZMb5dTb!5&9Z5RFyW{HNXS>78S9o03Kpo zzN^VWWTpd^n>cd_8k*5}@B(pO&NDY3g3T#sF`0`%Tjl?(g$3C6)MJqM*=7Xd$Zh2pR!tC1M+Pg(GKI=UF1r2V&2C>wl zaElKWu`4D~bYJ7wWY&5b8y!C4(KP&?sM+G^>nyh9xooId)Dv+@$A1>%wY@bf`t7&x z#Ladiny{)-WHvWO=zWO?805|P+C?1a3qZ&`PqI6*6$Uh5t|G$Q*)kIsf8Gw$4uBfbwFJmqLN{EXWlS7wRPLk7fR z^HHPjbPMUIRM%VZ`ht9$@=3$yT&;eU%}};SxhKUA@(3Z@^qA4Xa0%0+6F#G{Kp8dV zZfsPR)lpm@^FuL;|8l(KKWZL7qmGpgYVz#FM`JNh7xHy~@WgN*T-lC) zi82m*tSFT?vJB^Nz5X}zZii&VZqhN^#16Mvs|z({g)?v?WZf0BYem*3YPWo_?(c$X z#OvYhI)hKCAnz(%P}ZTyYDBA!yTmHt-Ne1cj*dY>wq<$V*pGG?PU!2;&hs3-2Ct^| zp8TIh^80wk4AJ{z%{+8m6>Mai!X)q6sH-CN8P5qL6mN1dug0xXE)>Y@UxzFt14)<&U~)OvNt!s zjt-^8JV(n%UETY9*uP6(?)0ggU+gu#9+sa|q^g~j0#ZN5taulkMw>5tkylR7uC2E{?G#BFe$(i}CUpr_{{LFueG0M;B3xi8P>uF}Q%*l1g zgf9ln7s~I+qZ#|B37Zfz6mG?oGKSDIKYU@MFK8-YCZr9u@I;K%7Y_Q8 z;1ULEm9DuWz1yeA#dtkUScm!c{;=*{JqhdJ55o5>2i=G_tvmVf3;(TB3*G6<3ZZ{K zLGkX*Rv+TMaY0*aoasgTJ4PoT`;chMC)@h?0Pk_?Jx>C2^___LE)N~{1=DN~HZeWE zWVt)1JtW=@eE2b(trHz+9W6hd7xp*oR0mTwte@foQ~x# eYz1bKT;Q-69 Ij!(ZwUzspn4DUS9BUK9{XcsP(+wN)K^0~W!t{BU{3<@P@JY^*aroTva z54lXM44?IsYDlCQOO=C`5R<+OXPx&@7A)aoo>0xD=$IY%xT`ITx#E+lhJ)k~&Q4B# zgf{*}}i zx?Ncyv8+_WI#Nx#4=c*VD9>x)Tw1U9$BA0|P3?LwWKtke0R^$#n z{8t~B{|+~<=NtpUCFp{DGB&ljd+QHe;;ahm=m-nUe7`diVTzFN&bRCv>x$f2J$$n4 z2-d#dWmHTmQ`}6n;}BXqE%??Z6o-U%;QA)WCCvYT@)&1A#@uVpvVT8`HLWy>}arWP$G>Y!P?Mk=J`SYt0PvC~lu}vuKhq=_)?io{WiFeKM zhJZg^V2@r;EG+?1u=Ug|P5;A=_f@{(z%&|j)lhx-hJst+Z7+bOHapEl?em*t*(nC5 zd`nd*KEo@{vnl}bG=qs5+(6>uCKR>;w=l9F=i;Kg~J`&hE zIfY-qhyXom#vLi}y+GWzGdf3ktTe^97Q8L9s)UH=4E`{-?ZF`WydRwRh!YzZ4UUly zRosxcwy`|i56Ia<7ppA!L^PA&2PRTH@Jp!(zVN9+@sfd8