From: sfu5 Date: Thu, 13 Dec 2012 06:47:06 +0000 (+0000) Subject: 1. Add EFI_COMPONENT_NAME2_PROTOCOL.GetControllerName() support. X-Git-Tag: edk2-stable201903~12839 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=216f79703b8cb8dc65abdd768bedb2bcdbc1a1f8 1. Add EFI_COMPONENT_NAME2_PROTOCOL.GetControllerName() support. 2. Fix the driver binding Stop() hang issue in the network stack. 3. Add Ip4 raw data support. 4. Add iSCSI Dhcp option 60 support. Signed-off-by: Fu Siyuan Reviewed-by: Ye Ting Reviewed-by: Ouyang Qian git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13995 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/MdeModulePkg/Include/Library/NetLib.h b/MdeModulePkg/Include/Library/NetLib.h index fa59254a25..d85c259b86 100644 --- a/MdeModulePkg/Include/Library/NetLib.h +++ b/MdeModulePkg/Include/Library/NetLib.h @@ -662,6 +662,72 @@ NetListInsertBefore ( IN OUT LIST_ENTRY *NewEntry ); +/** + Callback function which provided by user to remove one node in NetDestroyLinkList process. + + @param[in] Entry The entry to be removed. + @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList. + + @retval EFI_SUCCESS The entry has been removed successfully. + @retval Others Fail to remove the entry. + +**/ +typedef +EFI_STATUS +(EFIAPI *NET_DESTROY_LINK_LIST_CALLBACK) ( + IN LIST_ENTRY *Entry, + IN VOID *Context OPTIONAL +); + +/** + Safe destroy nodes in a linked list, and return the length of the list after all possible operations finished. + + Destroy network children list by list traversals is not safe due to graph dependencies between nodes. + This function performs a safe traversal to destroy these nodes by checking to see if the node being destroyed + has been removed from the list or not. + If it has been removed, then restart the traversal from the head. + If it hasn't been removed, then continue with the next node directly. + This function will end the iterate and return the CallBack's last return value if error happens, + or retrun EFI_SUCCESS if 2 complete passes are made with no changes in the number of children in the list. + + @param[in] List The head of the list. + @param[in] CallBack Pointer to the callback function to destroy one node in the list. + @param[in] Context Pointer to the callback function's context: corresponds to the + parameter Context in NET_DESTROY_LINK_LIST_CALLBACK. + @param[out] ListLength The length of the link list if the function returns successfully. + + @retval EFI_SUCCESS Two complete passes are made with no changes in the number of children. + @retval EFI_INVALID_PARAMETER The input parameter is invalid. + @retval Others Return the CallBack's last return value. + +**/ +EFI_STATUS +EFIAPI +NetDestroyLinkList ( + IN LIST_ENTRY *List, + IN NET_DESTROY_LINK_LIST_CALLBACK CallBack, + IN VOID *Context, OPTIONAL + OUT UINTN *ListLength OPTIONAL +); + +/** + This function checks the input Handle to see if it's one of these handles in ChildHandleBuffer. + + @param[in] Handle Handle to be checked. + @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. + @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL + if NumberOfChildren is 0. + + @retval TURE Found the input Handle in ChildHandleBuffer. + @retval FALSE Can't find the input Handle in ChildHandleBuffer. + +**/ +BOOLEAN +NetIsInHandleBuffer ( + IN EFI_HANDLE Handle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL +); // // Object container: EFI network stack spec defines various kinds of @@ -1337,6 +1403,28 @@ NetLibStrToIp6andPrefix ( OUT UINT8 *PrefixLength ); +/** + + Convert one EFI_IPv6_ADDRESS to Null-terminated Unicode string. + The text representation of address is defined in RFC 4291. + + @param[in] Ip6Address The pointer to the IPv6 address. + @param[out] String The buffer to return the converted string. + @param[in] StringSize The length in bytes of the input String. + + @retval EFI_SUCCESS Convert to string successfully. + @retval EFI_INVALID_PARAMETER The input parameter is invalid. + @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small for the result. BufferSize has been + updated with the size needed to complete the request. +**/ +EFI_STATUS +EFIAPI +NetLibIp6ToStr ( + IN EFI_IPv6_ADDRESS *Ip6Address, + OUT CHAR16 *String, + IN UINTN StringSize + ); + // // Various signatures // diff --git a/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c b/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c index 956f733400..174c3c83f7 100644 --- a/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c +++ b/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c @@ -40,6 +40,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #define NIC_ITEM_CONFIG_SIZE sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * MAX_IP4_CONFIG_IN_VARIABLE +#define DEFAULT_ZERO_START ((UINTN) ~0) // // All the supported IP4 maskes in host byte order. @@ -1065,6 +1066,115 @@ NetListInsertBefore ( PostEntry->BackLink = NewEntry; } +/** + Safe destroy nodes in a linked list, and return the length of the list after all possible operations finished. + + Destroy network child instance list by list traversals is not safe due to graph dependencies between nodes. + This function performs a safe traversal to destroy these nodes by checking to see if the node being destroyed + has been removed from the list or not. + If it has been removed, then restart the traversal from the head. + If it hasn't been removed, then continue with the next node directly. + This function will end the iterate and return the CallBack's last return value if error happens, + or retrun EFI_SUCCESS if 2 complete passes are made with no changes in the number of children in the list. + + @param[in] List The head of the list. + @param[in] CallBack Pointer to the callback function to destroy one node in the list. + @param[in] Context Pointer to the callback function's context: corresponds to the + parameter Context in NET_DESTROY_LINK_LIST_CALLBACK. + @param[out] ListLength The length of the link list if the function returns successfully. + + @retval EFI_SUCCESS Two complete passes are made with no changes in the number of children. + @retval EFI_INVALID_PARAMETER The input parameter is invalid. + @retval Others Return the CallBack's last return value. + +**/ +EFI_STATUS +EFIAPI +NetDestroyLinkList ( + IN LIST_ENTRY *List, + IN NET_DESTROY_LINK_LIST_CALLBACK CallBack, + IN VOID *Context, OPTIONAL + OUT UINTN *ListLength OPTIONAL +) +{ + UINTN PreviousLength; + LIST_ENTRY *Entry; + LIST_ENTRY *Ptr; + UINTN Length; + EFI_STATUS Status; + + if (List == NULL || CallBack == NULL) { + return EFI_INVALID_PARAMETER; + } + + Length = 0; + do { + PreviousLength = Length; + Entry = GetFirstNode (List); + while (!IsNull (List, Entry)) { + Status = CallBack (Entry, Context); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Walk through the list to see whether the Entry has been removed or not. + // If the Entry still exists, just try to destroy the next one. + // If not, go back to the start point to iterate the list again. + // + for (Ptr = List->ForwardLink; Ptr != List; Ptr = Ptr->ForwardLink) { + if (Ptr == Entry) { + break; + } + } + if (Ptr == Entry) { + Entry = GetNextNode (List, Entry); + } else { + Entry = GetFirstNode (List); + } + } + for (Length = 0, Ptr = List->ForwardLink; Ptr != List; Length++, Ptr = Ptr->ForwardLink); + } while (Length != PreviousLength); + + if (ListLength != NULL) { + *ListLength = Length; + } + return EFI_SUCCESS; +} + +/** + This function checks the input Handle to see if it's one of these handles in ChildHandleBuffer. + + @param[in] Handle Handle to be checked. + @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. + @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL + if NumberOfChildren is 0. + + @retval TURE Found the input Handle in ChildHandleBuffer. + @retval FALSE Can't find the input Handle in ChildHandleBuffer. + +**/ +BOOLEAN +NetIsInHandleBuffer ( + IN EFI_HANDLE Handle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL +) +{ + UINTN Index; + + if (NumberOfChildren == 0 || ChildHandleBuffer == NULL) { + return FALSE; + } + + for (Index = 0; Index < NumberOfChildren; Index++) { + if (Handle == ChildHandleBuffer[Index]) { + return TRUE; + } + } + + return FALSE; +} + /** Initialize the netmap. Netmap is a reposity to keep the pairs. @@ -3175,7 +3285,110 @@ Exit: return Status; } +/** + + Convert one EFI_IPv6_ADDRESS to Null-terminated Unicode string. + The text representation of address is defined in RFC 4291. + + @param[in] Ip6Address The pointer to the IPv6 address. + @param[out] String The buffer to return the converted string. + @param[in] StringSize The length in bytes of the input String. + + @retval EFI_SUCCESS Convert to string successfully. + @retval EFI_INVALID_PARAMETER The input parameter is invalid. + @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small for the result. BufferSize has been + updated with the size needed to complete the request. +**/ +EFI_STATUS +EFIAPI +NetLibIp6ToStr ( + IN EFI_IPv6_ADDRESS *Ip6Address, + OUT CHAR16 *String, + IN UINTN StringSize + ) +{ + UINT16 Ip6Addr[8]; + UINTN Index; + UINTN LongestZerosStart; + UINTN LongestZerosLength; + UINTN CurrentZerosStart; + UINTN CurrentZerosLength; + CHAR16 Buffer[sizeof"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"]; + CHAR16 *Ptr; + + if (Ip6Address == NULL || String == NULL || StringSize == 0) { + return EFI_INVALID_PARAMETER; + } + // + // Convert the UINT8 array to an UINT16 array for easy handling. + // + ZeroMem (Ip6Addr, sizeof (Ip6Addr)); + for (Index = 0; Index < 16; Index++) { + Ip6Addr[Index / 2] |= (Ip6Address->Addr[Index] << ((1 - (Index % 2)) << 3)); + } + + // + // Find the longest zeros and mark it. + // + CurrentZerosStart = DEFAULT_ZERO_START; + CurrentZerosLength = 0; + LongestZerosStart = DEFAULT_ZERO_START; + LongestZerosLength = 0; + for (Index = 0; Index < 8; Index++) { + if (Ip6Addr[Index] == 0) { + if (CurrentZerosStart == DEFAULT_ZERO_START) { + CurrentZerosStart = Index; + CurrentZerosLength = 1; + } else { + CurrentZerosLength++; + } + } else { + if (CurrentZerosStart != DEFAULT_ZERO_START) { + if (CurrentZerosLength > 2 && (LongestZerosStart == (DEFAULT_ZERO_START) || CurrentZerosLength > LongestZerosLength)) { + LongestZerosStart = CurrentZerosStart; + LongestZerosLength = CurrentZerosLength; + } + CurrentZerosStart = DEFAULT_ZERO_START; + CurrentZerosLength = 0; + } + } + } + + if (CurrentZerosStart != DEFAULT_ZERO_START && CurrentZerosLength > 2) { + if (LongestZerosStart == DEFAULT_ZERO_START || LongestZerosLength < CurrentZerosLength) { + LongestZerosStart = CurrentZerosStart; + LongestZerosLength = CurrentZerosLength; + } + } + + Ptr = Buffer; + for (Index = 0; Index < 8; Index++) { + if (LongestZerosStart != DEFAULT_ZERO_START && Index >= LongestZerosStart && Index < LongestZerosStart + LongestZerosLength) { + if (Index == LongestZerosStart) { + *Ptr++ = L':'; + } + continue; + } + if (Index != 0) { + *Ptr++ = L':'; + } + Ptr += UnicodeSPrint(Ptr, 10, L"%x", Ip6Addr[Index]); + } + + if (LongestZerosStart != DEFAULT_ZERO_START && LongestZerosStart + LongestZerosLength == 8) { + *Ptr++ = L':'; + } + *Ptr = L'\0'; + + if ((UINTN)Ptr - (UINTN)Buffer > StringSize) { + return EFI_BUFFER_TOO_SMALL; + } + + StrCpy (String, Buffer); + + return EFI_SUCCESS; +} /** This function obtains the system guid from the smbios table. diff --git a/MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c b/MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c index 37042d11cd..8914ebfa34 100644 --- a/MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c +++ b/MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c @@ -1,7 +1,7 @@ /** @file ARP driver functions. -Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at
@@ -241,6 +241,35 @@ ArpCleanService ( } } +/** + Callback function which provided by user to remove one node in NetDestroyLinkList process. + + @param[in] Entry The entry to be removed. + @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList. + + @retval EFI_SUCCESS The entry has been removed successfully. + @retval Others Fail to remove the entry. + +**/ +EFI_STATUS +ArpDestroyChildEntryInHandleBuffer ( + IN LIST_ENTRY *Entry, + IN VOID *Context +) +{ + ARP_INSTANCE_DATA *Instance; + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + + if (Entry == NULL || Context == NULL) { + return EFI_INVALID_PARAMETER; + } + + Instance = NET_LIST_USER_STRUCT_S (Entry, ARP_INSTANCE_DATA, List, ARP_INSTANCE_DATA_SIGNATURE); + ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *) Context; + + return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle); +} + /** Tests to see if this driver supports a given controller. @@ -446,14 +475,14 @@ ArpDriverBindingStop ( EFI_HANDLE NicHandle; EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; ARP_SERVICE_DATA *ArpService; - ARP_INSTANCE_DATA *Instance; + LIST_ENTRY *List; // // Get the NicHandle which the arp servicebinding is installed on. // NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid); if (NicHandle == NULL) { - return EFI_DEVICE_ERROR; + return EFI_SUCCESS; } // @@ -474,7 +503,21 @@ ArpDriverBindingStop ( ArpService = ARP_SERVICE_DATA_FROM_THIS (ServiceBinding); - if (NumberOfChildren == 0) { + if (NumberOfChildren != 0) { + // + // NumberOfChildren is not zero, destroy all the ARP children instances. + // + List = &ArpService->ChildrenList; + Status = NetDestroyLinkList ( + List, + ArpDestroyChildEntryInHandleBuffer, + ServiceBinding, + NULL + ); + ASSERT (IsListEmpty (&ArpService->PendingRequestTable)); + ASSERT (IsListEmpty (&ArpService->DeniedCacheTable)); + ASSERT (IsListEmpty (&ArpService->ResolvedCacheTable)); + } else if (IsListEmpty (&ArpService->ChildrenList)) { // // Uninstall the ARP ServiceBinding protocol. // @@ -491,17 +534,6 @@ ArpDriverBindingStop ( ArpCleanService (ArpService); FreePool (ArpService); - } else { - - while (!IsListEmpty (&ArpService->ChildrenList)) { - Instance = NET_LIST_HEAD (&ArpService->ChildrenList, ARP_INSTANCE_DATA, List); - - ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle); - } - - ASSERT (IsListEmpty (&ArpService->PendingRequestTable)); - ASSERT (IsListEmpty (&ArpService->DeniedCacheTable)); - ASSERT (IsListEmpty (&ArpService->ResolvedCacheTable)); } return EFI_SUCCESS; @@ -690,14 +722,14 @@ ArpServiceBindingDestroyChild ( Instance = ARP_INSTANCE_DATA_FROM_THIS (Arp); - if (Instance->Destroyed) { + if (Instance->InDestroy) { return EFI_SUCCESS; } // - // Use the Destroyed as a flag to avoid re-entrance. + // Use the InDestroy as a flag to avoid re-entrance. // - Instance->Destroyed = TRUE; + Instance->InDestroy = TRUE; // // Close the Managed Network protocol. @@ -722,7 +754,7 @@ ArpServiceBindingDestroyChild ( DEBUG ((EFI_D_ERROR, "ArpSBDestroyChild: Failed to uninstall the arp protocol, %r.\n", Status)); - Instance->Destroyed = FALSE; + Instance->InDestroy = FALSE; return Status; } diff --git a/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.c b/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.c index c754177a1f..633c3e7d38 100644 --- a/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.c +++ b/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.c @@ -1,7 +1,7 @@ /** @file The implementation of the ARP protocol. -Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at
@@ -52,7 +52,7 @@ ArpInitInstance ( CopyMem (&Instance->ArpProto, &mEfiArpProtocolTemplate, sizeof (Instance->ArpProto)); Instance->Configured = FALSE; - Instance->Destroyed = FALSE; + Instance->InDestroy = FALSE; InitializeListHead (&Instance->List); } diff --git a/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.h b/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.h index 418b4c81c7..a5dce7d9a5 100644 --- a/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.h +++ b/MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.h @@ -1,7 +1,7 @@ /** @file EFI Address Resolution Protocol (ARP) Protocol interface header file. -Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at
@@ -123,7 +123,7 @@ typedef struct { LIST_ENTRY List; EFI_ARP_CONFIG_DATA ConfigData; BOOLEAN Configured; - BOOLEAN Destroyed; + BOOLEAN InDestroy; } ARP_INSTANCE_DATA; #define ARP_SERVICE_DATA_SIGNATURE SIGNATURE_32('A', 'R', 'P', 'S') diff --git a/MdeModulePkg/Universal/Network/ArpDxe/ComponentName.c b/MdeModulePkg/Universal/Network/ArpDxe/ComponentName.c index 136b1df88e..ee47fb1ef7 100644 --- a/MdeModulePkg/Universal/Network/ArpDxe/ComponentName.c +++ b/MdeModulePkg/Universal/Network/ArpDxe/ComponentName.c @@ -1,7 +1,7 @@ /** @file UEFI Component Name(2) protocol implementation for ArpDxe driver. -Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at
@@ -39,6 +39,11 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mArpDriverNameTable[] = { { NULL, NULL } }; +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mArpControllerNameTable[] = { + { "eng;en", L"ARP Controller" }, + { NULL, NULL } +}; + /** Retrieves a Unicode string that is the user readable name of the driver. @@ -173,6 +178,48 @@ ArpComponentNameGetControllerName ( OUT CHAR16 **ControllerName ) { - return EFI_UNSUPPORTED; -} + EFI_STATUS Status; + EFI_ARP_PROTOCOL *Arp; + + // + // Only provide names for child handles. + // + if (ChildHandle == NULL) { + return EFI_UNSUPPORTED; + } + + // + // Make sure this driver produced ChildHandle + // + Status = EfiTestChildHandle ( + ControllerHandle, + ChildHandle, + &gEfiManagedNetworkProtocolGuid + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Retrieve an instance of a produced protocol from ChildHandle + // + Status = gBS->OpenProtocol ( + ChildHandle, + &gEfiArpProtocolGuid, + (VOID **)&Arp, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mArpControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gArpComponentName) + ); +} diff --git a/MdeModulePkg/Universal/Network/Dhcp4Dxe/ComponentName.c b/MdeModulePkg/Universal/Network/Dhcp4Dxe/ComponentName.c index e9d86fb56e..2ea07608f1 100644 --- a/MdeModulePkg/Universal/Network/Dhcp4Dxe/ComponentName.c +++ b/MdeModulePkg/Universal/Network/Dhcp4Dxe/ComponentName.c @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -174,6 +174,20 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mDhcpDriverNameTable[] = } }; +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gDhcpControllerNameTable = NULL; + +CHAR16 *mDhcp4ControllerName[] = { + L"DHCPv4 (State=0, Stopped)", + L"DHCPv4 (State=1, Init)", + L"DHCPv4 (State=2, Selecting)", + L"DHCPv4 (State=3, Requesting)", + L"DHCPv4 (State=4, Bound)", + L"DHCPv4 (State=5, Renewing)", + L"DHCPv4 (State=6, Rebinding)", + L"DHCPv4 (State=7, InitReboot)", + L"DHCPv4 (State=8, Rebooting)" +}; + /** Retrieves a Unicode string that is the user readable name of the driver. @@ -230,6 +244,66 @@ DhcpComponentNameGetDriverName ( ); } +/** + Update the component name for the Dhcp4 child handle. + + @param Dhcp4[in] A pointer to the EFI_DHCP4_PROTOCOL. + + + @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully. + @retval EFI_INVALID_PARAMETER The input parameter is invalid. + @retval EFI_DEVICE_ERROR DHCP is in unknown state. + +**/ +EFI_STATUS +UpdateName ( + IN EFI_DHCP4_PROTOCOL *Dhcp4 + ) +{ + EFI_STATUS Status; + EFI_DHCP4_MODE_DATA Dhcp4ModeData; + + if (Dhcp4 == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Format the child name into the string buffer. + // + Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4ModeData); + if (EFI_ERROR (Status)) { + return Status; + } + + if (gDhcpControllerNameTable != NULL) { + FreeUnicodeStringTable (gDhcpControllerNameTable); + gDhcpControllerNameTable = NULL; + } + + if (Dhcp4ModeData.State > Dhcp4Rebooting) { + return EFI_DEVICE_ERROR; + } + + Status = AddUnicodeString2 ( + "eng", + gDhcp4ComponentName.SupportedLanguages, + &gDhcpControllerNameTable, + mDhcp4ControllerName[Dhcp4ModeData.State], + TRUE + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return AddUnicodeString2 ( + "en", + gDhcp4ComponentName2.SupportedLanguages, + &gDhcpControllerNameTable, + mDhcp4ControllerName[Dhcp4ModeData.State], + FALSE + ); +} + /** Retrieves a Unicode string that is the user readable name of the controller that is being managed by a driver. @@ -308,5 +382,56 @@ DhcpComponentNameGetControllerName ( OUT CHAR16 **ControllerName ) { - return EFI_UNSUPPORTED; + EFI_STATUS Status; + EFI_DHCP4_PROTOCOL *Dhcp4; + + // + // Only provide names for child handles. + // + if (ChildHandle == NULL) { + return EFI_UNSUPPORTED; + } + + // + // Make sure this driver produced ChildHandle + // + Status = EfiTestChildHandle ( + ControllerHandle, + ChildHandle, + &gEfiUdp4ProtocolGuid + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Retrieve an instance of a produced protocol from ChildHandle + // + Status = gBS->OpenProtocol ( + ChildHandle, + &gEfiDhcp4ProtocolGuid, + (VOID **)&Dhcp4, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Update the component name for this child handle. + // + Status = UpdateName (Dhcp4); + if (EFI_ERROR (Status)) { + return Status; + } + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + gDhcpControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gDhcp4ComponentName) + ); } diff --git a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.c b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.c index 8a773d9461..20758d38cf 100644 --- a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.c +++ b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.c @@ -212,7 +212,6 @@ Dhcp4CreateService ( DhcpSb->Signature = DHCP_SERVICE_SIGNATURE; DhcpSb->ServiceState = DHCP_UNCONFIGED; - DhcpSb->InDestroy = FALSE; DhcpSb->Controller = Controller; DhcpSb->Image = ImageHandle; InitializeListHead (&DhcpSb->Children); @@ -354,6 +353,35 @@ ON_ERROR: return Status; } +/** + Callback function which provided by user to remove one node in NetDestroyLinkList process. + + @param[in] Entry The entry to be removed. + @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList. + + @retval EFI_SUCCESS The entry has been removed successfully. + @retval Others Fail to remove the entry. + +**/ +EFI_STATUS +Dhcp4DestroyChildEntry ( + IN LIST_ENTRY *Entry, + IN VOID *Context +) +{ + DHCP_PROTOCOL *Instance; + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + + if (Entry == NULL || Context == NULL) { + return EFI_INVALID_PARAMETER; + } + + Instance = NET_LIST_USER_STRUCT_S (Entry, DHCP_PROTOCOL, Link, DHCP_PROTOCOL_SIGNATURE); + ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *) Context; + + return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle); +} + /** Stop this driver on ControllerHandle. This service is called by the @@ -384,10 +412,10 @@ Dhcp4DriverBindingStop ( { EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; DHCP_SERVICE *DhcpSb; - DHCP_PROTOCOL *Instance; EFI_HANDLE NicHandle; EFI_STATUS Status; - EFI_TPL OldTpl; + LIST_ENTRY *List; + UINTN ListLength; // // DHCP driver opens UDP child, So, the ControllerHandle is the @@ -396,7 +424,7 @@ Dhcp4DriverBindingStop ( NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp4ProtocolGuid); if (NicHandle == NULL) { - return EFI_DEVICE_ERROR; + return EFI_SUCCESS; } Status = gBS->OpenProtocol ( @@ -413,16 +441,30 @@ Dhcp4DriverBindingStop ( } DhcpSb = DHCP_SERVICE_FROM_THIS (ServiceBinding); - - if (DhcpSb->InDestroy) { - return EFI_SUCCESS; + if (!IsListEmpty (&DhcpSb->Children)) { + // + // Destroy all the children instances before destory the service. + // + List = &DhcpSb->Children; + Status = NetDestroyLinkList ( + List, + Dhcp4DestroyChildEntry, + ServiceBinding, + &ListLength + ); + if (EFI_ERROR (Status) || ListLength != 0) { + Status = EFI_DEVICE_ERROR; + } } - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - if (NumberOfChildren == 0) { + if (NumberOfChildren == 0 && !IsListEmpty (&DhcpSb->Children)) { + Status = EFI_DEVICE_ERROR; + } - DhcpSb->InDestroy = TRUE; + if (NumberOfChildren == 0 && IsListEmpty (&DhcpSb->Children)) { + // + // Destroy the service itself if no child instance left. + // DhcpSb->ServiceState = DHCP_DESTROY; gBS->UninstallProtocolInterface ( @@ -433,24 +475,15 @@ Dhcp4DriverBindingStop ( Dhcp4CloseService (DhcpSb); - FreePool (DhcpSb); - } else { - // - // Don't use NET_LIST_FOR_EACH_SAFE here, Dhcp4ServiceBindingDestroyChild - // may cause other child to be deleted. - // - while (!IsListEmpty (&DhcpSb->Children)) { - Instance = NET_LIST_HEAD (&DhcpSb->Children, DHCP_PROTOCOL, Link); - ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle); - } - - if (DhcpSb->NumChildren != 0) { - Status = EFI_DEVICE_ERROR; + if (gDhcpControllerNameTable != NULL) { + FreeUnicodeStringTable (gDhcpControllerNameTable); + gDhcpControllerNameTable = NULL; } + FreePool (DhcpSb); + + Status = EFI_SUCCESS; } - gBS->RestoreTPL (OldTpl); - return Status; } @@ -663,12 +696,13 @@ Dhcp4ServiceBindingDestroyChild ( // // Uninstall the DHCP4 protocol first to enable a top down destruction. // + gBS->RestoreTPL (OldTpl); Status = gBS->UninstallProtocolInterface ( ChildHandle, &gEfiDhcp4ProtocolGuid, Dhcp ); - + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); if (EFI_ERROR (Status)) { Instance->InDestroy = FALSE; diff --git a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.h b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.h index b59b74135b..b4a63ef173 100644 --- a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.h +++ b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.h @@ -1,7 +1,7 @@ /** @file Header for the DHCP4 driver. -Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -17,6 +17,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. extern EFI_COMPONENT_NAME_PROTOCOL gDhcp4ComponentName; extern EFI_COMPONENT_NAME2_PROTOCOL gDhcp4ComponentName2; +extern EFI_UNICODE_STRING_TABLE *gDhcpControllerNameTable; /** Test to see if this driver supports ControllerHandle. This service diff --git a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c index b9a85f2333..41b5e95997 100644 --- a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c +++ b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c @@ -1,7 +1,7 @@ /** @file This file implement the EFI_DHCP4_PROTOCOL interface. -Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -1234,6 +1234,8 @@ Dhcp4InstanceCreateUdpIo ( ) { DHCP_SERVICE *DhcpSb; + EFI_STATUS Status; + VOID *Udp4; ASSERT (Instance->Token != NULL); @@ -1248,7 +1250,19 @@ Dhcp4InstanceCreateUdpIo ( if (Instance->UdpIo == NULL) { return EFI_OUT_OF_RESOURCES; } else { - return EFI_SUCCESS; + Status = gBS->OpenProtocol ( + Instance->UdpIo->UdpHandle, + &gEfiUdp4ProtocolGuid, + (VOID **) &Udp4, + Instance->Service->Image, + Instance->Handle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + if (EFI_ERROR (Status)) { + UdpIoFreeIo (Instance->UdpIo); + Instance->UdpIo = NULL; + } + return Status; } } @@ -1416,6 +1430,12 @@ SIGNAL_USER: // NetbufQueFlush (&Instance->ResponseQueue); UdpIoCleanIo (Instance->UdpIo); + gBS->CloseProtocol ( + Instance->UdpIo->UdpHandle, + &gEfiUdp4ProtocolGuid, + Instance->Service->Image, + Instance->Handle + ); UdpIoFreeIo (Instance->UdpIo); Instance->UdpIo = NULL; Instance->Token = NULL; @@ -1581,6 +1601,12 @@ ON_ERROR: if (EFI_ERROR (Status) && (Instance->UdpIo != NULL)) { UdpIoCleanIo (Instance->UdpIo); + gBS->CloseProtocol ( + Instance->UdpIo->UdpHandle, + &gEfiUdp4ProtocolGuid, + Instance->Service->Image, + Instance->Handle + ); UdpIoFreeIo (Instance->UdpIo); Instance->UdpIo = NULL; Instance->Token = NULL; diff --git a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.h b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.h index 08faff0206..44213cf40a 100644 --- a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.h +++ b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.h @@ -84,7 +84,6 @@ struct _DHCP_SERVICE { EFI_SERVICE_BINDING_PROTOCOL ServiceBinding; INTN ServiceState; // CONFIGED, UNCONFIGED, and DESTROY - BOOLEAN InDestroy; EFI_HANDLE Controller; EFI_HANDLE Image; diff --git a/MdeModulePkg/Universal/Network/IScsiDxe/ComponentName.c b/MdeModulePkg/Universal/Network/IScsiDxe/ComponentName.c index acb9c0758d..e88587a4bb 100644 --- a/MdeModulePkg/Universal/Network/IScsiDxe/ComponentName.c +++ b/MdeModulePkg/Universal/Network/IScsiDxe/ComponentName.c @@ -1,7 +1,7 @@ /** @file UEFI Component Name(2) protocol implementation for iSCSI. -Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -37,6 +37,11 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIScsiDriverNameTable[] = {NULL, NULL} }; +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIScsiControllerNameTable[] = { + {"eng;en", L"iSCSI (IPv4)"}, + {NULL, NULL} +}; + /** Retrieves a Unicode string that is the user readable name of the EFI Driver. @@ -131,5 +136,36 @@ IScsiComponentNameGetControllerName ( OUT CHAR16 **ControllerName ) { - return EFI_UNSUPPORTED; + EFI_HANDLE IScsiController; + ISCSI_PRIVATE_PROTOCOL *IScsiIdentifier; + EFI_STATUS Status; + + // + // Get the handle of the controller we are controling. + // + IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp4ProtocolGuid); + if (IScsiController == NULL) { + return EFI_UNSUPPORTED; + } + + Status = gBS->OpenProtocol ( + IScsiController, + &gEfiCallerIdGuid, + (VOID **)&IScsiIdentifier, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mIScsiControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gIScsiComponentName) + ); } + diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/ComponentName.c b/MdeModulePkg/Universal/Network/Ip4Dxe/ComponentName.c index d3fcf048fc..2ccfb3cc1c 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/ComponentName.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/ComponentName.c @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at
@@ -173,6 +173,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIp4DriverNameTable[] = { } }; +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gIp4ControllerNameTable = NULL; + /** Retrieves a Unicode string that is the user readable name of the driver. @@ -230,6 +232,74 @@ Ip4ComponentNameGetDriverName ( } +/** + Update the component name for the IP4 child handle. + + @param Ip4[in] A pointer to the EFI_IP4_PROTOCOL. + + + @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully. + @retval EFI_INVALID_PARAMETER The input parameter is invalid. + +**/ +EFI_STATUS +UpdateName ( + IN EFI_IP4_PROTOCOL *Ip4 + ) +{ + EFI_STATUS Status; + CHAR16 HandleName[80]; + EFI_IP4_MODE_DATA Ip4ModeData; + + if (Ip4 == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Format the child name into the string buffer as: + // IPv4 (SrcIP=127.0.0.1, DestIP=127.0.0.1) + // + Status = Ip4->GetModeData (Ip4, &Ip4ModeData, NULL, NULL); + if (EFI_ERROR (Status)) { + return Status; + } + + if (!Ip4ModeData.IsStarted || !Ip4ModeData.IsConfigured) { + UnicodeSPrint (HandleName, sizeof (HandleName), L"IPv4 (Not started)"); + } else { + UnicodeSPrint (HandleName, sizeof (HandleName), + L"IPv4 (SrcIP=%d.%d.%d.%d)", + Ip4ModeData.ConfigData.StationAddress.Addr[0], + Ip4ModeData.ConfigData.StationAddress.Addr[1], + Ip4ModeData.ConfigData.StationAddress.Addr[2], + Ip4ModeData.ConfigData.StationAddress.Addr[3] + ); + } + + if (gIp4ControllerNameTable != NULL) { + FreeUnicodeStringTable (gIp4ControllerNameTable); + gIp4ControllerNameTable = NULL; + } + Status = AddUnicodeString2 ( + "eng", + gIp4ComponentName.SupportedLanguages, + &gIp4ControllerNameTable, + HandleName, + TRUE + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return AddUnicodeString2 ( + "en", + gIp4ComponentName2.SupportedLanguages, + &gIp4ControllerNameTable, + HandleName, + FALSE + ); +} + /** Retrieves a Unicode string that is the user readable name of the controller that is being managed by a driver. @@ -308,5 +378,57 @@ Ip4ComponentNameGetControllerName ( OUT CHAR16 **ControllerName ) { - return EFI_UNSUPPORTED; + EFI_STATUS Status; + EFI_IP4_PROTOCOL *Ip4; + + // + // Only provide names for child handles. + // + if (ChildHandle == NULL) { + return EFI_UNSUPPORTED; + } + + // + // Make sure this driver produced ChildHandle + // + Status = EfiTestChildHandle ( + ControllerHandle, + ChildHandle, + &gEfiManagedNetworkProtocolGuid + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Retrieve an instance of a produced protocol from ChildHandle + // + Status = gBS->OpenProtocol ( + ChildHandle, + &gEfiIp4ProtocolGuid, + (VOID **)&Ip4, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Update the component name for this child handle. + // + Status = UpdateName (Ip4); + if (EFI_ERROR (Status)) { + return Status; + } + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + gIp4ControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gIp4ComponentName) + ); } + diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Common.h b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Common.h index 295f822979..64049303e4 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Common.h +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Common.h @@ -1,7 +1,7 @@ /** @file Common definition for IP4. -Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -63,6 +63,9 @@ typedef struct _IP4_SERVICE IP4_SERVICE; #define IP4_FIRST_FRAGMENT(FragmentField) \ ((BOOLEAN)(((FragmentField) & IP4_HEAD_OFFSET_MASK) == 0)) +#define IP4_DO_NOT_FRAGMENT(FragmentField) \ + ((BOOLEAN)(((FragmentField) & IP4_HEAD_DF_MASK) == IP4_HEAD_DF_MASK)) + #define IP4_IS_BROADCAST(CastType) ((CastType) >= IP4_LOCAL_BROADCAST) /// diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c index 4ce85a3f51..5a84837a44 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c @@ -176,7 +176,6 @@ Ip4CreateService ( IpSb->ServiceBinding.CreateChild = Ip4ServiceBindingCreateChild; IpSb->ServiceBinding.DestroyChild = Ip4ServiceBindingDestroyChild; IpSb->State = IP4_SERVICE_UNSTARTED; - IpSb->InDestroy = FALSE; IpSb->NumChildren = 0; InitializeListHead (&IpSb->Children); @@ -396,6 +395,42 @@ Ip4CleanService ( return EFI_SUCCESS; } +/** + Callback function which provided by user to remove one node in NetDestroyLinkList process. + + @param[in] Entry The entry to be removed. + @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList. + + @retval EFI_SUCCESS The entry has been removed successfully. + @retval Others Fail to remove the entry. + +**/ +EFI_STATUS +Ip4DestroyChildEntryInHandleBuffer ( + IN LIST_ENTRY *Entry, + IN VOID *Context +) +{ + IP4_PROTOCOL *IpInstance; + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + UINTN NumberOfChildren; + EFI_HANDLE *ChildHandleBuffer; + + if (Entry == NULL || Context == NULL) { + return EFI_INVALID_PARAMETER; + } + + IpInstance = NET_LIST_USER_STRUCT_S (Entry, IP4_PROTOCOL, Link, IP4_PROTOCOL_SIGNATURE); + ServiceBinding = ((IP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding; + NumberOfChildren = ((IP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren; + ChildHandleBuffer = ((IP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer; + + if (!NetIsInHandleBuffer (IpInstance->Handle, NumberOfChildren, ChildHandleBuffer)) { + return EFI_SUCCESS; + } + + return ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle); +} /** Start this driver on ControllerHandle. This service is called by the @@ -529,14 +564,13 @@ Ip4DriverBindingStop ( IN EFI_HANDLE *ChildHandleBuffer ) { - EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; - IP4_SERVICE *IpSb; - IP4_PROTOCOL *IpInstance; - EFI_HANDLE NicHandle; - EFI_STATUS Status; - EFI_TPL OldTpl; - INTN State; - BOOLEAN IsArp; + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + IP4_SERVICE *IpSb; + EFI_HANDLE NicHandle; + EFI_STATUS Status; + INTN State; + LIST_ENTRY *List; + IP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context; // // IP4 driver opens the MNP child, ARP children or the IP4_CONFIG protocol @@ -557,7 +591,6 @@ Ip4DriverBindingStop ( ControllerHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL ); - if (Status == EFI_SUCCESS) { // // Retrieve the IP4 service binding protocol. If failed, it is @@ -572,15 +605,11 @@ Ip4DriverBindingStop ( ControllerHandle, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); - if (EFI_ERROR (Status)) { return EFI_DEVICE_ERROR; } IpSb = IP4_SERVICE_FROM_PROTOCOL (ServiceBinding); - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - if (IpSb->Ip4Config != NULL && (IpSb->State != IP4_SERVICE_DESTROY)) { IpSb->Ip4Config->Stop (IpSb->Ip4Config); @@ -591,9 +620,7 @@ Ip4DriverBindingStop ( IpSb->Image, ControllerHandle ); - if (EFI_ERROR (Status)) { - gBS->RestoreTPL (OldTpl); return Status; } @@ -609,7 +636,6 @@ Ip4DriverBindingStop ( gBS->CloseEvent (IpSb->ReconfigEvent); } - gBS->RestoreTPL (OldTpl); return EFI_SUCCESS; } @@ -619,16 +645,12 @@ Ip4DriverBindingStop ( // service binding is installed on the NIC handle. So, need to open // the protocol info to find the NIC handle. // - IsArp = FALSE; NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid); - if (NicHandle == NULL) { NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiArpProtocolGuid); - IsArp = TRUE; - } - - if (NicHandle == NULL) { - return EFI_DEVICE_ERROR; + if (NicHandle == NULL) { + return EFI_SUCCESS; + } } // @@ -642,34 +664,23 @@ Ip4DriverBindingStop ( NicHandle, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); - if (EFI_ERROR (Status)) { return EFI_DEVICE_ERROR; } IpSb = IP4_SERVICE_FROM_PROTOCOL (ServiceBinding); - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - if (IpSb->InDestroy) { - gBS->RestoreTPL (OldTpl); - return EFI_SUCCESS; - } - - if (IsArp) { - while (!IsListEmpty (&IpSb->Children)) { - IpInstance = NET_LIST_HEAD (&IpSb->Children, IP4_PROTOCOL, Link); - - ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle); - } - - if (IpSb->NumChildren != 0) { - Status = EFI_DEVICE_ERROR; - goto ON_ERROR; - } - - IpSb->InDestroy = TRUE; - + if (NumberOfChildren != 0) { + List = &IpSb->Children; + Context.ServiceBinding = ServiceBinding; + Context.NumberOfChildren = NumberOfChildren; + Context.ChildHandleBuffer = ChildHandleBuffer; + Status = NetDestroyLinkList ( + List, + Ip4DestroyChildEntryInHandleBuffer, + &Context, + NULL + ); + } else if (IsListEmpty (&IpSb->Children)) { State = IpSb->State; IpSb->State = IP4_SERVICE_DESTROY; @@ -682,7 +693,6 @@ Ip4DriverBindingStop ( // OK, clean other resources then uninstall the service binding protocol. // Status = Ip4CleanService (IpSb); - if (EFI_ERROR (Status)) { IpSb->State = State; goto ON_ERROR; @@ -693,52 +703,15 @@ Ip4DriverBindingStop ( &gEfiIp4ServiceBindingProtocolGuid, ServiceBinding ); - - FreePool (IpSb); - } else if (NumberOfChildren == 0) { - IpSb->InDestroy = TRUE; - - State = IpSb->State; - IpSb->State = IP4_SERVICE_DESTROY; - - // - // Clear the variable data. - // - Ip4ClearVariableData (IpSb); - - // - // OK, clean other resources then uninstall the service binding protocol. - // - Status = Ip4CleanService (IpSb); - - if (EFI_ERROR (Status)) { - IpSb->State = State; - goto ON_ERROR; + + if (gIp4ControllerNameTable != NULL) { + FreeUnicodeStringTable (gIp4ControllerNameTable); + gIp4ControllerNameTable = NULL; } - - gBS->UninstallProtocolInterface ( - NicHandle, - &gEfiIp4ServiceBindingProtocolGuid, - ServiceBinding - ); - FreePool (IpSb); - } else { - - while (!IsListEmpty (&IpSb->Children)) { - IpInstance = NET_LIST_HEAD (&IpSb->Children, IP4_PROTOCOL, Link); - - ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle); - } - - if (IpSb->NumChildren != 0) { - Status = EFI_DEVICE_ERROR; - } } ON_ERROR: - - gBS->RestoreTPL (OldTpl); return Status; } @@ -935,6 +908,15 @@ Ip4ServiceBindingDestroyChild ( ChildHandle ); + if (IpInstance->Interface != NULL && IpInstance->Interface->Arp != NULL) { + gBS->CloseProtocol ( + IpInstance->Interface->ArpHandle, + &gEfiArpProtocolGuid, + gIp4DriverBinding.DriverBindingHandle, + ChildHandle + ); + } + // // Uninstall the IP4 protocol first. Many thing happens during // this: @@ -949,12 +931,13 @@ Ip4ServiceBindingDestroyChild ( // will be called back before preceeding. If any packets not recycled, // that means there is a resource leak. // + gBS->RestoreTPL (OldTpl); Status = gBS->UninstallProtocolInterface ( ChildHandle, &gEfiIp4ProtocolGuid, &IpInstance->Ip4Proto ); - + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); if (EFI_ERROR (Status)) { goto ON_ERROR; } diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.h b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.h index 96044fd0ce..32984bad66 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.h +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.h @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -19,6 +19,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. extern EFI_DRIVER_BINDING_PROTOCOL gIp4DriverBinding; extern EFI_COMPONENT_NAME_PROTOCOL gIp4ComponentName; extern EFI_COMPONENT_NAME2_PROTOCOL gIp4ComponentName2; +extern EFI_UNICODE_STRING_TABLE *gIp4ControllerNameTable; + +typedef struct { + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + UINTN NumberOfChildren; + EFI_HANDLE *ChildHandleBuffer; +} IP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT; // // Function prototype for the driver's entry point diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Icmp.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Icmp.c index 18cb9ff360..e5e2b984ee 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Icmp.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Icmp.c @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -193,7 +193,7 @@ Ip4ProcessIcmpError ( } IP4_GET_CLIP_INFO (Packet)->Status = EFI_ICMP_ERROR; - return Ip4Demultiplex (IpSb, Head, Packet); + return Ip4Demultiplex (IpSb, Head, Packet, NULL, 0); } @@ -308,7 +308,7 @@ Ip4ProcessIcmpQuery ( return Ip4IcmpReplyEcho (IpSb, Head, Packet); } - return Ip4Demultiplex (IpSb, Head, Packet); + return Ip4Demultiplex (IpSb, Head, Packet, NULL, 0); } diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c index f4ce3ea025..74bf7f76eb 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c @@ -868,6 +868,7 @@ Ip4ConfigProtocol ( EFI_STATUS Status; IP4_ADDR Ip; IP4_ADDR Netmask; + EFI_ARP_PROTOCOL *Arp; IpSb = IpInstance->Service; @@ -972,6 +973,20 @@ Ip4ConfigProtocol ( } IpInstance->Interface = IpIf; + if (IpIf->Arp != NULL) { + Arp = NULL; + Status = gBS->OpenProtocol ( + IpIf->ArpHandle, + &gEfiArpProtocolGuid, + (VOID **) &Arp, + gIp4DriverBinding.DriverBindingHandle, + IpInstance->Handle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + } InsertTailList (&IpIf->IpInstances, &IpInstance->AddrLink); CopyMem (&IpInstance->ConfigData, Config, sizeof (IpInstance->ConfigData)); @@ -1028,6 +1043,14 @@ Ip4CleanProtocol ( if (IpInstance->Interface != NULL) { RemoveEntryList (&IpInstance->AddrLink); + if (IpInstance->Interface->Arp != NULL) { + gBS->CloseProtocol ( + IpInstance->Interface->ArpHandle, + &gEfiArpProtocolGuid, + gIp4DriverBinding.DriverBindingHandle, + IpInstance->Handle + ); + } Ip4FreeInterface (IpInstance->Interface, IpInstance); IpInstance->Interface = NULL; } @@ -1193,14 +1216,6 @@ EfiIp4Configure ( // Validate the configuration first. // if (IpConfigData != NULL) { - // - // This implementation doesn't support RawData - // - if (IpConfigData->RawData) { - Status = EFI_UNSUPPORTED; - goto ON_EXIT; - } - CopyMem (&IpAddress, &IpConfigData->StationAddress, sizeof (IP4_ADDR)); CopyMem (&SubnetMask, &IpConfigData->SubnetMask, sizeof (IP4_ADDR)); @@ -1620,22 +1635,23 @@ Ip4TokenExist ( return EFI_SUCCESS; } - /** Validate the user's token against current station address. - @param[in] Token User's token to validate - @param[in] IpIf The IP4 child's interface. + @param[in] Token User's token to validate. + @param[in] IpIf The IP4 child's interface. + @param[in] RawData Set to TRUE to send unformatted packets. - @retval EFI_INVALID_PARAMETER Some parameters are invalid + @retval EFI_INVALID_PARAMETER Some parameters are invalid. @retval EFI_BAD_BUFFER_SIZE The user's option/data is too long. - @retval EFI_SUCCESS The token is OK + @retval EFI_SUCCESS The token is valid. **/ EFI_STATUS Ip4TxTokenValid ( IN EFI_IP4_COMPLETION_TOKEN *Token, - IN IP4_INTERFACE *IpIf + IN IP4_INTERFACE *IpIf, + IN BOOLEAN RawData ) { EFI_IP4_TRANSMIT_DATA *TxData; @@ -1653,20 +1669,7 @@ Ip4TxTokenValid ( TxData = Token->Packet.TxData; // - // Check the IP options: no more than 40 bytes and format is OK - // - if (TxData->OptionsLength != 0) { - if ((TxData->OptionsLength > 40) || (TxData->OptionsBuffer == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (!Ip4OptionIsValid (TxData->OptionsBuffer, TxData->OptionsLength, FALSE)) { - return EFI_INVALID_PARAMETER; - } - } - - // - // Check the fragment table: no empty fragment, and length isn't bogus + // Check the fragment table: no empty fragment, and length isn't bogus. // if ((TxData->TotalDataLength == 0) || (TxData->FragmentCount == 0)) { return EFI_INVALID_PARAMETER; @@ -1674,6 +1677,10 @@ Ip4TxTokenValid ( Offset = TxData->TotalDataLength; + if (Offset > IP4_MAX_PACKET_SIZE) { + return EFI_BAD_BUFFER_SIZE; + } + for (Index = 0; Index < TxData->FragmentCount; Index++) { if ((TxData->FragmentTable[Index].FragmentBuffer == NULL) || (TxData->FragmentTable[Index].FragmentLength == 0)) { @@ -1688,6 +1695,27 @@ Ip4TxTokenValid ( return EFI_INVALID_PARAMETER; } + // + // NOTE that OptionsLength/OptionsBuffer/OverrideData are ignored if RawData + // is TRUE. + // + if (RawData) { + return EFI_SUCCESS; + } + + // + // Check the IP options: no more than 40 bytes and format is OK + // + if (TxData->OptionsLength != 0) { + if ((TxData->OptionsLength > 40) || (TxData->OptionsBuffer == NULL)) { + return EFI_INVALID_PARAMETER; + } + + if (!Ip4OptionIsValid (TxData->OptionsBuffer, TxData->OptionsLength, FALSE)) { + return EFI_INVALID_PARAMETER; + } + } + // // Check the source and gateway: they must be a valid unicast. // Gateway must also be on the connected network. @@ -1888,6 +1916,10 @@ EfiIp4Transmit ( EFI_TPL OldTpl; BOOLEAN DontFragment; UINT32 HeadLen; + UINT8 RawHdrLen; + UINT32 OptionsLength; + UINT8 *OptionsBuffer; + VOID *FirstFragment; if (This == NULL) { return EFI_INVALID_PARAMETER; @@ -1913,7 +1945,7 @@ EfiIp4Transmit ( // // make sure that token is properly formated // - Status = Ip4TxTokenValid (Token, IpIf); + Status = Ip4TxTokenValid (Token, IpIf, Config->RawData); if (EFI_ERROR (Status)) { goto ON_EXIT; @@ -1933,32 +1965,82 @@ EfiIp4Transmit ( // TxData = Token->Packet.TxData; - CopyMem (&Head.Dst, &TxData->DestinationAddress, sizeof (IP4_ADDR)); - Head.Dst = NTOHL (Head.Dst); + FirstFragment = NULL; - if (TxData->OverrideData != NULL) { - Override = TxData->OverrideData; - Head.Protocol = Override->Protocol; - Head.Tos = Override->TypeOfService; - Head.Ttl = Override->TimeToLive; - DontFragment = Override->DoNotFragment; + if (Config->RawData) { + // + // When RawData is TRUE, first buffer in FragmentTable points to a raw + // IPv4 fragment including IPv4 header and options. + // + FirstFragment = TxData->FragmentTable[0].FragmentBuffer; + CopyMem (&RawHdrLen, FirstFragment, sizeof (UINT8)); - CopyMem (&Head.Src, &Override->SourceAddress, sizeof (IP4_ADDR)); - CopyMem (&GateWay, &Override->GatewayAddress, sizeof (IP4_ADDR)); + RawHdrLen = (UINT8) (RawHdrLen & 0x0f); + if (RawHdrLen < 5) { + return EFI_INVALID_PARAMETER; + } + + RawHdrLen = (UINT8) (RawHdrLen << 2); + + CopyMem (&Head, FirstFragment, IP4_MIN_HEADLEN); + + Ip4NtohHead (&Head); + HeadLen = 0; + DontFragment = IP4_DO_NOT_FRAGMENT (Head.Fragment); - Head.Src = NTOHL (Head.Src); - GateWay = NTOHL (GateWay); + if (!DontFragment) { + return EFI_INVALID_PARAMETER; + } + + GateWay = IP4_ALLZERO_ADDRESS; + + // + // Get IPv4 options from first fragment. + // + if (RawHdrLen == IP4_MIN_HEADLEN) { + OptionsLength = 0; + OptionsBuffer = NULL; + } else { + OptionsLength = RawHdrLen - IP4_MIN_HEADLEN; + OptionsBuffer = (UINT8 *) FirstFragment + IP4_MIN_HEADLEN; + } + + // + // Trim off IPv4 header and options from first fragment. + // + TxData->FragmentTable[0].FragmentBuffer = (UINT8 *) FirstFragment + RawHdrLen; + TxData->FragmentTable[0].FragmentLength = TxData->FragmentTable[0].FragmentLength - RawHdrLen; } else { - Head.Src = IpIf->Ip; - GateWay = IP4_ALLZERO_ADDRESS; - Head.Protocol = Config->DefaultProtocol; - Head.Tos = Config->TypeOfService; - Head.Ttl = Config->TimeToLive; - DontFragment = Config->DoNotFragment; - } + CopyMem (&Head.Dst, &TxData->DestinationAddress, sizeof (IP4_ADDR)); + Head.Dst = NTOHL (Head.Dst); - Head.Fragment = IP4_HEAD_FRAGMENT_FIELD (DontFragment, FALSE, 0); - HeadLen = (TxData->OptionsLength + 3) & (~0x03); + if (TxData->OverrideData != NULL) { + Override = TxData->OverrideData; + Head.Protocol = Override->Protocol; + Head.Tos = Override->TypeOfService; + Head.Ttl = Override->TimeToLive; + DontFragment = Override->DoNotFragment; + + CopyMem (&Head.Src, &Override->SourceAddress, sizeof (IP4_ADDR)); + CopyMem (&GateWay, &Override->GatewayAddress, sizeof (IP4_ADDR)); + + Head.Src = NTOHL (Head.Src); + GateWay = NTOHL (GateWay); + } else { + Head.Src = IpIf->Ip; + GateWay = IP4_ALLZERO_ADDRESS; + Head.Protocol = Config->DefaultProtocol; + Head.Tos = Config->TypeOfService; + Head.Ttl = Config->TimeToLive; + DontFragment = Config->DoNotFragment; + } + + Head.Fragment = IP4_HEAD_FRAGMENT_FIELD (DontFragment, FALSE, 0); + HeadLen = (TxData->OptionsLength + 3) & (~0x03); + + OptionsLength = TxData->OptionsLength; + OptionsBuffer = (UINT8 *) (TxData->OptionsBuffer); + } // // If don't fragment and fragment needed, return error @@ -2004,6 +2086,13 @@ EfiIp4Transmit ( // free the IP4_TXTOKEN_WRAP. Now, the token wrap hasn't been // enqueued. // + if (Config->RawData) { + // + // Restore pointer of first fragment in RawData mode. + // + TxData->FragmentTable[0].FragmentBuffer = (UINT8 *) FirstFragment; + } + NetbufFree (Wrap->Packet); goto ON_EXIT; } @@ -2019,8 +2108,8 @@ EfiIp4Transmit ( IpInstance, Wrap->Packet, &Head, - TxData->OptionsBuffer, - TxData->OptionsLength, + OptionsBuffer, + OptionsLength, GateWay, Ip4OnPacketSent, Wrap @@ -2028,9 +2117,24 @@ EfiIp4Transmit ( if (EFI_ERROR (Status)) { Wrap->Sent = FALSE; + + if (Config->RawData) { + // + // Restore pointer of first fragment in RawData mode. + // + TxData->FragmentTable[0].FragmentBuffer = (UINT8 *) FirstFragment; + } + NetbufFree (Wrap->Packet); } + if (Config->RawData) { + // + // Restore pointer of first fragment in RawData mode. + // + TxData->FragmentTable[0].FragmentBuffer = (UINT8 *) FirstFragment; + } + ON_EXIT: gBS->RestoreTPL (OldTpl); return Status; diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h index 563cf7f91f..ad8a9276bd 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h @@ -33,6 +33,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include #include "Ip4Common.h" #include "Ip4Driver.h" @@ -160,7 +161,6 @@ struct _IP4_SERVICE { UINT32 Signature; EFI_SERVICE_BINDING_PROTOCOL ServiceBinding; INTN State; - BOOLEAN InDestroy; // // List of all the IP instances and interfaces, and default diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c index d985b1aeb6..62163f4c57 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c @@ -714,7 +714,7 @@ Ip4PreProcessPacket ( UINT16 Checksum; // - // Check that the IP4 header is correctly formatted + // Check if the IP4 header is correctly formatted. // if ((*Packet)->TotalSize < IP4_MIN_HEADLEN) { return EFI_INVALID_PARAMETER; @@ -774,7 +774,7 @@ Ip4PreProcessPacket ( } // - // Trim the head off, after this point, the packet is headless. + // Trim the head off, after this point, the packet is headless, // and Packet->TotalLen == Info->Length. // NetbufTrim (*Packet, HeadLen, TRUE); @@ -928,7 +928,7 @@ Ip4AccpetFrame ( break; default: - Ip4Demultiplex (IpSb, Head, Packet); + Ip4Demultiplex (IpSb, Head, Packet, Option, OptionLen); } Packet = NULL; @@ -1151,8 +1151,8 @@ Ip4OnRecyclePacket ( to the upper layer. Upper layer will signal the recycle event in it when it is done with the packet. - @param[in] IpInstance The IP4 child to receive the packet - @param[in] Packet The packet to deliver up. + @param[in] IpInstance The IP4 child to receive the packet. + @param[in] Packet The packet to deliver up. @retval Wrap if warp the packet succeed. @retval NULL failed to wrap the packet . @@ -1167,6 +1167,7 @@ Ip4WrapRxData ( IP4_RXDATA_WRAP *Wrap; EFI_IP4_RECEIVE_DATA *RxData; EFI_STATUS Status; + BOOLEAN RawData; Wrap = AllocatePool (IP4_RXDATA_WRAP_SIZE (Packet->BlockOpNum)); @@ -1180,7 +1181,7 @@ Ip4WrapRxData ( Wrap->Packet = Packet; RxData = &Wrap->RxData; - ZeroMem (&RxData->TimeStamp, sizeof (EFI_TIME)); + ZeroMem (RxData, sizeof (EFI_IP4_RECEIVE_DATA)); Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, @@ -1197,17 +1198,21 @@ Ip4WrapRxData ( ASSERT (Packet->Ip.Ip4 != NULL); + ASSERT (IpInstance != NULL); + RawData = IpInstance->ConfigData.RawData; + // // The application expects a network byte order header. // - RxData->HeaderLength = (Packet->Ip.Ip4->HeadLen << 2); - RxData->Header = (EFI_IP4_HEADER *) Ip4NtohHead (Packet->Ip.Ip4); - - RxData->OptionsLength = RxData->HeaderLength - IP4_MIN_HEADLEN; - RxData->Options = NULL; + if (!RawData) { + RxData->HeaderLength = (Packet->Ip.Ip4->HeadLen << 2); + RxData->Header = (EFI_IP4_HEADER *) Ip4NtohHead (Packet->Ip.Ip4); + RxData->OptionsLength = RxData->HeaderLength - IP4_MIN_HEADLEN; + RxData->Options = NULL; - if (RxData->OptionsLength != 0) { - RxData->Options = (VOID *) (RxData->Header + 1); + if (RxData->OptionsLength != 0) { + RxData->Options = (VOID *) (RxData->Header + 1); + } } RxData->DataLength = Packet->TotalSize; @@ -1246,6 +1251,7 @@ Ip4InstanceDeliverPacket ( NET_BUF *Packet; NET_BUF *Dup; UINT8 *Head; + UINT32 HeadLen; // // Deliver a packet if there are both a packet and a receive token. @@ -1271,24 +1277,32 @@ Ip4InstanceDeliverPacket ( // // Create a duplicated packet if this packet is shared // - Dup = NetbufDuplicate (Packet, NULL, IP4_MAX_HEADLEN); + if (IpInstance->ConfigData.RawData) { + HeadLen = 0; + } else { + HeadLen = IP4_MAX_HEADLEN; + } + + Dup = NetbufDuplicate (Packet, NULL, HeadLen); if (Dup == NULL) { return EFI_OUT_OF_RESOURCES; } - // - // Copy the IP head over. The packet to deliver up is - // headless. Trim the head off after copy. The IP head - // may be not continuous before the data. - // - Head = NetbufAllocSpace (Dup, IP4_MAX_HEADLEN, NET_BUF_HEAD); - ASSERT (Head != NULL); - - Dup->Ip.Ip4 = (IP4_HEAD *) Head; - - CopyMem (Head, Packet->Ip.Ip4, Packet->Ip.Ip4->HeadLen << 2); - NetbufTrim (Dup, IP4_MAX_HEADLEN, TRUE); + if (!IpInstance->ConfigData.RawData) { + // + // Copy the IP head over. The packet to deliver up is + // headless. Trim the head off after copy. The IP head + // may be not continuous before the data. + // + Head = NetbufAllocSpace (Dup, IP4_MAX_HEADLEN, NET_BUF_HEAD); + ASSERT (Head != NULL); + + Dup->Ip.Ip4 = (IP4_HEAD *) Head; + + CopyMem (Head, Packet->Ip.Ip4, Packet->Ip.Ip4->HeadLen << 2); + NetbufTrim (Dup, IP4_MAX_HEADLEN, TRUE); + } Wrap = Ip4WrapRxData (IpInstance, Dup); @@ -1326,10 +1340,12 @@ Ip4InstanceDeliverPacket ( Enqueue a received packet to all the IP children that share the same interface. - @param[in] IpSb The IP4 service instance that receive the packet - @param[in] Head The header of the received packet - @param[in] Packet The data of the received packet - @param[in] IpIf The interface to enqueue the packet to + @param[in] IpSb The IP4 service instance that receive the packet. + @param[in] Head The header of the received packet. + @param[in] Packet The data of the received packet. + @param[in] Option Point to the IP4 packet header options. + @param[in] OptionLen Length of the IP4 packet header options. + @param[in] IpIf The interface to enqueue the packet to. @return The number of the IP4 children that accepts the packet @@ -1339,6 +1355,8 @@ Ip4InterfaceEnquePacket ( IN IP4_SERVICE *IpSb, IN IP4_HEAD *Head, IN NET_BUF *Packet, + IN UINT8 *Option, + IN UINT32 OptionLen, IN IP4_INTERFACE *IpIf ) { @@ -1404,6 +1422,13 @@ Ip4InterfaceEnquePacket ( IpInstance = NET_LIST_USER_STRUCT (Entry, IP4_PROTOCOL, AddrLink); NET_CHECK_SIGNATURE (IpInstance, IP4_PROTOCOL_SIGNATURE); + // + // In RawData mode, add IPv4 headers and options back to packet. + // + if ((IpInstance->ConfigData.RawData) && (Option != NULL) && (OptionLen != 0)){ + Ip4PrependHead (Packet, Head, Option, OptionLen); + } + if (Ip4InstanceEnquePacket (IpInstance, Head, Packet) == EFI_SUCCESS) { Enqueued++; } @@ -1450,11 +1475,13 @@ Ip4InterfaceDeliverPacket ( child wants to consume the packet because each IP child needs its own copy of the packet to make changes. - @param[in] IpSb The IP4 service instance that received the packet - @param[in] Head The header of the received packet - @param[in] Packet The data of the received packet + @param[in] IpSb The IP4 service instance that received the packet. + @param[in] Head The header of the received packet. + @param[in] Packet The data of the received packet. + @param[in] Option Point to the IP4 packet header options. + @param[in] OptionLen Length of the IP4 packet header options. - @retval EFI_NOT_FOUND No IP child accepts the packet + @retval EFI_NOT_FOUND No IP child accepts the packet. @retval EFI_SUCCESS The packet is enqueued or delivered to some IP children. @@ -1463,7 +1490,9 @@ EFI_STATUS Ip4Demultiplex ( IN IP4_SERVICE *IpSb, IN IP4_HEAD *Head, - IN NET_BUF *Packet + IN NET_BUF *Packet, + IN UINT8 *Option, + IN UINT32 OptionLen ) { LIST_ENTRY *Entry; @@ -1480,7 +1509,14 @@ Ip4Demultiplex ( IpIf = NET_LIST_USER_STRUCT (Entry, IP4_INTERFACE, Link); if (IpIf->Configured) { - Enqueued += Ip4InterfaceEnquePacket (IpSb, Head, Packet, IpIf); + Enqueued += Ip4InterfaceEnquePacket ( + IpSb, + Head, + Packet, + Option, + OptionLen, + IpIf + ); } } diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h index fda4d18c9c..1c8e8b2a15 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -141,11 +141,13 @@ Ip4AccpetFrame ( child wants to consume the packet because each IP child needs its own copy of the packet to make changes. - @param[in] IpSb The IP4 service instance that received the packet - @param[in] Head The header of the received packet - @param[in] Packet The data of the received packet + @param[in] IpSb The IP4 service instance that received the packet. + @param[in] Head The header of the received packet. + @param[in] Packet The data of the received packet. + @param[in] Option Point to the IP4 packet header options. + @param[in] OptionLen Length of the IP4 packet header options. - @retval EFI_NOT_FOUND No IP child accepts the packet + @retval EFI_NOT_FOUND No IP child accepts the packet. @retval EFI_SUCCESS The packet is enqueued or delivered to some IP children. @@ -154,17 +156,21 @@ EFI_STATUS Ip4Demultiplex ( IN IP4_SERVICE *IpSb, IN IP4_HEAD *Head, - IN NET_BUF *Packet + IN NET_BUF *Packet, + IN UINT8 *Option, + IN UINT32 OptionLen ); /** Enqueue a received packet to all the IP children that share the same interface. - @param[in] IpSb The IP4 service instance that receive the packet - @param[in] Head The header of the received packet - @param[in] Packet The data of the received packet - @param[in] IpIf The interface to enqueue the packet to + @param[in] IpSb The IP4 service instance that receive the packet. + @param[in] Head The header of the received packet. + @param[in] Packet The data of the received packet. + @param[in] Option Point to the IP4 packet header options. + @param[in] OptionLen Length of the IP4 packet header options. + @param[in] IpIf The interface to enqueue the packet to. @return The number of the IP4 children that accepts the packet @@ -174,6 +180,8 @@ Ip4InterfaceEnquePacket ( IN IP4_SERVICE *IpSb, IN IP4_HEAD *Head, IN NET_BUF *Packet, + IN UINT8 *Option, + IN UINT32 OptionLen, IN IP4_INTERFACE *IpIf ); diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c index 85dffe0643..7ff17b6637 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c @@ -1,7 +1,7 @@ /** @file Transmit the IP4 packet. -Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -204,6 +204,10 @@ Ip4SysPacketSent ( @retval EFI_NO_MAPPING There is no interface to the destination. @retval EFI_NOT_FOUND There is no route to the destination @retval EFI_SUCCESS The packet is successfully transmitted. + @retval EFI_BAD_BUFFER_SIZE The length of the IPv4 header + option length + + total data length is greater than MTU (or greater + than the maximum packet size if Token.Packet.TxData. + OverrideData.DoNotFragment is TRUE.) @retval Others Failed to transmit the packet. **/ @@ -231,6 +235,7 @@ Ip4Output ( UINT32 Offset; UINT32 Mtu; UINT32 Num; + BOOLEAN RawData; // // Select an interface/source for system packet, application @@ -252,11 +257,18 @@ Ip4Output ( // // Before IPsec process, prepared the IP head. + // If Ip4Output is transmitting RawData, don't update IPv4 header. // - HeadLen = sizeof (IP4_HEAD) + ((OptLen + 3) & (~0x03)); - Head->HeadLen = (UINT8) (HeadLen >> 2); - Head->Id = mIp4Id++; - Head->Ver = 4; + HeadLen = sizeof (IP4_HEAD) + ((OptLen + 3) & (~0x03)); + + if ((IpInstance != NULL) && IpInstance->ConfigData.RawData) { + RawData = TRUE; + } else { + Head->HeadLen = (UINT8) (HeadLen >> 2); + Head->Id = mIp4Id++; + Head->Ver = 4; + RawData = FALSE; + } // // Call IPsec process. @@ -323,6 +335,13 @@ Ip4Output ( Mtu = IpSb->MaxPacketSize + sizeof (IP4_HEAD); if (Packet->TotalSize + HeadLen > Mtu) { + // + // Fragmentation is diabled for RawData mode. + // + if (RawData) { + return EFI_BAD_BUFFER_SIZE; + } + // // Packet is fragmented from the tail to the head, that is, the // first frame sent is the last fragment of the packet. The first diff --git a/MdeModulePkg/Universal/Network/MnpDxe/ComponentName.c b/MdeModulePkg/Universal/Network/MnpDxe/ComponentName.c index c56ad061e1..9e66dc254b 100644 --- a/MdeModulePkg/Universal/Network/MnpDxe/ComponentName.c +++ b/MdeModulePkg/Universal/Network/MnpDxe/ComponentName.c @@ -1,7 +1,7 @@ /** @file UEFI Component Name(2) protocol implementation for MnpDxe driver. -Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full @@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ -#include "MnpDriver.h" +#include "MnpImpl.h" // // EFI Component Name Protocol @@ -44,6 +44,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mMnpDriverNameTable[ } }; +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gMnpControllerNameTable = NULL; + /** Retrieves a Unicode string that is the user readable name of the driver. @@ -100,6 +102,106 @@ MnpComponentNameGetDriverName ( ); } +/** + Update the component name for the MNP child handle. + + @param Mnp[in] A pointer to the EFI_MANAGED_NETWORK_PROTOCOL. + + + @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully. + @retval EFI_INVALID_PARAMETER The input parameter is invalid. + +**/ +EFI_STATUS +UpdateName ( + IN EFI_MANAGED_NETWORK_PROTOCOL *Mnp + ) +{ + EFI_STATUS Status; + MNP_INSTANCE_DATA *Instance; + CHAR16 HandleName[80]; + EFI_MANAGED_NETWORK_CONFIG_DATA MnpConfigData; + EFI_SIMPLE_NETWORK_MODE SnpModeData; + UINTN OffSet; + UINTN Index; + + if (Mnp == NULL) { + return EFI_INVALID_PARAMETER; + } + + Instance = MNP_INSTANCE_DATA_FROM_THIS (Mnp); + // + // Format the child name into the string buffer as: + // MNP (MAC=FF-FF-FF-FF-FF-FF, ProtocolType=0x0800, VlanId=0) + // + Status = Mnp->GetModeData (Mnp, &MnpConfigData, &SnpModeData); + if (!EFI_ERROR (Status)) { + OffSet = 0; + // + // Print the MAC address. + // + OffSet += UnicodeSPrint ( + HandleName, + sizeof (HandleName), + L"MNP (MAC=" + ); + for (Index = 0; Index < SnpModeData.HwAddressSize; Index++) { + OffSet += UnicodeSPrint ( + HandleName + OffSet, + sizeof (HandleName) - OffSet, + L"%02X-", + SnpModeData.CurrentAddress.Addr[Index] + ); + } + // + // Remove the last '-' + // + OffSet--; + // + // Print the ProtocolType and VLAN ID for this instance. + // + OffSet += UnicodeSPrint ( + HandleName + OffSet, + sizeof (HandleName) - OffSet, + L", ProtocolType=0x%X, VlanId=%d)", + MnpConfigData.ProtocolTypeFilter, + Instance->MnpServiceData->VlanId + ); + } else if (Status == EFI_NOT_STARTED) { + UnicodeSPrint ( + HandleName, + sizeof (HandleName), + L"MNP (Not started)" + ); + } else { + return Status; + } + + if (gMnpControllerNameTable != NULL) { + FreeUnicodeStringTable (gMnpControllerNameTable); + gMnpControllerNameTable = NULL; + } + + Status = AddUnicodeString2 ( + "eng", + gMnpComponentName.SupportedLanguages, + &gMnpControllerNameTable, + HandleName, + TRUE + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return AddUnicodeString2 ( + "en", + gMnpComponentName2.SupportedLanguages, + &gMnpControllerNameTable, + HandleName, + FALSE + ); +} + /** Retrieves a Unicode string that is the user readable name of the controller that is being managed by a driver. @@ -178,5 +280,68 @@ MnpComponentNameGetControllerName ( OUT CHAR16 **ControllerName ) { - return EFI_UNSUPPORTED; + EFI_STATUS Status; + EFI_MANAGED_NETWORK_PROTOCOL *Mnp; + + // + // Only provide names for MNP child handles. + // + if (ChildHandle == NULL) { + return EFI_UNSUPPORTED; + } + + // + // Make sure this driver is currently managing ControllerHandle + // + Status = EfiTestManagedDevice ( + ControllerHandle, + gMnpDriverBinding.DriverBindingHandle, + &gEfiSimpleNetworkProtocolGuid + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Make sure this driver produced ChildHandle + // + Status = EfiTestChildHandle ( + ControllerHandle, + ChildHandle, + &gEfiManagedNetworkServiceBindingProtocolGuid + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Retrieve an instance of a produced protocol from ChildHandle + // + Status = gBS->OpenProtocol ( + ChildHandle, + &gEfiManagedNetworkProtocolGuid, + (VOID **)&Mnp, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Update the component name for this child handle. + // + Status = UpdateName (Mnp); + if (EFI_ERROR (Status)) { + return Status; + } + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + gMnpControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gMnpComponentName) + ); } diff --git a/MdeModulePkg/Universal/Network/MnpDxe/ComponentName.h b/MdeModulePkg/Universal/Network/MnpDxe/ComponentName.h index 6f60ef7e69..6232c3e1ed 100644 --- a/MdeModulePkg/Universal/Network/MnpDxe/ComponentName.h +++ b/MdeModulePkg/Universal/Network/MnpDxe/ComponentName.h @@ -1,7 +1,7 @@ /** @file The header file of UEFI Component Name(2) protocol. -Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full @@ -21,6 +21,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. extern EFI_COMPONENT_NAME2_PROTOCOL gMnpComponentName2; extern EFI_COMPONENT_NAME_PROTOCOL gMnpComponentName; +extern EFI_UNICODE_STRING_TABLE *gMnpControllerNameTable; /** Retrieves a Unicode string that is the user readable name of the driver. diff --git a/MdeModulePkg/Universal/Network/MnpDxe/MnpConfig.c b/MdeModulePkg/Universal/Network/MnpDxe/MnpConfig.c index c19c71b411..9586db7a2e 100644 --- a/MdeModulePkg/Universal/Network/MnpDxe/MnpConfig.c +++ b/MdeModulePkg/Universal/Network/MnpDxe/MnpConfig.c @@ -1,7 +1,7 @@ /** @file Implementation of Managed Network Protocol private services. -Copyright (c) 2005 - 2010, Intel Corporation. All rights reserved.
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full @@ -45,7 +45,6 @@ EFI_MANAGED_NETWORK_CONFIG_DATA mMnpDefaultConfigData = { FALSE }; - /** Add Count of net buffers to MnpDeviceData->FreeNbufQue. The length of the net buffer is specified by MnpDeviceData->BufferLength. @@ -686,6 +685,30 @@ MnpDestroyServiceData ( return Status; } +/** + Callback function which provided by user to remove one node in NetDestroyLinkList process. + + @param[in] Entry The entry to be removed. + @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList. + + @retval EFI_SUCCESS The entry has been removed successfully. + @retval Others Fail to remove the entry. + +**/ +EFI_STATUS +MnpDestoryChildEntry ( + IN LIST_ENTRY *Entry, + IN VOID *Context +) +{ + MNP_INSTANCE_DATA *Instance; + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + + ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *) Context; + Instance = CR (Entry, MNP_INSTANCE_DATA, InstEntry, MNP_INSTANCE_DATA_SIGNATURE); + return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle); +} + /** Destroy all child of the MNP service data. @@ -700,26 +723,20 @@ MnpDestroyServiceChild ( IN OUT MNP_SERVICE_DATA *MnpServiceData ) { - EFI_STATUS Status; - MNP_INSTANCE_DATA *Instance; - EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; - - ServiceBinding = &MnpServiceData->ServiceBinding; - while (!IsListEmpty (&MnpServiceData->ChildrenList)) { - // - // Don't use NetListRemoveHead here, the remove opreration will be done - // in ServiceBindingDestroyChild. - // - Instance = NET_LIST_HEAD ( - &MnpServiceData->ChildrenList, - MNP_INSTANCE_DATA, - InstEntry - ); - - Status = ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle); - if (EFI_ERROR (Status)) { - return Status; - } + LIST_ENTRY *List; + EFI_STATUS Status; + UINTN ListLength; + + List = &MnpServiceData->ChildrenList; + + Status = NetDestroyLinkList ( + List, + MnpDestoryChildEntry, + &MnpServiceData->ServiceBinding, + &ListLength + ); + if (EFI_ERROR (Status) || ListLength != 0) { + return EFI_DEVICE_ERROR; } return EFI_SUCCESS; diff --git a/MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.c b/MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.c index 03ddfb7ccc..84c618c27d 100644 --- a/MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.c +++ b/MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.c @@ -1,7 +1,7 @@ /** @file Implementation of driver entry point and driver binding protocol. -Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full @@ -26,6 +26,50 @@ EFI_DRIVER_BINDING_PROTOCOL gMnpDriverBinding = { NULL }; +/** + Callback function which provided by user to remove one node in NetDestroyLinkList process. + + @param[in] Entry The entry to be removed. + @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList. + + @retval EFI_SUCCESS The entry has been removed successfully. + @retval Others Fail to remove the entry. + +**/ +EFI_STATUS +MnpDestroyServiceDataEntry ( + IN LIST_ENTRY *Entry, + IN VOID *Context +) +{ + MNP_SERVICE_DATA *MnpServiceData; + + MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry); + return MnpDestroyServiceData (MnpServiceData); +} + +/** + Callback function which provided by user to remove one node in NetDestroyLinkList process. + + @param[in] Entry The entry to be removed. + @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList. + + @retval EFI_SUCCESS The entry has been removed successfully. + @retval Others Fail to remove the entry. + +**/ +EFI_STATUS +MnpDestroyServiceChildEntry ( + IN LIST_ENTRY *Entry, + IN VOID *Context +) +{ + MNP_SERVICE_DATA *MnpServiceData; + + MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry); + return MnpDestroyServiceChild (MnpServiceData); +} + /** Test to see if this driver supports ControllerHandle. This service is called by the EFI boot service ConnectController(). In @@ -276,8 +320,8 @@ MnpDriverBindingStop ( EFI_VLAN_CONFIG_PROTOCOL *VlanConfig; MNP_DEVICE_DATA *MnpDeviceData; MNP_SERVICE_DATA *MnpServiceData; - BOOLEAN AllChildrenStopped; - LIST_ENTRY *Entry; + LIST_ENTRY *List; + UINTN ListLength; // // Try to retrieve MNP service binding protocol from the ControllerHandle @@ -317,10 +361,15 @@ MnpDriverBindingStop ( // // Destroy all MNP service data // - while (!IsListEmpty (&MnpDeviceData->ServiceList)) { - Entry = GetFirstNode (&MnpDeviceData->ServiceList); - MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry); - MnpDestroyServiceData (MnpServiceData); + List = &MnpDeviceData->ServiceList; + Status = NetDestroyLinkList ( + List, + MnpDestroyServiceDataEntry, + NULL, + &ListLength + ); + if (EFI_ERROR (Status) || ListLength !=0) { + return EFI_DEVICE_ERROR; } // @@ -341,23 +390,24 @@ MnpDriverBindingStop ( MnpDestroyDeviceData (MnpDeviceData, This->DriverBindingHandle); FreePool (MnpDeviceData); + if (gMnpControllerNameTable != NULL) { + FreeUnicodeStringTable (gMnpControllerNameTable); + gMnpControllerNameTable = NULL; + } return EFI_SUCCESS; } // // Stop all MNP child // - AllChildrenStopped = TRUE; - NET_LIST_FOR_EACH (Entry, &MnpDeviceData->ServiceList) { - MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry); - - Status = MnpDestroyServiceChild (MnpServiceData); - if (EFI_ERROR (Status)) { - AllChildrenStopped = FALSE; - } - } - - if (!AllChildrenStopped) { + List = &MnpDeviceData->ServiceList; + Status = NetDestroyLinkList ( + List, + MnpDestroyServiceChildEntry, + NULL, + &ListLength + ); + if (EFI_ERROR (Status)) { return EFI_DEVICE_ERROR; } diff --git a/MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.h b/MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.h index f096862485..35a9b710db 100644 --- a/MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.h +++ b/MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.h @@ -1,7 +1,7 @@ /** @file Declaration of strctures and functions for MnpDxe driver. -Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full @@ -33,11 +33,17 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include #include "ComponentName.h" #define MNP_DEVICE_DATA_SIGNATURE SIGNATURE_32 ('M', 'n', 'p', 'D') +// +// Global Variables +// +extern EFI_DRIVER_BINDING_PROTOCOL gMnpDriverBinding; + typedef struct { UINT32 Signature; diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/ComponentName.c b/MdeModulePkg/Universal/Network/Mtftp4Dxe/ComponentName.c index 71f49f6039..901c2df064 100644 --- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/ComponentName.c +++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/ComponentName.c @@ -1,7 +1,7 @@ /** @file UEFI Component Name(2) protocol implementation for Mtftp4Dxe driver. -Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -12,7 +12,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ -#include "Mtftp4Driver.h" +#include "Mtftp4Impl.h" // // EFI Component Name Functions @@ -174,6 +174,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mMtftp4DriverNameTable[] } }; +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gMtftp4ControllerNameTable = NULL; + /** Retrieves a Unicode string that is the user readable name of the driver. @@ -230,6 +232,72 @@ Mtftp4ComponentNameGetDriverName ( ); } +/** + Update the component name for the Mtftp4 child handle. + + @param Mtftp4[in] A pointer to the EFI_MTFTP4_PROTOCOL. + + + @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully. + @retval EFI_INVALID_PARAMETER The input parameter is invalid. + +**/ +EFI_STATUS +UpdateName ( + IN EFI_MTFTP4_PROTOCOL *Mtftp4 + ) +{ + EFI_STATUS Status; + CHAR16 HandleName[80]; + EFI_MTFTP4_MODE_DATA ModeData; + + if (Mtftp4 == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Format the child name into the string buffer as: + // MTFTPv4 (ServerIp=192.168.1.10, ServerPort=69) + // + Status = Mtftp4->GetModeData (Mtftp4, &ModeData); + if (EFI_ERROR (Status)) { + return Status; + } + + UnicodeSPrint (HandleName, sizeof (HandleName), + L"MTFTPv4 (ServerIp=%d.%d.%d.%d, ServerPort=%d)", + ModeData.ConfigData.ServerIp.Addr[0], + ModeData.ConfigData.ServerIp.Addr[1], + ModeData.ConfigData.ServerIp.Addr[2], + ModeData.ConfigData.ServerIp.Addr[3], + ModeData.ConfigData.InitialServerPort + ); + + if (gMtftp4ControllerNameTable != NULL) { + FreeUnicodeStringTable (gMtftp4ControllerNameTable); + gMtftp4ControllerNameTable = NULL; + } + + Status = AddUnicodeString2 ( + "eng", + gMtftp4ComponentName.SupportedLanguages, + &gMtftp4ControllerNameTable, + HandleName, + TRUE + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return AddUnicodeString2 ( + "en", + gMtftp4ComponentName2.SupportedLanguages, + &gMtftp4ControllerNameTable, + HandleName, + FALSE + ); +} + /** Retrieves a Unicode string that is the user readable name of the controller that is being managed by a driver. @@ -308,5 +376,56 @@ Mtftp4ComponentNameGetControllerName ( OUT CHAR16 **ControllerName ) { - return EFI_UNSUPPORTED; + EFI_STATUS Status; + EFI_MTFTP4_PROTOCOL *Mtftp4; + + // + // Only provide names for child handles. + // + if (ChildHandle == NULL) { + return EFI_UNSUPPORTED; + } + + // + // Make sure this driver produced ChildHandle + // + Status = EfiTestChildHandle ( + ControllerHandle, + ChildHandle, + &gEfiUdp4ProtocolGuid + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Retrieve an instance of a produced protocol from ChildHandle + // + Status = gBS->OpenProtocol ( + ChildHandle, + &gEfiMtftp4ProtocolGuid, + (VOID **)&Mtftp4, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Update the component name for this child handle. + // + Status = UpdateName (Mtftp4); + if (EFI_ERROR (Status)) { + return Status; + } + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + gMtftp4ControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gMtftp4ComponentName) + ); } diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c index 2a12b1d5e7..8da47fc8df 100644 --- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c +++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c @@ -159,7 +159,6 @@ Mtftp4CreateService ( MtftpSb->Signature = MTFTP4_SERVICE_SIGNATURE; MtftpSb->ServiceBinding = gMtftp4ServiceBindingTemplete; - MtftpSb->InDestroy = FALSE; MtftpSb->ChildrenNum = 0; InitializeListHead (&MtftpSb->Children); @@ -318,6 +317,42 @@ ON_ERROR: return Status; } +/** + Callback function which provided by user to remove one node in NetDestroyLinkList process. + + @param[in] Entry The entry to be removed. + @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList. + + @retval EFI_SUCCESS The entry has been removed successfully. + @retval Others Fail to remove the entry. + +**/ +EFI_STATUS +Mtftp4DestroyChildEntryInHandleBuffer ( + IN LIST_ENTRY *Entry, + IN VOID *Context +) +{ + MTFTP4_PROTOCOL *Instance; + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + UINTN NumberOfChildren; + EFI_HANDLE *ChildHandleBuffer; + + if (Entry == NULL || Context == NULL) { + return EFI_INVALID_PARAMETER; + } + + Instance = NET_LIST_USER_STRUCT_S (Entry, MTFTP4_PROTOCOL, Link, MTFTP4_PROTOCOL_SIGNATURE); + ServiceBinding = ((MTFTP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding; + NumberOfChildren = ((MTFTP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren; + ChildHandleBuffer = ((MTFTP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer; + + if (!NetIsInHandleBuffer (Instance->Handle, NumberOfChildren, ChildHandleBuffer)) { + return EFI_SUCCESS; + } + + return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle); +} /** Stop the MTFTP driver on controller. The controller is a UDP @@ -341,12 +376,12 @@ Mtftp4DriverBindingStop ( IN EFI_HANDLE *ChildHandleBuffer ) { - EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; - MTFTP4_SERVICE *MtftpSb; - MTFTP4_PROTOCOL *Instance; - EFI_HANDLE NicHandle; - EFI_STATUS Status; - EFI_TPL OldTpl; + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + MTFTP4_SERVICE *MtftpSb; + EFI_HANDLE NicHandle; + EFI_STATUS Status; + LIST_ENTRY *List; + MTFTP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context; // // MTFTP driver opens UDP child, So, Controller is a UDP @@ -356,7 +391,7 @@ Mtftp4DriverBindingStop ( NicHandle = NetLibGetNicHandle (Controller, &gEfiUdp4ProtocolGuid); if (NicHandle == NULL) { - return EFI_DEVICE_ERROR; + return EFI_SUCCESS; } Status = gBS->OpenProtocol ( @@ -374,16 +409,23 @@ Mtftp4DriverBindingStop ( MtftpSb = MTFTP4_SERVICE_FROM_THIS (ServiceBinding); - if (MtftpSb->InDestroy) { - return EFI_SUCCESS; + if (!IsListEmpty (&MtftpSb->Children)) { + // + // Destroy the Mtftp4 child instance in ChildHandleBuffer. + // + List = &MtftpSb->Children; + Context.ServiceBinding = ServiceBinding; + Context.NumberOfChildren = NumberOfChildren; + Context.ChildHandleBuffer = ChildHandleBuffer; + Status = NetDestroyLinkList ( + List, + Mtftp4DestroyChildEntryInHandleBuffer, + &Context, + NULL + ); } - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - if (NumberOfChildren == 0) { - - MtftpSb->InDestroy = TRUE; - + if (NumberOfChildren == 0 && IsListEmpty (&MtftpSb->Children)) { gBS->UninstallProtocolInterface ( NicHandle, &gEfiMtftp4ServiceBindingProtocolGuid, @@ -391,21 +433,15 @@ Mtftp4DriverBindingStop ( ); Mtftp4CleanService (MtftpSb); - - FreePool (MtftpSb); - } else { - - while (!IsListEmpty (&MtftpSb->Children)) { - Instance = NET_LIST_HEAD (&MtftpSb->Children, MTFTP4_PROTOCOL, Link); - Mtftp4ServiceBindingDestroyChild (ServiceBinding, Instance->Handle); + if (gMtftp4ControllerNameTable != NULL) { + FreeUnicodeStringTable (gMtftp4ControllerNameTable); + gMtftp4ControllerNameTable = NULL; } + FreePool (MtftpSb); - if (MtftpSb->ChildrenNum != 0) { - Status = EFI_DEVICE_ERROR; - } + Status = EFI_SUCCESS; } - gBS->RestoreTPL (OldTpl); return Status; } @@ -429,7 +465,6 @@ Mtftp4InitProtocol ( InitializeListHead (&Instance->Link); CopyMem (&Instance->Mtftp4, &gMtftp4ProtocolTemplate, sizeof (Instance->Mtftp4)); Instance->State = MTFTP4_STATE_UNCONFIGED; - Instance->InDestroy = FALSE; Instance->Service = MtftpSb; InitializeListHead (&Instance->Blocks); @@ -499,7 +534,9 @@ Mtftp4ServiceBindingCreateChild ( ); if (EFI_ERROR (Status)) { - goto ON_ERROR; + UdpIoFreeIo (Instance->UnicastPort); + FreePool (Instance); + return Status; } Instance->Handle = *ChildHandle; @@ -516,13 +553,30 @@ Mtftp4ServiceBindingCreateChild ( EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER ); if (EFI_ERROR (Status)) { - gBS->UninstallMultipleProtocolInterfaces ( - Instance->Handle, - &gEfiMtftp4ProtocolGuid, - &Instance->Mtftp4, - NULL - ); + goto ON_ERROR; + } + // + // Open the Udp4 protocol by child. + // + Status = gBS->OpenProtocol ( + Instance->UnicastPort->UdpHandle, + &gEfiUdp4ProtocolGuid, + (VOID **) &Udp4, + gMtftp4DriverBinding.DriverBindingHandle, + Instance->Handle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + if (EFI_ERROR (Status)) { + // + // Close the Udp4 protocol. + // + gBS->CloseProtocol ( + MtftpSb->ConnectUdp->UdpHandle, + &gEfiUdp4ProtocolGuid, + gMtftp4DriverBinding.DriverBindingHandle, + ChildHandle + ); goto ON_ERROR; } @@ -536,13 +590,21 @@ Mtftp4ServiceBindingCreateChild ( gBS->RestoreTPL (OldTpl); -ON_ERROR: + return EFI_SUCCESS; - if (EFI_ERROR (Status)) { - UdpIoFreeIo (Instance->UnicastPort); - FreePool (Instance); +ON_ERROR: + if (Instance->Handle != NULL) { + gBS->UninstallMultipleProtocolInterfaces ( + Instance->Handle, + &gEfiMtftp4ProtocolGuid, + &Instance->Mtftp4, + NULL + ); } + UdpIoFreeIo (Instance->UnicastPort); + FreePool (Instance); + return Status; } @@ -615,6 +677,22 @@ Mtftp4ServiceBindingDestroyChild ( ChildHandle ); + gBS->CloseProtocol ( + Instance->UnicastPort->UdpHandle, + &gEfiUdp4ProtocolGuid, + gMtftp4DriverBinding.DriverBindingHandle, + ChildHandle + ); + + if (Instance->McastUdpPort != NULL) { + gBS->CloseProtocol ( + Instance->McastUdpPort->UdpHandle, + &gEfiUdp4ProtocolGuid, + gMtftp4DriverBinding.DriverBindingHandle, + ChildHandle + ); + } + // // Uninstall the MTFTP4 protocol first to enable a top down destruction. // diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.h b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.h index 63828bd433..936eab1ba1 100644 --- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.h +++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.h @@ -26,6 +26,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. extern EFI_COMPONENT_NAME_PROTOCOL gMtftp4ComponentName; extern EFI_COMPONENT_NAME2_PROTOCOL gMtftp4ComponentName2; extern EFI_DRIVER_BINDING_PROTOCOL gMtftp4DriverBinding; +extern EFI_UNICODE_STRING_TABLE *gMtftp4ControllerNameTable; /** Test whether MTFTP driver support this controller. diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c index 5183e1a5b3..f3a4952360 100644 --- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c +++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c @@ -58,6 +58,12 @@ Mtftp4CleanOperation ( } if (Instance->McastUdpPort != NULL) { + gBS->CloseProtocol ( + Instance->McastUdpPort->UdpHandle, + &gEfiUdp4ProtocolGuid, + gMtftp4DriverBinding.DriverBindingHandle, + Instance->Handle + ); UdpIoFreeIo (Instance->McastUdpPort); Instance->McastUdpPort = NULL; } diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.h b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.h index 41f524abb0..329c6d897a 100644 --- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.h +++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.h @@ -34,6 +34,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include extern EFI_MTFTP4_PROTOCOL gMtftp4ProtocolTemplate; @@ -68,8 +69,6 @@ struct _MTFTP4_SERVICE { UINT32 Signature; EFI_SERVICE_BINDING_PROTOCOL ServiceBinding; - BOOLEAN InDestroy; - UINT16 ChildrenNum; LIST_ENTRY Children; @@ -149,6 +148,12 @@ struct _MTFTP4_PROTOCOL { UDP_IO *McastUdpPort; }; +typedef struct { + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + UINTN NumberOfChildren; + EFI_HANDLE *ChildHandleBuffer; +} MTFTP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT; + /** Clean up the MTFTP session to get ready for new operation. diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c index 264598f49a..ae157c5e0a 100644 --- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c +++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c @@ -1,7 +1,7 @@ /** @file Routines to process Rrq (download). -Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -486,6 +486,7 @@ Mtftp4RrqHandleOack ( MTFTP4_OPTION Reply; EFI_STATUS Status; INTN Expected; + EFI_UDP4_PROTOCOL *Udp4; *Completed = FALSE; @@ -548,13 +549,31 @@ Mtftp4RrqHandleOack ( // Instance->McastIp = Reply.McastIp; Instance->McastPort = Reply.McastPort; - Instance->McastUdpPort = UdpIoCreateIo ( - Instance->Service->Controller, - Instance->Service->Image, - Mtftp4RrqConfigMcastPort, - UDP_IO_UDP4_VERSION, - Instance - ); + if (Instance->McastUdpPort == NULL) { + Instance->McastUdpPort = UdpIoCreateIo ( + Instance->Service->Controller, + Instance->Service->Image, + Mtftp4RrqConfigMcastPort, + UDP_IO_UDP4_VERSION, + Instance + ); + if (Instance->McastUdpPort != NULL) { + Status = gBS->OpenProtocol ( + Instance->McastUdpPort->UdpHandle, + &gEfiUdp4ProtocolGuid, + (VOID **) &Udp4, + Instance->Service->Image, + Instance->Handle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + if (EFI_ERROR (Status)) { + UdpIoFreeIo (Instance->McastUdpPort); + Instance->McastUdpPort = NULL; + return EFI_DEVICE_ERROR; + } + } + } + if (Instance->McastUdpPort == NULL) { return EFI_DEVICE_ERROR; diff --git a/MdeModulePkg/Universal/Network/SnpDxe/ComponentName.c b/MdeModulePkg/Universal/Network/SnpDxe/ComponentName.c index e8f7ec18bc..ef499d18cf 100644 --- a/MdeModulePkg/Universal/Network/SnpDxe/ComponentName.c +++ b/MdeModulePkg/Universal/Network/SnpDxe/ComponentName.c @@ -1,7 +1,7 @@ /** @file UEFI Component Name(2) protocol implementation for SnpDxe driver. -Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -175,6 +175,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mSimpleNetworkDriverNameT } }; +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gSimpleNetworkControllerNameTable = NULL; + /** Retrieves a Unicode string that is the user readable name of the driver. @@ -231,6 +233,78 @@ SimpleNetworkComponentNameGetDriverName ( ); } +/** + Update the component name for the Snp child handle. + + @param Snp[in] A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL. + + + @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully. + @retval EFI_INVALID_PARAMETER The input parameter is invalid. + +**/ +EFI_STATUS +UpdateName ( + IN EFI_SIMPLE_NETWORK_PROTOCOL *Snp + ) +{ + EFI_STATUS Status; + CHAR16 HandleName[80]; + UINTN OffSet; + UINTN Index; + + if (Snp == NULL) { + return EFI_INVALID_PARAMETER; + } + + OffSet = 0; + OffSet += UnicodeSPrint ( + HandleName, + sizeof (HandleName), + L"SNP (MAC=" + ); + for (Index = 0; Index < Snp->Mode->HwAddressSize; Index++) { + OffSet += UnicodeSPrint ( + HandleName + OffSet, + sizeof (HandleName) - OffSet, + L"%02X-", + Snp->Mode->CurrentAddress.Addr[Index] + ); + } + // + // Remove the last '-' + // + OffSet--; + OffSet += UnicodeSPrint ( + HandleName, + sizeof (HandleName), + L")" + ); + if (gSimpleNetworkControllerNameTable != NULL) { + FreeUnicodeStringTable (gSimpleNetworkControllerNameTable); + gSimpleNetworkControllerNameTable = NULL; + } + + Status = AddUnicodeString2 ( + "eng", + gSimpleNetworkComponentName.SupportedLanguages, + &gSimpleNetworkControllerNameTable, + HandleName, + TRUE + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return AddUnicodeString2 ( + "en", + gSimpleNetworkComponentName2.SupportedLanguages, + &gSimpleNetworkControllerNameTable, + HandleName, + FALSE + ); +} + /** Retrieves a Unicode string that is the user readable name of the controller that is being managed by a driver. @@ -310,5 +384,52 @@ SimpleNetworkComponentNameGetControllerName ( OUT CHAR16 **ControllerName ) { - return EFI_UNSUPPORTED; + EFI_STATUS Status; + EFI_SIMPLE_NETWORK_PROTOCOL *Snp; + + if (ChildHandle != NULL) { + return EFI_UNSUPPORTED; + } + + // + // Make sure this driver is currently managing ControllHandle + // + Status = EfiTestManagedDevice ( + ControllerHandle, + gSimpleNetworkDriverBinding.DriverBindingHandle, + &gEfiSimpleNetworkProtocolGuid + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Retrieve an instance of a produced protocol from ControllerHandle + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiSimpleNetworkProtocolGuid, + (VOID **)&Snp, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Update the component name for this child handle. + // + Status = UpdateName (Snp); + if (EFI_ERROR (Status)) { + return Status; + } + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + gSimpleNetworkControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gSimpleNetworkComponentName) + ); } diff --git a/MdeModulePkg/Universal/Network/SnpDxe/Snp.c b/MdeModulePkg/Universal/Network/SnpDxe/Snp.c index 72693e9ec4..f1fea0cff4 100644 --- a/MdeModulePkg/Universal/Network/SnpDxe/Snp.c +++ b/MdeModulePkg/Universal/Network/SnpDxe/Snp.c @@ -1,7 +1,7 @@ /** @file Implementation of driver entry point and driver binding protocol. -Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -828,7 +828,7 @@ SimpleNetworkDriverStop ( // // Simple Network Protocol Driver Global Variables // -EFI_DRIVER_BINDING_PROTOCOL mSimpleNetworkDriverBinding = { +EFI_DRIVER_BINDING_PROTOCOL gSimpleNetworkDriverBinding = { SimpleNetworkDriverSupported, SimpleNetworkDriverStart, SimpleNetworkDriverStop, @@ -1014,7 +1014,7 @@ InitializeSnpNiiDriver ( return EfiLibInstallDriverBindingComponentName2 ( ImageHandle, SystemTable, - &mSimpleNetworkDriverBinding, + &gSimpleNetworkDriverBinding, ImageHandle, &gSimpleNetworkComponentName, &gSimpleNetworkComponentName2 diff --git a/MdeModulePkg/Universal/Network/SnpDxe/Snp.h b/MdeModulePkg/Universal/Network/SnpDxe/Snp.h index dc63845334..4211b4dfc7 100644 --- a/MdeModulePkg/Universal/Network/SnpDxe/Snp.h +++ b/MdeModulePkg/Universal/Network/SnpDxe/Snp.h @@ -1,7 +1,7 @@ /** @file Declaration of strctures and functions for SnpDxe driver. -Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -31,6 +31,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include #include @@ -135,6 +136,7 @@ typedef struct { // // Global Variables // +extern EFI_DRIVER_BINDING_PROTOCOL gSimpleNetworkDriverBinding; extern EFI_COMPONENT_NAME_PROTOCOL gSimpleNetworkComponentName; extern EFI_COMPONENT_NAME2_PROTOCOL gSimpleNetworkComponentName2; diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/ComponentName.c b/MdeModulePkg/Universal/Network/Tcp4Dxe/ComponentName.c index 587f7c665b..dd0af8d7b4 100644 --- a/MdeModulePkg/Universal/Network/Tcp4Dxe/ComponentName.c +++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/ComponentName.c @@ -1,7 +1,7 @@ /** @file UEFI Component Name(2) protocol implementation for Tcp4Dxe driver. -Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -171,6 +171,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mTcpDriverNameTable[] = { } }; +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gTcpControllerNameTable = NULL; + /** Retrieves a Unicode string that is the user readable name of the driver. @@ -227,6 +229,76 @@ TcpComponentNameGetDriverName ( ); } +/** + Update the component name for the Tcp4 child handle. + + @param Tcp4[in] A pointer to the EFI_TCP4_PROTOCOL. + + + @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully. + @retval EFI_INVALID_PARAMETER The input parameter is invalid. + +**/ +EFI_STATUS +UpdateName ( + IN EFI_TCP4_PROTOCOL *Tcp4 + ) +{ + EFI_STATUS Status; + CHAR16 HandleName[80]; + EFI_TCP4_CONFIG_DATA Tcp4ConfigData; + + if (Tcp4 == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Format the child name into the string buffer as: + // TCPv4 (SrcPort=59, DestPort=60, ActiveFlag=TRUE) + // + Status = Tcp4->GetModeData (Tcp4, NULL, &Tcp4ConfigData, NULL, NULL, NULL); + if (!EFI_ERROR (Status)) { + UnicodeSPrint (HandleName, sizeof (HandleName), + L"TCPv4 (SrcPort=%d, DestPort=&d, ActiveFlag=%s)", + Tcp4ConfigData.AccessPoint.StationPort, + Tcp4ConfigData.AccessPoint.RemotePort, + (Tcp4ConfigData.AccessPoint.ActiveFlag ? L"TRUE" : L"FALSE") + ); + } if (Status == EFI_NOT_STARTED) { + UnicodeSPrint ( + HandleName, + sizeof (HandleName), + L"TCPv4 (Not started)" + ); + } else { + return Status; + } + + if (gTcpControllerNameTable != NULL) { + FreeUnicodeStringTable (gTcpControllerNameTable); + gTcpControllerNameTable = NULL; + } + + Status = AddUnicodeString2 ( + "eng", + gTcp4ComponentName.SupportedLanguages, + &gTcpControllerNameTable, + HandleName, + TRUE + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return AddUnicodeString2 ( + "en", + gTcp4ComponentName2.SupportedLanguages, + &gTcpControllerNameTable, + HandleName, + FALSE + ); +} + /** Retrieves a Unicode string that is the user readable name of the controller that is being managed by a driver. @@ -305,5 +377,56 @@ TcpComponentNameGetControllerName ( OUT CHAR16 **ControllerName ) { - return EFI_UNSUPPORTED; + EFI_STATUS Status; + EFI_TCP4_PROTOCOL *Tcp4; + + // + // Only provide names for child handles. + // + if (ChildHandle == NULL) { + return EFI_UNSUPPORTED; + } + + // + // Make sure this driver produced ChildHandle + // + Status = EfiTestChildHandle ( + ControllerHandle, + ChildHandle, + &gEfiIp4ProtocolGuid + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Retrieve an instance of a produced protocol from ChildHandle + // + Status = gBS->OpenProtocol ( + ChildHandle, + &gEfiTcp4ProtocolGuid, + (VOID **)&Tcp4, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Update the component name for this child handle. + // + Status = UpdateName (Tcp4); + if (EFI_ERROR (Status)) { + return Status; + } + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + gTcpControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gTcp4ComponentName) + ); } diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/SockInterface.c b/MdeModulePkg/Universal/Network/Tcp4Dxe/SockInterface.c index ac36460da8..feed86c590 100644 --- a/MdeModulePkg/Universal/Network/Tcp4Dxe/SockInterface.c +++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/SockInterface.c @@ -1,7 +1,7 @@ /** @file Interface function of the Socket. -Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -148,11 +148,11 @@ SockDestroyChild ( ASSERT ((Sock != NULL) && (Sock->ProtoHandler != NULL)); - if (Sock->IsDestroyed) { + if (Sock->InDestroy) { return EFI_SUCCESS; } - Sock->IsDestroyed = TRUE; + Sock->InDestroy = TRUE; Status = EfiAcquireLockOrFail (&(Sock->Lock)); if (EFI_ERROR (Status)) { @@ -173,7 +173,7 @@ SockDestroyChild ( DEBUG ((EFI_D_ERROR, "SockDestroyChild: Protocol detach socket" " failed with %r\n", Status)); - Sock->IsDestroyed = FALSE; + Sock->InDestroy = FALSE; } else if (SOCK_IS_CONFIGURED (Sock)) { SockConnFlush (Sock); diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/Socket.h b/MdeModulePkg/Universal/Network/Tcp4Dxe/Socket.h index b8ace790ca..8c25c63b11 100644 --- a/MdeModulePkg/Universal/Network/Tcp4Dxe/Socket.h +++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/Socket.h @@ -30,6 +30,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include #define SOCK_SND_BUF 0 #define SOCK_RCV_BUF 1 @@ -645,7 +646,7 @@ struct _SOCKET { SOCK_BUFFER SndBuffer; ///< Send buffer of application's data SOCK_BUFFER RcvBuffer; ///< Receive buffer of received data EFI_STATUS SockError; ///< The error returned by low layer protocol - BOOLEAN IsDestroyed; + BOOLEAN InDestroy; // // Fields used to manage the connection request diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dispatcher.c b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dispatcher.c index 688f9a7e99..93d10c9eb2 100644 --- a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dispatcher.c +++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dispatcher.c @@ -1,7 +1,7 @@ /** @file Tcp request dispatcher implementation. -Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -263,6 +263,8 @@ Tcp4AttachPcb ( TCP_CB *Tcb; TCP4_PROTO_DATA *ProtoData; IP_IO *IpIo; + EFI_STATUS Status; + VOID *Ip; Tcb = AllocateZeroPool (sizeof (TCP_CB)); @@ -286,6 +288,22 @@ Tcp4AttachPcb ( return EFI_OUT_OF_RESOURCES; } + // + // Open the new created IP instance BY_CHILD. + // + Status = gBS->OpenProtocol ( + Tcb->IpInfo->ChildHandle, + &gEfiIp4ProtocolGuid, + &Ip, + IpIo->Image, + Sk->SockHandle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + if (EFI_ERROR (Status)) { + IpIoRemoveIp (IpIo, Tcb->IpInfo); + return Status; + } + InitializeListHead (&Tcb->List); InitializeListHead (&Tcb->SndQue); InitializeListHead (&Tcb->RcvQue); @@ -318,6 +336,16 @@ Tcp4DetachPcb ( Tcp4FlushPcb (Tcb); + // + // Close the IP protocol. + // + gBS->CloseProtocol ( + Tcb->IpInfo->ChildHandle, + &gEfiIp4ProtocolGuid, + ProtoData->TcpService->IpIo->Image, + Sk->SockHandle + ); + IpIoRemoveIp (ProtoData->TcpService->IpIo, Tcb->IpInfo); FreePool (Tcb); diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c index a29b6bc434..1021252300 100644 --- a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c +++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c @@ -1,7 +1,7 @@ /** @file Tcp driver function. -Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -18,6 +18,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. UINT16 mTcp4RandomPort; extern EFI_COMPONENT_NAME_PROTOCOL gTcp4ComponentName; extern EFI_COMPONENT_NAME2_PROTOCOL gTcp4ComponentName2; +extern EFI_UNICODE_STRING_TABLE *gTcpControllerNameTable; TCP4_HEARTBEAT_TIMER mTcp4Timer = { NULL, @@ -135,6 +136,43 @@ Tcp4DestroyTimer ( mTcp4Timer.TimerEvent = NULL; } +/** + Callback function which provided by user to remove one node in NetDestroyLinkList process. + + @param[in] Entry The entry to be removed. + @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList. + + @retval EFI_SUCCESS The entry has been removed successfully. + @retval Others Fail to remove the entry. + +**/ +EFI_STATUS +Tcp4DestroyChildEntryInHandleBuffer ( + IN LIST_ENTRY *Entry, + IN VOID *Context +) +{ + SOCKET *Sock; + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + UINTN NumberOfChildren; + EFI_HANDLE *ChildHandleBuffer; + + if (Entry == NULL || Context == NULL) { + return EFI_INVALID_PARAMETER; + } + + Sock = NET_LIST_USER_STRUCT_S (Entry, SOCKET, Link, SOCK_SIGNATURE); + ServiceBinding = ((TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding; + NumberOfChildren = ((TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren; + ChildHandleBuffer = ((TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer; + + if (!NetIsInHandleBuffer (Sock->SockHandle, NumberOfChildren, ChildHandleBuffer)) { + return EFI_SUCCESS; + } + + return ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle); +} + /** The entry point for Tcp4 driver, used to install Tcp4 driver on the ImageHandle. @@ -387,6 +425,7 @@ ON_ERROR: if (TcpServiceData->IpIo != NULL) { IpIoDestroy (TcpServiceData->IpIo); + TcpServiceData->IpIo = NULL; } FreePool (TcpServiceData); @@ -431,17 +470,18 @@ Tcp4DriverBindingStop ( IN EFI_HANDLE *ChildHandleBuffer ) { - EFI_STATUS Status; - EFI_HANDLE NicHandle; - EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; - TCP4_SERVICE_DATA *TcpServiceData; - SOCKET *Sock; + EFI_STATUS Status; + EFI_HANDLE NicHandle; + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + TCP4_SERVICE_DATA *TcpServiceData; + LIST_ENTRY *List; + TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context; // Find the NicHandle where Tcp4 ServiceBinding Protocol is installed. // NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid); if (NicHandle == NULL) { - return EFI_DEVICE_ERROR; + return EFI_SUCCESS; } // @@ -465,7 +505,18 @@ Tcp4DriverBindingStop ( TcpServiceData = TCP4_FROM_THIS (ServiceBinding); - if (NumberOfChildren == 0) { + if (NumberOfChildren != 0) { + List = &TcpServiceData->SocketList; + Context.ServiceBinding = ServiceBinding; + Context.NumberOfChildren = NumberOfChildren; + Context.ChildHandleBuffer = ChildHandleBuffer; + Status = NetDestroyLinkList ( + List, + Tcp4DestroyChildEntryInHandleBuffer, + &Context, + NULL + ); + } else if (IsListEmpty (&TcpServiceData->SocketList)) { // // Uninstall TCP servicebinding protocol // @@ -480,6 +531,7 @@ Tcp4DriverBindingStop ( // Destroy the IpIO consumed by TCP driver // IpIoDestroy (TcpServiceData->IpIo); + TcpServiceData->IpIo = NULL; // // Destroy the heartbeat timer. @@ -491,17 +543,17 @@ Tcp4DriverBindingStop ( // TcpClearVariableData (TcpServiceData); + if (gTcpControllerNameTable != NULL) { + FreeUnicodeStringTable (gTcpControllerNameTable); + gTcpControllerNameTable = NULL; + } + // // Release the TCP service data // FreePool (TcpServiceData); - } else { - - while (!IsListEmpty (&TcpServiceData->SocketList)) { - Sock = NET_LIST_HEAD (&TcpServiceData->SocketList, SOCKET, Link); - ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle); - } + Status = EFI_SUCCESS; } return Status; @@ -713,14 +765,11 @@ Tcp4ServiceBindingDestroyChild ( EFI_STATUS Status; EFI_TCP4_PROTOCOL *Tcp4; SOCKET *Sock; - EFI_TPL OldTpl; if (NULL == This || NULL == ChildHandle) { return EFI_INVALID_PARAMETER; } - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - // // retrieve the Tcp4 protocol from ChildHandle // @@ -744,7 +793,6 @@ Tcp4ServiceBindingDestroyChild ( SockDestroyChild (Sock); } - gBS->RestoreTPL (OldTpl); return Status; } diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Main.h b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Main.h index c59075780f..cd904584bf 100644 --- a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Main.h +++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Main.h @@ -1,7 +1,7 @@ /** @file TCP4 protocol services header file. -Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -75,6 +75,12 @@ typedef struct _TCP4_ROUTE_INFO { EFI_IPv4_ADDRESS *GatewayAddress; } TCP4_ROUTE_INFO; +typedef struct { + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + UINTN NumberOfChildren; + EFI_HANDLE *ChildHandleBuffer; +} TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT; + /** Get the current operational status of a TCP instance. diff --git a/MdeModulePkg/Universal/Network/Udp4Dxe/ComponentName.c b/MdeModulePkg/Universal/Network/Udp4Dxe/ComponentName.c index acb8f167e1..cf311055e2 100644 --- a/MdeModulePkg/Universal/Network/Udp4Dxe/ComponentName.c +++ b/MdeModulePkg/Universal/Network/Udp4Dxe/ComponentName.c @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -174,6 +174,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUdpDriverNameTable[] = { } }; +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gUdpControllerNameTable = NULL; + /** Retrieves a Unicode string that is the user readable name of the driver. @@ -230,6 +232,75 @@ UdpComponentNameGetDriverName ( ); } +/** + Update the component name for the Udp4 child handle. + + @param Udp4[in] A pointer to the EFI_UDP4_PROTOCOL. + + + @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully. + @retval EFI_INVALID_PARAMETER The input parameter is invalid. + +**/ +EFI_STATUS +UpdateName ( + EFI_UDP4_PROTOCOL *Udp4 + ) +{ + EFI_STATUS Status; + CHAR16 HandleName[64]; + EFI_UDP4_CONFIG_DATA Udp4ConfigData; + + if (Udp4 == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Format the child name into the string buffer as: + // UDPv4 (SrcPort=59, DestPort=60) + // + Status = Udp4->GetModeData (Udp4, &Udp4ConfigData, NULL, NULL, NULL); + if (!EFI_ERROR (Status)) { + UnicodeSPrint (HandleName, sizeof (HandleName), + L"UDPv4 (SrcPort=%d, DestPort=%d)", + Udp4ConfigData.StationPort, + Udp4ConfigData.RemotePort + ); + } else if (Status == EFI_NOT_STARTED) { + UnicodeSPrint ( + HandleName, + sizeof (HandleName), + L"UDPv4 (Not started)" + ); + } else { + return Status; + } + + if (gUdpControllerNameTable != NULL) { + FreeUnicodeStringTable (gUdpControllerNameTable); + gUdpControllerNameTable = NULL; + } + + Status = AddUnicodeString2 ( + "eng", + gUdp4ComponentName.SupportedLanguages, + &gUdpControllerNameTable, + HandleName, + TRUE + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return AddUnicodeString2 ( + "en", + gUdp4ComponentName2.SupportedLanguages, + &gUdpControllerNameTable, + HandleName, + FALSE + ); +} + /** Retrieves a Unicode string that is the user readable name of the controller that is being managed by a driver. @@ -308,6 +379,57 @@ UdpComponentNameGetControllerName ( OUT CHAR16 **ControllerName ) { - return EFI_UNSUPPORTED; + EFI_STATUS Status; + EFI_UDP4_PROTOCOL *Udp4; + + // + // Only provide names for child handles. + // + if (ChildHandle == NULL) { + return EFI_UNSUPPORTED; + } + + // + // Make sure this driver produced ChildHandle + // + Status = EfiTestChildHandle ( + ControllerHandle, + ChildHandle, + &gEfiIp4ProtocolGuid + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Retrieve an instance of a produced protocol from ChildHandle + // + Status = gBS->OpenProtocol ( + ChildHandle, + &gEfiUdp4ProtocolGuid, + (VOID **)&Udp4, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Update the component name for this child handle. + // + Status = UpdateName (Udp4); + if (EFI_ERROR (Status)) { + return Status; + } + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + gUdpControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gUdp4ComponentName) + ); } diff --git a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Driver.c b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Driver.c index 5afb3aa58e..96b08d14e9 100644 --- a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Driver.c +++ b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Driver.c @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -28,6 +28,43 @@ EFI_SERVICE_BINDING_PROTOCOL mUdp4ServiceBinding = { Udp4ServiceBindingDestroyChild }; +/** + Callback function which provided by user to remove one node in NetDestroyLinkList process. + + @param[in] Entry The entry to be removed. + @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList. + + @retval EFI_SUCCESS The entry has been removed successfully. + @retval Others Fail to remove the entry. + +**/ +EFI_STATUS +Udp4DestroyChildEntryInHandleBuffer ( + IN LIST_ENTRY *Entry, + IN VOID *Context +) +{ + UDP4_INSTANCE_DATA *Instance; + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + UINTN NumberOfChildren; + EFI_HANDLE *ChildHandleBuffer; + + if (Entry == NULL || Context == NULL) { + return EFI_INVALID_PARAMETER; + } + + Instance = NET_LIST_USER_STRUCT_S (Entry, UDP4_INSTANCE_DATA, Link, UDP4_INSTANCE_DATA_SIGNATURE); + ServiceBinding = ((UDP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding; + NumberOfChildren = ((UDP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren; + ChildHandleBuffer = ((UDP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer; + + if (!NetIsInHandleBuffer (Instance->ChildHandle, NumberOfChildren, ChildHandleBuffer)) { + return EFI_SUCCESS; + } + + return ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle); +} + /** Test to see if this driver supports ControllerHandle. This service @@ -178,18 +215,19 @@ Udp4DriverBindingStop ( IN EFI_HANDLE *ChildHandleBuffer ) { - EFI_STATUS Status; - EFI_HANDLE NicHandle; - EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; - UDP4_SERVICE_DATA *Udp4Service; - UDP4_INSTANCE_DATA *Instance; + EFI_STATUS Status; + EFI_HANDLE NicHandle; + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + UDP4_SERVICE_DATA *Udp4Service; + UDP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context; + LIST_ENTRY *List; // // Find the NicHandle where UDP4 ServiceBinding Protocol is installed. // NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid); if (NicHandle == NULL) { - return EFI_DEVICE_ERROR; + return EFI_SUCCESS; } // @@ -208,9 +246,21 @@ Udp4DriverBindingStop ( } Udp4Service = UDP4_SERVICE_DATA_FROM_THIS (ServiceBinding); - - if (NumberOfChildren == 0) { - + if (NumberOfChildren != 0) { + // + // NumberOfChildren is not zero, destroy the children instances in ChildHandleBuffer. + // + List = &Udp4Service->ChildrenList; + Context.ServiceBinding = ServiceBinding; + Context.NumberOfChildren = NumberOfChildren; + Context.ChildHandleBuffer = ChildHandleBuffer; + Status = NetDestroyLinkList ( + List, + Udp4DestroyChildEntryInHandleBuffer, + &Context, + NULL + ); + } else { gBS->UninstallMultipleProtocolInterfaces ( NicHandle, &gEfiUdp4ServiceBindingProtocolGuid, @@ -222,14 +272,11 @@ Udp4DriverBindingStop ( Udp4CleanService (Udp4Service); - FreePool (Udp4Service); - } else { - - while (!IsListEmpty (&Udp4Service->ChildrenList)) { - Instance = NET_LIST_HEAD (&Udp4Service->ChildrenList, UDP4_INSTANCE_DATA, Link); - - ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle); + if (gUdpControllerNameTable != NULL) { + FreeUnicodeStringTable (gUdpControllerNameTable); + gUdpControllerNameTable = NULL; } + FreePool (Udp4Service); } return Status; @@ -323,6 +370,21 @@ Udp4ServiceBindingCreateChild ( goto ON_ERROR; } + // + // Open this instance's Ip4 protocol in the IpInfo BY_CHILD. + // + Status = gBS->OpenProtocol ( + Instance->IpInfo->ChildHandle, + &gEfiIp4ProtocolGuid, + (VOID **) &Ip4, + gUdp4DriverBinding.DriverBindingHandle, + Instance->ChildHandle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); // @@ -412,14 +474,14 @@ Udp4ServiceBindingDestroyChild ( Instance = UDP4_INSTANCE_DATA_FROM_THIS (Udp4Proto); - if (Instance->Destroyed) { + if (Instance->InDestroy) { return EFI_SUCCESS; } // // Use the Destroyed flag to avoid the re-entering of the following code. // - Instance->Destroyed = TRUE; + Instance->InDestroy = TRUE; // // Close the Ip4 protocol. @@ -430,6 +492,15 @@ Udp4ServiceBindingDestroyChild ( gUdp4DriverBinding.DriverBindingHandle, Instance->ChildHandle ); + // + // Close the Ip4 protocol on this instance's IpInfo. + // + gBS->CloseProtocol ( + Instance->IpInfo->ChildHandle, + &gEfiIp4ProtocolGuid, + gUdp4DriverBinding.DriverBindingHandle, + Instance->ChildHandle + ); // // Uninstall the Udp4Protocol previously installed on the ChildHandle. @@ -441,7 +512,7 @@ Udp4ServiceBindingDestroyChild ( NULL ); if (EFI_ERROR (Status)) { - Instance->Destroyed = FALSE; + Instance->InDestroy = FALSE; return Status; } diff --git a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c index 9326f3d344..8bba3572a2 100644 --- a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c +++ b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c @@ -1,7 +1,7 @@ /** @file The implementation of the Udp4 protocol. -Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -484,7 +484,7 @@ Udp4InitInstance ( Instance->IcmpError = EFI_SUCCESS; Instance->Configured = FALSE; Instance->IsNoMapping = FALSE; - Instance->Destroyed = FALSE; + Instance->InDestroy = FALSE; } diff --git a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.h b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.h index f8a39ebcf7..8142a4640f 100644 --- a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.h +++ b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.h @@ -1,7 +1,7 @@ /** @file EFI UDPv4 protocol implementation. -Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -31,12 +31,14 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include #include "Udp4Driver.h" extern EFI_COMPONENT_NAME_PROTOCOL gUdp4ComponentName; extern EFI_COMPONENT_NAME2_PROTOCOL gUdp4ComponentName2; +extern EFI_UNICODE_STRING_TABLE *gUdpControllerNameTable; extern EFI_SERVICE_BINDING_PROTOCOL mUdp4ServiceBinding; extern EFI_UDP4_PROTOCOL mUdp4Protocol; extern UINT16 mUdp4RandomPort; @@ -109,7 +111,7 @@ typedef struct _UDP4_INSTANCE_DATA_ { IP_IO_IP_INFO *IpInfo; - BOOLEAN Destroyed; + BOOLEAN InDestroy; } UDP4_INSTANCE_DATA; typedef struct _UDP4_RXDATA_WRAP_ { @@ -119,6 +121,12 @@ typedef struct _UDP4_RXDATA_WRAP_ { EFI_UDP4_RECEIVE_DATA RxData; } UDP4_RXDATA_WRAP; +typedef struct { + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + UINTN NumberOfChildren; + EFI_HANDLE *ChildHandleBuffer; +} UDP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT; + /** Reads the current operational settings. diff --git a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/ComponentName.c b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/ComponentName.c index 0d0378311d..f4ef59ce5e 100644 --- a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/ComponentName.c +++ b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/ComponentName.c @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -168,6 +168,17 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mPxeBcDriverNameTable[] = } }; +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mPxeBcControllerNameTable[] = { + { + "eng;en", + L"PXE Controller" + }, + { + NULL, + NULL + } +}; + /** Retrieves a Unicode string that is the user readable name of the driver. @@ -302,6 +313,53 @@ PxeBcComponentNameGetControllerName ( OUT CHAR16 **ControllerName ) { - return EFI_UNSUPPORTED; -} + EFI_PXE_BASE_CODE_PROTOCOL *PxeBc; + EFI_HANDLE NicHandle; + EFI_STATUS Status; + + if (ControllerHandle == NULL || ChildHandle != NULL) { + return EFI_UNSUPPORTED; + } + NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiArpProtocolGuid); + if (NicHandle == NULL) { + NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp4ProtocolGuid); + + if (NicHandle == NULL) { + NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid); + + if (NicHandle == NULL) { + NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp4ProtocolGuid); + + if (NicHandle == NULL) { + NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiMtftp4ProtocolGuid); + + if (NicHandle == NULL) { + return EFI_UNSUPPORTED; + } + } + } + } + } + + Status = gBS->OpenProtocol ( + NicHandle, + &gEfiPxeBaseCodeProtocolGuid, + (VOID **) &PxeBc, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mPxeBcControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gPxeBcComponentName) + ); +} diff --git a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDriver.c b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDriver.c index 0efcda58e5..2287863e3e 100644 --- a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDriver.c +++ b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDriver.c @@ -1,7 +1,7 @@ /** @file The driver binding for UEFI PXEBC protocol. -Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -526,7 +526,7 @@ PxeBcDriverBindingStop ( NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiMtftp4ProtocolGuid); if (NicHandle == NULL) { - return EFI_DEVICE_ERROR; + return EFI_SUCCESS; } } } diff --git a/MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigImpl.c b/MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigImpl.c index f992cea07b..10fb7fa670 100644 --- a/MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigImpl.c +++ b/MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigImpl.c @@ -1,7 +1,7 @@ /** @file HII Config Access protocol implementation of VLAN configuration module. -Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full @@ -489,6 +489,7 @@ InstallVlanConfigForm ( CHAR16 *MacString; EFI_DEVICE_PATH_PROTOCOL *ChildDevicePath; EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess; + EFI_VLAN_CONFIG_PROTOCOL *VlanConfig; // // Create child handle and install HII Config Access Protocol @@ -517,6 +518,22 @@ InstallVlanConfigForm ( } PrivateData->DriverHandle = DriverHandle; + // + // Establish the parent-child relationship between the new created + // child handle and the ControllerHandle. + // + Status = gBS->OpenProtocol ( + PrivateData->ControllerHandle, + &gEfiVlanConfigProtocolGuid, + (VOID **)&VlanConfig, + PrivateData->ImageHandle, + PrivateData->DriverHandle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + if (EFI_ERROR (Status)) { + return Status; + } + // // Publish the HII package list // @@ -593,6 +610,16 @@ UninstallVlanConfigForm ( PrivateData->HiiHandle = NULL; } + // + // End the parent-child relationship. + // + gBS->CloseProtocol ( + PrivateData->ControllerHandle, + &gEfiVlanConfigProtocolGuid, + PrivateData->ImageHandle, + PrivateData->DriverHandle + ); + // // Uninstall HII Config Access Protocol // diff --git a/NetworkPkg/Dhcp6Dxe/ComponentName.c b/NetworkPkg/Dhcp6Dxe/ComponentName.c index 178c8bca45..352df087f9 100644 --- a/NetworkPkg/Dhcp6Dxe/ComponentName.c +++ b/NetworkPkg/Dhcp6Dxe/ComponentName.c @@ -1,7 +1,7 @@ /** @file UEFI Component Name(2) protocol implementation for Dhcp6 driver. - Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -172,6 +172,19 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mDhcp6DriverNameTab } }; +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gDhcp6ControllerNameTable = NULL; + +CHAR16 *mDhcp6ControllerName[] = { + L"DHCPv6 (State=0, Init)", + L"DHCPv6 (State=1, Selecting)", + L"DHCPv6 (State=2, Requesting)", + L"DHCPv6 (State=3, Declining)", + L"DHCPv6 (State=4, Confirming)", + L"DHCPv6 (State=5, Releasing)", + L"DHCPv6 (State=6, Bound)", + L"DHCPv6 (State=7, Renewing)", + L"DHCPv6 (State=8, Rebinding)" +}; /** Retrieves a Unicode string that is the user-readable name of the driver. @@ -229,6 +242,67 @@ Dhcp6ComponentNameGetDriverName ( ); } +/** + Update the component name for the Dhcp6 child handle. + + @param Dhcp6[in] A pointer to the EFI_DHCP6_PROTOCOL. + + + @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully. + @retval EFI_INVALID_PARAMETER The input parameter is invalid. + +**/ +EFI_STATUS +UpdateName ( + IN EFI_DHCP6_PROTOCOL *Dhcp6 + ) +{ + EFI_STATUS Status; + EFI_DHCP6_MODE_DATA Dhcp6ModeData; + CHAR16 HandleName[64]; + + if (Dhcp6 == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Format the child name into the string buffer. + // + Status = Dhcp6->GetModeData (Dhcp6, &Dhcp6ModeData, NULL); + if (EFI_ERROR (Status)) { + return Status; + } + + if (gDhcp6ControllerNameTable != NULL) { + FreeUnicodeStringTable (gDhcp6ControllerNameTable); + gDhcp6ControllerNameTable = NULL; + } + + if (Dhcp6ModeData.Ia == NULL) { + UnicodeSPrint (HandleName, sizeof (HandleName), L"DHCPv6 (No configured IA)"); + } else { + StrCpy (HandleName, mDhcp6ControllerName[Dhcp6ModeData.Ia->State]); + } + + Status = AddUnicodeString2 ( + "eng", + gDhcp6ComponentName.SupportedLanguages, + &gDhcp6ControllerNameTable, + HandleName, + TRUE + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return AddUnicodeString2 ( + "en", + gDhcp6ComponentName2.SupportedLanguages, + &gDhcp6ControllerNameTable, + HandleName, + FALSE + ); +} /** Retrieves a Unicode string that is the user-readable name of the controller @@ -308,5 +382,57 @@ Dhcp6ComponentNameGetControllerName ( OUT CHAR16 **ControllerName ) { - return EFI_UNSUPPORTED; + EFI_STATUS Status; + EFI_DHCP6_PROTOCOL *Dhcp6; + + // + // Only provide names for child handles. + // + if (ChildHandle == NULL) { + return EFI_UNSUPPORTED; + } + + // + // Make sure this driver produced ChildHandle + // + Status = EfiTestChildHandle ( + ControllerHandle, + ChildHandle, + &gEfiUdp6ProtocolGuid + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Retrieve an instance of a produced protocol from ChildHandle + // + Status = gBS->OpenProtocol ( + ChildHandle, + &gEfiDhcp6ProtocolGuid, + (VOID **)&Dhcp6, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Update the component name for this child handle. + // + Status = UpdateName (Dhcp6); + if (EFI_ERROR (Status)) { + return Status; + } + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + gDhcp6ControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gDhcp6ComponentName) + ); } + diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c index 346986bd15..42caefb154 100644 --- a/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c +++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c @@ -31,7 +31,6 @@ EFI_SERVICE_BINDING_PROTOCOL gDhcp6ServiceBindingTemplate = { Dhcp6ServiceBindingDestroyChild }; - /** Configure the default Udp6Io to receive all the DHCP6 traffic on this network interface. @@ -155,7 +154,6 @@ Dhcp6CreateService ( // Initialize the fields of the new Dhcp6 service. // Dhcp6Srv->Signature = DHCP6_SERVICE_SIGNATURE; - Dhcp6Srv->InDestroy = FALSE; Dhcp6Srv->Controller = Controller; Dhcp6Srv->Image = ImageHandle; Dhcp6Srv->Xid = (0xffffff & NET_RANDOM (NetRandomInitSeed ())); @@ -328,6 +326,35 @@ Dhcp6CreateInstance ( return EFI_SUCCESS; } +/** + Callback function which provided by user to remove one node in NetDestroyLinkList process. + + @param[in] Entry The entry to be removed. + @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList. + + @retval EFI_SUCCESS The entry has been removed successfully. + @retval Others Fail to remove the entry. + +**/ +EFI_STATUS +Dhcp6DestroyChildEntry ( + IN LIST_ENTRY *Entry, + IN VOID *Context +) +{ + DHCP6_INSTANCE *Instance; + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + + if (Entry == NULL || Context == NULL) { + return EFI_INVALID_PARAMETER; + } + + Instance = NET_LIST_USER_STRUCT_S (Entry, DHCP6_INSTANCE, Link, DHCP6_INSTANCE_SIGNATURE); + ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *) Context; + + return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle); +} + /** Entry point of the DHCP6 driver to install various protocols. @@ -498,11 +525,11 @@ Dhcp6DriverBindingStop ( ) { EFI_STATUS Status; - EFI_TPL OldTpl; EFI_HANDLE NicHandle; EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; DHCP6_SERVICE *Service; - DHCP6_INSTANCE *Instance; + LIST_ENTRY *List; + UINTN ListLength; // // Find and check the Nic handle by the controller handle. @@ -510,7 +537,7 @@ Dhcp6DriverBindingStop ( NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp6ProtocolGuid); if (NicHandle == NULL) { - return EFI_DEVICE_ERROR; + return EFI_SUCCESS; } Status = gBS->OpenProtocol ( @@ -527,50 +554,44 @@ Dhcp6DriverBindingStop ( } Service = DHCP6_SERVICE_FROM_THIS (ServiceBinding); - - if (Service->InDestroy) { - return EFI_SUCCESS; + if (!IsListEmpty (&Service->Child)) { + // + // Destroy all the children instances before destory the service. + // + List = &Service->Child; + Status = NetDestroyLinkList ( + List, + Dhcp6DestroyChildEntry, + ServiceBinding, + &ListLength + ); + if (EFI_ERROR (Status) || ListLength != 0) { + Status = EFI_DEVICE_ERROR; + } } - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + if (NumberOfChildren == 0 && !IsListEmpty (&Service->Child)) { + Status = EFI_DEVICE_ERROR; + } - if (NumberOfChildren == 0) { + if (NumberOfChildren == 0 && IsListEmpty (&Service->Child)) { // // Destroy the service itself if no child instance left. // - Service->InDestroy = TRUE; - Status = gBS->UninstallProtocolInterface ( NicHandle, &gEfiDhcp6ServiceBindingProtocolGuid, ServiceBinding ); - if (EFI_ERROR (Status)) { - Service->InDestroy = FALSE; goto ON_EXIT; } Dhcp6DestroyService (Service); - - } else { - // - // Destroy all the children instances before destroy the service. - // - while (!IsListEmpty (&Service->Child)) { - Instance = NET_LIST_HEAD (&Service->Child, DHCP6_INSTANCE, Link); - ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle); - } - // - // Any of child failed to be destroyed. - // - if (Service->NumOfChild != 0) { - Status = EFI_DEVICE_ERROR; - } + Status = EFI_SUCCESS; } - + ON_EXIT: - gBS->RestoreTPL (OldTpl); return Status; } @@ -771,12 +792,13 @@ Dhcp6ServiceBindingDestroyChild ( // // Uninstall the MTFTP6 protocol first to enable a top down destruction. // + gBS->RestoreTPL (OldTpl); Status = gBS->UninstallProtocolInterface ( ChildHandle, &gEfiDhcp6ProtocolGuid, Dhcp6 ); - + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); if (EFI_ERROR (Status)) { Instance->InDestroy = FALSE; gBS->RestoreTPL (OldTpl); @@ -789,9 +811,8 @@ Dhcp6ServiceBindingDestroyChild ( RemoveEntryList (&Instance->Link); Service->NumOfChild--; - Dhcp6DestroyInstance (Instance); - gBS->RestoreTPL (OldTpl); + Dhcp6DestroyInstance (Instance); return EFI_SUCCESS; } diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.h index 4ef7f17963..bec47a0679 100644 --- a/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.h +++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.h @@ -2,7 +2,7 @@ Driver Binding functions and Service Binding functions declaration for Dhcp6 Driver. - Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -21,6 +21,7 @@ extern EFI_COMPONENT_NAME_PROTOCOL gDhcp6ComponentName; extern EFI_COMPONENT_NAME2_PROTOCOL gDhcp6ComponentName2; +extern EFI_UNICODE_STRING_TABLE *gDhcp6ControllerNameTable; /** Test to see if this driver supports ControllerHandle. This service diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c index 2c2b9f9f0e..934c03ed85 100644 --- a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c +++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c @@ -216,12 +216,11 @@ EfiDhcp6Stop ( Instance->UdpSts = EFI_ALREADY_STARTED; Status = Dhcp6SendReleaseMsg (Instance, Instance->IaCb.Ia); + gBS->RestoreTPL (OldTpl); if (EFI_ERROR (Status)) { goto ON_EXIT; } - gBS->RestoreTPL (OldTpl); - // // Poll udp out of the net tpl if synchoronus call. // diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h index d4e9746be8..71b16b1919 100644 --- a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h +++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h @@ -34,6 +34,7 @@ #include #include #include +#include typedef struct _DHCP6_IA_CB DHCP6_IA_CB; @@ -245,7 +246,7 @@ struct _DHCP6_INSTANCE { EFI_DHCP6_PACKET *AdSelect; UINT8 AdPref; EFI_IPv6_ADDRESS *Unicast; - EFI_STATUS UdpSts; + volatile EFI_STATUS UdpSts; BOOLEAN InDestroy; BOOLEAN MediaPresent; UINT64 StartTime; @@ -266,7 +267,6 @@ struct _DHCP6_SERVICE { UINT32 Xid; LIST_ENTRY Child; UINTN NumOfChild; - BOOLEAN InDestroy; }; /** diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c index f2e33f335f..0e83d07853 100644 --- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c +++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c @@ -2510,7 +2510,7 @@ Dhcp6HandleStateful ( ClientId = Service->ClientId; Status = EFI_SUCCESS; - if (Instance->InDestroy || Instance->Config == NULL) { + if (Instance->Config == NULL) { goto ON_CONTINUE; } @@ -2624,10 +2624,6 @@ Dhcp6HandleStateless ( IsMatched = FALSE; InfCb = NULL; - if (Instance->InDestroy) { - goto ON_EXIT; - } - if (Packet->Dhcp6.Header.MessageType != Dhcp6MsgReply) { goto ON_EXIT; } diff --git a/NetworkPkg/IScsiDxe/ComponentName.c b/NetworkPkg/IScsiDxe/ComponentName.c index e4e28e8961..1ee21f5d5d 100644 --- a/NetworkPkg/IScsiDxe/ComponentName.c +++ b/NetworkPkg/IScsiDxe/ComponentName.c @@ -1,7 +1,7 @@ /** @file UEFI Component Name(2) protocol implementation for iSCSI. -Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -43,6 +43,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIScsiDriverNameTable } }; +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gIScsiControllerNameTable = NULL; + /** Retrieves a Unicode string that is the user readable name of the driver. @@ -99,6 +101,99 @@ IScsiComponentNameGetDriverName ( ); } +/** + Update the component name for the iSCSI NIC handle. + + @param[in] Controller The handle of the NIC controller. + @param[in] Ipv6Flag TRUE if IP6 network stack is used. + + @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully. + @retval EFI_INVALID_PARAMETER The input parameter is invalid. + @retval EFI_UNSUPPORTED Can't get the corresponding NIC info from the Controller handle. + +**/ +EFI_STATUS +UpdateName ( + IN EFI_HANDLE Controller, + IN BOOLEAN Ipv6Flag + ) +{ + EFI_STATUS Status; + EFI_MAC_ADDRESS MacAddr; + UINTN HwAddressSize; + UINT16 VlanId; + ISCSI_NIC_INFO *ThisNic; + ISCSI_NIC_INFO *NicInfo; + LIST_ENTRY *Entry; + CHAR16 HandleName[80]; + + // + // Get MAC address of this network device. + // + Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Get VLAN ID of this network device. + // + VlanId = NetLibGetVlanId (Controller); + + // + // Check whether the NIC information exists. + // + ThisNic = NULL; + + NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) { + NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link); + if (NicInfo->HwAddressSize == HwAddressSize && + CompareMem (&NicInfo->PermanentAddress, MacAddr.Addr, HwAddressSize) == 0 && + NicInfo->VlanId == VlanId) { + + ThisNic = NicInfo; + break; + } + } + + if (ThisNic == NULL) { + return EFI_UNSUPPORTED; + } + + UnicodeSPrint ( + HandleName, + sizeof (HandleName), + L"iSCSI (%s, NicIndex=%d)", + Ipv6Flag ? L"IPv6" : L"IPv4", + ThisNic->NicIndex + ); + + if (gIScsiControllerNameTable != NULL) { + FreeUnicodeStringTable (gIScsiControllerNameTable); + gIScsiControllerNameTable = NULL; + } + + Status = AddUnicodeString2 ( + "eng", + gIScsiComponentName.SupportedLanguages, + &gIScsiControllerNameTable, + HandleName, + TRUE + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return AddUnicodeString2 ( + "en", + gIScsiComponentName2.SupportedLanguages, + &gIScsiControllerNameTable, + HandleName, + FALSE + ); +} + + /** Retrieves a Unicode string that is the user readable name of the controller that is being managed by a driver. @@ -177,5 +272,54 @@ IScsiComponentNameGetControllerName ( OUT CHAR16 **ControllerName ) { - return EFI_UNSUPPORTED; + EFI_HANDLE IScsiController; + BOOLEAN Ipv6Flag; + EFI_STATUS Status; + EFI_GUID *IScsiPrivateGuid; + ISCSI_PRIVATE_PROTOCOL *IScsiIdentifier; + + // + // Get the handle of the controller we are controling. + // + IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp4ProtocolGuid); + if (IScsiController != NULL) { + IScsiPrivateGuid = &gIScsiV4PrivateGuid; + Ipv6Flag = FALSE; + } else { + IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp6ProtocolGuid); + if (IScsiController != NULL) { + IScsiPrivateGuid = &gIScsiV6PrivateGuid; + Ipv6Flag = TRUE; + } else { + return EFI_UNSUPPORTED; + } + } + + // + // Retrieve an instance of a produced protocol from IScsiController + // + Status = gBS->OpenProtocol ( + IScsiController, + IScsiPrivateGuid, + (VOID **) &IScsiIdentifier, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = UpdateName(IScsiController, Ipv6Flag); + if (EFI_ERROR(Status)) { + return Status; + } + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + gIScsiControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gIScsiComponentName) + ); } diff --git a/NetworkPkg/IScsiDxe/IScsiDhcp6.c b/NetworkPkg/IScsiDxe/IScsiDhcp6.c index 2bf102ba8b..2627a59dd6 100644 --- a/NetworkPkg/IScsiDxe/IScsiDhcp6.c +++ b/NetworkPkg/IScsiDxe/IScsiDhcp6.c @@ -1,7 +1,7 @@ /** @file iSCSI DHCP6 related configuration routines. -Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -250,6 +250,7 @@ IScsiDhcp6ParseReply ( EFI_DHCP6_PACKET_OPTION *BootFileOpt; EFI_DHCP6_PACKET_OPTION **OptionList; ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData; + UINT16 ParaLen; OptionCount = 0; BootFileOpt = NULL; @@ -282,7 +283,7 @@ IScsiDhcp6ParseReply ( if (OptionList[Index]->OpCode == DHCP6_OPT_DNS_SERVERS) { if (((OptionList[Index]->OpLen & 0xf) != 0) || (OptionList[Index]->OpLen == 0)) { - Status = EFI_INVALID_PARAMETER; + Status = EFI_UNSUPPORTED; goto Exit; } // @@ -302,6 +303,24 @@ IScsiDhcp6ParseReply ( // The server sends this option to inform the client about an URL to a boot file. // BootFileOpt = OptionList[Index]; + } else if (OptionList[Index]->OpCode == DHCP6_OPT_BOOT_FILE_PARA) { + // + // The server sends this option to inform the client about DHCP6 server address. + // + if (OptionList[Index]->OpLen < 18) { + Status = EFI_UNSUPPORTED; + goto Exit; + } + // + // Check param-len 1, should be 16 bytes. + // + CopyMem (&ParaLen, &OptionList[Index]->Data[0], sizeof (UINT16)); + if (NTOHS (ParaLen) != 16) { + Status = EFI_UNSUPPORTED; + goto Exit; + } + + CopyMem (&ConfigData->DhcpServer, &OptionList[Index]->Data[2], sizeof (EFI_IPv6_ADDRESS)); } } @@ -405,7 +424,7 @@ IScsiDoDhcp6 ( goto ON_EXIT; } - Oro = AllocateZeroPool (sizeof (EFI_DHCP6_PACKET_OPTION) + 3); + Oro = AllocateZeroPool (sizeof (EFI_DHCP6_PACKET_OPTION) + 5); if (Oro == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; @@ -416,9 +435,10 @@ IScsiDoDhcp6 ( // All members in EFI_DHCP6_PACKET_OPTION are in network order. // Oro->OpCode = HTONS (DHCP6_OPT_REQUEST_OPTION); - Oro->OpLen = HTONS (2 * 2); + Oro->OpLen = HTONS (2 * 3); Oro->Data[1] = DHCP6_OPT_DNS_SERVERS; Oro->Data[3] = DHCP6_OPT_BOOT_FILE_URL; + Oro->Data[5] = DHCP6_OPT_BOOT_FILE_PARA; InfoReqReXmit.Irt = 4; InfoReqReXmit.Mrc = 1; diff --git a/NetworkPkg/IScsiDxe/IScsiDhcp6.h b/NetworkPkg/IScsiDxe/IScsiDhcp6.h index fe3dfb7e4d..4ca25bd494 100644 --- a/NetworkPkg/IScsiDxe/IScsiDhcp6.h +++ b/NetworkPkg/IScsiDxe/IScsiDhcp6.h @@ -1,7 +1,7 @@ /** @file The header file of iSCSI DHCP6 related configuration routines. -Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -22,6 +22,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. /// Assigned by IANA, RFC 5970 /// #define DHCP6_OPT_BOOT_FILE_URL 59 +#define DHCP6_OPT_BOOT_FILE_PARA 60 #define ISCSI_ROOT_PATH_ID "iscsi:" #define ISCSI_ROOT_PATH_FIELD_DELIMITER ':' diff --git a/NetworkPkg/IScsiDxe/IScsiDriver.c b/NetworkPkg/IScsiDxe/IScsiDriver.c index 7d8b18455c..2fd4c95a08 100644 --- a/NetworkPkg/IScsiDxe/IScsiDriver.c +++ b/NetworkPkg/IScsiDxe/IScsiDriver.c @@ -1,7 +1,7 @@ /** @file The entry point of IScsi driver. -Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -23,8 +23,8 @@ EFI_DRIVER_BINDING_PROTOCOL gIScsiDriverBinding = { NULL }; -EFI_GUID mIScsiV4PrivateGuid = ISCSI_V4_PRIVATE_GUID; -EFI_GUID mIScsiV6PrivateGuid = ISCSI_V6_PRIVATE_GUID; +EFI_GUID gIScsiV4PrivateGuid = ISCSI_V4_PRIVATE_GUID; +EFI_GUID gIScsiV6PrivateGuid = ISCSI_V6_PRIVATE_GUID; ISCSI_PRIVATE_DATA *mPrivate = NULL; /** @@ -121,7 +121,7 @@ IScsiDriverBindingSupported ( Status = gBS->OpenProtocol ( ControllerHandle, - &mIScsiV4PrivateGuid, + &gIScsiV4PrivateGuid, NULL, This->DriverBindingHandle, ControllerHandle, @@ -150,7 +150,7 @@ IScsiDriverBindingSupported ( Status = gBS->OpenProtocol ( ControllerHandle, - &mIScsiV6PrivateGuid, + &gIScsiV6PrivateGuid, NULL, This->DriverBindingHandle, ControllerHandle, @@ -231,11 +231,11 @@ IScsiStart ( // if (IpVersion == IP_VERSION_4) { - IScsiPrivateGuid = &mIScsiV4PrivateGuid; + IScsiPrivateGuid = &gIScsiV4PrivateGuid; TcpServiceBindingGuid = &gEfiTcp4ServiceBindingProtocolGuid; ProtocolGuid = &gEfiTcp4ProtocolGuid; } else if (IpVersion == IP_VERSION_6) { - IScsiPrivateGuid = &mIScsiV6PrivateGuid; + IScsiPrivateGuid = &gIScsiV6PrivateGuid; TcpServiceBindingGuid = &gEfiTcp6ServiceBindingProtocolGuid; ProtocolGuid = &gEfiTcp6ProtocolGuid; } else { @@ -931,13 +931,13 @@ IScsiDriverBindingStop ( // IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp4ProtocolGuid); if (IScsiController != NULL) { - ProtocolGuid = &mIScsiV4PrivateGuid; + ProtocolGuid = &gIScsiV4PrivateGuid; TcpProtocolGuid = &gEfiTcp4ProtocolGuid; TcpServiceBindingGuid = &gEfiTcp4ServiceBindingProtocolGuid; } else { IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp6ProtocolGuid); ASSERT (IScsiController != NULL); - ProtocolGuid = &mIScsiV6PrivateGuid; + ProtocolGuid = &gIScsiV6PrivateGuid; TcpProtocolGuid = &gEfiTcp6ProtocolGuid; TcpServiceBindingGuid = &gEfiTcp6ServiceBindingProtocolGuid; } @@ -1060,6 +1060,11 @@ IScsiUnload ( &gIScsiAuthenticationInfo, NULL ); + + if (gIScsiControllerNameTable!= NULL) { + FreeUnicodeStringTable (gIScsiControllerNameTable); + gIScsiControllerNameTable = NULL; + } return gBS->UninstallMultipleProtocolInterfaces ( ImageHandle, diff --git a/NetworkPkg/IScsiDxe/IScsiDriver.h b/NetworkPkg/IScsiDxe/IScsiDriver.h index 04866f0ed4..8c266fe763 100644 --- a/NetworkPkg/IScsiDxe/IScsiDriver.h +++ b/NetworkPkg/IScsiDxe/IScsiDriver.h @@ -1,7 +1,7 @@ /** @file The header file of IScsiDriver.c. -Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -33,9 +33,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. extern EFI_COMPONENT_NAME2_PROTOCOL gIScsiComponentName2; extern EFI_COMPONENT_NAME_PROTOCOL gIScsiComponentName; +extern EFI_UNICODE_STRING_TABLE *gIScsiControllerNameTable; extern EFI_ISCSI_INITIATOR_NAME_PROTOCOL gIScsiInitiatorName; extern EFI_AUTHENTICATION_INFO_PROTOCOL gIScsiAuthenticationInfo; extern EFI_EXT_SCSI_PASS_THRU_PROTOCOL gIScsiExtScsiPassThruProtocolTemplate; +extern EFI_GUID gIScsiV4PrivateGuid; +extern EFI_GUID gIScsiV6PrivateGuid; typedef struct { CHAR16 PortString[ISCSI_NAME_IFR_MAX_SIZE]; diff --git a/NetworkPkg/IScsiDxe/IScsiIbft.c b/NetworkPkg/IScsiDxe/IScsiIbft.c index 879d310cc9..9dba4e6f36 100644 --- a/NetworkPkg/IScsiDxe/IScsiIbft.c +++ b/NetworkPkg/IScsiDxe/IScsiIbft.c @@ -321,14 +321,10 @@ IScsiFillNICAndTargetSections ( Nic->SubnetMaskPrefixLength = NvData->PrefixLength; CopyMem (&Nic->Ip, &NvData->LocalIp, sizeof (EFI_IPv6_ADDRESS)); CopyMem (&Nic->Gateway, &NvData->Gateway, sizeof (EFI_IPv6_ADDRESS)); - CopyMem (&Nic->PrimaryDns, &Attempt->PrimaryDns, sizeof (EFI_IPv6_ADDRESS)); CopyMem (&Nic->SecondaryDns, &Attempt->SecondaryDns, sizeof (EFI_IPv6_ADDRESS)); - // - // TODO: DHCP server address cannot be retrieved by DHCPv6 process since - // DHCP server option is removed. - //CopyMem (&Nic->DhcpServer, &Attempt->DhcpServer, sizeof (EFI_IPv6_ADDRESS)); - // + CopyMem (&Nic->DhcpServer, &Attempt->DhcpServer, sizeof (EFI_IPv6_ADDRESS)); + } else { ASSERT (FALSE); } diff --git a/NetworkPkg/Ip6Dxe/ComponentName.c b/NetworkPkg/Ip6Dxe/ComponentName.c index bcdf4b1e42..dc164269a8 100644 --- a/NetworkPkg/Ip6Dxe/ComponentName.c +++ b/NetworkPkg/Ip6Dxe/ComponentName.c @@ -2,7 +2,7 @@ Implementation of EFI_COMPONENT_NAME_PROTOCOL and EFI_COMPONENT_NAME2_PROTOCOL protocol. - Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -174,6 +174,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIp6DriverNameTable[ } }; +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gIp6ControllerNameTable = NULL; + /** Retrieves a Unicode string that is the user-readable name of the driver. @@ -231,6 +233,88 @@ Ip6ComponentNameGetDriverName ( } +/** + Update the component name for the IP6 child handle. + + @param Ip6[in] A pointer to the EFI_IP6_PROTOCOL. + + + @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully. + @retval EFI_INVALID_PARAMETER The input parameter is invalid. + +**/ +EFI_STATUS +UpdateName ( + IN EFI_IP6_PROTOCOL *Ip6 + ) +{ + EFI_STATUS Status; + CHAR16 HandleName[128]; + EFI_IP6_MODE_DATA Ip6ModeData; + UINTN Offset; + CHAR16 Address[sizeof"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"]; + + if (Ip6 == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Format the child name into the string buffer. + // + Offset = 0; + Status = Ip6->GetModeData (Ip6, &Ip6ModeData, NULL, NULL); + if (!EFI_ERROR (Status) && Ip6ModeData.IsStarted) { + Status = NetLibIp6ToStr (&Ip6ModeData.ConfigData.StationAddress, Address, sizeof(Address)); + if (EFI_ERROR (Status)) { + return Status; + } + Offset += UnicodeSPrint ( + HandleName, + sizeof(HandleName), + L"IPv6(StationAddress=%s, ", + Address + ); + Status = NetLibIp6ToStr (&Ip6ModeData.ConfigData.DestinationAddress, Address, sizeof(Address)); + if (EFI_ERROR (Status)) { + return Status; + } + UnicodeSPrint ( + HandleName + Offset, + sizeof(HandleName) - Offset, + L"DestinationAddress=%s)", + Address + ); + } else if (!Ip6ModeData.IsStarted) { + UnicodeSPrint (HandleName, sizeof(HandleName), L"IPv6(Not started)"); + } else { + UnicodeSPrint (HandleName, sizeof(HandleName), L"IPv6(%r)", Status); + } + + if (gIp6ControllerNameTable != NULL) { + FreeUnicodeStringTable (gIp6ControllerNameTable); + gIp6ControllerNameTable = NULL; + } + + Status = AddUnicodeString2 ( + "eng", + gIp6ComponentName.SupportedLanguages, + &gIp6ControllerNameTable, + HandleName, + TRUE + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return AddUnicodeString2 ( + "en", + gIp6ComponentName2.SupportedLanguages, + &gIp6ControllerNameTable, + HandleName, + FALSE + ); +} + /** Retrieves a Unicode string that is the user-readable name of the controller that is being managed by a driver. @@ -309,5 +393,56 @@ Ip6ComponentNameGetControllerName ( OUT CHAR16 **ControllerName ) { - return EFI_UNSUPPORTED; + EFI_STATUS Status; + EFI_IP6_PROTOCOL *Ip6; + + // + // Only provide names for child handles. + // + if (ChildHandle == NULL) { + return EFI_UNSUPPORTED; + } + + // + // Make sure this driver produced ChildHandle + // + Status = EfiTestChildHandle ( + ControllerHandle, + ChildHandle, + &gEfiManagedNetworkProtocolGuid + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Retrieve an instance of a produced protocol from ChildHandle + // + Status = gBS->OpenProtocol ( + ChildHandle, + &gEfiIp6ProtocolGuid, + (VOID **)&Ip6, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Update the component name for this child handle. + // + Status = UpdateName (Ip6); + if (EFI_ERROR (Status)) { + return Status; + } + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + gIp6ControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gIp6ComponentName) + ); } diff --git a/NetworkPkg/Ip6Dxe/Ip6Common.c b/NetworkPkg/Ip6Dxe/Ip6Common.c index 2ae14a952c..459acd239f 100644 --- a/NetworkPkg/Ip6Dxe/Ip6Common.c +++ b/NetworkPkg/Ip6Dxe/Ip6Common.c @@ -1,7 +1,7 @@ /** @file The implementation of common functions shared by IP6 driver. - Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -328,6 +328,37 @@ Ip6AddAddr ( IpIf->AddressCount++; } +/** + Callback function which provided by user to remove one node in NetDestroyLinkList process. + + @param[in] Entry The entry to be removed. + @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList. + + @retval EFI_SUCCESS The entry has been removed successfully. + @retval Others Fail to remove the entry. + +**/ +EFI_STATUS +Ip6DestroyChildEntryByAddr ( + IN LIST_ENTRY *Entry, + IN VOID *Context +) +{ + IP6_PROTOCOL *Instance; + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + EFI_IPv6_ADDRESS *Address; + + Instance = NET_LIST_USER_STRUCT_S (Entry, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE); + ServiceBinding = ((IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT*) Context)->ServiceBinding; + Address = ((IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT*) Context)->Address; + + if ((Instance->State == IP6_STATE_CONFIGED) && EFI_IP6_EQUAL (&Instance->ConfigData.StationAddress, Address)) { + return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle); + } + + return EFI_SUCCESS; +} + /** Destroy the IP instance if its StationAddress is removed. It is the help function for Ip6RemoveAddr(). @@ -342,35 +373,20 @@ Ip6DestroyInstanceByAddress ( IN EFI_IPv6_ADDRESS *Address ) { - BOOLEAN OneDestroyed; - EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; - LIST_ENTRY *Entry; - IP6_PROTOCOL *Instance; + LIST_ENTRY *List; + IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT Context; NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - ServiceBinding = &IpSb->ServiceBinding; - - // - // Upper layer IP protocol consumers may have tight relationship between several - // IP protocol instances, in other words, calling ServiceBinding->DestroyChild to - // destroy one IP child may cause other related IP children destroyed too. This - // will probably leave hole in the children list when we iterate it. So everytime - // we just destroy one child then back to the start point to iterate the list. - // - do { - OneDestroyed = FALSE; - - NET_LIST_FOR_EACH (Entry, &IpSb->Children) { - Instance = NET_LIST_USER_STRUCT_S (Entry, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE); - - if ((Instance->State == IP6_STATE_CONFIGED) && EFI_IP6_EQUAL (&Instance->ConfigData.StationAddress, Address)) { - ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle); - OneDestroyed = TRUE; - break; - } - } - } while (OneDestroyed); + List = &IpSb->Children; + Context.ServiceBinding = &IpSb->ServiceBinding; + Context.Address = Address; + NetDestroyLinkList ( + List, + Ip6DestroyChildEntryByAddr, + &Context, + NULL + ); } /** diff --git a/NetworkPkg/Ip6Dxe/Ip6Common.h b/NetworkPkg/Ip6Dxe/Ip6Common.h index c3755f4859..9c2ddf4d4e 100644 --- a/NetworkPkg/Ip6Dxe/Ip6Common.h +++ b/NetworkPkg/Ip6Dxe/Ip6Common.h @@ -1,7 +1,7 @@ /** @file Common definition and functions for IP6 driver. - Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -60,6 +60,11 @@ typedef enum { Ip6AnyCast } IP6_ADDRESS_TYPE; +typedef struct { + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + EFI_IPv6_ADDRESS *Address; +} IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT; + typedef struct _IP6_INTERFACE IP6_INTERFACE; typedef struct _IP6_PROTOCOL IP6_PROTOCOL; typedef struct _IP6_SERVICE IP6_SERVICE; diff --git a/NetworkPkg/Ip6Dxe/Ip6Driver.c b/NetworkPkg/Ip6Dxe/Ip6Driver.c index 3fd1f73195..27550a5b3e 100644 --- a/NetworkPkg/Ip6Dxe/Ip6Driver.c +++ b/NetworkPkg/Ip6Dxe/Ip6Driver.c @@ -114,14 +114,16 @@ Ip6CleanService ( Ip6ConfigCleanInstance (&IpSb->Ip6ConfigInstance); - // - // Leave link-scope all-nodes multicast address (FF02::1) - // - Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &AllNodes); + if (!IpSb->LinkLocalDadFail) { + // + // Leave link-scope all-nodes multicast address (FF02::1) + // + Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &AllNodes); - Status = Ip6LeaveGroup (IpSb, &AllNodes); - if (EFI_ERROR (Status)) { - return Status; + Status = Ip6LeaveGroup (IpSb, &AllNodes); + if (EFI_ERROR (Status)) { + return Status; + } } if (IpSb->DefaultInterface != NULL) { @@ -244,7 +246,6 @@ Ip6CreateService ( IpSb->ServiceBinding.CreateChild = Ip6ServiceBindingCreateChild; IpSb->ServiceBinding.DestroyChild = Ip6ServiceBindingDestroyChild; IpSb->State = IP6_SERVICE_UNSTARTED; - IpSb->InDestroy = FALSE; IpSb->NumChildren = 0; InitializeListHead (&IpSb->Children); @@ -572,6 +573,43 @@ Ip6DriverBindingStart ( return Status; } +/** + Callback function which provided by user to remove one node in NetDestroyLinkList process. + + @param[in] Entry The entry to be removed. + @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList. + + @retval EFI_SUCCESS The entry has been removed successfully. + @retval Others Fail to remove the entry. + +**/ +EFI_STATUS +Ip6DestroyChildEntryInHandleBuffer ( + IN LIST_ENTRY *Entry, + IN VOID *Context +) +{ + IP6_PROTOCOL *IpInstance; + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + UINTN NumberOfChildren; + EFI_HANDLE *ChildHandleBuffer; + + if (Entry == NULL || Context == NULL) { + return EFI_INVALID_PARAMETER; + } + + IpInstance = NET_LIST_USER_STRUCT_S (Entry, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE); + ServiceBinding = ((IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding; + NumberOfChildren = ((IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren; + ChildHandleBuffer = ((IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer; + + if (!NetIsInHandleBuffer (IpInstance->Handle, NumberOfChildren, ChildHandleBuffer)) { + return EFI_SUCCESS; + } + + return ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle); +} + /** Stop this driver on ControllerHandle. @@ -595,30 +633,23 @@ Ip6DriverBindingStop ( IN EFI_HANDLE *ChildHandleBuffer OPTIONAL ) { - EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; - IP6_SERVICE *IpSb; - IP6_PROTOCOL *IpInstance; - EFI_HANDLE NicHandle; - EFI_STATUS Status; - BOOLEAN IsDhcp6; - EFI_TPL OldTpl; - INTN State; + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + IP6_SERVICE *IpSb; + EFI_HANDLE NicHandle; + EFI_STATUS Status; + LIST_ENTRY *List; + INTN State; + BOOLEAN IsDhcp6; + IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context; IsDhcp6 = FALSE; - NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp6ProtocolGuid); - - if (NicHandle != NULL) { - // - // DriverBindingStop is triggered by the uninstallation of the EFI DHCPv6 - // Protocol used by Ip6Config. - // - IsDhcp6 = TRUE; - } else { - - NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid); - - if (NicHandle == NULL) { - return EFI_DEVICE_ERROR; + NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid); + if (NicHandle == NULL) { + NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp6ProtocolGuid); + if (NicHandle != NULL) { + IsDhcp6 = TRUE; + } else { + return EFI_SUCCESS; } } @@ -636,21 +667,25 @@ Ip6DriverBindingStop ( IpSb = IP6_SERVICE_FROM_PROTOCOL (ServiceBinding); - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - if (IpSb->InDestroy) { - Status = EFI_SUCCESS; - goto Exit; - } - if (IsDhcp6) { - Status = Ip6ConfigDestroyDhcp6 (&IpSb->Ip6ConfigInstance); gBS->CloseEvent (IpSb->Ip6ConfigInstance.Dhcp6Event); IpSb->Ip6ConfigInstance.Dhcp6Event = NULL; - } else if (NumberOfChildren == 0) { - - IpSb->InDestroy = TRUE; + } else if (NumberOfChildren != 0) { + // + // NumberOfChildren is not zero, destroy the IP6 children instances in ChildHandleBuffer. + // + List = &IpSb->Children; + Context.ServiceBinding = ServiceBinding; + Context.NumberOfChildren = NumberOfChildren; + Context.ChildHandleBuffer = ChildHandleBuffer; + Status = NetDestroyLinkList ( + List, + Ip6DestroyChildEntryInHandleBuffer, + &Context, + NULL + ); + } else if (IsListEmpty (&IpSb->Children)) { State = IpSb->State; IpSb->State = IP6_SERVICE_DESTROY; @@ -675,24 +710,10 @@ Ip6DriverBindingStop ( ); ASSERT_EFI_ERROR (Status); FreePool (IpSb); - } else { - // - // NumberOfChildren is not zero, destroy all IP6 children instances. - // - while (!IsListEmpty (&IpSb->Children)) { - IpInstance = NET_LIST_HEAD (&IpSb->Children, IP6_PROTOCOL, Link); - ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle); - } - - if (IpSb->NumChildren != 0) { - Status = EFI_DEVICE_ERROR; - } + Status = EFI_SUCCESS; } - + Exit: - - gBS->RestoreTPL (OldTpl); - return Status; } @@ -830,7 +851,6 @@ Ip6ServiceBindingDestroyChild ( IP6_PROTOCOL *IpInstance; EFI_IP6_PROTOCOL *Ip6; EFI_TPL OldTpl; - INTN State; if ((This == NULL) || (ChildHandle == NULL)) { return EFI_INVALID_PARAMETER; @@ -868,13 +888,12 @@ Ip6ServiceBindingDestroyChild ( // when UDP driver is being stopped, it will destroy all // the IP child it opens. // - if (IpInstance->State == IP6_STATE_DESTROY) { + if (IpInstance->InDestroy) { gBS->RestoreTPL (OldTpl); return EFI_SUCCESS; } - State = IpInstance->State; - IpInstance->State = IP6_STATE_DESTROY; + IpInstance->InDestroy = TRUE; // // Close the Managed Network protocol. @@ -900,12 +919,13 @@ Ip6ServiceBindingDestroyChild ( // will be called back before preceeding. If any packets not recycled, // that means there is a resource leak. // + gBS->RestoreTPL (OldTpl); Status = gBS->UninstallProtocolInterface ( ChildHandle, &gEfiIp6ProtocolGuid, &IpInstance->Ip6Proto ); - + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); if (EFI_ERROR (Status)) { goto ON_ERROR; } @@ -935,7 +955,6 @@ Ip6ServiceBindingDestroyChild ( return EFI_SUCCESS; ON_ERROR: - IpInstance->State = State; gBS->RestoreTPL (OldTpl); return Status; diff --git a/NetworkPkg/Ip6Dxe/Ip6Driver.h b/NetworkPkg/Ip6Dxe/Ip6Driver.h index 4a23d836b8..d16ff48e2a 100644 --- a/NetworkPkg/Ip6Dxe/Ip6Driver.h +++ b/NetworkPkg/Ip6Dxe/Ip6Driver.h @@ -19,6 +19,13 @@ extern EFI_DRIVER_BINDING_PROTOCOL gIp6DriverBinding; extern EFI_COMPONENT_NAME_PROTOCOL gIp6ComponentName; extern EFI_COMPONENT_NAME2_PROTOCOL gIp6ComponentName2; +extern EFI_UNICODE_STRING_TABLE *gIp6ControllerNameTable; + +typedef struct { + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + UINTN NumberOfChildren; + EFI_HANDLE *ChildHandleBuffer; +}IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT; /** Clean up an IP6 service binding instance. It releases all diff --git a/NetworkPkg/Ip6Dxe/Ip6If.c b/NetworkPkg/Ip6Dxe/Ip6If.c index a934188479..280cd764f1 100644 --- a/NetworkPkg/Ip6Dxe/Ip6If.c +++ b/NetworkPkg/Ip6Dxe/Ip6If.c @@ -565,11 +565,7 @@ Ip6ReceiveFrame ( { EFI_STATUS Status; IP6_LINK_RX_TOKEN *Token; - - if (IpSb->InDestroy) { - return EFI_INVALID_PARAMETER; - } - + NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); Token = &IpSb->RecvRequest; diff --git a/NetworkPkg/Ip6Dxe/Ip6Impl.c b/NetworkPkg/Ip6Dxe/Ip6Impl.c index 44e0392511..365495a5e4 100644 --- a/NetworkPkg/Ip6Dxe/Ip6Impl.c +++ b/NetworkPkg/Ip6Dxe/Ip6Impl.c @@ -635,7 +635,7 @@ EfiIp6Configure ( IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This); IpSb = IpInstance->Service; - if (IpSb->LinkLocalDadFail) { + if (IpSb->LinkLocalDadFail && Ip6ConfigData != NULL) { return EFI_DEVICE_ERROR; } @@ -1777,10 +1777,6 @@ EfiIp6Cancel ( IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This); IpSb = IpInstance->Service; - if (IpSb->LinkLocalDadFail) { - return EFI_DEVICE_ERROR; - } - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); if (IpInstance->State != IP6_STATE_CONFIGED) { diff --git a/NetworkPkg/Ip6Dxe/Ip6Impl.h b/NetworkPkg/Ip6Dxe/Ip6Impl.h index 1241e63669..8f114bbb10 100644 --- a/NetworkPkg/Ip6Dxe/Ip6Impl.h +++ b/NetworkPkg/Ip6Dxe/Ip6Impl.h @@ -1,7 +1,7 @@ /** @file Implementation of EFI_IP6_PROTOCOL protocol interfaces and type definitions. - Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -68,7 +68,6 @@ // #define IP6_STATE_UNCONFIGED 0 #define IP6_STATE_CONFIGED 1 -#define IP6_STATE_DESTROY 2 // // The state of IP6 service. It starts from UNSTARTED. It transits @@ -157,13 +156,13 @@ struct _IP6_PROTOCOL { UINT32 GroupCount; EFI_IP6_CONFIG_DATA ConfigData; + BOOLEAN InDestroy; }; struct _IP6_SERVICE { UINT32 Signature; EFI_SERVICE_BINDING_PROTOCOL ServiceBinding; INTN State; - BOOLEAN InDestroy; // // List of all the IP instances and interfaces, and default diff --git a/NetworkPkg/Ip6Dxe/Ip6Nd.c b/NetworkPkg/Ip6Dxe/Ip6Nd.c index d510f330c1..9f30f9b20e 100644 --- a/NetworkPkg/Ip6Dxe/Ip6Nd.c +++ b/NetworkPkg/Ip6Dxe/Ip6Nd.c @@ -821,7 +821,8 @@ Ip6OnDADFinished ( UINT16 OptBuf[4]; EFI_DHCP6_PACKET_OPTION *Oro; EFI_DHCP6_RETRANSMISSION InfoReqReXmit; - + EFI_IPv6_ADDRESS AllNodes; + IpSb = IpIf->Service; AddrInfo = DadEntry->AddressInfo; @@ -922,6 +923,11 @@ Ip6OnDADFinished ( RemoveEntryList (&DadEntry->Link); FreePool (DadEntry); // + // Leave link-scope all-nodes multicast address (FF02::1) + // + Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &AllNodes); + Ip6LeaveGroup (IpSb, &AllNodes); + // // Disable IP operation since link-local address is a duplicate address. // IpSb->LinkLocalDadFail = TRUE; diff --git a/NetworkPkg/IpSecDxe/ComponentName.c b/NetworkPkg/IpSecDxe/ComponentName.c index e164d8bbb3..d68b175cc1 100644 --- a/NetworkPkg/IpSecDxe/ComponentName.c +++ b/NetworkPkg/IpSecDxe/ComponentName.c @@ -1,7 +1,7 @@ /** @file UEFI Component Name(2) protocol implementation for IPsec driver. - Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -172,6 +172,17 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIpSecDriverNameTable[] = } }; +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIpSecControllerNameTable[] = { + { + "eng;en", + L"IPsec Controller" + }, + { + NULL, + NULL + } +}; + /** Retrieves a Unicode string that is the user-readable name of the driver. @@ -306,5 +317,35 @@ IpSecComponentNameGetControllerName ( OUT CHAR16 **ControllerName ) { - return EFI_UNSUPPORTED; + EFI_STATUS Status; + + // + // ChildHandle must be NULL for a Device Driver + // + if (ChildHandle != NULL) { + return EFI_UNSUPPORTED; + } + + // + // Make sure this driver is currently managing ControllerHandle + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiIpSec2ProtocolGuid, + NULL, + NULL, + NULL, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mIpSecControllerNameTable, + ControllerName, + (BOOLEAN) (This == &gIpSecComponentName) + ); } diff --git a/NetworkPkg/Mtftp6Dxe/ComponentName.c b/NetworkPkg/Mtftp6Dxe/ComponentName.c index 72a5eb0582..f4327abcf9 100644 --- a/NetworkPkg/Mtftp6Dxe/ComponentName.c +++ b/NetworkPkg/Mtftp6Dxe/ComponentName.c @@ -1,7 +1,7 @@ /** @file UEFI Component Name(2) protocol implementation for Mtftp6 driver. - Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -170,6 +170,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mMtftp6DriverNameT } }; +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gMtftp6ControllerNameTable = NULL; + /** Retrieves a Unicode string that is the user-readable name of the driver. @@ -226,6 +228,74 @@ Mtftp6ComponentNameGetDriverName ( ); } +/** + Update the component name for the Mtftp6 child handle. + + @param Mtftp6[in] A pointer to the EFI_MTFTP6_PROTOCOL. + + + @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully. + @retval EFI_INVALID_PARAMETER The input parameter is invalid. + +**/ +EFI_STATUS +UpdateName ( + IN EFI_MTFTP6_PROTOCOL *Mtftp6 + ) +{ + EFI_STATUS Status; + CHAR16 HandleName[128]; + EFI_MTFTP6_MODE_DATA Mtftp6ModeData; + CHAR16 Address[sizeof"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"]; + + if (Mtftp6 == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Format the child name into the string buffer. + // + Status = Mtftp6->GetModeData (Mtftp6, &Mtftp6ModeData); + if (!EFI_ERROR (Status)) { + Status = NetLibIp6ToStr (&Mtftp6ModeData.ConfigData.ServerIp, Address, sizeof(Address)); + if (EFI_ERROR (Status)) { + return Status; + } + UnicodeSPrint (HandleName, sizeof (HandleName), + L"MTFTPv6(ServerIp=%s, InitialServerPort=%d)", + Address, + Mtftp6ModeData.ConfigData.InitialServerPort + ); + } else { + UnicodeSPrint (HandleName, 0x100, L"MTFTPv6(%r)", Status); + } + + if (gMtftp6ControllerNameTable != NULL) { + FreeUnicodeStringTable (gMtftp6ControllerNameTable); + gMtftp6ControllerNameTable = NULL; + } + + Status = AddUnicodeString2 ( + "eng", + gMtftp6ComponentName.SupportedLanguages, + &gMtftp6ControllerNameTable, + HandleName, + TRUE + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return AddUnicodeString2 ( + "en", + gMtftp6ComponentName2.SupportedLanguages, + &gMtftp6ControllerNameTable, + HandleName, + FALSE + ); +} + + /** Retrieves a Unicode string that is the user-readable name of the controller that is being managed by a driver. @@ -304,5 +374,57 @@ Mtftp6ComponentNameGetControllerName ( OUT CHAR16 **ControllerName ) { - return EFI_UNSUPPORTED; + EFI_STATUS Status; + EFI_MTFTP6_PROTOCOL *Mtftp6; + + // + // Only provide names for child handles. + // + if (ChildHandle == NULL) { + return EFI_UNSUPPORTED; + } + + // + // Make sure this driver produced ChildHandle + // + Status = EfiTestChildHandle ( + ControllerHandle, + ChildHandle, + &gEfiUdp6ProtocolGuid + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Retrieve an instance of a produced protocol from ChildHandle + // + Status = gBS->OpenProtocol ( + ChildHandle, + &gEfiMtftp6ProtocolGuid, + (VOID **)&Mtftp6, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Update the component name for this child handle. + // + Status = UpdateName (Mtftp6); + if (EFI_ERROR (Status)) { + return Status; + } + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + gMtftp6ControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gMtftp6ComponentName) + ); } + diff --git a/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.c b/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.c index 432eea9cd4..79cd6bae5a 100644 --- a/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.c +++ b/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.c @@ -98,7 +98,6 @@ Mtftp6CreateService ( Mtftp6Srv->Signature = MTFTP6_SERVICE_SIGNATURE; Mtftp6Srv->Controller = Controller; Mtftp6Srv->Image = Image; - Mtftp6Srv->InDestroy = FALSE; Mtftp6Srv->ChildrenNum = 0; CopyMem ( @@ -237,6 +236,44 @@ Mtftp6CreateInstance ( } +/** + Callback function which provided by user to remove one node in NetDestroyLinkList process. + + @param[in] Entry The entry to be removed. + @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList. + + @retval EFI_SUCCESS The entry has been removed successfully. + @retval Others Fail to remove the entry. + +**/ +EFI_STATUS +Mtftp6DestroyChildEntryInHandleBuffer ( + IN LIST_ENTRY *Entry, + IN VOID *Context +) +{ + MTFTP6_INSTANCE *Instance; + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + UINTN NumberOfChildren; + EFI_HANDLE *ChildHandleBuffer; + + if (Entry == NULL || Context == NULL) { + return EFI_INVALID_PARAMETER; + } + + Instance = NET_LIST_USER_STRUCT_S (Entry, MTFTP6_INSTANCE, Link, MTFTP6_INSTANCE_SIGNATURE); + ServiceBinding = ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding; + NumberOfChildren = ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren; + ChildHandleBuffer = ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer; + + if (!NetIsInHandleBuffer (Instance->Handle, NumberOfChildren, ChildHandleBuffer)) { + return EFI_SUCCESS; + } + + return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle); +} + + /** This is the declaration of an EFI image entry point. This entry point is the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including @@ -429,20 +466,20 @@ Mtftp6DriverBindingStop ( IN EFI_HANDLE *ChildHandleBuffer ) { - EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; - MTFTP6_SERVICE *Service; - MTFTP6_INSTANCE *Instance; - EFI_HANDLE NicHandle; - EFI_STATUS Status; - EFI_TPL OldTpl; - + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + MTFTP6_SERVICE *Service; + EFI_HANDLE NicHandle; + EFI_STATUS Status; + LIST_ENTRY *List; + MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context; + // // Locate the Nic handle to retrieve the Mtftp6 private data. // NicHandle = NetLibGetNicHandle (Controller, &gEfiUdp6ProtocolGuid); if (NicHandle == NULL) { - return EFI_DEVICE_ERROR; + return EFI_SUCCESS; } Status = gBS->OpenProtocol ( @@ -460,18 +497,26 @@ Mtftp6DriverBindingStop ( Service = MTFTP6_SERVICE_FROM_THIS (ServiceBinding); - if (Service->InDestroy) { - return EFI_SUCCESS; + if (!IsListEmpty (&Service->Children)) { + // + // Destroy the Mtftp6 child instance in ChildHandleBuffer. + // + List = &Service->Children; + Context.ServiceBinding = ServiceBinding; + Context.NumberOfChildren = NumberOfChildren; + Context.ChildHandleBuffer = ChildHandleBuffer; + Status = NetDestroyLinkList ( + List, + Mtftp6DestroyChildEntryInHandleBuffer, + &Context, + NULL + ); } - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - if (NumberOfChildren == 0) { + if (NumberOfChildren == 0 && IsListEmpty (&Service->Children)) { // // Destroy the Mtftp6 service if there is no Mtftp6 child instance left. // - Service->InDestroy = TRUE; - gBS->UninstallProtocolInterface ( NicHandle, &gEfiMtftp6ServiceBindingProtocolGuid, @@ -479,22 +524,9 @@ Mtftp6DriverBindingStop ( ); Mtftp6DestroyService (Service); - - } else { - // - // Destroy the Mtftp6 child instance one by one. - // - while (!IsListEmpty (&Service->Children)) { - Instance = NET_LIST_HEAD (&Service->Children, MTFTP6_INSTANCE, Link); - Mtftp6ServiceBindingDestroyChild (ServiceBinding, Instance->Handle); - } - - if (Service->ChildrenNum != 0) { - Status = EFI_DEVICE_ERROR; - } + Status = EFI_SUCCESS; } - gBS->RestoreTPL (OldTpl); return Status; } @@ -674,15 +706,34 @@ Mtftp6ServiceBindingDestroyChild ( ChildHandle ); + if (Instance->UdpIo != NULL) { + gBS->CloseProtocol ( + Instance->UdpIo->UdpHandle, + &gEfiUdp6ProtocolGuid, + gMtftp6DriverBinding.DriverBindingHandle, + Instance->Handle + ); + } + + if (Instance->McastUdpIo != NULL) { + gBS->CloseProtocol ( + Instance->McastUdpIo->UdpHandle, + &gEfiUdp6ProtocolGuid, + gMtftp6DriverBinding.DriverBindingHandle, + Instance->Handle + ); + } + // // Uninstall the MTFTP6 protocol first to enable a top down destruction. // + gBS->RestoreTPL (OldTpl); Status = gBS->UninstallProtocolInterface ( ChildHandle, &gEfiMtftp6ProtocolGuid, Mtftp6 ); - + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); if (EFI_ERROR (Status)) { Instance->InDestroy = FALSE; gBS->RestoreTPL (OldTpl); @@ -695,9 +746,9 @@ Mtftp6ServiceBindingDestroyChild ( RemoveEntryList (&Instance->Link); Service->ChildrenNum --; - Mtftp6DestroyInstance (Instance); - gBS->RestoreTPL (OldTpl); + Mtftp6DestroyInstance (Instance); + return EFI_SUCCESS; } diff --git a/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.h b/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.h index 3e3165b5e4..55ac1ddffb 100644 --- a/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.h +++ b/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.h @@ -2,7 +2,7 @@ Driver Binding functions and Service Binding functions declaration for Mtftp6 Driver. - Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -21,6 +21,7 @@ extern EFI_COMPONENT_NAME_PROTOCOL gMtftp6ComponentName; extern EFI_COMPONENT_NAME2_PROTOCOL gMtftp6ComponentName2; +extern EFI_UNICODE_STRING_TABLE *gMtftp6ControllerNameTable; /** Test to see if this driver supports Controller. This service diff --git a/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.c b/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.c index 4a4e5b192c..9b08455ef3 100644 --- a/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.c +++ b/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.c @@ -197,6 +197,19 @@ EfiMtftp6Configure ( UDP_IO_UDP6_VERSION, NULL ); + if (Instance->UdpIo != NULL) { + Status = gBS->OpenProtocol ( + Instance->UdpIo->UdpHandle, + &gEfiUdp6ProtocolGuid, + (VOID **) &Udp6, + Service->Image, + Instance->Handle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + } } if (Instance->UdpIo == NULL) { @@ -626,8 +639,6 @@ EfiMtftp6Poll ( // if (Instance->Config == NULL) { return EFI_NOT_STARTED; - } else if (Instance->InDestroy) { - return EFI_DEVICE_ERROR; } Udp6 = Instance->UdpIo->Protocol.Udp6; diff --git a/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.h b/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.h index 68fa0da115..6b1ce7f853 100644 --- a/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.h +++ b/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.h @@ -29,6 +29,7 @@ #include #include #include +#include typedef struct _MTFTP6_SERVICE MTFTP6_SERVICE; typedef struct _MTFTP6_INSTANCE MTFTP6_INSTANCE; @@ -117,9 +118,14 @@ struct _MTFTP6_SERVICE { // mtftp driver and udp driver. // UDP_IO *DummyUdpIo; - BOOLEAN InDestroy; }; +typedef struct { + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + UINTN NumberOfChildren; + EFI_HANDLE *ChildHandleBuffer; +} MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT; + /** Returns the current operating mode data for the MTFTP6 instance. diff --git a/NetworkPkg/Mtftp6Dxe/Mtftp6Rrq.c b/NetworkPkg/Mtftp6Dxe/Mtftp6Rrq.c index 7fc613a665..4a481f4b46 100644 --- a/NetworkPkg/Mtftp6Dxe/Mtftp6Rrq.c +++ b/NetworkPkg/Mtftp6Dxe/Mtftp6Rrq.c @@ -453,6 +453,7 @@ Mtftp6RrqHandleOack ( MTFTP6_EXT_OPTION_INFO ExtInfo; EFI_STATUS Status; INTN Expected; + EFI_UDP6_PROTOCOL *Udp6; *IsCompleted = FALSE; @@ -555,6 +556,21 @@ Mtftp6RrqHandleOack ( UDP_IO_UDP6_VERSION, Instance ); + if (Instance->McastUdpIo != NULL) { + Status = gBS->OpenProtocol ( + Instance->McastUdpIo->UdpHandle, + &gEfiUdp6ProtocolGuid, + (VOID **) &Udp6, + Instance->Service->Image, + Instance->Handle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + if (EFI_ERROR (Status)) { + UdpIoFreeIo (Instance->McastUdpIo); + Instance->McastUdpIo = NULL; + return EFI_DEVICE_ERROR; + } + } } if (Instance->McastUdpIo == NULL) { diff --git a/NetworkPkg/Mtftp6Dxe/Mtftp6Support.c b/NetworkPkg/Mtftp6Dxe/Mtftp6Support.c index 24ce0e85ba..f5b22313ee 100644 --- a/NetworkPkg/Mtftp6Dxe/Mtftp6Support.c +++ b/NetworkPkg/Mtftp6Dxe/Mtftp6Support.c @@ -1,7 +1,7 @@ /** @file Mtftp6 support functions implementation. - Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -903,6 +903,12 @@ Mtftp6OperationClean ( } if (Instance->McastUdpIo != NULL) { + gBS->CloseProtocol ( + Instance->McastUdpIo->UdpHandle, + &gEfiUdp6ProtocolGuid, + Instance->McastUdpIo->Image, + Instance->Handle + ); UdpIoFreeIo (Instance->McastUdpIo); Instance->McastUdpIo = NULL; } diff --git a/NetworkPkg/TcpDxe/ComponentName.c b/NetworkPkg/TcpDxe/ComponentName.c index f1e0e62f73..9b4dada6a0 100644 --- a/NetworkPkg/TcpDxe/ComponentName.c +++ b/NetworkPkg/TcpDxe/ComponentName.c @@ -2,7 +2,7 @@ Implementation of protocols EFI_COMPONENT_NAME_PROTOCOL and EFI_COMPONENT_NAME2_PROTOCOL. - Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -170,6 +170,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mTcpDriverNameTabl } }; +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gTcpControllerNameTable = NULL; + /** Retrieves a Unicode string that is the user-readable name of the driver. @@ -224,6 +226,142 @@ TcpComponentNameGetDriverName ( ); } +/** + Update the component name for the Tcp4 child handle. + + @param Tcp4[in] A pointer to the EFI_TCP4_PROTOCOL. + + + @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully. + @retval EFI_INVALID_PARAMETER The input parameter is invalid. + +**/ +EFI_STATUS +UpdateTcp4Name ( + IN EFI_TCP4_PROTOCOL *Tcp4 + ) +{ + EFI_STATUS Status; + CHAR16 HandleName[80]; + EFI_TCP4_CONFIG_DATA Tcp4ConfigData; + + if (Tcp4 == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Format the child name into the string buffer as: + // TCPv4 (SrcPort=59, DestPort=60, ActiveFlag=TRUE) + // + Status = Tcp4->GetModeData (Tcp4, NULL, &Tcp4ConfigData, NULL, NULL, NULL); + if (!EFI_ERROR (Status)) { + UnicodeSPrint (HandleName, sizeof (HandleName), + L"TCPv4 (SrcPort=%d, DestPort=&d, ActiveFlag=%s)", + Tcp4ConfigData.AccessPoint.StationPort, + Tcp4ConfigData.AccessPoint.RemotePort, + (Tcp4ConfigData.AccessPoint.ActiveFlag ? L"TRUE" : L"FALSE") + ); + } if (Status == EFI_NOT_STARTED) { + UnicodeSPrint ( + HandleName, + sizeof (HandleName), + L"TCPv4 (Not started)" + ); + } else { + return Status; + } + + if (gTcpControllerNameTable != NULL) { + FreeUnicodeStringTable (gTcpControllerNameTable); + gTcpControllerNameTable = NULL; + } + + Status = AddUnicodeString2 ( + "eng", + gTcpComponentName.SupportedLanguages, + &gTcpControllerNameTable, + HandleName, + TRUE + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return AddUnicodeString2 ( + "en", + gTcpComponentName2.SupportedLanguages, + &gTcpControllerNameTable, + HandleName, + FALSE + ); +} + +/** + Update the component name for the Tcp6 child handle. + + @param Tcp6[in] A pointer to the EFI_TCP6_PROTOCOL. + + + @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully. + @retval EFI_INVALID_PARAMETER The input parameter is invalid. + +**/ +EFI_STATUS +UpdateTcp6Name ( + IN EFI_TCP6_PROTOCOL *Tcp6 + ) +{ + EFI_STATUS Status; + CHAR16 HandleName[80]; + EFI_TCP6_CONFIG_DATA Tcp6ConfigData; + + if (Tcp6 == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Format the child name into the string buffer. + // + Status = Tcp6->GetModeData (Tcp6, NULL, &Tcp6ConfigData, NULL, NULL, NULL); + if (!EFI_ERROR (Status)) { + UnicodeSPrint (HandleName, sizeof (HandleName), + L"TCPv6(SrcPort=%d, DestPort=%d, ActiveFlag=%d)", + Tcp6ConfigData.AccessPoint.StationPort, + Tcp6ConfigData.AccessPoint.RemotePort, + Tcp6ConfigData.AccessPoint.ActiveFlag + ); + } else if (Status == EFI_NOT_STARTED) { + UnicodeSPrint (HandleName, sizeof (HandleName), L"TCPv6(Not started)"); + } else { + return Status; + } + + + if (gTcpControllerNameTable != NULL) { + FreeUnicodeStringTable (gTcpControllerNameTable); + gTcpControllerNameTable = NULL; + } + + Status = AddUnicodeString2 ( + "eng", + gTcpComponentName.SupportedLanguages, + &gTcpControllerNameTable, + HandleName, + TRUE + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return AddUnicodeString2 ( + "en", + gTcpComponentName2.SupportedLanguages, + &gTcpControllerNameTable, + HandleName, + FALSE + ); +} + /** Retrieves a Unicode string that is the user-readable name of the controller that is being managed by a driver. @@ -300,5 +438,89 @@ TcpComponentNameGetControllerName ( OUT CHAR16 **ControllerName ) { - return EFI_UNSUPPORTED; + EFI_STATUS Status; + EFI_TCP4_PROTOCOL *Tcp4; + EFI_TCP6_PROTOCOL *Tcp6; + + // + // Only provide names for child handles. + // + if (ChildHandle == NULL) { + return EFI_UNSUPPORTED; + } + + // + // Make sure this driver produced ChildHandle + // + Status = EfiTestChildHandle ( + ControllerHandle, + ChildHandle, + &gEfiIp6ProtocolGuid + ); + if (!EFI_ERROR (Status)) { + // + // Retrieve an instance of a produced protocol from ChildHandle + // + Status = gBS->OpenProtocol ( + ChildHandle, + &gEfiTcp6ProtocolGuid, + (VOID **)&Tcp6, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Update the component name for this child handle. + // + Status = UpdateTcp6Name (Tcp6); + if (EFI_ERROR (Status)) { + return Status; + } + } + + // + // Make sure this driver is currently managing ControllHandle + // + Status = EfiTestChildHandle ( + ControllerHandle, + ChildHandle, + &gEfiIp4ProtocolGuid + ); + if (!EFI_ERROR (Status)) { + // + // Retrieve an instance of a produced protocol from ChildHandle + // + Status = gBS->OpenProtocol ( + ChildHandle, + &gEfiTcp4ProtocolGuid, + (VOID **)&Tcp4, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Update the component name for this child handle. + // + Status = UpdateTcp4Name (Tcp4); + if (EFI_ERROR (Status)) { + return Status; + } + } + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + gTcpControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gTcpComponentName) + ); } + diff --git a/NetworkPkg/TcpDxe/SockInterface.c b/NetworkPkg/TcpDxe/SockInterface.c index 075e9ada6a..4abda74220 100644 --- a/NetworkPkg/TcpDxe/SockInterface.c +++ b/NetworkPkg/TcpDxe/SockInterface.c @@ -146,11 +146,11 @@ SockDestroyChild ( ASSERT ((Sock != NULL) && (Sock->ProtoHandler != NULL)); - if (Sock->IsDestroyed) { + if (Sock->InDestroy) { return EFI_SUCCESS; } - Sock->IsDestroyed = TRUE; + Sock->InDestroy = TRUE; Status = EfiAcquireLockOrFail (&(Sock->Lock)); if (EFI_ERROR (Status)) { @@ -177,7 +177,7 @@ SockDestroyChild ( Status) ); - Sock->IsDestroyed = FALSE; + Sock->InDestroy = FALSE; } else if (SOCK_IS_CONFIGURED (Sock)) { SockConnFlush (Sock); diff --git a/NetworkPkg/TcpDxe/Socket.h b/NetworkPkg/TcpDxe/Socket.h index 9e2d907150..5a63047f90 100644 --- a/NetworkPkg/TcpDxe/Socket.h +++ b/NetworkPkg/TcpDxe/Socket.h @@ -477,7 +477,7 @@ struct _TCP_SOCKET { SOCK_BUFFER SndBuffer; ///< Send buffer of application's data SOCK_BUFFER RcvBuffer; ///< Receive buffer of received data EFI_STATUS SockError; ///< The error returned by low layer protocol - BOOLEAN IsDestroyed; + BOOLEAN InDestroy; // // Fields used to manage the connection request diff --git a/NetworkPkg/TcpDxe/TcpDispatcher.c b/NetworkPkg/TcpDxe/TcpDispatcher.c index 3e6d34c63f..d3d2cb1c3a 100644 --- a/NetworkPkg/TcpDxe/TcpDispatcher.c +++ b/NetworkPkg/TcpDxe/TcpDispatcher.c @@ -354,7 +354,16 @@ TcpAttachPcb ( TCP_CB *Tcb; TCP_PROTO_DATA *ProtoData; IP_IO *IpIo; + EFI_STATUS Status; + VOID *Ip; + EFI_GUID *IpProtocolGuid; + if (Sk->IpVersion == IP_VERSION_4) { + IpProtocolGuid = &gEfiIp4ProtocolGuid; + } else { + IpProtocolGuid = &gEfiIp6ProtocolGuid; + } + Tcb = AllocateZeroPool (sizeof (TCP_CB)); if (Tcb == NULL) { @@ -377,6 +386,22 @@ TcpAttachPcb ( return EFI_OUT_OF_RESOURCES; } + // + // Open the new created IP instance BY_CHILD. + // + Status = gBS->OpenProtocol ( + Tcb->IpInfo->ChildHandle, + IpProtocolGuid, + &Ip, + IpIo->Image, + Sk->SockHandle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + if (EFI_ERROR (Status)) { + IpIoRemoveIp (IpIo, Tcb->IpInfo); + return Status; + } + InitializeListHead (&Tcb->List); InitializeListHead (&Tcb->SndQue); InitializeListHead (&Tcb->RcvQue); @@ -401,7 +426,14 @@ TcpDetachPcb ( { TCP_PROTO_DATA *ProtoData; TCP_CB *Tcb; + EFI_GUID *IpProtocolGuid; + if (Sk->IpVersion == IP_VERSION_4) { + IpProtocolGuid = &gEfiIp4ProtocolGuid; + } else { + IpProtocolGuid = &gEfiIp6ProtocolGuid; + } + ProtoData = (TCP_PROTO_DATA *) Sk->ProtoReserved; Tcb = ProtoData->TcpPcb; @@ -409,6 +441,16 @@ TcpDetachPcb ( TcpFlushPcb (Tcb); + // + // Close the IP protocol. + // + gBS->CloseProtocol ( + Tcb->IpInfo->ChildHandle, + IpProtocolGuid, + ProtoData->TcpService->IpIo->Image, + Sk->SockHandle + ); + IpIoRemoveIp (ProtoData->TcpService->IpIo, Tcb->IpInfo); FreePool (Tcb); diff --git a/NetworkPkg/TcpDxe/TcpDriver.c b/NetworkPkg/TcpDxe/TcpDriver.c index c9ac10c758..4e697b1f4e 100644 --- a/NetworkPkg/TcpDxe/TcpDriver.c +++ b/NetworkPkg/TcpDxe/TcpDriver.c @@ -1,7 +1,7 @@ /** @file The driver binding and service binding protocol for the TCP driver. - Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -323,6 +323,7 @@ ON_ERROR: if (TcpServiceData->IpIo != NULL) { IpIoDestroy (TcpServiceData->IpIo); + TcpServiceData->IpIo = NULL; } FreePool (TcpServiceData); @@ -330,14 +331,53 @@ ON_ERROR: return Status; } +/** + Callback function which provided by user to remove one node in NetDestroyLinkList process. + + @param[in] Entry The entry to be removed. + @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList. + + @retval EFI_SUCCESS The entry has been removed successfully. + @retval Others Fail to remove the entry. + +**/ +EFI_STATUS +TcpDestroyChildEntryInHandleBuffer ( + IN LIST_ENTRY *Entry, + IN VOID *Context +) +{ + SOCKET *Sock; + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + UINTN NumberOfChildren; + EFI_HANDLE *ChildHandleBuffer; + + if (Entry == NULL || Context == NULL) { + return EFI_INVALID_PARAMETER; + } + + Sock = NET_LIST_USER_STRUCT_S (Entry, SOCKET, Link, SOCK_SIGNATURE); + ServiceBinding = ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding; + NumberOfChildren = ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren; + ChildHandleBuffer = ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer; + + if (!NetIsInHandleBuffer (Sock->SockHandle, NumberOfChildren, ChildHandleBuffer)) { + return EFI_SUCCESS; + } + + return ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle); +} + /** Destroy a TCP6 or TCP4 service binding instance. It will release all the resources allocated by the instance. @param[in] Controller Controller handle of device to bind driver to. @param[in] ImageHandle The TCP driver's image handle. - @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number + @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of children is zero stop the entire bus driver. + @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL + if NumberOfChildren is 0. @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6 @retval EFI_SUCCESS The resources used by the instance were cleaned up. @@ -349,6 +389,7 @@ TcpDestroyService ( IN EFI_HANDLE Controller, IN EFI_HANDLE ImageHandle, IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer, OPTIONAL IN UINT8 IpVersion ) { @@ -358,7 +399,8 @@ TcpDestroyService ( EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; TCP_SERVICE_DATA *TcpServiceData; EFI_STATUS Status; - SOCKET *Sock; + LIST_ENTRY *List; + TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context; ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6)); @@ -372,7 +414,7 @@ TcpDestroyService ( NicHandle = NetLibGetNicHandle (Controller, IpProtocolGuid); if (NicHandle == NULL) { - return EFI_NOT_FOUND; + return EFI_SUCCESS; } Status = gBS->OpenProtocol ( @@ -389,7 +431,18 @@ TcpDestroyService ( TcpServiceData = TCP_SERVICE_FROM_THIS (ServiceBinding); - if (NumberOfChildren == 0) { + if (NumberOfChildren != 0) { + List = &TcpServiceData->SocketList; + Context.ServiceBinding = ServiceBinding; + Context.NumberOfChildren = NumberOfChildren; + Context.ChildHandleBuffer = ChildHandleBuffer; + Status = NetDestroyLinkList ( + List, + TcpDestroyChildEntryInHandleBuffer, + &Context, + NULL + ); + } else if (IsListEmpty (&TcpServiceData->SocketList)) { // // Uninstall TCP servicebinding protocol // @@ -404,6 +457,7 @@ TcpDestroyService ( // Destroy the IpIO consumed by TCP driver // IpIoDestroy (TcpServiceData->IpIo); + TcpServiceData->IpIo = NULL; // // Destroy the heartbeat timer. @@ -419,16 +473,11 @@ TcpDestroyService ( // Release the TCP service data // FreePool (TcpServiceData); - } else { - - while (!IsListEmpty (&TcpServiceData->SocketList)) { - Sock = NET_LIST_HEAD (&TcpServiceData->SocketList, SOCKET, Link); - ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle); - } + Status = EFI_SUCCESS; } - return EFI_SUCCESS; + return Status; } /** @@ -595,6 +644,7 @@ TcpDriverBindingStop ( ControllerHandle, This->DriverBindingHandle, NumberOfChildren, + ChildHandleBuffer, IP_VERSION_4 ); @@ -602,6 +652,7 @@ TcpDriverBindingStop ( ControllerHandle, This->DriverBindingHandle, NumberOfChildren, + ChildHandleBuffer, IP_VERSION_6 ); @@ -839,14 +890,11 @@ TcpServiceBindingDestroyChild ( EFI_STATUS Status; VOID *Tcp; SOCKET *Sock; - EFI_TPL OldTpl; if (NULL == This || NULL == ChildHandle) { return EFI_INVALID_PARAMETER; } - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - // // retrieve the Tcp4 protocol from ChildHandle // @@ -885,7 +933,5 @@ TcpServiceBindingDestroyChild ( SockDestroyChild (Sock); } - gBS->RestoreTPL (OldTpl); - return Status; } diff --git a/NetworkPkg/TcpDxe/TcpMain.h b/NetworkPkg/TcpDxe/TcpMain.h index 69c764cde1..bd4434e26b 100644 --- a/NetworkPkg/TcpDxe/TcpMain.h +++ b/NetworkPkg/TcpDxe/TcpMain.h @@ -2,7 +2,7 @@ Declaration of protocol interfaces in EFI_TCP4_PROTOCOL and EFI_TCP6_PROTOCOL. It is the common head file for all Tcp*.c in TCP driver. - Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -21,6 +21,7 @@ #include #include #include +#include #include "Socket.h" #include "TcpProto.h" @@ -32,6 +33,7 @@ extern UINT16 mTcp6RandomPort; extern CHAR16 *mTcpStateName[]; extern EFI_COMPONENT_NAME_PROTOCOL gTcpComponentName; extern EFI_COMPONENT_NAME2_PROTOCOL gTcpComponentName2; +extern EFI_UNICODE_STRING_TABLE *gTcpControllerNameTable; extern LIST_ENTRY mTcpRunQue; extern LIST_ENTRY mTcpListenQue; @@ -90,6 +92,12 @@ typedef struct _TCP4_ROUTE_INFO { EFI_IPv4_ADDRESS *GatewayAddress; } TCP4_ROUTE_INFO; +typedef struct { + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + UINTN NumberOfChildren; + EFI_HANDLE *ChildHandleBuffer; +} TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT; + // // EFI_TCP4_PROTOCOL definitions. // diff --git a/NetworkPkg/Udp6Dxe/ComponentName.c b/NetworkPkg/Udp6Dxe/ComponentName.c index 2511465187..93c2003f34 100644 --- a/NetworkPkg/Udp6Dxe/ComponentName.c +++ b/NetworkPkg/Udp6Dxe/ComponentName.c @@ -1,7 +1,7 @@ /** @file UEFI Component Name(2) protocol implementation for UDP6 driver. - Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -174,6 +174,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUdp6DriverNameTable[] = } }; +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gUdp6ControllerNameTable = NULL; + /** Retrieves a Unicode string that is the user-readable name of the driver. @@ -230,6 +232,70 @@ Udp6ComponentNameGetDriverName ( ); } +/** + Update the component name for the Udp6 child handle. + + @param Udp6[in] A pointer to the EFI_UDP6_PROTOCOL. + + + @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully. + @retval EFI_INVALID_PARAMETER The input parameter is invalid. + +**/ +EFI_STATUS +UpdateName ( + IN EFI_UDP6_PROTOCOL *Udp6 + ) +{ + EFI_STATUS Status; + CHAR16 HandleName[64]; + EFI_UDP6_CONFIG_DATA Udp6ConfigData; + + if (Udp6 == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Format the child name into the string buffer. + // + Status = Udp6->GetModeData (Udp6, &Udp6ConfigData, NULL, NULL, NULL); + if (!EFI_ERROR (Status)) { + UnicodeSPrint (HandleName, sizeof (HandleName), + L"UDPv6 (SrcPort=%d, DestPort=%d)", + Udp6ConfigData.StationPort, + Udp6ConfigData.RemotePort + ); + } else if (Status == EFI_NOT_STARTED) { + UnicodeSPrint (HandleName, sizeof (HandleName), L"UDPv6 (Not started)"); + } else { + UnicodeSPrint (HandleName, sizeof (HandleName), L"UDPv6 (%r)", Status); + } + + if (gUdp6ControllerNameTable != NULL) { + FreeUnicodeStringTable (gUdp6ControllerNameTable); + gUdp6ControllerNameTable = NULL; + } + + Status = AddUnicodeString2 ( + "eng", + gUdp6ComponentName.SupportedLanguages, + &gUdp6ControllerNameTable, + HandleName, + TRUE + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return AddUnicodeString2 ( + "en", + gUdp6ComponentName2.SupportedLanguages, + &gUdp6ControllerNameTable, + HandleName, + FALSE + ); +} + /** Retrieves a Unicode string that is the user-readable name of the controller that is being managed by a driver. @@ -308,6 +374,56 @@ Udp6ComponentNameGetControllerName ( OUT CHAR16 **ControllerName ) { - return EFI_UNSUPPORTED; -} + EFI_STATUS Status; + EFI_UDP6_PROTOCOL *Udp6; + + // + // Only provide names for child handles. + // + if (ChildHandle == NULL) { + return EFI_UNSUPPORTED; + } + + // + // Make sure this driver produced ChildHandle + // + Status = EfiTestChildHandle ( + ControllerHandle, + ChildHandle, + &gEfiIp6ProtocolGuid + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Retrieve an instance of a produced protocol from ChildHandle + // + Status = gBS->OpenProtocol ( + ChildHandle, + &gEfiUdp6ProtocolGuid, + (VOID **)&Udp6, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Update the component name for this child handle. + // + Status = UpdateName (Udp6); + if (EFI_ERROR (Status)) { + return Status; + } + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + gUdp6ControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gUdp6ComponentName) + ); +} diff --git a/NetworkPkg/Udp6Dxe/Udp6Driver.c b/NetworkPkg/Udp6Dxe/Udp6Driver.c index 1726ebbde4..62c2b9affd 100644 --- a/NetworkPkg/Udp6Dxe/Udp6Driver.c +++ b/NetworkPkg/Udp6Dxe/Udp6Driver.c @@ -1,7 +1,7 @@ /** @file Driver Binding functions and Service Binding functions for the Network driver module. - Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -178,6 +178,43 @@ EXIT: return Status; } +/** + Callback function which provided by user to remove one node in NetDestroyLinkList process. + + @param[in] Entry The entry to be removed. + @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList. + + @retval EFI_SUCCESS The entry has been removed successfully. + @retval Others Fail to remove the entry. + +**/ +EFI_STATUS +Udp6DestroyChildEntryInHandleBuffer ( + IN LIST_ENTRY *Entry, + IN VOID *Context +) +{ + UDP6_INSTANCE_DATA *Instance; + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + UINTN NumberOfChildren; + EFI_HANDLE *ChildHandleBuffer; + + if (Entry == NULL || Context == NULL) { + return EFI_INVALID_PARAMETER; + } + + Instance = NET_LIST_USER_STRUCT_S (Entry, UDP6_INSTANCE_DATA, Link, UDP6_INSTANCE_DATA_SIGNATURE); + ServiceBinding = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding; + NumberOfChildren = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren; + ChildHandleBuffer = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer; + + if (!NetIsInHandleBuffer (Instance->ChildHandle, NumberOfChildren, ChildHandleBuffer)) { + return EFI_SUCCESS; + } + + return ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle); +} + /** Stop this driver on ControllerHandle. @@ -211,14 +248,15 @@ Udp6DriverBindingStop ( EFI_HANDLE NicHandle; EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; UDP6_SERVICE_DATA *Udp6Service; - UDP6_INSTANCE_DATA *Instance; + LIST_ENTRY *List; + UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context; // // Find the NicHandle where UDP6 ServiceBinding Protocol is installed. // NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp6ProtocolGuid); if (NicHandle == NULL) { - return EFI_DEVICE_ERROR; + return EFI_SUCCESS; } // @@ -238,8 +276,21 @@ Udp6DriverBindingStop ( Udp6Service = UDP6_SERVICE_DATA_FROM_THIS (ServiceBinding); - if (NumberOfChildren == 0) { - + if (NumberOfChildren != 0) { + // + // NumberOfChildren is not zero, destroy the children instances in ChildHandleBuffer. + // + List = &Udp6Service->ChildrenList; + Context.ServiceBinding = ServiceBinding; + Context.NumberOfChildren = NumberOfChildren; + Context.ChildHandleBuffer = ChildHandleBuffer; + Status = NetDestroyLinkList ( + List, + Udp6DestroyChildEntryInHandleBuffer, + &Context, + NULL + ); + } else if (IsListEmpty (&Udp6Service->ChildrenList)) { gBS->UninstallMultipleProtocolInterfaces ( NicHandle, &gEfiUdp6ServiceBindingProtocolGuid, @@ -252,13 +303,8 @@ Udp6DriverBindingStop ( Udp6CleanService (Udp6Service); FreePool (Udp6Service); - } else { - - while (!IsListEmpty (&Udp6Service->ChildrenList)) { - Instance = NET_LIST_HEAD (&Udp6Service->ChildrenList, UDP6_INSTANCE_DATA, Link); - Status = ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle); - } + Status = EFI_SUCCESS; } return Status; @@ -351,6 +397,21 @@ Udp6ServiceBindingCreateChild ( goto ON_ERROR; } + // + // Open this instance's Ip6 protocol in the IpInfo BY_CHILD. + // + Status = gBS->OpenProtocol ( + Instance->IpInfo->ChildHandle, + &gEfiIp6ProtocolGuid, + (VOID **) &Ip6, + gUdp6DriverBinding.DriverBindingHandle, + Instance->ChildHandle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); // @@ -440,17 +501,17 @@ Udp6ServiceBindingDestroyChild ( Instance = UDP6_INSTANCE_DATA_FROM_THIS (Udp6Proto); - if (Instance->Destroyed) { + if (Instance->InDestroy) { return EFI_SUCCESS; } // // Use the Destroyed flag to avoid the re-entering of the following code. // - Instance->Destroyed = TRUE; + Instance->InDestroy = TRUE; // - // Close the Ip6 protocol. + // Close the Ip6 protocol on the default IpIo. // gBS->CloseProtocol ( Udp6Service->IpIo->ChildHandle, @@ -458,6 +519,15 @@ Udp6ServiceBindingDestroyChild ( gUdp6DriverBinding.DriverBindingHandle, Instance->ChildHandle ); + // + // Close the Ip6 protocol on this instance's IpInfo. + // + gBS->CloseProtocol ( + Instance->IpInfo->ChildHandle, + &gEfiIp6ProtocolGuid, + gUdp6DriverBinding.DriverBindingHandle, + Instance->ChildHandle + ); // // Uninstall the Udp6Protocol previously installed on the ChildHandle. @@ -469,7 +539,7 @@ Udp6ServiceBindingDestroyChild ( NULL ); if (EFI_ERROR (Status)) { - Instance->Destroyed = FALSE; + Instance->InDestroy = FALSE; return Status; } diff --git a/NetworkPkg/Udp6Dxe/Udp6Impl.c b/NetworkPkg/Udp6Dxe/Udp6Impl.c index 8e259319b9..3830b14415 100644 --- a/NetworkPkg/Udp6Dxe/Udp6Impl.c +++ b/NetworkPkg/Udp6Dxe/Udp6Impl.c @@ -1,7 +1,7 @@ /** @file Udp6 driver's whole implementation. - Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -363,7 +363,8 @@ ON_ERROR: } IpIoDestroy (Udp6Service->IpIo); - + Udp6Service->IpIo = NULL; + return Status; } @@ -388,6 +389,9 @@ Udp6CleanService ( // Destroy the IpIo. // IpIoDestroy (Udp6Service->IpIo); + Udp6Service->IpIo = NULL; + + ZeroMem (Udp6Service, sizeof (UDP6_SERVICE_DATA)); } @@ -491,7 +495,7 @@ Udp6InitInstance ( Instance->IcmpError = EFI_SUCCESS; Instance->Configured = FALSE; Instance->IsNoMapping = FALSE; - Instance->Destroyed = FALSE; + Instance->InDestroy = FALSE; } diff --git a/NetworkPkg/Udp6Dxe/Udp6Impl.h b/NetworkPkg/Udp6Dxe/Udp6Impl.h index 108e30b71c..9ca4f4a011 100644 --- a/NetworkPkg/Udp6Dxe/Udp6Impl.h +++ b/NetworkPkg/Udp6Dxe/Udp6Impl.h @@ -1,7 +1,7 @@ /** @file Udp6 driver's whole implementation and internal data structures. - Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -30,11 +30,13 @@ #include #include #include +#include #include "Udp6Driver.h" extern EFI_COMPONENT_NAME2_PROTOCOL gUdp6ComponentName2; extern EFI_COMPONENT_NAME_PROTOCOL gUdp6ComponentName; +extern EFI_UNICODE_STRING_TABLE *gUdp6ControllerNameTable; extern EFI_SERVICE_BINDING_PROTOCOL mUdp6ServiceBinding; extern EFI_UDP6_PROTOCOL mUdp6Protocol; extern UINT16 mUdp6RandomPort; @@ -97,7 +99,7 @@ typedef struct _UDP6_INSTANCE_DATA { UINT16 HeadSum; EFI_STATUS IcmpError; IP_IO_IP_INFO *IpInfo; - BOOLEAN Destroyed; + BOOLEAN InDestroy; } UDP6_INSTANCE_DATA; typedef struct _UDP6_RXDATA_WRAP { @@ -107,6 +109,12 @@ typedef struct _UDP6_RXDATA_WRAP { EFI_UDP6_RECEIVE_DATA RxData; } UDP6_RXDATA_WRAP; +typedef struct { + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + UINTN NumberOfChildren; + EFI_HANDLE *ChildHandleBuffer; +} UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT; + /** Clean the Udp service context data. diff --git a/NetworkPkg/UefiPxeBcDxe/ComponentName.c b/NetworkPkg/UefiPxeBcDxe/ComponentName.c index 05e338a7f9..6e48d4aa18 100644 --- a/NetworkPkg/UefiPxeBcDxe/ComponentName.c +++ b/NetworkPkg/UefiPxeBcDxe/ComponentName.c @@ -1,7 +1,7 @@ /** @file UEFI Component Name(2) protocol implementation for UefiPxeBc driver. - Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -171,6 +171,16 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mPxeBcDriverNameTab } }; +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mPxeBcControllerNameTable[] = { + { + "eng;en", + L"PXE Controller" + }, + { + NULL, + NULL + } +}; /** Retrieves a Unicode string that is the user-readable name of the driver. @@ -307,6 +317,42 @@ PxeBcComponentNameGetControllerName ( OUT CHAR16 **ControllerName ) { - return EFI_UNSUPPORTED; -} + EFI_STATUS Status; + EFI_HANDLE NicHandle; + PXEBC_PRIVATE_PROTOCOL *Id; + if (ControllerHandle == NULL || ChildHandle != NULL) { + return EFI_UNSUPPORTED; + } + + NicHandle = PxeBcGetNicByIp4Children (ControllerHandle); + if (NicHandle == NULL) { + NicHandle = PxeBcGetNicByIp6Children (ControllerHandle); + if (NicHandle == NULL) { + return EFI_UNSUPPORTED; + } + } + + // + // Try to retrieve the private data by PxeBcPrivate protocol. + // + Status = gBS->OpenProtocol ( + NicHandle, + &gEfiCallerIdGuid, + (VOID **) &Id, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mPxeBcControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gPxeBcComponentName) + ); +} diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c index 080b751cb1..b29df68bbd 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c @@ -1398,7 +1398,7 @@ PxeBcDriverBindingStop ( if (NicHandle == NULL) { NicHandle = PxeBcGetNicByIp6Children (ControllerHandle); if (NicHandle == NULL) { - return EFI_DEVICE_ERROR; + return EFI_SUCCESS; } else { IsIpv6 = TRUE; } diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcSupport.h b/NetworkPkg/UefiPxeBcDxe/PxeBcSupport.h index c82237be0e..80e56bc06f 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcSupport.h +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcSupport.h @@ -1,7 +1,7 @@ /** @file Support functions declaration for UefiPxeBc Driver. - Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.
+ Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -485,4 +485,29 @@ CalcElapsedTime ( IN PXEBC_PRIVATE_DATA *Private ); +/** + Get the Nic handle using any child handle in the IPv4 stack. + + @param[in] ControllerHandle Pointer to child handle over IPv4. + + @return NicHandle The pointer to the Nic handle. + +**/ +EFI_HANDLE +PxeBcGetNicByIp4Children ( + IN EFI_HANDLE ControllerHandle + ); + +/** + Get the Nic handle using any child handle in the IPv6 stack. + + @param[in] ControllerHandle Pointer to child handle over IPv6. + + @return NicHandle The pointer to the Nic handle. + +**/ +EFI_HANDLE +PxeBcGetNicByIp6Children ( + IN EFI_HANDLE ControllerHandle + ); #endif