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/Mtftp6Dxe/ComponentName.c | 126 ++++++++++++++++++++++++++++++++++- NetworkPkg/Mtftp6Dxe/Mtftp6Driver.c | 117 +++++++++++++++++++++++--------- NetworkPkg/Mtftp6Dxe/Mtftp6Driver.h | 3 +- NetworkPkg/Mtftp6Dxe/Mtftp6Impl.c | 15 ++++- NetworkPkg/Mtftp6Dxe/Mtftp6Impl.h | 8 ++- NetworkPkg/Mtftp6Dxe/Mtftp6Rrq.c | 16 +++++ NetworkPkg/Mtftp6Dxe/Mtftp6Support.c | 8 ++- 7 files changed, 253 insertions(+), 40 deletions(-) (limited to 'NetworkPkg/Mtftp6Dxe') diff --git a/NetworkPkg/Mtftp6Dxe/ComponentName.c b/NetworkPkg/Mtftp6Dxe/ComponentName.c index 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; } -- cgit v1.2.3