]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c
MdeModulePkg-DxeCore: rename CoreGetMemoryMapPropertiesTable
[mirror_edk2.git] / NetworkPkg / Dhcp6Dxe / Dhcp6Driver.c
index 9bd4c9197a4049a5bc6fcf980821549dc38d3ac6..de53a1a9b4125c6723af85e163a1dd669c28eb46 100644 (file)
@@ -2,7 +2,7 @@
   Driver Binding functions and Service Binding functions\r
   implementationfor for Dhcp6 Driver.\r
 \r
   Driver Binding functions and Service Binding functions\r
   implementationfor for Dhcp6 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
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
@@ -31,7 +31,6 @@ EFI_SERVICE_BINDING_PROTOCOL gDhcp6ServiceBindingTemplate = {
   Dhcp6ServiceBindingDestroyChild\r
 };\r
 \r
   Dhcp6ServiceBindingDestroyChild\r
 };\r
 \r
-\r
 /**\r
   Configure the default Udp6Io to receive all the DHCP6 traffic\r
   on this network interface.\r
 /**\r
   Configure the default Udp6Io to receive all the DHCP6 traffic\r
   on this network interface.\r
@@ -82,7 +81,7 @@ Dhcp6ConfigureUdpIo (
 \r
 \r
 /**\r
 \r
 \r
 /**\r
-  Destory the Dhcp6 service. The Dhcp6 service may be partly initialized,\r
+  Destroy the Dhcp6 service. The Dhcp6 service may be partly initialized,\r
   or partly destroyed. If a resource is destroyed, it is marked as such in\r
   case the destroy failed and being called again later.\r
 \r
   or partly destroyed. If a resource is destroyed, it is marked as such in\r
   case the destroy failed and being called again later.\r
 \r
@@ -95,7 +94,7 @@ Dhcp6DestroyService (
   )\r
 {\r
   //\r
   )\r
 {\r
   //\r
-  // All children instances should have been already destoryed here.\r
+  // All children instances should have been already destroyed here.\r
   //\r
   ASSERT (Service->NumOfChild == 0);\r
 \r
   //\r
   ASSERT (Service->NumOfChild == 0);\r
 \r
@@ -132,6 +131,7 @@ Dhcp6CreateService (
   )\r
 {\r
   DHCP6_SERVICE             *Dhcp6Srv;\r
   )\r
 {\r
   DHCP6_SERVICE             *Dhcp6Srv;\r
+  EFI_STATUS                Status;\r
 \r
   *Service = NULL;\r
   Dhcp6Srv = AllocateZeroPool (sizeof (DHCP6_SERVICE));\r
 \r
   *Service = NULL;\r
   Dhcp6Srv = AllocateZeroPool (sizeof (DHCP6_SERVICE));\r
@@ -154,7 +154,6 @@ Dhcp6CreateService (
   // Initialize the fields of the new Dhcp6 service.\r
   //\r
   Dhcp6Srv->Signature       = DHCP6_SERVICE_SIGNATURE;\r
   // Initialize the fields of the new Dhcp6 service.\r
   //\r
   Dhcp6Srv->Signature       = DHCP6_SERVICE_SIGNATURE;\r
-  Dhcp6Srv->InDestory       = FALSE;\r
   Dhcp6Srv->Controller      = Controller;\r
   Dhcp6Srv->Image           = ImageHandle;\r
   Dhcp6Srv->Xid             = (0xffffff & NET_RANDOM (NetRandomInitSeed ()));\r
   Dhcp6Srv->Controller      = Controller;\r
   Dhcp6Srv->Image           = ImageHandle;\r
   Dhcp6Srv->Xid             = (0xffffff & NET_RANDOM (NetRandomInitSeed ()));\r
@@ -166,7 +165,21 @@ Dhcp6CreateService (
     );\r
 \r
   //\r
     );\r
 \r
   //\r
-  // Generate client Duid in the format of Duid-llt.\r
+  // Locate Ip6->Ip6Config and store it for get IP6 Duplicate Address Detection transmits.\r
+  //\r
+  Status = gBS->HandleProtocol (\r
+                  Controller,\r
+                  &gEfiIp6ConfigProtocolGuid,\r
+                  (VOID **) &Dhcp6Srv->Ip6Cfg\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    FreePool (Dhcp6Srv);\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Generate client Duid: If SMBIOS system UUID is located, generate DUID in DUID-UUID format.\r
+  // Otherwise, in DUID-LLT format.\r
   //\r
   Dhcp6Srv->ClientId        = Dhcp6GenerateClientId (Dhcp6Srv->Snp->Mode);\r
 \r
   //\r
   Dhcp6Srv->ClientId        = Dhcp6GenerateClientId (Dhcp6Srv->Snp->Mode);\r
 \r
@@ -279,7 +292,7 @@ Dhcp6CreateInstance (
   Dhcp6Ins->Signature       = DHCP6_INSTANCE_SIGNATURE;\r
   Dhcp6Ins->UdpSts          = EFI_ALREADY_STARTED;\r
   Dhcp6Ins->Service         = Service;\r
   Dhcp6Ins->Signature       = DHCP6_INSTANCE_SIGNATURE;\r
   Dhcp6Ins->UdpSts          = EFI_ALREADY_STARTED;\r
   Dhcp6Ins->Service         = Service;\r
-  Dhcp6Ins->InDestory       = FALSE;\r
+  Dhcp6Ins->InDestroy       = FALSE;\r
   Dhcp6Ins->MediaPresent    = TRUE;\r
 \r
   CopyMem (\r
   Dhcp6Ins->MediaPresent    = TRUE;\r
 \r
   CopyMem (\r
@@ -313,6 +326,36 @@ Dhcp6CreateInstance (
   return EFI_SUCCESS;\r
 }\r
 \r
   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
+EFIAPI\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
 \r
 /**\r
   Entry point of the DHCP6 driver to install various protocols.\r
@@ -483,11 +526,11 @@ Dhcp6DriverBindingStop (
   )\r
 {\r
   EFI_STATUS                       Status;\r
   )\r
 {\r
   EFI_STATUS                       Status;\r
-  EFI_TPL                          OldTpl;\r
   EFI_HANDLE                       NicHandle;\r
   EFI_SERVICE_BINDING_PROTOCOL     *ServiceBinding;\r
   DHCP6_SERVICE                    *Service;\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
 \r
   //\r
   // Find and check the Nic handle by the controller handle.\r
@@ -495,7 +538,7 @@ Dhcp6DriverBindingStop (
   NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp6ProtocolGuid);\r
 \r
   if (NicHandle == NULL) {\r
   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
   }\r
 \r
   Status = gBS->OpenProtocol (\r
@@ -512,50 +555,44 @@ Dhcp6DriverBindingStop (
   }\r
 \r
   Service = DHCP6_SERVICE_FROM_THIS (ServiceBinding);\r
   }\r
 \r
   Service = DHCP6_SERVICE_FROM_THIS (ServiceBinding);\r
-\r
-  if (Service->InDestory) {\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
   }\r
 \r
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+  if (NumberOfChildren == 0 && !IsListEmpty (&Service->Child)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+  }\r
 \r
 \r
-  if (NumberOfChildren == 0) {\r
+  if (NumberOfChildren == 0 && IsListEmpty (&Service->Child)) {\r
     //\r
     //\r
-    // Destory the service itself if no child instance left.\r
+    // Destroy the service itself if no child instance left.\r
     //\r
     //\r
-    Service->InDestory = TRUE;\r
-\r
     Status = gBS->UninstallProtocolInterface (\r
                     NicHandle,\r
                     &gEfiDhcp6ServiceBindingProtocolGuid,\r
                     ServiceBinding\r
                     );\r
     Status = gBS->UninstallProtocolInterface (\r
                     NicHandle,\r
                     &gEfiDhcp6ServiceBindingProtocolGuid,\r
                     ServiceBinding\r
                     );\r
-\r
     if (EFI_ERROR (Status)) {\r
     if (EFI_ERROR (Status)) {\r
-      Service->InDestory = FALSE;\r
       goto ON_EXIT;\r
     }\r
 \r
     Dhcp6DestroyService (Service);\r
       goto ON_EXIT;\r
     }\r
 \r
     Dhcp6DestroyService (Service);\r
-\r
-  } else {\r
-    //\r
-    // Destory all the children instances before destory 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
+  \r
 ON_EXIT:\r
 ON_EXIT:\r
-  gBS->RestoreTPL (OldTpl);\r
   return Status;\r
 }\r
 \r
   return Status;\r
 }\r
 \r
@@ -732,13 +769,13 @@ Dhcp6ServiceBindingDestroyChild (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (Instance->InDestory) {\r
+  if (Instance->InDestroy) {\r
     return EFI_SUCCESS;\r
   }\r
 \r
   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
     return EFI_SUCCESS;\r
   }\r
 \r
   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
-  Instance->InDestory = TRUE;\r
+  Instance->InDestroy = TRUE;\r
 \r
   Status = gBS->CloseProtocol (\r
                   Service->UdpIo->UdpHandle,\r
 \r
   Status = gBS->CloseProtocol (\r
                   Service->UdpIo->UdpHandle,\r
@@ -748,7 +785,7 @@ Dhcp6ServiceBindingDestroyChild (
                   );\r
 \r
   if (EFI_ERROR (Status)) {\r
                   );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    Instance->InDestory = FALSE;\r
+    Instance->InDestroy = FALSE;\r
     gBS->RestoreTPL (OldTpl);\r
     return Status;\r
   }\r
     gBS->RestoreTPL (OldTpl);\r
     return Status;\r
   }\r
@@ -756,14 +793,15 @@ Dhcp6ServiceBindingDestroyChild (
   //\r
   // Uninstall the MTFTP6 protocol first to enable a top down destruction.\r
   //\r
   //\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
   Status = gBS->UninstallProtocolInterface (\r
                   ChildHandle,\r
                   &gEfiDhcp6ProtocolGuid,\r
                   Dhcp6\r
                   );\r
-\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
   if (EFI_ERROR (Status)) {\r
   if (EFI_ERROR (Status)) {\r
-    Instance->InDestory = FALSE;\r
+    Instance->InDestroy = FALSE;\r
     gBS->RestoreTPL (OldTpl);\r
     return Status;\r
   }\r
     gBS->RestoreTPL (OldTpl);\r
     return Status;\r
   }\r
@@ -774,9 +812,8 @@ Dhcp6ServiceBindingDestroyChild (
   RemoveEntryList (&Instance->Link);\r
   Service->NumOfChild--;\r
 \r
   RemoveEntryList (&Instance->Link);\r
   Service->NumOfChild--;\r
 \r
-  Dhcp6DestroyInstance (Instance);\r
-\r
   gBS->RestoreTPL (OldTpl);\r
 \r
   gBS->RestoreTPL (OldTpl);\r
 \r
+  Dhcp6DestroyInstance (Instance);\r
   return EFI_SUCCESS;\r
 }\r
   return EFI_SUCCESS;\r
 }\r