]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/Udp6Dxe/Udp6Driver.c
1. Add EFI_COMPONENT_NAME2_PROTOCOL.GetControllerName() support.
[mirror_edk2.git] / NetworkPkg / Udp6Dxe / Udp6Driver.c
index 1726ebbde466649267ecfec2a56b297973068e3d..62c2b9affd0fb5c3f3b00dca2b61a99b1c7011ad 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 - 2011, 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,43 @@ 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
+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 +248,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 +276,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 +303,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 +397,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
@@ -440,17 +501,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 +519,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 +539,7 @@ Udp6ServiceBindingDestroyChild (
                   NULL\r
                   );\r
   if (EFI_ERROR (Status)) {\r
-    Instance->Destroyed = FALSE;\r
+    Instance->InDestroy = FALSE;\r
     return Status;\r
   }\r
 \r