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