X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=NetworkPkg%2FTcpDxe%2FTcpDriver.c;h=ce3dd0be634d71aead735ba31e03628424991104;hb=3f5287971ffdb5c42e3325a3a94c101f08d3a02a;hp=3e01f34892ffe006d5d4ec90367e4e7084ac0048;hpb=76389e18c04833a87811550ed6db06f1790aacde;p=mirror_edk2.git
diff --git a/NetworkPkg/TcpDxe/TcpDriver.c b/NetworkPkg/TcpDxe/TcpDriver.c
index 3e01f34892..ce3dd0be63 100644
--- a/NetworkPkg/TcpDxe/TcpDriver.c
+++ b/NetworkPkg/TcpDxe/TcpDriver.c
@@ -1,7 +1,7 @@
/** @file
The driver binding and service binding protocol for the TCP driver.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -66,10 +66,19 @@ SOCK_INIT_DATA mTcpDefaultSockData = {
NULL,
};
-EFI_DRIVER_BINDING_PROTOCOL gTcpDriverBinding = {
- TcpDriverBindingSupported,
- TcpDriverBindingStart,
- TcpDriverBindingStop,
+EFI_DRIVER_BINDING_PROTOCOL gTcp4DriverBinding = {
+ Tcp4DriverBindingSupported,
+ Tcp4DriverBindingStart,
+ Tcp4DriverBindingStop,
+ 0xa,
+ NULL,
+ NULL
+};
+
+EFI_DRIVER_BINDING_PROTOCOL gTcp6DriverBinding = {
+ Tcp6DriverBindingSupported,
+ Tcp6DriverBindingStart,
+ Tcp6DriverBindingStop,
0xa,
NULL,
NULL
@@ -172,7 +181,7 @@ TcpDriverEntryPoint (
Status = EfiLibInstallDriverBindingComponentName2 (
ImageHandle,
SystemTable,
- &gTcpDriverBinding,
+ &gTcp4DriverBinding,
ImageHandle,
&gTcpComponentName,
&gTcpComponentName2
@@ -181,6 +190,31 @@ TcpDriverEntryPoint (
return Status;
}
+ //
+ // Install the TCP Driver Binding Protocol
+ //
+ Status = EfiLibInstallDriverBindingComponentName2 (
+ ImageHandle,
+ SystemTable,
+ &gTcp6DriverBinding,
+ NULL,
+ &gTcpComponentName,
+ &gTcpComponentName2
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->UninstallMultipleProtocolInterfaces (
+ ImageHandle,
+ &gEfiDriverBindingProtocolGuid,
+ &gTcp4DriverBinding,
+ &gEfiComponentName2ProtocolGuid,
+ &gTcpComponentName2,
+ &gEfiComponentNameProtocolGuid,
+ &gTcpComponentName,
+ NULL
+ );
+ return Status;
+ }
+
//
// Initialize ISS and random port.
//
@@ -315,14 +349,13 @@ TcpCreateService (
goto ON_ERROR;
}
- TcpSetVariableData (TcpServiceData);
-
return EFI_SUCCESS;
ON_ERROR:
if (TcpServiceData->IpIo != NULL) {
IpIoDestroy (TcpServiceData->IpIo);
+ TcpServiceData->IpIo = NULL;
}
FreePool (TcpServiceData);
@@ -330,14 +363,54 @@ 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
+EFIAPI
+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 +422,7 @@ TcpDestroyService (
IN EFI_HANDLE Controller,
IN EFI_HANDLE ImageHandle,
IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer, OPTIONAL
IN UINT8 IpVersion
)
{
@@ -358,7 +432,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 +447,7 @@ TcpDestroyService (
NicHandle = NetLibGetNicHandle (Controller, IpProtocolGuid);
if (NicHandle == NULL) {
- return EFI_NOT_FOUND;
+ return EFI_SUCCESS;
}
Status = gBS->OpenProtocol (
@@ -389,7 +464,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,31 +490,22 @@ TcpDestroyService (
// Destroy the IpIO consumed by TCP driver
//
IpIoDestroy (TcpServiceData->IpIo);
+ TcpServiceData->IpIo = NULL;
//
// Destroy the heartbeat timer.
//
TcpDestroyTimer ();
- //
- // Clear the variable.
- //
- TcpClearVariableData (TcpServiceData);
-
//
// 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;
}
/**
@@ -446,14 +523,13 @@ TcpDestroyService (
**/
EFI_STATUS
EFIAPI
-TcpDriverBindingSupported (
+Tcp4DriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
)
{
EFI_STATUS Status;
- BOOLEAN IsTcp4Started;
//
// Test for the Tcp4ServiceBinding Protocol
@@ -466,29 +542,114 @@ TcpDriverBindingSupported (
ControllerHandle,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
- if (EFI_ERROR (Status)) {
- //
- // Test for the Ip4ServiceBinding Protocol
- //
- Status = gBS->OpenProtocol (
- ControllerHandle,
- &gEfiIp4ServiceBindingProtocolGuid,
- NULL,
- This->DriverBindingHandle,
- ControllerHandle,
- EFI_OPEN_PROTOCOL_TEST_PROTOCOL
- );
- if (!EFI_ERROR (Status)) {
- return EFI_SUCCESS;
- }
+ if (!EFI_ERROR (Status)) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ //
+ // Test for the Ip4ServiceBinding Protocol
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiIp4ServiceBindingProtocolGuid,
+ NULL,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+ return Status;
+}
- IsTcp4Started = FALSE;
- } else {
- IsTcp4Started = TRUE;
+/**
+ Start this driver on ControllerHandle.
+
+ @param[in] This Protocol instance pointer.
+ @param[in] ControllerHandle Handle of device to bind driver to.
+ @param[in] RemainingDevicePath Optional parameter use to pick a specific child
+ device to start.
+
+ @retval EFI_SUCCESS The driver is added to ControllerHandle.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources to start the
+ driver.
+ @retval other The driver cannot be added to ControllerHandle.
+
+**/
+EFI_STATUS
+EFIAPI
+Tcp4DriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+
+ Status = TcpCreateService (ControllerHandle, This->DriverBindingHandle, IP_VERSION_4);
+ if ((Status == EFI_ALREADY_STARTED) || (Status == EFI_UNSUPPORTED)) {
+ Status = EFI_SUCCESS;
}
+ return Status;
+}
+
+/**
+ Stop this driver on ControllerHandle.
+
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ @param[in] ControllerHandle A handle to the device being stopped. The handle must
+ support a bus specific I/O protocol for the driver
+ to use to stop the device.
+ @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
+ @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
+ if NumberOfChildren is 0.
+
+ @retval EFI_SUCCESS The device was stopped.
+ @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+Tcp4DriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
+ )
+{
+ return TcpDestroyService (
+ ControllerHandle,
+ This->DriverBindingHandle,
+ NumberOfChildren,
+ ChildHandleBuffer,
+ IP_VERSION_4
+ );
+}
+
+/**
+ Test to see if this driver supports ControllerHandle.
+
+ @param[in] This Protocol instance pointer.
+ @param[in] ControllerHandle Handle of device to test.
+ @param[in] RemainingDevicePath Optional parameter use to pick a specific
+ child device to start.
+
+ @retval EFI_SUCCESS This driver supports this device.
+ @retval EFI_ALREADY_STARTED This driver is already running on this device.
+ @retval other This driver does not support this device.
+
+**/
+EFI_STATUS
+EFIAPI
+Tcp6DriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+
//
- // Check the Tcp6ServiceBinding Protocol
+ // Test for the Tcp6ServiceBinding Protocol
//
Status = gBS->OpenProtocol (
ControllerHandle,
@@ -498,26 +659,22 @@ TcpDriverBindingSupported (
ControllerHandle,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
- if (EFI_ERROR (Status)) {
- //
- // Test for the Ip6ServiceBinding Protocol
- //
- Status = gBS->OpenProtocol (
- ControllerHandle,
- &gEfiIp6ServiceBindingProtocolGuid,
- NULL,
- This->DriverBindingHandle,
- ControllerHandle,
- EFI_OPEN_PROTOCOL_TEST_PROTOCOL
- );
- if (!EFI_ERROR (Status)) {
- return EFI_SUCCESS;
- }
- } else if (IsTcp4Started) {
+ if (!EFI_ERROR (Status)) {
return EFI_ALREADY_STARTED;
}
-
- return EFI_UNSUPPORTED;
+
+ //
+ // Test for the Ip6ServiceBinding Protocol
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiIp6ServiceBindingProtocolGuid,
+ NULL,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+ return Status;
}
/**
@@ -536,32 +693,20 @@ TcpDriverBindingSupported (
**/
EFI_STATUS
EFIAPI
-TcpDriverBindingStart (
+Tcp6DriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
)
{
- EFI_STATUS Tcp4Status;
- EFI_STATUS Tcp6Status;
-
- Tcp4Status = TcpCreateService (ControllerHandle, This->DriverBindingHandle, IP_VERSION_4);
- if ((Tcp4Status == EFI_ALREADY_STARTED) || (Tcp4Status == EFI_UNSUPPORTED)) {
- Tcp4Status = EFI_SUCCESS;
- }
+ EFI_STATUS Status;
- Tcp6Status = TcpCreateService (ControllerHandle, This->DriverBindingHandle, IP_VERSION_6);
- if ((Tcp6Status == EFI_ALREADY_STARTED) || (Tcp6Status == EFI_UNSUPPORTED)) {
- Tcp6Status = EFI_SUCCESS;
+ Status = TcpCreateService (ControllerHandle, This->DriverBindingHandle, IP_VERSION_6);
+ if ((Status == EFI_ALREADY_STARTED) || (Status == EFI_UNSUPPORTED)) {
+ Status = EFI_SUCCESS;
}
- if (!EFI_ERROR (Tcp4Status) || !EFI_ERROR (Tcp6Status)) {
- return EFI_SUCCESS;
- } else if (EFI_ERROR (Tcp4Status)) {
- return Tcp4Status;
- } else {
- return Tcp6Status;
- }
+ return Status;
}
/**
@@ -581,35 +726,20 @@ TcpDriverBindingStart (
**/
EFI_STATUS
EFIAPI
-TcpDriverBindingStop (
+Tcp6DriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
)
{
- EFI_STATUS Tcp4Status;
- EFI_STATUS Tcp6Status;
-
- Tcp4Status = TcpDestroyService (
- ControllerHandle,
- This->DriverBindingHandle,
- NumberOfChildren,
- IP_VERSION_4
- );
-
- Tcp6Status = TcpDestroyService (
- ControllerHandle,
- This->DriverBindingHandle,
- NumberOfChildren,
- IP_VERSION_6
- );
-
- if (EFI_ERROR (Tcp4Status) && EFI_ERROR (Tcp6Status)) {
- return EFI_DEVICE_ERROR;
- } else {
- return EFI_SUCCESS;
- }
+ return TcpDestroyService (
+ ControllerHandle,
+ This->DriverBindingHandle,
+ NumberOfChildren,
+ ChildHandleBuffer,
+ IP_VERSION_6
+ );
}
/**
@@ -665,7 +795,7 @@ TcpCreateSocketCallback (
(VOID **) &This->ParentDevicePath,
TcpServiceData->DriverBindingHandle,
This->SockHandle,
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
gBS->CloseProtocol (
@@ -713,16 +843,6 @@ TcpDestroySocketCallback (
//
RemoveEntryList (&This->Link);
- //
- // Close the device path protocol
- //
- gBS->CloseProtocol (
- TcpServiceData->ControllerHandle,
- &gEfiDevicePathProtocolGuid,
- TcpServiceData->DriverBindingHandle,
- This->SockHandle
- );
-
//
// Close the IP protocol.
//
@@ -823,7 +943,7 @@ TcpServiceBindingCreateChild (
@retval EFI_SUCCES The protocol was removed from ChildHandle.
@retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
- @retval EFI_INVALID_PARAMETER Child handle is not a valid UEFI Handle.
+ @retval EFI_INVALID_PARAMETER Child handle is NULL.
@retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
because its services are being used.
@retval other The child handle was not destroyed.
@@ -839,14 +959,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
//
@@ -854,7 +971,7 @@ TcpServiceBindingDestroyChild (
ChildHandle,
&gEfiTcp4ProtocolGuid,
&Tcp,
- gTcpDriverBinding.DriverBindingHandle,
+ gTcp4DriverBinding.DriverBindingHandle,
ChildHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
@@ -866,7 +983,7 @@ TcpServiceBindingDestroyChild (
ChildHandle,
&gEfiTcp6ProtocolGuid,
&Tcp,
- gTcpDriverBinding.DriverBindingHandle,
+ gTcp6DriverBinding.DriverBindingHandle,
ChildHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
@@ -885,7 +1002,5 @@ TcpServiceBindingDestroyChild (
SockDestroyChild (Sock);
}
- gBS->RestoreTPL (OldTpl);
-
return Status;
}