1. Add EFI_COMPONENT_NAME2_PROTOCOL.GetControllerName() support.
authorsfu5 <sfu5@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 13 Dec 2012 06:47:06 +0000 (06:47 +0000)
committersfu5 <sfu5@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 13 Dec 2012 06:47:06 +0000 (06:47 +0000)
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

91 files changed:
MdeModulePkg/Include/Library/NetLib.h
MdeModulePkg/Library/DxeNetLib/DxeNetLib.c
MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c
MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.c
MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.h
MdeModulePkg/Universal/Network/ArpDxe/ComponentName.c
MdeModulePkg/Universal/Network/Dhcp4Dxe/ComponentName.c
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.c
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.h
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.h
MdeModulePkg/Universal/Network/IScsiDxe/ComponentName.c
MdeModulePkg/Universal/Network/Ip4Dxe/ComponentName.c
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Common.h
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.h
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Icmp.c
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c
MdeModulePkg/Universal/Network/MnpDxe/ComponentName.c
MdeModulePkg/Universal/Network/MnpDxe/ComponentName.h
MdeModulePkg/Universal/Network/MnpDxe/MnpConfig.c
MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.c
MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.h
MdeModulePkg/Universal/Network/Mtftp4Dxe/ComponentName.c
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.h
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.h
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c
MdeModulePkg/Universal/Network/SnpDxe/ComponentName.c
MdeModulePkg/Universal/Network/SnpDxe/Snp.c
MdeModulePkg/Universal/Network/SnpDxe/Snp.h
MdeModulePkg/Universal/Network/Tcp4Dxe/ComponentName.c
MdeModulePkg/Universal/Network/Tcp4Dxe/SockInterface.c
MdeModulePkg/Universal/Network/Tcp4Dxe/Socket.h
MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dispatcher.c
MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c
MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Main.h
MdeModulePkg/Universal/Network/Udp4Dxe/ComponentName.c
MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Driver.c
MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c
MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.h
MdeModulePkg/Universal/Network/UefiPxeBcDxe/ComponentName.c
MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDriver.c
MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigImpl.c
NetworkPkg/Dhcp6Dxe/ComponentName.c
NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c
NetworkPkg/Dhcp6Dxe/Dhcp6Driver.h
NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c
NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h
NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
NetworkPkg/IScsiDxe/ComponentName.c
NetworkPkg/IScsiDxe/IScsiDhcp6.c
NetworkPkg/IScsiDxe/IScsiDhcp6.h
NetworkPkg/IScsiDxe/IScsiDriver.c
NetworkPkg/IScsiDxe/IScsiDriver.h
NetworkPkg/IScsiDxe/IScsiIbft.c
NetworkPkg/Ip6Dxe/ComponentName.c
NetworkPkg/Ip6Dxe/Ip6Common.c
NetworkPkg/Ip6Dxe/Ip6Common.h
NetworkPkg/Ip6Dxe/Ip6Driver.c
NetworkPkg/Ip6Dxe/Ip6Driver.h
NetworkPkg/Ip6Dxe/Ip6If.c
NetworkPkg/Ip6Dxe/Ip6Impl.c
NetworkPkg/Ip6Dxe/Ip6Impl.h
NetworkPkg/Ip6Dxe/Ip6Nd.c
NetworkPkg/IpSecDxe/ComponentName.c
NetworkPkg/Mtftp6Dxe/ComponentName.c
NetworkPkg/Mtftp6Dxe/Mtftp6Driver.c
NetworkPkg/Mtftp6Dxe/Mtftp6Driver.h
NetworkPkg/Mtftp6Dxe/Mtftp6Impl.c
NetworkPkg/Mtftp6Dxe/Mtftp6Impl.h
NetworkPkg/Mtftp6Dxe/Mtftp6Rrq.c
NetworkPkg/Mtftp6Dxe/Mtftp6Support.c
NetworkPkg/TcpDxe/ComponentName.c
NetworkPkg/TcpDxe/SockInterface.c
NetworkPkg/TcpDxe/Socket.h
NetworkPkg/TcpDxe/TcpDispatcher.c
NetworkPkg/TcpDxe/TcpDriver.c
NetworkPkg/TcpDxe/TcpMain.h
NetworkPkg/Udp6Dxe/ComponentName.c
NetworkPkg/Udp6Dxe/Udp6Driver.c
NetworkPkg/Udp6Dxe/Udp6Impl.c
NetworkPkg/Udp6Dxe/Udp6Impl.h
NetworkPkg/UefiPxeBcDxe/ComponentName.c
NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c
NetworkPkg/UefiPxeBcDxe/PxeBcSupport.h

index fa59254..d85c259 100644 (file)
@@ -662,6 +662,72 @@ NetListInsertBefore (
   IN OUT LIST_ENTRY     *NewEntry\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
+typedef\r
+EFI_STATUS\r
+(EFIAPI *NET_DESTROY_LINK_LIST_CALLBACK) (\r
+  IN LIST_ENTRY         *Entry,\r
+  IN VOID               *Context   OPTIONAL\r
+);\r
+\r
+/**\r
+  Safe destroy nodes in a linked list, and return the length of the list after all possible operations finished.\r
+\r
+  Destroy network children list by list traversals is not safe due to graph dependencies between nodes.\r
+  This function performs a safe traversal to destroy these nodes by checking to see if the node being destroyed\r
+  has been removed from the list or not.\r
+  If it has been removed, then restart the traversal from the head.\r
+  If it hasn't been removed, then continue with the next node directly.\r
+  This function will end the iterate and return the CallBack's last return value if error happens,\r
+  or retrun EFI_SUCCESS if 2 complete passes are made with no changes in the number of children in the list.  \r
+\r
+  @param[in]    List             The head of the list.\r
+  @param[in]    CallBack         Pointer to the callback function to destroy one node in the list.\r
+  @param[in]    Context          Pointer to the callback function's context: corresponds to the\r
+                                 parameter Context in NET_DESTROY_LINK_LIST_CALLBACK.\r
+  @param[out]   ListLength       The length of the link list if the function returns successfully.\r
+\r
+  @retval EFI_SUCCESS            Two complete passes are made with no changes in the number of children.\r
+  @retval EFI_INVALID_PARAMETER  The input parameter is invalid.\r
+  @retval Others                 Return the CallBack's last return value.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+NetDestroyLinkList (\r
+  IN   LIST_ENTRY                       *List,\r
+  IN   NET_DESTROY_LINK_LIST_CALLBACK   CallBack,\r
+  IN   VOID                             *Context,    OPTIONAL\r
+  OUT  UINTN                            *ListLength  OPTIONAL\r
+);\r
+\r
+/**\r
+  This function checks the input Handle to see if it's one of these handles in ChildHandleBuffer.\r
+\r
+  @param[in]  Handle             Handle to be checked.\r
+  @param[in]  NumberOfChildren   Number of Handles in ChildHandleBuffer.\r
+  @param[in]  ChildHandleBuffer  An array of child handles to be freed. May be NULL\r
+                                 if NumberOfChildren is 0.\r
+\r
+  @retval TURE                   Found the input Handle in ChildHandleBuffer.\r
+  @retval FALSE                  Can't find the input Handle in ChildHandleBuffer.\r
+\r
+**/\r
+BOOLEAN\r
+NetIsInHandleBuffer (\r
+  IN  EFI_HANDLE          Handle,\r
+  IN  UINTN               NumberOfChildren,\r
+  IN  EFI_HANDLE          *ChildHandleBuffer OPTIONAL\r
+);\r
 \r
 //\r
 // Object container: EFI network stack spec defines various kinds of\r
@@ -1337,6 +1403,28 @@ NetLibStrToIp6andPrefix (
   OUT      UINT8                 *PrefixLength\r
   );\r
 \r
+/**\r
+\r
+  Convert one EFI_IPv6_ADDRESS to Null-terminated Unicode string.\r
+  The text representation of address is defined in RFC 4291.\r
+  \r
+  @param[in]       Ip6Address     The pointer to the IPv6 address.\r
+  @param[out]      String         The buffer to return the converted string.\r
+  @param[in]       StringSize     The length in bytes of the input String.\r
+                                  \r
+  @retval EFI_SUCCESS             Convert to string successfully.\r
+  @retval EFI_INVALID_PARAMETER   The input parameter is invalid.\r
+  @retval EFI_BUFFER_TOO_SMALL    The BufferSize is too small for the result. BufferSize has been \r
+                                  updated with the size needed to complete the request.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+NetLibIp6ToStr (\r
+  IN         EFI_IPv6_ADDRESS      *Ip6Address,\r
+  OUT        CHAR16                *String,\r
+  IN         UINTN                 StringSize\r
+  );\r
+\r
 //\r
 // Various signatures\r
 //\r
index 956f733..174c3c8 100644 (file)
@@ -40,6 +40,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/UefiLib.h>\r
 \r
 #define NIC_ITEM_CONFIG_SIZE   sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * MAX_IP4_CONFIG_IN_VARIABLE\r
+#define DEFAULT_ZERO_START     ((UINTN) ~0)\r
 \r
 //\r
 // All the supported IP4 maskes in host byte order.\r
@@ -1065,6 +1066,115 @@ NetListInsertBefore (
   PostEntry->BackLink               = NewEntry;\r
 }\r
 \r
+/**\r
+  Safe destroy nodes in a linked list, and return the length of the list after all possible operations finished.\r
+\r
+  Destroy network child instance list by list traversals is not safe due to graph dependencies between nodes.\r
+  This function performs a safe traversal to destroy these nodes by checking to see if the node being destroyed\r
+  has been removed from the list or not.\r
+  If it has been removed, then restart the traversal from the head.\r
+  If it hasn't been removed, then continue with the next node directly.\r
+  This function will end the iterate and return the CallBack's last return value if error happens,\r
+  or retrun EFI_SUCCESS if 2 complete passes are made with no changes in the number of children in the list.  \r
+\r
+  @param[in]    List             The head of the list.\r
+  @param[in]    CallBack         Pointer to the callback function to destroy one node in the list.\r
+  @param[in]    Context          Pointer to the callback function's context: corresponds to the\r
+                                 parameter Context in NET_DESTROY_LINK_LIST_CALLBACK.\r
+  @param[out]   ListLength       The length of the link list if the function returns successfully.\r
+\r
+  @retval EFI_SUCCESS            Two complete passes are made with no changes in the number of children.\r
+  @retval EFI_INVALID_PARAMETER  The input parameter is invalid.\r
+  @retval Others                 Return the CallBack's last return value.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+NetDestroyLinkList (\r
+  IN   LIST_ENTRY                       *List,\r
+  IN   NET_DESTROY_LINK_LIST_CALLBACK   CallBack,\r
+  IN   VOID                             *Context,    OPTIONAL\r
+  OUT  UINTN                            *ListLength  OPTIONAL\r
+)\r
+{\r
+  UINTN                         PreviousLength;\r
+  LIST_ENTRY                    *Entry;\r
+  LIST_ENTRY                    *Ptr;\r
+  UINTN                         Length;\r
+  EFI_STATUS                    Status;\r
+\r
+  if (List == NULL || CallBack == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Length = 0;\r
+  do {\r
+    PreviousLength = Length;\r
+    Entry = GetFirstNode (List);\r
+    while (!IsNull (List, Entry)) {\r
+      Status = CallBack (Entry, Context);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+      //\r
+      // Walk through the list to see whether the Entry has been removed or not.\r
+      // If the Entry still exists, just try to destroy the next one.\r
+      // If not, go back to the start point to iterate the list again.\r
+      //\r
+      for (Ptr = List->ForwardLink; Ptr != List; Ptr = Ptr->ForwardLink) {\r
+        if (Ptr == Entry) {\r
+          break;\r
+        }\r
+      }\r
+      if (Ptr == Entry) {\r
+        Entry = GetNextNode (List, Entry);\r
+      } else {\r
+        Entry = GetFirstNode (List);\r
+      }\r
+    }\r
+    for (Length = 0, Ptr = List->ForwardLink; Ptr != List; Length++, Ptr = Ptr->ForwardLink);\r
+  } while (Length != PreviousLength);\r
+\r
+  if (ListLength != NULL) {\r
+    *ListLength = Length;\r
+  }\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This function checks the input Handle to see if it's one of these handles in ChildHandleBuffer.\r
+\r
+  @param[in]  Handle             Handle to be checked.\r
+  @param[in]  NumberOfChildren   Number of Handles in ChildHandleBuffer.\r
+  @param[in]  ChildHandleBuffer  An array of child handles to be freed. May be NULL\r
+                                 if NumberOfChildren is 0.\r
+\r
+  @retval TURE                   Found the input Handle in ChildHandleBuffer.\r
+  @retval FALSE                  Can't find the input Handle in ChildHandleBuffer.\r
+\r
+**/\r
+BOOLEAN\r
+NetIsInHandleBuffer (\r
+  IN  EFI_HANDLE          Handle,\r
+  IN  UINTN               NumberOfChildren,\r
+  IN  EFI_HANDLE          *ChildHandleBuffer OPTIONAL\r
+)\r
+{\r
+  UINTN     Index;\r
+  \r
+  if (NumberOfChildren == 0 || ChildHandleBuffer == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  for (Index = 0; Index < NumberOfChildren; Index++) {\r
+    if (Handle == ChildHandleBuffer[Index]) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
 \r
 /**\r
   Initialize the netmap. Netmap is a reposity to keep the <Key, Value> pairs.\r
@@ -3175,7 +3285,110 @@ Exit:
   return Status;\r
 }\r
 \r
+/**\r
+\r
+  Convert one EFI_IPv6_ADDRESS to Null-terminated Unicode string.\r
+  The text representation of address is defined in RFC 4291.\r
+  \r
+  @param[in]       Ip6Address     The pointer to the IPv6 address.\r
+  @param[out]      String         The buffer to return the converted string.\r
+  @param[in]       StringSize     The length in bytes of the input String.\r
+                                  \r
+  @retval EFI_SUCCESS             Convert to string successfully.\r
+  @retval EFI_INVALID_PARAMETER   The input parameter is invalid.\r
+  @retval EFI_BUFFER_TOO_SMALL    The BufferSize is too small for the result. BufferSize has been \r
+                                  updated with the size needed to complete the request.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+NetLibIp6ToStr (\r
+  IN         EFI_IPv6_ADDRESS      *Ip6Address,\r
+  OUT        CHAR16                *String,\r
+  IN         UINTN                 StringSize\r
+  )\r
+{\r
+  UINT16     Ip6Addr[8];\r
+  UINTN      Index;\r
+  UINTN      LongestZerosStart;\r
+  UINTN      LongestZerosLength;\r
+  UINTN      CurrentZerosStart;\r
+  UINTN      CurrentZerosLength;\r
+  CHAR16     Buffer[sizeof"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];\r
+  CHAR16     *Ptr;\r
+\r
+  if (Ip6Address == NULL || String == NULL || StringSize == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
 \r
+  //\r
+  // Convert the UINT8 array to an UINT16 array for easy handling.\r
+  // \r
+  ZeroMem (Ip6Addr, sizeof (Ip6Addr));\r
+  for (Index = 0; Index < 16; Index++) {\r
+    Ip6Addr[Index / 2] |= (Ip6Address->Addr[Index] << ((1 - (Index % 2)) << 3));\r
+  }\r
+\r
+  //\r
+  // Find the longest zeros and mark it.\r
+  //\r
+  CurrentZerosStart  = DEFAULT_ZERO_START;\r
+  CurrentZerosLength = 0;\r
+  LongestZerosStart  = DEFAULT_ZERO_START;\r
+  LongestZerosLength = 0;\r
+  for (Index = 0; Index < 8; Index++) {\r
+    if (Ip6Addr[Index] == 0) {\r
+      if (CurrentZerosStart == DEFAULT_ZERO_START) {\r
+        CurrentZerosStart = Index;\r
+        CurrentZerosLength = 1;\r
+      } else {\r
+        CurrentZerosLength++;\r
+      }\r
+    } else {\r
+      if (CurrentZerosStart != DEFAULT_ZERO_START) {\r
+        if (CurrentZerosLength > 2 && (LongestZerosStart == (DEFAULT_ZERO_START) || CurrentZerosLength > LongestZerosLength)) {\r
+          LongestZerosStart  = CurrentZerosStart;\r
+          LongestZerosLength = CurrentZerosLength;\r
+        }\r
+        CurrentZerosStart  = DEFAULT_ZERO_START;\r
+        CurrentZerosLength = 0;\r
+      }\r
+    }\r
+  }\r
+  \r
+  if (CurrentZerosStart != DEFAULT_ZERO_START && CurrentZerosLength > 2) {\r
+    if (LongestZerosStart == DEFAULT_ZERO_START || LongestZerosLength < CurrentZerosLength) {\r
+      LongestZerosStart  = CurrentZerosStart;\r
+      LongestZerosLength = CurrentZerosLength;\r
+    }\r
+  }\r
+\r
+  Ptr = Buffer;\r
+  for (Index = 0; Index < 8; Index++) {\r
+    if (LongestZerosStart != DEFAULT_ZERO_START && Index >= LongestZerosStart && Index < LongestZerosStart + LongestZerosLength) {\r
+      if (Index == LongestZerosStart) {\r
+        *Ptr++ = L':';\r
+      }\r
+      continue;\r
+    }\r
+    if (Index != 0) {\r
+      *Ptr++ = L':';\r
+    }\r
+    Ptr += UnicodeSPrint(Ptr, 10, L"%x", Ip6Addr[Index]);\r
+  }\r
+  \r
+  if (LongestZerosStart != DEFAULT_ZERO_START && LongestZerosStart + LongestZerosLength == 8) {\r
+    *Ptr++ = L':';\r
+  }\r
+  *Ptr = L'\0';\r
+\r
+  if ((UINTN)Ptr - (UINTN)Buffer > StringSize) {\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  StrCpy (String, Buffer);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
 \r
 /**\r
   This function obtains the system guid from the smbios table.\r
index 37042d1..8914ebf 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   ARP driver functions.\r
   \r
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at<BR>\r
@@ -242,6 +242,35 @@ ArpCleanService (
 }\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
+ArpDestroyChildEntryInHandleBuffer (\r
+  IN LIST_ENTRY         *Entry,\r
+  IN VOID               *Context\r
+)\r
+{\r
+  ARP_INSTANCE_DATA             *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, ARP_INSTANCE_DATA, List, ARP_INSTANCE_DATA_SIGNATURE);\r
+  ServiceBinding    = (EFI_SERVICE_BINDING_PROTOCOL *) Context;\r
+\r
+  return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);\r
+}\r
+\r
+/**\r
   Tests to see if this driver supports a given controller. \r
   \r
   If a child device is provided, it further tests to see if this driver supports \r
@@ -446,14 +475,14 @@ ArpDriverBindingStop (
   EFI_HANDLE                    NicHandle;\r
   EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;\r
   ARP_SERVICE_DATA              *ArpService;\r
-  ARP_INSTANCE_DATA             *Instance;\r
+  LIST_ENTRY                    *List;\r
 \r
   //\r
   // Get the NicHandle which the arp servicebinding is installed on.\r
   //\r
   NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);\r
   if (NicHandle == NULL) {\r
-    return EFI_DEVICE_ERROR;\r
+    return EFI_SUCCESS;\r
   }\r
 \r
   //\r
@@ -474,7 +503,21 @@ ArpDriverBindingStop (
 \r
   ArpService = ARP_SERVICE_DATA_FROM_THIS (ServiceBinding);\r
 \r
-  if (NumberOfChildren == 0) {\r
+  if (NumberOfChildren != 0) {\r
+    //\r
+    // NumberOfChildren is not zero, destroy all the ARP children instances.\r
+    //\r
+    List = &ArpService->ChildrenList;\r
+    Status = NetDestroyLinkList (\r
+               List,\r
+               ArpDestroyChildEntryInHandleBuffer,\r
+               ServiceBinding,\r
+               NULL\r
+               );\r
+    ASSERT (IsListEmpty (&ArpService->PendingRequestTable));\r
+    ASSERT (IsListEmpty (&ArpService->DeniedCacheTable));\r
+    ASSERT (IsListEmpty (&ArpService->ResolvedCacheTable));\r
+  } else if (IsListEmpty (&ArpService->ChildrenList)) {\r
     //\r
     // Uninstall the ARP ServiceBinding protocol.\r
     //\r
@@ -491,17 +534,6 @@ ArpDriverBindingStop (
     ArpCleanService (ArpService);\r
 \r
     FreePool (ArpService);\r
-  } else {\r
-\r
-    while (!IsListEmpty (&ArpService->ChildrenList)) {\r
-      Instance = NET_LIST_HEAD (&ArpService->ChildrenList, ARP_INSTANCE_DATA, List);\r
-\r
-      ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);\r
-    }\r
-\r
-    ASSERT (IsListEmpty (&ArpService->PendingRequestTable));\r
-    ASSERT (IsListEmpty (&ArpService->DeniedCacheTable));\r
-    ASSERT (IsListEmpty (&ArpService->ResolvedCacheTable));\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -690,14 +722,14 @@ ArpServiceBindingDestroyChild (
 \r
   Instance = ARP_INSTANCE_DATA_FROM_THIS (Arp);\r
 \r
-  if (Instance->Destroyed) {\r
+  if (Instance->InDestroy) {\r
     return EFI_SUCCESS;\r
   }\r
 \r
   //\r
-  // Use the Destroyed as a flag to avoid re-entrance.\r
+  // Use the InDestroy as a flag to avoid re-entrance.\r
   //\r
-  Instance->Destroyed = TRUE;\r
+  Instance->InDestroy = TRUE;\r
 \r
   //\r
   // Close the Managed Network protocol.\r
@@ -722,7 +754,7 @@ ArpServiceBindingDestroyChild (
     DEBUG ((EFI_D_ERROR, "ArpSBDestroyChild: Failed to uninstall the arp protocol, %r.\n",\r
       Status));\r
 \r
-    Instance->Destroyed = FALSE;\r
+    Instance->InDestroy = FALSE;\r
     return Status;\r
   }\r
 \r
index c754177..633c3e7 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   The implementation of the ARP protocol.\r
   \r
-Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at<BR>\r
@@ -52,7 +52,7 @@ ArpInitInstance (
   CopyMem (&Instance->ArpProto, &mEfiArpProtocolTemplate, sizeof (Instance->ArpProto));\r
 \r
   Instance->Configured = FALSE;\r
-  Instance->Destroyed  = FALSE;\r
+  Instance->InDestroy  = FALSE;\r
 \r
   InitializeListHead (&Instance->List);\r
 }\r
index 418b4c8..a5dce7d 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   EFI Address Resolution Protocol (ARP) Protocol interface header file.\r
 \r
-Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at<BR>\r
@@ -123,7 +123,7 @@ typedef struct {
   LIST_ENTRY           List;\r
   EFI_ARP_CONFIG_DATA  ConfigData;\r
   BOOLEAN              Configured;\r
-  BOOLEAN              Destroyed;\r
+  BOOLEAN              InDestroy;\r
 } ARP_INSTANCE_DATA;\r
 \r
 #define ARP_SERVICE_DATA_SIGNATURE  SIGNATURE_32('A', 'R', 'P', 'S')\r
index 136b1df..ee47fb1 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   UEFI Component Name(2) protocol implementation for ArpDxe driver.\r
 \r
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at<BR>\r
@@ -39,6 +39,11 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mArpDriverNameTable[] = {
   { NULL, NULL }\r
 };\r
 \r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mArpControllerNameTable[] = {\r
+  { "eng;en", L"ARP Controller" },\r
+  { NULL, NULL }\r
+};\r
+\r
 /**\r
   Retrieves a Unicode string that is the user readable name of the driver.\r
 \r
@@ -173,6 +178,48 @@ ArpComponentNameGetControllerName (
   OUT CHAR16                                          **ControllerName\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
-}\r
+  EFI_STATUS                    Status;\r
+  EFI_ARP_PROTOCOL              *Arp;\r
+\r
+  //\r
+  // Only provide names for child handles.\r
+  //\r
+  if (ChildHandle == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  \r
+  // \r
+  // Make sure this driver produced ChildHandle \r
+  // \r
+  Status = EfiTestChildHandle (\r
+             ControllerHandle,\r
+             ChildHandle,\r
+             &gEfiManagedNetworkProtocolGuid\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  // \r
+  // Retrieve an instance of a produced protocol from ChildHandle  \r
+  // \r
+  Status = gBS->OpenProtocol (\r
+                  ChildHandle,\r
+                  &gEfiArpProtocolGuid,\r
+                 (VOID **)&Arp,\r
+                  NULL,\r
+                  NULL,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
+  return LookupUnicodeString2 (\r
+           Language,\r
+           This->SupportedLanguages,\r
+           mArpControllerNameTable,\r
+           ControllerName,\r
+           (BOOLEAN)(This == &gArpComponentName)\r
+           );\r
+}\r
index e9d86fb..2ea0760 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 \r
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -174,6 +174,20 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mDhcpDriverNameTable[] =
   }\r
 };\r
 \r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE    *gDhcpControllerNameTable = NULL;\r
+\r
+CHAR16 *mDhcp4ControllerName[] = {\r
+  L"DHCPv4 (State=0, Stopped)",\r
+  L"DHCPv4 (State=1, Init)",\r
+  L"DHCPv4 (State=2, Selecting)",\r
+  L"DHCPv4 (State=3, Requesting)",\r
+  L"DHCPv4 (State=4, Bound)",\r
+  L"DHCPv4 (State=5, Renewing)",\r
+  L"DHCPv4 (State=6, Rebinding)",\r
+  L"DHCPv4 (State=7, InitReboot)",\r
+  L"DHCPv4 (State=8, Rebooting)"\r
+};\r
+\r
 /**\r
   Retrieves a Unicode string that is the user readable name of the driver.\r
 \r
@@ -231,6 +245,66 @@ DhcpComponentNameGetDriverName (
 }\r
 \r
 /**\r
+  Update the component name for the Dhcp4 child handle.\r
+\r
+  @param  Dhcp4[in]               A pointer to the EFI_DHCP4_PROTOCOL.\r
+\r
+  \r
+  @retval EFI_SUCCESS             Update the ControllerNameTable of this instance successfully.\r
+  @retval EFI_INVALID_PARAMETER   The input parameter is invalid.\r
+  @retval EFI_DEVICE_ERROR        DHCP is in unknown state.\r
+  \r
+**/\r
+EFI_STATUS\r
+UpdateName (\r
+  IN     EFI_DHCP4_PROTOCOL             *Dhcp4\r
+  )\r
+{\r
+  EFI_STATUS                       Status;\r
+  EFI_DHCP4_MODE_DATA              Dhcp4ModeData;\r
+\r
+  if (Dhcp4 == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Format the child name into the string buffer.\r
+  //\r
+  Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4ModeData);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  \r
+  if (gDhcpControllerNameTable != NULL) {\r
+    FreeUnicodeStringTable (gDhcpControllerNameTable);\r
+    gDhcpControllerNameTable = NULL;\r
+  }\r
+  \r
+  if (Dhcp4ModeData.State > Dhcp4Rebooting) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+  \r
+  Status = AddUnicodeString2 (\r
+             "eng",\r
+             gDhcp4ComponentName.SupportedLanguages,\r
+             &gDhcpControllerNameTable,\r
+             mDhcp4ControllerName[Dhcp4ModeData.State],\r
+             TRUE\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  \r
+  return AddUnicodeString2 (\r
+           "en",\r
+           gDhcp4ComponentName2.SupportedLanguages,\r
+           &gDhcpControllerNameTable,\r
+           mDhcp4ControllerName[Dhcp4ModeData.State],\r
+           FALSE\r
+           );\r
+}\r
+\r
+/**\r
   Retrieves a Unicode string that is the user readable name of the controller\r
   that is being managed by a driver.\r
 \r
@@ -308,5 +382,56 @@ DhcpComponentNameGetControllerName (
   OUT CHAR16                                          **ControllerName\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  EFI_STATUS                    Status;\r
+  EFI_DHCP4_PROTOCOL            *Dhcp4;\r
+\r
+  //\r
+  // Only provide names for child handles.\r
+  //\r
+  if (ChildHandle == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  \r
+  // \r
+  // Make sure this driver produced ChildHandle \r
+  // \r
+  Status = EfiTestChildHandle (\r
+             ControllerHandle,\r
+             ChildHandle,\r
+             &gEfiUdp4ProtocolGuid\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  // \r
+  // Retrieve an instance of a produced protocol from ChildHandle  \r
+  // \r
+  Status = gBS->OpenProtocol (\r
+                  ChildHandle,\r
+                  &gEfiDhcp4ProtocolGuid,\r
+                  (VOID **)&Dhcp4,\r
+                  NULL,\r
+                  NULL,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Update the component name for this child handle.\r
+  //\r
+  Status = UpdateName (Dhcp4);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return LookupUnicodeString2 (\r
+           Language,\r
+           This->SupportedLanguages,\r
+           gDhcpControllerNameTable,\r
+           ControllerName,\r
+           (BOOLEAN)(This == &gDhcp4ComponentName)\r
+           );\r
 }\r
index 8a773d9..20758d3 100644 (file)
@@ -212,7 +212,6 @@ Dhcp4CreateService (
 \r
   DhcpSb->Signature       = DHCP_SERVICE_SIGNATURE;\r
   DhcpSb->ServiceState    = DHCP_UNCONFIGED;\r
-  DhcpSb->InDestroy       = FALSE;\r
   DhcpSb->Controller      = Controller;\r
   DhcpSb->Image           = ImageHandle;\r
   InitializeListHead (&DhcpSb->Children);\r
@@ -354,6 +353,35 @@ 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
+Dhcp4DestroyChildEntry (\r
+  IN LIST_ENTRY         *Entry,\r
+  IN VOID               *Context\r
+)\r
+{\r
+  DHCP_PROTOCOL                    *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, DHCP_PROTOCOL, Link, DHCP_PROTOCOL_SIGNATURE);\r
+  ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *) Context;\r
+\r
+  return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);\r
+}\r
+\r
 \r
 /**\r
   Stop this driver on ControllerHandle. This service is called by the\r
@@ -384,10 +412,10 @@ Dhcp4DriverBindingStop (
 {\r
   EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;\r
   DHCP_SERVICE                  *DhcpSb;\r
-  DHCP_PROTOCOL                 *Instance;\r
   EFI_HANDLE                    NicHandle;\r
   EFI_STATUS                    Status;\r
-  EFI_TPL                       OldTpl;\r
+  LIST_ENTRY                    *List;\r
+  UINTN                         ListLength;\r
 \r
   //\r
   // DHCP driver opens UDP child, So, the ControllerHandle is the\r
@@ -396,7 +424,7 @@ Dhcp4DriverBindingStop (
   NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp4ProtocolGuid);\r
 \r
   if (NicHandle == NULL) {\r
-    return EFI_DEVICE_ERROR;\r
+    return EFI_SUCCESS;\r
   }\r
 \r
    Status = gBS->OpenProtocol (\r
@@ -413,16 +441,30 @@ Dhcp4DriverBindingStop (
   }\r
 \r
   DhcpSb = DHCP_SERVICE_FROM_THIS (ServiceBinding);\r
-\r
-  if (DhcpSb->InDestroy) {\r
-    return EFI_SUCCESS;\r
+  if (!IsListEmpty (&DhcpSb->Children)) {\r
+    //\r
+    // Destroy all the children instances before destory the service.\r
+    //  \r
+    List = &DhcpSb->Children;\r
+    Status = NetDestroyLinkList (\r
+               List,\r
+               Dhcp4DestroyChildEntry,\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
-\r
-  if (NumberOfChildren == 0) {\r
+  if (NumberOfChildren == 0 && !IsListEmpty (&DhcpSb->Children)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+  }\r
 \r
-    DhcpSb->InDestroy    = TRUE;\r
+  if (NumberOfChildren == 0 && IsListEmpty (&DhcpSb->Children)) {\r
+    //\r
+    // Destroy the service itself if no child instance left.\r
+    //\r
     DhcpSb->ServiceState = DHCP_DESTROY;\r
 \r
     gBS->UninstallProtocolInterface (\r
@@ -433,24 +475,15 @@ Dhcp4DriverBindingStop (
 \r
     Dhcp4CloseService (DhcpSb);\r
 \r
-    FreePool (DhcpSb);\r
-  } else {\r
-    //\r
-    // Don't use NET_LIST_FOR_EACH_SAFE here, Dhcp4ServiceBindingDestroyChild\r
-    // may cause other child to be deleted.\r
-    //\r
-    while (!IsListEmpty (&DhcpSb->Children)) {\r
-      Instance = NET_LIST_HEAD (&DhcpSb->Children, DHCP_PROTOCOL, Link);\r
-      ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);\r
-    }\r
-\r
-    if (DhcpSb->NumChildren != 0) {\r
-      Status = EFI_DEVICE_ERROR;\r
+    if (gDhcpControllerNameTable != NULL) {\r
+      FreeUnicodeStringTable (gDhcpControllerNameTable);\r
+      gDhcpControllerNameTable = NULL;\r
     }\r
+    FreePool (DhcpSb);\r
+    \r
+    Status = EFI_SUCCESS;\r
   }\r
 \r
-  gBS->RestoreTPL (OldTpl);\r
-\r
   return Status;\r
 }\r
 \r
@@ -663,12 +696,13 @@ Dhcp4ServiceBindingDestroyChild (
   //\r
   // Uninstall the DHCP4 protocol first to enable a top down destruction.\r
   //\r
+  gBS->RestoreTPL (OldTpl);\r
   Status = gBS->UninstallProtocolInterface (\r
                   ChildHandle,\r
                   &gEfiDhcp4ProtocolGuid,\r
                   Dhcp\r
                   );\r
-\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
   if (EFI_ERROR (Status)) {\r
     Instance->InDestroy = FALSE;\r
 \r
index b59b741..b4a63ef 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Header for the DHCP4 driver.\r
   \r
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -17,6 +17,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 extern EFI_COMPONENT_NAME_PROTOCOL  gDhcp4ComponentName;\r
 extern EFI_COMPONENT_NAME2_PROTOCOL gDhcp4ComponentName2;\r
+extern EFI_UNICODE_STRING_TABLE     *gDhcpControllerNameTable;\r
 \r
 /**\r
   Test to see if this driver supports ControllerHandle. This service\r
index b9a85f2..41b5e95 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   This file implement the EFI_DHCP4_PROTOCOL interface.\r
 \r
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -1234,6 +1234,8 @@ Dhcp4InstanceCreateUdpIo (
   )\r
 {\r
   DHCP_SERVICE  *DhcpSb;\r
+  EFI_STATUS    Status;\r
+  VOID          *Udp4;\r
 \r
   ASSERT (Instance->Token != NULL);\r
 \r
@@ -1248,7 +1250,19 @@ Dhcp4InstanceCreateUdpIo (
   if (Instance->UdpIo == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   } else {\r
-    return EFI_SUCCESS;\r
+    Status = gBS->OpenProtocol (\r
+                    Instance->UdpIo->UdpHandle,\r
+                    &gEfiUdp4ProtocolGuid,\r
+                    (VOID **) &Udp4,\r
+                    Instance->Service->Image,\r
+                    Instance->Handle,\r
+                    EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      UdpIoFreeIo (Instance->UdpIo);\r
+      Instance->UdpIo = NULL;\r
+    }\r
+    return Status;\r
   }\r
 }\r
 \r
@@ -1416,6 +1430,12 @@ SIGNAL_USER:
   //\r
   NetbufQueFlush (&Instance->ResponseQueue);\r
   UdpIoCleanIo (Instance->UdpIo);\r
+  gBS->CloseProtocol (\r
+         Instance->UdpIo->UdpHandle,\r
+         &gEfiUdp4ProtocolGuid,\r
+         Instance->Service->Image,\r
+         Instance->Handle\r
+         );\r
   UdpIoFreeIo (Instance->UdpIo);\r
   Instance->UdpIo = NULL;\r
   Instance->Token = NULL;\r
@@ -1581,6 +1601,12 @@ ON_ERROR:
 \r
   if (EFI_ERROR (Status) && (Instance->UdpIo != NULL)) {\r
     UdpIoCleanIo (Instance->UdpIo);\r
+    gBS->CloseProtocol (\r
+           Instance->UdpIo->UdpHandle,\r
+           &gEfiUdp4ProtocolGuid,\r
+           Instance->Service->Image,\r
+           Instance->Handle\r
+           );\r
     UdpIoFreeIo (Instance->UdpIo);\r
     Instance->UdpIo = NULL;\r
     Instance->Token = NULL;\r
index 08faff0..44213cf 100644 (file)
@@ -84,7 +84,6 @@ struct _DHCP_SERVICE {
   EFI_SERVICE_BINDING_PROTOCOL  ServiceBinding;\r
 \r
   INTN                          ServiceState; // CONFIGED, UNCONFIGED, and DESTROY\r
-  BOOLEAN                       InDestroy;\r
 \r
   EFI_HANDLE                    Controller;\r
   EFI_HANDLE                    Image;\r
index acb9c07..e88587a 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   UEFI Component Name(2) protocol implementation for iSCSI.\r
 \r
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -37,6 +37,11 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIScsiDriverNameTable[] =
   {NULL, NULL}\r
 };\r
 \r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE  mIScsiControllerNameTable[] = {\r
+  {"eng;en", L"iSCSI (IPv4)"},\r
+  {NULL, NULL}\r
+};\r
+\r
 /**\r
   Retrieves a Unicode string that is the user readable name of the EFI Driver.\r
 \r
@@ -131,5 +136,36 @@ IScsiComponentNameGetControllerName (
   OUT CHAR16                        **ControllerName\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  EFI_HANDLE                      IScsiController;\r
+  ISCSI_PRIVATE_PROTOCOL          *IScsiIdentifier;\r
+  EFI_STATUS                      Status;\r
+  \r
+  //\r
+  // Get the handle of the controller we are controling.\r
+  //\r
+  IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp4ProtocolGuid);\r
+  if (IScsiController == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Status = gBS->OpenProtocol (\r
+                  IScsiController,\r
+                  &gEfiCallerIdGuid,\r
+                  (VOID **)&IScsiIdentifier,\r
+                  NULL,\r
+                  NULL,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  \r
+  return LookupUnicodeString2 (\r
+           Language,\r
+           This->SupportedLanguages,\r
+           mIScsiControllerNameTable,\r
+           ControllerName,\r
+           (BOOLEAN)(This == &gIScsiComponentName)\r
+           );\r
 }\r
+\r
index d3fcf04..2ccfb3c 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
   \r
-Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at<BR>\r
@@ -173,6 +173,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIp4DriverNameTable[] = {
   }\r
 };\r
 \r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE  *gIp4ControllerNameTable = NULL;\r
+\r
 /**\r
   Retrieves a Unicode string that is the user readable name of the driver.\r
 \r
@@ -231,6 +233,74 @@ Ip4ComponentNameGetDriverName (
 }\r
 \r
 /**\r
+  Update the component name for the IP4 child handle.\r
+\r
+  @param  Ip4[in]                 A pointer to the EFI_IP4_PROTOCOL.\r
+\r
+  \r
+  @retval EFI_SUCCESS             Update the ControllerNameTable of this instance successfully.\r
+  @retval EFI_INVALID_PARAMETER   The input parameter is invalid.\r
+  \r
+**/\r
+EFI_STATUS\r
+UpdateName (\r
+  IN     EFI_IP4_PROTOCOL         *Ip4\r
+  )\r
+{\r
+  EFI_STATUS                       Status;\r
+  CHAR16                           HandleName[80];\r
+  EFI_IP4_MODE_DATA                Ip4ModeData;\r
+\r
+  if (Ip4 == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Format the child name into the string buffer as:\r
+  // IPv4 (SrcIP=127.0.0.1, DestIP=127.0.0.1)\r
+  //\r
+  Status = Ip4->GetModeData (Ip4, &Ip4ModeData, NULL, NULL);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  if (!Ip4ModeData.IsStarted || !Ip4ModeData.IsConfigured) {\r
+    UnicodeSPrint (HandleName, sizeof (HandleName), L"IPv4 (Not started)");\r
+  } else {\r
+    UnicodeSPrint (HandleName, sizeof (HandleName),\r
+      L"IPv4 (SrcIP=%d.%d.%d.%d)",\r
+      Ip4ModeData.ConfigData.StationAddress.Addr[0],\r
+      Ip4ModeData.ConfigData.StationAddress.Addr[1],\r
+      Ip4ModeData.ConfigData.StationAddress.Addr[2],\r
+      Ip4ModeData.ConfigData.StationAddress.Addr[3]\r
+      );\r
+  }\r
+\r
+  if (gIp4ControllerNameTable != NULL) {\r
+    FreeUnicodeStringTable (gIp4ControllerNameTable);\r
+    gIp4ControllerNameTable = NULL;\r
+  }\r
+  Status = AddUnicodeString2 (\r
+             "eng",\r
+             gIp4ComponentName.SupportedLanguages,\r
+             &gIp4ControllerNameTable,\r
+             HandleName,\r
+             TRUE\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  \r
+  return AddUnicodeString2 (\r
+           "en",\r
+           gIp4ComponentName2.SupportedLanguages,\r
+           &gIp4ControllerNameTable,\r
+           HandleName,\r
+           FALSE\r
+           );\r
+}\r
+\r
+/**\r
   Retrieves a Unicode string that is the user readable name of the controller\r
   that is being managed by a driver.\r
 \r
@@ -308,5 +378,57 @@ Ip4ComponentNameGetControllerName (
   OUT CHAR16                                          **ControllerName\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  EFI_STATUS                    Status;  \r
+  EFI_IP4_PROTOCOL              *Ip4;\r
+  \r
+  //\r
+  // Only provide names for child handles.\r
+  //\r
+  if (ChildHandle == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  // \r
+  // Make sure this driver produced ChildHandle \r
+  // \r
+  Status = EfiTestChildHandle (\r
+             ControllerHandle,\r
+             ChildHandle,\r
+             &gEfiManagedNetworkProtocolGuid\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  // \r
+  // Retrieve an instance of a produced protocol from ChildHandle  \r
+  // \r
+  Status = gBS->OpenProtocol (\r
+                  ChildHandle,\r
+                  &gEfiIp4ProtocolGuid,\r
+                  (VOID **)&Ip4,\r
+                  NULL,\r
+                  NULL,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Update the component name for this child handle.\r
+  //\r
+  Status = UpdateName (Ip4);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return LookupUnicodeString2 (\r
+           Language,\r
+           This->SupportedLanguages,\r
+           gIp4ControllerNameTable,\r
+           ControllerName,\r
+           (BOOLEAN)(This == &gIp4ComponentName)\r
+           );\r
 }\r
+\r
index 295f822..6404930 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Common definition for IP4.\r
   \r
-Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -63,6 +63,9 @@ typedef struct _IP4_SERVICE    IP4_SERVICE;
 #define IP4_FIRST_FRAGMENT(FragmentField) \\r
           ((BOOLEAN)(((FragmentField) & IP4_HEAD_OFFSET_MASK) == 0))\r
 \r
+#define IP4_DO_NOT_FRAGMENT(FragmentField) \\r
+          ((BOOLEAN)(((FragmentField) & IP4_HEAD_DF_MASK) == IP4_HEAD_DF_MASK))\r
+\r
 #define IP4_IS_BROADCAST(CastType) ((CastType) >= IP4_LOCAL_BROADCAST)\r
 \r
 ///\r
index 4ce85a3..5a84837 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
index 96044fd..32984ba 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 \r
-Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -19,6 +19,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 extern EFI_DRIVER_BINDING_PROTOCOL   gIp4DriverBinding;\r
 extern EFI_COMPONENT_NAME_PROTOCOL   gIp4ComponentName;\r
 extern EFI_COMPONENT_NAME2_PROTOCOL  gIp4ComponentName2;\r
+extern EFI_UNICODE_STRING_TABLE      *gIp4ControllerNameTable;\r
+\r
+typedef struct {\r
+  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;\r
+  UINTN                         NumberOfChildren;\r
+  EFI_HANDLE                    *ChildHandleBuffer;\r
+} IP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT;\r
 \r
 //\r
 // Function prototype for the driver's entry point\r
index 18cb9ff..e5e2b98 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 \r
-Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -193,7 +193,7 @@ Ip4ProcessIcmpError (
   }\r
 \r
   IP4_GET_CLIP_INFO (Packet)->Status = EFI_ICMP_ERROR;\r
-  return Ip4Demultiplex (IpSb, Head, Packet);\r
+  return Ip4Demultiplex (IpSb, Head, Packet, NULL, 0);\r
 }\r
 \r
 \r
@@ -308,7 +308,7 @@ Ip4ProcessIcmpQuery (
     return Ip4IcmpReplyEcho (IpSb, Head, Packet);\r
   }\r
 \r
-  return Ip4Demultiplex (IpSb, Head, Packet);\r
+  return Ip4Demultiplex (IpSb, Head, Packet, NULL, 0);\r
 }\r
 \r
 \r
index f4ce3ea..74bf7f7 100644 (file)
@@ -868,6 +868,7 @@ Ip4ConfigProtocol (
   EFI_STATUS                Status;\r
   IP4_ADDR                  Ip;\r
   IP4_ADDR                  Netmask;\r
+  EFI_ARP_PROTOCOL          *Arp;\r
 \r
   IpSb = IpInstance->Service;\r
 \r
@@ -972,6 +973,20 @@ Ip4ConfigProtocol (
   }\r
 \r
   IpInstance->Interface = IpIf;\r
+  if (IpIf->Arp != NULL) {\r
+    Arp = NULL;\r
+    Status = gBS->OpenProtocol (\r
+                    IpIf->ArpHandle,\r
+                    &gEfiArpProtocolGuid,\r
+                    (VOID **) &Arp,\r
+                    gIp4DriverBinding.DriverBindingHandle,\r
+                    IpInstance->Handle,\r
+                    EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      goto ON_ERROR;\r
+    }\r
+  }\r
   InsertTailList (&IpIf->IpInstances, &IpInstance->AddrLink);\r
 \r
   CopyMem (&IpInstance->ConfigData, Config, sizeof (IpInstance->ConfigData));\r
@@ -1028,6 +1043,14 @@ Ip4CleanProtocol (
 \r
   if (IpInstance->Interface != NULL) {\r
     RemoveEntryList (&IpInstance->AddrLink);\r
+    if (IpInstance->Interface->Arp != NULL) {\r
+      gBS->CloseProtocol (\r
+             IpInstance->Interface->ArpHandle,\r
+             &gEfiArpProtocolGuid,\r
+             gIp4DriverBinding.DriverBindingHandle,\r
+             IpInstance->Handle\r
+             );\r
+    }\r
     Ip4FreeInterface (IpInstance->Interface, IpInstance);\r
     IpInstance->Interface = NULL;\r
   }\r
@@ -1193,14 +1216,6 @@ EfiIp4Configure (
   // Validate the configuration first.\r
   //\r
   if (IpConfigData != NULL) {\r
-    //\r
-    // This implementation doesn't support RawData\r
-    //\r
-    if (IpConfigData->RawData) {\r
-      Status = EFI_UNSUPPORTED;\r
-      goto ON_EXIT;\r
-    }\r
-\r
 \r
     CopyMem (&IpAddress, &IpConfigData->StationAddress, sizeof (IP4_ADDR));\r
     CopyMem (&SubnetMask, &IpConfigData->SubnetMask, sizeof (IP4_ADDR));\r
@@ -1620,22 +1635,23 @@ Ip4TokenExist (
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   Validate the user's token against current station address.\r
 \r
-  @param[in]  Token                  User's token to validate\r
-  @param[in]  IpIf                   The IP4 child's interface.\r
+  @param[in]  Token              User's token to validate.\r
+  @param[in]  IpIf               The IP4 child's interface.\r
+  @param[in]  RawData            Set to TRUE to send unformatted packets.\r
 \r
-  @retval EFI_INVALID_PARAMETER  Some parameters are invalid\r
+  @retval EFI_INVALID_PARAMETER  Some parameters are invalid.\r
   @retval EFI_BAD_BUFFER_SIZE    The user's option/data is too long.\r
-  @retval EFI_SUCCESS            The token is OK\r
+  @retval EFI_SUCCESS            The token is valid.\r
 \r
 **/\r
 EFI_STATUS\r
 Ip4TxTokenValid (\r
   IN EFI_IP4_COMPLETION_TOKEN   *Token,\r
-  IN IP4_INTERFACE              *IpIf\r
+  IN IP4_INTERFACE              *IpIf,\r
+  IN BOOLEAN                    RawData\r
   )\r
 {\r
   EFI_IP4_TRANSMIT_DATA     *TxData;\r
@@ -1653,20 +1669,7 @@ Ip4TxTokenValid (
   TxData = Token->Packet.TxData;\r
 \r
   //\r
-  // Check the IP options: no more than 40 bytes and format is OK\r
-  //\r
-  if (TxData->OptionsLength != 0) {\r
-    if ((TxData->OptionsLength > 40) || (TxData->OptionsBuffer == NULL)) {\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-\r
-    if (!Ip4OptionIsValid (TxData->OptionsBuffer, TxData->OptionsLength, FALSE)) {\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Check the fragment table: no empty fragment, and length isn't bogus\r
+  // Check the fragment table: no empty fragment, and length isn't bogus.\r
   //\r
   if ((TxData->TotalDataLength == 0) || (TxData->FragmentCount == 0)) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -1674,6 +1677,10 @@ Ip4TxTokenValid (
 \r
   Offset = TxData->TotalDataLength;\r
 \r
+  if (Offset > IP4_MAX_PACKET_SIZE) {\r
+    return EFI_BAD_BUFFER_SIZE;\r
+  }\r
+\r
   for (Index = 0; Index < TxData->FragmentCount; Index++) {\r
     if ((TxData->FragmentTable[Index].FragmentBuffer == NULL) ||\r
         (TxData->FragmentTable[Index].FragmentLength == 0)) {\r
@@ -1689,6 +1696,27 @@ Ip4TxTokenValid (
   }\r
 \r
   //\r
+  // NOTE that OptionsLength/OptionsBuffer/OverrideData are ignored if RawData\r
+  // is TRUE.\r
+  //\r
+  if (RawData) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // Check the IP options: no more than 40 bytes and format is OK\r
+  //\r
+  if (TxData->OptionsLength != 0) {\r
+    if ((TxData->OptionsLength > 40) || (TxData->OptionsBuffer == NULL)) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    if (!Ip4OptionIsValid (TxData->OptionsBuffer, TxData->OptionsLength, FALSE)) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+\r
+  //\r
   // Check the source and gateway: they must be a valid unicast.\r
   // Gateway must also be on the connected network.\r
   //\r
@@ -1888,6 +1916,10 @@ EfiIp4Transmit (
   EFI_TPL                   OldTpl;\r
   BOOLEAN                   DontFragment;\r
   UINT32                    HeadLen;\r
+  UINT8                     RawHdrLen;\r
+  UINT32                    OptionsLength;\r
+  UINT8                     *OptionsBuffer;\r
+  VOID                      *FirstFragment;\r
 \r
   if (This == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -1913,7 +1945,7 @@ EfiIp4Transmit (
   //\r
   // make sure that token is properly formated\r
   //\r
-  Status = Ip4TxTokenValid (Token, IpIf);\r
+  Status = Ip4TxTokenValid (Token, IpIf, Config->RawData);\r
 \r
   if (EFI_ERROR (Status)) {\r
     goto ON_EXIT;\r
@@ -1933,32 +1965,82 @@ EfiIp4Transmit (
   //\r
   TxData = Token->Packet.TxData;\r
 \r
-  CopyMem (&Head.Dst, &TxData->DestinationAddress, sizeof (IP4_ADDR));\r
-  Head.Dst = NTOHL (Head.Dst);\r
+  FirstFragment = NULL;\r
 \r
-  if (TxData->OverrideData != NULL) {\r
-    Override      = TxData->OverrideData;\r
-    Head.Protocol = Override->Protocol;\r
-    Head.Tos      = Override->TypeOfService;\r
-    Head.Ttl      = Override->TimeToLive;\r
-    DontFragment  = Override->DoNotFragment;\r
+  if (Config->RawData) {\r
+    //\r
+    // When RawData is TRUE, first buffer in FragmentTable points to a raw\r
+    // IPv4 fragment including IPv4 header and options.\r
+    //\r
+    FirstFragment = TxData->FragmentTable[0].FragmentBuffer;\r
+    CopyMem (&RawHdrLen, FirstFragment, sizeof (UINT8));\r
 \r
-    CopyMem (&Head.Src, &Override->SourceAddress, sizeof (IP4_ADDR));\r
-    CopyMem (&GateWay, &Override->GatewayAddress, sizeof (IP4_ADDR));\r
+    RawHdrLen = (UINT8) (RawHdrLen & 0x0f);\r
+    if (RawHdrLen < 5) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    RawHdrLen = (UINT8) (RawHdrLen << 2);\r
+    \r
+    CopyMem (&Head, FirstFragment, IP4_MIN_HEADLEN);\r
+\r
+    Ip4NtohHead (&Head);\r
+    HeadLen      = 0;\r
+    DontFragment = IP4_DO_NOT_FRAGMENT (Head.Fragment);\r
 \r
-    Head.Src = NTOHL (Head.Src);\r
-    GateWay  = NTOHL (GateWay);\r
+    if (!DontFragment) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    GateWay = IP4_ALLZERO_ADDRESS;\r
+\r
+    //\r
+    // Get IPv4 options from first fragment.\r
+    //\r
+    if (RawHdrLen == IP4_MIN_HEADLEN) {\r
+      OptionsLength = 0;\r
+      OptionsBuffer = NULL;\r
+    } else {\r
+      OptionsLength = RawHdrLen - IP4_MIN_HEADLEN;\r
+      OptionsBuffer = (UINT8 *) FirstFragment + IP4_MIN_HEADLEN;\r
+    }\r
+\r
+    //\r
+    // Trim off IPv4 header and options from first fragment.\r
+    //\r
+    TxData->FragmentTable[0].FragmentBuffer = (UINT8 *) FirstFragment + RawHdrLen;\r
+    TxData->FragmentTable[0].FragmentLength = TxData->FragmentTable[0].FragmentLength - RawHdrLen;\r
   } else {\r
-    Head.Src      = IpIf->Ip;\r
-    GateWay       = IP4_ALLZERO_ADDRESS;\r
-    Head.Protocol = Config->DefaultProtocol;\r
-    Head.Tos      = Config->TypeOfService;\r
-    Head.Ttl      = Config->TimeToLive;\r
-    DontFragment  = Config->DoNotFragment;\r
-  }\r
+    CopyMem (&Head.Dst, &TxData->DestinationAddress, sizeof (IP4_ADDR));\r
+    Head.Dst = NTOHL (Head.Dst);\r
 \r
-  Head.Fragment = IP4_HEAD_FRAGMENT_FIELD (DontFragment, FALSE, 0);\r
-  HeadLen       = (TxData->OptionsLength + 3) & (~0x03);\r
+    if (TxData->OverrideData != NULL) {\r
+      Override      = TxData->OverrideData;\r
+      Head.Protocol = Override->Protocol;\r
+      Head.Tos      = Override->TypeOfService;\r
+      Head.Ttl      = Override->TimeToLive;\r
+      DontFragment  = Override->DoNotFragment;\r
+\r
+      CopyMem (&Head.Src, &Override->SourceAddress, sizeof (IP4_ADDR));\r
+      CopyMem (&GateWay, &Override->GatewayAddress, sizeof (IP4_ADDR));\r
+\r
+      Head.Src = NTOHL (Head.Src);\r
+      GateWay  = NTOHL (GateWay);\r
+    } else {\r
+      Head.Src      = IpIf->Ip;\r
+      GateWay       = IP4_ALLZERO_ADDRESS;\r
+      Head.Protocol = Config->DefaultProtocol;\r
+      Head.Tos      = Config->TypeOfService;\r
+      Head.Ttl      = Config->TimeToLive;\r
+      DontFragment  = Config->DoNotFragment;\r
+    }\r
+\r
+    Head.Fragment = IP4_HEAD_FRAGMENT_FIELD (DontFragment, FALSE, 0);\r
+    HeadLen       = (TxData->OptionsLength + 3) & (~0x03);\r
+\r
+    OptionsLength = TxData->OptionsLength;\r
+    OptionsBuffer = (UINT8 *) (TxData->OptionsBuffer);\r
+  }\r
 \r
   //\r
   // If don't fragment and fragment needed, return error\r
@@ -2004,6 +2086,13 @@ EfiIp4Transmit (
     // free the IP4_TXTOKEN_WRAP. Now, the token wrap hasn't been\r
     // enqueued.\r
     //\r
+    if (Config->RawData) {\r
+      //\r
+      // Restore pointer of first fragment in RawData mode.\r
+      //\r
+      TxData->FragmentTable[0].FragmentBuffer = (UINT8 *) FirstFragment;\r
+    }\r
+\r
     NetbufFree (Wrap->Packet);\r
     goto ON_EXIT;\r
   }\r
@@ -2019,8 +2108,8 @@ EfiIp4Transmit (
              IpInstance,\r
              Wrap->Packet,\r
              &Head,\r
-             TxData->OptionsBuffer,\r
-             TxData->OptionsLength,\r
+             OptionsBuffer,\r
+             OptionsLength,\r
              GateWay,\r
              Ip4OnPacketSent,\r
              Wrap\r
@@ -2028,9 +2117,24 @@ EfiIp4Transmit (
 \r
   if (EFI_ERROR (Status)) {\r
     Wrap->Sent = FALSE;\r
+\r
+    if (Config->RawData) {\r
+      //\r
+      // Restore pointer of first fragment in RawData mode.\r
+      //\r
+      TxData->FragmentTable[0].FragmentBuffer = (UINT8 *) FirstFragment;\r
+    }\r
+\r
     NetbufFree (Wrap->Packet);\r
   }\r
 \r
+  if (Config->RawData) {\r
+    //\r
+    // Restore pointer of first fragment in RawData mode.\r
+    //\r
+    TxData->FragmentTable[0].FragmentBuffer = (UINT8 *) FirstFragment;\r
+  }\r
+\r
 ON_EXIT:\r
   gBS->RestoreTPL (OldTpl);\r
   return Status;\r
index 563cf7f..ad8a927 100644 (file)
@@ -33,6 +33,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/DpcLib.h>\r
+#include <Library/PrintLib.h>\r
 \r
 #include "Ip4Common.h"\r
 #include "Ip4Driver.h"\r
@@ -160,7 +161,6 @@ struct _IP4_SERVICE {
   UINT32                          Signature;\r
   EFI_SERVICE_BINDING_PROTOCOL    ServiceBinding;\r
   INTN                            State;\r
-  BOOLEAN                         InDestroy;\r
 \r
   //\r
   // List of all the IP instances and interfaces, and default\r
index d985b1a..62163f4 100644 (file)
@@ -714,7 +714,7 @@ Ip4PreProcessPacket (
   UINT16                    Checksum;\r
 \r
   //\r
-  // Check that the IP4 header is correctly formatted\r
+  // Check if the IP4 header is correctly formatted.\r
   //\r
   if ((*Packet)->TotalSize < IP4_MIN_HEADLEN) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -774,7 +774,7 @@ Ip4PreProcessPacket (
   }\r
 \r
   //\r
-  // Trim the head off, after this point, the packet is headless.\r
+  // Trim the head off, after this point, the packet is headless,\r
   // and Packet->TotalLen == Info->Length.\r
   //\r
   NetbufTrim (*Packet, HeadLen, TRUE);\r
@@ -928,7 +928,7 @@ Ip4AccpetFrame (
     break;\r
 \r
   default:\r
-    Ip4Demultiplex (IpSb, Head, Packet);\r
+    Ip4Demultiplex (IpSb, Head, Packet, Option, OptionLen);\r
   }\r
 \r
   Packet = NULL;\r
@@ -1151,8 +1151,8 @@ Ip4OnRecyclePacket (
   to the upper layer. Upper layer will signal the recycle event in\r
   it when it is done with the packet.\r
 \r
-  @param[in]  IpInstance             The IP4 child to receive the packet\r
-  @param[in]  Packet                 The packet to deliver up.\r
+  @param[in]  IpInstance    The IP4 child to receive the packet.\r
+  @param[in]  Packet        The packet to deliver up.\r
 \r
   @retval Wrap              if warp the packet succeed.\r
   @retval NULL              failed to wrap the packet .\r
@@ -1167,6 +1167,7 @@ Ip4WrapRxData (
   IP4_RXDATA_WRAP           *Wrap;\r
   EFI_IP4_RECEIVE_DATA      *RxData;\r
   EFI_STATUS                Status;\r
+  BOOLEAN                   RawData;\r
 \r
   Wrap = AllocatePool (IP4_RXDATA_WRAP_SIZE (Packet->BlockOpNum));\r
 \r
@@ -1180,7 +1181,7 @@ Ip4WrapRxData (
   Wrap->Packet      = Packet;\r
   RxData            = &Wrap->RxData;\r
 \r
-  ZeroMem (&RxData->TimeStamp, sizeof (EFI_TIME));\r
+  ZeroMem (RxData, sizeof (EFI_IP4_RECEIVE_DATA));\r
 \r
   Status = gBS->CreateEvent (\r
                   EVT_NOTIFY_SIGNAL,\r
@@ -1197,17 +1198,21 @@ Ip4WrapRxData (
 \r
   ASSERT (Packet->Ip.Ip4 != NULL);\r
 \r
+  ASSERT (IpInstance != NULL);\r
+  RawData = IpInstance->ConfigData.RawData;\r
+\r
   //\r
   // The application expects a network byte order header.\r
   //\r
-  RxData->HeaderLength  = (Packet->Ip.Ip4->HeadLen << 2);\r
-  RxData->Header        = (EFI_IP4_HEADER *) Ip4NtohHead (Packet->Ip.Ip4);\r
-\r
-  RxData->OptionsLength = RxData->HeaderLength - IP4_MIN_HEADLEN;\r
-  RxData->Options       = NULL;\r
+  if (!RawData) {\r
+    RxData->HeaderLength  = (Packet->Ip.Ip4->HeadLen << 2);\r
+    RxData->Header        = (EFI_IP4_HEADER *) Ip4NtohHead (Packet->Ip.Ip4);\r
+    RxData->OptionsLength = RxData->HeaderLength - IP4_MIN_HEADLEN;\r
+    RxData->Options       = NULL;\r
 \r
-  if (RxData->OptionsLength != 0) {\r
-    RxData->Options = (VOID *) (RxData->Header + 1);\r
+    if (RxData->OptionsLength != 0) {\r
+      RxData->Options = (VOID *) (RxData->Header + 1);\r
+    }\r
   }\r
 \r
   RxData->DataLength  = Packet->TotalSize;\r
@@ -1246,6 +1251,7 @@ Ip4InstanceDeliverPacket (
   NET_BUF                   *Packet;\r
   NET_BUF                   *Dup;\r
   UINT8                     *Head;\r
+  UINT32                    HeadLen;\r
 \r
   //\r
   // Deliver a packet if there are both a packet and a receive token.\r
@@ -1271,24 +1277,32 @@ Ip4InstanceDeliverPacket (
       //\r
       // Create a duplicated packet if this packet is shared\r
       //\r
-      Dup = NetbufDuplicate (Packet, NULL, IP4_MAX_HEADLEN);\r
+      if (IpInstance->ConfigData.RawData) {\r
+        HeadLen = 0;\r
+      } else {\r
+        HeadLen = IP4_MAX_HEADLEN;\r
+      }\r
+\r
+      Dup = NetbufDuplicate (Packet, NULL, HeadLen);\r
 \r
       if (Dup == NULL) {\r
         return EFI_OUT_OF_RESOURCES;\r
       }\r
 \r
-      //\r
-      // Copy the IP head over. The packet to deliver up is\r
-      // headless. Trim the head off after copy. The IP head\r
-      // may be not continuous before the data.\r
-      //\r
-      Head = NetbufAllocSpace (Dup, IP4_MAX_HEADLEN, NET_BUF_HEAD);\r
-      ASSERT (Head != NULL);\r
-      \r
-      Dup->Ip.Ip4 = (IP4_HEAD *) Head;\r
-\r
-      CopyMem (Head, Packet->Ip.Ip4, Packet->Ip.Ip4->HeadLen << 2);\r
-      NetbufTrim (Dup, IP4_MAX_HEADLEN, TRUE);\r
+      if (!IpInstance->ConfigData.RawData) {\r
+        //\r
+        // Copy the IP head over. The packet to deliver up is\r
+        // headless. Trim the head off after copy. The IP head\r
+        // may be not continuous before the data.\r
+        //\r
+        Head = NetbufAllocSpace (Dup, IP4_MAX_HEADLEN, NET_BUF_HEAD);\r
+        ASSERT (Head != NULL);\r
+        \r
+        Dup->Ip.Ip4 = (IP4_HEAD *) Head;\r
+\r
+        CopyMem (Head, Packet->Ip.Ip4, Packet->Ip.Ip4->HeadLen << 2);\r
+        NetbufTrim (Dup, IP4_MAX_HEADLEN, TRUE);\r
+      }\r
 \r
       Wrap = Ip4WrapRxData (IpInstance, Dup);\r
 \r
@@ -1326,10 +1340,12 @@ Ip4InstanceDeliverPacket (
   Enqueue a received packet to all the IP children that share\r
   the same interface.\r
 \r
-  @param[in]  IpSb                   The IP4 service instance that receive the packet\r
-  @param[in]  Head                   The header of the received packet\r
-  @param[in]  Packet                 The data of the received packet\r
-  @param[in]  IpIf                   The interface to enqueue the packet to\r
+  @param[in]  IpSb               The IP4 service instance that receive the packet.\r
+  @param[in]  Head               The header of the received packet.\r
+  @param[in]  Packet             The data of the received packet.\r
+  @param[in]  Option             Point to the IP4 packet header options.\r
+  @param[in]  OptionLen          Length of the IP4 packet header options.  \r
+  @param[in]  IpIf               The interface to enqueue the packet to.\r
 \r
   @return The number of the IP4 children that accepts the packet\r
 \r
@@ -1339,6 +1355,8 @@ Ip4InterfaceEnquePacket (
   IN IP4_SERVICE            *IpSb,\r
   IN IP4_HEAD               *Head,\r
   IN NET_BUF                *Packet,\r
+  IN UINT8                  *Option,\r
+  IN UINT32                 OptionLen,\r
   IN IP4_INTERFACE          *IpIf\r
   )\r
 {\r
@@ -1404,6 +1422,13 @@ Ip4InterfaceEnquePacket (
     IpInstance = NET_LIST_USER_STRUCT (Entry, IP4_PROTOCOL, AddrLink);\r
     NET_CHECK_SIGNATURE (IpInstance, IP4_PROTOCOL_SIGNATURE);\r
 \r
+    //\r
+    // In RawData mode, add IPv4 headers and options back to packet.\r
+    //\r
+    if ((IpInstance->ConfigData.RawData) && (Option != NULL) && (OptionLen != 0)){\r
+      Ip4PrependHead (Packet, Head, Option, OptionLen);\r
+    }\r
+\r
     if (Ip4InstanceEnquePacket (IpInstance, Head, Packet) == EFI_SUCCESS) {\r
       Enqueued++;\r
     }\r
@@ -1450,11 +1475,13 @@ Ip4InterfaceDeliverPacket (
   child wants to consume the packet because each IP child needs\r
   its own copy of the packet to make changes.\r
 \r
-  @param[in]  IpSb                   The IP4 service instance that received the packet\r
-  @param[in]  Head                   The header of the received packet\r
-  @param[in]  Packet                 The data of the received packet\r
+  @param[in]  IpSb               The IP4 service instance that received the packet.\r
+  @param[in]  Head               The header of the received packet.\r
+  @param[in]  Packet             The data of the received packet.\r
+  @param[in]  Option             Point to the IP4 packet header options.\r
+  @param[in]  OptionLen          Length of the IP4 packet header options.\r
 \r
-  @retval EFI_NOT_FOUND          No IP child accepts the packet\r
+  @retval EFI_NOT_FOUND          No IP child accepts the packet.\r
   @retval EFI_SUCCESS            The packet is enqueued or delivered to some IP\r
                                  children.\r
 \r
@@ -1463,7 +1490,9 @@ EFI_STATUS
 Ip4Demultiplex (\r
   IN IP4_SERVICE            *IpSb,\r
   IN IP4_HEAD               *Head,\r
-  IN NET_BUF                *Packet\r
+  IN NET_BUF                *Packet,\r
+  IN UINT8                  *Option,\r
+  IN UINT32                 OptionLen\r
   )\r
 {\r
   LIST_ENTRY                *Entry;\r
@@ -1480,7 +1509,14 @@ Ip4Demultiplex (
     IpIf = NET_LIST_USER_STRUCT (Entry, IP4_INTERFACE, Link);\r
 \r
     if (IpIf->Configured) {\r
-      Enqueued += Ip4InterfaceEnquePacket (IpSb, Head, Packet, IpIf);\r
+      Enqueued += Ip4InterfaceEnquePacket (\r
+                    IpSb,\r
+                    Head,\r
+                    Packet,\r
+                    Option,\r
+                    OptionLen,\r
+                    IpIf\r
+                    );\r
     }\r
   }\r
 \r
index fda4d18..1c8e8b2 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 \r
-Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -141,11 +141,13 @@ Ip4AccpetFrame (
   child wants to consume the packet because each IP child needs\r
   its own copy of the packet to make changes.\r
 \r
-  @param[in]  IpSb                   The IP4 service instance that received the packet\r
-  @param[in]  Head                   The header of the received packet\r
-  @param[in]  Packet                 The data of the received packet\r
+  @param[in]  IpSb               The IP4 service instance that received the packet.\r
+  @param[in]  Head               The header of the received packet.\r
+  @param[in]  Packet             The data of the received packet.\r
+  @param[in]  Option             Point to the IP4 packet header options.\r
+  @param[in]  OptionLen          Length of the IP4 packet header options.\r
 \r
-  @retval EFI_NOT_FOUND          No IP child accepts the packet\r
+  @retval EFI_NOT_FOUND          No IP child accepts the packet.\r
   @retval EFI_SUCCESS            The packet is enqueued or delivered to some IP\r
                                  children.\r
 \r
@@ -154,17 +156,21 @@ EFI_STATUS
 Ip4Demultiplex (\r
   IN IP4_SERVICE            *IpSb,\r
   IN IP4_HEAD               *Head,\r
-  IN NET_BUF                *Packet\r
+  IN NET_BUF                *Packet,\r
+  IN UINT8                  *Option,\r
+  IN UINT32                 OptionLen\r
   );\r
 \r
 /**\r
   Enqueue a received packet to all the IP children that share\r
   the same interface.\r
 \r
-  @param[in]  IpSb                   The IP4 service instance that receive the packet\r
-  @param[in]  Head                   The header of the received packet\r
-  @param[in]  Packet                 The data of the received packet\r
-  @param[in]  IpIf                   The interface to enqueue the packet to\r
+  @param[in]  IpSb               The IP4 service instance that receive the packet.\r
+  @param[in]  Head               The header of the received packet.\r
+  @param[in]  Packet             The data of the received packet.\r
+  @param[in]  Option             Point to the IP4 packet header options.\r
+  @param[in]  OptionLen          Length of the IP4 packet header options.  \r
+  @param[in]  IpIf               The interface to enqueue the packet to.\r
 \r
   @return The number of the IP4 children that accepts the packet\r
 \r
@@ -174,6 +180,8 @@ Ip4InterfaceEnquePacket (
   IN IP4_SERVICE            *IpSb,\r
   IN IP4_HEAD               *Head,\r
   IN NET_BUF                *Packet,\r
+  IN UINT8                  *Option,\r
+  IN UINT32                 OptionLen,\r
   IN IP4_INTERFACE          *IpIf\r
   );\r
 \r
index 85dffe0..7ff17b6 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Transmit the IP4 packet.\r
   \r
-Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -204,6 +204,10 @@ Ip4SysPacketSent (
   @retval EFI_NO_MAPPING       There is no interface to the destination.\r
   @retval EFI_NOT_FOUND        There is no route to the destination\r
   @retval EFI_SUCCESS          The packet is successfully transmitted.\r
+  @retval EFI_BAD_BUFFER_SIZE  The length of the IPv4 header + option length +\r
+                               total data length is greater than MTU (or greater\r
+                               than the maximum packet size if Token.Packet.TxData.\r
+                               OverrideData.DoNotFragment is TRUE.)\r
   @retval Others               Failed to transmit the packet.\r
 \r
 **/\r
@@ -231,6 +235,7 @@ Ip4Output (
   UINT32                    Offset;\r
   UINT32                    Mtu;\r
   UINT32                    Num;\r
+  BOOLEAN                   RawData;\r
 \r
   //\r
   // Select an interface/source for system packet, application\r
@@ -252,11 +257,18 @@ Ip4Output (
 \r
   //\r
   // Before IPsec process, prepared the IP head.\r
+  // If Ip4Output is transmitting RawData, don't update IPv4 header.\r
   //\r
-  HeadLen        = sizeof (IP4_HEAD) + ((OptLen + 3) & (~0x03));\r
-  Head->HeadLen  = (UINT8) (HeadLen >> 2);\r
-  Head->Id       = mIp4Id++;\r
-  Head->Ver      = 4;\r
+  HeadLen = sizeof (IP4_HEAD) + ((OptLen + 3) & (~0x03));\r
+\r
+  if ((IpInstance != NULL) && IpInstance->ConfigData.RawData) {\r
+    RawData        = TRUE;\r
+  } else {\r
+    Head->HeadLen  = (UINT8) (HeadLen >> 2);\r
+    Head->Id       = mIp4Id++;\r
+    Head->Ver      = 4;\r
+    RawData        = FALSE;\r
+  }\r
   \r
   //\r
   // Call IPsec process.\r
@@ -324,6 +336,13 @@ Ip4Output (
 \r
   if (Packet->TotalSize + HeadLen > Mtu) {\r
     //\r
+    // Fragmentation is diabled for RawData mode.\r
+    //\r
+    if (RawData) {\r
+      return EFI_BAD_BUFFER_SIZE;\r
+    }\r
+    \r
+    //\r
     // Packet is fragmented from the tail to the head, that is, the\r
     // first frame sent is the last fragment of the packet. The first\r
     // fragment is NOT sent in this loop. First compute how many\r
index c56ad06..9e66dc2 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   UEFI Component Name(2) protocol implementation for MnpDxe driver.\r
 \r
-Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions\r
 of the BSD License which accompanies this distribution.  The full\r
@@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 **/\r
 \r
-#include  "MnpDriver.h"\r
+#include  "MnpImpl.h"\r
 \r
 //\r
 // EFI Component Name Protocol\r
@@ -44,6 +44,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE      mMnpDriverNameTable[
   }\r
 };\r
 \r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE    *gMnpControllerNameTable = NULL;\r
+\r
 /**\r
   Retrieves a Unicode string that is the user readable name of the driver.\r
 \r
@@ -101,6 +103,106 @@ MnpComponentNameGetDriverName (
 }\r
 \r
 /**\r
+  Update the component name for the MNP child handle.\r
+\r
+  @param  Mnp[in]                 A pointer to the EFI_MANAGED_NETWORK_PROTOCOL.\r
+\r
+  \r
+  @retval EFI_SUCCESS             Update the ControllerNameTable of this instance successfully.\r
+  @retval EFI_INVALID_PARAMETER   The input parameter is invalid.\r
+  \r
+**/\r
+EFI_STATUS\r
+UpdateName (\r
+  IN   EFI_MANAGED_NETWORK_PROTOCOL     *Mnp\r
+  )\r
+{\r
+  EFI_STATUS                       Status;\r
+  MNP_INSTANCE_DATA                *Instance;\r
+  CHAR16                           HandleName[80];\r
+  EFI_MANAGED_NETWORK_CONFIG_DATA  MnpConfigData;\r
+  EFI_SIMPLE_NETWORK_MODE          SnpModeData;\r
+  UINTN                            OffSet;\r
+  UINTN                            Index;\r
+\r
+  if (Mnp == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Instance = MNP_INSTANCE_DATA_FROM_THIS (Mnp);\r
+  //\r
+  // Format the child name into the string buffer as:\r
+  // MNP (MAC=FF-FF-FF-FF-FF-FF, ProtocolType=0x0800, VlanId=0)\r
+  //\r
+  Status = Mnp->GetModeData (Mnp, &MnpConfigData, &SnpModeData);\r
+  if (!EFI_ERROR (Status)) {\r
+    OffSet = 0;\r
+    //\r
+    // Print the MAC address.\r
+    //\r
+    OffSet += UnicodeSPrint (\r
+                HandleName,\r
+                sizeof (HandleName),\r
+                L"MNP (MAC="\r
+                );\r
+    for (Index = 0; Index < SnpModeData.HwAddressSize; Index++) {\r
+      OffSet += UnicodeSPrint (\r
+                  HandleName + OffSet,\r
+                  sizeof (HandleName) - OffSet,\r
+                  L"%02X-",\r
+                  SnpModeData.CurrentAddress.Addr[Index]\r
+                  );\r
+    }\r
+    //\r
+    // Remove the last '-'\r
+    //\r
+    OffSet--;  \r
+    //\r
+    // Print the ProtocolType and VLAN ID for this instance.\r
+    //\r
+    OffSet += UnicodeSPrint (\r
+                HandleName + OffSet,\r
+                sizeof (HandleName) - OffSet,\r
+                L", ProtocolType=0x%X, VlanId=%d)",\r
+                MnpConfigData.ProtocolTypeFilter,\r
+                Instance->MnpServiceData->VlanId\r
+                );\r
+  } else if (Status == EFI_NOT_STARTED) {\r
+    UnicodeSPrint (\r
+      HandleName,\r
+      sizeof (HandleName),\r
+      L"MNP (Not started)"\r
+      );\r
+  } else {\r
+    return Status;\r
+  }\r
+  \r
+  if (gMnpControllerNameTable != NULL) {\r
+    FreeUnicodeStringTable (gMnpControllerNameTable);\r
+    gMnpControllerNameTable = NULL;\r
+  }\r
+  \r
+  Status = AddUnicodeString2 (\r
+             "eng",\r
+             gMnpComponentName.SupportedLanguages,\r
+             &gMnpControllerNameTable,\r
+             HandleName,\r
+             TRUE\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  \r
+  return AddUnicodeString2 (\r
+           "en",\r
+           gMnpComponentName2.SupportedLanguages,\r
+           &gMnpControllerNameTable,\r
+           HandleName,\r
+           FALSE\r
+           );\r
+}\r
+\r
+/**\r
   Retrieves a Unicode string that is the user readable name of the controller\r
   that is being managed by a driver.\r
 \r
@@ -178,5 +280,68 @@ MnpComponentNameGetControllerName (
      OUT CHAR16                        **ControllerName\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  EFI_STATUS                    Status;\r
+  EFI_MANAGED_NETWORK_PROTOCOL  *Mnp;\r
+\r
+  //\r
+  // Only provide names for MNP child handles.\r
+  //\r
+  if (ChildHandle == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
\r
+  // \r
+  // Make sure this driver is currently managing ControllerHandle  \r
+  // \r
+  Status = EfiTestManagedDevice (\r
+             ControllerHandle,\r
+             gMnpDriverBinding.DriverBindingHandle,\r
+             &gEfiSimpleNetworkProtocolGuid\r
+             );\r
+  if (EFI_ERROR (Status)) { \r
+    return Status;\r
+  }\r
+  \r
+  // \r
+  // Make sure this driver produced ChildHandle \r
+  // \r
+  Status = EfiTestChildHandle (\r
+             ControllerHandle,\r
+             ChildHandle,\r
+             &gEfiManagedNetworkServiceBindingProtocolGuid\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  // \r
+  // Retrieve an instance of a produced protocol from ChildHandle  \r
+  // \r
+  Status = gBS->OpenProtocol (\r
+                  ChildHandle,\r
+                  &gEfiManagedNetworkProtocolGuid,\r
+                  (VOID **)&Mnp,\r
+                  NULL,\r
+                  NULL,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Update the component name for this child handle.\r
+  //\r
+  Status = UpdateName (Mnp);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return LookupUnicodeString2 (\r
+           Language,\r
+           This->SupportedLanguages,\r
+           gMnpControllerNameTable,\r
+           ControllerName,\r
+           (BOOLEAN)(This == &gMnpComponentName)\r
+           );\r
 }\r
index 6f60ef7..6232c3e 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   The header file of UEFI Component Name(2) protocol.\r
 \r
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions\r
 of the BSD License which accompanies this distribution.  The full\r
@@ -21,6 +21,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 extern EFI_COMPONENT_NAME2_PROTOCOL gMnpComponentName2;\r
 extern EFI_COMPONENT_NAME_PROTOCOL  gMnpComponentName;\r
+extern EFI_UNICODE_STRING_TABLE     *gMnpControllerNameTable;\r
 \r
 /**\r
   Retrieves a Unicode string that is the user readable name of the driver.\r
index c19c71b..9586db7 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Implementation of Managed Network Protocol private services.\r
 \r
-Copyright (c) 2005 - 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions\r
 of the BSD License which accompanies this distribution.  The full\r
@@ -45,7 +45,6 @@ EFI_MANAGED_NETWORK_CONFIG_DATA mMnpDefaultConfigData = {
   FALSE\r
 };\r
 \r
-\r
 /**\r
   Add Count of net buffers to MnpDeviceData->FreeNbufQue. The length of the net\r
   buffer is specified by MnpDeviceData->BufferLength.\r
@@ -687,6 +686,30 @@ MnpDestroyServiceData (
 }\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
+MnpDestoryChildEntry (\r
+  IN LIST_ENTRY         *Entry,\r
+  IN VOID               *Context\r
+)\r
+{\r
+  MNP_INSTANCE_DATA             *Instance;\r
+  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;\r
+\r
+  ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *) Context;\r
+  Instance = CR (Entry, MNP_INSTANCE_DATA, InstEntry, MNP_INSTANCE_DATA_SIGNATURE);\r
+  return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);\r
+}\r
+\r
+/**\r
   Destroy all child of the MNP service data.\r
 \r
   @param[in, out]  MnpServiceData    Pointer to the mnp service context data.\r
@@ -700,26 +723,20 @@ MnpDestroyServiceChild (
   IN OUT MNP_SERVICE_DATA    *MnpServiceData\r
   )\r
 {\r
-  EFI_STATUS                    Status;\r
-  MNP_INSTANCE_DATA             *Instance;\r
-  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;\r
-\r
-  ServiceBinding = &MnpServiceData->ServiceBinding;\r
-  while (!IsListEmpty (&MnpServiceData->ChildrenList)) {\r
-    //\r
-    // Don't use NetListRemoveHead here, the remove opreration will be done\r
-    // in ServiceBindingDestroyChild.\r
-    //\r
-    Instance = NET_LIST_HEAD (\r
-                 &MnpServiceData->ChildrenList,\r
-                 MNP_INSTANCE_DATA,\r
-                 InstEntry\r
-                 );\r
-\r
-    Status = ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
+  LIST_ENTRY                         *List;\r
+  EFI_STATUS                         Status;\r
+  UINTN                              ListLength;\r
+  \r
+  List = &MnpServiceData->ChildrenList;\r
+  \r
+  Status = NetDestroyLinkList (\r
+             List,\r
+             MnpDestoryChildEntry,\r
+             &MnpServiceData->ServiceBinding,\r
+             &ListLength\r
+             );\r
+  if (EFI_ERROR (Status) || ListLength != 0) {\r
+    return EFI_DEVICE_ERROR;\r
   }\r
 \r
   return EFI_SUCCESS;\r
index 03ddfb7..84c618c 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Implementation of driver entry point and driver binding protocol.\r
 \r
-Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions\r
 of the BSD License which accompanies this distribution.  The full\r
@@ -27,6 +27,50 @@ EFI_DRIVER_BINDING_PROTOCOL gMnpDriverBinding = {
 };\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
+MnpDestroyServiceDataEntry (\r
+  IN LIST_ENTRY         *Entry,\r
+  IN VOID               *Context\r
+)\r
+{\r
+  MNP_SERVICE_DATA              *MnpServiceData;\r
+  \r
+  MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);\r
+  return MnpDestroyServiceData (MnpServiceData);\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
+MnpDestroyServiceChildEntry (\r
+  IN LIST_ENTRY         *Entry,\r
+  IN VOID               *Context\r
+)\r
+{\r
+  MNP_SERVICE_DATA              *MnpServiceData;\r
+\r
+  MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);\r
+  return MnpDestroyServiceChild (MnpServiceData);\r
+}\r
+\r
+/**\r
   Test to see if this driver supports ControllerHandle. This service\r
   is called by the EFI boot service ConnectController(). In\r
   order to make drivers as small as possible, there are a few calling\r
@@ -276,8 +320,8 @@ MnpDriverBindingStop (
   EFI_VLAN_CONFIG_PROTOCOL      *VlanConfig;\r
   MNP_DEVICE_DATA               *MnpDeviceData;\r
   MNP_SERVICE_DATA              *MnpServiceData;\r
-  BOOLEAN                       AllChildrenStopped;\r
-  LIST_ENTRY                    *Entry;\r
+  LIST_ENTRY                    *List;\r
+  UINTN                         ListLength;\r
 \r
   //\r
   // Try to retrieve MNP service binding protocol from the ControllerHandle\r
@@ -317,10 +361,15 @@ MnpDriverBindingStop (
     //\r
     // Destroy all MNP service data\r
     //\r
-    while (!IsListEmpty (&MnpDeviceData->ServiceList)) {\r
-      Entry = GetFirstNode (&MnpDeviceData->ServiceList);\r
-      MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);\r
-      MnpDestroyServiceData (MnpServiceData);\r
+    List = &MnpDeviceData->ServiceList;\r
+    Status = NetDestroyLinkList (\r
+               List,\r
+               MnpDestroyServiceDataEntry,\r
+               NULL,\r
+               &ListLength\r
+               );\r
+    if (EFI_ERROR (Status) || ListLength !=0) {\r
+      return EFI_DEVICE_ERROR;\r
     }\r
 \r
     //\r
@@ -341,23 +390,24 @@ MnpDriverBindingStop (
     MnpDestroyDeviceData (MnpDeviceData, This->DriverBindingHandle);\r
     FreePool (MnpDeviceData);\r
 \r
+    if (gMnpControllerNameTable != NULL) {\r
+      FreeUnicodeStringTable (gMnpControllerNameTable);\r
+      gMnpControllerNameTable = NULL;\r
+    }\r
     return EFI_SUCCESS;\r
   }\r
 \r
   //\r
   // Stop all MNP child\r
   //\r
-  AllChildrenStopped = TRUE;\r
-  NET_LIST_FOR_EACH (Entry, &MnpDeviceData->ServiceList) {\r
-    MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);\r
-\r
-    Status = MnpDestroyServiceChild (MnpServiceData);\r
-    if (EFI_ERROR (Status)) {\r
-      AllChildrenStopped = FALSE;\r
-    }\r
-  }\r
-\r
-  if (!AllChildrenStopped) {\r
+  List = &MnpDeviceData->ServiceList;\r
+  Status = NetDestroyLinkList (\r
+             List,\r
+             MnpDestroyServiceChildEntry,\r
+             NULL,\r
+             &ListLength\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
index f096862..35a9b71 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Declaration of strctures and functions for MnpDxe driver.\r
 \r
-Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions\r
 of the BSD License which accompanies this distribution.  The full\r
@@ -33,11 +33,17 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/DpcLib.h>\r
 #include <Library/UefiRuntimeServicesTableLib.h>\r
 #include <Library/DevicePathLib.h>\r
+#include <Library/PrintLib.h>\r
 \r
 #include "ComponentName.h"\r
 \r
 #define MNP_DEVICE_DATA_SIGNATURE  SIGNATURE_32 ('M', 'n', 'p', 'D')\r
 \r
+//\r
+// Global Variables\r
+//\r
+extern  EFI_DRIVER_BINDING_PROTOCOL gMnpDriverBinding;\r
+\r
 typedef struct {\r
   UINT32                        Signature;\r
 \r
index 71f49f6..901c2df 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   UEFI Component Name(2) protocol implementation for Mtftp4Dxe driver.\r
   \r
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -12,7 +12,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 **/\r
 \r
-#include "Mtftp4Driver.h"\r
+#include "Mtftp4Impl.h"\r
 \r
 //\r
 // EFI Component Name Functions\r
@@ -174,6 +174,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mMtftp4DriverNameTable[]
   }\r
 };\r
 \r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gMtftp4ControllerNameTable = NULL;\r
+\r
 /**\r
   Retrieves a Unicode string that is the user readable name of the driver.\r
 \r
@@ -231,6 +233,72 @@ Mtftp4ComponentNameGetDriverName (
 }\r
 \r
 /**\r
+  Update the component name for the Mtftp4 child handle.\r
+\r
+  @param  Mtftp4[in]                A pointer to the EFI_MTFTP4_PROTOCOL.\r
+\r
+  \r
+  @retval EFI_SUCCESS               Update the ControllerNameTable of this instance successfully.\r
+  @retval EFI_INVALID_PARAMETER     The input parameter is invalid.\r
+  \r
+**/\r
+EFI_STATUS\r
+UpdateName (\r
+  IN   EFI_MTFTP4_PROTOCOL             *Mtftp4\r
+  )\r
+{\r
+  EFI_STATUS                       Status;\r
+  CHAR16                           HandleName[80];\r
+  EFI_MTFTP4_MODE_DATA             ModeData;\r
+\r
+  if (Mtftp4 == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Format the child name into the string buffer as:\r
+  // MTFTPv4 (ServerIp=192.168.1.10, ServerPort=69)\r
+  //\r
+  Status = Mtftp4->GetModeData (Mtftp4, &ModeData);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  UnicodeSPrint (HandleName, sizeof (HandleName),\r
+    L"MTFTPv4 (ServerIp=%d.%d.%d.%d, ServerPort=%d)",\r
+    ModeData.ConfigData.ServerIp.Addr[0],\r
+    ModeData.ConfigData.ServerIp.Addr[1],\r
+    ModeData.ConfigData.ServerIp.Addr[2],\r
+    ModeData.ConfigData.ServerIp.Addr[3],\r
+    ModeData.ConfigData.InitialServerPort\r
+    );\r
+\r
+  if (gMtftp4ControllerNameTable != NULL) {\r
+    FreeUnicodeStringTable (gMtftp4ControllerNameTable);\r
+    gMtftp4ControllerNameTable = NULL;\r
+  }\r
+  \r
+  Status = AddUnicodeString2 (\r
+             "eng",\r
+             gMtftp4ComponentName.SupportedLanguages,\r
+             &gMtftp4ControllerNameTable,\r
+             HandleName,\r
+             TRUE\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  \r
+  return AddUnicodeString2 (\r
+           "en",\r
+           gMtftp4ComponentName2.SupportedLanguages,\r
+           &gMtftp4ControllerNameTable,\r
+           HandleName,\r
+           FALSE\r
+           );\r
+}\r
+\r
+/**\r
   Retrieves a Unicode string that is the user readable name of the controller\r
   that is being managed by a driver.\r
 \r
@@ -308,5 +376,56 @@ Mtftp4ComponentNameGetControllerName (
      OUT CHAR16                                    **ControllerName\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  EFI_STATUS                    Status;\r
+  EFI_MTFTP4_PROTOCOL           *Mtftp4;\r
+\r
+  //\r
+  // Only provide names for child handles.\r
+  //\r
+  if (ChildHandle == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  \r
+  // \r
+  // Make sure this driver produced ChildHandle \r
+  // \r
+  Status = EfiTestChildHandle (\r
+             ControllerHandle,\r
+             ChildHandle,\r
+             &gEfiUdp4ProtocolGuid\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  // \r
+  // Retrieve an instance of a produced protocol from ChildHandle\r
+  // \r
+  Status = gBS->OpenProtocol (\r
+                  ChildHandle,\r
+                  &gEfiMtftp4ProtocolGuid,\r
+                  (VOID **)&Mtftp4,\r
+                  NULL,\r
+                  NULL,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Update the component name for this child handle.\r
+  //\r
+  Status = UpdateName (Mtftp4);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return LookupUnicodeString2 (\r
+           Language,\r
+           This->SupportedLanguages,\r
+           gMtftp4ControllerNameTable,\r
+           ControllerName,\r
+           (BOOLEAN)(This == &gMtftp4ComponentName)\r
+           );\r
 }\r
index 2a12b1d..8da47fc 100644 (file)
@@ -159,7 +159,6 @@ Mtftp4CreateService (
 \r
   MtftpSb->Signature      = MTFTP4_SERVICE_SIGNATURE;\r
   MtftpSb->ServiceBinding = gMtftp4ServiceBindingTemplete;\r
-  MtftpSb->InDestroy      = FALSE;\r
   MtftpSb->ChildrenNum    = 0;\r
   InitializeListHead (&MtftpSb->Children);\r
 \r
@@ -318,6 +317,42 @@ 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
+Mtftp4DestroyChildEntryInHandleBuffer (\r
+  IN LIST_ENTRY         *Entry,\r
+  IN VOID               *Context\r
+)\r
+{\r
+  MTFTP4_PROTOCOL               *Instance;\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
+  Instance = NET_LIST_USER_STRUCT_S (Entry, MTFTP4_PROTOCOL, Link, MTFTP4_PROTOCOL_SIGNATURE);\r
+  ServiceBinding    = ((MTFTP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;\r
+  NumberOfChildren  = ((MTFTP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;\r
+  ChildHandleBuffer = ((MTFTP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;\r
+\r
+  if (!NetIsInHandleBuffer (Instance->Handle, NumberOfChildren, ChildHandleBuffer)) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);\r
+}\r
 \r
 /**\r
   Stop the MTFTP driver on controller. The controller is a UDP\r
@@ -341,12 +376,12 @@ Mtftp4DriverBindingStop (
   IN EFI_HANDLE                  *ChildHandleBuffer\r
   )\r
 {\r
-  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;\r
-  MTFTP4_SERVICE                *MtftpSb;\r
-  MTFTP4_PROTOCOL               *Instance;\r
-  EFI_HANDLE                    NicHandle;\r
-  EFI_STATUS                    Status;\r
-  EFI_TPL                       OldTpl;\r
+  EFI_SERVICE_BINDING_PROTOCOL               *ServiceBinding;\r
+  MTFTP4_SERVICE                             *MtftpSb;\r
+  EFI_HANDLE                                 NicHandle;\r
+  EFI_STATUS                                 Status;\r
+  LIST_ENTRY                                 *List;\r
+  MTFTP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;\r
 \r
   //\r
   // MTFTP driver opens UDP child, So, Controller is a UDP\r
@@ -356,7 +391,7 @@ Mtftp4DriverBindingStop (
   NicHandle = NetLibGetNicHandle (Controller, &gEfiUdp4ProtocolGuid);\r
 \r
   if (NicHandle == NULL) {\r
-    return EFI_DEVICE_ERROR;\r
+    return EFI_SUCCESS;\r
   }\r
 \r
   Status = gBS->OpenProtocol (\r
@@ -374,16 +409,23 @@ Mtftp4DriverBindingStop (
 \r
   MtftpSb = MTFTP4_SERVICE_FROM_THIS (ServiceBinding);\r
 \r
-  if (MtftpSb->InDestroy) {\r
-    return EFI_SUCCESS;\r
+  if (!IsListEmpty (&MtftpSb->Children)) {\r
+    //\r
+    // Destroy the Mtftp4 child instance in ChildHandleBuffer.\r
+    //\r
+    List = &MtftpSb->Children;\r
+    Context.ServiceBinding    = ServiceBinding;\r
+    Context.NumberOfChildren  = NumberOfChildren;\r
+    Context.ChildHandleBuffer = ChildHandleBuffer;\r
+    Status = NetDestroyLinkList (\r
+               List,\r
+               Mtftp4DestroyChildEntryInHandleBuffer,\r
+               &Context,\r
+               NULL\r
+               );\r
   }\r
 \r
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
-  if (NumberOfChildren == 0) {\r
-\r
-    MtftpSb->InDestroy = TRUE;\r
-\r
+  if (NumberOfChildren == 0 && IsListEmpty (&MtftpSb->Children)) {\r
     gBS->UninstallProtocolInterface (\r
            NicHandle,\r
            &gEfiMtftp4ServiceBindingProtocolGuid,\r
@@ -391,21 +433,15 @@ Mtftp4DriverBindingStop (
            );\r
 \r
     Mtftp4CleanService (MtftpSb);\r
-\r
-    FreePool (MtftpSb);\r
-  } else {\r
-\r
-    while (!IsListEmpty (&MtftpSb->Children)) {\r
-      Instance = NET_LIST_HEAD (&MtftpSb->Children, MTFTP4_PROTOCOL, Link);\r
-      Mtftp4ServiceBindingDestroyChild (ServiceBinding, Instance->Handle);\r
+    if (gMtftp4ControllerNameTable != NULL) {\r
+      FreeUnicodeStringTable (gMtftp4ControllerNameTable);\r
+      gMtftp4ControllerNameTable = NULL;\r
     }\r
+    FreePool (MtftpSb);\r
 \r
-    if (MtftpSb->ChildrenNum != 0) {\r
-      Status = EFI_DEVICE_ERROR;\r
-    }\r
+    Status = EFI_SUCCESS;\r
   }\r
 \r
-  gBS->RestoreTPL (OldTpl);\r
   return Status;\r
 }\r
 \r
@@ -429,7 +465,6 @@ Mtftp4InitProtocol (
   InitializeListHead (&Instance->Link);\r
   CopyMem (&Instance->Mtftp4, &gMtftp4ProtocolTemplate, sizeof (Instance->Mtftp4));\r
   Instance->State     = MTFTP4_STATE_UNCONFIGED;\r
-  Instance->InDestroy = FALSE;\r
   Instance->Service   = MtftpSb;\r
 \r
   InitializeListHead (&Instance->Blocks);\r
@@ -499,7 +534,9 @@ Mtftp4ServiceBindingCreateChild (
                   );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    goto ON_ERROR;\r
+    UdpIoFreeIo (Instance->UnicastPort);\r
+    FreePool (Instance);\r
+    return Status;\r
   }\r
 \r
   Instance->Handle  = *ChildHandle;\r
@@ -516,13 +553,30 @@ Mtftp4ServiceBindingCreateChild (
                   EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
                   );\r
   if (EFI_ERROR (Status)) {\r
-    gBS->UninstallMultipleProtocolInterfaces (\r
-           Instance->Handle,\r
-           &gEfiMtftp4ProtocolGuid,\r
-           &Instance->Mtftp4,\r
-           NULL\r
-           );\r
+    goto ON_ERROR;\r
+  }\r
 \r
+  //\r
+  // Open the Udp4 protocol by child.\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Instance->UnicastPort->UdpHandle,\r
+                  &gEfiUdp4ProtocolGuid,\r
+                  (VOID **) &Udp4,\r
+                  gMtftp4DriverBinding.DriverBindingHandle,\r
+                  Instance->Handle,\r
+                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // Close the Udp4 protocol.\r
+    //\r
+    gBS->CloseProtocol (\r
+           MtftpSb->ConnectUdp->UdpHandle,\r
+           &gEfiUdp4ProtocolGuid,\r
+           gMtftp4DriverBinding.DriverBindingHandle,\r
+           ChildHandle\r
+           );\r
     goto ON_ERROR;\r
   }\r
 \r
@@ -536,13 +590,21 @@ Mtftp4ServiceBindingCreateChild (
 \r
   gBS->RestoreTPL (OldTpl);\r
 \r
-ON_ERROR:\r
+  return EFI_SUCCESS;\r
 \r
-  if (EFI_ERROR (Status)) {\r
-    UdpIoFreeIo (Instance->UnicastPort);\r
-    FreePool (Instance);\r
+ON_ERROR:\r
+  if (Instance->Handle != NULL) {\r
+    gBS->UninstallMultipleProtocolInterfaces (\r
+           Instance->Handle,\r
+           &gEfiMtftp4ProtocolGuid,\r
+           &Instance->Mtftp4,\r
+           NULL\r
+           );\r
   }\r
 \r
+  UdpIoFreeIo (Instance->UnicastPort);\r
+  FreePool (Instance);\r
+\r
   return Status;\r
 }\r
 \r
@@ -615,6 +677,22 @@ Mtftp4ServiceBindingDestroyChild (
          ChildHandle\r
          );\r
 \r
+  gBS->CloseProtocol (\r
+         Instance->UnicastPort->UdpHandle,\r
+         &gEfiUdp4ProtocolGuid,\r
+         gMtftp4DriverBinding.DriverBindingHandle,\r
+         ChildHandle\r
+         );\r
+\r
+  if (Instance->McastUdpPort != NULL) {\r
+    gBS->CloseProtocol (\r
+           Instance->McastUdpPort->UdpHandle,\r
+           &gEfiUdp4ProtocolGuid,\r
+           gMtftp4DriverBinding.DriverBindingHandle,\r
+           ChildHandle\r
+           );  \r
+  }\r
+\r
   //\r
   // Uninstall the MTFTP4 protocol first to enable a top down destruction.\r
   //\r
index 63828bd..936eab1 100644 (file)
@@ -26,6 +26,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 extern EFI_COMPONENT_NAME_PROTOCOL   gMtftp4ComponentName;\r
 extern EFI_COMPONENT_NAME2_PROTOCOL  gMtftp4ComponentName2;\r
 extern EFI_DRIVER_BINDING_PROTOCOL   gMtftp4DriverBinding;\r
+extern EFI_UNICODE_STRING_TABLE      *gMtftp4ControllerNameTable;\r
 \r
 /**\r
   Test whether MTFTP driver support this controller.\r
index 5183e1a..f3a4952 100644 (file)
@@ -58,6 +58,12 @@ Mtftp4CleanOperation (
   }\r
 \r
   if (Instance->McastUdpPort != NULL) {\r
+    gBS->CloseProtocol (\r
+           Instance->McastUdpPort->UdpHandle,\r
+           &gEfiUdp4ProtocolGuid,\r
+           gMtftp4DriverBinding.DriverBindingHandle,\r
+           Instance->Handle\r
+           );\r
     UdpIoFreeIo (Instance->McastUdpPort);\r
     Instance->McastUdpPort = NULL;\r
   }\r
index 41f524a..329c6d8 100644 (file)
@@ -34,6 +34,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/UdpIoLib.h>\r
+#include <LIbrary/PrintLib.h>\r
 \r
 extern EFI_MTFTP4_PROTOCOL  gMtftp4ProtocolTemplate;\r
 \r
@@ -68,8 +69,6 @@ struct _MTFTP4_SERVICE {
   UINT32                        Signature;\r
   EFI_SERVICE_BINDING_PROTOCOL  ServiceBinding;\r
 \r
-  BOOLEAN                       InDestroy;\r
-\r
   UINT16                        ChildrenNum;\r
   LIST_ENTRY                    Children;\r
 \r
@@ -149,6 +148,12 @@ struct _MTFTP4_PROTOCOL {
   UDP_IO                        *McastUdpPort;\r
 };\r
 \r
+typedef struct {\r
+  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;\r
+  UINTN                         NumberOfChildren;\r
+  EFI_HANDLE                    *ChildHandleBuffer;\r
+} MTFTP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT;\r
+\r
 /**\r
   Clean up the MTFTP session to get ready for new operation.\r
 \r
index 264598f..ae157c5 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Routines to process Rrq (download).\r
   \r
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -486,6 +486,7 @@ Mtftp4RrqHandleOack (
   MTFTP4_OPTION             Reply;\r
   EFI_STATUS                Status;\r
   INTN                      Expected;\r
+  EFI_UDP4_PROTOCOL         *Udp4;\r
 \r
   *Completed = FALSE;\r
 \r
@@ -548,13 +549,31 @@ Mtftp4RrqHandleOack (
       //\r
       Instance->McastIp      = Reply.McastIp;\r
       Instance->McastPort    = Reply.McastPort;\r
-      Instance->McastUdpPort = UdpIoCreateIo (\r
-                                 Instance->Service->Controller,\r
-                                 Instance->Service->Image,\r
-                                 Mtftp4RrqConfigMcastPort,\r
-                                 UDP_IO_UDP4_VERSION,\r
-                                 Instance\r
-                                 );\r
+      if (Instance->McastUdpPort == NULL) {\r
+        Instance->McastUdpPort = UdpIoCreateIo (\r
+                                   Instance->Service->Controller,\r
+                                   Instance->Service->Image,\r
+                                   Mtftp4RrqConfigMcastPort,\r
+                                   UDP_IO_UDP4_VERSION,\r
+                                   Instance\r
+                                   );\r
+        if (Instance->McastUdpPort != NULL) {\r
+          Status = gBS->OpenProtocol (\r
+                          Instance->McastUdpPort->UdpHandle,\r
+                          &gEfiUdp4ProtocolGuid,\r
+                          (VOID **) &Udp4,\r
+                          Instance->Service->Image,\r
+                          Instance->Handle,\r
+                          EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+                          );\r
+          if (EFI_ERROR (Status)) {\r
+            UdpIoFreeIo (Instance->McastUdpPort);\r
+            Instance->McastUdpPort = NULL;\r
+            return EFI_DEVICE_ERROR;\r
+          }\r
+        }\r
+      }\r
+\r
 \r
       if (Instance->McastUdpPort == NULL) {\r
         return EFI_DEVICE_ERROR;\r
index e8f7ec1..ef499d1 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
     UEFI Component Name(2) protocol implementation for SnpDxe driver.\r
 \r
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials are licensed \r
 and made available under the terms and conditions of the BSD License which \r
 accompanies this distribution. The full text of the license may be found at \r
@@ -175,6 +175,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mSimpleNetworkDriverNameT
   }\r
 };\r
 \r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gSimpleNetworkControllerNameTable = NULL;\r
+\r
 /**\r
   Retrieves a Unicode string that is the user readable name of the driver.\r
 \r
@@ -232,6 +234,78 @@ SimpleNetworkComponentNameGetDriverName (
 }\r
 \r
 /**\r
+  Update the component name for the Snp child handle.\r
+\r
+  @param  Snp[in]                   A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL.\r
+\r
+  \r
+  @retval EFI_SUCCESS               Update the ControllerNameTable of this instance successfully.\r
+  @retval EFI_INVALID_PARAMETER     The input parameter is invalid.\r
+  \r
+**/\r
+EFI_STATUS\r
+UpdateName (\r
+  IN  EFI_SIMPLE_NETWORK_PROTOCOL   *Snp\r
+  )\r
+{\r
+  EFI_STATUS                       Status;\r
+  CHAR16                           HandleName[80];\r
+  UINTN                            OffSet;\r
+  UINTN                            Index;\r
+\r
+  if (Snp == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  OffSet = 0;\r
+  OffSet += UnicodeSPrint (\r
+              HandleName,\r
+              sizeof (HandleName),\r
+              L"SNP (MAC="\r
+              );\r
+  for (Index = 0; Index < Snp->Mode->HwAddressSize; Index++) {\r
+    OffSet += UnicodeSPrint (\r
+                HandleName + OffSet,\r
+                sizeof (HandleName) - OffSet,\r
+                L"%02X-",\r
+                Snp->Mode->CurrentAddress.Addr[Index]\r
+                );\r
+  }\r
+  //\r
+  // Remove the last '-'\r
+  //\r
+  OffSet--;\r
+  OffSet += UnicodeSPrint (\r
+              HandleName,\r
+              sizeof (HandleName),\r
+              L")"\r
+              );\r
+  if (gSimpleNetworkControllerNameTable != NULL) {\r
+    FreeUnicodeStringTable (gSimpleNetworkControllerNameTable);\r
+    gSimpleNetworkControllerNameTable = NULL;\r
+  }\r
+  \r
+  Status = AddUnicodeString2 (\r
+             "eng",\r
+             gSimpleNetworkComponentName.SupportedLanguages,\r
+             &gSimpleNetworkControllerNameTable,\r
+             HandleName,\r
+             TRUE\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  \r
+  return AddUnicodeString2 (\r
+           "en",\r
+           gSimpleNetworkComponentName2.SupportedLanguages,\r
+           &gSimpleNetworkControllerNameTable,\r
+           HandleName,\r
+           FALSE\r
+           );\r
+}\r
+\r
+/**\r
   Retrieves a Unicode string that is the user readable name of the controller\r
   that is being managed by a driver.\r
 \r
@@ -310,5 +384,52 @@ SimpleNetworkComponentNameGetControllerName (
   OUT CHAR16                                          **ControllerName\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  EFI_STATUS                    Status;\r
+  EFI_SIMPLE_NETWORK_PROTOCOL   *Snp;\r
+  \r
+  if (ChildHandle != NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Make sure this driver is currently managing ControllHandle\r
+  //\r
+  Status = EfiTestManagedDevice (\r
+             ControllerHandle,\r
+             gSimpleNetworkDriverBinding.DriverBindingHandle,\r
+             &gEfiSimpleNetworkProtocolGuid\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  // \r
+  // Retrieve an instance of a produced protocol from ControllerHandle\r
+  // \r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiSimpleNetworkProtocolGuid,\r
+                  (VOID **)&Snp,\r
+                  NULL,\r
+                  NULL,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  //\r
+  // Update the component name for this child handle.\r
+  //\r
+  Status = UpdateName (Snp);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return LookupUnicodeString2 (\r
+           Language,\r
+           This->SupportedLanguages,\r
+           gSimpleNetworkControllerNameTable,\r
+           ControllerName,\r
+           (BOOLEAN)(This == &gSimpleNetworkComponentName)\r
+           );\r
 }\r
index 72693e9..f1fea0c 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Implementation of driver entry point and driver binding protocol.\r
 \r
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials are licensed\r
 and made available under the terms and conditions of the BSD License which\r
 accompanies this distribution. The full text of the license may be found at\r
@@ -828,7 +828,7 @@ SimpleNetworkDriverStop (
 //\r
 // Simple Network Protocol Driver Global Variables\r
 //\r
-EFI_DRIVER_BINDING_PROTOCOL mSimpleNetworkDriverBinding = {\r
+EFI_DRIVER_BINDING_PROTOCOL gSimpleNetworkDriverBinding = {\r
   SimpleNetworkDriverSupported,\r
   SimpleNetworkDriverStart,\r
   SimpleNetworkDriverStop,\r
@@ -1014,7 +1014,7 @@ InitializeSnpNiiDriver (
   return EfiLibInstallDriverBindingComponentName2 (\r
            ImageHandle,\r
            SystemTable,\r
-           &mSimpleNetworkDriverBinding,\r
+           &gSimpleNetworkDriverBinding,\r
            ImageHandle,\r
            &gSimpleNetworkComponentName,\r
            &gSimpleNetworkComponentName2\r
index dc63845..4211b4d 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
     Declaration of strctures and functions for SnpDxe driver.\r
 \r
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials are licensed\r
 and made available under the terms and conditions of the BSD License which\r
 accompanies this distribution. The full text of the license may be found at\r
@@ -31,6 +31,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/BaseLib.h>\r
 #include <Library/UefiLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
+#include <Library/PrintLib.h>\r
 \r
 #include <IndustryStandard/Pci.h>\r
 \r
@@ -135,6 +136,7 @@ typedef struct {
 //\r
 // Global Variables\r
 //\r
+extern EFI_DRIVER_BINDING_PROTOCOL    gSimpleNetworkDriverBinding;\r
 extern EFI_COMPONENT_NAME_PROTOCOL    gSimpleNetworkComponentName;\r
 extern EFI_COMPONENT_NAME2_PROTOCOL   gSimpleNetworkComponentName2;\r
 \r
index 587f7c6..dd0af8d 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   UEFI Component Name(2) protocol implementation for Tcp4Dxe driver.\r
 \r
-Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -171,6 +171,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mTcpDriverNameTable[] = {
   }\r
 };\r
 \r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gTcpControllerNameTable = NULL;\r
+\r
 /**\r
   Retrieves a Unicode string that is the user readable name of the driver.\r
 \r
@@ -228,6 +230,76 @@ TcpComponentNameGetDriverName (
 }\r
 \r
 /**\r
+  Update the component name for the Tcp4 child handle.\r
+\r
+  @param  Tcp4[in]                   A pointer to the EFI_TCP4_PROTOCOL.\r
+\r
+  \r
+  @retval EFI_SUCCESS                Update the ControllerNameTable of this instance successfully.\r
+  @retval EFI_INVALID_PARAMETER      The input parameter is invalid.\r
+  \r
+**/\r
+EFI_STATUS\r
+UpdateName (\r
+  IN  EFI_TCP4_PROTOCOL             *Tcp4\r
+  )\r
+{\r
+  EFI_STATUS                       Status;\r
+  CHAR16                           HandleName[80];\r
+  EFI_TCP4_CONFIG_DATA             Tcp4ConfigData;\r
+\r
+  if (Tcp4 == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Format the child name into the string buffer as:\r
+  // TCPv4 (SrcPort=59, DestPort=60, ActiveFlag=TRUE)\r
+  //\r
+  Status = Tcp4->GetModeData (Tcp4, NULL, &Tcp4ConfigData, NULL, NULL, NULL);\r
+  if (!EFI_ERROR (Status)) {\r
+    UnicodeSPrint (HandleName, sizeof (HandleName),\r
+      L"TCPv4 (SrcPort=%d, DestPort=&d, ActiveFlag=%s)",\r
+      Tcp4ConfigData.AccessPoint.StationPort,\r
+      Tcp4ConfigData.AccessPoint.RemotePort,\r
+      (Tcp4ConfigData.AccessPoint.ActiveFlag ? L"TRUE" : L"FALSE")\r
+      );\r
+  } if (Status == EFI_NOT_STARTED) {\r
+    UnicodeSPrint (\r
+      HandleName,\r
+      sizeof (HandleName),\r
+      L"TCPv4 (Not started)"\r
+      );\r
+  } else {\r
+    return Status;\r
+  }\r
+\r
+  if (gTcpControllerNameTable != NULL) {\r
+    FreeUnicodeStringTable (gTcpControllerNameTable);\r
+    gTcpControllerNameTable = NULL;\r
+  }\r
+  \r
+  Status = AddUnicodeString2 (\r
+             "eng",\r
+             gTcp4ComponentName.SupportedLanguages,\r
+             &gTcpControllerNameTable,\r
+             HandleName,\r
+             TRUE\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  \r
+  return AddUnicodeString2 (\r
+           "en",\r
+           gTcp4ComponentName2.SupportedLanguages,\r
+           &gTcpControllerNameTable,\r
+           HandleName,\r
+           FALSE\r
+           );\r
+}\r
+\r
+/**\r
   Retrieves a Unicode string that is the user readable name of the controller\r
   that is being managed by a driver.\r
 \r
@@ -305,5 +377,56 @@ TcpComponentNameGetControllerName (
      OUT CHAR16                       **ControllerName\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  EFI_STATUS                    Status;\r
+  EFI_TCP4_PROTOCOL             *Tcp4;\r
+\r
+  //\r
+  // Only provide names for child handles.\r
+  //\r
+  if (ChildHandle == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  \r
+  // \r
+  // Make sure this driver produced ChildHandle \r
+  // \r
+  Status = EfiTestChildHandle (\r
+             ControllerHandle,\r
+             ChildHandle,\r
+             &gEfiIp4ProtocolGuid\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  // \r
+  // Retrieve an instance of a produced protocol from ChildHandle\r
+  // \r
+  Status = gBS->OpenProtocol (\r
+                  ChildHandle,\r
+                  &gEfiTcp4ProtocolGuid,\r
+                  (VOID **)&Tcp4,\r
+                  NULL,\r
+                  NULL,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Update the component name for this child handle.\r
+  //\r
+  Status = UpdateName (Tcp4);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return LookupUnicodeString2 (\r
+           Language,\r
+           This->SupportedLanguages,\r
+           gTcpControllerNameTable,\r
+           ControllerName,\r
+           (BOOLEAN)(This == &gTcp4ComponentName)\r
+           );\r
 }\r
index ac36460..feed86c 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Interface function of the Socket.\r
 \r
-Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -148,11 +148,11 @@ SockDestroyChild (
 \r
   ASSERT ((Sock != NULL) && (Sock->ProtoHandler != NULL));\r
 \r
-  if (Sock->IsDestroyed) {\r
+  if (Sock->InDestroy) {\r
     return EFI_SUCCESS;\r
   }\r
 \r
-  Sock->IsDestroyed = TRUE;\r
+  Sock->InDestroy = TRUE;\r
 \r
   Status = EfiAcquireLockOrFail (&(Sock->Lock));\r
   if (EFI_ERROR (Status)) {\r
@@ -173,7 +173,7 @@ SockDestroyChild (
     DEBUG ((EFI_D_ERROR, "SockDestroyChild: Protocol detach socket"\r
       " failed with %r\n", Status));\r
 \r
-    Sock->IsDestroyed = FALSE;\r
+    Sock->InDestroy = FALSE;\r
   } else if (SOCK_IS_CONFIGURED (Sock)) {\r
 \r
     SockConnFlush (Sock);\r
index b8ace79..8c25c63 100644 (file)
@@ -30,6 +30,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/UefiDriverEntryPoint.h>\r
 #include <Library/UefiLib.h>\r
 #include <Library/DpcLib.h>\r
+#include <Library/PrintLib.h>\r
 \r
 #define SOCK_SND_BUF        0\r
 #define SOCK_RCV_BUF        1\r
@@ -645,7 +646,7 @@ struct _SOCKET {
   SOCK_BUFFER           SndBuffer;  ///< Send buffer of application's data\r
   SOCK_BUFFER           RcvBuffer;  ///< Receive buffer of received data\r
   EFI_STATUS            SockError;  ///< The error returned by low layer protocol\r
-  BOOLEAN               IsDestroyed;\r
+  BOOLEAN               InDestroy;\r
 \r
   //\r
   // Fields used to manage the connection request\r
index 688f9a7..93d10c9 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Tcp request dispatcher implementation.\r
 \r
-Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -263,6 +263,8 @@ Tcp4AttachPcb (
   TCP_CB            *Tcb;\r
   TCP4_PROTO_DATA   *ProtoData;\r
   IP_IO             *IpIo;\r
+  EFI_STATUS        Status;\r
+  VOID              *Ip;\r
 \r
   Tcb = AllocateZeroPool (sizeof (TCP_CB));\r
 \r
@@ -286,6 +288,22 @@ Tcp4AttachPcb (
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
+  //\r
+  // Open the new created IP instance BY_CHILD.\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Tcb->IpInfo->ChildHandle,\r
+                  &gEfiIp4ProtocolGuid,\r
+                  &Ip,\r
+                  IpIo->Image,\r
+                  Sk->SockHandle,\r
+                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    IpIoRemoveIp (IpIo, Tcb->IpInfo);\r
+    return Status;\r
+  }\r
+\r
   InitializeListHead (&Tcb->List);\r
   InitializeListHead (&Tcb->SndQue);\r
   InitializeListHead (&Tcb->RcvQue);\r
@@ -318,6 +336,16 @@ Tcp4DetachPcb (
 \r
   Tcp4FlushPcb (Tcb);\r
 \r
+  //\r
+  // Close the IP protocol.\r
+  //\r
+  gBS->CloseProtocol (\r
+         Tcb->IpInfo->ChildHandle,\r
+         &gEfiIp4ProtocolGuid,\r
+         ProtoData->TcpService->IpIo->Image,\r
+         Sk->SockHandle\r
+         );\r
+  \r
   IpIoRemoveIp (ProtoData->TcpService->IpIo, Tcb->IpInfo);\r
 \r
   FreePool (Tcb);\r
index a29b6bc..1021252 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Tcp driver function.\r
 \r
-Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -18,6 +18,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 UINT16                                mTcp4RandomPort;\r
 extern EFI_COMPONENT_NAME_PROTOCOL    gTcp4ComponentName;\r
 extern EFI_COMPONENT_NAME2_PROTOCOL   gTcp4ComponentName2;\r
+extern EFI_UNICODE_STRING_TABLE       *gTcpControllerNameTable;\r
 \r
 TCP4_HEARTBEAT_TIMER  mTcp4Timer = {\r
   NULL,\r
@@ -136,6 +137,43 @@ Tcp4DestroyTimer (
 }\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
+Tcp4DestroyChildEntryInHandleBuffer (\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    = ((TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;\r
+  NumberOfChildren  = ((TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;\r
+  ChildHandleBuffer = ((TCP4_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
   The entry point for Tcp4 driver, used to install Tcp4 driver on the ImageHandle.\r
 \r
   @param  ImageHandle   The firmware allocated handle for this\r
@@ -387,6 +425,7 @@ ON_ERROR:
 \r
   if (TcpServiceData->IpIo != NULL) {\r
     IpIoDestroy (TcpServiceData->IpIo);\r
+    TcpServiceData->IpIo = NULL;\r
   }\r
 \r
   FreePool (TcpServiceData);\r
@@ -431,17 +470,18 @@ Tcp4DriverBindingStop (
   IN  EFI_HANDLE                   *ChildHandleBuffer\r
   )\r
 {\r
-  EFI_STATUS                          Status;\r
-  EFI_HANDLE                          NicHandle;\r
-  EFI_SERVICE_BINDING_PROTOCOL        *ServiceBinding;\r
-  TCP4_SERVICE_DATA                   *TcpServiceData;\r
-  SOCKET                              *Sock;\r
+  EFI_STATUS                                Status;\r
+  EFI_HANDLE                                NicHandle;\r
+  EFI_SERVICE_BINDING_PROTOCOL              *ServiceBinding;\r
+  TCP4_SERVICE_DATA                         *TcpServiceData;\r
+  LIST_ENTRY                                *List;\r
+  TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT  Context;\r
 \r
   // Find the NicHandle where Tcp4 ServiceBinding Protocol is installed.\r
   //\r
   NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);\r
   if (NicHandle == NULL) {\r
-    return EFI_DEVICE_ERROR;\r
+    return EFI_SUCCESS;\r
   }\r
 \r
   //\r
@@ -465,7 +505,18 @@ Tcp4DriverBindingStop (
 \r
   TcpServiceData = TCP4_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
+               Tcp4DestroyChildEntryInHandleBuffer,\r
+               &Context,\r
+               NULL\r
+               );\r
+  } else if (IsListEmpty (&TcpServiceData->SocketList)) {\r
     //\r
     // Uninstall TCP servicebinding protocol\r
     //\r
@@ -480,6 +531,7 @@ Tcp4DriverBindingStop (
     // Destroy the IpIO consumed by TCP driver\r
     //\r
     IpIoDestroy (TcpServiceData->IpIo);\r
+    TcpServiceData->IpIo = NULL;\r
 \r
     //\r
     // Destroy the heartbeat timer.\r
@@ -491,17 +543,17 @@ Tcp4DriverBindingStop (
     //\r
     TcpClearVariableData (TcpServiceData);\r
 \r
+    if (gTcpControllerNameTable != NULL) {\r
+      FreeUnicodeStringTable (gTcpControllerNameTable);\r
+      gTcpControllerNameTable = NULL;\r
+    }\r
+    \r
     //\r
     // 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 Status;\r
@@ -713,14 +765,11 @@ Tcp4ServiceBindingDestroyChild (
   EFI_STATUS         Status;\r
   EFI_TCP4_PROTOCOL  *Tcp4;\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
@@ -744,7 +793,6 @@ Tcp4ServiceBindingDestroyChild (
     SockDestroyChild (Sock);\r
   }\r
 \r
-  gBS->RestoreTPL (OldTpl);\r
   return Status;\r
 }\r
 \r
index c590757..cd90458 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   TCP4 protocol services header file.\r
 \r
-Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -75,6 +75,12 @@ typedef struct _TCP4_ROUTE_INFO {
   EFI_IPv4_ADDRESS  *GatewayAddress;\r
 } TCP4_ROUTE_INFO;\r
 \r
+typedef struct {\r
+  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;\r
+  UINTN                         NumberOfChildren;\r
+  EFI_HANDLE                    *ChildHandleBuffer;\r
+} TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT;\r
+\r
 /**\r
   Get the current operational status of a TCP instance.\r
   \r
index acb8f16..cf31105 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 \r
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -174,6 +174,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUdpDriverNameTable[] = {
   }\r
 };\r
 \r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gUdpControllerNameTable = NULL;\r
+  \r
 /**\r
   Retrieves a Unicode string that is the user readable name of the driver.\r
 \r
@@ -231,6 +233,75 @@ UdpComponentNameGetDriverName (
 }\r
 \r
 /**\r
+  Update the component name for the Udp4 child handle.\r
+\r
+  @param  Udp4[in]                   A pointer to the EFI_UDP4_PROTOCOL.\r
+\r
+  \r
+  @retval EFI_SUCCESS                Update the ControllerNameTable of this instance successfully.\r
+  @retval EFI_INVALID_PARAMETER      The input parameter is invalid.\r
+  \r
+**/\r
+EFI_STATUS\r
+UpdateName (\r
+  EFI_UDP4_PROTOCOL             *Udp4\r
+  )\r
+{\r
+  EFI_STATUS                       Status;\r
+  CHAR16                           HandleName[64];\r
+  EFI_UDP4_CONFIG_DATA             Udp4ConfigData;\r
+\r
+  if (Udp4 == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Format the child name into the string buffer as:\r
+  // UDPv4 (SrcPort=59, DestPort=60)\r
+  //\r
+  Status = Udp4->GetModeData (Udp4, &Udp4ConfigData, NULL, NULL, NULL);\r
+  if (!EFI_ERROR (Status)) {\r
+    UnicodeSPrint (HandleName, sizeof (HandleName),\r
+      L"UDPv4 (SrcPort=%d, DestPort=%d)",\r
+      Udp4ConfigData.StationPort,\r
+      Udp4ConfigData.RemotePort\r
+      );\r
+  } else if (Status == EFI_NOT_STARTED) {\r
+    UnicodeSPrint (\r
+      HandleName,\r
+      sizeof (HandleName),\r
+      L"UDPv4 (Not started)"\r
+      );\r
+  } else {\r
+    return Status;\r
+  }\r
+\r
+  if (gUdpControllerNameTable != NULL) {\r
+    FreeUnicodeStringTable (gUdpControllerNameTable);\r
+    gUdpControllerNameTable = NULL;\r
+  }\r
+  \r
+  Status = AddUnicodeString2 (\r
+             "eng",\r
+             gUdp4ComponentName.SupportedLanguages,\r
+             &gUdpControllerNameTable,\r
+             HandleName,\r
+             TRUE\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  \r
+  return AddUnicodeString2 (\r
+           "en",\r
+           gUdp4ComponentName2.SupportedLanguages,\r
+           &gUdpControllerNameTable,\r
+           HandleName,\r
+           FALSE\r
+           );\r
+}\r
+\r
+/**\r
   Retrieves a Unicode string that is the user readable name of the controller\r
   that is being managed by a driver.\r
 \r
@@ -308,6 +379,57 @@ UdpComponentNameGetControllerName (
   OUT CHAR16                                          **ControllerName\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  EFI_STATUS                    Status;\r
+  EFI_UDP4_PROTOCOL             *Udp4;\r
+\r
+  //\r
+  // Only provide names for child handles.\r
+  //\r
+  if (ChildHandle == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  \r
+  //\r
+  // Make sure this driver produced ChildHandle\r
+  //\r
+  Status = EfiTestChildHandle (\r
+             ControllerHandle,\r
+             ChildHandle,\r
+             &gEfiIp4ProtocolGuid\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Retrieve an instance of a produced protocol from ChildHandle\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  ChildHandle,\r
+                  &gEfiUdp4ProtocolGuid,\r
+                  (VOID **)&Udp4,\r
+                  NULL,\r
+                  NULL,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Update the component name for this child handle.\r
+  //\r
+  Status = UpdateName (Udp4);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return LookupUnicodeString2 (\r
+           Language,\r
+           This->SupportedLanguages,\r
+           gUdpControllerNameTable,\r
+           ControllerName,\r
+           (BOOLEAN)(This == &gUdp4ComponentName)\r
+           );\r
 }\r
 \r
index 5afb3aa..96b08d1 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 \r
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -28,6 +28,43 @@ EFI_SERVICE_BINDING_PROTOCOL mUdp4ServiceBinding = {
   Udp4ServiceBindingDestroyChild\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
+Udp4DestroyChildEntryInHandleBuffer (\r
+  IN LIST_ENTRY         *Entry,\r
+  IN VOID               *Context\r
+)\r
+{\r
+  UDP4_INSTANCE_DATA            *Instance;\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
+  Instance = NET_LIST_USER_STRUCT_S (Entry, UDP4_INSTANCE_DATA, Link, UDP4_INSTANCE_DATA_SIGNATURE);\r
+  ServiceBinding    = ((UDP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;\r
+  NumberOfChildren  = ((UDP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;\r
+  ChildHandleBuffer = ((UDP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;\r
+\r
+  if (!NetIsInHandleBuffer (Instance->ChildHandle, NumberOfChildren, ChildHandleBuffer)) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  return ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);\r
+}\r
+\r
 \r
 /**\r
   Test to see if this driver supports ControllerHandle. This service\r
@@ -178,18 +215,19 @@ Udp4DriverBindingStop (
   IN  EFI_HANDLE                   *ChildHandleBuffer\r
   )\r
 {\r
-  EFI_STATUS                    Status;\r
-  EFI_HANDLE                    NicHandle;\r
-  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;\r
-  UDP4_SERVICE_DATA             *Udp4Service;\r
-  UDP4_INSTANCE_DATA            *Instance;\r
+  EFI_STATUS                                Status;\r
+  EFI_HANDLE                                NicHandle;\r
+  EFI_SERVICE_BINDING_PROTOCOL              *ServiceBinding;\r
+  UDP4_SERVICE_DATA                         *Udp4Service;\r
+  UDP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT  Context;\r
+  LIST_ENTRY                                *List;\r
 \r
   //\r
   // Find the NicHandle where UDP4 ServiceBinding Protocol is installed.\r
   //\r
   NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);\r
   if (NicHandle == NULL) {\r
-    return EFI_DEVICE_ERROR;\r
+    return EFI_SUCCESS;\r
   }\r
 \r
   //\r
@@ -208,9 +246,21 @@ Udp4DriverBindingStop (
   }\r
 \r
   Udp4Service = UDP4_SERVICE_DATA_FROM_THIS (ServiceBinding);\r
-\r
-  if (NumberOfChildren == 0) {\r
-\r
+  if (NumberOfChildren != 0) {\r
+    //\r
+    // NumberOfChildren is not zero, destroy the children instances in ChildHandleBuffer.\r
+    //\r
+    List = &Udp4Service->ChildrenList;\r
+    Context.ServiceBinding    = ServiceBinding;\r
+    Context.NumberOfChildren  = NumberOfChildren;\r
+    Context.ChildHandleBuffer = ChildHandleBuffer;\r
+    Status = NetDestroyLinkList (\r
+               List,\r
+               Udp4DestroyChildEntryInHandleBuffer,\r
+               &Context,\r
+               NULL\r
+               );\r
+  } else {\r
     gBS->UninstallMultipleProtocolInterfaces (\r
            NicHandle,\r
            &gEfiUdp4ServiceBindingProtocolGuid,\r
@@ -222,14 +272,11 @@ Udp4DriverBindingStop (
 \r
     Udp4CleanService (Udp4Service);\r
 \r
-    FreePool (Udp4Service);\r
-  } else {\r
-\r
-    while (!IsListEmpty (&Udp4Service->ChildrenList)) {\r
-      Instance = NET_LIST_HEAD (&Udp4Service->ChildrenList, UDP4_INSTANCE_DATA, Link);\r
-\r
-      ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);\r
+    if (gUdpControllerNameTable != NULL) {\r
+      FreeUnicodeStringTable (gUdpControllerNameTable);\r
+      gUdpControllerNameTable = NULL;\r
     }\r
+    FreePool (Udp4Service);\r
   }\r
 \r
   return Status;\r
@@ -323,6 +370,21 @@ Udp4ServiceBindingCreateChild (
     goto ON_ERROR;\r
   }\r
 \r
+  //\r
+  // Open this instance's Ip4 protocol in the IpInfo BY_CHILD.\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Instance->IpInfo->ChildHandle,\r
+                  &gEfiIp4ProtocolGuid,\r
+                  (VOID **) &Ip4,\r
+                  gUdp4DriverBinding.DriverBindingHandle,\r
+                  Instance->ChildHandle,\r
+                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto ON_ERROR;\r
+  }\r
+\r
   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
   //\r
@@ -412,14 +474,14 @@ Udp4ServiceBindingDestroyChild (
 \r
   Instance = UDP4_INSTANCE_DATA_FROM_THIS (Udp4Proto);\r
 \r
-  if (Instance->Destroyed) {\r
+  if (Instance->InDestroy) {\r
     return EFI_SUCCESS;\r
   }\r
 \r
   //\r
   // Use the Destroyed flag to avoid the re-entering of the following code.\r
   //\r
-  Instance->Destroyed = TRUE;\r
+  Instance->InDestroy = TRUE;\r
 \r
   //\r
   // Close the Ip4 protocol.\r
@@ -430,6 +492,15 @@ Udp4ServiceBindingDestroyChild (
          gUdp4DriverBinding.DriverBindingHandle,\r
          Instance->ChildHandle\r
          );\r
+  //\r
+  // Close the Ip4 protocol on this instance's IpInfo.\r
+  //\r
+  gBS->CloseProtocol (\r
+         Instance->IpInfo->ChildHandle,\r
+         &gEfiIp4ProtocolGuid,\r
+         gUdp4DriverBinding.DriverBindingHandle,\r
+         Instance->ChildHandle\r
+         );  \r
 \r
   //\r
   // Uninstall the Udp4Protocol previously installed on the ChildHandle.\r
@@ -441,7 +512,7 @@ Udp4ServiceBindingDestroyChild (
                   NULL\r
                   );\r
   if (EFI_ERROR (Status)) {\r
-    Instance->Destroyed = FALSE;\r
+    Instance->InDestroy = FALSE;\r
     return Status;\r
   }\r
 \r
index 9326f3d..8bba357 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   The implementation of the Udp4 protocol.\r
   \r
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -484,7 +484,7 @@ Udp4InitInstance (
   Instance->IcmpError   = EFI_SUCCESS;\r
   Instance->Configured  = FALSE;\r
   Instance->IsNoMapping = FALSE;\r
-  Instance->Destroyed   = FALSE;\r
+  Instance->InDestroy   = FALSE;\r
 }\r
 \r
 \r
index f8a39eb..8142a46 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   EFI UDPv4 protocol implementation.\r
    \r
-Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -31,12 +31,14 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/TimerLib.h>\r
 #include <Library/DpcLib.h>\r
+#include <Library/PrintLib.h>\r
 \r
 #include "Udp4Driver.h"\r
 \r
 \r
 extern EFI_COMPONENT_NAME_PROTOCOL     gUdp4ComponentName;\r
 extern EFI_COMPONENT_NAME2_PROTOCOL    gUdp4ComponentName2;\r
+extern EFI_UNICODE_STRING_TABLE        *gUdpControllerNameTable;\r
 extern EFI_SERVICE_BINDING_PROTOCOL    mUdp4ServiceBinding;\r
 extern EFI_UDP4_PROTOCOL               mUdp4Protocol;\r
 extern UINT16                          mUdp4RandomPort;\r
@@ -109,7 +111,7 @@ typedef struct _UDP4_INSTANCE_DATA_ {
 \r
   IP_IO_IP_INFO         *IpInfo;\r
 \r
-  BOOLEAN               Destroyed;\r
+  BOOLEAN               InDestroy;\r
 } UDP4_INSTANCE_DATA;\r
 \r
 typedef struct _UDP4_RXDATA_WRAP_ {\r
@@ -119,6 +121,12 @@ typedef struct _UDP4_RXDATA_WRAP_ {
   EFI_UDP4_RECEIVE_DATA  RxData;\r
 } UDP4_RXDATA_WRAP;\r
 \r
+typedef struct {\r
+  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;\r
+  UINTN                         NumberOfChildren;\r
+  EFI_HANDLE                    *ChildHandleBuffer;\r
+} UDP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT;\r
+\r
 /**\r
   Reads the current operational settings.\r
 \r
index 0d03783..f4ef59c 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 \r
-Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -168,6 +168,17 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mPxeBcDriverNameTable[] =
   }\r
 };\r
 \r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mPxeBcControllerNameTable[] = {\r
+  {\r
+    "eng;en",\r
+    L"PXE Controller"\r
+  },\r
+  {\r
+    NULL,\r
+    NULL\r
+  }\r
+};\r
+\r
 /**\r
   Retrieves a Unicode string that is the user readable name of the driver.\r
 \r
@@ -302,6 +313,53 @@ PxeBcComponentNameGetControllerName (
   OUT CHAR16                       **ControllerName\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
-}\r
+  EFI_PXE_BASE_CODE_PROTOCOL  *PxeBc;\r
+  EFI_HANDLE                  NicHandle;\r
+  EFI_STATUS                  Status;\r
+  \r
+  if (ControllerHandle == NULL || ChildHandle != NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
 \r
+  NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiArpProtocolGuid);\r
+  if (NicHandle == NULL) {\r
+    NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp4ProtocolGuid);\r
+\r
+    if (NicHandle == NULL) {\r
+      NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);\r
+\r
+      if (NicHandle == NULL) {\r
+        NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp4ProtocolGuid);\r
+\r
+        if (NicHandle == NULL) {\r
+          NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiMtftp4ProtocolGuid);\r
+\r
+          if (NicHandle == NULL) {\r
+            return EFI_UNSUPPORTED;\r
+          }\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  Status = gBS->OpenProtocol (\r
+                  NicHandle,\r
+                  &gEfiPxeBaseCodeProtocolGuid,\r
+                  (VOID **) &PxeBc,\r
+                  NULL,\r
+                  NULL,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return LookupUnicodeString2 (\r
+           Language,\r
+           This->SupportedLanguages,\r
+           mPxeBcControllerNameTable,\r
+           ControllerName,\r
+           (BOOLEAN)(This == &gPxeBcComponentName)\r
+           );\r
+}\r
index 0efcda5..2287863 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   The driver binding for UEFI PXEBC protocol.\r
 \r
-Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -526,7 +526,7 @@ PxeBcDriverBindingStop (
           NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiMtftp4ProtocolGuid);\r
 \r
           if (NicHandle == NULL) {\r
-            return EFI_DEVICE_ERROR;\r
+            return EFI_SUCCESS;\r
           }\r
         }\r
       }\r
index f992cea..10fb7fa 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   HII Config Access protocol implementation of VLAN configuration module.\r
 \r
-Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions\r
 of the BSD License which accompanies this distribution.  The full\r
@@ -489,6 +489,7 @@ InstallVlanConfigForm (
   CHAR16                          *MacString;\r
   EFI_DEVICE_PATH_PROTOCOL        *ChildDevicePath;\r
   EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;\r
+  EFI_VLAN_CONFIG_PROTOCOL        *VlanConfig;\r
 \r
   //\r
   // Create child handle and install HII Config Access Protocol\r
@@ -518,6 +519,22 @@ InstallVlanConfigForm (
   PrivateData->DriverHandle = DriverHandle;\r
 \r
   //\r
+  // Establish the parent-child relationship between the new created\r
+  // child handle and the ControllerHandle.\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  PrivateData->ControllerHandle,\r
+                  &gEfiVlanConfigProtocolGuid,\r
+                  (VOID **)&VlanConfig,\r
+                  PrivateData->ImageHandle,\r
+                  PrivateData->DriverHandle,\r
+                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
   // Publish the HII package list\r
   //\r
   HiiHandle = HiiAddPackages (\r
@@ -594,6 +611,16 @@ UninstallVlanConfigForm (
   }\r
 \r
   //\r
+  // End the parent-child relationship.\r
+  //\r
+  gBS->CloseProtocol (\r
+         PrivateData->ControllerHandle,\r
+         &gEfiVlanConfigProtocolGuid,\r
+         PrivateData->ImageHandle,\r
+         PrivateData->DriverHandle\r
+         );\r
+\r
+  //\r
   // Uninstall HII Config Access Protocol\r
   //\r
   if (PrivateData->DriverHandle != NULL) {\r
index 178c8bc..352df08 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   UEFI Component Name(2) protocol implementation 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
@@ -172,6 +172,19 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE       mDhcp6DriverNameTab
   }\r
 };\r
 \r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE   *gDhcp6ControllerNameTable = NULL;\r
+\r
+CHAR16 *mDhcp6ControllerName[] = {\r
+  L"DHCPv6 (State=0, Init)",\r
+  L"DHCPv6 (State=1, Selecting)",\r
+  L"DHCPv6 (State=2, Requesting)",\r
+  L"DHCPv6 (State=3, Declining)",\r
+  L"DHCPv6 (State=4, Confirming)",\r
+  L"DHCPv6 (State=5, Releasing)",\r
+  L"DHCPv6 (State=6, Bound)",\r
+  L"DHCPv6 (State=7, Renewing)",\r
+  L"DHCPv6 (State=8, Rebinding)"\r
+};\r
 \r
 /**\r
   Retrieves a Unicode string that is the user-readable name of the driver.\r
@@ -229,6 +242,67 @@ Dhcp6ComponentNameGetDriverName (
            );\r
 }\r
 \r
+/**\r
+  Update the component name for the Dhcp6 child handle.\r
+\r
+  @param  Dhcp6[in]                   A pointer to the EFI_DHCP6_PROTOCOL.\r
+\r
+  \r
+  @retval EFI_SUCCESS                 Update the ControllerNameTable of this instance successfully.\r
+  @retval EFI_INVALID_PARAMETER       The input parameter is invalid.\r
+  \r
+**/\r
+EFI_STATUS\r
+UpdateName (\r
+  IN   EFI_DHCP6_PROTOCOL             *Dhcp6\r
+  )\r
+{\r
+  EFI_STATUS                       Status;\r
+  EFI_DHCP6_MODE_DATA              Dhcp6ModeData;\r
+  CHAR16                           HandleName[64];\r
+\r
+  if (Dhcp6 == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Format the child name into the string buffer.\r
+  //\r
+  Status = Dhcp6->GetModeData (Dhcp6, &Dhcp6ModeData, NULL);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  \r
+  if (gDhcp6ControllerNameTable != NULL) {\r
+    FreeUnicodeStringTable (gDhcp6ControllerNameTable);\r
+    gDhcp6ControllerNameTable = NULL;\r
+  }\r
+  \r
+  if (Dhcp6ModeData.Ia == NULL) {\r
+    UnicodeSPrint (HandleName, sizeof (HandleName), L"DHCPv6 (No configured IA)");\r
+  } else {\r
+    StrCpy (HandleName, mDhcp6ControllerName[Dhcp6ModeData.Ia->State]);\r
+  }\r
+  \r
+  Status = AddUnicodeString2 (\r
+             "eng",\r
+             gDhcp6ComponentName.SupportedLanguages,\r
+             &gDhcp6ControllerNameTable,\r
+             HandleName,\r
+             TRUE\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  \r
+  return AddUnicodeString2 (\r
+           "en",\r
+           gDhcp6ComponentName2.SupportedLanguages,\r
+           &gDhcp6ControllerNameTable,\r
+           HandleName,\r
+           FALSE\r
+           );\r
+}\r
 \r
 /**\r
   Retrieves a Unicode string that is the user-readable name of the controller\r
@@ -308,5 +382,57 @@ Dhcp6ComponentNameGetControllerName (
   OUT CHAR16                                          **ControllerName\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  EFI_STATUS                    Status;\r
+  EFI_DHCP6_PROTOCOL            *Dhcp6;\r
+\r
+  //\r
+  // Only provide names for child handles.\r
+  //\r
+  if (ChildHandle == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  \r
+  // \r
+  // Make sure this driver produced ChildHandle \r
+  // \r
+  Status = EfiTestChildHandle (\r
+             ControllerHandle,\r
+             ChildHandle, \r
+             &gEfiUdp6ProtocolGuid\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Retrieve an instance of a produced protocol from ChildHandle\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  ChildHandle,\r
+                  &gEfiDhcp6ProtocolGuid,\r
+                  (VOID **)&Dhcp6, \r
+                  NULL,\r
+                  NULL,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Update the component name for this child handle.\r
+  //\r
+  Status = UpdateName (Dhcp6);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return LookupUnicodeString2 (\r
+           Language,\r
+           This->SupportedLanguages,\r
+           gDhcp6ControllerNameTable,\r
+           ControllerName,\r
+           (BOOLEAN)(This == &gDhcp6ComponentName)\r
+           );\r
 }\r
+\r
index 346986b..42caefb 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
index 4ef7f17..bec47a0 100644 (file)
@@ -2,7 +2,7 @@
   Driver Binding functions and Service Binding functions\r
   declaration 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
@@ -21,6 +21,7 @@
 \r
 extern EFI_COMPONENT_NAME_PROTOCOL  gDhcp6ComponentName;\r
 extern EFI_COMPONENT_NAME2_PROTOCOL gDhcp6ComponentName2;\r
+extern EFI_UNICODE_STRING_TABLE     *gDhcp6ControllerNameTable;\r
 \r
 /**\r
   Test to see if this driver supports ControllerHandle. This service\r
index 2c2b9f9..934c03e 100644 (file)
@@ -216,12 +216,11 @@ EfiDhcp6Stop (
 \r
   Instance->UdpSts = EFI_ALREADY_STARTED;\r
   Status = Dhcp6SendReleaseMsg (Instance, Instance->IaCb.Ia);\r
+  gBS->RestoreTPL (OldTpl);\r
   if (EFI_ERROR (Status)) {\r
     goto ON_EXIT;\r
   }\r
 \r
-  gBS->RestoreTPL (OldTpl);\r
-\r
   //\r
   // Poll udp out of the net tpl if synchoronus call.\r
   //\r
index d4e9746..71b16b1 100644 (file)
@@ -34,6 +34,7 @@
 #include <Library/UefiLib.h>\r
 #include <Library/BaseLib.h>\r
 #include <Library/NetLib.h>\r
+#include <Library/PrintLib.h>\r
 \r
 \r
 typedef struct _DHCP6_IA_CB    DHCP6_IA_CB;\r
@@ -245,7 +246,7 @@ struct _DHCP6_INSTANCE {
   EFI_DHCP6_PACKET              *AdSelect;\r
   UINT8                         AdPref;\r
   EFI_IPv6_ADDRESS              *Unicast;\r
-  EFI_STATUS                    UdpSts;\r
+  volatile EFI_STATUS           UdpSts;\r
   BOOLEAN                       InDestroy;\r
   BOOLEAN                       MediaPresent;\r
   UINT64                        StartTime;\r
@@ -266,7 +267,6 @@ struct _DHCP6_SERVICE {
   UINT32                        Xid;\r
   LIST_ENTRY                    Child;\r
   UINTN                         NumOfChild;\r
-  BOOLEAN                       InDestroy;\r
 };\r
 \r
 /**\r
index f2e33f3..0e83d07 100644 (file)
@@ -2510,7 +2510,7 @@ Dhcp6HandleStateful (
   ClientId = Service->ClientId;\r
   Status   = EFI_SUCCESS;\r
 \r
-  if (Instance->InDestroy || Instance->Config == NULL) {\r
+  if (Instance->Config == NULL) {\r
     goto ON_CONTINUE;\r
   }\r
 \r
@@ -2624,10 +2624,6 @@ Dhcp6HandleStateless (
   IsMatched = FALSE;\r
   InfCb     = NULL;\r
 \r
-  if (Instance->InDestroy) {\r
-    goto ON_EXIT;\r
-  }\r
-\r
   if (Packet->Dhcp6.Header.MessageType != Dhcp6MsgReply) {\r
     goto ON_EXIT;\r
   }\r
index e4e28e8..1ee21f5 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   UEFI Component Name(2) protocol implementation for iSCSI.\r
 \r
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -43,6 +43,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE     mIScsiDriverNameTable
   }\r
 };\r
 \r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE  *gIScsiControllerNameTable = NULL;\r
+\r
 /**\r
   Retrieves a Unicode string that is the user readable name of the driver.\r
 \r
@@ -100,6 +102,99 @@ IScsiComponentNameGetDriverName (
 }\r
 \r
 /**\r
+  Update the component name for the iSCSI NIC handle.\r
+\r
+  @param[in]  Controller            The handle of the NIC controller.\r
+  @param[in]  Ipv6Flag              TRUE if IP6 network stack is used.\r
+  \r
+  @retval EFI_SUCCESS               Update the ControllerNameTable of this instance successfully.\r
+  @retval EFI_INVALID_PARAMETER     The input parameter is invalid.\r
+  @retval EFI_UNSUPPORTED           Can't get the corresponding NIC info from the Controller handle.\r
+  \r
+**/\r
+EFI_STATUS\r
+UpdateName (\r
+  IN   EFI_HANDLE  Controller,\r
+  IN   BOOLEAN     Ipv6Flag\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  EFI_MAC_ADDRESS             MacAddr;\r
+  UINTN                       HwAddressSize;\r
+  UINT16                      VlanId;\r
+  ISCSI_NIC_INFO              *ThisNic;\r
+  ISCSI_NIC_INFO              *NicInfo;\r
+  LIST_ENTRY                  *Entry;\r
+  CHAR16                      HandleName[80];\r
+\r
+  //\r
+  // Get MAC address of this network device.\r
+  //\r
+  Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Get VLAN ID of this network device.\r
+  //\r
+  VlanId = NetLibGetVlanId (Controller);\r
+\r
+  //\r
+  // Check whether the NIC information exists.\r
+  //\r
+  ThisNic = NULL;\r
+\r
+  NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {\r
+    NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);\r
+    if (NicInfo->HwAddressSize == HwAddressSize &&\r
+        CompareMem (&NicInfo->PermanentAddress, MacAddr.Addr, HwAddressSize) == 0 &&\r
+        NicInfo->VlanId == VlanId) {\r
+\r
+      ThisNic = NicInfo;\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (ThisNic == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  UnicodeSPrint (\r
+    HandleName,\r
+    sizeof (HandleName),\r
+    L"iSCSI (%s, NicIndex=%d)",\r
+    Ipv6Flag ? L"IPv6" : L"IPv4",\r
+    ThisNic->NicIndex\r
+  );\r
+\r
+  if (gIScsiControllerNameTable != NULL) {\r
+    FreeUnicodeStringTable (gIScsiControllerNameTable);\r
+    gIScsiControllerNameTable = NULL;\r
+  }\r
+\r
+  Status = AddUnicodeString2 (\r
+             "eng",\r
+             gIScsiComponentName.SupportedLanguages,\r
+             &gIScsiControllerNameTable,\r
+             HandleName,\r
+             TRUE\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return AddUnicodeString2 (\r
+           "en",\r
+           gIScsiComponentName2.SupportedLanguages,\r
+           &gIScsiControllerNameTable,\r
+           HandleName,\r
+           FALSE\r
+           );\r
+}\r
+\r
+\r
+/**\r
   Retrieves a Unicode string that is the user readable name of the controller\r
   that is being managed by a driver.\r
 \r
@@ -177,5 +272,54 @@ IScsiComponentNameGetControllerName (
   OUT CHAR16                        **ControllerName\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  EFI_HANDLE                      IScsiController;\r
+  BOOLEAN                         Ipv6Flag;\r
+  EFI_STATUS                      Status;\r
+  EFI_GUID                        *IScsiPrivateGuid;\r
+  ISCSI_PRIVATE_PROTOCOL          *IScsiIdentifier;\r
+\r
+  //\r
+  // Get the handle of the controller we are controling.\r
+  //\r
+  IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp4ProtocolGuid);\r
+  if (IScsiController != NULL) {\r
+    IScsiPrivateGuid = &gIScsiV4PrivateGuid;\r
+    Ipv6Flag = FALSE;\r
+  } else {\r
+    IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp6ProtocolGuid);\r
+    if (IScsiController != NULL) {\r
+      IScsiPrivateGuid = &gIScsiV6PrivateGuid;\r
+      Ipv6Flag = TRUE;\r
+    } else {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+  }\r
+\r
+  // \r
+  // Retrieve an instance of a produced protocol from IScsiController  \r
+  // \r
+  Status = gBS->OpenProtocol (\r
+                  IScsiController,\r
+                  IScsiPrivateGuid,\r
+                  (VOID **) &IScsiIdentifier,\r
+                  NULL,\r
+                  NULL,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = UpdateName(IScsiController, Ipv6Flag);\r
+  if (EFI_ERROR(Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return LookupUnicodeString2 (\r
+           Language,\r
+           This->SupportedLanguages,\r
+           gIScsiControllerNameTable,\r
+           ControllerName,\r
+           (BOOLEAN)(This == &gIScsiComponentName)\r
+           );\r
 }\r
index 2bf102b..2627a59 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   iSCSI DHCP6 related configuration routines.\r
 \r
-Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -250,6 +250,7 @@ IScsiDhcp6ParseReply (
   EFI_DHCP6_PACKET_OPTION     *BootFileOpt;\r
   EFI_DHCP6_PACKET_OPTION     **OptionList;\r
   ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData;\r
+  UINT16                      ParaLen;\r
  \r
   OptionCount = 0;\r
   BootFileOpt = NULL;\r
@@ -282,7 +283,7 @@ IScsiDhcp6ParseReply (
     if (OptionList[Index]->OpCode == DHCP6_OPT_DNS_SERVERS) {\r
 \r
       if (((OptionList[Index]->OpLen & 0xf) != 0) || (OptionList[Index]->OpLen == 0)) {\r
-        Status = EFI_INVALID_PARAMETER;\r
+        Status = EFI_UNSUPPORTED;\r
         goto Exit;\r
       }\r
       //\r
@@ -302,6 +303,24 @@ IScsiDhcp6ParseReply (
       // The server sends this option to inform the client about an URL to a boot file.\r
       //\r
       BootFileOpt = OptionList[Index];\r
+    } else if (OptionList[Index]->OpCode == DHCP6_OPT_BOOT_FILE_PARA) {\r
+      //\r
+      // The server sends this option to inform the client about DHCP6 server address.\r
+      //\r
+      if (OptionList[Index]->OpLen < 18) {\r
+        Status = EFI_UNSUPPORTED;\r
+        goto Exit;\r
+      }\r
+      //\r
+      // Check param-len 1, should be 16 bytes.\r
+      //\r
+      CopyMem (&ParaLen, &OptionList[Index]->Data[0], sizeof (UINT16));\r
+      if (NTOHS (ParaLen) != 16) {\r
+        Status = EFI_UNSUPPORTED;\r
+        goto Exit;\r
+      }\r
+\r
+      CopyMem (&ConfigData->DhcpServer, &OptionList[Index]->Data[2], sizeof (EFI_IPv6_ADDRESS));\r
     }\r
   }\r
 \r
@@ -405,7 +424,7 @@ IScsiDoDhcp6 (
     goto ON_EXIT;\r
   }\r
 \r
-  Oro = AllocateZeroPool (sizeof (EFI_DHCP6_PACKET_OPTION) + 3);\r
+  Oro = AllocateZeroPool (sizeof (EFI_DHCP6_PACKET_OPTION) + 5);\r
   if (Oro == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto ON_EXIT;\r
@@ -416,9 +435,10 @@ IScsiDoDhcp6 (
   // All members in EFI_DHCP6_PACKET_OPTION are in network order.\r
   //\r
   Oro->OpCode  = HTONS (DHCP6_OPT_REQUEST_OPTION);\r
-  Oro->OpLen   = HTONS (2 * 2);\r
+  Oro->OpLen   = HTONS (2 * 3);\r
   Oro->Data[1] = DHCP6_OPT_DNS_SERVERS;\r
   Oro->Data[3] = DHCP6_OPT_BOOT_FILE_URL;\r
+  Oro->Data[5] = DHCP6_OPT_BOOT_FILE_PARA;\r
 \r
   InfoReqReXmit.Irt = 4;\r
   InfoReqReXmit.Mrc = 1;\r
index fe3dfb7..4ca25bd 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   The header file of iSCSI DHCP6 related configuration routines.\r
 \r
-Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -22,6 +22,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 /// Assigned by IANA, RFC 5970\r
 ///\r
 #define DHCP6_OPT_BOOT_FILE_URL  59\r
+#define DHCP6_OPT_BOOT_FILE_PARA 60\r
 \r
 #define ISCSI_ROOT_PATH_ID                   "iscsi:"\r
 #define ISCSI_ROOT_PATH_FIELD_DELIMITER      ':'\r
index 7d8b184..2fd4c95 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   The entry point of IScsi driver.\r
 \r
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -23,8 +23,8 @@ EFI_DRIVER_BINDING_PROTOCOL gIScsiDriverBinding = {
   NULL\r
 };\r
 \r
-EFI_GUID                    mIScsiV4PrivateGuid = ISCSI_V4_PRIVATE_GUID;\r
-EFI_GUID                    mIScsiV6PrivateGuid = ISCSI_V6_PRIVATE_GUID;\r
+EFI_GUID                    gIScsiV4PrivateGuid = ISCSI_V4_PRIVATE_GUID;\r
+EFI_GUID                    gIScsiV6PrivateGuid = ISCSI_V6_PRIVATE_GUID;\r
 ISCSI_PRIVATE_DATA          *mPrivate           = NULL;\r
 \r
 /**\r
@@ -121,7 +121,7 @@ IScsiDriverBindingSupported (
 \r
   Status = gBS->OpenProtocol (\r
                   ControllerHandle,\r
-                  &mIScsiV4PrivateGuid,\r
+                  &gIScsiV4PrivateGuid,\r
                   NULL,\r
                   This->DriverBindingHandle,\r
                   ControllerHandle,\r
@@ -150,7 +150,7 @@ IScsiDriverBindingSupported (
 \r
   Status = gBS->OpenProtocol (\r
                   ControllerHandle,\r
-                  &mIScsiV6PrivateGuid,\r
+                  &gIScsiV6PrivateGuid,\r
                   NULL,\r
                   This->DriverBindingHandle,\r
                   ControllerHandle,\r
@@ -231,11 +231,11 @@ IScsiStart (
   //\r
 \r
   if (IpVersion == IP_VERSION_4) {\r
-    IScsiPrivateGuid      = &mIScsiV4PrivateGuid;\r
+    IScsiPrivateGuid      = &gIScsiV4PrivateGuid;\r
     TcpServiceBindingGuid = &gEfiTcp4ServiceBindingProtocolGuid;\r
     ProtocolGuid          = &gEfiTcp4ProtocolGuid;\r
   } else if (IpVersion == IP_VERSION_6) {\r
-    IScsiPrivateGuid      = &mIScsiV6PrivateGuid;\r
+    IScsiPrivateGuid      = &gIScsiV6PrivateGuid;\r
     TcpServiceBindingGuid = &gEfiTcp6ServiceBindingProtocolGuid;\r
     ProtocolGuid          = &gEfiTcp6ProtocolGuid;\r
   } else {\r
@@ -931,13 +931,13 @@ IScsiDriverBindingStop (
   //\r
   IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp4ProtocolGuid);\r
   if (IScsiController != NULL) {\r
-    ProtocolGuid            = &mIScsiV4PrivateGuid;\r
+    ProtocolGuid            = &gIScsiV4PrivateGuid;\r
     TcpProtocolGuid         = &gEfiTcp4ProtocolGuid;\r
     TcpServiceBindingGuid   = &gEfiTcp4ServiceBindingProtocolGuid;\r
   } else {\r
     IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp6ProtocolGuid);\r
     ASSERT (IScsiController != NULL);\r
-    ProtocolGuid            = &mIScsiV6PrivateGuid;\r
+    ProtocolGuid            = &gIScsiV6PrivateGuid;\r
     TcpProtocolGuid         = &gEfiTcp6ProtocolGuid;\r
     TcpServiceBindingGuid   = &gEfiTcp6ServiceBindingProtocolGuid;\r
   }\r
@@ -1060,6 +1060,11 @@ IScsiUnload (
          &gIScsiAuthenticationInfo,\r
          NULL\r
          );\r
+\r
+  if (gIScsiControllerNameTable!= NULL) {\r
+    FreeUnicodeStringTable (gIScsiControllerNameTable);\r
+    gIScsiControllerNameTable = NULL;\r
+  }\r
   \r
   return gBS->UninstallMultipleProtocolInterfaces (\r
                 ImageHandle,\r
index 04866f0..8c266fe 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   The header file of IScsiDriver.c.\r
 \r
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -33,9 +33,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 extern EFI_COMPONENT_NAME2_PROTOCOL       gIScsiComponentName2;\r
 extern EFI_COMPONENT_NAME_PROTOCOL        gIScsiComponentName;\r
+extern EFI_UNICODE_STRING_TABLE           *gIScsiControllerNameTable;\r
 extern EFI_ISCSI_INITIATOR_NAME_PROTOCOL  gIScsiInitiatorName;\r
 extern EFI_AUTHENTICATION_INFO_PROTOCOL   gIScsiAuthenticationInfo;\r
 extern EFI_EXT_SCSI_PASS_THRU_PROTOCOL    gIScsiExtScsiPassThruProtocolTemplate;\r
+extern EFI_GUID                           gIScsiV4PrivateGuid;\r
+extern EFI_GUID                           gIScsiV6PrivateGuid;\r
 \r
 typedef struct {\r
   CHAR16          PortString[ISCSI_NAME_IFR_MAX_SIZE];\r
index 879d310..9dba4e6 100644 (file)
@@ -321,14 +321,10 @@ IScsiFillNICAndTargetSections (
       Nic->SubnetMaskPrefixLength = NvData->PrefixLength;\r
       CopyMem (&Nic->Ip, &NvData->LocalIp, sizeof (EFI_IPv6_ADDRESS));\r
       CopyMem (&Nic->Gateway, &NvData->Gateway, sizeof (EFI_IPv6_ADDRESS));\r
-      \r
       CopyMem (&Nic->PrimaryDns, &Attempt->PrimaryDns, sizeof (EFI_IPv6_ADDRESS));\r
       CopyMem (&Nic->SecondaryDns, &Attempt->SecondaryDns, sizeof (EFI_IPv6_ADDRESS));\r
-      //\r
-      // TODO: DHCP server address cannot be retrieved by DHCPv6 process since \r
-      // DHCP server option is removed.\r
-      //CopyMem (&Nic->DhcpServer, &Attempt->DhcpServer, sizeof (EFI_IPv6_ADDRESS));\r
-      //\r
+      CopyMem (&Nic->DhcpServer, &Attempt->DhcpServer, sizeof (EFI_IPv6_ADDRESS));\r
+\r
     } else {\r
       ASSERT (FALSE);\r
     }\r
index bcdf4b1..dc16426 100644 (file)
@@ -2,7 +2,7 @@
   Implementation of EFI_COMPONENT_NAME_PROTOCOL and\r
   EFI_COMPONENT_NAME2_PROTOCOL protocol.\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
@@ -174,6 +174,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE      mIp6DriverNameTable[
   }\r
 };\r
 \r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE      *gIp6ControllerNameTable = NULL;\r
+\r
 /**\r
   Retrieves a Unicode string that is the user-readable name of the driver.\r
 \r
@@ -232,6 +234,88 @@ Ip6ComponentNameGetDriverName (
 }\r
 \r
 /**\r
+  Update the component name for the IP6 child handle.\r
+\r
+  @param  Ip6[in]                   A pointer to the EFI_IP6_PROTOCOL.\r
+\r
+  \r
+  @retval EFI_SUCCESS               Update the ControllerNameTable of this instance successfully.\r
+  @retval EFI_INVALID_PARAMETER     The input parameter is invalid.\r
+  \r
+**/\r
+EFI_STATUS\r
+UpdateName (\r
+  IN    EFI_IP6_PROTOCOL         *Ip6\r
+  )\r
+{\r
+  EFI_STATUS                       Status;\r
+  CHAR16                           HandleName[128];\r
+  EFI_IP6_MODE_DATA                Ip6ModeData;\r
+  UINTN                            Offset;\r
+  CHAR16                           Address[sizeof"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];\r
+\r
+  if (Ip6 == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Format the child name into the string buffer.\r
+  //\r
+  Offset = 0;\r
+  Status = Ip6->GetModeData (Ip6, &Ip6ModeData, NULL, NULL);\r
+  if (!EFI_ERROR (Status) && Ip6ModeData.IsStarted) {\r
+    Status = NetLibIp6ToStr (&Ip6ModeData.ConfigData.StationAddress, Address, sizeof(Address));\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+    Offset += UnicodeSPrint (\r
+                HandleName,\r
+                sizeof(HandleName),\r
+                L"IPv6(StationAddress=%s, ",\r
+                Address\r
+                );\r
+    Status = NetLibIp6ToStr (&Ip6ModeData.ConfigData.DestinationAddress, Address, sizeof(Address));\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+    UnicodeSPrint (\r
+      HandleName + Offset,\r
+      sizeof(HandleName) - Offset,\r
+      L"DestinationAddress=%s)",\r
+      Address\r
+      );\r
+  } else if (!Ip6ModeData.IsStarted) {\r
+    UnicodeSPrint (HandleName, sizeof(HandleName), L"IPv6(Not started)");\r
+  } else {\r
+    UnicodeSPrint (HandleName, sizeof(HandleName), L"IPv6(%r)", Status);\r
+  }\r
+\r
+  if (gIp6ControllerNameTable != NULL) {\r
+      FreeUnicodeStringTable (gIp6ControllerNameTable);\r
+      gIp6ControllerNameTable = NULL;\r
+  }\r
+  \r
+  Status = AddUnicodeString2 (\r
+             "eng",\r
+             gIp6ComponentName.SupportedLanguages,\r
+             &gIp6ControllerNameTable,\r
+             HandleName,\r
+             TRUE\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  \r
+  return AddUnicodeString2 (\r
+           "en",\r
+           gIp6ComponentName2.SupportedLanguages,\r
+           &gIp6ControllerNameTable,\r
+           HandleName,\r
+           FALSE\r
+           );\r
+}\r
+\r
+/**\r
   Retrieves a Unicode string that is the user-readable name of the controller\r
   that is being managed by a driver.\r
 \r
@@ -309,5 +393,56 @@ Ip6ComponentNameGetControllerName (
   OUT CHAR16                                          **ControllerName\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  EFI_STATUS                    Status;\r
+  EFI_IP6_PROTOCOL              *Ip6;\r
+  \r
+  //\r
+  // Only provide names for child handles.\r
+  //\r
+  if (ChildHandle == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Make sure this driver produced ChildHandle \r
+  //\r
+  Status = EfiTestChildHandle (\r
+             ControllerHandle,\r
+             ChildHandle,\r
+             &gEfiManagedNetworkProtocolGuid\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Retrieve an instance of a produced protocol from ChildHandle\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  ChildHandle,\r
+                  &gEfiIp6ProtocolGuid,\r
+                  (VOID **)&Ip6,\r
+                  NULL,\r
+                  NULL,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Update the component name for this child handle.\r
+  //\r
+  Status = UpdateName (Ip6);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return LookupUnicodeString2 (\r
+           Language,\r
+           This->SupportedLanguages,\r
+           gIp6ControllerNameTable,\r
+           ControllerName,\r
+           (BOOLEAN)(This == &gIp6ComponentName)\r
+           );\r
 }\r
index 2ae14a9..459acd2 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   The implementation of common functions shared by IP6 driver.\r
 \r
-  Copyright (c) 2009 - 2010, 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
@@ -329,6 +329,37 @@ Ip6AddAddr (
 }\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
+Ip6DestroyChildEntryByAddr (\r
+  IN LIST_ENTRY         *Entry,\r
+  IN VOID               *Context\r
+)\r
+{\r
+  IP6_PROTOCOL                  *Instance;\r
+  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;\r
+  EFI_IPv6_ADDRESS              *Address;\r
+  \r
+  Instance = NET_LIST_USER_STRUCT_S (Entry, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE);\r
+  ServiceBinding = ((IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT*) Context)->ServiceBinding;\r
+  Address = ((IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT*) Context)->Address;\r
+\r
+  if ((Instance->State == IP6_STATE_CONFIGED) && EFI_IP6_EQUAL (&Instance->ConfigData.StationAddress, Address)) {\r
+    return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);\r
+  }\r
+  \r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
   Destroy the IP instance if its StationAddress is removed. It is the help function\r
   for Ip6RemoveAddr().\r
 \r
@@ -342,35 +373,20 @@ Ip6DestroyInstanceByAddress (
   IN EFI_IPv6_ADDRESS  *Address\r
   )\r
 {\r
-  BOOLEAN                       OneDestroyed;\r
-  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;\r
-  LIST_ENTRY                    *Entry;\r
-  IP6_PROTOCOL                  *Instance;\r
+  LIST_ENTRY                    *List;\r
+  IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT  Context;\r
 \r
   NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);\r
 \r
-  ServiceBinding = &IpSb->ServiceBinding;\r
-\r
-  //\r
-  // Upper layer IP protocol consumers may have tight relationship between several\r
-  // IP protocol instances, in other words, calling ServiceBinding->DestroyChild to\r
-  // destroy one IP child may cause other related IP children destroyed too. This\r
-  // will probably leave hole in the children list when we iterate it. So everytime\r
-  // we just destroy one child then back to the start point to iterate the list.\r
-  //\r
-  do {\r
-    OneDestroyed = FALSE;\r
-\r
-    NET_LIST_FOR_EACH (Entry, &IpSb->Children) {\r
-      Instance = NET_LIST_USER_STRUCT_S (Entry, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE);\r
-\r
-      if ((Instance->State == IP6_STATE_CONFIGED) && EFI_IP6_EQUAL (&Instance->ConfigData.StationAddress, Address)) {\r
-        ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);\r
-        OneDestroyed = TRUE;\r
-        break;\r
-      }\r
-    }\r
-  } while (OneDestroyed);\r
+  List = &IpSb->Children;\r
+  Context.ServiceBinding = &IpSb->ServiceBinding;\r
+  Context.Address = Address;\r
+  NetDestroyLinkList (\r
+    List,\r
+    Ip6DestroyChildEntryByAddr,\r
+    &Context,\r
+    NULL\r
+    );\r
 }\r
 \r
 /**\r
index c3755f4..9c2ddf4 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Common definition and functions for IP6 driver.\r
 \r
-  Copyright (c) 2009 - 2010, 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
@@ -60,6 +60,11 @@ typedef enum {
   Ip6AnyCast\r
 } IP6_ADDRESS_TYPE;\r
 \r
+typedef struct {\r
+  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;\r
+  EFI_IPv6_ADDRESS              *Address;\r
+} IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT;\r
+\r
 typedef struct _IP6_INTERFACE    IP6_INTERFACE;\r
 typedef struct _IP6_PROTOCOL     IP6_PROTOCOL;\r
 typedef struct _IP6_SERVICE      IP6_SERVICE;\r
index 3fd1f73..27550a5 100644 (file)
@@ -114,14 +114,16 @@ Ip6CleanService (
 \r
   Ip6ConfigCleanInstance (&IpSb->Ip6ConfigInstance);\r
 \r
-  //\r
-  // Leave link-scope all-nodes multicast address (FF02::1)\r
-  //\r
-  Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &AllNodes);\r
+  if (!IpSb->LinkLocalDadFail) {\r
+    //\r
+    // Leave link-scope all-nodes multicast address (FF02::1)\r
+    //\r
+    Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &AllNodes);\r
 \r
-  Status = Ip6LeaveGroup (IpSb, &AllNodes);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
+    Status = Ip6LeaveGroup (IpSb, &AllNodes);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }  \r
   }\r
 \r
   if (IpSb->DefaultInterface != NULL) {\r
@@ -244,7 +246,6 @@ Ip6CreateService (
   IpSb->ServiceBinding.CreateChild  = Ip6ServiceBindingCreateChild;\r
   IpSb->ServiceBinding.DestroyChild = Ip6ServiceBindingDestroyChild;\r
   IpSb->State                       = IP6_SERVICE_UNSTARTED;\r
-  IpSb->InDestroy                   = FALSE;\r
 \r
   IpSb->NumChildren                 = 0;\r
   InitializeListHead (&IpSb->Children);\r
@@ -573,6 +574,43 @@ Ip6DriverBindingStart (
 }\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
+Ip6DestroyChildEntryInHandleBuffer (\r
+  IN LIST_ENTRY         *Entry,\r
+  IN VOID               *Context\r
+)\r
+{\r
+  IP6_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, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE);\r
+  ServiceBinding    = ((IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;\r
+  NumberOfChildren  = ((IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;\r
+  ChildHandleBuffer = ((IP6_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
   Stop this driver on ControllerHandle.\r
 \r
   @param[in]  This               Protocol instance pointer.\r
@@ -595,30 +633,23 @@ Ip6DriverBindingStop (
   IN  EFI_HANDLE                   *ChildHandleBuffer OPTIONAL\r
   )\r
 {\r
-  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;\r
-  IP6_SERVICE                   *IpSb;\r
-  IP6_PROTOCOL                  *IpInstance;\r
-  EFI_HANDLE                    NicHandle;\r
-  EFI_STATUS                    Status;\r
-  BOOLEAN                       IsDhcp6;\r
-  EFI_TPL                       OldTpl;\r
-  INTN                          State;\r
+  EFI_SERVICE_BINDING_PROTOCOL            *ServiceBinding;\r
+  IP6_SERVICE                             *IpSb;\r
+  EFI_HANDLE                              NicHandle;\r
+  EFI_STATUS                              Status;\r
+  LIST_ENTRY                              *List;\r
+  INTN                                    State;\r
+  BOOLEAN                                 IsDhcp6;\r
+  IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;\r
 \r
   IsDhcp6   = FALSE;\r
-  NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp6ProtocolGuid);\r
-\r
-  if (NicHandle != NULL) {\r
-    //\r
-    // DriverBindingStop is triggered by the uninstallation of the EFI DHCPv6\r
-    // Protocol used by Ip6Config.\r
-    //\r
-    IsDhcp6 = TRUE;\r
-  } else {\r
-\r
-    NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);\r
-\r
-    if (NicHandle == NULL) {\r
-      return EFI_DEVICE_ERROR;\r
+  NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);\r
+  if (NicHandle == NULL) {\r
+    NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp6ProtocolGuid);\r
+    if (NicHandle != NULL) {\r
+      IsDhcp6 = TRUE;\r
+    } else {\r
+      return EFI_SUCCESS;\r
     }\r
   }\r
 \r
@@ -636,21 +667,25 @@ Ip6DriverBindingStop (
 \r
   IpSb = IP6_SERVICE_FROM_PROTOCOL (ServiceBinding);\r
 \r
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
-  if (IpSb->InDestroy) {\r
-    Status = EFI_SUCCESS;\r
-    goto Exit;\r
-  }\r
-\r
   if (IsDhcp6) {\r
-\r
     Status = Ip6ConfigDestroyDhcp6 (&IpSb->Ip6ConfigInstance);\r
     gBS->CloseEvent (IpSb->Ip6ConfigInstance.Dhcp6Event);\r
     IpSb->Ip6ConfigInstance.Dhcp6Event = NULL;\r
-  } else if (NumberOfChildren == 0) {\r
-\r
-    IpSb->InDestroy = TRUE;\r
+  } else if (NumberOfChildren != 0) {\r
+    //\r
+    // NumberOfChildren is not zero, destroy the IP6 children instances in ChildHandleBuffer.\r
+    //\r
+    List = &IpSb->Children;\r
+    Context.ServiceBinding    = ServiceBinding;\r
+    Context.NumberOfChildren  = NumberOfChildren;\r
+    Context.ChildHandleBuffer = ChildHandleBuffer;\r
+    Status = NetDestroyLinkList (\r
+               List,\r
+               Ip6DestroyChildEntryInHandleBuffer,\r
+               &Context,\r
+               NULL\r
+               );\r
+  } else if (IsListEmpty (&IpSb->Children)) {\r
     State           = IpSb->State;\r
     IpSb->State     = IP6_SERVICE_DESTROY;\r
 \r
@@ -675,24 +710,10 @@ Ip6DriverBindingStop (
                     );\r
     ASSERT_EFI_ERROR (Status);\r
     FreePool (IpSb);\r
-  } else {\r
-    //\r
-    // NumberOfChildren is not zero, destroy all IP6 children instances.\r
-    //\r
-    while (!IsListEmpty (&IpSb->Children)) {\r
-      IpInstance = NET_LIST_HEAD (&IpSb->Children, IP6_PROTOCOL, Link);\r
-      ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle);\r
-    }\r
-\r
-    if (IpSb->NumChildren != 0) {\r
-      Status = EFI_DEVICE_ERROR;\r
-    }\r
+    Status = EFI_SUCCESS;\r
   }\r
-\r
+  \r
 Exit:\r
-\r
-  gBS->RestoreTPL (OldTpl);\r
-\r
   return Status;\r
 }\r
 \r
@@ -830,7 +851,6 @@ Ip6ServiceBindingDestroyChild (
   IP6_PROTOCOL              *IpInstance;\r
   EFI_IP6_PROTOCOL          *Ip6;\r
   EFI_TPL                   OldTpl;\r
-  INTN                      State;\r
 \r
   if ((This == NULL) || (ChildHandle == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -868,13 +888,12 @@ Ip6ServiceBindingDestroyChild (
   // when UDP driver is being stopped, it will destroy all\r
   // the IP child it opens.\r
   //\r
-  if (IpInstance->State == IP6_STATE_DESTROY) {\r
+  if (IpInstance->InDestroy) {\r
     gBS->RestoreTPL (OldTpl);\r
     return EFI_SUCCESS;\r
   }\r
 \r
-  State             = IpInstance->State;\r
-  IpInstance->State = IP6_STATE_DESTROY;\r
+  IpInstance->InDestroy = TRUE;\r
 \r
   //\r
   // Close the Managed Network protocol.\r
@@ -900,12 +919,13 @@ Ip6ServiceBindingDestroyChild (
   // 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
                   &gEfiIp6ProtocolGuid,\r
                   &IpInstance->Ip6Proto\r
                   );\r
-\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
   if (EFI_ERROR (Status)) {\r
     goto ON_ERROR;\r
   }\r
@@ -935,7 +955,6 @@ Ip6ServiceBindingDestroyChild (
   return EFI_SUCCESS;\r
 \r
 ON_ERROR:\r
-  IpInstance->State = State;\r
   gBS->RestoreTPL (OldTpl);\r
 \r
   return Status;\r
index 4a23d83..d16ff48 100644 (file)
 extern EFI_DRIVER_BINDING_PROTOCOL  gIp6DriverBinding;\r
 extern EFI_COMPONENT_NAME_PROTOCOL  gIp6ComponentName;\r
 extern EFI_COMPONENT_NAME2_PROTOCOL gIp6ComponentName2;\r
+extern EFI_UNICODE_STRING_TABLE     *gIp6ControllerNameTable;\r
+\r
+typedef struct {\r
+  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;\r
+  UINTN                         NumberOfChildren;\r
+  EFI_HANDLE                    *ChildHandleBuffer;\r
+}IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT;\r
 \r
 /**\r
   Clean up an IP6 service binding instance. It releases all\r
index a934188..280cd76 100644 (file)
@@ -565,11 +565,7 @@ Ip6ReceiveFrame (
 {\r
   EFI_STATUS                Status;\r
   IP6_LINK_RX_TOKEN         *Token;\r
-\r
-  if (IpSb->InDestroy) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
+  \r
   NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);\r
 \r
   Token           = &IpSb->RecvRequest;\r
index 44e0392..365495a 100644 (file)
@@ -635,7 +635,7 @@ EfiIp6Configure (
   IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This);\r
   IpSb       = IpInstance->Service;\r
 \r
-  if (IpSb->LinkLocalDadFail) {\r
+  if (IpSb->LinkLocalDadFail && Ip6ConfigData != NULL) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
@@ -1777,10 +1777,6 @@ EfiIp6Cancel (
   IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This);\r
   IpSb       = IpInstance->Service;\r
 \r
-  if (IpSb->LinkLocalDadFail) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
   if (IpInstance->State != IP6_STATE_CONFIGED) {\r
index 1241e63..8f114bb 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Implementation of EFI_IP6_PROTOCOL protocol interfaces and type definitions.\r
 \r
-  Copyright (c) 2009 - 2010, 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
@@ -68,7 +68,6 @@
 //\r
 #define IP6_STATE_UNCONFIGED   0\r
 #define IP6_STATE_CONFIGED     1\r
-#define IP6_STATE_DESTROY      2\r
 \r
 //\r
 // The state of IP6 service. It starts from UNSTARTED. It transits\r
@@ -157,13 +156,13 @@ struct _IP6_PROTOCOL {
   UINT32                    GroupCount;\r
 \r
   EFI_IP6_CONFIG_DATA       ConfigData;\r
+  BOOLEAN                   InDestroy;\r
 };\r
 \r
 struct _IP6_SERVICE {\r
   UINT32                          Signature;\r
   EFI_SERVICE_BINDING_PROTOCOL    ServiceBinding;\r
   INTN                            State;\r
-  BOOLEAN                         InDestroy;\r
 \r
   //\r
   // List of all the IP instances and interfaces, and default\r
index d510f33..9f30f9b 100644 (file)
@@ -821,7 +821,8 @@ Ip6OnDADFinished (
   UINT16                    OptBuf[4];\r
   EFI_DHCP6_PACKET_OPTION   *Oro;\r
   EFI_DHCP6_RETRANSMISSION  InfoReqReXmit;\r
-\r
+  EFI_IPv6_ADDRESS          AllNodes;\r
+  \r
   IpSb     = IpIf->Service;\r
   AddrInfo = DadEntry->AddressInfo;\r
 \r
@@ -922,6 +923,11 @@ Ip6OnDADFinished (
     RemoveEntryList (&DadEntry->Link);\r
     FreePool (DadEntry);\r
     //\r
+    // Leave link-scope all-nodes multicast address (FF02::1)\r
+    //\r
+    Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &AllNodes);\r
+    Ip6LeaveGroup (IpSb, &AllNodes);\r
+    //\r
     // Disable IP operation since link-local address is a duplicate address.\r
     //\r
     IpSb->LinkLocalDadFail = TRUE;\r
index e164d8b..d68b175 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   UEFI Component Name(2) protocol implementation for IPsec 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
@@ -172,6 +172,17 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIpSecDriverNameTable[] =
   }\r
 };\r
 \r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIpSecControllerNameTable[] = {\r
+  {\r
+    "eng;en",\r
+    L"IPsec Controller"\r
+  },\r
+  {\r
+    NULL,\r
+    NULL\r
+  }\r
+};\r
+\r
 /**\r
   Retrieves a Unicode string that is the user-readable name of the driver.\r
 \r
@@ -306,5 +317,35 @@ IpSecComponentNameGetControllerName (
   OUT CHAR16                       **ControllerName\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  // ChildHandle must be NULL for a Device Driver\r
+  //\r
+  if (ChildHandle != NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  \r
+  //\r
+  // Make sure this driver is currently managing ControllerHandle\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiIpSec2ProtocolGuid,\r
+                  NULL,\r
+                  NULL,\r
+                  NULL,\r
+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return LookupUnicodeString2 (\r
+           Language,\r
+           This->SupportedLanguages,\r
+           mIpSecControllerNameTable,\r
+           ControllerName,\r
+           (BOOLEAN) (This == &gIpSecComponentName)\r
+           );\r
 }\r
index 72a5eb0..f4327ab 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   UEFI Component Name(2) protocol implementation for Mtftp6 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
@@ -170,6 +170,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE        mMtftp6DriverNameT
   }\r
 };\r
 \r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE   *gMtftp6ControllerNameTable = NULL;\r
+\r
 /**\r
   Retrieves a Unicode string that is the user-readable name of the driver.\r
 \r
@@ -227,6 +229,74 @@ Mtftp6ComponentNameGetDriverName (
 }\r
 \r
 /**\r
+  Update the component name for the Mtftp6 child handle.\r
+\r
+  @param  Mtftp6[in]                A pointer to the EFI_MTFTP6_PROTOCOL.\r
+\r
+  \r
+  @retval EFI_SUCCESS               Update the ControllerNameTable of this instance successfully.\r
+  @retval EFI_INVALID_PARAMETER     The input parameter is invalid.\r
+  \r
+**/\r
+EFI_STATUS\r
+UpdateName (\r
+  IN    EFI_MTFTP6_PROTOCOL             *Mtftp6\r
+  )\r
+{\r
+  EFI_STATUS                       Status;\r
+  CHAR16                           HandleName[128];\r
+  EFI_MTFTP6_MODE_DATA             Mtftp6ModeData;\r
+  CHAR16                           Address[sizeof"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];\r
+\r
+  if (Mtftp6 == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r