]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/Udp6Dxe/Udp6Driver.c
Fix a bug about the iSCSI DHCP dependency issue.
[mirror_edk2.git] / NetworkPkg / Udp6Dxe / Udp6Driver.c
index 1cfd5f1b4d5889cb0d0bf91b1dfaa3c2be591c5f..1c2c33336ea2f1ad9c20bbf0b0ea2d78e3b2df60 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Driver Binding functions and Service Binding functions for the Network driver module.\r
 \r
-  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
@@ -178,6 +178,44 @@ EXIT:
   return Status;\r
 }\r
 \r
+/**\r
+  Callback function which provided by user to remove one node in NetDestroyLinkList process.\r
+  \r
+  @param[in]    Entry           The entry to be removed.\r
+  @param[in]    Context         Pointer to the callback context corresponds to the Context in NetDestroyLinkList.\r
+\r
+  @retval EFI_SUCCESS           The entry has been removed successfully.\r
+  @retval Others                Fail to remove the entry.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Udp6DestroyChildEntryInHandleBuffer (\r
+  IN LIST_ENTRY         *Entry,\r
+  IN VOID               *Context\r
+  )\r
+{\r
+  UDP6_INSTANCE_DATA            *Instance;\r
+  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;\r
+  UINTN                         NumberOfChildren;\r
+  EFI_HANDLE                    *ChildHandleBuffer;\r
+\r
+  if (Entry == NULL || Context == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Instance = NET_LIST_USER_STRUCT_S (Entry, UDP6_INSTANCE_DATA, Link, UDP6_INSTANCE_DATA_SIGNATURE);\r
+  ServiceBinding    = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;\r
+  NumberOfChildren  = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;\r
+  ChildHandleBuffer = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;\r
+\r
+  if (!NetIsInHandleBuffer (Instance->ChildHandle, NumberOfChildren, ChildHandleBuffer)) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  return ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);\r
+}\r
+\r
 /**\r
   Stop this driver on ControllerHandle.\r
 \r
@@ -211,14 +249,15 @@ Udp6DriverBindingStop (
   EFI_HANDLE                    NicHandle;\r
   EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;\r
   UDP6_SERVICE_DATA             *Udp6Service;\r
-  UDP6_INSTANCE_DATA            *Instance;\r
+  LIST_ENTRY                    *List;\r
+  UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;\r
 \r
   //\r
   // Find the NicHandle where UDP6 ServiceBinding Protocol is installed.\r
   //\r
   NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp6ProtocolGuid);\r
   if (NicHandle == NULL) {\r
-    return EFI_DEVICE_ERROR;\r
+    return EFI_SUCCESS;\r
   }\r
 \r
   //\r
@@ -238,8 +277,21 @@ Udp6DriverBindingStop (
 \r
   Udp6Service = UDP6_SERVICE_DATA_FROM_THIS (ServiceBinding);\r
 \r
-  if (NumberOfChildren == 0) {\r
-\r
+  if (NumberOfChildren != 0) {\r
+    //\r
+    // NumberOfChildren is not zero, destroy the children instances in ChildHandleBuffer.\r
+    //\r
+    List = &Udp6Service->ChildrenList;\r
+    Context.ServiceBinding    = ServiceBinding;\r
+    Context.NumberOfChildren  = NumberOfChildren;\r
+    Context.ChildHandleBuffer = ChildHandleBuffer;\r
+    Status = NetDestroyLinkList (\r
+               List,\r
+               Udp6DestroyChildEntryInHandleBuffer,\r
+               &Context,\r
+               NULL\r
+               );\r
+  } else if (IsListEmpty (&Udp6Service->ChildrenList)) {\r
     gBS->UninstallMultipleProtocolInterfaces (\r
            NicHandle,\r
            &gEfiUdp6ServiceBindingProtocolGuid,\r
@@ -252,13 +304,8 @@ Udp6DriverBindingStop (
     Udp6CleanService (Udp6Service);\r
 \r
     FreePool (Udp6Service);\r
-  } else {\r
 \r
-    while (!IsListEmpty (&Udp6Service->ChildrenList)) {\r
-      Instance = NET_LIST_HEAD (&Udp6Service->ChildrenList, UDP6_INSTANCE_DATA, Link);\r
-\r
-      Status = ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);\r
-    }\r
+    Status = EFI_SUCCESS;\r
   }\r
 \r
   return Status;\r
@@ -351,6 +398,21 @@ Udp6ServiceBindingCreateChild (
     goto ON_ERROR;\r
   }\r
 \r
+  //\r
+  // Open this instance's Ip6 protocol in the IpInfo BY_CHILD.\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Instance->IpInfo->ChildHandle,\r
+                  &gEfiIp6ProtocolGuid,\r
+                  (VOID **) &Ip6,\r
+                  gUdp6DriverBinding.DriverBindingHandle,\r
+                  Instance->ChildHandle,\r
+                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto ON_ERROR;\r
+  }\r
+  \r
   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
   //\r
@@ -398,7 +460,7 @@ ON_ERROR:
                                  handle.\r
   @retval EFI_UNSUPPORTED        The child handle does not support the I/O services\r
                                  that are being removed.\r
-  @retval EFI_INVALID_PARAMETER  Child handle is not a valid EFI Handle.\r
+  @retval EFI_INVALID_PARAMETER  Child handle is NULL.\r
   @retval EFI_ACCESS_DENIED      The child handle could not be destroyed because\r
                                  its  I/O services are being used.\r
   @retval other                  The child handle was not destroyed.\r
@@ -440,17 +502,17 @@ Udp6ServiceBindingDestroyChild (
 \r
   Instance = UDP6_INSTANCE_DATA_FROM_THIS (Udp6Proto);\r
 \r
-  if (Instance->Destroyed) {\r
+  if (Instance->InDestroy) {\r
     return EFI_SUCCESS;\r
   }\r
 \r
   //\r
   // Use the Destroyed flag to avoid the re-entering of the following code.\r
   //\r
-  Instance->Destroyed = TRUE;\r
+  Instance->InDestroy = TRUE;\r
 \r
   //\r
-  // Close the Ip6 protocol.\r
+  // Close the Ip6 protocol on the default IpIo.\r
   //\r
   gBS->CloseProtocol (\r
          Udp6Service->IpIo->ChildHandle,\r
@@ -458,6 +520,15 @@ Udp6ServiceBindingDestroyChild (
          gUdp6DriverBinding.DriverBindingHandle,\r
          Instance->ChildHandle\r
          );\r
+  //\r
+  // Close the Ip6 protocol on this instance's IpInfo.\r
+  //\r
+  gBS->CloseProtocol (\r
+         Instance->IpInfo->ChildHandle,\r
+         &gEfiIp6ProtocolGuid,\r
+         gUdp6DriverBinding.DriverBindingHandle,\r
+         Instance->ChildHandle\r
+         );\r
 \r
   //\r
   // Uninstall the Udp6Protocol previously installed on the ChildHandle.\r
@@ -469,7 +540,7 @@ Udp6ServiceBindingDestroyChild (
                   NULL\r
                   );\r
   if (EFI_ERROR (Status)) {\r
-    Instance->Destroyed = FALSE;\r
+    Instance->InDestroy = FALSE;\r
     return Status;\r
   }\r
 \r