]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c
1. Add EFI_COMPONENT_NAME2_PROTOCOL.GetControllerName() support.
[mirror_edk2.git] / NetworkPkg / Dhcp6Dxe / Dhcp6Driver.c
index 346986bd159cebb0d22fb3b9ee0db997ed4c1c62..42caefb154c08ebd8eaa959b440c626ae00a0fe2 100644 (file)
@@ -31,7 +31,6 @@ EFI_SERVICE_BINDING_PROTOCOL gDhcp6ServiceBindingTemplate = {
   Dhcp6ServiceBindingDestroyChild\r
 };\r
 \r
-\r
 /**\r
   Configure the default Udp6Io to receive all the DHCP6 traffic\r
   on this network interface.\r
@@ -155,7 +154,6 @@ Dhcp6CreateService (
   // Initialize the fields of the new Dhcp6 service.\r
   //\r
   Dhcp6Srv->Signature       = DHCP6_SERVICE_SIGNATURE;\r
-  Dhcp6Srv->InDestroy       = FALSE;\r
   Dhcp6Srv->Controller      = Controller;\r
   Dhcp6Srv->Image           = ImageHandle;\r
   Dhcp6Srv->Xid             = (0xffffff & NET_RANDOM (NetRandomInitSeed ()));\r
@@ -328,6 +326,35 @@ Dhcp6CreateInstance (
   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
+Dhcp6DestroyChildEntry (\r
+  IN LIST_ENTRY         *Entry,\r
+  IN VOID               *Context\r
+)\r
+{\r
+  DHCP6_INSTANCE                   *Instance;\r
+  EFI_SERVICE_BINDING_PROTOCOL     *ServiceBinding;\r
+\r
+  if (Entry == NULL || Context == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Instance = NET_LIST_USER_STRUCT_S (Entry, DHCP6_INSTANCE, Link, DHCP6_INSTANCE_SIGNATURE);\r
+  ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *) Context;\r
+  \r
+  return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);\r
+}\r
+\r
 \r
 /**\r
   Entry point of the DHCP6 driver to install various protocols.\r
@@ -498,11 +525,11 @@ Dhcp6DriverBindingStop (
   )\r
 {\r
   EFI_STATUS                       Status;\r
-  EFI_TPL                          OldTpl;\r
   EFI_HANDLE                       NicHandle;\r
   EFI_SERVICE_BINDING_PROTOCOL     *ServiceBinding;\r
   DHCP6_SERVICE                    *Service;\r
-  DHCP6_INSTANCE                   *Instance;\r
+  LIST_ENTRY                       *List;\r
+  UINTN                            ListLength;\r
 \r
   //\r
   // Find and check the Nic handle by the controller handle.\r
@@ -510,7 +537,7 @@ Dhcp6DriverBindingStop (
   NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp6ProtocolGuid);\r
 \r
   if (NicHandle == NULL) {\r
-    return EFI_DEVICE_ERROR;\r
+    return EFI_SUCCESS;\r
   }\r
 \r
   Status = gBS->OpenProtocol (\r
@@ -527,50 +554,44 @@ Dhcp6DriverBindingStop (
   }\r
 \r
   Service = DHCP6_SERVICE_FROM_THIS (ServiceBinding);\r
-\r
-  if (Service->InDestroy) {\r
-    return EFI_SUCCESS;\r
+  if (!IsListEmpty (&Service->Child)) {\r
+    //\r
+    // Destroy all the children instances before destory the service.\r
+    //  \r
+    List = &Service->Child;\r
+    Status = NetDestroyLinkList (\r
+               List,\r
+               Dhcp6DestroyChildEntry,\r
+               ServiceBinding,\r
+               &ListLength\r
+               );\r
+    if (EFI_ERROR (Status) || ListLength != 0) {\r
+      Status = EFI_DEVICE_ERROR;\r
+    }\r
   }\r
 \r
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+  if (NumberOfChildren == 0 && !IsListEmpty (&Service->Child)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+  }\r
 \r
-  if (NumberOfChildren == 0) {\r
+  if (NumberOfChildren == 0 && IsListEmpty (&Service->Child)) {\r
     //\r
     // Destroy the service itself if no child instance left.\r
     //\r
-    Service->InDestroy = TRUE;\r
-\r
     Status = gBS->UninstallProtocolInterface (\r
                     NicHandle,\r
                     &gEfiDhcp6ServiceBindingProtocolGuid,\r
                     ServiceBinding\r
                     );\r
-\r
     if (EFI_ERROR (Status)) {\r
-      Service->InDestroy = FALSE;\r
       goto ON_EXIT;\r
     }\r
 \r
     Dhcp6DestroyService (Service);\r
-\r
-  } else {\r
-    //\r
-    // Destroy all the children instances before destroy the service.\r
-    //\r
-    while (!IsListEmpty (&Service->Child)) {\r
-      Instance = NET_LIST_HEAD (&Service->Child, DHCP6_INSTANCE, Link);\r
-      ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);\r
-    }\r
-    //\r
-    // Any of child failed to be destroyed.\r
-    //\r
-    if (Service->NumOfChild != 0) {\r
-      Status = EFI_DEVICE_ERROR;\r
-    }\r
+    Status = EFI_SUCCESS;\r
   }\r
-\r
+  \r
 ON_EXIT:\r
-  gBS->RestoreTPL (OldTpl);\r
   return Status;\r
 }\r
 \r
@@ -771,12 +792,13 @@ Dhcp6ServiceBindingDestroyChild (
   //\r
   // Uninstall the MTFTP6 protocol first to enable a top down destruction.\r
   //\r
+  gBS->RestoreTPL (OldTpl);\r
   Status = gBS->UninstallProtocolInterface (\r
                   ChildHandle,\r
                   &gEfiDhcp6ProtocolGuid,\r
                   Dhcp6\r
                   );\r
-\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
   if (EFI_ERROR (Status)) {\r
     Instance->InDestroy = FALSE;\r
     gBS->RestoreTPL (OldTpl);\r
@@ -789,9 +811,8 @@ Dhcp6ServiceBindingDestroyChild (
   RemoveEntryList (&Instance->Link);\r
   Service->NumOfChild--;\r
 \r
-  Dhcp6DestroyInstance (Instance);\r
-\r
   gBS->RestoreTPL (OldTpl);\r
 \r
+  Dhcp6DestroyInstance (Instance);\r
   return EFI_SUCCESS;\r
 }\r