X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=NetworkPkg%2FIScsiDxe%2FIScsiMisc.c;h=94f3725866611763c70d557348e377a482a44e0d;hb=bee0f2f167e6e982e665c851d605cd50e7748e08;hp=efd05cfbd404135f8ec70259bb137e69ec1c0b28;hpb=8b134dfdad4ea17b8c85111248df496894f81978;p=mirror_edk2.git diff --git a/NetworkPkg/IScsiDxe/IScsiMisc.c b/NetworkPkg/IScsiDxe/IScsiMisc.c index efd05cfbd4..94f3725866 100644 --- a/NetworkPkg/IScsiDxe/IScsiMisc.c +++ b/NetworkPkg/IScsiDxe/IScsiMisc.c @@ -1,7 +1,7 @@ /** @file Miscellaneous routines for iSCSI driver. -Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2018, 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 @@ -465,10 +465,115 @@ IScsiGenRandom ( } +/** + Check whether UNDI protocol supports IPv6. + + @param[in] ControllerHandle Controller handle. + @param[in] Image Handle of the image. + @param[out] Ipv6Support TRUE if UNDI supports IPv6. + + @retval EFI_SUCCESS Get the result whether UNDI supports IPv6 by NII or AIP protocol successfully. + @retval EFI_NOT_FOUND Don't know whether UNDI supports IPv6 since NII or AIP is not available. + +**/ +EFI_STATUS +IScsiCheckIpv6Support ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE Image, + OUT BOOLEAN *Ipv6Support + ) +{ + EFI_HANDLE Handle; + EFI_ADAPTER_INFORMATION_PROTOCOL *Aip; + EFI_STATUS Status; + EFI_GUID *InfoTypesBuffer; + UINTN InfoTypeBufferCount; + UINTN TypeIndex; + BOOLEAN Supported; + VOID *InfoBlock; + UINTN InfoBlockSize; + + EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *Nii; + + ASSERT (Ipv6Support != NULL); + + // + // Check whether the UNDI supports IPv6 by NII protocol. + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiNetworkInterfaceIdentifierProtocolGuid_31, + (VOID **) &Nii, + Image, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (Status == EFI_SUCCESS) { + *Ipv6Support = Nii->Ipv6Supported; + return EFI_SUCCESS; + } + + // + // Get the NIC handle by SNP protocol. + // + Handle = NetLibGetSnpHandle (ControllerHandle, NULL); + if (Handle == NULL) { + return EFI_NOT_FOUND; + } + + Aip = NULL; + Status = gBS->HandleProtocol ( + Handle, + &gEfiAdapterInformationProtocolGuid, + (VOID *) &Aip + ); + if (EFI_ERROR (Status) || Aip == NULL) { + return EFI_NOT_FOUND; + } + + InfoTypesBuffer = NULL; + InfoTypeBufferCount = 0; + Status = Aip->GetSupportedTypes (Aip, &InfoTypesBuffer, &InfoTypeBufferCount); + if (EFI_ERROR (Status) || InfoTypesBuffer == NULL) { + FreePool (InfoTypesBuffer); + return EFI_NOT_FOUND; + } + + Supported = FALSE; + for (TypeIndex = 0; TypeIndex < InfoTypeBufferCount; TypeIndex++) { + if (CompareGuid (&InfoTypesBuffer[TypeIndex], &gEfiAdapterInfoUndiIpv6SupportGuid)) { + Supported = TRUE; + break; + } + } + + FreePool (InfoTypesBuffer); + if (!Supported) { + return EFI_NOT_FOUND; + } + + // + // We now have adapter information block. + // + InfoBlock = NULL; + InfoBlockSize = 0; + Status = Aip->GetInformation (Aip, &gEfiAdapterInfoUndiIpv6SupportGuid, &InfoBlock, &InfoBlockSize); + if (EFI_ERROR (Status) || InfoBlock == NULL) { + FreePool (InfoBlock); + return EFI_NOT_FOUND; + } + + *Ipv6Support = ((EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT *) InfoBlock)->Ipv6Support; + FreePool (InfoBlock); + + return EFI_SUCCESS; +} + /** Record the NIC info in global structure. @param[in] Controller The handle of the controller. + @param[in] Image Handle of the image. @retval EFI_SUCCESS The operation is completed. @retval EFI_OUT_OF_RESOURCES Do not have sufficient resources to finish this @@ -477,7 +582,8 @@ IScsiGenRandom ( **/ EFI_STATUS IScsiAddNic ( - IN EFI_HANDLE Controller + IN EFI_HANDLE Controller, + IN EFI_HANDLE Image ) { EFI_STATUS Status; @@ -509,6 +615,19 @@ IScsiAddNic ( CompareMem (&NicInfo->PermanentAddress, MacAddr.Addr, HwAddressSize) == 0 && NicInfo->VlanId == VlanId) { mPrivate->CurrentNic = NicInfo->NicIndex; + + // + // Set IPv6 available flag. + // + Status = IScsiCheckIpv6Support (Controller, Image, &NicInfo->Ipv6Available); + if (EFI_ERROR (Status)) { + // + // Fail to get the data whether UNDI supports IPv6. + // Set default value to TRUE. + // + NicInfo->Ipv6Available = TRUE; + } + return EFI_SUCCESS; } @@ -530,7 +649,19 @@ IScsiAddNic ( NicInfo->VlanId = VlanId; NicInfo->NicIndex = (UINT8) (mPrivate->MaxNic + 1); mPrivate->MaxNic = NicInfo->NicIndex; - + + // + // Set IPv6 available flag. + // + Status = IScsiCheckIpv6Support (Controller, Image, &NicInfo->Ipv6Available); + if (EFI_ERROR (Status)) { + // + // Fail to get the data whether UNDI supports IPv6. + // Set default value to TRUE. + // + NicInfo->Ipv6Available = TRUE; + } + // // Get the PCI location. // @@ -1667,8 +1798,9 @@ IScsiCleanDriverData ( } EXIT: - - gBS->CloseEvent (Private->ExitBootServiceEvent); + if (Private->ExitBootServiceEvent != NULL) { + gBS->CloseEvent (Private->ExitBootServiceEvent); + } mCallbackInfo->Current = NULL; @@ -1994,9 +2126,12 @@ IScsiGetConfigData ( continue; } - } else if (AttemptTmp->SessionConfigData.InitiatorInfoFromDhcp && !AttemptTmp->ValidPath) { + } else if (AttemptTmp->SessionConfigData.InitiatorInfoFromDhcp && + !AttemptTmp->ValidPath && + AttemptTmp->NicIndex == mPrivate->CurrentNic) { // - // Get DHCP information for already added, but failed, attempt. + // If the attempt associates with the current NIC, we can + // get DHCP information for already added, but failed, attempt. // AttemptTmp->DhcpSuccess = FALSE; if (!mPrivate->Ipv6Flag && (AttemptTmp->SessionConfigData.IpMode == IP_MODE_IP4)) { @@ -2351,8 +2486,10 @@ IScsiOnExitBootService ( ISCSI_DRIVER_DATA *Private; Private = (ISCSI_DRIVER_DATA *) Context; + gBS->CloseEvent (Private->ExitBootServiceEvent); - + Private->ExitBootServiceEvent = NULL; + if (Private->Session != NULL) { IScsiSessionAbort (Private->Session); }