summaryrefslogtreecommitdiff
path: root/NetworkPkg
diff options
context:
space:
mode:
Diffstat (limited to 'NetworkPkg')
-rw-r--r--NetworkPkg/Dhcp6Dxe/ComponentName.c130
-rw-r--r--NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c89
-rw-r--r--NetworkPkg/Dhcp6Dxe/Dhcp6Driver.h3
-rw-r--r--NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c3
-rw-r--r--NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h4
-rw-r--r--NetworkPkg/Dhcp6Dxe/Dhcp6Io.c6
-rw-r--r--NetworkPkg/IScsiDxe/ComponentName.c148
-rw-r--r--NetworkPkg/IScsiDxe/IScsiDhcp6.c28
-rw-r--r--NetworkPkg/IScsiDxe/IScsiDhcp6.h3
-rw-r--r--NetworkPkg/IScsiDxe/IScsiDriver.c23
-rw-r--r--NetworkPkg/IScsiDxe/IScsiDriver.h5
-rw-r--r--NetworkPkg/IScsiDxe/IScsiIbft.c8
-rw-r--r--NetworkPkg/Ip6Dxe/ComponentName.c139
-rw-r--r--NetworkPkg/Ip6Dxe/Ip6Common.c70
-rw-r--r--NetworkPkg/Ip6Dxe/Ip6Common.h7
-rw-r--r--NetworkPkg/Ip6Dxe/Ip6Driver.c145
-rw-r--r--NetworkPkg/Ip6Dxe/Ip6Driver.h7
-rw-r--r--NetworkPkg/Ip6Dxe/Ip6If.c6
-rw-r--r--NetworkPkg/Ip6Dxe/Ip6Impl.c6
-rw-r--r--NetworkPkg/Ip6Dxe/Ip6Impl.h5
-rw-r--r--NetworkPkg/Ip6Dxe/Ip6Nd.c8
-rw-r--r--NetworkPkg/IpSecDxe/ComponentName.c45
-rw-r--r--NetworkPkg/Mtftp6Dxe/ComponentName.c126
-rw-r--r--NetworkPkg/Mtftp6Dxe/Mtftp6Driver.c117
-rw-r--r--NetworkPkg/Mtftp6Dxe/Mtftp6Driver.h3
-rw-r--r--NetworkPkg/Mtftp6Dxe/Mtftp6Impl.c15
-rw-r--r--NetworkPkg/Mtftp6Dxe/Mtftp6Impl.h8
-rw-r--r--NetworkPkg/Mtftp6Dxe/Mtftp6Rrq.c16
-rw-r--r--NetworkPkg/Mtftp6Dxe/Mtftp6Support.c8
-rw-r--r--NetworkPkg/TcpDxe/ComponentName.c226
-rw-r--r--NetworkPkg/TcpDxe/SockInterface.c6
-rw-r--r--NetworkPkg/TcpDxe/Socket.h2
-rw-r--r--NetworkPkg/TcpDxe/TcpDispatcher.c42
-rw-r--r--NetworkPkg/TcpDxe/TcpDriver.c80
-rw-r--r--NetworkPkg/TcpDxe/TcpMain.h10
-rw-r--r--NetworkPkg/Udp6Dxe/ComponentName.c122
-rw-r--r--NetworkPkg/Udp6Dxe/Udp6Driver.c100
-rw-r--r--NetworkPkg/Udp6Dxe/Udp6Impl.c10
-rw-r--r--NetworkPkg/Udp6Dxe/Udp6Impl.h12
-rw-r--r--NetworkPkg/UefiPxeBcDxe/ComponentName.c52
-rw-r--r--NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c2
-rw-r--r--NetworkPkg/UefiPxeBcDxe/PxeBcSupport.h27
42 files changed, 1602 insertions, 270 deletions
diff --git a/NetworkPkg/Dhcp6Dxe/ComponentName.c b/NetworkPkg/Dhcp6Dxe/ComponentName.c
index 178c8bca45..352df087f9 100644
--- a/NetworkPkg/Dhcp6Dxe/ComponentName.c
+++ b/NetworkPkg/Dhcp6Dxe/ComponentName.c
@@ -1,7 +1,7 @@
/** @file
UEFI Component Name(2) protocol implementation for Dhcp6 driver.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<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
@@ -172,6 +172,19 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mDhcp6DriverNameTab
}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gDhcp6ControllerNameTable = NULL;
+
+CHAR16 *mDhcp6ControllerName[] = {
+ L"DHCPv6 (State=0, Init)",
+ L"DHCPv6 (State=1, Selecting)",
+ L"DHCPv6 (State=2, Requesting)",
+ L"DHCPv6 (State=3, Declining)",
+ L"DHCPv6 (State=4, Confirming)",
+ L"DHCPv6 (State=5, Releasing)",
+ L"DHCPv6 (State=6, Bound)",
+ L"DHCPv6 (State=7, Renewing)",
+ L"DHCPv6 (State=8, Rebinding)"
+};
/**
Retrieves a Unicode string that is the user-readable name of the driver.
@@ -229,6 +242,67 @@ Dhcp6ComponentNameGetDriverName (
);
}
+/**
+ Update the component name for the Dhcp6 child handle.
+
+ @param Dhcp6[in] A pointer to the EFI_DHCP6_PROTOCOL.
+
+
+ @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+
+**/
+EFI_STATUS
+UpdateName (
+ IN EFI_DHCP6_PROTOCOL *Dhcp6
+ )
+{
+ EFI_STATUS Status;
+ EFI_DHCP6_MODE_DATA Dhcp6ModeData;
+ CHAR16 HandleName[64];
+
+ if (Dhcp6 == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Format the child name into the string buffer.
+ //
+ Status = Dhcp6->GetModeData (Dhcp6, &Dhcp6ModeData, NULL);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (gDhcp6ControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gDhcp6ControllerNameTable);
+ gDhcp6ControllerNameTable = NULL;
+ }
+
+ if (Dhcp6ModeData.Ia == NULL) {
+ UnicodeSPrint (HandleName, sizeof (HandleName), L"DHCPv6 (No configured IA)");
+ } else {
+ StrCpy (HandleName, mDhcp6ControllerName[Dhcp6ModeData.Ia->State]);
+ }
+
+ Status = AddUnicodeString2 (
+ "eng",
+ gDhcp6ComponentName.SupportedLanguages,
+ &gDhcp6ControllerNameTable,
+ HandleName,
+ TRUE
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return AddUnicodeString2 (
+ "en",
+ gDhcp6ComponentName2.SupportedLanguages,
+ &gDhcp6ControllerNameTable,
+ HandleName,
+ FALSE
+ );
+}
/**
Retrieves a Unicode string that is the user-readable name of the controller
@@ -308,5 +382,57 @@ Dhcp6ComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+ EFI_DHCP6_PROTOCOL *Dhcp6;
+
+ //
+ // Only provide names for child handles.
+ //
+ if (ChildHandle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver produced ChildHandle
+ //
+ Status = EfiTestChildHandle (
+ ControllerHandle,
+ ChildHandle,
+ &gEfiUdp6ProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Retrieve an instance of a produced protocol from ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiDhcp6ProtocolGuid,
+ (VOID **)&Dhcp6,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Update the component name for this child handle.
+ //
+ Status = UpdateName (Dhcp6);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ gDhcp6ControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gDhcp6ComponentName)
+ );
}
+
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c
index 346986bd15..42caefb154 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c
@@ -31,7 +31,6 @@ EFI_SERVICE_BINDING_PROTOCOL gDhcp6ServiceBindingTemplate = {
Dhcp6ServiceBindingDestroyChild
};
-
/**
Configure the default Udp6Io to receive all the DHCP6 traffic
on this network interface.
@@ -155,7 +154,6 @@ Dhcp6CreateService (
// Initialize the fields of the new Dhcp6 service.
//
Dhcp6Srv->Signature = DHCP6_SERVICE_SIGNATURE;
- Dhcp6Srv->InDestroy = FALSE;
Dhcp6Srv->Controller = Controller;
Dhcp6Srv->Image = ImageHandle;
Dhcp6Srv->Xid = (0xffffff & NET_RANDOM (NetRandomInitSeed ()));
@@ -328,6 +326,35 @@ Dhcp6CreateInstance (
return EFI_SUCCESS;
}
+/**
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.
+
+ @param[in] Entry The entry to be removed.
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
+
+ @retval EFI_SUCCESS The entry has been removed successfully.
+ @retval Others Fail to remove the entry.
+
+**/
+EFI_STATUS
+Dhcp6DestroyChildEntry (
+ IN LIST_ENTRY *Entry,
+ IN VOID *Context
+)
+{
+ DHCP6_INSTANCE *Instance;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+
+ if (Entry == NULL || Context == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Instance = NET_LIST_USER_STRUCT_S (Entry, DHCP6_INSTANCE, Link, DHCP6_INSTANCE_SIGNATURE);
+ ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *) Context;
+
+ return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
+}
+
/**
Entry point of the DHCP6 driver to install various protocols.
@@ -498,11 +525,11 @@ Dhcp6DriverBindingStop (
)
{
EFI_STATUS Status;
- EFI_TPL OldTpl;
EFI_HANDLE NicHandle;
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
DHCP6_SERVICE *Service;
- DHCP6_INSTANCE *Instance;
+ LIST_ENTRY *List;
+ UINTN ListLength;
//
// Find and check the Nic handle by the controller handle.
@@ -510,7 +537,7 @@ Dhcp6DriverBindingStop (
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp6ProtocolGuid);
if (NicHandle == NULL) {
- return EFI_DEVICE_ERROR;
+ return EFI_SUCCESS;
}
Status = gBS->OpenProtocol (
@@ -527,50 +554,44 @@ Dhcp6DriverBindingStop (
}
Service = DHCP6_SERVICE_FROM_THIS (ServiceBinding);
-
- if (Service->InDestroy) {
- return EFI_SUCCESS;
+ if (!IsListEmpty (&Service->Child)) {
+ //
+ // Destroy all the children instances before destory the service.
+ //
+ List = &Service->Child;
+ Status = NetDestroyLinkList (
+ List,
+ Dhcp6DestroyChildEntry,
+ ServiceBinding,
+ &ListLength
+ );
+ if (EFI_ERROR (Status) || ListLength != 0) {
+ Status = EFI_DEVICE_ERROR;
+ }
}
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+ if (NumberOfChildren == 0 && !IsListEmpty (&Service->Child)) {
+ Status = EFI_DEVICE_ERROR;
+ }
- if (NumberOfChildren == 0) {
+ if (NumberOfChildren == 0 && IsListEmpty (&Service->Child)) {
//
// Destroy the service itself if no child instance left.
//
- Service->InDestroy = TRUE;
-
Status = gBS->UninstallProtocolInterface (
NicHandle,
&gEfiDhcp6ServiceBindingProtocolGuid,
ServiceBinding
);
-
if (EFI_ERROR (Status)) {
- Service->InDestroy = FALSE;
goto ON_EXIT;
}
Dhcp6DestroyService (Service);
-
- } else {
- //
- // Destroy all the children instances before destroy the service.
- //
- while (!IsListEmpty (&Service->Child)) {
- Instance = NET_LIST_HEAD (&Service->Child, DHCP6_INSTANCE, Link);
- ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
- }
- //
- // Any of child failed to be destroyed.
- //
- if (Service->NumOfChild != 0) {
- Status = EFI_DEVICE_ERROR;
- }
+ Status = EFI_SUCCESS;
}
-
+
ON_EXIT:
- gBS->RestoreTPL (OldTpl);
return Status;
}
@@ -771,12 +792,13 @@ Dhcp6ServiceBindingDestroyChild (
//
// Uninstall the MTFTP6 protocol first to enable a top down destruction.
//
+ gBS->RestoreTPL (OldTpl);
Status = gBS->UninstallProtocolInterface (
ChildHandle,
&gEfiDhcp6ProtocolGuid,
Dhcp6
);
-
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
if (EFI_ERROR (Status)) {
Instance->InDestroy = FALSE;
gBS->RestoreTPL (OldTpl);
@@ -789,9 +811,8 @@ Dhcp6ServiceBindingDestroyChild (
RemoveEntryList (&Instance->Link);
Service->NumOfChild--;
- Dhcp6DestroyInstance (Instance);
-
gBS->RestoreTPL (OldTpl);
+ Dhcp6DestroyInstance (Instance);
return EFI_SUCCESS;
}
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.h
index 4ef7f17963..bec47a0679 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.h
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.h
@@ -2,7 +2,7 @@
Driver Binding functions and Service Binding functions
declaration for Dhcp6 Driver.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<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
@@ -21,6 +21,7 @@
extern EFI_COMPONENT_NAME_PROTOCOL gDhcp6ComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gDhcp6ComponentName2;
+extern EFI_UNICODE_STRING_TABLE *gDhcp6ControllerNameTable;
/**
Test to see if this driver supports ControllerHandle. This service
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c
index 2c2b9f9f0e..934c03ed85 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c
@@ -216,12 +216,11 @@ EfiDhcp6Stop (
Instance->UdpSts = EFI_ALREADY_STARTED;
Status = Dhcp6SendReleaseMsg (Instance, Instance->IaCb.Ia);
+ gBS->RestoreTPL (OldTpl);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
- gBS->RestoreTPL (OldTpl);
-
//
// Poll udp out of the net tpl if synchoronus call.
//
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h
index d4e9746be8..71b16b1919 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h
@@ -34,6 +34,7 @@
#include <Library/UefiLib.h>
#include <Library/BaseLib.h>
#include <Library/NetLib.h>
+#include <Library/PrintLib.h>
typedef struct _DHCP6_IA_CB DHCP6_IA_CB;
@@ -245,7 +246,7 @@ struct _DHCP6_INSTANCE {
EFI_DHCP6_PACKET *AdSelect;
UINT8 AdPref;
EFI_IPv6_ADDRESS *Unicast;
- EFI_STATUS UdpSts;
+ volatile EFI_STATUS UdpSts;
BOOLEAN InDestroy;
BOOLEAN MediaPresent;
UINT64 StartTime;
@@ -266,7 +267,6 @@ struct _DHCP6_SERVICE {
UINT32 Xid;
LIST_ENTRY Child;
UINTN NumOfChild;
- BOOLEAN InDestroy;
};
/**
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
index f2e33f335f..0e83d07853 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
@@ -2510,7 +2510,7 @@ Dhcp6HandleStateful (
ClientId = Service->ClientId;
Status = EFI_SUCCESS;
- if (Instance->InDestroy || Instance->Config == NULL) {
+ if (Instance->Config == NULL) {
goto ON_CONTINUE;
}
@@ -2624,10 +2624,6 @@ Dhcp6HandleStateless (
IsMatched = FALSE;
InfCb = NULL;
- if (Instance->InDestroy) {
- goto ON_EXIT;
- }
-
if (Packet->Dhcp6.Header.MessageType != Dhcp6MsgReply) {
goto ON_EXIT;
}
diff --git a/NetworkPkg/IScsiDxe/ComponentName.c b/NetworkPkg/IScsiDxe/ComponentName.c
index e4e28e8961..1ee21f5d5d 100644
--- a/NetworkPkg/IScsiDxe/ComponentName.c
+++ b/NetworkPkg/IScsiDxe/ComponentName.c
@@ -1,7 +1,7 @@
/** @file
UEFI Component Name(2) protocol implementation for iSCSI.
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<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
@@ -43,6 +43,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIScsiDriverNameTable
}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gIScsiControllerNameTable = NULL;
+
/**
Retrieves a Unicode string that is the user readable name of the driver.
@@ -100,6 +102,99 @@ IScsiComponentNameGetDriverName (
}
/**
+ Update the component name for the iSCSI NIC handle.
+
+ @param[in] Controller The handle of the NIC controller.
+ @param[in] Ipv6Flag TRUE if IP6 network stack is used.
+
+ @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+ @retval EFI_UNSUPPORTED Can't get the corresponding NIC info from the Controller handle.
+
+**/
+EFI_STATUS
+UpdateName (
+ IN EFI_HANDLE Controller,
+ IN BOOLEAN Ipv6Flag
+ )
+{
+ EFI_STATUS Status;
+ EFI_MAC_ADDRESS MacAddr;
+ UINTN HwAddressSize;
+ UINT16 VlanId;
+ ISCSI_NIC_INFO *ThisNic;
+ ISCSI_NIC_INFO *NicInfo;
+ LIST_ENTRY *Entry;
+ CHAR16 HandleName[80];
+
+ //
+ // Get MAC address of this network device.
+ //
+ Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get VLAN ID of this network device.
+ //
+ VlanId = NetLibGetVlanId (Controller);
+
+ //
+ // Check whether the NIC information exists.
+ //
+ ThisNic = NULL;
+
+ NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {
+ NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);
+ if (NicInfo->HwAddressSize == HwAddressSize &&
+ CompareMem (&NicInfo->PermanentAddress, MacAddr.Addr, HwAddressSize) == 0 &&
+ NicInfo->VlanId == VlanId) {
+
+ ThisNic = NicInfo;
+ break;
+ }
+ }
+
+ if (ThisNic == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ UnicodeSPrint (
+ HandleName,
+ sizeof (HandleName),
+ L"iSCSI (%s, NicIndex=%d)",
+ Ipv6Flag ? L"IPv6" : L"IPv4",
+ ThisNic->NicIndex
+ );
+
+ if (gIScsiControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gIScsiControllerNameTable);
+ gIScsiControllerNameTable = NULL;
+ }
+
+ Status = AddUnicodeString2 (
+ "eng",
+ gIScsiComponentName.SupportedLanguages,
+ &gIScsiControllerNameTable,
+ HandleName,
+ TRUE
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return AddUnicodeString2 (
+ "en",
+ gIScsiComponentName2.SupportedLanguages,
+ &gIScsiControllerNameTable,
+ HandleName,
+ FALSE
+ );
+}
+
+
+/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
@@ -177,5 +272,54 @@ IScsiComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
+ EFI_HANDLE IScsiController;
+ BOOLEAN Ipv6Flag;
+ EFI_STATUS Status;
+ EFI_GUID *IScsiPrivateGuid;
+ ISCSI_PRIVATE_PROTOCOL *IScsiIdentifier;
+
+ //
+ // Get the handle of the controller we are controling.
+ //
+ IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp4ProtocolGuid);
+ if (IScsiController != NULL) {
+ IScsiPrivateGuid = &gIScsiV4PrivateGuid;
+ Ipv6Flag = FALSE;
+ } else {
+ IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp6ProtocolGuid);
+ if (IScsiController != NULL) {
+ IScsiPrivateGuid = &gIScsiV6PrivateGuid;
+ Ipv6Flag = TRUE;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ //
+ // Retrieve an instance of a produced protocol from IScsiController
+ //
+ Status = gBS->OpenProtocol (
+ IScsiController,
+ IScsiPrivateGuid,
+ (VOID **) &IScsiIdentifier,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = UpdateName(IScsiController, Ipv6Flag);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ gIScsiControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gIScsiComponentName)
+ );
}
diff --git a/NetworkPkg/IScsiDxe/IScsiDhcp6.c b/NetworkPkg/IScsiDxe/IScsiDhcp6.c
index 2bf102ba8b..2627a59dd6 100644
--- a/NetworkPkg/IScsiDxe/IScsiDhcp6.c
+++ b/NetworkPkg/IScsiDxe/IScsiDhcp6.c
@@ -1,7 +1,7 @@
/** @file
iSCSI DHCP6 related configuration routines.
-Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<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 text of the license may be found at
@@ -250,6 +250,7 @@ IScsiDhcp6ParseReply (
EFI_DHCP6_PACKET_OPTION *BootFileOpt;
EFI_DHCP6_PACKET_OPTION **OptionList;
ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData;
+ UINT16 ParaLen;
OptionCount = 0;
BootFileOpt = NULL;
@@ -282,7 +283,7 @@ IScsiDhcp6ParseReply (
if (OptionList[Index]->OpCode == DHCP6_OPT_DNS_SERVERS) {
if (((OptionList[Index]->OpLen & 0xf) != 0) || (OptionList[Index]->OpLen == 0)) {
- Status = EFI_INVALID_PARAMETER;
+ Status = EFI_UNSUPPORTED;
goto Exit;
}
//
@@ -302,6 +303,24 @@ IScsiDhcp6ParseReply (
// The server sends this option to inform the client about an URL to a boot file.
//
BootFileOpt = OptionList[Index];
+ } else if (OptionList[Index]->OpCode == DHCP6_OPT_BOOT_FILE_PARA) {
+ //
+ // The server sends this option to inform the client about DHCP6 server address.
+ //
+ if (OptionList[Index]->OpLen < 18) {
+ Status = EFI_UNSUPPORTED;
+ goto Exit;
+ }
+ //
+ // Check param-len 1, should be 16 bytes.
+ //
+ CopyMem (&ParaLen, &OptionList[Index]->Data[0], sizeof (UINT16));
+ if (NTOHS (ParaLen) != 16) {
+ Status = EFI_UNSUPPORTED;
+ goto Exit;
+ }
+
+ CopyMem (&ConfigData->DhcpServer, &OptionList[Index]->Data[2], sizeof (EFI_IPv6_ADDRESS));
}
}
@@ -405,7 +424,7 @@ IScsiDoDhcp6 (
goto ON_EXIT;
}
- Oro = AllocateZeroPool (sizeof (EFI_DHCP6_PACKET_OPTION) + 3);
+ Oro = AllocateZeroPool (sizeof (EFI_DHCP6_PACKET_OPTION) + 5);
if (Oro == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
@@ -416,9 +435,10 @@ IScsiDoDhcp6 (
// All members in EFI_DHCP6_PACKET_OPTION are in network order.
//
Oro->OpCode = HTONS (DHCP6_OPT_REQUEST_OPTION);
- Oro->OpLen = HTONS (2 * 2);
+ Oro->OpLen = HTONS (2 * 3);
Oro->Data[1] = DHCP6_OPT_DNS_SERVERS;
Oro->Data[3] = DHCP6_OPT_BOOT_FILE_URL;
+ Oro->Data[5] = DHCP6_OPT_BOOT_FILE_PARA;
InfoReqReXmit.Irt = 4;
InfoReqReXmit.Mrc = 1;
diff --git a/NetworkPkg/IScsiDxe/IScsiDhcp6.h b/NetworkPkg/IScsiDxe/IScsiDhcp6.h
index fe3dfb7e4d..4ca25bd494 100644
--- a/NetworkPkg/IScsiDxe/IScsiDhcp6.h
+++ b/NetworkPkg/IScsiDxe/IScsiDhcp6.h
@@ -1,7 +1,7 @@
/** @file
The header file of iSCSI DHCP6 related configuration routines.
-Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<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
@@ -22,6 +22,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
/// Assigned by IANA, RFC 5970
///
#define DHCP6_OPT_BOOT_FILE_URL 59
+#define DHCP6_OPT_BOOT_FILE_PARA 60
#define ISCSI_ROOT_PATH_ID "iscsi:"
#define ISCSI_ROOT_PATH_FIELD_DELIMITER ':'
diff --git a/NetworkPkg/IScsiDxe/IScsiDriver.c b/NetworkPkg/IScsiDxe/IScsiDriver.c
index 7d8b18455c..2fd4c95a08 100644
--- a/NetworkPkg/IScsiDxe/IScsiDriver.c
+++ b/NetworkPkg/IScsiDxe/IScsiDriver.c
@@ -1,7 +1,7 @@
/** @file
The entry point of IScsi driver.
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<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
@@ -23,8 +23,8 @@ EFI_DRIVER_BINDING_PROTOCOL gIScsiDriverBinding = {
NULL
};
-EFI_GUID mIScsiV4PrivateGuid = ISCSI_V4_PRIVATE_GUID;
-EFI_GUID mIScsiV6PrivateGuid = ISCSI_V6_PRIVATE_GUID;
+EFI_GUID gIScsiV4PrivateGuid = ISCSI_V4_PRIVATE_GUID;
+EFI_GUID gIScsiV6PrivateGuid = ISCSI_V6_PRIVATE_GUID;
ISCSI_PRIVATE_DATA *mPrivate = NULL;
/**
@@ -121,7 +121,7 @@ IScsiDriverBindingSupported (
Status = gBS->OpenProtocol (
ControllerHandle,
- &mIScsiV4PrivateGuid,
+ &gIScsiV4PrivateGuid,
NULL,
This->DriverBindingHandle,
ControllerHandle,
@@ -150,7 +150,7 @@ IScsiDriverBindingSupported (
Status = gBS->OpenProtocol (
ControllerHandle,
- &mIScsiV6PrivateGuid,
+ &gIScsiV6PrivateGuid,
NULL,
This->DriverBindingHandle,
ControllerHandle,
@@ -231,11 +231,11 @@ IScsiStart (
//
if (IpVersion == IP_VERSION_4) {
- IScsiPrivateGuid = &mIScsiV4PrivateGuid;
+ IScsiPrivateGuid = &gIScsiV4PrivateGuid;
TcpServiceBindingGuid = &gEfiTcp4ServiceBindingProtocolGuid;
ProtocolGuid = &gEfiTcp4ProtocolGuid;
} else if (IpVersion == IP_VERSION_6) {
- IScsiPrivateGuid = &mIScsiV6PrivateGuid;
+ IScsiPrivateGuid = &gIScsiV6PrivateGuid;
TcpServiceBindingGuid = &gEfiTcp6ServiceBindingProtocolGuid;
ProtocolGuid = &gEfiTcp6ProtocolGuid;
} else {
@@ -931,13 +931,13 @@ IScsiDriverBindingStop (
//
IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp4ProtocolGuid);
if (IScsiController != NULL) {
- ProtocolGuid = &mIScsiV4PrivateGuid;
+ ProtocolGuid = &gIScsiV4PrivateGuid;
TcpProtocolGuid = &gEfiTcp4ProtocolGuid;
TcpServiceBindingGuid = &gEfiTcp4ServiceBindingProtocolGuid;
} else {
IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp6ProtocolGuid);
ASSERT (IScsiController != NULL);
- ProtocolGuid = &mIScsiV6PrivateGuid;
+ ProtocolGuid = &gIScsiV6PrivateGuid;
TcpProtocolGuid = &gEfiTcp6ProtocolGuid;
TcpServiceBindingGuid = &gEfiTcp6ServiceBindingProtocolGuid;
}
@@ -1060,6 +1060,11 @@ IScsiUnload (
&gIScsiAuthenticationInfo,
NULL
);
+
+ if (gIScsiControllerNameTable!= NULL) {
+ FreeUnicodeStringTable (gIScsiControllerNameTable);
+ gIScsiControllerNameTable = NULL;
+ }
return gBS->UninstallMultipleProtocolInterfaces (
ImageHandle,
diff --git a/NetworkPkg/IScsiDxe/IScsiDriver.h b/NetworkPkg/IScsiDxe/IScsiDriver.h
index 04866f0ed4..8c266fe763 100644
--- a/NetworkPkg/IScsiDxe/IScsiDriver.h
+++ b/NetworkPkg/IScsiDxe/IScsiDriver.h
@@ -1,7 +1,7 @@
/** @file
The header file of IScsiDriver.c.
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<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
@@ -33,9 +33,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
extern EFI_COMPONENT_NAME2_PROTOCOL gIScsiComponentName2;
extern EFI_COMPONENT_NAME_PROTOCOL gIScsiComponentName;
+extern EFI_UNICODE_STRING_TABLE *gIScsiControllerNameTable;
extern EFI_ISCSI_INITIATOR_NAME_PROTOCOL gIScsiInitiatorName;
extern EFI_AUTHENTICATION_INFO_PROTOCOL gIScsiAuthenticationInfo;
extern EFI_EXT_SCSI_PASS_THRU_PROTOCOL gIScsiExtScsiPassThruProtocolTemplate;
+extern EFI_GUID gIScsiV4PrivateGuid;
+extern EFI_GUID gIScsiV6PrivateGuid;
typedef struct {
CHAR16 PortString[ISCSI_NAME_IFR_MAX_SIZE];
diff --git a/NetworkPkg/IScsiDxe/IScsiIbft.c b/NetworkPkg/IScsiDxe/IScsiIbft.c
index 879d310cc9..9dba4e6f36 100644
--- a/NetworkPkg/IScsiDxe/IScsiIbft.c
+++ b/NetworkPkg/IScsiDxe/IScsiIbft.c
@@ -321,14 +321,10 @@ IScsiFillNICAndTargetSections (
Nic->SubnetMaskPrefixLength = NvData->PrefixLength;
CopyMem (&Nic->Ip, &NvData->LocalIp, sizeof (EFI_IPv6_ADDRESS));
CopyMem (&Nic->Gateway, &NvData->Gateway, sizeof (EFI_IPv6_ADDRESS));
-
CopyMem (&Nic->PrimaryDns, &Attempt->PrimaryDns, sizeof (EFI_IPv6_ADDRESS));
CopyMem (&Nic->SecondaryDns, &Attempt->SecondaryDns, sizeof (EFI_IPv6_ADDRESS));
- //
- // TODO: DHCP server address cannot be retrieved by DHCPv6 process since
- // DHCP server option is removed.
- //CopyMem (&Nic->DhcpServer, &Attempt->DhcpServer, sizeof (EFI_IPv6_ADDRESS));
- //
+ CopyMem (&Nic->DhcpServer, &Attempt->DhcpServer, sizeof (EFI_IPv6_ADDRESS));
+
} else {
ASSERT (FALSE);
}
diff --git a/NetworkPkg/Ip6Dxe/ComponentName.c b/NetworkPkg/Ip6Dxe/ComponentName.c
index bcdf4b1e42..dc164269a8 100644
--- a/NetworkPkg/Ip6Dxe/ComponentName.c
+++ b/NetworkPkg/Ip6Dxe/ComponentName.c
@@ -2,7 +2,7 @@
Implementation of EFI_COMPONENT_NAME_PROTOCOL and
EFI_COMPONENT_NAME2_PROTOCOL protocol.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<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
@@ -174,6 +174,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIp6DriverNameTable[
}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gIp6ControllerNameTable = NULL;
+
/**
Retrieves a Unicode string that is the user-readable name of the driver.
@@ -232,6 +234,88 @@ Ip6ComponentNameGetDriverName (
}
/**
+ Update the component name for the IP6 child handle.
+
+ @param Ip6[in] A pointer to the EFI_IP6_PROTOCOL.
+
+
+ @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+
+**/
+EFI_STATUS
+UpdateName (
+ IN EFI_IP6_PROTOCOL *Ip6
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 HandleName[128];
+ EFI_IP6_MODE_DATA Ip6ModeData;
+ UINTN Offset;
+ CHAR16 Address[sizeof"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
+
+ if (Ip6 == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Format the child name into the string buffer.
+ //
+ Offset = 0;
+ Status = Ip6->GetModeData (Ip6, &Ip6ModeData, NULL, NULL);
+ if (!EFI_ERROR (Status) && Ip6ModeData.IsStarted) {
+ Status = NetLibIp6ToStr (&Ip6ModeData.ConfigData.StationAddress, Address, sizeof(Address));
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Offset += UnicodeSPrint (
+ HandleName,
+ sizeof(HandleName),
+ L"IPv6(StationAddress=%s, ",
+ Address
+ );
+ Status = NetLibIp6ToStr (&Ip6ModeData.ConfigData.DestinationAddress, Address, sizeof(Address));
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ UnicodeSPrint (
+ HandleName + Offset,
+ sizeof(HandleName) - Offset,
+ L"DestinationAddress=%s)",
+ Address
+ );
+ } else if (!Ip6ModeData.IsStarted) {
+ UnicodeSPrint (HandleName, sizeof(HandleName), L"IPv6(Not started)");
+ } else {
+ UnicodeSPrint (HandleName, sizeof(HandleName), L"IPv6(%r)", Status);
+ }
+
+ if (gIp6ControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gIp6ControllerNameTable);
+ gIp6ControllerNameTable = NULL;
+ }
+
+ Status = AddUnicodeString2 (
+ "eng",
+ gIp6ComponentName.SupportedLanguages,
+ &gIp6ControllerNameTable,
+ HandleName,
+ TRUE
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return AddUnicodeString2 (
+ "en",
+ gIp6ComponentName2.SupportedLanguages,
+ &gIp6ControllerNameTable,
+ HandleName,
+ FALSE
+ );
+}
+
+/**
Retrieves a Unicode string that is the user-readable name of the controller
that is being managed by a driver.
@@ -309,5 +393,56 @@ Ip6ComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+ EFI_IP6_PROTOCOL *Ip6;
+
+ //
+ // Only provide names for child handles.
+ //
+ if (ChildHandle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver produced ChildHandle
+ //
+ Status = EfiTestChildHandle (
+ ControllerHandle,
+ ChildHandle,
+ &gEfiManagedNetworkProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Retrieve an instance of a produced protocol from ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiIp6ProtocolGuid,
+ (VOID **)&Ip6,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Update the component name for this child handle.
+ //
+ Status = UpdateName (Ip6);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ gIp6ControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gIp6ComponentName)
+ );
}
diff --git a/NetworkPkg/Ip6Dxe/Ip6Common.c b/NetworkPkg/Ip6Dxe/Ip6Common.c
index 2ae14a952c..459acd239f 100644
--- a/NetworkPkg/Ip6Dxe/Ip6Common.c
+++ b/NetworkPkg/Ip6Dxe/Ip6Common.c
@@ -1,7 +1,7 @@
/** @file
The implementation of common functions shared by IP6 driver.
- Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<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
@@ -329,6 +329,37 @@ Ip6AddAddr (
}
/**
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.
+
+ @param[in] Entry The entry to be removed.
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
+
+ @retval EFI_SUCCESS The entry has been removed successfully.
+ @retval Others Fail to remove the entry.
+
+**/
+EFI_STATUS
+Ip6DestroyChildEntryByAddr (
+ IN LIST_ENTRY *Entry,
+ IN VOID *Context
+)
+{
+ IP6_PROTOCOL *Instance;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ EFI_IPv6_ADDRESS *Address;
+
+ Instance = NET_LIST_USER_STRUCT_S (Entry, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE);
+ ServiceBinding = ((IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT*) Context)->ServiceBinding;
+ Address = ((IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT*) Context)->Address;
+
+ if ((Instance->State == IP6_STATE_CONFIGED) && EFI_IP6_EQUAL (&Instance->ConfigData.StationAddress, Address)) {
+ return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
Destroy the IP instance if its StationAddress is removed. It is the help function
for Ip6RemoveAddr().
@@ -342,35 +373,20 @@ Ip6DestroyInstanceByAddress (
IN EFI_IPv6_ADDRESS *Address
)
{
- BOOLEAN OneDestroyed;
- EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
- LIST_ENTRY *Entry;
- IP6_PROTOCOL *Instance;
+ LIST_ENTRY *List;
+ IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT Context;
NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
- ServiceBinding = &IpSb->ServiceBinding;
-
- //
- // Upper layer IP protocol consumers may have tight relationship between several
- // IP protocol instances, in other words, calling ServiceBinding->DestroyChild to
- // destroy one IP child may cause other related IP children destroyed too. This
- // will probably leave hole in the children list when we iterate it. So everytime
- // we just destroy one child then back to the start point to iterate the list.
- //
- do {
- OneDestroyed = FALSE;
-
- NET_LIST_FOR_EACH (Entry, &IpSb->Children) {
- Instance = NET_LIST_USER_STRUCT_S (Entry, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE);
-
- if ((Instance->State == IP6_STATE_CONFIGED) && EFI_IP6_EQUAL (&Instance->ConfigData.StationAddress, Address)) {
- ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
- OneDestroyed = TRUE;
- break;
- }
- }
- } while (OneDestroyed);
+ List = &IpSb->Children;
+ Context.ServiceBinding = &IpSb->ServiceBinding;
+ Context.Address = Address;
+ NetDestroyLinkList (
+ List,
+ Ip6DestroyChildEntryByAddr,
+ &Context,
+ NULL
+ );
}
/**
diff --git a/NetworkPkg/Ip6Dxe/Ip6Common.h b/NetworkPkg/Ip6Dxe/Ip6Common.h
index c3755f4859..9c2ddf4d4e 100644
--- a/NetworkPkg/Ip6Dxe/Ip6Common.h
+++ b/NetworkPkg/Ip6Dxe/Ip6Common.h
@@ -1,7 +1,7 @@
/** @file
Common definition and functions for IP6 driver.
- Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<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
@@ -60,6 +60,11 @@ typedef enum {
Ip6AnyCast
} IP6_ADDRESS_TYPE;
+typedef struct {
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ EFI_IPv6_ADDRESS *Address;
+} IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT;
+
typedef struct _IP6_INTERFACE IP6_INTERFACE;
typedef struct _IP6_PROTOCOL IP6_PROTOCOL;
typedef struct _IP6_SERVICE IP6_SERVICE;
diff --git a/NetworkPkg/Ip6Dxe/Ip6Driver.c b/NetworkPkg/Ip6Dxe/Ip6Driver.c
index 3fd1f73195..27550a5b3e 100644
--- a/NetworkPkg/Ip6Dxe/Ip6Driver.c
+++ b/NetworkPkg/Ip6Dxe/Ip6Driver.c
@@ -114,14 +114,16 @@ Ip6CleanService (
Ip6ConfigCleanInstance (&IpSb->Ip6ConfigInstance);
- //
- // Leave link-scope all-nodes multicast address (FF02::1)
- //
- Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &AllNodes);
+ if (!IpSb->LinkLocalDadFail) {
+ //
+ // Leave link-scope all-nodes multicast address (FF02::1)
+ //
+ Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &AllNodes);
- Status = Ip6LeaveGroup (IpSb, &AllNodes);
- if (EFI_ERROR (Status)) {
- return Status;
+ Status = Ip6LeaveGroup (IpSb, &AllNodes);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
}
if (IpSb->DefaultInterface != NULL) {
@@ -244,7 +246,6 @@ Ip6CreateService (
IpSb->ServiceBinding.CreateChild = Ip6ServiceBindingCreateChild;
IpSb->ServiceBinding.DestroyChild = Ip6ServiceBindingDestroyChild;
IpSb->State = IP6_SERVICE_UNSTARTED;
- IpSb->InDestroy = FALSE;
IpSb->NumChildren = 0;
InitializeListHead (&IpSb->Children);
@@ -573,6 +574,43 @@ Ip6DriverBindingStart (
}
/**
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.
+
+ @param[in] Entry The entry to be removed.
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
+
+ @retval EFI_SUCCESS The entry has been removed successfully.
+ @retval Others Fail to remove the entry.
+
+**/
+EFI_STATUS
+Ip6DestroyChildEntryInHandleBuffer (
+ IN LIST_ENTRY *Entry,
+ IN VOID *Context
+)
+{
+ IP6_PROTOCOL *IpInstance;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+
+ if (Entry == NULL || Context == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ IpInstance = NET_LIST_USER_STRUCT_S (Entry, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE);
+ ServiceBinding = ((IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;
+ NumberOfChildren = ((IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;
+ ChildHandleBuffer = ((IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;
+
+ if (!NetIsInHandleBuffer (IpInstance->Handle, NumberOfChildren, ChildHandleBuffer)) {
+ return EFI_SUCCESS;
+ }
+
+ return ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle);
+}
+
+/**
Stop this driver on ControllerHandle.
@param[in] This Protocol instance pointer.
@@ -595,30 +633,23 @@ Ip6DriverBindingStop (
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
)
{
- EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
- IP6_SERVICE *IpSb;
- IP6_PROTOCOL *IpInstance;
- EFI_HANDLE NicHandle;
- EFI_STATUS Status;
- BOOLEAN IsDhcp6;
- EFI_TPL OldTpl;
- INTN State;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ IP6_SERVICE *IpSb;
+ EFI_HANDLE NicHandle;
+ EFI_STATUS Status;
+ LIST_ENTRY *List;
+ INTN State;
+ BOOLEAN IsDhcp6;
+ IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
IsDhcp6 = FALSE;
- NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp6ProtocolGuid);
-
- if (NicHandle != NULL) {
- //
- // DriverBindingStop is triggered by the uninstallation of the EFI DHCPv6
- // Protocol used by Ip6Config.
- //
- IsDhcp6 = TRUE;
- } else {
-
- NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
-
- if (NicHandle == NULL) {
- return EFI_DEVICE_ERROR;
+ NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
+ if (NicHandle == NULL) {
+ NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp6ProtocolGuid);
+ if (NicHandle != NULL) {
+ IsDhcp6 = TRUE;
+ } else {
+ return EFI_SUCCESS;
}
}
@@ -636,21 +667,25 @@ Ip6DriverBindingStop (
IpSb = IP6_SERVICE_FROM_PROTOCOL (ServiceBinding);
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-
- if (IpSb->InDestroy) {
- Status = EFI_SUCCESS;
- goto Exit;
- }
-
if (IsDhcp6) {
-
Status = Ip6ConfigDestroyDhcp6 (&IpSb->Ip6ConfigInstance);
gBS->CloseEvent (IpSb->Ip6ConfigInstance.Dhcp6Event);
IpSb->Ip6ConfigInstance.Dhcp6Event = NULL;
- } else if (NumberOfChildren == 0) {
-
- IpSb->InDestroy = TRUE;
+ } else if (NumberOfChildren != 0) {
+ //
+ // NumberOfChildren is not zero, destroy the IP6 children instances in ChildHandleBuffer.
+ //
+ List = &IpSb->Children;
+ Context.ServiceBinding = ServiceBinding;
+ Context.NumberOfChildren = NumberOfChildren;
+ Context.ChildHandleBuffer = ChildHandleBuffer;
+ Status = NetDestroyLinkList (
+ List,
+ Ip6DestroyChildEntryInHandleBuffer,
+ &Context,
+ NULL
+ );
+ } else if (IsListEmpty (&IpSb->Children)) {
State = IpSb->State;
IpSb->State = IP6_SERVICE_DESTROY;
@@ -675,24 +710,10 @@ Ip6DriverBindingStop (
);
ASSERT_EFI_ERROR (Status);
FreePool (IpSb);
- } else {
- //
- // NumberOfChildren is not zero, destroy all IP6 children instances.
- //
- while (!IsListEmpty (&IpSb->Children)) {
- IpInstance = NET_LIST_HEAD (&IpSb->Children, IP6_PROTOCOL, Link);
- ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle);
- }
-
- if (IpSb->NumChildren != 0) {
- Status = EFI_DEVICE_ERROR;
- }
+ Status = EFI_SUCCESS;
}
-
+
Exit:
-
- gBS->RestoreTPL (OldTpl);
-
return Status;
}
@@ -830,7 +851,6 @@ Ip6ServiceBindingDestroyChild (
IP6_PROTOCOL *IpInstance;
EFI_IP6_PROTOCOL *Ip6;
EFI_TPL OldTpl;
- INTN State;
if ((This == NULL) || (ChildHandle == NULL)) {
return EFI_INVALID_PARAMETER;
@@ -868,13 +888,12 @@ Ip6ServiceBindingDestroyChild (
// when UDP driver is being stopped, it will destroy all
// the IP child it opens.
//
- if (IpInstance->State == IP6_STATE_DESTROY) {
+ if (IpInstance->InDestroy) {
gBS->RestoreTPL (OldTpl);
return EFI_SUCCESS;
}
- State = IpInstance->State;
- IpInstance->State = IP6_STATE_DESTROY;
+ IpInstance->InDestroy = TRUE;
//
// Close the Managed Network protocol.
@@ -900,12 +919,13 @@ Ip6ServiceBindingDestroyChild (
// will be called back before preceeding. If any packets not recycled,
// that means there is a resource leak.
//
+ gBS->RestoreTPL (OldTpl);
Status = gBS->UninstallProtocolInterface (
ChildHandle,
&gEfiIp6ProtocolGuid,
&IpInstance->Ip6Proto
);
-
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
@@ -935,7 +955,6 @@ Ip6ServiceBindingDestroyChild (
return EFI_SUCCESS;
ON_ERROR:
- IpInstance->State = State;
gBS->RestoreTPL (OldTpl);
return Status;
diff --git a/NetworkPkg/Ip6Dxe/Ip6Driver.h b/NetworkPkg/Ip6Dxe/Ip6Driver.h
index 4a23d836b8..d16ff48e2a 100644
--- a/NetworkPkg/Ip6Dxe/Ip6Driver.h
+++ b/NetworkPkg/Ip6Dxe/Ip6Driver.h
@@ -19,6 +19,13 @@
extern EFI_DRIVER_BINDING_PROTOCOL gIp6DriverBinding;
extern EFI_COMPONENT_NAME_PROTOCOL gIp6ComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gIp6ComponentName2;
+extern EFI_UNICODE_STRING_TABLE *gIp6ControllerNameTable;
+
+typedef struct {
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+}IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT;
/**
Clean up an IP6 service binding instance. It releases all
diff --git a/NetworkPkg/Ip6Dxe/Ip6If.c b/NetworkPkg/Ip6Dxe/Ip6If.c
index a934188479..280cd764f1 100644
--- a/NetworkPkg/Ip6Dxe/Ip6If.c
+++ b/NetworkPkg/Ip6Dxe/Ip6If.c
@@ -565,11 +565,7 @@ Ip6ReceiveFrame (
{
EFI_STATUS Status;
IP6_LINK_RX_TOKEN *Token;
-
- if (IpSb->InDestroy) {
- return EFI_INVALID_PARAMETER;
- }
-
+
NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
Token = &IpSb->RecvRequest;
diff --git a/NetworkPkg/Ip6Dxe/Ip6Impl.c b/NetworkPkg/Ip6Dxe/Ip6Impl.c
index 44e0392511..365495a5e4 100644
--- a/NetworkPkg/Ip6Dxe/Ip6Impl.c
+++ b/NetworkPkg/Ip6Dxe/Ip6Impl.c
@@ -635,7 +635,7 @@ EfiIp6Configure (
IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This);
IpSb = IpInstance->Service;
- if (IpSb->LinkLocalDadFail) {
+ if (IpSb->LinkLocalDadFail && Ip6ConfigData != NULL) {
return EFI_DEVICE_ERROR;
}
@@ -1777,10 +1777,6 @@ EfiIp6Cancel (
IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This);
IpSb = IpInstance->Service;
- if (IpSb->LinkLocalDadFail) {
- return EFI_DEVICE_ERROR;
- }
-
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
if (IpInstance->State != IP6_STATE_CONFIGED) {
diff --git a/NetworkPkg/Ip6Dxe/Ip6Impl.h b/NetworkPkg/Ip6Dxe/Ip6Impl.h
index 1241e63669..8f114bbb10 100644
--- a/NetworkPkg/Ip6Dxe/Ip6Impl.h
+++ b/NetworkPkg/Ip6Dxe/Ip6Impl.h
@@ -1,7 +1,7 @@
/** @file
Implementation of EFI_IP6_PROTOCOL protocol interfaces and type definitions.
- Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<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
@@ -68,7 +68,6 @@
//
#define IP6_STATE_UNCONFIGED 0
#define IP6_STATE_CONFIGED 1
-#define IP6_STATE_DESTROY 2
//
// The state of IP6 service. It starts from UNSTARTED. It transits
@@ -157,13 +156,13 @@ struct _IP6_PROTOCOL {
UINT32 GroupCount;
EFI_IP6_CONFIG_DATA ConfigData;
+ BOOLEAN InDestroy;
};
struct _IP6_SERVICE {
UINT32 Signature;
EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;
INTN State;
- BOOLEAN InDestroy;
//
// List of all the IP instances and interfaces, and default
diff --git a/NetworkPkg/Ip6Dxe/Ip6Nd.c b/NetworkPkg/Ip6Dxe/Ip6Nd.c
index d510f330c1..9f30f9b20e 100644
--- a/NetworkPkg/Ip6Dxe/Ip6Nd.c
+++ b/NetworkPkg/Ip6Dxe/Ip6Nd.c
@@ -821,7 +821,8 @@ Ip6OnDADFinished (
UINT16 OptBuf[4];
EFI_DHCP6_PACKET_OPTION *Oro;
EFI_DHCP6_RETRANSMISSION InfoReqReXmit;
-
+ EFI_IPv6_ADDRESS AllNodes;
+
IpSb = IpIf->Service;
AddrInfo = DadEntry->AddressInfo;
@@ -922,6 +923,11 @@ Ip6OnDADFinished (
RemoveEntryList (&DadEntry->Link);
FreePool (DadEntry);
//
+ // Leave link-scope all-nodes multicast address (FF02::1)
+ //
+ Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &AllNodes);
+ Ip6LeaveGroup (IpSb, &AllNodes);
+ //
// Disable IP operation since link-local address is a duplicate address.
//
IpSb->LinkLocalDadFail = TRUE;
diff --git a/NetworkPkg/IpSecDxe/ComponentName.c b/NetworkPkg/IpSecDxe/ComponentName.c
index e164d8bbb3..d68b175cc1 100644
--- a/NetworkPkg/IpSecDxe/ComponentName.c
+++ b/NetworkPkg/IpSecDxe/ComponentName.c
@@ -1,7 +1,7 @@
/** @file
UEFI Component Name(2) protocol implementation for IPsec driver.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<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
@@ -172,6 +172,17 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIpSecDriverNameTable[] =
}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIpSecControllerNameTable[] = {
+ {
+ "eng;en",
+ L"IPsec Controller"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
/**
Retrieves a Unicode string that is the user-readable name of the driver.
@@ -306,5 +317,35 @@ IpSecComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+
+ //
+ // ChildHandle must be NULL for a Device Driver
+ //
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver is currently managing ControllerHandle
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiIpSec2ProtocolGuid,
+ NULL,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mIpSecControllerNameTable,
+ ControllerName,
+ (BOOLEAN) (This == &gIpSecComponentName)
+ );
}
diff --git a/NetworkPkg/Mtftp6Dxe/ComponentName.c b/NetworkPkg/Mtftp6Dxe/ComponentName.c
index 72a5eb0582..f4327abcf9 100644
--- a/NetworkPkg/Mtftp6Dxe/ComponentName.c
+++ b/NetworkPkg/Mtftp6Dxe/ComponentName.c
@@ -1,7 +1,7 @@
/** @file
UEFI Component Name(2) protocol implementation for Mtftp6 driver.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<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
@@ -170,6 +170,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mMtftp6DriverNameT
}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gMtftp6ControllerNameTable = NULL;
+
/**
Retrieves a Unicode string that is the user-readable name of the driver.
@@ -227,6 +229,74 @@ Mtftp6ComponentNameGetDriverName (
}
/**
+ Update the component name for the Mtftp6 child handle.
+
+ @param Mtftp6[in] A pointer to the EFI_MTFTP6_PROTOCOL.
+
+
+ @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+
+**/
+EFI_STATUS
+UpdateName (
+ IN EFI_MTFTP6_PROTOCOL *Mtftp6
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 HandleName[128];
+ EFI_MTFTP6_MODE_DATA Mtftp6ModeData;
+ CHAR16 Address[sizeof"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
+
+ if (Mtftp6 == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Format the child name into the string buffer.
+ //
+ Status = Mtftp6->GetModeData (Mtftp6, &Mtftp6ModeData);
+ if (!EFI_ERROR (Status)) {
+ Status = NetLibIp6ToStr (&Mtftp6ModeData.ConfigData.ServerIp, Address, sizeof(Address));
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ UnicodeSPrint (HandleName, sizeof (HandleName),
+ L"MTFTPv6(ServerIp=%s, InitialServerPort=%d)",
+ Address,
+ Mtftp6ModeData.ConfigData.InitialServerPort
+ );
+ } else {
+ UnicodeSPrint (HandleName, 0x100, L"MTFTPv6(%r)", Status);
+ }
+
+ if (gMtftp6ControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gMtftp6ControllerNameTable);
+ gMtftp6ControllerNameTable = NULL;
+ }
+
+ Status = AddUnicodeString2 (
+ "eng",
+ gMtftp6ComponentName.SupportedLanguages,
+ &gMtftp6ControllerNameTable,
+ HandleName,
+ TRUE
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return AddUnicodeString2 (
+ "en",
+ gMtftp6ComponentName2.SupportedLanguages,
+ &gMtftp6ControllerNameTable,
+ HandleName,
+ FALSE
+ );
+}
+
+
+/**
Retrieves a Unicode string that is the user-readable name of the controller
that is being managed by a driver.
@@ -304,5 +374,57 @@ Mtftp6ComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+ EFI_MTFTP6_PROTOCOL *Mtftp6;
+
+ //
+ // Only provide names for child handles.
+ //
+ if (ChildHandle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver produced ChildHandle
+ //
+ Status = EfiTestChildHandle (
+ ControllerHandle,
+ ChildHandle,
+ &gEfiUdp6ProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Retrieve an instance of a produced protocol from ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiMtftp6ProtocolGuid,
+ (VOID **)&Mtftp6,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Update the component name for this child handle.
+ //
+ Status = UpdateName (Mtftp6);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ gMtftp6ControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gMtftp6ComponentName)
+ );
}
+
diff --git a/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.c b/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.c
index 432eea9cd4..79cd6bae5a 100644
--- a/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.c
+++ b/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.c
@@ -98,7 +98,6 @@ Mtftp6CreateService (
Mtftp6Srv->Signature = MTFTP6_SERVICE_SIGNATURE;
Mtftp6Srv->Controller = Controller;
Mtftp6Srv->Image = Image;
- Mtftp6Srv->InDestroy = FALSE;
Mtftp6Srv->ChildrenNum = 0;
CopyMem (
@@ -238,6 +237,44 @@ Mtftp6CreateInstance (
/**
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.
+
+ @param[in] Entry The entry to be removed.
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
+
+ @retval EFI_SUCCESS The entry has been removed successfully.
+ @retval Others Fail to remove the entry.
+
+**/
+EFI_STATUS
+Mtftp6DestroyChildEntryInHandleBuffer (
+ IN LIST_ENTRY *Entry,
+ IN VOID *Context
+)
+{
+ MTFTP6_INSTANCE *Instance;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+
+ if (Entry == NULL || Context == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Instance = NET_LIST_USER_STRUCT_S (Entry, MTFTP6_INSTANCE, Link, MTFTP6_INSTANCE_SIGNATURE);
+ ServiceBinding = ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;
+ NumberOfChildren = ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;
+ ChildHandleBuffer = ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;
+
+ if (!NetIsInHandleBuffer (Instance->Handle, NumberOfChildren, ChildHandleBuffer)) {
+ return EFI_SUCCESS;
+ }
+
+ return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
+}
+
+
+/**
This is the declaration of an EFI image entry point. This entry point is
the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
both device drivers and bus drivers.
@@ -429,20 +466,20 @@ Mtftp6DriverBindingStop (
IN EFI_HANDLE *ChildHandleBuffer
)
{
- EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
- MTFTP6_SERVICE *Service;
- MTFTP6_INSTANCE *Instance;
- EFI_HANDLE NicHandle;
- EFI_STATUS Status;
- EFI_TPL OldTpl;
-
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ MTFTP6_SERVICE *Service;
+ EFI_HANDLE NicHandle;
+ EFI_STATUS Status;
+ LIST_ENTRY *List;
+ MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
+
//
// Locate the Nic handle to retrieve the Mtftp6 private data.
//
NicHandle = NetLibGetNicHandle (Controller, &gEfiUdp6ProtocolGuid);
if (NicHandle == NULL) {
- return EFI_DEVICE_ERROR;
+ return EFI_SUCCESS;
}
Status = gBS->OpenProtocol (
@@ -460,18 +497,26 @@ Mtftp6DriverBindingStop (
Service = MTFTP6_SERVICE_FROM_THIS (ServiceBinding);
- if (Service->InDestroy) {
- return EFI_SUCCESS;
+ if (!IsListEmpty (&Service->Children)) {
+ //
+ // Destroy the Mtftp6 child instance in ChildHandleBuffer.
+ //
+ List = &Service->Children;
+ Context.ServiceBinding = ServiceBinding;
+ Context.NumberOfChildren = NumberOfChildren;
+ Context.ChildHandleBuffer = ChildHandleBuffer;
+ Status = NetDestroyLinkList (
+ List,
+ Mtftp6DestroyChildEntryInHandleBuffer,
+ &Context,
+ NULL
+ );
}
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-
- if (NumberOfChildren == 0) {
+ if (NumberOfChildren == 0 && IsListEmpty (&Service->Children)) {
//
// Destroy the Mtftp6 service if there is no Mtftp6 child instance left.
//
- Service->InDestroy = TRUE;
-
gBS->UninstallProtocolInterface (
NicHandle,
&gEfiMtftp6ServiceBindingProtocolGuid,
@@ -479,22 +524,9 @@ Mtftp6DriverBindingStop (
);
Mtftp6DestroyService (Service);
-
- } else {
- //
- // Destroy the Mtftp6 child instance one by one.
- //
- while (!IsListEmpty (&Service->Children)) {
- Instance = NET_LIST_HEAD (&Service->Children, MTFTP6_INSTANCE, Link);
- Mtftp6ServiceBindingDestroyChild (ServiceBinding, Instance->Handle);
- }
-
- if (Service->ChildrenNum != 0) {
- Status = EFI_DEVICE_ERROR;
- }
+ Status = EFI_SUCCESS;
}
- gBS->RestoreTPL (OldTpl);
return Status;
}
@@ -674,15 +706,34 @@ Mtftp6ServiceBindingDestroyChild (
ChildHandle
);
+ if (Instance->UdpIo != NULL) {
+ gBS->CloseProtocol (
+ Instance->UdpIo->UdpHandle,
+ &gEfiUdp6ProtocolGuid,
+ gMtftp6DriverBinding.DriverBindingHandle,
+ Instance->Handle
+ );
+ }
+
+ if (Instance->McastUdpIo != NULL) {
+ gBS->CloseProtocol (
+ Instance->McastUdpIo->UdpHandle,
+ &gEfiUdp6ProtocolGuid,
+ gMtftp6DriverBinding.DriverBindingHandle,
+ Instance->Handle
+ );
+ }
+
//
// Uninstall the MTFTP6 protocol first to enable a top down destruction.
//
+ gBS->RestoreTPL (OldTpl);
Status = gBS->UninstallProtocolInterface (
ChildHandle,
&gEfiMtftp6ProtocolGuid,
Mtftp6
);
-
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
if (EFI_ERROR (Status)) {
Instance->InDestroy = FALSE;
gBS->RestoreTPL (OldTpl);
@@ -695,9 +746,9 @@ Mtftp6ServiceBindingDestroyChild (
RemoveEntryList (&Instance->Link);
Service->ChildrenNum --;
- Mtftp6DestroyInstance (Instance);
-
gBS->RestoreTPL (OldTpl);
+ Mtftp6DestroyInstance (Instance);
+
return EFI_SUCCESS;
}
diff --git a/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.h b/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.h
index 3e3165b5e4..55ac1ddffb 100644
--- a/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.h
+++ b/NetworkPkg/Mtftp6Dxe/Mtftp6Driver.h
@@ -2,7 +2,7 @@
Driver Binding functions and Service Binding functions
declaration for Mtftp6 Driver.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<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
@@ -21,6 +21,7 @@
extern EFI_COMPONENT_NAME_PROTOCOL gMtftp6ComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gMtftp6ComponentName2;
+extern EFI_UNICODE_STRING_TABLE *gMtftp6ControllerNameTable;
/**
Test to see if this driver supports Controller. This service
diff --git a/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.c b/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.c
index 4a4e5b192c..9b08455ef3 100644
--- a/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.c
+++ b/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.c
@@ -197,6 +197,19 @@ EfiMtftp6Configure (
UDP_IO_UDP6_VERSION,
NULL
);
+ if (Instance->UdpIo != NULL) {
+ Status = gBS->OpenProtocol (
+ Instance->UdpIo->UdpHandle,
+ &gEfiUdp6ProtocolGuid,
+ (VOID **) &Udp6,
+ Service->Image,
+ Instance->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+ }
}
if (Instance->UdpIo == NULL) {
@@ -626,8 +639,6 @@ EfiMtftp6Poll (
//
if (Instance->Config == NULL) {
return EFI_NOT_STARTED;
- } else if (Instance->InDestroy) {
- return EFI_DEVICE_ERROR;
}
Udp6 = Instance->UdpIo->Protocol.Udp6;
diff --git a/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.h b/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.h
index 68fa0da115..6b1ce7f853 100644
--- a/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.h
+++ b/NetworkPkg/Mtftp6Dxe/Mtftp6Impl.h
@@ -29,6 +29,7 @@
#include <Library/UefiLib.h>
#include <Library/BaseLib.h>
#include <Library/NetLib.h>
+#include <Library/PrintLib.h>
typedef struct _MTFTP6_SERVICE MTFTP6_SERVICE;
typedef struct _MTFTP6_INSTANCE MTFTP6_INSTANCE;
@@ -117,9 +118,14 @@ struct _MTFTP6_SERVICE {
// mtftp driver and udp driver.
//
UDP_IO *DummyUdpIo;
- BOOLEAN InDestroy;
};
+typedef struct {
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+} MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT;
+
/**
Returns the current operating mode data for the MTFTP6 instance.
diff --git a/NetworkPkg/Mtftp6Dxe/Mtftp6Rrq.c b/NetworkPkg/Mtftp6Dxe/Mtftp6Rrq.c
index 7fc613a665..4a481f4b46 100644
--- a/NetworkPkg/Mtftp6Dxe/Mtftp6Rrq.c
+++ b/NetworkPkg/Mtftp6Dxe/Mtftp6Rrq.c
@@ -453,6 +453,7 @@ Mtftp6RrqHandleOack (
MTFTP6_EXT_OPTION_INFO ExtInfo;
EFI_STATUS Status;
INTN Expected;
+ EFI_UDP6_PROTOCOL *Udp6;
*IsCompleted = FALSE;
@@ -555,6 +556,21 @@ Mtftp6RrqHandleOack (
UDP_IO_UDP6_VERSION,
Instance
);
+ if (Instance->McastUdpIo != NULL) {
+ Status = gBS->OpenProtocol (
+ Instance->McastUdpIo->UdpHandle,
+ &gEfiUdp6ProtocolGuid,
+ (VOID **) &Udp6,
+ Instance->Service->Image,
+ Instance->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (EFI_ERROR (Status)) {
+ UdpIoFreeIo (Instance->McastUdpIo);
+ Instance->McastUdpIo = NULL;
+ return EFI_DEVICE_ERROR;
+ }
+ }
}
if (Instance->McastUdpIo == NULL) {
diff --git a/NetworkPkg/Mtftp6Dxe/Mtftp6Support.c b/NetworkPkg/Mtftp6Dxe/Mtftp6Support.c
index 24ce0e85ba..f5b22313ee 100644
--- a/NetworkPkg/Mtftp6Dxe/Mtftp6Support.c
+++ b/NetworkPkg/Mtftp6Dxe/Mtftp6Support.c
@@ -1,7 +1,7 @@
/** @file
Mtftp6 support functions implementation.
- Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<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
@@ -903,6 +903,12 @@ Mtftp6OperationClean (
}
if (Instance->McastUdpIo != NULL) {
+ gBS->CloseProtocol (
+ Instance->McastUdpIo->UdpHandle,
+ &gEfiUdp6ProtocolGuid,
+ Instance->McastUdpIo->Image,
+ Instance->Handle
+ );
UdpIoFreeIo (Instance->McastUdpIo);
Instance->McastUdpIo = NULL;
}
diff --git a/NetworkPkg/TcpDxe/ComponentName.c b/NetworkPkg/TcpDxe/ComponentName.c
index f1e0e62f73..9b4dada6a0 100644
--- a/NetworkPkg/TcpDxe/ComponentName.c
+++ b/NetworkPkg/TcpDxe/ComponentName.c
@@ -2,7 +2,7 @@
Implementation of protocols EFI_COMPONENT_NAME_PROTOCOL and
EFI_COMPONENT_NAME2_PROTOCOL.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<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
@@ -170,6 +170,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mTcpDriverNameTabl
}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gTcpControllerNameTable = NULL;
+
/**
Retrieves a Unicode string that is the user-readable name of the driver.
@@ -225,6 +227,142 @@ TcpComponentNameGetDriverName (
}
/**
+ Update the component name for the Tcp4 child handle.
+
+ @param Tcp4[in] A pointer to the EFI_TCP4_PROTOCOL.
+
+
+ @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+
+**/
+EFI_STATUS
+UpdateTcp4Name (
+ IN EFI_TCP4_PROTOCOL *Tcp4
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 HandleName[80];
+ EFI_TCP4_CONFIG_DATA Tcp4ConfigData;
+
+ if (Tcp4 == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Format the child name into the string buffer as:
+ // TCPv4 (SrcPort=59, DestPort=60, ActiveFlag=TRUE)
+ //
+ Status = Tcp4->GetModeData (Tcp4, NULL, &Tcp4ConfigData, NULL, NULL, NULL);
+ if (!EFI_ERROR (Status)) {
+ UnicodeSPrint (HandleName, sizeof (HandleName),
+ L"TCPv4 (SrcPort=%d, DestPort=&d, ActiveFlag=%s)",
+ Tcp4ConfigData.AccessPoint.StationPort,
+ Tcp4ConfigData.AccessPoint.RemotePort,
+ (Tcp4ConfigData.AccessPoint.ActiveFlag ? L"TRUE" : L"FALSE")
+ );
+ } if (Status == EFI_NOT_STARTED) {
+ UnicodeSPrint (
+ HandleName,
+ sizeof (HandleName),
+ L"TCPv4 (Not started)"
+ );
+ } else {
+ return Status;
+ }
+
+ if (gTcpControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gTcpControllerNameTable);
+ gTcpControllerNameTable = NULL;
+ }
+
+ Status = AddUnicodeString2 (
+ "eng",
+ gTcpComponentName.SupportedLanguages,
+ &gTcpControllerNameTable,
+ HandleName,
+ TRUE
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return AddUnicodeString2 (
+ "en",
+ gTcpComponentName2.SupportedLanguages,
+ &gTcpControllerNameTable,
+ HandleName,
+ FALSE
+ );
+}
+
+/**
+ Update the component name for the Tcp6 child handle.
+
+ @param Tcp6[in] A pointer to the EFI_TCP6_PROTOCOL.
+
+
+ @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+
+**/
+EFI_STATUS
+UpdateTcp6Name (
+ IN EFI_TCP6_PROTOCOL *Tcp6
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 HandleName[80];
+ EFI_TCP6_CONFIG_DATA Tcp6ConfigData;
+
+ if (Tcp6 == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Format the child name into the string buffer.
+ //
+ Status = Tcp6->GetModeData (Tcp6, NULL, &Tcp6ConfigData, NULL, NULL, NULL);
+ if (!EFI_ERROR (Status)) {
+ UnicodeSPrint (HandleName, sizeof (HandleName),
+ L"TCPv6(SrcPort=%d, DestPort=%d, ActiveFlag=%d)",
+ Tcp6ConfigData.AccessPoint.StationPort,
+ Tcp6ConfigData.AccessPoint.RemotePort,
+ Tcp6ConfigData.AccessPoint.ActiveFlag
+ );
+ } else if (Status == EFI_NOT_STARTED) {
+ UnicodeSPrint (HandleName, sizeof (HandleName), L"TCPv6(Not started)");
+ } else {
+ return Status;
+ }
+
+
+ if (gTcpControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gTcpControllerNameTable);
+ gTcpControllerNameTable = NULL;
+ }
+
+ Status = AddUnicodeString2 (
+ "eng",
+ gTcpComponentName.SupportedLanguages,
+ &gTcpControllerNameTable,
+ HandleName,
+ TRUE
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return AddUnicodeString2 (
+ "en",
+ gTcpComponentName2.SupportedLanguages,
+ &gTcpControllerNameTable,
+ HandleName,
+ FALSE
+ );
+}
+
+/**
Retrieves a Unicode string that is the user-readable name of the controller
that is being managed by a driver.
@@ -300,5 +438,89 @@ TcpComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
+ EFI_STATUS Status;
+ EFI_TCP4_PROTOCOL *Tcp4;
+ EFI_TCP6_PROTOCOL *Tcp6;
+
+ //
+ // Only provide names for child handles.
+ //
+ if (ChildHandle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver produced ChildHandle
+ //
+ Status = EfiTestChildHandle (
+ ControllerHandle,
+ ChildHandle,
+ &gEfiIp6ProtocolGuid
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Retrieve an instance of a produced protocol from ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiTcp6ProtocolGuid,
+ (VOID **)&Tcp6,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Update the component name for this child handle.
+ //
+ Status = UpdateTcp6Name (Tcp6);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ //
+ // Make sure this driver is currently managing ControllHandle
+ //
+ Status = EfiTestChildHandle (
+ ControllerHandle,
+ ChildHandle,
+ &gEfiIp4ProtocolGuid
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Retrieve an instance of a produced protocol from ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiTcp4ProtocolGuid,
+ (VOID **)&Tcp4,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Update the component name for this child handle.
+ //
+ Status = UpdateTcp4Name (Tcp4);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ gTcpControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gTcpComponentName)
+ );
}
+
diff --git a/NetworkPkg/TcpDxe/SockInterface.c b/NetworkPkg/TcpDxe/SockInterface.c
index 075e9ada6a..4abda74220 100644
--- a/NetworkPkg/TcpDxe/SockInterface.c
+++ b/NetworkPkg/TcpDxe/SockInterface.c
@@ -146,11 +146,11 @@ SockDestroyChild (
ASSERT ((Sock != NULL) && (Sock->ProtoHandler != NULL));
- if (Sock->IsDestroyed) {
+ if (Sock->InDestroy) {
return EFI_SUCCESS;
}
- Sock->IsDestroyed = TRUE;
+ Sock->InDestroy = TRUE;
Status = EfiAcquireLockOrFail (&(Sock->Lock));
if (EFI_ERROR (Status)) {
@@ -177,7 +177,7 @@ SockDestroyChild (
Status)
);
- Sock->IsDestroyed = FALSE;
+ Sock->InDestroy = FALSE;
} else if (SOCK_IS_CONFIGURED (Sock)) {
SockConnFlush (Sock);
diff --git a/NetworkPkg/TcpDxe/Socket.h b/NetworkPkg/TcpDxe/Socket.h
index 9e2d907150..5a63047f90 100644
--- a/NetworkPkg/TcpDxe/Socket.h
+++ b/NetworkPkg/TcpDxe/Socket.h
@@ -477,7 +477,7 @@ struct _TCP_SOCKET {
SOCK_BUFFER SndBuffer; ///< Send buffer of application's data
SOCK_BUFFER RcvBuffer; ///< Receive buffer of received data
EFI_STATUS SockError; ///< The error returned by low layer protocol
- BOOLEAN IsDestroyed;
+ BOOLEAN InDestroy;
//
// Fields used to manage the connection request
diff --git a/NetworkPkg/TcpDxe/TcpDispatcher.c b/NetworkPkg/TcpDxe/TcpDispatcher.c
index 3e6d34c63f..d3d2cb1c3a 100644
--- a/NetworkPkg/TcpDxe/TcpDispatcher.c
+++ b/NetworkPkg/TcpDxe/TcpDispatcher.c
@@ -354,7 +354,16 @@ TcpAttachPcb (
TCP_CB *Tcb;
TCP_PROTO_DATA *ProtoData;
IP_IO *IpIo;
+ EFI_STATUS Status;
+ VOID *Ip;
+ EFI_GUID *IpProtocolGuid;
+ if (Sk->IpVersion == IP_VERSION_4) {
+ IpProtocolGuid = &gEfiIp4ProtocolGuid;
+ } else {
+ IpProtocolGuid = &gEfiIp6ProtocolGuid;
+ }
+
Tcb = AllocateZeroPool (sizeof (TCP_CB));
if (Tcb == NULL) {
@@ -377,6 +386,22 @@ TcpAttachPcb (
return EFI_OUT_OF_RESOURCES;
}
+ //
+ // Open the new created IP instance BY_CHILD.
+ //
+ Status = gBS->OpenProtocol (
+ Tcb->IpInfo->ChildHandle,
+ IpProtocolGuid,
+ &Ip,
+ IpIo->Image,
+ Sk->SockHandle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (EFI_ERROR (Status)) {
+ IpIoRemoveIp (IpIo, Tcb->IpInfo);
+ return Status;
+ }
+
InitializeListHead (&Tcb->List);
InitializeListHead (&Tcb->SndQue);
InitializeListHead (&Tcb->RcvQue);
@@ -401,7 +426,14 @@ TcpDetachPcb (
{
TCP_PROTO_DATA *ProtoData;
TCP_CB *Tcb;
+ EFI_GUID *IpProtocolGuid;
+ if (Sk->IpVersion == IP_VERSION_4) {
+ IpProtocolGuid = &gEfiIp4ProtocolGuid;
+ } else {
+ IpProtocolGuid = &gEfiIp6ProtocolGuid;
+ }
+
ProtoData = (TCP_PROTO_DATA *) Sk->ProtoReserved;
Tcb = ProtoData->TcpPcb;
@@ -409,6 +441,16 @@ TcpDetachPcb (
TcpFlushPcb (Tcb);
+ //
+ // Close the IP protocol.
+ //
+ gBS->CloseProtocol (
+ Tcb->IpInfo->ChildHandle,
+ IpProtocolGuid,
+ ProtoData->TcpService->IpIo->Image,
+ Sk->SockHandle
+ );
+
IpIoRemoveIp (ProtoData->TcpService->IpIo, Tcb->IpInfo);
FreePool (Tcb);
diff --git a/NetworkPkg/TcpDxe/TcpDriver.c b/NetworkPkg/TcpDxe/TcpDriver.c
index c9ac10c758..4e697b1f4e 100644
--- a/NetworkPkg/TcpDxe/TcpDriver.c
+++ b/NetworkPkg/TcpDxe/TcpDriver.c
@@ -1,7 +1,7 @@
/** @file
The driver binding and service binding protocol for the TCP driver.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<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
@@ -323,6 +323,7 @@ ON_ERROR:
if (TcpServiceData->IpIo != NULL) {
IpIoDestroy (TcpServiceData->IpIo);
+ TcpServiceData->IpIo = NULL;
}
FreePool (TcpServiceData);
@@ -331,13 +332,52 @@ ON_ERROR:
}
/**
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.
+
+ @param[in] Entry The entry to be removed.
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
+
+ @retval EFI_SUCCESS The entry has been removed successfully.
+ @retval Others Fail to remove the entry.
+
+**/
+EFI_STATUS
+TcpDestroyChildEntryInHandleBuffer (
+ IN LIST_ENTRY *Entry,
+ IN VOID *Context
+)
+{
+ SOCKET *Sock;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+
+ if (Entry == NULL || Context == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Sock = NET_LIST_USER_STRUCT_S (Entry, SOCKET, Link, SOCK_SIGNATURE);
+ ServiceBinding = ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;
+ NumberOfChildren = ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;
+ ChildHandleBuffer = ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;
+
+ if (!NetIsInHandleBuffer (Sock->SockHandle, NumberOfChildren, ChildHandleBuffer)) {
+ return EFI_SUCCESS;
+ }
+
+ return ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle);
+}
+
+/**
Destroy a TCP6 or TCP4 service binding instance. It will release all
the resources allocated by the instance.
@param[in] Controller Controller handle of device to bind driver to.
@param[in] ImageHandle The TCP driver's image handle.
- @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number
+ @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number
of children is zero stop the entire bus driver.
+ @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
+ if NumberOfChildren is 0.
@param[in] IpVersion IP_VERSION_4 or IP_VERSION_6
@retval EFI_SUCCESS The resources used by the instance were cleaned up.
@@ -349,6 +389,7 @@ TcpDestroyService (
IN EFI_HANDLE Controller,
IN EFI_HANDLE ImageHandle,
IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer, OPTIONAL
IN UINT8 IpVersion
)
{
@@ -358,7 +399,8 @@ TcpDestroyService (
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
TCP_SERVICE_DATA *TcpServiceData;
EFI_STATUS Status;
- SOCKET *Sock;
+ LIST_ENTRY *List;
+ TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6));
@@ -372,7 +414,7 @@ TcpDestroyService (
NicHandle = NetLibGetNicHandle (Controller, IpProtocolGuid);
if (NicHandle == NULL) {
- return EFI_NOT_FOUND;
+ return EFI_SUCCESS;
}
Status = gBS->OpenProtocol (
@@ -389,7 +431,18 @@ TcpDestroyService (
TcpServiceData = TCP_SERVICE_FROM_THIS (ServiceBinding);
- if (NumberOfChildren == 0) {
+ if (NumberOfChildren != 0) {
+ List = &TcpServiceData->SocketList;
+ Context.ServiceBinding = ServiceBinding;
+ Context.NumberOfChildren = NumberOfChildren;
+ Context.ChildHandleBuffer = ChildHandleBuffer;
+ Status = NetDestroyLinkList (
+ List,
+ TcpDestroyChildEntryInHandleBuffer,
+ &Context,
+ NULL
+ );
+ } else if (IsListEmpty (&TcpServiceData->SocketList)) {
//
// Uninstall TCP servicebinding protocol
//
@@ -404,6 +457,7 @@ TcpDestroyService (
// Destroy the IpIO consumed by TCP driver
//
IpIoDestroy (TcpServiceData->IpIo);
+ TcpServiceData->IpIo = NULL;
//
// Destroy the heartbeat timer.
@@ -419,16 +473,11 @@ TcpDestroyService (
// Release the TCP service data
//
FreePool (TcpServiceData);
- } else {
-
- while (!IsListEmpty (&TcpServiceData->SocketList)) {
- Sock = NET_LIST_HEAD (&TcpServiceData->SocketList, SOCKET, Link);
- ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle);
- }
+ Status = EFI_SUCCESS;
}
- return EFI_SUCCESS;
+ return Status;
}
/**
@@ -595,6 +644,7 @@ TcpDriverBindingStop (
ControllerHandle,
This->DriverBindingHandle,
NumberOfChildren,
+ ChildHandleBuffer,
IP_VERSION_4
);
@@ -602,6 +652,7 @@ TcpDriverBindingStop (
ControllerHandle,
This->DriverBindingHandle,
NumberOfChildren,
+ ChildHandleBuffer,
IP_VERSION_6
);
@@ -839,14 +890,11 @@ TcpServiceBindingDestroyChild (
EFI_STATUS Status;
VOID *Tcp;
SOCKET *Sock;
- EFI_TPL OldTpl;
if (NULL == This || NULL == ChildHandle) {
return EFI_INVALID_PARAMETER;
}
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-
//
// retrieve the Tcp4 protocol from ChildHandle
//
@@ -885,7 +933,5 @@ TcpServiceBindingDestroyChild (
SockDestroyChild (Sock);
}
- gBS->RestoreTPL (OldTpl);
-
return Status;
}
diff --git a/NetworkPkg/TcpDxe/TcpMain.h b/NetworkPkg/TcpDxe/TcpMain.h
index 69c764cde1..bd4434e26b 100644
--- a/NetworkPkg/TcpDxe/TcpMain.h
+++ b/NetworkPkg/TcpDxe/TcpMain.h
@@ -2,7 +2,7 @@
Declaration of protocol interfaces in EFI_TCP4_PROTOCOL and EFI_TCP6_PROTOCOL.
It is the common head file for all Tcp*.c in TCP driver.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<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
@@ -21,6 +21,7 @@
#include <Protocol/DriverBinding.h>
#include <Library/IpIoLib.h>
#include <Library/DevicePathLib.h>
+#include <Library/PrintLib.h>
#include "Socket.h"
#include "TcpProto.h"
@@ -32,6 +33,7 @@ extern UINT16 mTcp6RandomPort;
extern CHAR16 *mTcpStateName[];
extern EFI_COMPONENT_NAME_PROTOCOL gTcpComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gTcpComponentName2;
+extern EFI_UNICODE_STRING_TABLE *gTcpControllerNameTable;
extern LIST_ENTRY mTcpRunQue;
extern LIST_ENTRY mTcpListenQue;
@@ -90,6 +92,12 @@ typedef struct _TCP4_ROUTE_INFO {
EFI_IPv4_ADDRESS *GatewayAddress;
} TCP4_ROUTE_INFO;
+typedef struct {
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+} TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT;
+
//
// EFI_TCP4_PROTOCOL definitions.
//
diff --git a/NetworkPkg/Udp6Dxe/ComponentName.c b/NetworkPkg/Udp6Dxe/ComponentName.c
index 2511465187..93c2003f34 100644
--- a/NetworkPkg/Udp6Dxe/ComponentName.c
+++ b/NetworkPkg/Udp6Dxe/ComponentName.c
@@ -1,7 +1,7 @@
/** @file
UEFI Component Name(2) protocol implementation for UDP6 driver.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<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
@@ -174,6 +174,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUdp6DriverNameTable[] =
}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gUdp6ControllerNameTable = NULL;
+
/**
Retrieves a Unicode string that is the user-readable name of the driver.
@@ -231,6 +233,70 @@ Udp6ComponentNameGetDriverName (
}
/**
+ Update the component name for the Udp6 child handle.
+
+ @param Udp6[in] A pointer to the EFI_UDP6_PROTOCOL.
+
+
+ @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid.
+
+**/
+EFI_STATUS
+UpdateName (
+ IN EFI_UDP6_PROTOCOL *Udp6
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 HandleName[64];
+ EFI_UDP6_CONFIG_DATA Udp6ConfigData;
+
+ if (Udp6 == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Format the child name into the string buffer.
+ //
+ Status = Udp6->GetModeData (Udp6, &Udp6ConfigData, NULL, NULL, NULL);
+ if (!EFI_ERROR (Status)) {
+ UnicodeSPrint (HandleName, sizeof (HandleName),
+ L"UDPv6 (SrcPort=%d, DestPort=%d)",
+ Udp6ConfigData.StationPort,
+ Udp6ConfigData.RemotePort
+ );
+ } else if (Status == EFI_NOT_STARTED) {
+ UnicodeSPrint (HandleName, sizeof (HandleName), L"UDPv6 (Not started)");
+ } else {
+ UnicodeSPrint (HandleName, sizeof (HandleName), L"UDPv6 (%r)", Status);
+ }
+
+ if (gUdp6ControllerNameTable != NULL) {
+ FreeUnicodeStringTable (gUdp6ControllerNameTable);
+ gUdp6ControllerNameTable = NULL;
+ }
+
+ Status = AddUnicodeString2 (
+ "eng",
+ gUdp6ComponentName.SupportedLanguages,
+ &gUdp6ControllerNameTable,
+ HandleName,
+ TRUE
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return AddUnicodeString2 (
+ "en",
+ gUdp6ComponentName2.SupportedLanguages,
+ &gUdp6ControllerNameTable,
+ HandleName,
+ FALSE
+ );
+}
+
+/**
Retrieves a Unicode string that is the user-readable name of the controller
that is being managed by a driver.
@@ -308,6 +374,56 @@ Udp6ComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
-}
+ EFI_STATUS Status;
+ EFI_UDP6_PROTOCOL *Udp6;
+
+ //
+ // Only provide names for child handles.
+ //
+ if (ChildHandle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver produced ChildHandle
+ //
+ Status = EfiTestChildHandle (
+ ControllerHandle,
+ ChildHandle,
+ &gEfiIp6ProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Retrieve an instance of a produced protocol from ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiUdp6ProtocolGuid,
+ (VOID **)&Udp6,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Update the component name for this child handle.
+ //
+ Status = UpdateName (Udp6);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ gUdp6ControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gUdp6ComponentName)
+ );
+}
diff --git a/NetworkPkg/Udp6Dxe/Udp6Driver.c b/NetworkPkg/Udp6Dxe/Udp6Driver.c
index 1726ebbde4..62c2b9affd 100644
--- a/NetworkPkg/Udp6Dxe/Udp6Driver.c
+++ b/NetworkPkg/Udp6Dxe/Udp6Driver.c
@@ -1,7 +1,7 @@
/** @file
Driver Binding functions and Service Binding functions for the Network driver module.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<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
@@ -179,6 +179,43 @@ EXIT:
}
/**
+ Callback function which provided by user to remove one node in NetDestroyLinkList process.
+
+ @param[in] Entry The entry to be removed.
+ @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
+
+ @retval EFI_SUCCESS The entry has been removed successfully.
+ @retval Others Fail to remove the entry.
+
+**/
+EFI_STATUS
+Udp6DestroyChildEntryInHandleBuffer (
+ IN LIST_ENTRY *Entry,
+ IN VOID *Context
+)
+{
+ UDP6_INSTANCE_DATA *Instance;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+
+ if (Entry == NULL || Context == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Instance = NET_LIST_USER_STRUCT_S (Entry, UDP6_INSTANCE_DATA, Link, UDP6_INSTANCE_DATA_SIGNATURE);
+ ServiceBinding = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;
+ NumberOfChildren = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;
+ ChildHandleBuffer = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;
+
+ if (!NetIsInHandleBuffer (Instance->ChildHandle, NumberOfChildren, ChildHandleBuffer)) {
+ return EFI_SUCCESS;
+ }
+
+ return ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);
+}
+
+/**
Stop this driver on ControllerHandle.
This service is called by the EFI boot service DisconnectController(). In order to
@@ -211,14 +248,15 @@ Udp6DriverBindingStop (
EFI_HANDLE NicHandle;
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
UDP6_SERVICE_DATA *Udp6Service;
- UDP6_INSTANCE_DATA *Instance;
+ LIST_ENTRY *List;
+ UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
//
// Find the NicHandle where UDP6 ServiceBinding Protocol is installed.
//
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp6ProtocolGuid);
if (NicHandle == NULL) {
- return EFI_DEVICE_ERROR;
+ return EFI_SUCCESS;
}
//
@@ -238,8 +276,21 @@ Udp6DriverBindingStop (
Udp6Service = UDP6_SERVICE_DATA_FROM_THIS (ServiceBinding);
- if (NumberOfChildren == 0) {
-
+ if (NumberOfChildren != 0) {
+ //
+ // NumberOfChildren is not zero, destroy the children instances in ChildHandleBuffer.
+ //
+ List = &Udp6Service->ChildrenList;
+ Context.ServiceBinding = ServiceBinding;
+ Context.NumberOfChildren = NumberOfChildren;
+ Context.ChildHandleBuffer = ChildHandleBuffer;
+ Status = NetDestroyLinkList (
+ List,
+ Udp6DestroyChildEntryInHandleBuffer,
+ &Context,
+ NULL
+ );
+ } else if (IsListEmpty (&Udp6Service->ChildrenList)) {
gBS->UninstallMultipleProtocolInterfaces (
NicHandle,
&gEfiUdp6ServiceBindingProtocolGuid,
@@ -252,13 +303,8 @@ Udp6DriverBindingStop (
Udp6CleanService (Udp6Service);
FreePool (Udp6Service);
- } else {
-
- while (!IsListEmpty (&Udp6Service->ChildrenList)) {
- Instance = NET_LIST_HEAD (&Udp6Service->ChildrenList, UDP6_INSTANCE_DATA, Link);
- Status = ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);
- }
+ Status = EFI_SUCCESS;
}
return Status;
@@ -351,6 +397,21 @@ Udp6ServiceBindingCreateChild (
goto ON_ERROR;
}
+ //
+ // Open this instance's Ip6 protocol in the IpInfo BY_CHILD.
+ //
+ Status = gBS->OpenProtocol (
+ Instance->IpInfo->ChildHandle,
+ &gEfiIp6ProtocolGuid,
+ (VOID **) &Ip6,
+ gUdp6DriverBinding.DriverBindingHandle,
+ Instance->ChildHandle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
//
@@ -440,17 +501,17 @@ Udp6ServiceBindingDestroyChild (
Instance = UDP6_INSTANCE_DATA_FROM_THIS (Udp6Proto);
- if (Instance->Destroyed) {
+ if (Instance->InDestroy) {
return EFI_SUCCESS;
}
//
// Use the Destroyed flag to avoid the re-entering of the following code.
//
- Instance->Destroyed = TRUE;
+ Instance->InDestroy = TRUE;
//
- // Close the Ip6 protocol.
+ // Close the Ip6 protocol on the default IpIo.
//
gBS->CloseProtocol (
Udp6Service->IpIo->ChildHandle,
@@ -458,6 +519,15 @@ Udp6ServiceBindingDestroyChild (
gUdp6DriverBinding.DriverBindingHandle,
Instance->ChildHandle
);
+ //
+ // Close the Ip6 protocol on this instance's IpInfo.
+ //
+ gBS->CloseProtocol (
+ Instance->IpInfo->ChildHandle,
+ &gEfiIp6ProtocolGuid,
+ gUdp6DriverBinding.DriverBindingHandle,
+ Instance->ChildHandle
+ );
//
// Uninstall the Udp6Protocol previously installed on the ChildHandle.
@@ -469,7 +539,7 @@ Udp6ServiceBindingDestroyChild (
NULL
);
if (EFI_ERROR (Status)) {
- Instance->Destroyed = FALSE;
+ Instance->InDestroy = FALSE;
return Status;
}
diff --git a/NetworkPkg/Udp6Dxe/Udp6Impl.c b/NetworkPkg/Udp6Dxe/Udp6Impl.c
index 8e259319b9..3830b14415 100644
--- a/NetworkPkg/Udp6Dxe/Udp6Impl.c
+++ b/NetworkPkg/Udp6Dxe/Udp6Impl.c
@@ -1,7 +1,7 @@
/** @file
Udp6 driver's whole implementation.
- Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<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
@@ -363,7 +363,8 @@ ON_ERROR:
}
IpIoDestroy (Udp6Service->IpIo);
-
+ Udp6Service->IpIo = NULL;
+
return Status;
}
@@ -388,6 +389,9 @@ Udp6CleanService (
// Destroy the IpIo.
//
IpIoDestroy (Udp6Service->IpIo);
+ Udp6Service->IpIo = NULL;
+
+ ZeroMem (Udp6Service, sizeof (UDP6_SERVICE_DATA));
}
@@ -491,7 +495,7 @@ Udp6InitInstance (
Instance->IcmpError = EFI_SUCCESS;
Instance->Configured = FALSE;
Instance->IsNoMapping = FALSE;
- Instance->Destroyed = FALSE;
+ Instance->InDestroy = FALSE;
}
diff --git a/NetworkPkg/Udp6Dxe/Udp6Impl.h b/NetworkPkg/Udp6Dxe/Udp6Impl.h
index 108e30b71c..9ca4f4a011 100644
--- a/NetworkPkg/Udp6Dxe/Udp6Impl.h
+++ b/NetworkPkg/Udp6Dxe/Udp6Impl.h
@@ -1,7 +1,7 @@
/** @file
Udp6 driver's whole implementation and internal data structures.
- Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<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
@@ -30,11 +30,13 @@
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DpcLib.h>
+#include <Library/PrintLib.h>
#include "Udp6Driver.h"
extern EFI_COMPONENT_NAME2_PROTOCOL gUdp6ComponentName2;
extern EFI_COMPONENT_NAME_PROTOCOL gUdp6ComponentName;
+extern EFI_UNICODE_STRING_TABLE *gUdp6ControllerNameTable;
extern EFI_SERVICE_BINDING_PROTOCOL mUdp6ServiceBinding;
extern EFI_UDP6_PROTOCOL mUdp6Protocol;
extern UINT16 mUdp6RandomPort;
@@ -97,7 +99,7 @@ typedef struct _UDP6_INSTANCE_DATA {
UINT16 HeadSum;
EFI_STATUS IcmpError;
IP_IO_IP_INFO *IpInfo;
- BOOLEAN Destroyed;
+ BOOLEAN InDestroy;
} UDP6_INSTANCE_DATA;
typedef struct _UDP6_RXDATA_WRAP {
@@ -107,6 +109,12 @@ typedef struct _UDP6_RXDATA_WRAP {
EFI_UDP6_RECEIVE_DATA RxData;
} UDP6_RXDATA_WRAP;
+typedef struct {
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ UINTN NumberOfChildren;
+ EFI_HANDLE *ChildHandleBuffer;
+} UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT;
+
/**
Clean the Udp service context data.
diff --git a/NetworkPkg/UefiPxeBcDxe/ComponentName.c b/NetworkPkg/UefiPxeBcDxe/ComponentName.c
index 05e338a7f9..6e48d4aa18 100644
--- a/NetworkPkg/UefiPxeBcDxe/ComponentName.c
+++ b/NetworkPkg/UefiPxeBcDxe/ComponentName.c
@@ -1,7 +1,7 @@
/** @file
UEFI Component Name(2) protocol implementation for UefiPxeBc driver.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<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
@@ -171,6 +171,16 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mPxeBcDriverNameTab
}
};
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mPxeBcControllerNameTable[] = {
+ {
+ "eng;en",
+ L"PXE Controller"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
/**
Retrieves a Unicode string that is the user-readable name of the driver.
@@ -307,6 +317,42 @@ PxeBcComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
- return EFI_UNSUPPORTED;
-}
+ EFI_STATUS Status;
+ EFI_HANDLE NicHandle;
+ PXEBC_PRIVATE_PROTOCOL *Id;
+ if (ControllerHandle == NULL || ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ NicHandle = PxeBcGetNicByIp4Children (ControllerHandle);
+ if (NicHandle == NULL) {
+ NicHandle = PxeBcGetNicByIp6Children (ControllerHandle);
+ if (NicHandle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ //
+ // Try to retrieve the private data by PxeBcPrivate protocol.
+ //
+ Status = gBS->OpenProtocol (
+ NicHandle,
+ &gEfiCallerIdGuid,
+ (VOID **) &Id,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mPxeBcControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gPxeBcComponentName)
+ );
+}
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c
index 080b751cb1..b29df68bbd 100644
--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c
+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c
@@ -1398,7 +1398,7 @@ PxeBcDriverBindingStop (
if (NicHandle == NULL) {
NicHandle = PxeBcGetNicByIp6Children (ControllerHandle);
if (NicHandle == NULL) {
- return EFI_DEVICE_ERROR;
+ return EFI_SUCCESS;
} else {
IsIpv6 = TRUE;
}
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcSupport.h b/NetworkPkg/UefiPxeBcDxe/PxeBcSupport.h
index c82237be0e..80e56bc06f 100644
--- a/NetworkPkg/UefiPxeBcDxe/PxeBcSupport.h
+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcSupport.h
@@ -1,7 +1,7 @@
/** @file
Support functions declaration for UefiPxeBc Driver.
- Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<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
@@ -485,4 +485,29 @@ CalcElapsedTime (
IN PXEBC_PRIVATE_DATA *Private
);
+/**
+ Get the Nic handle using any child handle in the IPv4 stack.
+
+ @param[in] ControllerHandle Pointer to child handle over IPv4.
+
+ @return NicHandle The pointer to the Nic handle.
+
+**/
+EFI_HANDLE
+PxeBcGetNicByIp4Children (
+ IN EFI_HANDLE ControllerHandle
+ );
+
+/**
+ Get the Nic handle using any child handle in the IPv6 stack.
+
+ @param[in] ControllerHandle Pointer to child handle over IPv6.
+
+ @return NicHandle The pointer to the Nic handle.
+
+**/
+EFI_HANDLE
+PxeBcGetNicByIp6Children (
+ IN EFI_HANDLE ControllerHandle
+ );
#endif