]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Driver.c
BaseTools:Change the path of the file that Binary Cache
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Udp4Dxe / Udp4Driver.c
index c063d41b4236641413f17dfec3a8184256751098..63b103b8efcc57c5ac8b8333fac6a42a3c56718f 100644 (file)
@@ -1,13 +1,7 @@
 /** @file\r
 \r
-Copyright (c) 2006, Intel Corporation.<BR>\r
-All rights reserved. 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
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -28,6 +22,44 @@ 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
+EFIAPI\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
@@ -127,7 +159,7 @@ Udp4DriverBindingStart (
 \r
   Status = Udp4CreateService (Udp4Service, This->DriverBindingHandle, ControllerHandle);\r
   if (EFI_ERROR (Status)) {\r
-    gBS->FreePool (Udp4Service);\r
+    FreePool (Udp4Service);\r
     return Status;\r
   }\r
 \r
@@ -142,9 +174,7 @@ Udp4DriverBindingStart (
                   );\r
   if (EFI_ERROR (Status)) {\r
     Udp4CleanService (Udp4Service);\r
-    gBS->FreePool (Udp4Service);\r
-  } else {\r
-    Udp4SetVariableData (Udp4Service);\r
+    FreePool (Udp4Service);\r
   }\r
 \r
   return Status;\r
@@ -158,7 +188,7 @@ Udp4DriverBindingStart (
   restrictions for this service. DisconnectController()\r
   must follow these calling restrictions. If any other agent wishes\r
   to call Stop() it must also follow these calling restrictions.\r
-  \r
+\r
   @param[in]  This              Protocol instance pointer.\r
   @param[in]  ControllerHandle  Handle of device to stop driver on\r
   @param[in]  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of\r
@@ -178,18 +208,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 +239,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
@@ -218,18 +261,13 @@ Udp4DriverBindingStop (
            NULL\r
            );\r
 \r
-    Udp4ClearVariableData (Udp4Service);\r
-\r
     Udp4CleanService (Udp4Service);\r
 \r
-    gBS->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
@@ -238,19 +276,19 @@ Udp4DriverBindingStop (
 \r
 /**\r
   Creates a child handle and installs a protocol.\r
-  \r
-  The CreateChild() function installs a protocol on ChildHandle. \r
-  If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle. \r
+\r
+  The CreateChild() function installs a protocol on ChildHandle.\r
+  If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.\r
   If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.\r
 \r
-  @param  This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
-  @param  ChildHandle Pointer to the handle of the child to create. If it is NULL,\r
-                      then a new handle is created. If it is a pointer to an existing UEFI handle, \r
-                      then the protocol is added to the existing UEFI handle.\r
+  @param[in] This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
+  @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,\r
+                         then a new handle is created. If it is a pointer to an existing UEFI handle,\r
+                         then the protocol is added to the existing UEFI handle.\r
 \r
   @retval EFI_SUCCES            The protocol was added to ChildHandle.\r
   @retval EFI_INVALID_PARAMETER ChildHandle is NULL.\r
-  @retval EFI_OUT_OF_RESOURCES  There are not enough resources availabe to create\r
+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to create\r
                                 the child\r
   @retval other                 The child handle was not created\r
 \r
@@ -323,6 +361,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
@@ -352,7 +405,7 @@ ON_ERROR:
 \r
   Udp4CleanInstance (Instance);\r
 \r
-  gBS->FreePool (Instance);\r
+  FreePool (Instance);\r
 \r
   return Status;\r
 }\r
@@ -360,17 +413,17 @@ ON_ERROR:
 \r
 /**\r
   Destroys a child handle with a protocol installed on it.\r
-  \r
-  The DestroyChild() function does the opposite of CreateChild(). It removes a protocol \r
-  that was installed by CreateChild() from ChildHandle. If the removed protocol is the \r
+\r
+  The DestroyChild() function does the opposite of CreateChild(). It removes a protocol\r
+  that was installed by CreateChild() from ChildHandle. If the removed protocol is the\r
   last protocol on ChildHandle, then ChildHandle is destroyed.\r
 \r
-  @param  This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
-  @param  ChildHandle Handle of the child to destroy\r
+  @param[in] This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
+  @param[in] ChildHandle Handle of the child to destroy\r
 \r
   @retval EFI_SUCCES            The protocol was removed from ChildHandle.\r
   @retval EFI_UNSUPPORTED       ChildHandle does not support the protocol that is being removed.\r
-  @retval EFI_INVALID_PARAMETER Child handle is not a valid UEFI Handle.\r
+  @retval EFI_INVALID_PARAMETER Child handle is NULL.\r
   @retval EFI_ACCESS_DENIED     The protocol could not be removed from the ChildHandle\r
                                 because its services are being used.\r
   @retval other                 The child handle was not destroyed\r
@@ -412,14 +465,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 +483,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 +503,7 @@ Udp4ServiceBindingDestroyChild (
                   NULL\r
                   );\r
   if (EFI_ERROR (Status)) {\r
-    Instance->Destroyed = FALSE;\r
+    Instance->InDestroy = FALSE;\r
     return Status;\r
   }\r
 \r
@@ -470,7 +532,7 @@ Udp4ServiceBindingDestroyChild (
 \r
   gBS->RestoreTPL (OldTpl);\r
 \r
-  gBS->FreePool (Instance);\r
+  FreePool (Instance);\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -479,7 +541,7 @@ Udp4ServiceBindingDestroyChild (
   This is the declaration of an EFI image entry point. This entry point is\r
   the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including\r
   both device drivers and bus drivers.\r
-  \r
+\r
   The entry point for Udp4 driver which installs the driver binding\r
   and component name protocol on its ImageHandle.\r
 \r