]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/TcpDxe/TcpDriver.c
1. Add EFI_COMPONENT_NAME2_PROTOCOL.GetControllerName() support.
[mirror_edk2.git] / NetworkPkg / TcpDxe / TcpDriver.c
index 3e01f34892ffe006d5d4ec90367e4e7084ac0048..4e697b1f4e4fbeff434d3113a163e75f0989e11e 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   The driver binding and service binding protocol for the TCP driver.\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
@@ -323,6 +323,7 @@ ON_ERROR:
 \r
   if (TcpServiceData->IpIo != NULL) {\r
     IpIoDestroy (TcpServiceData->IpIo);\r
+    TcpServiceData->IpIo = NULL;\r
   }\r
 \r
   FreePool (TcpServiceData);\r
@@ -330,14 +331,53 @@ ON_ERROR:
   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
+TcpDestroyChildEntryInHandleBuffer (\r
+  IN LIST_ENTRY         *Entry,\r
+  IN VOID               *Context\r
+)\r
+{\r
+  SOCKET                        *Sock;\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
+  Sock = NET_LIST_USER_STRUCT_S (Entry, SOCKET, Link, SOCK_SIGNATURE);\r
+  ServiceBinding    = ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;\r
+  NumberOfChildren  = ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;\r
+  ChildHandleBuffer = ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;\r
+\r
+  if (!NetIsInHandleBuffer (Sock->SockHandle, NumberOfChildren, ChildHandleBuffer)) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  return ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle);\r
+}\r
+\r
 /**\r
   Destroy a TCP6 or TCP4 service binding instance. It will release all\r
   the resources allocated by the instance.\r
 \r
   @param[in]  Controller         Controller handle of device to bind driver to.\r
   @param[in]  ImageHandle        The TCP driver's image handle.\r
-  @param[in]  NumberOfChildren    Number of Handles in ChildHandleBuffer. If number\r
+  @param[in]  NumberOfChildren   Number of Handles in ChildHandleBuffer. If number\r
                                  of children is zero stop the entire bus driver.\r
+  @param[in]  ChildHandleBuffer  An array of child handles to be freed. May be NULL\r
+                                 if NumberOfChildren is 0.  \r
   @param[in]  IpVersion          IP_VERSION_4 or IP_VERSION_6\r
 \r
   @retval EFI_SUCCESS            The resources used by the instance were cleaned up.\r
@@ -349,6 +389,7 @@ TcpDestroyService (
   IN EFI_HANDLE  Controller,\r
   IN EFI_HANDLE  ImageHandle,\r
   IN UINTN       NumberOfChildren,\r
+  IN EFI_HANDLE  *ChildHandleBuffer, OPTIONAL\r
   IN UINT8       IpVersion\r
   )\r
 {\r
@@ -358,7 +399,8 @@ TcpDestroyService (
   EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;\r
   TCP_SERVICE_DATA              *TcpServiceData;\r
   EFI_STATUS                    Status;\r
-  SOCKET                        *Sock;\r
+  LIST_ENTRY                    *List;\r
+  TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT  Context;\r
 \r
   ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6));\r
 \r
@@ -372,7 +414,7 @@ TcpDestroyService (
 \r
   NicHandle = NetLibGetNicHandle (Controller, IpProtocolGuid);\r
   if (NicHandle == NULL) {\r
-    return EFI_NOT_FOUND;\r
+    return EFI_SUCCESS;\r
   }\r
 \r
   Status = gBS->OpenProtocol (\r
@@ -389,7 +431,18 @@ TcpDestroyService (
 \r
   TcpServiceData = TCP_SERVICE_FROM_THIS (ServiceBinding);\r
 \r
-  if (NumberOfChildren == 0) {\r
+  if (NumberOfChildren != 0) {\r
+    List = &TcpServiceData->SocketList;\r
+    Context.ServiceBinding = ServiceBinding;\r
+    Context.NumberOfChildren = NumberOfChildren;\r
+    Context.ChildHandleBuffer = ChildHandleBuffer;\r
+    Status = NetDestroyLinkList (\r
+               List,\r
+               TcpDestroyChildEntryInHandleBuffer,\r
+               &Context,\r
+               NULL\r
+               );\r
+  } else if (IsListEmpty (&TcpServiceData->SocketList)) {\r
     //\r
     // Uninstall TCP servicebinding protocol\r
     //\r
@@ -404,6 +457,7 @@ TcpDestroyService (
     // Destroy the IpIO consumed by TCP driver\r
     //\r
     IpIoDestroy (TcpServiceData->IpIo);\r
+    TcpServiceData->IpIo = NULL;\r
 \r
     //\r
     // Destroy the heartbeat timer.\r
@@ -419,16 +473,11 @@ TcpDestroyService (
     // Release the TCP service data\r
     //\r
     FreePool (TcpServiceData);\r
-  } else {\r
-\r
-    while (!IsListEmpty (&TcpServiceData->SocketList)) {\r
-      Sock = NET_LIST_HEAD (&TcpServiceData->SocketList, SOCKET, Link);\r
 \r
-      ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle);\r
-    }\r
+    Status = EFI_SUCCESS;\r
   }\r
 \r
-  return EFI_SUCCESS;\r
+  return Status;\r
 }\r
 \r
 /**\r
@@ -595,6 +644,7 @@ TcpDriverBindingStop (
                  ControllerHandle,\r
                  This->DriverBindingHandle,\r
                  NumberOfChildren,\r
+                 ChildHandleBuffer,\r
                  IP_VERSION_4\r
                  );\r
 \r
@@ -602,6 +652,7 @@ TcpDriverBindingStop (
                  ControllerHandle,\r
                  This->DriverBindingHandle,\r
                  NumberOfChildren,\r
+                 ChildHandleBuffer,\r
                  IP_VERSION_6\r
                  );\r
 \r
@@ -823,7 +874,7 @@ TcpServiceBindingCreateChild (
 \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
@@ -839,14 +890,11 @@ TcpServiceBindingDestroyChild (
   EFI_STATUS  Status;\r
   VOID        *Tcp;\r
   SOCKET      *Sock;\r
-  EFI_TPL     OldTpl;\r
 \r
   if (NULL == This || NULL == ChildHandle) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
   //\r
   // retrieve the Tcp4 protocol from ChildHandle\r
   //\r
@@ -885,7 +933,5 @@ TcpServiceBindingDestroyChild (
     SockDestroyChild (Sock);\r
   }\r
 \r
-  gBS->RestoreTPL (OldTpl);\r
-\r
   return Status;\r
 }\r