]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c
1. Add EFI_COMPONENT_NAME2_PROTOCOL.GetControllerName() support.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Ip4Dxe / Ip4Driver.c
index 4ce85a3f51823d86d2ac12d000b84d9c683b7d11..5a84837a444805a6b9e94ae68f269c6f838be67e 100644 (file)
@@ -176,7 +176,6 @@ Ip4CreateService (
   IpSb->ServiceBinding.CreateChild  = Ip4ServiceBindingCreateChild;\r
   IpSb->ServiceBinding.DestroyChild = Ip4ServiceBindingDestroyChild;\r
   IpSb->State                       = IP4_SERVICE_UNSTARTED;\r
-  IpSb->InDestroy                   = FALSE;\r
 \r
   IpSb->NumChildren                 = 0;\r
   InitializeListHead (&IpSb->Children);\r
@@ -396,6 +395,42 @@ Ip4CleanService (
   return EFI_SUCCESS;\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
+Ip4DestroyChildEntryInHandleBuffer (\r
+  IN LIST_ENTRY         *Entry,\r
+  IN VOID               *Context\r
+)\r
+{\r
+  IP4_PROTOCOL                  *IpInstance;\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
+  IpInstance = NET_LIST_USER_STRUCT_S (Entry, IP4_PROTOCOL, Link, IP4_PROTOCOL_SIGNATURE);\r
+  ServiceBinding    = ((IP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;\r
+  NumberOfChildren  = ((IP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;\r
+  ChildHandleBuffer = ((IP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;\r
+\r
+  if (!NetIsInHandleBuffer (IpInstance->Handle, NumberOfChildren, ChildHandleBuffer)) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  return ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle);\r
+}\r
 \r
 /**\r
   Start this driver on ControllerHandle. This service is called by the\r
@@ -529,14 +564,13 @@ Ip4DriverBindingStop (
   IN  EFI_HANDLE                   *ChildHandleBuffer\r
   )\r
 {\r
-  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;\r
-  IP4_SERVICE                   *IpSb;\r
-  IP4_PROTOCOL                  *IpInstance;\r
-  EFI_HANDLE                    NicHandle;\r
-  EFI_STATUS                    Status;\r
-  EFI_TPL                       OldTpl;\r
-  INTN                          State;\r
-  BOOLEAN                       IsArp;\r
+  EFI_SERVICE_BINDING_PROTOCOL             *ServiceBinding;\r
+  IP4_SERVICE                              *IpSb; \r
+  EFI_HANDLE                               NicHandle;\r
+  EFI_STATUS                               Status; \r
+  INTN                                     State;\r
+  LIST_ENTRY                               *List;\r
+  IP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT  Context;\r
 \r
   //\r
   // IP4 driver opens the MNP child, ARP children or the IP4_CONFIG protocol\r
@@ -557,7 +591,6 @@ Ip4DriverBindingStop (
                   ControllerHandle,\r
                   EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
                   );\r
-\r
   if (Status == EFI_SUCCESS) {\r
     //\r
     // Retrieve the IP4 service binding protocol. If failed, it is\r
@@ -572,15 +605,11 @@ Ip4DriverBindingStop (
                     ControllerHandle,\r
                     EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
                     );\r
-\r
     if (EFI_ERROR (Status)) {\r
       return EFI_DEVICE_ERROR;\r
     }\r
 \r
     IpSb = IP4_SERVICE_FROM_PROTOCOL (ServiceBinding);\r
-\r
-    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
     if (IpSb->Ip4Config != NULL && (IpSb->State != IP4_SERVICE_DESTROY)) {\r
 \r
       IpSb->Ip4Config->Stop (IpSb->Ip4Config);\r
@@ -591,9 +620,7 @@ Ip4DriverBindingStop (
                       IpSb->Image,\r
                       ControllerHandle\r
                       );\r
-\r
       if (EFI_ERROR (Status)) {\r
-        gBS->RestoreTPL (OldTpl);\r
         return Status;\r
       }\r
 \r
@@ -609,7 +636,6 @@ Ip4DriverBindingStop (
       gBS->CloseEvent (IpSb->ReconfigEvent);\r
     }\r
 \r
-    gBS->RestoreTPL (OldTpl);\r
     return EFI_SUCCESS;\r
   }\r
 \r
@@ -619,16 +645,12 @@ Ip4DriverBindingStop (
   // service binding is installed on the NIC handle. So, need to open\r
   // the protocol info to find the NIC handle.\r
   //\r
-  IsArp     = FALSE;\r
   NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);\r
-\r
   if (NicHandle == NULL) {\r
     NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiArpProtocolGuid);\r
-    IsArp     = TRUE;\r
-  }\r
-\r
-  if (NicHandle == NULL) {\r
-    return EFI_DEVICE_ERROR;\r
+    if (NicHandle == NULL) {\r
+      return EFI_SUCCESS;\r
+    }\r
   }\r
 \r
   //\r
@@ -642,34 +664,23 @@ Ip4DriverBindingStop (
                   NicHandle,\r
                   EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
                   );\r
-\r
   if (EFI_ERROR (Status)) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
   IpSb   = IP4_SERVICE_FROM_PROTOCOL (ServiceBinding);\r
-\r
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
-  if (IpSb->InDestroy) {\r
-    gBS->RestoreTPL (OldTpl);\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  if (IsArp) {\r
-    while (!IsListEmpty (&IpSb->Children)) {\r
-      IpInstance = NET_LIST_HEAD (&IpSb->Children, IP4_PROTOCOL, Link);\r
-\r
-      ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle);\r
-    }\r
-\r
-    if (IpSb->NumChildren != 0) {\r
-      Status = EFI_DEVICE_ERROR;\r
-      goto ON_ERROR;\r
-    }\r
-\r
-    IpSb->InDestroy = TRUE;\r
-\r
+  if (NumberOfChildren != 0) {\r
+    List = &IpSb->Children;\r
+    Context.ServiceBinding    = ServiceBinding;\r
+    Context.NumberOfChildren  = NumberOfChildren;\r
+    Context.ChildHandleBuffer = ChildHandleBuffer;\r
+    Status = NetDestroyLinkList (\r
+               List,\r
+               Ip4DestroyChildEntryInHandleBuffer,\r
+               &Context,\r
+               NULL\r
+               );\r
+  } else if (IsListEmpty (&IpSb->Children)) {\r
     State           = IpSb->State;\r
     IpSb->State     = IP4_SERVICE_DESTROY;\r
 \r
@@ -682,7 +693,6 @@ Ip4DriverBindingStop (
     // OK, clean other resources then uninstall the service binding protocol.\r
     //\r
     Status = Ip4CleanService (IpSb);\r
-\r
     if (EFI_ERROR (Status)) {\r
       IpSb->State = State;\r
       goto ON_ERROR;\r
@@ -693,52 +703,15 @@ Ip4DriverBindingStop (
            &gEfiIp4ServiceBindingProtocolGuid,\r
            ServiceBinding\r
            );\r
-\r
-    FreePool (IpSb);\r
-  } else if (NumberOfChildren == 0) {\r
-    IpSb->InDestroy = TRUE;\r
-\r
-    State           = IpSb->State;\r
-    IpSb->State     = IP4_SERVICE_DESTROY;\r
-\r
-    //\r
-    // Clear the variable data.\r
-    //\r
-    Ip4ClearVariableData (IpSb);\r
-\r
-    //\r
-    // OK, clean other resources then uninstall the service binding protocol.\r
-    //\r
-    Status = Ip4CleanService (IpSb);\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      IpSb->State = State;\r
-      goto ON_ERROR;\r
+    \r
+    if (gIp4ControllerNameTable != NULL) {\r
+      FreeUnicodeStringTable (gIp4ControllerNameTable);\r
+      gIp4ControllerNameTable = NULL;\r
     }\r
-\r
-    gBS->UninstallProtocolInterface (\r
-           NicHandle,\r
-           &gEfiIp4ServiceBindingProtocolGuid,\r
-           ServiceBinding\r
-           );\r
-\r
     FreePool (IpSb);\r
-  } else {\r
-\r
-    while (!IsListEmpty (&IpSb->Children)) {\r
-      IpInstance = NET_LIST_HEAD (&IpSb->Children, IP4_PROTOCOL, Link);\r
-\r
-      ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle);\r
-    }\r
-\r
-    if (IpSb->NumChildren != 0) {\r
-      Status = EFI_DEVICE_ERROR;\r
-    }\r
   }\r
 \r
 ON_ERROR:\r
-\r
-  gBS->RestoreTPL (OldTpl);\r
   return Status;\r
 }\r
 \r
@@ -935,6 +908,15 @@ Ip4ServiceBindingDestroyChild (
          ChildHandle\r
          );\r
 \r
+  if (IpInstance->Interface != NULL && IpInstance->Interface->Arp != NULL) {\r
+    gBS->CloseProtocol (\r
+           IpInstance->Interface->ArpHandle,\r
+           &gEfiArpProtocolGuid,\r
+           gIp4DriverBinding.DriverBindingHandle,\r
+           ChildHandle\r
+           );\r
+  }\r
+\r
   //\r
   // Uninstall the IP4 protocol first. Many thing happens during\r
   // this:\r
@@ -949,12 +931,13 @@ Ip4ServiceBindingDestroyChild (
   // will be called back before preceeding. If any packets not recycled,\r
   // that means there is a resource leak.\r
   //\r
+  gBS->RestoreTPL (OldTpl);\r
   Status = gBS->UninstallProtocolInterface (\r
                   ChildHandle,\r
                   &gEfiIp4ProtocolGuid,\r
                   &IpInstance->Ip4Proto\r
                   );\r
-\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
   if (EFI_ERROR (Status)) {\r
     goto ON_ERROR;\r
   }\r