From 216f79703b8cb8dc65abdd768bedb2bcdbc1a1f8 Mon Sep 17 00:00:00 2001
From: sfu5 <sfu5@6f19259b-4bc3-4df7-8a09-765794883524>
Date: Thu, 13 Dec 2012 06:47:06 +0000
Subject: 1. Add EFI_COMPONENT_NAME2_PROTOCOL.GetControllerName() support. 2.
 Fix the driver binding Stop() hang issue in the network stack. 3. Add Ip4 raw
 data support. 4. Add iSCSI Dhcp option 60 support.

Signed-off-by: Fu Siyuan <siyuan.fu@intel.com>
Reviewed-by: Ye Ting <ting.ye@intel.com>
Reviewed-by: Ouyang Qian <qian.ouyang@intel.com>

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13995 6f19259b-4bc3-4df7-8a09-765794883524
---
 NetworkPkg/Mtftp6Dxe/ComponentName.c | 126 ++++++++++++++++++++++++++++++++++-
 NetworkPkg/Mtftp6Dxe/Mtftp6Driver.c  | 117 +++++++++++++++++++++++---------
 NetworkPkg/Mtftp6Dxe/Mtftp6Driver.h  |   3 +-
 NetworkPkg/Mtftp6Dxe/Mtftp6Impl.c    |  15 ++++-
 NetworkPkg/Mtftp6Dxe/Mtftp6Impl.h    |   8 ++-
 NetworkPkg/Mtftp6Dxe/Mtftp6Rrq.c     |  16 +++++
 NetworkPkg/Mtftp6Dxe/Mtftp6Support.c |   8 ++-
 7 files changed, 253 insertions(+), 40 deletions(-)

(limited to 'NetworkPkg/Mtftp6Dxe')

diff --git a/NetworkPkg/Mtftp6Dxe/ComponentName.c b/NetworkPkg/Mtftp6Dxe/ComponentName.c
index 72a5eb0..f4327ab 100644
--- a/NetworkPkg/Mtftp6Dxe/ComponentName.c
+++ b/NetworkPkg/Mtftp6Dxe/ComponentName.c
@@ -1,7 +1,7 @@
 /** @file
   UEFI Component Name(2) protocol implementation for Mtftp6 driver.
 
-  Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
 
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD License
@@ -170,6 +170,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE        mMtftp6DriverNameT
   }
 };
 
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE   *gMtftp6ControllerNameTable = NULL;
+
 /**
   Retrieves a Unicode string that is the user-readable name of the driver.
 
@@ -227,6 +229,74 @@ Mtftp6ComponentNameGetDriverName (
 }
 
 /**
+  Update the component name for the Mtftp6 child handle.
+
+  @param  Mtftp6[in]                A pointer to the EFI_MTFTP6_PROTOCOL.
+
+  
+  @retval EFI_SUCCESS               Update the ControllerNameTable of this instance successfully.
+  @retval EFI_INVALID_PARAMETER     The input parameter is invalid.
+  
+**/
+EFI_STATUS
+UpdateName (
+  IN    EFI_MTFTP6_PROTOCOL             *Mtftp6
+  )
+{
+  EFI_STATUS                       Status;
+  CHAR16                           HandleName[128];
+  EFI_MTFTP6_MODE_DATA             Mtftp6ModeData;
+  CHAR16                           Address[sizeof"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
+
+  if (Mtftp6 == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Format the child name into the string buffer.
+  //
+  Status = Mtftp6->GetModeData (Mtftp6, &Mtftp6ModeData);
+  if (!EFI_ERROR (Status)) {
+    Status = NetLibIp6ToStr (&Mtftp6ModeData.ConfigData.ServerIp, Address, sizeof(Address));
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    UnicodeSPrint (HandleName, sizeof (HandleName), 
+      L"MTFTPv6(ServerIp=%s, InitialServerPort=%d)",
+      Address,
+      Mtftp6ModeData.ConfigData.InitialServerPort
+      );
+  } else {
+    UnicodeSPrint (HandleName, 0x100, L"MTFTPv6(%r)", Status);
+  }
+
+  if (gMtftp6ControllerNameTable != NULL) {
+    FreeUnicodeStringTable (gMtftp6ControllerNameTable);
+    gMtftp6ControllerNameTable = NULL;
+  }
+  
+  Status = AddUnicodeString2 (
+             "eng",
+             gMtftp6ComponentName.SupportedLanguages,
+             &gMtftp6ControllerNameTable,
+             HandleName,
+             TRUE
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  
+  return AddUnicodeString2 (
+           "en",
+           gMtftp6ComponentName2.SupportedLanguages,
+           &gMtftp6ControllerNameTable,
+           HandleName,
+           FALSE
+           );
+}
+
+
+/**
   Retrieves a Unicode string that is the user-readable name of the controller
   that is being managed by a driver.
 
@@ -304,5 +374,57 @@ Mtftp6ComponentNameGetControllerName (
   OUT CHAR16                                          **ControllerName
   )
 {
-  return EFI_UNSUPPORTED;
+  EFI_STATUS                    Status;
+  EFI_MTFTP6_PROTOCOL           *Mtftp6;
+
+  //
+  // Only provide names for child handles.
+  //
+  if (ChildHandle == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+  
+  // 
+  // Make sure this driver produced ChildHandle 
+  // 
+  Status = EfiTestChildHandle (
+             ControllerHandle,
+             ChildHandle, 
+             &gEfiUdp6ProtocolGuid
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Retrieve an instance of a produced protocol from ChildHandle
+  //
+  Status = gBS->OpenProtocol (
+                  ChildHandle,
+                  &gEfiMtftp6ProtocolGuid,
+                  (VOID **)&Mtftp6,
+                  NULL,
+                  NULL,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Update the component name for this child handle.
+  //
+  Status = UpdateName (Mtftp6);
+  if (EFI_ERROR (Status)) {
+    return Status; 
+  }
+
+  return LookupUnicodeString2 (
+           Language,
+           This->SupportedLanguages,
+           gMtftp6ControllerNameTable,
+           ControllerName,
+           (BOOLEAN)(This == &gMtftp6ComponentName)
+           );
 }
+
diff --git a/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.c b/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.c
index 432eea9..79cd6ba 100644
--- a/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.c
+++ b/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.c
@@ -98,7 +98,6 @@ Mtftp6CreateService (
   Mtftp6Srv->Signature      = MTFTP6_SERVICE_SIGNATURE;
   Mtftp6Srv->Controller     = Controller;
   Mtftp6Srv->Image          = Image;
-  Mtftp6Srv->InDestroy      = FALSE;
   Mtftp6Srv->ChildrenNum    = 0;
 
   CopyMem (
@@ -238,6 +237,44 @@ Mtftp6CreateInstance (
 
 
 /**
+  Callback function which provided by user to remove one node in NetDestroyLinkList process.
+  
+  @param[in]    Entry           The entry to be removed.
+  @param[in]    Context         Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
+
+  @retval EFI_SUCCESS           The entry has been removed successfully.
+  @retval Others                Fail to remove the entry.
+
+**/
+EFI_STATUS
+Mtftp6DestroyChildEntryInHandleBuffer (
+  IN LIST_ENTRY         *Entry,
+  IN VOID               *Context
+)
+{
+  MTFTP6_INSTANCE               *Instance;
+  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;
+  UINTN                         NumberOfChildren;
+  EFI_HANDLE                    *ChildHandleBuffer;
+
+  if (Entry == NULL || Context == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Instance = NET_LIST_USER_STRUCT_S (Entry, MTFTP6_INSTANCE, Link, MTFTP6_INSTANCE_SIGNATURE);
+  ServiceBinding    = ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;
+  NumberOfChildren  = ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;
+  ChildHandleBuffer = ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;
+
+  if (!NetIsInHandleBuffer (Instance->Handle, NumberOfChildren, ChildHandleBuffer)) {
+    return EFI_SUCCESS;
+  }
+
+  return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
+}
+
+
+/**
   This is the declaration of an EFI image entry point. This entry point is
   the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
   both device drivers and bus drivers.
@@ -429,20 +466,20 @@ Mtftp6DriverBindingStop (
   IN  EFI_HANDLE                  *ChildHandleBuffer
   )
 {
-  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;
-  MTFTP6_SERVICE                *Service;
-  MTFTP6_INSTANCE               *Instance;
-  EFI_HANDLE                    NicHandle;
-  EFI_STATUS                    Status;
-  EFI_TPL                       OldTpl;
-
+  EFI_SERVICE_BINDING_PROTOCOL               *ServiceBinding;
+  MTFTP6_SERVICE                             *Service;
+  EFI_HANDLE                                 NicHandle;
+  EFI_STATUS                                 Status;
+  LIST_ENTRY                                 *List;
+  MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
+  
   //
   // Locate the Nic handle to retrieve the Mtftp6 private data.
   //
   NicHandle = NetLibGetNicHandle (Controller, &gEfiUdp6ProtocolGuid);
 
   if (NicHandle == NULL) {
-    return EFI_DEVICE_ERROR;
+    return EFI_SUCCESS;
   }
 
   Status = gBS->OpenProtocol (
@@ -460,18 +497,26 @@ Mtftp6DriverBindingStop (
 
   Service = MTFTP6_SERVICE_FROM_THIS (ServiceBinding);
 
-  if (Service->InDestroy) {
-    return EFI_SUCCESS;
+  if (!IsListEmpty (&Service->Children)) {
+    //
+    // Destroy the Mtftp6 child instance in ChildHandleBuffer.
+    //
+    List = &Service->Children;
+    Context.ServiceBinding    = ServiceBinding;
+    Context.NumberOfChildren  = NumberOfChildren;
+    Context.ChildHandleBuffer = ChildHandleBuffer;
+    Status = NetDestroyLinkList (
+               List,
+               Mtftp6DestroyChildEntryInHandleBuffer,
+               &Context,
+               NULL
+               );
   }
 
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-
-  if (NumberOfChildren == 0) {
+  if (NumberOfChildren == 0 && IsListEmpty (&Service->Children)) {
     //
     // Destroy the Mtftp6 service if there is no Mtftp6 child instance left.
     //
-    Service->InDestroy = TRUE;
-
     gBS->UninstallProtocolInterface (
            NicHandle,
            &gEfiMtftp6ServiceBindingProtocolGuid,
@@ -479,22 +524,9 @@ Mtftp6DriverBindingStop (
            );
 
     Mtftp6DestroyService (Service);
-
-  } else {
-    //
-    // Destroy the Mtftp6 child instance one by one.
-    //
-    while (!IsListEmpty (&Service->Children)) {
-      Instance = NET_LIST_HEAD (&Service->Children, MTFTP6_INSTANCE, Link);
-      Mtftp6ServiceBindingDestroyChild (ServiceBinding, Instance->Handle);
-    }
-
-    if (Service->ChildrenNum != 0) {
-      Status = EFI_DEVICE_ERROR;
-    }
+    Status = EFI_SUCCESS;
   }
 
-  gBS->RestoreTPL (OldTpl);
   return Status;
 }
 
@@ -674,15 +706,34 @@ Mtftp6ServiceBindingDestroyChild (
          ChildHandle
          );
 
+  if (Instance->UdpIo != NULL) {
+    gBS->CloseProtocol (
+         Instance->UdpIo->UdpHandle,
+         &gEfiUdp6ProtocolGuid,
+         gMtftp6DriverBinding.DriverBindingHandle,
+         Instance->Handle
+         );
+  }
+
+  if (Instance->McastUdpIo != NULL) {
+    gBS->CloseProtocol (
+           Instance->McastUdpIo->UdpHandle,
+           &gEfiUdp6ProtocolGuid,
+           gMtftp6DriverBinding.DriverBindingHandle,
+           Instance->Handle
+           );
+  }
+
   //
   // Uninstall the MTFTP6 protocol first to enable a top down destruction.
   //
+  gBS->RestoreTPL (OldTpl);
   Status = gBS->UninstallProtocolInterface (
                   ChildHandle,
                   &gEfiMtftp6ProtocolGuid,
                   Mtftp6
                   );
-
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
   if (EFI_ERROR (Status)) {
     Instance->InDestroy = FALSE;
     gBS->RestoreTPL (OldTpl);
@@ -695,9 +746,9 @@ Mtftp6ServiceBindingDestroyChild (
   RemoveEntryList (&Instance->Link);
   Service->ChildrenNum --;
 
-  Mtftp6DestroyInstance (Instance);
-
   gBS->RestoreTPL (OldTpl);
 
+  Mtftp6DestroyInstance (Instance);
+
   return EFI_SUCCESS;
 }
diff --git a/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.h b/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.h
index 3e3165b..55ac1dd 100644
--- a/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.h
+++ b/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.h
@@ -2,7 +2,7 @@
   Driver Binding functions and Service Binding functions
   declaration for Mtftp6 Driver.
 
-  Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
 
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD License
@@ -21,6 +21,7 @@
 
 extern EFI_COMPONENT_NAME_PROTOCOL  gMtftp6ComponentName;
 extern EFI_COMPONENT_NAME2_PROTOCOL gMtftp6ComponentName2;
+extern EFI_UNICODE_STRING_TABLE     *gMtftp6ControllerNameTable;
 
 /**
   Test to see if this driver supports Controller. This service
diff --git a/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.c b/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.c
index 4a4e5b1..9b08455 100644
--- a/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.c
+++ b/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.c
@@ -197,6 +197,19 @@ EfiMtftp6Configure (
                           UDP_IO_UDP6_VERSION,
                           NULL
                           );
+      if (Instance->UdpIo != NULL) {
+        Status = gBS->OpenProtocol (
+                        Instance->UdpIo->UdpHandle,
+                        &gEfiUdp6ProtocolGuid,
+                        (VOID **) &Udp6,
+                        Service->Image,
+                        Instance->Handle,
+                        EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+                        );
+        if (EFI_ERROR (Status)) {
+          goto ON_EXIT;
+        }
+      }
     }
 
     if (Instance->UdpIo == NULL) {
@@ -626,8 +639,6 @@ EfiMtftp6Poll (
   //
   if (Instance->Config == NULL) {
     return EFI_NOT_STARTED;
-  } else if (Instance->InDestroy) {
-    return EFI_DEVICE_ERROR;
   }
 
   Udp6 = Instance->UdpIo->Protocol.Udp6;
diff --git a/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.h b/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.h
index 68fa0da..6b1ce7f 100644
--- a/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.h
+++ b/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.h
@@ -29,6 +29,7 @@
 #include <Library/UefiLib.h>
 #include <Library/BaseLib.h>
 #include <Library/NetLib.h>
+#include <Library/PrintLib.h>
 
 typedef struct _MTFTP6_SERVICE  MTFTP6_SERVICE;
 typedef struct _MTFTP6_INSTANCE MTFTP6_INSTANCE;
@@ -117,9 +118,14 @@ struct _MTFTP6_SERVICE {
   // mtftp driver and udp driver.
   //
   UDP_IO                        *DummyUdpIo;
-  BOOLEAN                       InDestroy;
 };
 
+typedef struct {
+  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;
+  UINTN                         NumberOfChildren;
+  EFI_HANDLE                    *ChildHandleBuffer;
+} MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT;
+
 /**
   Returns the current operating mode data for the MTFTP6 instance.
 
diff --git a/NetworkPkg/Mtftp6Dxe/Mtftp6Rrq.c b/NetworkPkg/Mtftp6Dxe/Mtftp6Rrq.c
index 7fc613a..4a481f4 100644
--- a/NetworkPkg/Mtftp6Dxe/Mtftp6Rrq.c
+++ b/NetworkPkg/Mtftp6Dxe/Mtftp6Rrq.c
@@ -453,6 +453,7 @@ Mtftp6RrqHandleOack (
   MTFTP6_EXT_OPTION_INFO    ExtInfo;
   EFI_STATUS                Status;
   INTN                      Expected;
+  EFI_UDP6_PROTOCOL         *Udp6;
 
   *IsCompleted = FALSE;
 
@@ -555,6 +556,21 @@ Mtftp6RrqHandleOack (
                                  UDP_IO_UDP6_VERSION,
                                  Instance
                                  );
+        if (Instance->McastUdpIo != NULL) {
+          Status = gBS->OpenProtocol (
+                          Instance->McastUdpIo->UdpHandle,
+                          &gEfiUdp6ProtocolGuid,
+                          (VOID **) &Udp6,
+                          Instance->Service->Image,
+                          Instance->Handle,
+                          EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+                          );
+          if (EFI_ERROR (Status)) {
+            UdpIoFreeIo (Instance->McastUdpIo);
+            Instance->McastUdpIo = NULL;
+            return EFI_DEVICE_ERROR;
+          }
+        }
       }
 
       if (Instance->McastUdpIo == NULL) {
diff --git a/NetworkPkg/Mtftp6Dxe/Mtftp6Support.c b/NetworkPkg/Mtftp6Dxe/Mtftp6Support.c
index 24ce0e8..f5b2231 100644
--- a/NetworkPkg/Mtftp6Dxe/Mtftp6Support.c
+++ b/NetworkPkg/Mtftp6Dxe/Mtftp6Support.c
@@ -1,7 +1,7 @@
 /** @file
   Mtftp6 support functions implementation.
 
-  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
 
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD License
@@ -903,6 +903,12 @@ Mtftp6OperationClean (
   }
 
   if (Instance->McastUdpIo != NULL) {
+    gBS->CloseProtocol (
+           Instance->McastUdpIo->UdpHandle,
+           &gEfiUdp6ProtocolGuid,
+           Instance->McastUdpIo->Image,
+           Instance->Handle
+           );
     UdpIoFreeIo (Instance->McastUdpIo);
     Instance->McastUdpIo = NULL;
   }
-- 
cgit v1.1