return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Check whether an iSCSI HBA adapter already installs an AIP instance with\r
+ network boot policy matching the value specified in PcdIScsiAIPNetworkBootPolicy.\r
+ If yes, return EFI_SUCCESS.\r
+\r
+ @retval EFI_SUCCESS Found an AIP with matching network boot policy.\r
+ @retval EFI_NOT_FOUND AIP is unavailable or the network boot policy\r
+ not matched.\r
+**/\r
+EFI_STATUS\r
+IScsiCheckAip (\r
+ )\r
+{\r
+ UINTN AipHandleCount;\r
+ EFI_HANDLE *AipHandleBuffer;\r
+ UINTN AipIndex;\r
+ EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;\r
+ EFI_EXT_SCSI_PASS_THRU_PROTOCOL *ExtScsiPassThru;\r
+ EFI_GUID *InfoTypesBuffer;\r
+ UINTN InfoTypeBufferCount;\r
+ UINTN TypeIndex;\r
+ VOID *InfoBlock;\r
+ UINTN InfoBlockSize;\r
+ BOOLEAN Supported;\r
+ EFI_ADAPTER_INFO_NETWORK_BOOT *NetworkBoot;\r
+ EFI_STATUS Status;\r
+ UINT8 NetworkBootPolicy;\r
+\r
+ //\r
+ // Check any AIP instances exist in system.\r
+ //\r
+ AipHandleCount = 0;\r
+ AipHandleBuffer = NULL;\r
+ Status = gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ &gEfiAdapterInformationProtocolGuid,\r
+ NULL,\r
+ &AipHandleCount,\r
+ &AipHandleBuffer\r
+ );\r
+ if (EFI_ERROR (Status) || AipHandleCount == 0) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ ASSERT (AipHandleBuffer != NULL);\r
+\r
+ InfoBlock = NULL;\r
+\r
+ for (AipIndex = 0; AipIndex < AipHandleCount; AipIndex++) {\r
+ Status = gBS->HandleProtocol (\r
+ AipHandleBuffer[AipIndex],\r
+ &gEfiAdapterInformationProtocolGuid,\r
+ (VOID *) &Aip\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ ASSERT (Aip != NULL);\r
+\r
+ Status = gBS->HandleProtocol (\r
+ AipHandleBuffer[AipIndex],\r
+ &gEfiExtScsiPassThruProtocolGuid,\r
+ (VOID *) &ExtScsiPassThru\r
+ );\r
+ if (EFI_ERROR (Status) || ExtScsiPassThru == NULL) {\r
+ continue;\r
+ }\r
+\r
+ InfoTypesBuffer = NULL;\r
+ InfoTypeBufferCount = 0;\r
+ Status = Aip->GetSupportedTypes (Aip, &InfoTypesBuffer, &InfoTypeBufferCount);\r
+ if (EFI_ERROR (Status) || InfoTypesBuffer == NULL) {\r
+ continue;\r
+ }\r
+ //\r
+ // Check whether the AIP instance has Network boot information block.\r
+ //\r
+ Supported = FALSE;\r
+ for (TypeIndex = 0; TypeIndex < InfoTypeBufferCount; TypeIndex++) {\r
+ if (CompareGuid (&InfoTypesBuffer[TypeIndex], &gEfiAdapterInfoNetworkBootGuid)) {\r
+ Supported = TRUE;\r
+ break;\r
+ }\r
+ }\r
+\r
+ FreePool (InfoTypesBuffer);\r
+ if (!Supported) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // We now have network boot information block.\r
+ //\r
+ InfoBlock = NULL;\r
+ InfoBlockSize = 0;\r
+ Status = Aip->GetInformation (Aip, &gEfiAdapterInfoNetworkBootGuid, &InfoBlock, &InfoBlockSize);\r
+ if (EFI_ERROR (Status) || InfoBlock == NULL) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Check whether the network boot policy matches.\r
+ //\r
+ NetworkBoot = (EFI_ADAPTER_INFO_NETWORK_BOOT *) InfoBlock;\r
+ NetworkBootPolicy = PcdGet8 (PcdIScsiAIPNetworkBootPolicy);\r
+\r
+ if (NetworkBootPolicy == STOP_UEFI_ISCSI_IF_HBA_INSTALL_AIP) {\r
+ Status = EFI_SUCCESS;\r
+ goto Exit;\r
+ }\r
+ if (((NetworkBootPolicy & STOP_UEFI_ISCSI_IF_AIP_SUPPORT_IP4) != 0 &&\r
+ !NetworkBoot->iScsiIpv4BootCapablity) ||\r
+ ((NetworkBootPolicy & STOP_UEFI_ISCSI_IF_AIP_SUPPORT_IP6) != 0 &&\r
+ !NetworkBoot->iScsiIpv6BootCapablity) ||\r
+ ((NetworkBootPolicy & STOP_UEFI_ISCSI_IF_AIP_SUPPORT_OFFLOAD) != 0 &&\r
+ !NetworkBoot->OffloadCapability) ||\r
+ ((NetworkBootPolicy & STOP_UEFI_ISCSI_IF_AIP_SUPPORT_MPIO) != 0 &&\r
+ !NetworkBoot->iScsiMpioCapability) ||\r
+ ((NetworkBootPolicy & STOP_UEFI_ISCSI_IF_AIP_CONFIGURED_IP4) != 0 &&\r
+ !NetworkBoot->iScsiIpv4Boot) ||\r
+ ((NetworkBootPolicy & STOP_UEFI_ISCSI_IF_AIP_CONFIGURED_IP6) != 0 &&\r
+ !NetworkBoot->iScsiIpv6Boot)) {\r
+ FreePool (InfoBlock);\r
+ continue;\r
+ }\r
+\r
+ Status = EFI_SUCCESS;\r
+ goto Exit;\r
+ }\r
+\r
+ Status = EFI_NOT_FOUND;\r
+\r
+Exit:\r
+ if (InfoBlock != NULL) {\r
+ FreePool (InfoBlock);\r
+ }\r
+ if (AipHandleBuffer != NULL) {\r
+ FreePool (AipHandleBuffer);\r
+ }\r
+ return Status;\r
+}\r
\r
/**\r
Tests to see if this driver supports a given controller. This is the worker function for\r
BOOLEAN NeedUpdate;\r
VOID *Interface;\r
EFI_GUID *ProtocolGuid;\r
+ UINT8 NetworkBootPolicy;\r
\r
//\r
// Test to see if iSCSI driver supports the given controller.\r
return EFI_UNSUPPORTED;\r
}\r
\r
+ NetworkBootPolicy = PcdGet8 (PcdIScsiAIPNetworkBootPolicy);\r
+ if (NetworkBootPolicy != ALWAYS_USE_UEFI_ISCSI_AND_IGNORE_AIP) {\r
+ //\r
+ // Check existing iSCSI AIP.\r
+ //\r
+ Status = IScsiCheckAip ();\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Find iSCSI AIP with specified network boot policy. return EFI_ABORTED.\r
+ //\r
+ return EFI_ABORTED;\r
+ }\r
+ }\r
+ \r
//\r
// Record the incoming NIC info.\r
//\r