From 216f79703b8cb8dc65abdd768bedb2bcdbc1a1f8 Mon Sep 17 00:00:00 2001 From: sfu5 Date: Thu, 13 Dec 2012 06:47:06 +0000 Subject: 1. Add EFI_COMPONENT_NAME2_PROTOCOL.GetControllerName() support. 2. Fix the driver binding Stop() hang issue in the network stack. 3. Add Ip4 raw data support. 4. Add iSCSI Dhcp option 60 support. Signed-off-by: Fu Siyuan 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 --- NetworkPkg/Dhcp6Dxe/ComponentName.c | 130 +++++++++++++++++++++++++++++++++++- NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c | 89 ++++++++++++++---------- NetworkPkg/Dhcp6Dxe/Dhcp6Driver.h | 3 +- NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c | 3 +- NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h | 4 +- NetworkPkg/Dhcp6Dxe/Dhcp6Io.c | 6 +- 6 files changed, 189 insertions(+), 46 deletions(-) (limited to 'NetworkPkg/Dhcp6Dxe') 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; } -- cgit v1.2.3