summaryrefslogtreecommitdiffstats
path: root/MdeModulePkg/Universal/Network
diff options
context:
space:
mode:
authorsfu5 <sfu5@6f19259b-4bc3-4df7-8a09-765794883524>2012-12-13 06:47:06 +0000
committersfu5 <sfu5@6f19259b-4bc3-4df7-8a09-765794883524>2012-12-13 06:47:06 +0000
commit216f79703b8cb8dc65abdd768bedb2bcdbc1a1f8 (patch)
tree847cafec4185c79f082ccb9a5e895062a06980c1 /MdeModulePkg/Universal/Network
parent906e1cb7f7f178f5cb2a3bebbac59f6aa8c273a4 (diff)
downloadedk2-216f79703b8cb8dc65abdd768bedb2bcdbc1a1f8.tar.gz
edk2-216f79703b8cb8dc65abdd768bedb2bcdbc1a1f8.tar.bz2
edk2-216f79703b8cb8dc65abdd768bedb2bcdbc1a1f8.zip
1. Add EFI_COMPONENT_NAME2_PROTOCOL.GetControllerName() support.
2. Fix the driver binding Stop() hang issue in the network stack. 3. Add Ip4 raw data support. 4. Add iSCSI Dhcp option 60 support. Signed-off-by: Fu Siyuan <siyuan.fu@intel.com> Reviewed-by: Ye Ting <ting.ye@intel.com> Reviewed-by: Ouyang Qian <qian.ouyang@intel.com> git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13995 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdeModulePkg/Universal/Network')
-rw-r--r--MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c70
-rw-r--r--MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.c4
-rw-r--r--MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.h4
-rw-r--r--MdeModulePkg/Universal/Network/ArpDxe/ComponentName.c53
-rw-r--r--MdeModulePkg/Universal/Network/Dhcp4Dxe/ComponentName.c129
-rw-r--r--MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.c88
-rw-r--r--MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.h3
-rw-r--r--MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c30
-rw-r--r--MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.h1
-rw-r--r--MdeModulePkg/Universal/Network/IScsiDxe/ComponentName.c40
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/ComponentName.c126
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Common.h5
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c163
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.h9
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Icmp.c6
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c208
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h2
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c108
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h28
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c29
-rw-r--r--MdeModulePkg/Universal/Network/MnpDxe/ComponentName.c171
-rw-r--r--MdeModulePkg/Universal/Network/MnpDxe/ComponentName.h3
-rw-r--r--MdeModulePkg/Universal/Network/MnpDxe/MnpConfig.c61
-rw-r--r--MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.c86
-rw-r--r--MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.h8
-rw-r--r--MdeModulePkg/Universal/Network/Mtftp4Dxe/ComponentName.c125
-rw-r--r--MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c156
-rw-r--r--MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.h1
-rw-r--r--MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c6
-rw-r--r--MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.h9
-rw-r--r--MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c35
-rw-r--r--MdeModulePkg/Universal/Network/SnpDxe/ComponentName.c125
-rw-r--r--MdeModulePkg/Universal/Network/SnpDxe/Snp.c6
-rw-r--r--MdeModulePkg/Universal/Network/SnpDxe/Snp.h4
-rw-r--r--MdeModulePkg/Universal/Network/Tcp4Dxe/ComponentName.c127
-rw-r--r--MdeModulePkg/Universal/Network/Tcp4Dxe/SockInterface.c8
-rw-r--r--MdeModulePkg/Universal/Network/Tcp4Dxe/Socket.h3
-rw-r--r--MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dispatcher.c30
-rw-r--r--MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c84
-rw-r--r--MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Main.h8
-rw-r--r--MdeModulePkg/Universal/Network/Udp4Dxe/ComponentName.c126
-rw-r--r--MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Driver.c111
-rw-r--r--MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c4
-rw-r--r--MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.h12
-rw-r--r--MdeModulePkg/Universal/Network/UefiPxeBcDxe/ComponentName.c64
-rw-r--r--MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDriver.c4
-rw-r--r--MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigImpl.c29
47 files changed, 2088 insertions, 424 deletions
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.<BR>
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at<BR>
@@ -242,6 +242,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.
If a child device is provided, it further tests to see if this driver supports
@@ -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.<BR>
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at<BR>
@@ -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.<BR>
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at<BR>
@@ -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.<BR>
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at<BR>
@@ -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.<BR>
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
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.
@@ -231,6 +245,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.<BR>
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
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.<BR>
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
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.<BR>
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
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.<BR>
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at<BR>
@@ -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.
@@ -231,6 +233,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.<BR>
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
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.<BR>
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
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.<BR>
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
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)) {
@@ -1689,6 +1696,27 @@ Ip4TxTokenValid (
}
//
+ // 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 <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DpcLib.h>
+#include <Library/PrintLib.h>
#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.<BR>
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
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.<BR>
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
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.
@@ -324,6 +336,13 @@ Ip4Output (
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
// fragment is NOT sent in this loop. First compute how many
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.<BR>
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
of the BSD License 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.
@@ -101,6 +103,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.<BR>
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
of the BSD License 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.<BR>
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
of the BSD License 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.
@@ -687,6 +686,30 @@ MnpDestroyServiceData (
}
/**
+ 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.
@param[in, out] MnpServiceData Pointer to the mnp service context 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.<BR>
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
of the BSD License which accompanies this distribution. The full
@@ -27,6 +27,50 @@ EFI_DRIVER_BINDING_PROTOCOL gMnpDriverBinding = {
};
/**
+ 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
order to make drivers as small as possible, there are a few calling
@@ -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.<BR>
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
of the BSD License which accompanies this distribution. The full
@@ -33,11 +33,17 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/DpcLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/DevicePathLib.h>
+#include <Library/PrintLib.h>
#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.<BR>
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
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.
@@ -231,6 +233,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 <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UdpIoLib.h>
+#include <LIbrary/PrintLib.h>
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.<BR>
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
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.<BR>
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed
and made available under the terms and conditions of the BSD License 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.
@@ -232,6 +234,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.<BR>
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed
and made available under the terms and conditions of the BSD License 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.<BR>
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed
and made available under the terms and conditions of the BSD License 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 <Library/BaseLib.h>
#include <Library/UefiLib.h>
#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
#include <IndustryStandard/Pci.h>
@@ -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.<BR>
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
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.
@@ -228,6 +230,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.<BR>
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
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 <Library/UefiDriverEntryPoint.h>
#include <Library/UefiLib.h>
#include <Library/DpcLib.h>
+#include <Library/PrintLib.h>
#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.<BR>
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
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.<BR>
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
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,
@@ -136,6 +137,43 @@ Tcp4DestroyTimer (
}
/**
+ 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.
@param ImageHandle The firmware allocated handle for this
@@ -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.<BR>
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
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.<BR>
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
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.
@@ -231,6 +233,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.<BR>
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
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.<BR>
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
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.<BR>
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
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 <Library/MemoryAllocationLib.h>
#include <Library/TimerLib.h>
#include <Library/DpcLib.h>
+#include <Library/PrintLib.h>
#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.<BR>
+Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
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.<BR>
+Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
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.<BR>
+Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
of the BSD License 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
@@ -518,6 +519,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
//
HiiHandle = HiiAddPackages (
@@ -594,6 +611,16 @@ UninstallVlanConfigForm (
}
//
+ // End the parent-child relationship.
+ //
+ gBS->CloseProtocol (
+ PrivateData->ControllerHandle,
+ &gEfiVlanConfigProtocolGuid,
+ PrivateData->ImageHandle,
+ PrivateData->DriverHandle
+ );
+
+ //
// Uninstall HII Config Access Protocol
//
if (PrivateData->DriverHandle != NULL) {