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
This commit is contained in:
sfu5 2012-12-13 06:47:06 +00:00
parent 906e1cb7f7
commit 216f79703b
91 changed files with 3991 additions and 694 deletions

View File

@ -662,6 +662,72 @@ NetListInsertBefore (
IN OUT LIST_ENTRY *NewEntry
);
/**
Callback function which provided by user to remove one node in NetDestroyLinkList process.
@param[in] Entry The entry to be removed.
@param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
@retval EFI_SUCCESS The entry has been removed successfully.
@retval Others Fail to remove the entry.
**/
typedef
EFI_STATUS
(EFIAPI *NET_DESTROY_LINK_LIST_CALLBACK) (
IN LIST_ENTRY *Entry,
IN VOID *Context OPTIONAL
);
/**
Safe destroy nodes in a linked list, and return the length of the list after all possible operations finished.
Destroy network children list by list traversals is not safe due to graph dependencies between nodes.
This function performs a safe traversal to destroy these nodes by checking to see if the node being destroyed
has been removed from the list or not.
If it has been removed, then restart the traversal from the head.
If it hasn't been removed, then continue with the next node directly.
This function will end the iterate and return the CallBack's last return value if error happens,
or retrun EFI_SUCCESS if 2 complete passes are made with no changes in the number of children in the list.
@param[in] List The head of the list.
@param[in] CallBack Pointer to the callback function to destroy one node in the list.
@param[in] Context Pointer to the callback function's context: corresponds to the
parameter Context in NET_DESTROY_LINK_LIST_CALLBACK.
@param[out] ListLength The length of the link list if the function returns successfully.
@retval EFI_SUCCESS Two complete passes are made with no changes in the number of children.
@retval EFI_INVALID_PARAMETER The input parameter is invalid.
@retval Others Return the CallBack's last return value.
**/
EFI_STATUS
EFIAPI
NetDestroyLinkList (
IN LIST_ENTRY *List,
IN NET_DESTROY_LINK_LIST_CALLBACK CallBack,
IN VOID *Context, OPTIONAL
OUT UINTN *ListLength OPTIONAL
);
/**
This function checks the input Handle to see if it's one of these handles in ChildHandleBuffer.
@param[in] Handle Handle to be checked.
@param[in] NumberOfChildren Number of Handles in ChildHandleBuffer.
@param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
if NumberOfChildren is 0.
@retval TURE Found the input Handle in ChildHandleBuffer.
@retval FALSE Can't find the input Handle in ChildHandleBuffer.
**/
BOOLEAN
NetIsInHandleBuffer (
IN EFI_HANDLE Handle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
);
//
// Object container: EFI network stack spec defines various kinds of
@ -1337,6 +1403,28 @@ NetLibStrToIp6andPrefix (
OUT UINT8 *PrefixLength
);
/**
Convert one EFI_IPv6_ADDRESS to Null-terminated Unicode string.
The text representation of address is defined in RFC 4291.
@param[in] Ip6Address The pointer to the IPv6 address.
@param[out] String The buffer to return the converted string.
@param[in] StringSize The length in bytes of the input String.
@retval EFI_SUCCESS Convert to string successfully.
@retval EFI_INVALID_PARAMETER The input parameter is invalid.
@retval EFI_BUFFER_TOO_SMALL The BufferSize is too small for the result. BufferSize has been
updated with the size needed to complete the request.
**/
EFI_STATUS
EFIAPI
NetLibIp6ToStr (
IN EFI_IPv6_ADDRESS *Ip6Address,
OUT CHAR16 *String,
IN UINTN StringSize
);
//
// Various signatures
//

View File

@ -40,6 +40,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/UefiLib.h>
#define NIC_ITEM_CONFIG_SIZE sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * MAX_IP4_CONFIG_IN_VARIABLE
#define DEFAULT_ZERO_START ((UINTN) ~0)
//
// All the supported IP4 maskes in host byte order.
@ -1065,6 +1066,115 @@ NetListInsertBefore (
PostEntry->BackLink = NewEntry;
}
/**
Safe destroy nodes in a linked list, and return the length of the list after all possible operations finished.
Destroy network child instance list by list traversals is not safe due to graph dependencies between nodes.
This function performs a safe traversal to destroy these nodes by checking to see if the node being destroyed
has been removed from the list or not.
If it has been removed, then restart the traversal from the head.
If it hasn't been removed, then continue with the next node directly.
This function will end the iterate and return the CallBack's last return value if error happens,
or retrun EFI_SUCCESS if 2 complete passes are made with no changes in the number of children in the list.
@param[in] List The head of the list.
@param[in] CallBack Pointer to the callback function to destroy one node in the list.
@param[in] Context Pointer to the callback function's context: corresponds to the
parameter Context in NET_DESTROY_LINK_LIST_CALLBACK.
@param[out] ListLength The length of the link list if the function returns successfully.
@retval EFI_SUCCESS Two complete passes are made with no changes in the number of children.
@retval EFI_INVALID_PARAMETER The input parameter is invalid.
@retval Others Return the CallBack's last return value.
**/
EFI_STATUS
EFIAPI
NetDestroyLinkList (
IN LIST_ENTRY *List,
IN NET_DESTROY_LINK_LIST_CALLBACK CallBack,
IN VOID *Context, OPTIONAL
OUT UINTN *ListLength OPTIONAL
)
{
UINTN PreviousLength;
LIST_ENTRY *Entry;
LIST_ENTRY *Ptr;
UINTN Length;
EFI_STATUS Status;
if (List == NULL || CallBack == NULL) {
return EFI_INVALID_PARAMETER;
}
Length = 0;
do {
PreviousLength = Length;
Entry = GetFirstNode (List);
while (!IsNull (List, Entry)) {
Status = CallBack (Entry, Context);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Walk through the list to see whether the Entry has been removed or not.
// If the Entry still exists, just try to destroy the next one.
// If not, go back to the start point to iterate the list again.
//
for (Ptr = List->ForwardLink; Ptr != List; Ptr = Ptr->ForwardLink) {
if (Ptr == Entry) {
break;
}
}
if (Ptr == Entry) {
Entry = GetNextNode (List, Entry);
} else {
Entry = GetFirstNode (List);
}
}
for (Length = 0, Ptr = List->ForwardLink; Ptr != List; Length++, Ptr = Ptr->ForwardLink);
} while (Length != PreviousLength);
if (ListLength != NULL) {
*ListLength = Length;
}
return EFI_SUCCESS;
}
/**
This function checks the input Handle to see if it's one of these handles in ChildHandleBuffer.
@param[in] Handle Handle to be checked.
@param[in] NumberOfChildren Number of Handles in ChildHandleBuffer.
@param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
if NumberOfChildren is 0.
@retval TURE Found the input Handle in ChildHandleBuffer.
@retval FALSE Can't find the input Handle in ChildHandleBuffer.
**/
BOOLEAN
NetIsInHandleBuffer (
IN EFI_HANDLE Handle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
)
{
UINTN Index;
if (NumberOfChildren == 0 || ChildHandleBuffer == NULL) {
return FALSE;
}
for (Index = 0; Index < NumberOfChildren; Index++) {
if (Handle == ChildHandleBuffer[Index]) {
return TRUE;
}
}
return FALSE;
}
/**
Initialize the netmap. Netmap is a reposity to keep the <Key, Value> pairs.
@ -3175,7 +3285,110 @@ Exit:
return Status;
}
/**
Convert one EFI_IPv6_ADDRESS to Null-terminated Unicode string.
The text representation of address is defined in RFC 4291.
@param[in] Ip6Address The pointer to the IPv6 address.
@param[out] String The buffer to return the converted string.
@param[in] StringSize The length in bytes of the input String.
@retval EFI_SUCCESS Convert to string successfully.
@retval EFI_INVALID_PARAMETER The input parameter is invalid.
@retval EFI_BUFFER_TOO_SMALL The BufferSize is too small for the result. BufferSize has been
updated with the size needed to complete the request.
**/
EFI_STATUS
EFIAPI
NetLibIp6ToStr (
IN EFI_IPv6_ADDRESS *Ip6Address,
OUT CHAR16 *String,
IN UINTN StringSize
)
{
UINT16 Ip6Addr[8];
UINTN Index;
UINTN LongestZerosStart;
UINTN LongestZerosLength;
UINTN CurrentZerosStart;
UINTN CurrentZerosLength;
CHAR16 Buffer[sizeof"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
CHAR16 *Ptr;
if (Ip6Address == NULL || String == NULL || StringSize == 0) {
return EFI_INVALID_PARAMETER;
}
//
// Convert the UINT8 array to an UINT16 array for easy handling.
//
ZeroMem (Ip6Addr, sizeof (Ip6Addr));
for (Index = 0; Index < 16; Index++) {
Ip6Addr[Index / 2] |= (Ip6Address->Addr[Index] << ((1 - (Index % 2)) << 3));
}
//
// Find the longest zeros and mark it.
//
CurrentZerosStart = DEFAULT_ZERO_START;
CurrentZerosLength = 0;
LongestZerosStart = DEFAULT_ZERO_START;
LongestZerosLength = 0;
for (Index = 0; Index < 8; Index++) {
if (Ip6Addr[Index] == 0) {
if (CurrentZerosStart == DEFAULT_ZERO_START) {
CurrentZerosStart = Index;
CurrentZerosLength = 1;
} else {
CurrentZerosLength++;
}
} else {
if (CurrentZerosStart != DEFAULT_ZERO_START) {
if (CurrentZerosLength > 2 && (LongestZerosStart == (DEFAULT_ZERO_START) || CurrentZerosLength > LongestZerosLength)) {
LongestZerosStart = CurrentZerosStart;
LongestZerosLength = CurrentZerosLength;
}
CurrentZerosStart = DEFAULT_ZERO_START;
CurrentZerosLength = 0;
}
}
}
if (CurrentZerosStart != DEFAULT_ZERO_START && CurrentZerosLength > 2) {
if (LongestZerosStart == DEFAULT_ZERO_START || LongestZerosLength < CurrentZerosLength) {
LongestZerosStart = CurrentZerosStart;
LongestZerosLength = CurrentZerosLength;
}
}
Ptr = Buffer;
for (Index = 0; Index < 8; Index++) {
if (LongestZerosStart != DEFAULT_ZERO_START && Index >= LongestZerosStart && Index < LongestZerosStart + LongestZerosLength) {
if (Index == LongestZerosStart) {
*Ptr++ = L':';
}
continue;
}
if (Index != 0) {
*Ptr++ = L':';
}
Ptr += UnicodeSPrint(Ptr, 10, L"%x", Ip6Addr[Index]);
}
if (LongestZerosStart != DEFAULT_ZERO_START && LongestZerosStart + LongestZerosLength == 8) {
*Ptr++ = L':';
}
*Ptr = L'\0';
if ((UINTN)Ptr - (UINTN)Buffer > StringSize) {
return EFI_BUFFER_TOO_SMALL;
}
StrCpy (String, Buffer);
return EFI_SUCCESS;
}
/**
This function obtains the system guid from the smbios table.

View File

@ -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>
@ -241,6 +241,35 @@ ArpCleanService (
}
}
/**
Callback function which provided by user to remove one node in NetDestroyLinkList process.
@param[in] Entry The entry to be removed.
@param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
@retval EFI_SUCCESS The entry has been removed successfully.
@retval Others Fail to remove the entry.
**/
EFI_STATUS
ArpDestroyChildEntryInHandleBuffer (
IN LIST_ENTRY *Entry,
IN VOID *Context
)
{
ARP_INSTANCE_DATA *Instance;
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
if (Entry == NULL || Context == NULL) {
return EFI_INVALID_PARAMETER;
}
Instance = NET_LIST_USER_STRUCT_S (Entry, ARP_INSTANCE_DATA, List, ARP_INSTANCE_DATA_SIGNATURE);
ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *) Context;
return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
}
/**
Tests to see if this driver supports a given controller.
@ -446,14 +475,14 @@ ArpDriverBindingStop (
EFI_HANDLE NicHandle;
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
ARP_SERVICE_DATA *ArpService;
ARP_INSTANCE_DATA *Instance;
LIST_ENTRY *List;
//
// Get the NicHandle which the arp servicebinding is installed on.
//
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
if (NicHandle == NULL) {
return EFI_DEVICE_ERROR;
return EFI_SUCCESS;
}
//
@ -474,7 +503,21 @@ ArpDriverBindingStop (
ArpService = ARP_SERVICE_DATA_FROM_THIS (ServiceBinding);
if (NumberOfChildren == 0) {
if (NumberOfChildren != 0) {
//
// NumberOfChildren is not zero, destroy all the ARP children instances.
//
List = &ArpService->ChildrenList;
Status = NetDestroyLinkList (
List,
ArpDestroyChildEntryInHandleBuffer,
ServiceBinding,
NULL
);
ASSERT (IsListEmpty (&ArpService->PendingRequestTable));
ASSERT (IsListEmpty (&ArpService->DeniedCacheTable));
ASSERT (IsListEmpty (&ArpService->ResolvedCacheTable));
} else if (IsListEmpty (&ArpService->ChildrenList)) {
//
// Uninstall the ARP ServiceBinding protocol.
//
@ -491,17 +534,6 @@ ArpDriverBindingStop (
ArpCleanService (ArpService);
FreePool (ArpService);
} else {
while (!IsListEmpty (&ArpService->ChildrenList)) {
Instance = NET_LIST_HEAD (&ArpService->ChildrenList, ARP_INSTANCE_DATA, List);
ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
}
ASSERT (IsListEmpty (&ArpService->PendingRequestTable));
ASSERT (IsListEmpty (&ArpService->DeniedCacheTable));
ASSERT (IsListEmpty (&ArpService->ResolvedCacheTable));
}
return EFI_SUCCESS;
@ -690,14 +722,14 @@ ArpServiceBindingDestroyChild (
Instance = ARP_INSTANCE_DATA_FROM_THIS (Arp);
if (Instance->Destroyed) {
if (Instance->InDestroy) {
return EFI_SUCCESS;
}
//
// Use the Destroyed as a flag to avoid re-entrance.
// Use the InDestroy as a flag to avoid re-entrance.
//
Instance->Destroyed = TRUE;
Instance->InDestroy = TRUE;
//
// Close the Managed Network protocol.
@ -722,7 +754,7 @@ ArpServiceBindingDestroyChild (
DEBUG ((EFI_D_ERROR, "ArpSBDestroyChild: Failed to uninstall the arp protocol, %r.\n",
Status));
Instance->Destroyed = FALSE;
Instance->InDestroy = FALSE;
return Status;
}

View File

@ -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);
}

View File

@ -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')

View File

@ -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)
);
}

View File

@ -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.
@ -230,6 +244,66 @@ DhcpComponentNameGetDriverName (
);
}
/**
Update the component name for the Dhcp4 child handle.
@param Dhcp4[in] A pointer to the EFI_DHCP4_PROTOCOL.
@retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
@retval EFI_INVALID_PARAMETER The input parameter is invalid.
@retval EFI_DEVICE_ERROR DHCP is in unknown state.
**/
EFI_STATUS
UpdateName (
IN EFI_DHCP4_PROTOCOL *Dhcp4
)
{
EFI_STATUS Status;
EFI_DHCP4_MODE_DATA Dhcp4ModeData;
if (Dhcp4 == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Format the child name into the string buffer.
//
Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4ModeData);
if (EFI_ERROR (Status)) {
return Status;
}
if (gDhcpControllerNameTable != NULL) {
FreeUnicodeStringTable (gDhcpControllerNameTable);
gDhcpControllerNameTable = NULL;
}
if (Dhcp4ModeData.State > Dhcp4Rebooting) {
return EFI_DEVICE_ERROR;
}
Status = AddUnicodeString2 (
"eng",
gDhcp4ComponentName.SupportedLanguages,
&gDhcpControllerNameTable,
mDhcp4ControllerName[Dhcp4ModeData.State],
TRUE
);
if (EFI_ERROR (Status)) {
return Status;
}
return AddUnicodeString2 (
"en",
gDhcp4ComponentName2.SupportedLanguages,
&gDhcpControllerNameTable,
mDhcp4ControllerName[Dhcp4ModeData.State],
FALSE
);
}
/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
@ -308,5 +382,56 @@ DhcpComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
return EFI_UNSUPPORTED;
EFI_STATUS Status;
EFI_DHCP4_PROTOCOL *Dhcp4;
//
// Only provide names for child handles.
//
if (ChildHandle == NULL) {
return EFI_UNSUPPORTED;
}
//
// Make sure this driver produced ChildHandle
//
Status = EfiTestChildHandle (
ControllerHandle,
ChildHandle,
&gEfiUdp4ProtocolGuid
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Retrieve an instance of a produced protocol from ChildHandle
//
Status = gBS->OpenProtocol (
ChildHandle,
&gEfiDhcp4ProtocolGuid,
(VOID **)&Dhcp4,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Update the component name for this child handle.
//
Status = UpdateName (Dhcp4);
if (EFI_ERROR (Status)) {
return Status;
}
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
gDhcpControllerNameTable,
ControllerName,
(BOOLEAN)(This == &gDhcp4ComponentName)
);
}

View File

@ -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 && !IsListEmpty (&DhcpSb->Children)) {
Status = EFI_DEVICE_ERROR;
}
if (NumberOfChildren == 0) {
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);
if (gDhcpControllerNameTable != NULL) {
FreeUnicodeStringTable (gDhcpControllerNameTable);
gDhcpControllerNameTable = NULL;
}
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;
}
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;

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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)
);
}

View File

@ -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.
@ -230,6 +232,74 @@ Ip4ComponentNameGetDriverName (
}
/**
Update the component name for the IP4 child handle.
@param Ip4[in] A pointer to the EFI_IP4_PROTOCOL.
@retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
@retval EFI_INVALID_PARAMETER The input parameter is invalid.
**/
EFI_STATUS
UpdateName (
IN EFI_IP4_PROTOCOL *Ip4
)
{
EFI_STATUS Status;
CHAR16 HandleName[80];
EFI_IP4_MODE_DATA Ip4ModeData;
if (Ip4 == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Format the child name into the string buffer as:
// IPv4 (SrcIP=127.0.0.1, DestIP=127.0.0.1)
//
Status = Ip4->GetModeData (Ip4, &Ip4ModeData, NULL, NULL);
if (EFI_ERROR (Status)) {
return Status;
}
if (!Ip4ModeData.IsStarted || !Ip4ModeData.IsConfigured) {
UnicodeSPrint (HandleName, sizeof (HandleName), L"IPv4 (Not started)");
} else {
UnicodeSPrint (HandleName, sizeof (HandleName),
L"IPv4 (SrcIP=%d.%d.%d.%d)",
Ip4ModeData.ConfigData.StationAddress.Addr[0],
Ip4ModeData.ConfigData.StationAddress.Addr[1],
Ip4ModeData.ConfigData.StationAddress.Addr[2],
Ip4ModeData.ConfigData.StationAddress.Addr[3]
);
}
if (gIp4ControllerNameTable != NULL) {
FreeUnicodeStringTable (gIp4ControllerNameTable);
gIp4ControllerNameTable = NULL;
}
Status = AddUnicodeString2 (
"eng",
gIp4ComponentName.SupportedLanguages,
&gIp4ControllerNameTable,
HandleName,
TRUE
);
if (EFI_ERROR (Status)) {
return Status;
}
return AddUnicodeString2 (
"en",
gIp4ComponentName2.SupportedLanguages,
&gIp4ControllerNameTable,
HandleName,
FALSE
);
}
/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
@ -308,5 +378,57 @@ Ip4ComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
return EFI_UNSUPPORTED;
EFI_STATUS Status;
EFI_IP4_PROTOCOL *Ip4;
//
// Only provide names for child handles.
//
if (ChildHandle == NULL) {
return EFI_UNSUPPORTED;
}
//
// Make sure this driver produced ChildHandle
//
Status = EfiTestChildHandle (
ControllerHandle,
ChildHandle,
&gEfiManagedNetworkProtocolGuid
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Retrieve an instance of a produced protocol from ChildHandle
//
Status = gBS->OpenProtocol (
ChildHandle,
&gEfiIp4ProtocolGuid,
(VOID **)&Ip4,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Update the component name for this child handle.
//
Status = UpdateName (Ip4);
if (EFI_ERROR (Status)) {
return Status;
}
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
gIp4ControllerNameTable,
ControllerName,
(BOOLEAN)(This == &gIp4ComponentName)
);
}

View File

@ -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)
///

View File

@ -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
);
if (gIp4ControllerNameTable != NULL) {
FreeUnicodeStringTable (gIp4ControllerNameTable);
gIp4ControllerNameTable = NULL;
}
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;
}
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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -868,6 +868,7 @@ Ip4ConfigProtocol (
EFI_STATUS Status;
IP4_ADDR Ip;
IP4_ADDR Netmask;
EFI_ARP_PROTOCOL *Arp;
IpSb = IpInstance->Service;
@ -972,6 +973,20 @@ Ip4ConfigProtocol (
}
IpInstance->Interface = IpIf;
if (IpIf->Arp != NULL) {
Arp = NULL;
Status = gBS->OpenProtocol (
IpIf->ArpHandle,
&gEfiArpProtocolGuid,
(VOID **) &Arp,
gIp4DriverBinding.DriverBindingHandle,
IpInstance->Handle,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
}
InsertTailList (&IpIf->IpInstances, &IpInstance->AddrLink);
CopyMem (&IpInstance->ConfigData, Config, sizeof (IpInstance->ConfigData));
@ -1028,6 +1043,14 @@ Ip4CleanProtocol (
if (IpInstance->Interface != NULL) {
RemoveEntryList (&IpInstance->AddrLink);
if (IpInstance->Interface->Arp != NULL) {
gBS->CloseProtocol (
IpInstance->Interface->ArpHandle,
&gEfiArpProtocolGuid,
gIp4DriverBinding.DriverBindingHandle,
IpInstance->Handle
);
}
Ip4FreeInterface (IpInstance->Interface, IpInstance);
IpInstance->Interface = NULL;
}
@ -1193,14 +1216,6 @@ EfiIp4Configure (
// Validate the configuration first.
//
if (IpConfigData != NULL) {
//
// This implementation doesn't support RawData
//
if (IpConfigData->RawData) {
Status = EFI_UNSUPPORTED;
goto ON_EXIT;
}
CopyMem (&IpAddress, &IpConfigData->StationAddress, sizeof (IP4_ADDR));
CopyMem (&SubnetMask, &IpConfigData->SubnetMask, sizeof (IP4_ADDR));
@ -1620,22 +1635,23 @@ Ip4TokenExist (
return EFI_SUCCESS;
}
/**
Validate the user's token against current station address.
@param[in] Token User's token to validate
@param[in] IpIf The IP4 child's interface.
@param[in] Token User's token to validate.
@param[in] IpIf The IP4 child's interface.
@param[in] RawData Set to TRUE to send unformatted packets.
@retval EFI_INVALID_PARAMETER Some parameters are invalid
@retval EFI_INVALID_PARAMETER Some parameters are invalid.
@retval EFI_BAD_BUFFER_SIZE The user's option/data is too long.
@retval EFI_SUCCESS The token is OK
@retval EFI_SUCCESS The token is valid.
**/
EFI_STATUS
Ip4TxTokenValid (
IN EFI_IP4_COMPLETION_TOKEN *Token,
IN IP4_INTERFACE *IpIf
IN IP4_INTERFACE *IpIf,
IN BOOLEAN RawData
)
{
EFI_IP4_TRANSMIT_DATA *TxData;
@ -1653,20 +1669,7 @@ Ip4TxTokenValid (
TxData = Token->Packet.TxData;
//
// Check the IP options: no more than 40 bytes and format is OK
//
if (TxData->OptionsLength != 0) {
if ((TxData->OptionsLength > 40) || (TxData->OptionsBuffer == NULL)) {
return EFI_INVALID_PARAMETER;
}
if (!Ip4OptionIsValid (TxData->OptionsBuffer, TxData->OptionsLength, FALSE)) {
return EFI_INVALID_PARAMETER;
}
}
//
// Check the fragment table: no empty fragment, and length isn't bogus
// Check the fragment table: no empty fragment, and length isn't bogus.
//
if ((TxData->TotalDataLength == 0) || (TxData->FragmentCount == 0)) {
return EFI_INVALID_PARAMETER;
@ -1674,6 +1677,10 @@ Ip4TxTokenValid (
Offset = TxData->TotalDataLength;
if (Offset > IP4_MAX_PACKET_SIZE) {
return EFI_BAD_BUFFER_SIZE;
}
for (Index = 0; Index < TxData->FragmentCount; Index++) {
if ((TxData->FragmentTable[Index].FragmentBuffer == NULL) ||
(TxData->FragmentTable[Index].FragmentLength == 0)) {
@ -1688,6 +1695,27 @@ Ip4TxTokenValid (
return EFI_INVALID_PARAMETER;
}
//
// NOTE that OptionsLength/OptionsBuffer/OverrideData are ignored if RawData
// is TRUE.
//
if (RawData) {
return EFI_SUCCESS;
}
//
// Check the IP options: no more than 40 bytes and format is OK
//
if (TxData->OptionsLength != 0) {
if ((TxData->OptionsLength > 40) || (TxData->OptionsBuffer == NULL)) {
return EFI_INVALID_PARAMETER;
}
if (!Ip4OptionIsValid (TxData->OptionsBuffer, TxData->OptionsLength, FALSE)) {
return EFI_INVALID_PARAMETER;
}
}
//
// Check the source and gateway: they must be a valid unicast.
// Gateway must also be on the connected network.
@ -1888,6 +1916,10 @@ EfiIp4Transmit (
EFI_TPL OldTpl;
BOOLEAN DontFragment;
UINT32 HeadLen;
UINT8 RawHdrLen;
UINT32 OptionsLength;
UINT8 *OptionsBuffer;
VOID *FirstFragment;
if (This == NULL) {
return EFI_INVALID_PARAMETER;
@ -1913,7 +1945,7 @@ EfiIp4Transmit (
//
// make sure that token is properly formated
//
Status = Ip4TxTokenValid (Token, IpIf);
Status = Ip4TxTokenValid (Token, IpIf, Config->RawData);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
@ -1933,32 +1965,82 @@ EfiIp4Transmit (
//
TxData = Token->Packet.TxData;
CopyMem (&Head.Dst, &TxData->DestinationAddress, sizeof (IP4_ADDR));
Head.Dst = NTOHL (Head.Dst);
FirstFragment = NULL;
if (TxData->OverrideData != NULL) {
Override = TxData->OverrideData;
Head.Protocol = Override->Protocol;
Head.Tos = Override->TypeOfService;
Head.Ttl = Override->TimeToLive;
DontFragment = Override->DoNotFragment;
if (Config->RawData) {
//
// When RawData is TRUE, first buffer in FragmentTable points to a raw
// IPv4 fragment including IPv4 header and options.
//
FirstFragment = TxData->FragmentTable[0].FragmentBuffer;
CopyMem (&RawHdrLen, FirstFragment, sizeof (UINT8));
CopyMem (&Head.Src, &Override->SourceAddress, sizeof (IP4_ADDR));
CopyMem (&GateWay, &Override->GatewayAddress, sizeof (IP4_ADDR));
RawHdrLen = (UINT8) (RawHdrLen & 0x0f);
if (RawHdrLen < 5) {
return EFI_INVALID_PARAMETER;
}
Head.Src = NTOHL (Head.Src);
GateWay = NTOHL (GateWay);
RawHdrLen = (UINT8) (RawHdrLen << 2);
CopyMem (&Head, FirstFragment, IP4_MIN_HEADLEN);
Ip4NtohHead (&Head);
HeadLen = 0;
DontFragment = IP4_DO_NOT_FRAGMENT (Head.Fragment);
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;

View File

@ -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

View File

@ -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);
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;
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;
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);
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
);
}
}

View File

@ -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
);

View File

@ -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.
@ -323,6 +335,13 @@ Ip4Output (
Mtu = IpSb->MaxPacketSize + sizeof (IP4_HEAD);
if (Packet->TotalSize + HeadLen > Mtu) {
//
// Fragmentation is diabled for RawData mode.
//
if (RawData) {
return EFI_BAD_BUFFER_SIZE;
}
//
// Packet is fragmented from the tail to the head, that is, the
// first frame sent is the last fragment of the packet. The first

View File

@ -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.
@ -100,6 +102,106 @@ MnpComponentNameGetDriverName (
);
}
/**
Update the component name for the MNP child handle.
@param Mnp[in] A pointer to the EFI_MANAGED_NETWORK_PROTOCOL.
@retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
@retval EFI_INVALID_PARAMETER The input parameter is invalid.
**/
EFI_STATUS
UpdateName (
IN EFI_MANAGED_NETWORK_PROTOCOL *Mnp
)
{
EFI_STATUS Status;
MNP_INSTANCE_DATA *Instance;
CHAR16 HandleName[80];
EFI_MANAGED_NETWORK_CONFIG_DATA MnpConfigData;
EFI_SIMPLE_NETWORK_MODE SnpModeData;
UINTN OffSet;
UINTN Index;
if (Mnp == NULL) {
return EFI_INVALID_PARAMETER;
}
Instance = MNP_INSTANCE_DATA_FROM_THIS (Mnp);
//
// Format the child name into the string buffer as:
// MNP (MAC=FF-FF-FF-FF-FF-FF, ProtocolType=0x0800, VlanId=0)
//
Status = Mnp->GetModeData (Mnp, &MnpConfigData, &SnpModeData);
if (!EFI_ERROR (Status)) {
OffSet = 0;
//
// Print the MAC address.
//
OffSet += UnicodeSPrint (
HandleName,
sizeof (HandleName),
L"MNP (MAC="
);
for (Index = 0; Index < SnpModeData.HwAddressSize; Index++) {
OffSet += UnicodeSPrint (
HandleName + OffSet,
sizeof (HandleName) - OffSet,
L"%02X-",
SnpModeData.CurrentAddress.Addr[Index]
);
}
//
// Remove the last '-'
//
OffSet--;
//
// Print the ProtocolType and VLAN ID for this instance.
//
OffSet += UnicodeSPrint (
HandleName + OffSet,
sizeof (HandleName) - OffSet,
L", ProtocolType=0x%X, VlanId=%d)",
MnpConfigData.ProtocolTypeFilter,
Instance->MnpServiceData->VlanId
);
} else if (Status == EFI_NOT_STARTED) {
UnicodeSPrint (
HandleName,
sizeof (HandleName),
L"MNP (Not started)"
);
} else {
return Status;
}
if (gMnpControllerNameTable != NULL) {
FreeUnicodeStringTable (gMnpControllerNameTable);
gMnpControllerNameTable = NULL;
}
Status = AddUnicodeString2 (
"eng",
gMnpComponentName.SupportedLanguages,
&gMnpControllerNameTable,
HandleName,
TRUE
);
if (EFI_ERROR (Status)) {
return Status;
}
return AddUnicodeString2 (
"en",
gMnpComponentName2.SupportedLanguages,
&gMnpControllerNameTable,
HandleName,
FALSE
);
}
/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
@ -178,5 +280,68 @@ MnpComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
return EFI_UNSUPPORTED;
EFI_STATUS Status;
EFI_MANAGED_NETWORK_PROTOCOL *Mnp;
//
// Only provide names for MNP child handles.
//
if (ChildHandle == NULL) {
return EFI_UNSUPPORTED;
}
//
// Make sure this driver is currently managing ControllerHandle
//
Status = EfiTestManagedDevice (
ControllerHandle,
gMnpDriverBinding.DriverBindingHandle,
&gEfiSimpleNetworkProtocolGuid
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Make sure this driver produced ChildHandle
//
Status = EfiTestChildHandle (
ControllerHandle,
ChildHandle,
&gEfiManagedNetworkServiceBindingProtocolGuid
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Retrieve an instance of a produced protocol from ChildHandle
//
Status = gBS->OpenProtocol (
ChildHandle,
&gEfiManagedNetworkProtocolGuid,
(VOID **)&Mnp,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Update the component name for this child handle.
//
Status = UpdateName (Mnp);
if (EFI_ERROR (Status)) {
return Status;
}
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
gMnpControllerNameTable,
ControllerName,
(BOOLEAN)(This == &gMnpComponentName)
);
}

View File

@ -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.

View File

@ -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.
@ -686,6 +685,30 @@ MnpDestroyServiceData (
return Status;
}
/**
Callback function which provided by user to remove one node in NetDestroyLinkList process.
@param[in] Entry The entry to be removed.
@param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
@retval EFI_SUCCESS The entry has been removed successfully.
@retval Others Fail to remove the entry.
**/
EFI_STATUS
MnpDestoryChildEntry (
IN LIST_ENTRY *Entry,
IN VOID *Context
)
{
MNP_INSTANCE_DATA *Instance;
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *) Context;
Instance = CR (Entry, MNP_INSTANCE_DATA, InstEntry, MNP_INSTANCE_DATA_SIGNATURE);
return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
}
/**
Destroy all child of the MNP service data.
@ -700,26 +723,20 @@ MnpDestroyServiceChild (
IN OUT MNP_SERVICE_DATA *MnpServiceData
)
{
EFI_STATUS Status;
MNP_INSTANCE_DATA *Instance;
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
ServiceBinding = &MnpServiceData->ServiceBinding;
while (!IsListEmpty (&MnpServiceData->ChildrenList)) {
//
// Don't use NetListRemoveHead here, the remove opreration will be done
// in ServiceBindingDestroyChild.
//
Instance = NET_LIST_HEAD (
&MnpServiceData->ChildrenList,
MNP_INSTANCE_DATA,
InstEntry
);
Status = ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
if (EFI_ERROR (Status)) {
return Status;
}
LIST_ENTRY *List;
EFI_STATUS Status;
UINTN ListLength;
List = &MnpServiceData->ChildrenList;
Status = NetDestroyLinkList (
List,
MnpDestoryChildEntry,
&MnpServiceData->ServiceBinding,
&ListLength
);
if (EFI_ERROR (Status) || ListLength != 0) {
return EFI_DEVICE_ERROR;
}
return EFI_SUCCESS;

View File

@ -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
@ -26,6 +26,50 @@ EFI_DRIVER_BINDING_PROTOCOL gMnpDriverBinding = {
NULL
};
/**
Callback function which provided by user to remove one node in NetDestroyLinkList process.
@param[in] Entry The entry to be removed.
@param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
@retval EFI_SUCCESS The entry has been removed successfully.
@retval Others Fail to remove the entry.
**/
EFI_STATUS
MnpDestroyServiceDataEntry (
IN LIST_ENTRY *Entry,
IN VOID *Context
)
{
MNP_SERVICE_DATA *MnpServiceData;
MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);
return MnpDestroyServiceData (MnpServiceData);
}
/**
Callback function which provided by user to remove one node in NetDestroyLinkList process.
@param[in] Entry The entry to be removed.
@param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
@retval EFI_SUCCESS The entry has been removed successfully.
@retval Others Fail to remove the entry.
**/
EFI_STATUS
MnpDestroyServiceChildEntry (
IN LIST_ENTRY *Entry,
IN VOID *Context
)
{
MNP_SERVICE_DATA *MnpServiceData;
MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);
return MnpDestroyServiceChild (MnpServiceData);
}
/**
Test to see if this driver supports ControllerHandle. This service
is called by the EFI boot service ConnectController(). In
@ -276,8 +320,8 @@ MnpDriverBindingStop (
EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
MNP_DEVICE_DATA *MnpDeviceData;
MNP_SERVICE_DATA *MnpServiceData;
BOOLEAN AllChildrenStopped;
LIST_ENTRY *Entry;
LIST_ENTRY *List;
UINTN ListLength;
//
// Try to retrieve MNP service binding protocol from the ControllerHandle
@ -317,10 +361,15 @@ MnpDriverBindingStop (
//
// Destroy all MNP service data
//
while (!IsListEmpty (&MnpDeviceData->ServiceList)) {
Entry = GetFirstNode (&MnpDeviceData->ServiceList);
MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);
MnpDestroyServiceData (MnpServiceData);
List = &MnpDeviceData->ServiceList;
Status = NetDestroyLinkList (
List,
MnpDestroyServiceDataEntry,
NULL,
&ListLength
);
if (EFI_ERROR (Status) || ListLength !=0) {
return EFI_DEVICE_ERROR;
}
//
@ -341,23 +390,24 @@ MnpDriverBindingStop (
MnpDestroyDeviceData (MnpDeviceData, This->DriverBindingHandle);
FreePool (MnpDeviceData);
if (gMnpControllerNameTable != NULL) {
FreeUnicodeStringTable (gMnpControllerNameTable);
gMnpControllerNameTable = NULL;
}
return EFI_SUCCESS;
}
//
// Stop all MNP child
//
AllChildrenStopped = TRUE;
NET_LIST_FOR_EACH (Entry, &MnpDeviceData->ServiceList) {
MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);
Status = MnpDestroyServiceChild (MnpServiceData);
if (EFI_ERROR (Status)) {
AllChildrenStopped = FALSE;
}
}
if (!AllChildrenStopped) {
List = &MnpDeviceData->ServiceList;
Status = NetDestroyLinkList (
List,
MnpDestroyServiceChildEntry,
NULL,
&ListLength
);
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}

View File

@ -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;

View File

@ -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.
@ -230,6 +232,72 @@ Mtftp4ComponentNameGetDriverName (
);
}
/**
Update the component name for the Mtftp4 child handle.
@param Mtftp4[in] A pointer to the EFI_MTFTP4_PROTOCOL.
@retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
@retval EFI_INVALID_PARAMETER The input parameter is invalid.
**/
EFI_STATUS
UpdateName (
IN EFI_MTFTP4_PROTOCOL *Mtftp4
)
{
EFI_STATUS Status;
CHAR16 HandleName[80];
EFI_MTFTP4_MODE_DATA ModeData;
if (Mtftp4 == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Format the child name into the string buffer as:
// MTFTPv4 (ServerIp=192.168.1.10, ServerPort=69)
//
Status = Mtftp4->GetModeData (Mtftp4, &ModeData);
if (EFI_ERROR (Status)) {
return Status;
}
UnicodeSPrint (HandleName, sizeof (HandleName),
L"MTFTPv4 (ServerIp=%d.%d.%d.%d, ServerPort=%d)",
ModeData.ConfigData.ServerIp.Addr[0],
ModeData.ConfigData.ServerIp.Addr[1],
ModeData.ConfigData.ServerIp.Addr[2],
ModeData.ConfigData.ServerIp.Addr[3],
ModeData.ConfigData.InitialServerPort
);
if (gMtftp4ControllerNameTable != NULL) {
FreeUnicodeStringTable (gMtftp4ControllerNameTable);
gMtftp4ControllerNameTable = NULL;
}
Status = AddUnicodeString2 (
"eng",
gMtftp4ComponentName.SupportedLanguages,
&gMtftp4ControllerNameTable,
HandleName,
TRUE
);
if (EFI_ERROR (Status)) {
return Status;
}
return AddUnicodeString2 (
"en",
gMtftp4ComponentName2.SupportedLanguages,
&gMtftp4ControllerNameTable,
HandleName,
FALSE
);
}
/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
@ -308,5 +376,56 @@ Mtftp4ComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
return EFI_UNSUPPORTED;
EFI_STATUS Status;
EFI_MTFTP4_PROTOCOL *Mtftp4;
//
// Only provide names for child handles.
//
if (ChildHandle == NULL) {
return EFI_UNSUPPORTED;
}
//
// Make sure this driver produced ChildHandle
//
Status = EfiTestChildHandle (
ControllerHandle,
ChildHandle,
&gEfiUdp4ProtocolGuid
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Retrieve an instance of a produced protocol from ChildHandle
//
Status = gBS->OpenProtocol (
ChildHandle,
&gEfiMtftp4ProtocolGuid,
(VOID **)&Mtftp4,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Update the component name for this child handle.
//
Status = UpdateName (Mtftp4);
if (EFI_ERROR (Status)) {
return Status;
}
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
gMtftp4ControllerNameTable,
ControllerName,
(BOOLEAN)(This == &gMtftp4ComponentName)
);
}

View File

@ -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);
if (gMtftp4ControllerNameTable != NULL) {
FreeUnicodeStringTable (gMtftp4ControllerNameTable);
gMtftp4ControllerNameTable = NULL;
}
FreePool (MtftpSb);
} else {
while (!IsListEmpty (&MtftpSb->Children)) {
Instance = NET_LIST_HEAD (&MtftpSb->Children, MTFTP4_PROTOCOL, Link);
Mtftp4ServiceBindingDestroyChild (ServiceBinding, Instance->Handle);
}
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.
//

View File

@ -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.

View File

@ -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;
}

View File

@ -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.

View File

@ -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;

View File

@ -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.
@ -231,6 +233,78 @@ SimpleNetworkComponentNameGetDriverName (
);
}
/**
Update the component name for the Snp child handle.
@param Snp[in] A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL.
@retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
@retval EFI_INVALID_PARAMETER The input parameter is invalid.
**/
EFI_STATUS
UpdateName (
IN EFI_SIMPLE_NETWORK_PROTOCOL *Snp
)
{
EFI_STATUS Status;
CHAR16 HandleName[80];
UINTN OffSet;
UINTN Index;
if (Snp == NULL) {
return EFI_INVALID_PARAMETER;
}
OffSet = 0;
OffSet += UnicodeSPrint (
HandleName,
sizeof (HandleName),
L"SNP (MAC="
);
for (Index = 0; Index < Snp->Mode->HwAddressSize; Index++) {
OffSet += UnicodeSPrint (
HandleName + OffSet,
sizeof (HandleName) - OffSet,
L"%02X-",
Snp->Mode->CurrentAddress.Addr[Index]
);
}
//
// Remove the last '-'
//
OffSet--;
OffSet += UnicodeSPrint (
HandleName,
sizeof (HandleName),
L")"
);
if (gSimpleNetworkControllerNameTable != NULL) {
FreeUnicodeStringTable (gSimpleNetworkControllerNameTable);
gSimpleNetworkControllerNameTable = NULL;
}
Status = AddUnicodeString2 (
"eng",
gSimpleNetworkComponentName.SupportedLanguages,
&gSimpleNetworkControllerNameTable,
HandleName,
TRUE
);
if (EFI_ERROR (Status)) {
return Status;
}
return AddUnicodeString2 (
"en",
gSimpleNetworkComponentName2.SupportedLanguages,
&gSimpleNetworkControllerNameTable,
HandleName,
FALSE
);
}
/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
@ -310,5 +384,52 @@ SimpleNetworkComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
return EFI_UNSUPPORTED;
EFI_STATUS Status;
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
if (ChildHandle != NULL) {
return EFI_UNSUPPORTED;
}
//
// Make sure this driver is currently managing ControllHandle
//
Status = EfiTestManagedDevice (
ControllerHandle,
gSimpleNetworkDriverBinding.DriverBindingHandle,
&gEfiSimpleNetworkProtocolGuid
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Retrieve an instance of a produced protocol from ControllerHandle
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiSimpleNetworkProtocolGuid,
(VOID **)&Snp,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Update the component name for this child handle.
//
Status = UpdateName (Snp);
if (EFI_ERROR (Status)) {
return Status;
}
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
gSimpleNetworkControllerNameTable,
ControllerName,
(BOOLEAN)(This == &gSimpleNetworkComponentName)
);
}

View File

@ -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

View File

@ -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;

View File

@ -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.
@ -227,6 +229,76 @@ TcpComponentNameGetDriverName (
);
}
/**
Update the component name for the Tcp4 child handle.
@param Tcp4[in] A pointer to the EFI_TCP4_PROTOCOL.
@retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
@retval EFI_INVALID_PARAMETER The input parameter is invalid.
**/
EFI_STATUS
UpdateName (
IN EFI_TCP4_PROTOCOL *Tcp4
)
{
EFI_STATUS Status;
CHAR16 HandleName[80];
EFI_TCP4_CONFIG_DATA Tcp4ConfigData;
if (Tcp4 == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Format the child name into the string buffer as:
// TCPv4 (SrcPort=59, DestPort=60, ActiveFlag=TRUE)
//
Status = Tcp4->GetModeData (Tcp4, NULL, &Tcp4ConfigData, NULL, NULL, NULL);
if (!EFI_ERROR (Status)) {
UnicodeSPrint (HandleName, sizeof (HandleName),
L"TCPv4 (SrcPort=%d, DestPort=&d, ActiveFlag=%s)",
Tcp4ConfigData.AccessPoint.StationPort,
Tcp4ConfigData.AccessPoint.RemotePort,
(Tcp4ConfigData.AccessPoint.ActiveFlag ? L"TRUE" : L"FALSE")
);
} if (Status == EFI_NOT_STARTED) {
UnicodeSPrint (
HandleName,
sizeof (HandleName),
L"TCPv4 (Not started)"
);
} else {
return Status;
}
if (gTcpControllerNameTable != NULL) {
FreeUnicodeStringTable (gTcpControllerNameTable);
gTcpControllerNameTable = NULL;
}
Status = AddUnicodeString2 (
"eng",
gTcp4ComponentName.SupportedLanguages,
&gTcpControllerNameTable,
HandleName,
TRUE
);
if (EFI_ERROR (Status)) {
return Status;
}
return AddUnicodeString2 (
"en",
gTcp4ComponentName2.SupportedLanguages,
&gTcpControllerNameTable,
HandleName,
FALSE
);
}
/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
@ -305,5 +377,56 @@ TcpComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
return EFI_UNSUPPORTED;
EFI_STATUS Status;
EFI_TCP4_PROTOCOL *Tcp4;
//
// Only provide names for child handles.
//
if (ChildHandle == NULL) {
return EFI_UNSUPPORTED;
}
//
// Make sure this driver produced ChildHandle
//
Status = EfiTestChildHandle (
ControllerHandle,
ChildHandle,
&gEfiIp4ProtocolGuid
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Retrieve an instance of a produced protocol from ChildHandle
//
Status = gBS->OpenProtocol (
ChildHandle,
&gEfiTcp4ProtocolGuid,
(VOID **)&Tcp4,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Update the component name for this child handle.
//
Status = UpdateName (Tcp4);
if (EFI_ERROR (Status)) {
return Status;
}
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
gTcpControllerNameTable,
ControllerName,
(BOOLEAN)(This == &gTcp4ComponentName)
);
}

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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,
@ -135,6 +136,43 @@ Tcp4DestroyTimer (
mTcp4Timer.TimerEvent = NULL;
}
/**
Callback function which provided by user to remove one node in NetDestroyLinkList process.
@param[in] Entry The entry to be removed.
@param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
@retval EFI_SUCCESS The entry has been removed successfully.
@retval Others Fail to remove the entry.
**/
EFI_STATUS
Tcp4DestroyChildEntryInHandleBuffer (
IN LIST_ENTRY *Entry,
IN VOID *Context
)
{
SOCKET *Sock;
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
UINTN NumberOfChildren;
EFI_HANDLE *ChildHandleBuffer;
if (Entry == NULL || Context == NULL) {
return EFI_INVALID_PARAMETER;
}
Sock = NET_LIST_USER_STRUCT_S (Entry, SOCKET, Link, SOCK_SIGNATURE);
ServiceBinding = ((TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;
NumberOfChildren = ((TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;
ChildHandleBuffer = ((TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;
if (!NetIsInHandleBuffer (Sock->SockHandle, NumberOfChildren, ChildHandleBuffer)) {
return EFI_SUCCESS;
}
return ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle);
}
/**
The entry point for Tcp4 driver, used to install Tcp4 driver on the ImageHandle.
@ -387,6 +425,7 @@ ON_ERROR:
if (TcpServiceData->IpIo != NULL) {
IpIoDestroy (TcpServiceData->IpIo);
TcpServiceData->IpIo = NULL;
}
FreePool (TcpServiceData);
@ -431,17 +470,18 @@ Tcp4DriverBindingStop (
IN EFI_HANDLE *ChildHandleBuffer
)
{
EFI_STATUS Status;
EFI_HANDLE NicHandle;
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
TCP4_SERVICE_DATA *TcpServiceData;
SOCKET *Sock;
EFI_STATUS Status;
EFI_HANDLE NicHandle;
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
TCP4_SERVICE_DATA *TcpServiceData;
LIST_ENTRY *List;
TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
// Find the NicHandle where Tcp4 ServiceBinding Protocol is installed.
//
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);
if (NicHandle == NULL) {
return EFI_DEVICE_ERROR;
return EFI_SUCCESS;
}
//
@ -465,7 +505,18 @@ Tcp4DriverBindingStop (
TcpServiceData = TCP4_FROM_THIS (ServiceBinding);
if (NumberOfChildren == 0) {
if (NumberOfChildren != 0) {
List = &TcpServiceData->SocketList;
Context.ServiceBinding = ServiceBinding;
Context.NumberOfChildren = NumberOfChildren;
Context.ChildHandleBuffer = ChildHandleBuffer;
Status = NetDestroyLinkList (
List,
Tcp4DestroyChildEntryInHandleBuffer,
&Context,
NULL
);
} else if (IsListEmpty (&TcpServiceData->SocketList)) {
//
// Uninstall TCP servicebinding protocol
//
@ -480,6 +531,7 @@ Tcp4DriverBindingStop (
// Destroy the IpIO consumed by TCP driver
//
IpIoDestroy (TcpServiceData->IpIo);
TcpServiceData->IpIo = NULL;
//
// Destroy the heartbeat timer.
@ -491,17 +543,17 @@ Tcp4DriverBindingStop (
//
TcpClearVariableData (TcpServiceData);
if (gTcpControllerNameTable != NULL) {
FreeUnicodeStringTable (gTcpControllerNameTable);
gTcpControllerNameTable = NULL;
}
//
// Release the TCP service data
//
FreePool (TcpServiceData);
} else {
while (!IsListEmpty (&TcpServiceData->SocketList)) {
Sock = NET_LIST_HEAD (&TcpServiceData->SocketList, SOCKET, Link);
ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle);
}
Status = EFI_SUCCESS;
}
return Status;
@ -713,14 +765,11 @@ Tcp4ServiceBindingDestroyChild (
EFI_STATUS Status;
EFI_TCP4_PROTOCOL *Tcp4;
SOCKET *Sock;
EFI_TPL OldTpl;
if (NULL == This || NULL == ChildHandle) {
return EFI_INVALID_PARAMETER;
}
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
//
// retrieve the Tcp4 protocol from ChildHandle
//
@ -744,7 +793,6 @@ Tcp4ServiceBindingDestroyChild (
SockDestroyChild (Sock);
}
gBS->RestoreTPL (OldTpl);
return Status;
}

View File

@ -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.

View File

@ -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.
@ -230,6 +232,75 @@ UdpComponentNameGetDriverName (
);
}
/**
Update the component name for the Udp4 child handle.
@param Udp4[in] A pointer to the EFI_UDP4_PROTOCOL.
@retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
@retval EFI_INVALID_PARAMETER The input parameter is invalid.
**/
EFI_STATUS
UpdateName (
EFI_UDP4_PROTOCOL *Udp4
)
{
EFI_STATUS Status;
CHAR16 HandleName[64];
EFI_UDP4_CONFIG_DATA Udp4ConfigData;
if (Udp4 == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Format the child name into the string buffer as:
// UDPv4 (SrcPort=59, DestPort=60)
//
Status = Udp4->GetModeData (Udp4, &Udp4ConfigData, NULL, NULL, NULL);
if (!EFI_ERROR (Status)) {
UnicodeSPrint (HandleName, sizeof (HandleName),
L"UDPv4 (SrcPort=%d, DestPort=%d)",
Udp4ConfigData.StationPort,
Udp4ConfigData.RemotePort
);
} else if (Status == EFI_NOT_STARTED) {
UnicodeSPrint (
HandleName,
sizeof (HandleName),
L"UDPv4 (Not started)"
);
} else {
return Status;
}
if (gUdpControllerNameTable != NULL) {
FreeUnicodeStringTable (gUdpControllerNameTable);
gUdpControllerNameTable = NULL;
}
Status = AddUnicodeString2 (
"eng",
gUdp4ComponentName.SupportedLanguages,
&gUdpControllerNameTable,
HandleName,
TRUE
);
if (EFI_ERROR (Status)) {
return Status;
}
return AddUnicodeString2 (
"en",
gUdp4ComponentName2.SupportedLanguages,
&gUdpControllerNameTable,
HandleName,
FALSE
);
}
/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
@ -308,6 +379,57 @@ UdpComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
return EFI_UNSUPPORTED;
EFI_STATUS Status;
EFI_UDP4_PROTOCOL *Udp4;
//
// Only provide names for child handles.
//
if (ChildHandle == NULL) {
return EFI_UNSUPPORTED;
}
//
// Make sure this driver produced ChildHandle
//
Status = EfiTestChildHandle (
ControllerHandle,
ChildHandle,
&gEfiIp4ProtocolGuid
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Retrieve an instance of a produced protocol from ChildHandle
//
Status = gBS->OpenProtocol (
ChildHandle,
&gEfiUdp4ProtocolGuid,
(VOID **)&Udp4,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Update the component name for this child handle.
//
Status = UpdateName (Udp4);
if (EFI_ERROR (Status)) {
return Status;
}
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
gUdpControllerNameTable,
ControllerName,
(BOOLEAN)(This == &gUdp4ComponentName)
);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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.

View File

@ -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)
);
}

View File

@ -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;
}
}
}

View File

@ -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
@ -517,6 +518,22 @@ InstallVlanConfigForm (
}
PrivateData->DriverHandle = DriverHandle;
//
// Establish the parent-child relationship between the new created
// child handle and the ControllerHandle.
//
Status = gBS->OpenProtocol (
PrivateData->ControllerHandle,
&gEfiVlanConfigProtocolGuid,
(VOID **)&VlanConfig,
PrivateData->ImageHandle,
PrivateData->DriverHandle,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Publish the HII package list
//
@ -593,6 +610,16 @@ UninstallVlanConfigForm (
PrivateData->HiiHandle = NULL;
}
//
// End the parent-child relationship.
//
gBS->CloseProtocol (
PrivateData->ControllerHandle,
&gEfiVlanConfigProtocolGuid,
PrivateData->ImageHandle,
PrivateData->DriverHandle
);
//
// Uninstall HII Config Access Protocol
//

View File

@ -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)
);
}

View File

@ -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;
}

View File

@ -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

View File

@ -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.
//

View File

@ -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;
};
/**

View File

@ -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;
}

View File

@ -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.
@ -99,6 +101,99 @@ IScsiComponentNameGetDriverName (
);
}
/**
Update the component name for the iSCSI NIC handle.
@param[in] Controller The handle of the NIC controller.
@param[in] Ipv6Flag TRUE if IP6 network stack is used.
@retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
@retval EFI_INVALID_PARAMETER The input parameter is invalid.
@retval EFI_UNSUPPORTED Can't get the corresponding NIC info from the Controller handle.
**/
EFI_STATUS
UpdateName (
IN EFI_HANDLE Controller,
IN BOOLEAN Ipv6Flag
)
{
EFI_STATUS Status;
EFI_MAC_ADDRESS MacAddr;
UINTN HwAddressSize;
UINT16 VlanId;
ISCSI_NIC_INFO *ThisNic;
ISCSI_NIC_INFO *NicInfo;
LIST_ENTRY *Entry;
CHAR16 HandleName[80];
//
// Get MAC address of this network device.
//
Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Get VLAN ID of this network device.
//
VlanId = NetLibGetVlanId (Controller);
//
// Check whether the NIC information exists.
//
ThisNic = NULL;
NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {
NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);
if (NicInfo->HwAddressSize == HwAddressSize &&
CompareMem (&NicInfo->PermanentAddress, MacAddr.Addr, HwAddressSize) == 0 &&
NicInfo->VlanId == VlanId) {
ThisNic = NicInfo;
break;
}
}
if (ThisNic == NULL) {
return EFI_UNSUPPORTED;
}
UnicodeSPrint (
HandleName,
sizeof (HandleName),
L"iSCSI (%s, NicIndex=%d)",
Ipv6Flag ? L"IPv6" : L"IPv4",
ThisNic->NicIndex
);
if (gIScsiControllerNameTable != NULL) {
FreeUnicodeStringTable (gIScsiControllerNameTable);
gIScsiControllerNameTable = NULL;
}
Status = AddUnicodeString2 (
"eng",
gIScsiComponentName.SupportedLanguages,
&gIScsiControllerNameTable,
HandleName,
TRUE
);
if (EFI_ERROR (Status)) {
return Status;
}
return AddUnicodeString2 (
"en",
gIScsiComponentName2.SupportedLanguages,
&gIScsiControllerNameTable,
HandleName,
FALSE
);
}
/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
@ -177,5 +272,54 @@ IScsiComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
return EFI_UNSUPPORTED;
EFI_HANDLE IScsiController;
BOOLEAN Ipv6Flag;
EFI_STATUS Status;
EFI_GUID *IScsiPrivateGuid;
ISCSI_PRIVATE_PROTOCOL *IScsiIdentifier;
//
// Get the handle of the controller we are controling.
//
IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp4ProtocolGuid);
if (IScsiController != NULL) {
IScsiPrivateGuid = &gIScsiV4PrivateGuid;
Ipv6Flag = FALSE;
} else {
IScsiController = NetLibGetNicHandle (ControllerHandle, &gEfiTcp6ProtocolGuid);
if (IScsiController != NULL) {
IScsiPrivateGuid = &gIScsiV6PrivateGuid;
Ipv6Flag = TRUE;
} else {
return EFI_UNSUPPORTED;
}
}
//
// Retrieve an instance of a produced protocol from IScsiController
//
Status = gBS->OpenProtocol (
IScsiController,
IScsiPrivateGuid,
(VOID **) &IScsiIdentifier,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = UpdateName(IScsiController, Ipv6Flag);
if (EFI_ERROR(Status)) {
return Status;
}
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
gIScsiControllerNameTable,
ControllerName,
(BOOLEAN)(This == &gIScsiComponentName)
);
}

View File

@ -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;

View File

@ -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 ':'

View File

@ -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,

View File

@ -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];

View File

@ -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);
}

View File

@ -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.
@ -231,6 +233,88 @@ Ip6ComponentNameGetDriverName (
}
/**
Update the component name for the IP6 child handle.
@param Ip6[in] A pointer to the EFI_IP6_PROTOCOL.
@retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
@retval EFI_INVALID_PARAMETER The input parameter is invalid.
**/
EFI_STATUS
UpdateName (
IN EFI_IP6_PROTOCOL *Ip6
)
{
EFI_STATUS Status;
CHAR16 HandleName[128];
EFI_IP6_MODE_DATA Ip6ModeData;
UINTN Offset;
CHAR16 Address[sizeof"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
if (Ip6 == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Format the child name into the string buffer.
//
Offset = 0;
Status = Ip6->GetModeData (Ip6, &Ip6ModeData, NULL, NULL);
if (!EFI_ERROR (Status) && Ip6ModeData.IsStarted) {
Status = NetLibIp6ToStr (&Ip6ModeData.ConfigData.StationAddress, Address, sizeof(Address));
if (EFI_ERROR (Status)) {
return Status;
}
Offset += UnicodeSPrint (
HandleName,
sizeof(HandleName),
L"IPv6(StationAddress=%s, ",
Address
);
Status = NetLibIp6ToStr (&Ip6ModeData.ConfigData.DestinationAddress, Address, sizeof(Address));
if (EFI_ERROR (Status)) {
return Status;
}
UnicodeSPrint (
HandleName + Offset,
sizeof(HandleName) - Offset,
L"DestinationAddress=%s)",
Address
);
} else if (!Ip6ModeData.IsStarted) {
UnicodeSPrint (HandleName, sizeof(HandleName), L"IPv6(Not started)");
} else {
UnicodeSPrint (HandleName, sizeof(HandleName), L"IPv6(%r)", Status);
}
if (gIp6ControllerNameTable != NULL) {
FreeUnicodeStringTable (gIp6ControllerNameTable);
gIp6ControllerNameTable = NULL;
}
Status = AddUnicodeString2 (
"eng",
gIp6ComponentName.SupportedLanguages,
&gIp6ControllerNameTable,
HandleName,
TRUE
);
if (EFI_ERROR (Status)) {
return Status;
}
return AddUnicodeString2 (
"en",
gIp6ComponentName2.SupportedLanguages,
&gIp6ControllerNameTable,
HandleName,
FALSE
);
}
/**
Retrieves a Unicode string that is the user-readable name of the controller
that is being managed by a driver.
@ -309,5 +393,56 @@ Ip6ComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
return EFI_UNSUPPORTED;
EFI_STATUS Status;
EFI_IP6_PROTOCOL *Ip6;
//
// Only provide names for child handles.
//
if (ChildHandle == NULL) {
return EFI_UNSUPPORTED;
}
//
// Make sure this driver produced ChildHandle
//
Status = EfiTestChildHandle (
ControllerHandle,
ChildHandle,
&gEfiManagedNetworkProtocolGuid
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Retrieve an instance of a produced protocol from ChildHandle
//
Status = gBS->OpenProtocol (
ChildHandle,
&gEfiIp6ProtocolGuid,
(VOID **)&Ip6,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Update the component name for this child handle.
//
Status = UpdateName (Ip6);
if (EFI_ERROR (Status)) {
return Status;
}
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
gIp6ControllerNameTable,
ControllerName,
(BOOLEAN)(This == &gIp6ComponentName)
);
}

View File

@ -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
@ -328,6 +328,37 @@ Ip6AddAddr (
IpIf->AddressCount++;
}
/**
Callback function which provided by user to remove one node in NetDestroyLinkList process.
@param[in] Entry The entry to be removed.
@param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
@retval EFI_SUCCESS The entry has been removed successfully.
@retval Others Fail to remove the entry.
**/
EFI_STATUS
Ip6DestroyChildEntryByAddr (
IN LIST_ENTRY *Entry,
IN VOID *Context
)
{
IP6_PROTOCOL *Instance;
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
EFI_IPv6_ADDRESS *Address;
Instance = NET_LIST_USER_STRUCT_S (Entry, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE);
ServiceBinding = ((IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT*) Context)->ServiceBinding;
Address = ((IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT*) Context)->Address;
if ((Instance->State == IP6_STATE_CONFIGED) && EFI_IP6_EQUAL (&Instance->ConfigData.StationAddress, Address)) {
return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
}
return EFI_SUCCESS;
}
/**
Destroy the IP instance if its StationAddress is removed. It is the help function
for Ip6RemoveAddr().
@ -342,35 +373,20 @@ Ip6DestroyInstanceByAddress (
IN EFI_IPv6_ADDRESS *Address
)
{
BOOLEAN OneDestroyed;
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
LIST_ENTRY *Entry;
IP6_PROTOCOL *Instance;
LIST_ENTRY *List;
IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT Context;
NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
ServiceBinding = &IpSb->ServiceBinding;
//
// Upper layer IP protocol consumers may have tight relationship between several
// IP protocol instances, in other words, calling ServiceBinding->DestroyChild to
// destroy one IP child may cause other related IP children destroyed too. This
// will probably leave hole in the children list when we iterate it. So everytime
// we just destroy one child then back to the start point to iterate the list.
//
do {
OneDestroyed = FALSE;
NET_LIST_FOR_EACH (Entry, &IpSb->Children) {
Instance = NET_LIST_USER_STRUCT_S (Entry, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE);
if ((Instance->State == IP6_STATE_CONFIGED) && EFI_IP6_EQUAL (&Instance->ConfigData.StationAddress, Address)) {
ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
OneDestroyed = TRUE;
break;
}
}
} while (OneDestroyed);
List = &IpSb->Children;
Context.ServiceBinding = &IpSb->ServiceBinding;
Context.Address = Address;
NetDestroyLinkList (
List,
Ip6DestroyChildEntryByAddr,
&Context,
NULL
);
}
/**

View File

@ -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;

View File

@ -114,14 +114,16 @@ Ip6CleanService (
Ip6ConfigCleanInstance (&IpSb->Ip6ConfigInstance);
//
// Leave link-scope all-nodes multicast address (FF02::1)
//
Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &AllNodes);
if (!IpSb->LinkLocalDadFail) {
//
// Leave link-scope all-nodes multicast address (FF02::1)
//
Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &AllNodes);
Status = Ip6LeaveGroup (IpSb, &AllNodes);
if (EFI_ERROR (Status)) {
return Status;
Status = Ip6LeaveGroup (IpSb, &AllNodes);
if (EFI_ERROR (Status)) {
return Status;
}
}
if (IpSb->DefaultInterface != NULL) {
@ -244,7 +246,6 @@ Ip6CreateService (
IpSb->ServiceBinding.CreateChild = Ip6ServiceBindingCreateChild;
IpSb->ServiceBinding.DestroyChild = Ip6ServiceBindingDestroyChild;
IpSb->State = IP6_SERVICE_UNSTARTED;
IpSb->InDestroy = FALSE;
IpSb->NumChildren = 0;
InitializeListHead (&IpSb->Children);
@ -572,6 +573,43 @@ Ip6DriverBindingStart (
return Status;
}
/**
Callback function which provided by user to remove one node in NetDestroyLinkList process.
@param[in] Entry The entry to be removed.
@param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
@retval EFI_SUCCESS The entry has been removed successfully.
@retval Others Fail to remove the entry.
**/
EFI_STATUS
Ip6DestroyChildEntryInHandleBuffer (
IN LIST_ENTRY *Entry,
IN VOID *Context
)
{
IP6_PROTOCOL *IpInstance;
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
UINTN NumberOfChildren;
EFI_HANDLE *ChildHandleBuffer;
if (Entry == NULL || Context == NULL) {
return EFI_INVALID_PARAMETER;
}
IpInstance = NET_LIST_USER_STRUCT_S (Entry, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE);
ServiceBinding = ((IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;
NumberOfChildren = ((IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;
ChildHandleBuffer = ((IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;
if (!NetIsInHandleBuffer (IpInstance->Handle, NumberOfChildren, ChildHandleBuffer)) {
return EFI_SUCCESS;
}
return ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle);
}
/**
Stop this driver on ControllerHandle.
@ -595,30 +633,23 @@ Ip6DriverBindingStop (
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
)
{
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
IP6_SERVICE *IpSb;
IP6_PROTOCOL *IpInstance;
EFI_HANDLE NicHandle;
EFI_STATUS Status;
BOOLEAN IsDhcp6;
EFI_TPL OldTpl;
INTN State;
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
IP6_SERVICE *IpSb;
EFI_HANDLE NicHandle;
EFI_STATUS Status;
LIST_ENTRY *List;
INTN State;
BOOLEAN IsDhcp6;
IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
IsDhcp6 = FALSE;
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp6ProtocolGuid);
if (NicHandle != NULL) {
//
// DriverBindingStop is triggered by the uninstallation of the EFI DHCPv6
// Protocol used by Ip6Config.
//
IsDhcp6 = TRUE;
} else {
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
if (NicHandle == NULL) {
return EFI_DEVICE_ERROR;
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
if (NicHandle == NULL) {
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp6ProtocolGuid);
if (NicHandle != NULL) {
IsDhcp6 = TRUE;
} else {
return EFI_SUCCESS;
}
}
@ -636,21 +667,25 @@ Ip6DriverBindingStop (
IpSb = IP6_SERVICE_FROM_PROTOCOL (ServiceBinding);
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
if (IpSb->InDestroy) {
Status = EFI_SUCCESS;
goto Exit;
}
if (IsDhcp6) {
Status = Ip6ConfigDestroyDhcp6 (&IpSb->Ip6ConfigInstance);
gBS->CloseEvent (IpSb->Ip6ConfigInstance.Dhcp6Event);
IpSb->Ip6ConfigInstance.Dhcp6Event = NULL;
} else if (NumberOfChildren == 0) {
IpSb->InDestroy = TRUE;
} else if (NumberOfChildren != 0) {
//
// NumberOfChildren is not zero, destroy the IP6 children instances in ChildHandleBuffer.
//
List = &IpSb->Children;
Context.ServiceBinding = ServiceBinding;
Context.NumberOfChildren = NumberOfChildren;
Context.ChildHandleBuffer = ChildHandleBuffer;
Status = NetDestroyLinkList (
List,
Ip6DestroyChildEntryInHandleBuffer,
&Context,
NULL
);
} else if (IsListEmpty (&IpSb->Children)) {
State = IpSb->State;
IpSb->State = IP6_SERVICE_DESTROY;
@ -675,24 +710,10 @@ Ip6DriverBindingStop (
);
ASSERT_EFI_ERROR (Status);
FreePool (IpSb);
} else {
//
// NumberOfChildren is not zero, destroy all IP6 children instances.
//
while (!IsListEmpty (&IpSb->Children)) {
IpInstance = NET_LIST_HEAD (&IpSb->Children, IP6_PROTOCOL, Link);
ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle);
}
if (IpSb->NumChildren != 0) {
Status = EFI_DEVICE_ERROR;
}
Status = EFI_SUCCESS;
}
Exit:
gBS->RestoreTPL (OldTpl);
return Status;
}
@ -830,7 +851,6 @@ Ip6ServiceBindingDestroyChild (
IP6_PROTOCOL *IpInstance;
EFI_IP6_PROTOCOL *Ip6;
EFI_TPL OldTpl;
INTN State;
if ((This == NULL) || (ChildHandle == NULL)) {
return EFI_INVALID_PARAMETER;
@ -868,13 +888,12 @@ Ip6ServiceBindingDestroyChild (
// when UDP driver is being stopped, it will destroy all
// the IP child it opens.
//
if (IpInstance->State == IP6_STATE_DESTROY) {
if (IpInstance->InDestroy) {
gBS->RestoreTPL (OldTpl);
return EFI_SUCCESS;
}
State = IpInstance->State;
IpInstance->State = IP6_STATE_DESTROY;
IpInstance->InDestroy = TRUE;
//
// Close the Managed Network protocol.
@ -900,12 +919,13 @@ Ip6ServiceBindingDestroyChild (
// will be called back before preceeding. If any packets not recycled,
// that means there is a resource leak.
//
gBS->RestoreTPL (OldTpl);
Status = gBS->UninstallProtocolInterface (
ChildHandle,
&gEfiIp6ProtocolGuid,
&IpInstance->Ip6Proto
);
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
@ -935,7 +955,6 @@ Ip6ServiceBindingDestroyChild (
return EFI_SUCCESS;
ON_ERROR:
IpInstance->State = State;
gBS->RestoreTPL (OldTpl);
return Status;

View File

@ -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

View File

@ -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;

View File

@ -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) {

View File

@ -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

View File

@ -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;

View File

@ -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)
);
}

View File

@ -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.
@ -226,6 +228,74 @@ Mtftp6ComponentNameGetDriverName (
);
}
/**
Update the component name for the Mtftp6 child handle.
@param Mtftp6[in] A pointer to the EFI_MTFTP6_PROTOCOL.
@retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
@retval EFI_INVALID_PARAMETER The input parameter is invalid.
**/
EFI_STATUS
UpdateName (
IN EFI_MTFTP6_PROTOCOL *Mtftp6
)
{
EFI_STATUS Status;
CHAR16 HandleName[128];
EFI_MTFTP6_MODE_DATA Mtftp6ModeData;
CHAR16 Address[sizeof"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
if (Mtftp6 == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Format the child name into the string buffer.
//
Status = Mtftp6->GetModeData (Mtftp6, &Mtftp6ModeData);
if (!EFI_ERROR (Status)) {
Status = NetLibIp6ToStr (&Mtftp6ModeData.ConfigData.ServerIp, Address, sizeof(Address));
if (EFI_ERROR (Status)) {
return Status;
}
UnicodeSPrint (HandleName, sizeof (HandleName),
L"MTFTPv6(ServerIp=%s, InitialServerPort=%d)",
Address,
Mtftp6ModeData.ConfigData.InitialServerPort
);
} else {
UnicodeSPrint (HandleName, 0x100, L"MTFTPv6(%r)", Status);
}
if (gMtftp6ControllerNameTable != NULL) {
FreeUnicodeStringTable (gMtftp6ControllerNameTable);
gMtftp6ControllerNameTable = NULL;
}
Status = AddUnicodeString2 (
"eng",
gMtftp6ComponentName.SupportedLanguages,
&gMtftp6ControllerNameTable,
HandleName,
TRUE
);
if (EFI_ERROR (Status)) {
return Status;
}
return AddUnicodeString2 (
"en",
gMtftp6ComponentName2.SupportedLanguages,
&gMtftp6ControllerNameTable,
HandleName,
FALSE
);
}
/**
Retrieves a Unicode string that is the user-readable name of the controller
that is being managed by a driver.
@ -304,5 +374,57 @@ Mtftp6ComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
return EFI_UNSUPPORTED;
EFI_STATUS Status;
EFI_MTFTP6_PROTOCOL *Mtftp6;
//
// Only provide names for child handles.
//
if (ChildHandle == NULL) {
return EFI_UNSUPPORTED;
}
//
// Make sure this driver produced ChildHandle
//
Status = EfiTestChildHandle (
ControllerHandle,
ChildHandle,
&gEfiUdp6ProtocolGuid
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Retrieve an instance of a produced protocol from ChildHandle
//
Status = gBS->OpenProtocol (
ChildHandle,
&gEfiMtftp6ProtocolGuid,
(VOID **)&Mtftp6,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Update the component name for this child handle.
//
Status = UpdateName (Mtftp6);
if (EFI_ERROR (Status)) {
return Status;
}
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
gMtftp6ControllerNameTable,
ControllerName,
(BOOLEAN)(This == &gMtftp6ComponentName)
);
}

View File

@ -98,7 +98,6 @@ Mtftp6CreateService (
Mtftp6Srv->Signature = MTFTP6_SERVICE_SIGNATURE;
Mtftp6Srv->Controller = Controller;
Mtftp6Srv->Image = Image;
Mtftp6Srv->InDestroy = FALSE;
Mtftp6Srv->ChildrenNum = 0;
CopyMem (
@ -237,6 +236,44 @@ Mtftp6CreateInstance (
}
/**
Callback function which provided by user to remove one node in NetDestroyLinkList process.
@param[in] Entry The entry to be removed.
@param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
@retval EFI_SUCCESS The entry has been removed successfully.
@retval Others Fail to remove the entry.
**/
EFI_STATUS
Mtftp6DestroyChildEntryInHandleBuffer (
IN LIST_ENTRY *Entry,
IN VOID *Context
)
{
MTFTP6_INSTANCE *Instance;
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
UINTN NumberOfChildren;
EFI_HANDLE *ChildHandleBuffer;
if (Entry == NULL || Context == NULL) {
return EFI_INVALID_PARAMETER;
}
Instance = NET_LIST_USER_STRUCT_S (Entry, MTFTP6_INSTANCE, Link, MTFTP6_INSTANCE_SIGNATURE);
ServiceBinding = ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;
NumberOfChildren = ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;
ChildHandleBuffer = ((MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;
if (!NetIsInHandleBuffer (Instance->Handle, NumberOfChildren, ChildHandleBuffer)) {
return EFI_SUCCESS;
}
return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
}
/**
This is the declaration of an EFI image entry point. This entry point is
the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
@ -429,20 +466,20 @@ Mtftp6DriverBindingStop (
IN EFI_HANDLE *ChildHandleBuffer
)
{
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
MTFTP6_SERVICE *Service;
MTFTP6_INSTANCE *Instance;
EFI_HANDLE NicHandle;
EFI_STATUS Status;
EFI_TPL OldTpl;
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
MTFTP6_SERVICE *Service;
EFI_HANDLE NicHandle;
EFI_STATUS Status;
LIST_ENTRY *List;
MTFTP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
//
// Locate the Nic handle to retrieve the Mtftp6 private data.
//
NicHandle = NetLibGetNicHandle (Controller, &gEfiUdp6ProtocolGuid);
if (NicHandle == NULL) {
return EFI_DEVICE_ERROR;
return EFI_SUCCESS;
}
Status = gBS->OpenProtocol (
@ -460,18 +497,26 @@ Mtftp6DriverBindingStop (
Service = MTFTP6_SERVICE_FROM_THIS (ServiceBinding);
if (Service->InDestroy) {
return EFI_SUCCESS;
if (!IsListEmpty (&Service->Children)) {
//
// Destroy the Mtftp6 child instance in ChildHandleBuffer.
//
List = &Service->Children;
Context.ServiceBinding = ServiceBinding;
Context.NumberOfChildren = NumberOfChildren;
Context.ChildHandleBuffer = ChildHandleBuffer;
Status = NetDestroyLinkList (
List,
Mtftp6DestroyChildEntryInHandleBuffer,
&Context,
NULL
);
}
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
if (NumberOfChildren == 0) {
if (NumberOfChildren == 0 && IsListEmpty (&Service->Children)) {
//
// Destroy the Mtftp6 service if there is no Mtftp6 child instance left.
//
Service->InDestroy = TRUE;
gBS->UninstallProtocolInterface (
NicHandle,
&gEfiMtftp6ServiceBindingProtocolGuid,
@ -479,22 +524,9 @@ Mtftp6DriverBindingStop (
);
Mtftp6DestroyService (Service);
} else {
//
// Destroy the Mtftp6 child instance one by one.
//
while (!IsListEmpty (&Service->Children)) {
Instance = NET_LIST_HEAD (&Service->Children, MTFTP6_INSTANCE, Link);
Mtftp6ServiceBindingDestroyChild (ServiceBinding, Instance->Handle);
}
if (Service->ChildrenNum != 0) {
Status = EFI_DEVICE_ERROR;
}
Status = EFI_SUCCESS;
}
gBS->RestoreTPL (OldTpl);
return Status;
}
@ -674,15 +706,34 @@ Mtftp6ServiceBindingDestroyChild (
ChildHandle
);
if (Instance->UdpIo != NULL) {
gBS->CloseProtocol (
Instance->UdpIo->UdpHandle,
&gEfiUdp6ProtocolGuid,
gMtftp6DriverBinding.DriverBindingHandle,
Instance->Handle
);
}
if (Instance->McastUdpIo != NULL) {
gBS->CloseProtocol (
Instance->McastUdpIo->UdpHandle,
&gEfiUdp6ProtocolGuid,
gMtftp6DriverBinding.DriverBindingHandle,
Instance->Handle
);
}
//
// Uninstall the MTFTP6 protocol first to enable a top down destruction.
//
gBS->RestoreTPL (OldTpl);
Status = gBS->UninstallProtocolInterface (
ChildHandle,
&gEfiMtftp6ProtocolGuid,
Mtftp6
);
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
if (EFI_ERROR (Status)) {
Instance->InDestroy = FALSE;
gBS->RestoreTPL (OldTpl);
@ -695,9 +746,9 @@ Mtftp6ServiceBindingDestroyChild (
RemoveEntryList (&Instance->Link);
Service->ChildrenNum --;
Mtftp6DestroyInstance (Instance);
gBS->RestoreTPL (OldTpl);
Mtftp6DestroyInstance (Instance);
return EFI_SUCCESS;
}

View File

@ -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

View File

@ -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;

View File

@ -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.

View File

@ -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) {

View File

@ -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;
}

View File

@ -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.
@ -224,6 +226,142 @@ TcpComponentNameGetDriverName (
);
}
/**
Update the component name for the Tcp4 child handle.
@param Tcp4[in] A pointer to the EFI_TCP4_PROTOCOL.
@retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
@retval EFI_INVALID_PARAMETER The input parameter is invalid.
**/
EFI_STATUS
UpdateTcp4Name (
IN EFI_TCP4_PROTOCOL *Tcp4
)
{
EFI_STATUS Status;
CHAR16 HandleName[80];
EFI_TCP4_CONFIG_DATA Tcp4ConfigData;
if (Tcp4 == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Format the child name into the string buffer as:
// TCPv4 (SrcPort=59, DestPort=60, ActiveFlag=TRUE)
//
Status = Tcp4->GetModeData (Tcp4, NULL, &Tcp4ConfigData, NULL, NULL, NULL);
if (!EFI_ERROR (Status)) {
UnicodeSPrint (HandleName, sizeof (HandleName),
L"TCPv4 (SrcPort=%d, DestPort=&d, ActiveFlag=%s)",
Tcp4ConfigData.AccessPoint.StationPort,
Tcp4ConfigData.AccessPoint.RemotePort,
(Tcp4ConfigData.AccessPoint.ActiveFlag ? L"TRUE" : L"FALSE")
);
} if (Status == EFI_NOT_STARTED) {
UnicodeSPrint (
HandleName,
sizeof (HandleName),
L"TCPv4 (Not started)"
);
} else {
return Status;
}
if (gTcpControllerNameTable != NULL) {
FreeUnicodeStringTable (gTcpControllerNameTable);
gTcpControllerNameTable = NULL;
}
Status = AddUnicodeString2 (
"eng",
gTcpComponentName.SupportedLanguages,
&gTcpControllerNameTable,
HandleName,
TRUE
);
if (EFI_ERROR (Status)) {
return Status;
}
return AddUnicodeString2 (
"en",
gTcpComponentName2.SupportedLanguages,
&gTcpControllerNameTable,
HandleName,
FALSE
);
}
/**
Update the component name for the Tcp6 child handle.
@param Tcp6[in] A pointer to the EFI_TCP6_PROTOCOL.
@retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
@retval EFI_INVALID_PARAMETER The input parameter is invalid.
**/
EFI_STATUS
UpdateTcp6Name (
IN EFI_TCP6_PROTOCOL *Tcp6
)
{
EFI_STATUS Status;
CHAR16 HandleName[80];
EFI_TCP6_CONFIG_DATA Tcp6ConfigData;
if (Tcp6 == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Format the child name into the string buffer.
//
Status = Tcp6->GetModeData (Tcp6, NULL, &Tcp6ConfigData, NULL, NULL, NULL);
if (!EFI_ERROR (Status)) {
UnicodeSPrint (HandleName, sizeof (HandleName),
L"TCPv6(SrcPort=%d, DestPort=%d, ActiveFlag=%d)",
Tcp6ConfigData.AccessPoint.StationPort,
Tcp6ConfigData.AccessPoint.RemotePort,
Tcp6ConfigData.AccessPoint.ActiveFlag
);
} else if (Status == EFI_NOT_STARTED) {
UnicodeSPrint (HandleName, sizeof (HandleName), L"TCPv6(Not started)");
} else {
return Status;
}
if (gTcpControllerNameTable != NULL) {
FreeUnicodeStringTable (gTcpControllerNameTable);
gTcpControllerNameTable = NULL;
}
Status = AddUnicodeString2 (
"eng",
gTcpComponentName.SupportedLanguages,
&gTcpControllerNameTable,
HandleName,
TRUE
);
if (EFI_ERROR (Status)) {
return Status;
}
return AddUnicodeString2 (
"en",
gTcpComponentName2.SupportedLanguages,
&gTcpControllerNameTable,
HandleName,
FALSE
);
}
/**
Retrieves a Unicode string that is the user-readable name of the controller
that is being managed by a driver.
@ -300,5 +438,89 @@ TcpComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
return EFI_UNSUPPORTED;
EFI_STATUS Status;
EFI_TCP4_PROTOCOL *Tcp4;
EFI_TCP6_PROTOCOL *Tcp6;
//
// Only provide names for child handles.
//
if (ChildHandle == NULL) {
return EFI_UNSUPPORTED;
}
//
// Make sure this driver produced ChildHandle
//
Status = EfiTestChildHandle (
ControllerHandle,
ChildHandle,
&gEfiIp6ProtocolGuid
);
if (!EFI_ERROR (Status)) {
//
// Retrieve an instance of a produced protocol from ChildHandle
//
Status = gBS->OpenProtocol (
ChildHandle,
&gEfiTcp6ProtocolGuid,
(VOID **)&Tcp6,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Update the component name for this child handle.
//
Status = UpdateTcp6Name (Tcp6);
if (EFI_ERROR (Status)) {
return Status;
}
}
//
// Make sure this driver is currently managing ControllHandle
//
Status = EfiTestChildHandle (
ControllerHandle,
ChildHandle,
&gEfiIp4ProtocolGuid
);
if (!EFI_ERROR (Status)) {
//
// Retrieve an instance of a produced protocol from ChildHandle
//
Status = gBS->OpenProtocol (
ChildHandle,
&gEfiTcp4ProtocolGuid,
(VOID **)&Tcp4,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Update the component name for this child handle.
//
Status = UpdateTcp4Name (Tcp4);
if (EFI_ERROR (Status)) {
return Status;
}
}
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
gTcpControllerNameTable,
ControllerName,
(BOOLEAN)(This == &gTcpComponentName)
);
}

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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);
@ -330,14 +331,53 @@ ON_ERROR:
return Status;
}
/**
Callback function which provided by user to remove one node in NetDestroyLinkList process.
@param[in] Entry The entry to be removed.
@param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
@retval EFI_SUCCESS The entry has been removed successfully.
@retval Others Fail to remove the entry.
**/
EFI_STATUS
TcpDestroyChildEntryInHandleBuffer (
IN LIST_ENTRY *Entry,
IN VOID *Context
)
{
SOCKET *Sock;
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
UINTN NumberOfChildren;
EFI_HANDLE *ChildHandleBuffer;
if (Entry == NULL || Context == NULL) {
return EFI_INVALID_PARAMETER;
}
Sock = NET_LIST_USER_STRUCT_S (Entry, SOCKET, Link, SOCK_SIGNATURE);
ServiceBinding = ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;
NumberOfChildren = ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;
ChildHandleBuffer = ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;
if (!NetIsInHandleBuffer (Sock->SockHandle, NumberOfChildren, ChildHandleBuffer)) {
return EFI_SUCCESS;
}
return ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle);
}
/**
Destroy a TCP6 or TCP4 service binding instance. It will release all
the resources allocated by the instance.
@param[in] Controller Controller handle of device to bind driver to.
@param[in] ImageHandle The TCP driver's image handle.
@param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number
@param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number
of children is zero stop the entire bus driver.
@param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
if NumberOfChildren is 0.
@param[in] IpVersion IP_VERSION_4 or IP_VERSION_6
@retval EFI_SUCCESS The resources used by the instance were cleaned up.
@ -349,6 +389,7 @@ TcpDestroyService (
IN EFI_HANDLE Controller,
IN EFI_HANDLE ImageHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer, OPTIONAL
IN UINT8 IpVersion
)
{
@ -358,7 +399,8 @@ TcpDestroyService (
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
TCP_SERVICE_DATA *TcpServiceData;
EFI_STATUS Status;
SOCKET *Sock;
LIST_ENTRY *List;
TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6));
@ -372,7 +414,7 @@ TcpDestroyService (
NicHandle = NetLibGetNicHandle (Controller, IpProtocolGuid);
if (NicHandle == NULL) {
return EFI_NOT_FOUND;
return EFI_SUCCESS;
}
Status = gBS->OpenProtocol (
@ -389,7 +431,18 @@ TcpDestroyService (
TcpServiceData = TCP_SERVICE_FROM_THIS (ServiceBinding);
if (NumberOfChildren == 0) {
if (NumberOfChildren != 0) {
List = &TcpServiceData->SocketList;
Context.ServiceBinding = ServiceBinding;
Context.NumberOfChildren = NumberOfChildren;
Context.ChildHandleBuffer = ChildHandleBuffer;
Status = NetDestroyLinkList (
List,
TcpDestroyChildEntryInHandleBuffer,
&Context,
NULL
);
} else if (IsListEmpty (&TcpServiceData->SocketList)) {
//
// Uninstall TCP servicebinding protocol
//
@ -404,6 +457,7 @@ TcpDestroyService (
// Destroy the IpIO consumed by TCP driver
//
IpIoDestroy (TcpServiceData->IpIo);
TcpServiceData->IpIo = NULL;
//
// Destroy the heartbeat timer.
@ -419,16 +473,11 @@ TcpDestroyService (
// Release the TCP service data
//
FreePool (TcpServiceData);
} else {
while (!IsListEmpty (&TcpServiceData->SocketList)) {
Sock = NET_LIST_HEAD (&TcpServiceData->SocketList, SOCKET, Link);
ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle);
}
Status = EFI_SUCCESS;
}
return EFI_SUCCESS;
return Status;
}
/**
@ -595,6 +644,7 @@ TcpDriverBindingStop (
ControllerHandle,
This->DriverBindingHandle,
NumberOfChildren,
ChildHandleBuffer,
IP_VERSION_4
);
@ -602,6 +652,7 @@ TcpDriverBindingStop (
ControllerHandle,
This->DriverBindingHandle,
NumberOfChildren,
ChildHandleBuffer,
IP_VERSION_6
);
@ -839,14 +890,11 @@ TcpServiceBindingDestroyChild (
EFI_STATUS Status;
VOID *Tcp;
SOCKET *Sock;
EFI_TPL OldTpl;
if (NULL == This || NULL == ChildHandle) {
return EFI_INVALID_PARAMETER;
}
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
//
// retrieve the Tcp4 protocol from ChildHandle
//
@ -885,7 +933,5 @@ TcpServiceBindingDestroyChild (
SockDestroyChild (Sock);
}
gBS->RestoreTPL (OldTpl);
return Status;
}

View File

@ -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.
//

View File

@ -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.
@ -230,6 +232,70 @@ Udp6ComponentNameGetDriverName (
);
}
/**
Update the component name for the Udp6 child handle.
@param Udp6[in] A pointer to the EFI_UDP6_PROTOCOL.
@retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
@retval EFI_INVALID_PARAMETER The input parameter is invalid.
**/
EFI_STATUS
UpdateName (
IN EFI_UDP6_PROTOCOL *Udp6
)
{
EFI_STATUS Status;
CHAR16 HandleName[64];
EFI_UDP6_CONFIG_DATA Udp6ConfigData;
if (Udp6 == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Format the child name into the string buffer.
//
Status = Udp6->GetModeData (Udp6, &Udp6ConfigData, NULL, NULL, NULL);
if (!EFI_ERROR (Status)) {
UnicodeSPrint (HandleName, sizeof (HandleName),
L"UDPv6 (SrcPort=%d, DestPort=%d)",
Udp6ConfigData.StationPort,
Udp6ConfigData.RemotePort
);
} else if (Status == EFI_NOT_STARTED) {
UnicodeSPrint (HandleName, sizeof (HandleName), L"UDPv6 (Not started)");
} else {
UnicodeSPrint (HandleName, sizeof (HandleName), L"UDPv6 (%r)", Status);
}
if (gUdp6ControllerNameTable != NULL) {
FreeUnicodeStringTable (gUdp6ControllerNameTable);
gUdp6ControllerNameTable = NULL;
}
Status = AddUnicodeString2 (
"eng",
gUdp6ComponentName.SupportedLanguages,
&gUdp6ControllerNameTable,
HandleName,
TRUE
);
if (EFI_ERROR (Status)) {
return Status;
}
return AddUnicodeString2 (
"en",
gUdp6ComponentName2.SupportedLanguages,
&gUdp6ControllerNameTable,
HandleName,
FALSE
);
}
/**
Retrieves a Unicode string that is the user-readable name of the controller
that is being managed by a driver.
@ -308,6 +374,56 @@ Udp6ComponentNameGetControllerName (
OUT CHAR16 **ControllerName
)
{
return EFI_UNSUPPORTED;
}
EFI_STATUS Status;
EFI_UDP6_PROTOCOL *Udp6;
//
// Only provide names for child handles.
//
if (ChildHandle == NULL) {
return EFI_UNSUPPORTED;
}
//
// Make sure this driver produced ChildHandle
//
Status = EfiTestChildHandle (
ControllerHandle,
ChildHandle,
&gEfiIp6ProtocolGuid
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Retrieve an instance of a produced protocol from ChildHandle
//
Status = gBS->OpenProtocol (
ChildHandle,
&gEfiUdp6ProtocolGuid,
(VOID **)&Udp6,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Update the component name for this child handle.
//
Status = UpdateName (Udp6);
if (EFI_ERROR (Status)) {
return Status;
}
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
gUdp6ControllerNameTable,
ControllerName,
(BOOLEAN)(This == &gUdp6ComponentName)
);
}

View File

@ -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
@ -178,6 +178,43 @@ EXIT:
return Status;
}
/**
Callback function which provided by user to remove one node in NetDestroyLinkList process.
@param[in] Entry The entry to be removed.
@param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
@retval EFI_SUCCESS The entry has been removed successfully.
@retval Others Fail to remove the entry.
**/
EFI_STATUS
Udp6DestroyChildEntryInHandleBuffer (
IN LIST_ENTRY *Entry,
IN VOID *Context
)
{
UDP6_INSTANCE_DATA *Instance;
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
UINTN NumberOfChildren;
EFI_HANDLE *ChildHandleBuffer;
if (Entry == NULL || Context == NULL) {
return EFI_INVALID_PARAMETER;
}
Instance = NET_LIST_USER_STRUCT_S (Entry, UDP6_INSTANCE_DATA, Link, UDP6_INSTANCE_DATA_SIGNATURE);
ServiceBinding = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;
NumberOfChildren = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;
ChildHandleBuffer = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;
if (!NetIsInHandleBuffer (Instance->ChildHandle, NumberOfChildren, ChildHandleBuffer)) {
return EFI_SUCCESS;
}
return ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);
}
/**
Stop this driver on ControllerHandle.
@ -211,14 +248,15 @@ Udp6DriverBindingStop (
EFI_HANDLE NicHandle;
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
UDP6_SERVICE_DATA *Udp6Service;
UDP6_INSTANCE_DATA *Instance;
LIST_ENTRY *List;
UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
//
// Find the NicHandle where UDP6 ServiceBinding Protocol is installed.
//
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp6ProtocolGuid);
if (NicHandle == NULL) {
return EFI_DEVICE_ERROR;
return EFI_SUCCESS;
}
//
@ -238,8 +276,21 @@ Udp6DriverBindingStop (
Udp6Service = UDP6_SERVICE_DATA_FROM_THIS (ServiceBinding);
if (NumberOfChildren == 0) {
if (NumberOfChildren != 0) {
//
// NumberOfChildren is not zero, destroy the children instances in ChildHandleBuffer.
//
List = &Udp6Service->ChildrenList;
Context.ServiceBinding = ServiceBinding;
Context.NumberOfChildren = NumberOfChildren;
Context.ChildHandleBuffer = ChildHandleBuffer;
Status = NetDestroyLinkList (
List,
Udp6DestroyChildEntryInHandleBuffer,
&Context,
NULL
);
} else if (IsListEmpty (&Udp6Service->ChildrenList)) {
gBS->UninstallMultipleProtocolInterfaces (
NicHandle,
&gEfiUdp6ServiceBindingProtocolGuid,
@ -252,13 +303,8 @@ Udp6DriverBindingStop (
Udp6CleanService (Udp6Service);
FreePool (Udp6Service);
} else {
while (!IsListEmpty (&Udp6Service->ChildrenList)) {
Instance = NET_LIST_HEAD (&Udp6Service->ChildrenList, UDP6_INSTANCE_DATA, Link);
Status = ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);
}
Status = EFI_SUCCESS;
}
return Status;
@ -351,6 +397,21 @@ Udp6ServiceBindingCreateChild (
goto ON_ERROR;
}
//
// Open this instance's Ip6 protocol in the IpInfo BY_CHILD.
//
Status = gBS->OpenProtocol (
Instance->IpInfo->ChildHandle,
&gEfiIp6ProtocolGuid,
(VOID **) &Ip6,
gUdp6DriverBinding.DriverBindingHandle,
Instance->ChildHandle,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
//
@ -440,17 +501,17 @@ Udp6ServiceBindingDestroyChild (
Instance = UDP6_INSTANCE_DATA_FROM_THIS (Udp6Proto);
if (Instance->Destroyed) {
if (Instance->InDestroy) {
return EFI_SUCCESS;
}
//
// Use the Destroyed flag to avoid the re-entering of the following code.
//
Instance->Destroyed = TRUE;
Instance->InDestroy = TRUE;
//
// Close the Ip6 protocol.
// Close the Ip6 protocol on the default IpIo.
//
gBS->CloseProtocol (
Udp6Service->IpIo->ChildHandle,
@ -458,6 +519,15 @@ Udp6ServiceBindingDestroyChild (
gUdp6DriverBinding.DriverBindingHandle,
Instance->ChildHandle
);
//
// Close the Ip6 protocol on this instance's IpInfo.
//
gBS->CloseProtocol (
Instance->IpInfo->ChildHandle,
&gEfiIp6ProtocolGuid,
gUdp6DriverBinding.DriverBindingHandle,
Instance->ChildHandle
);
//
// Uninstall the Udp6Protocol previously installed on the ChildHandle.
@ -469,7 +539,7 @@ Udp6ServiceBindingDestroyChild (
NULL
);
if (EFI_ERROR (Status)) {
Instance->Destroyed = FALSE;
Instance->InDestroy = FALSE;
return Status;
}

View File

@ -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;
}

View File

@ -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.

View File

@ -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)
);
}

View File

@ -1398,7 +1398,7 @@ PxeBcDriverBindingStop (
if (NicHandle == NULL) {
NicHandle = PxeBcGetNicByIp6Children (ControllerHandle);
if (NicHandle == NULL) {
return EFI_DEVICE_ERROR;
return EFI_SUCCESS;
} else {
IsIpv6 = TRUE;
}

View File

@ -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