]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Driver.c
1. Add EFI_COMPONENT_NAME2_PROTOCOL.GetControllerName() support.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Udp4Dxe / Udp4Driver.c
index 5afb3aa58e86007c21a041c0cb5ff24e477b3bc0..96b08d14e91f6c641947831025cefb368b1988b3 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 \r
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2012, 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
@@ -28,6 +28,43 @@ EFI_SERVICE_BINDING_PROTOCOL mUdp4ServiceBinding = {
   Udp4ServiceBindingDestroyChild\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
+Udp4DestroyChildEntryInHandleBuffer (\r
+  IN LIST_ENTRY         *Entry,\r
+  IN VOID               *Context\r
+)\r
+{\r
+  UDP4_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, UDP4_INSTANCE_DATA, Link, UDP4_INSTANCE_DATA_SIGNATURE);\r
+  ServiceBinding    = ((UDP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;\r
+  NumberOfChildren  = ((UDP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;\r
+  ChildHandleBuffer = ((UDP4_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
 /**\r
   Test to see if this driver supports ControllerHandle. This service\r
@@ -178,18 +215,19 @@ Udp4DriverBindingStop (
   IN  EFI_HANDLE                   *ChildHandleBuffer\r
   )\r
 {\r
-  EFI_STATUS                    Status;\r
-  EFI_HANDLE                    NicHandle;\r
-  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;\r
-  UDP4_SERVICE_DATA             *Udp4Service;\r
-  UDP4_INSTANCE_DATA            *Instance;\r
+  EFI_STATUS                                Status;\r
+  EFI_HANDLE                                NicHandle;\r
+  EFI_SERVICE_BINDING_PROTOCOL              *ServiceBinding;\r
+  UDP4_SERVICE_DATA                         *Udp4Service;\r
+  UDP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT  Context;\r
+  LIST_ENTRY                                *List;\r
 \r
   //\r
   // Find the NicHandle where UDP4 ServiceBinding Protocol is installed.\r
   //\r
   NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);\r
   if (NicHandle == NULL) {\r
-    return EFI_DEVICE_ERROR;\r
+    return EFI_SUCCESS;\r
   }\r
 \r
   //\r
@@ -208,9 +246,21 @@ Udp4DriverBindingStop (
   }\r
 \r
   Udp4Service = UDP4_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 = &Udp4Service->ChildrenList;\r
+    Context.ServiceBinding    = ServiceBinding;\r
+    Context.NumberOfChildren  = NumberOfChildren;\r
+    Context.ChildHandleBuffer = ChildHandleBuffer;\r
+    Status = NetDestroyLinkList (\r
+               List,\r
+               Udp4DestroyChildEntryInHandleBuffer,\r
+               &Context,\r
+               NULL\r
+               );\r
+  } else {\r
     gBS->UninstallMultipleProtocolInterfaces (\r
            NicHandle,\r
            &gEfiUdp4ServiceBindingProtocolGuid,\r
@@ -222,14 +272,11 @@ Udp4DriverBindingStop (
 \r
     Udp4CleanService (Udp4Service);\r
 \r
-    FreePool (Udp4Service);\r
-  } else {\r
-\r
-    while (!IsListEmpty (&Udp4Service->ChildrenList)) {\r
-      Instance = NET_LIST_HEAD (&Udp4Service->ChildrenList, UDP4_INSTANCE_DATA, Link);\r
-\r
-      ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);\r
+    if (gUdpControllerNameTable != NULL) {\r
+      FreeUnicodeStringTable (gUdpControllerNameTable);\r
+      gUdpControllerNameTable = NULL;\r
     }\r
+    FreePool (Udp4Service);\r
   }\r
 \r
   return Status;\r
@@ -323,6 +370,21 @@ Udp4ServiceBindingCreateChild (
     goto ON_ERROR;\r
   }\r
 \r
+  //\r
+  // Open this instance's Ip4 protocol in the IpInfo BY_CHILD.\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Instance->IpInfo->ChildHandle,\r
+                  &gEfiIp4ProtocolGuid,\r
+                  (VOID **) &Ip4,\r
+                  gUdp4DriverBinding.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
@@ -412,14 +474,14 @@ Udp4ServiceBindingDestroyChild (
 \r
   Instance = UDP4_INSTANCE_DATA_FROM_THIS (Udp4Proto);\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 Ip4 protocol.\r
@@ -430,6 +492,15 @@ Udp4ServiceBindingDestroyChild (
          gUdp4DriverBinding.DriverBindingHandle,\r
          Instance->ChildHandle\r
          );\r
+  //\r
+  // Close the Ip4 protocol on this instance's IpInfo.\r
+  //\r
+  gBS->CloseProtocol (\r
+         Instance->IpInfo->ChildHandle,\r
+         &gEfiIp4ProtocolGuid,\r
+         gUdp4DriverBinding.DriverBindingHandle,\r
+         Instance->ChildHandle\r
+         );  \r
 \r
   //\r
   // Uninstall the Udp4Protocol previously installed on the ChildHandle.\r
@@ -441,7 +512,7 @@ Udp4ServiceBindingDestroyChild (
                   NULL\r
                   );\r
   if (EFI_ERROR (Status)) {\r
-    Instance->Destroyed = FALSE;\r
+    Instance->InDestroy = FALSE;\r
     return Status;\r
   }\r
 \r