+++ /dev/null
-/** @file\r
- Tcp driver function.\r
-\r
-Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php<BR>\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include "Tcp4Main.h"\r
-\r
-\r
-UINT16 mTcp4RandomPort;\r
-extern EFI_COMPONENT_NAME_PROTOCOL gTcp4ComponentName;\r
-extern EFI_COMPONENT_NAME2_PROTOCOL gTcp4ComponentName2;\r
-extern EFI_UNICODE_STRING_TABLE *gTcpControllerNameTable;\r
-\r
-TCP4_HEARTBEAT_TIMER mTcp4Timer = {\r
- NULL,\r
- 0\r
-};\r
-\r
-EFI_TCP4_PROTOCOL mTcp4ProtocolTemplate = {\r
- Tcp4GetModeData,\r
- Tcp4Configure,\r
- Tcp4Routes,\r
- Tcp4Connect,\r
- Tcp4Accept,\r
- Tcp4Transmit,\r
- Tcp4Receive,\r
- Tcp4Close,\r
- Tcp4Cancel,\r
- Tcp4Poll\r
-};\r
-\r
-SOCK_INIT_DATA mTcp4DefaultSockData = {\r
- SockStream,\r
- 0,\r
- NULL,\r
- TCP_BACKLOG,\r
- TCP_SND_BUF_SIZE,\r
- TCP_RCV_BUF_SIZE,\r
- &mTcp4ProtocolTemplate,\r
- Tcp4CreateSocketCallback,\r
- Tcp4DestroySocketCallback,\r
- NULL,\r
- NULL,\r
- 0,\r
- Tcp4Dispatcher,\r
- NULL,\r
-};\r
-\r
-EFI_DRIVER_BINDING_PROTOCOL mTcp4DriverBinding = {\r
- Tcp4DriverBindingSupported,\r
- Tcp4DriverBindingStart,\r
- Tcp4DriverBindingStop,\r
- 0xa,\r
- NULL,\r
- NULL\r
-};\r
-\r
-EFI_SERVICE_BINDING_PROTOCOL mTcp4ServiceBinding = {\r
- Tcp4ServiceBindingCreateChild,\r
- Tcp4ServiceBindingDestroyChild\r
-};\r
-\r
-\r
-/**\r
- Create and start the heartbeat timer for TCP driver.\r
-\r
- @retval EFI_SUCCESS The timer is successfully created and started.\r
- @retval other The timer is not created.\r
-\r
-**/\r
-EFI_STATUS\r
-Tcp4CreateTimer (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- Status = EFI_SUCCESS;\r
-\r
- if (mTcp4Timer.RefCnt == 0) {\r
-\r
- Status = gBS->CreateEvent (\r
- EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
- TPL_NOTIFY,\r
- TcpTicking,\r
- NULL,\r
- &mTcp4Timer.TimerEvent\r
- );\r
- if (!EFI_ERROR (Status)) {\r
-\r
- Status = gBS->SetTimer (\r
- mTcp4Timer.TimerEvent,\r
- TimerPeriodic,\r
- (UINT64) (TICKS_PER_SECOND / TCP_TICK_HZ)\r
- );\r
- }\r
- }\r
-\r
- if (!EFI_ERROR (Status)) {\r
-\r
- mTcp4Timer.RefCnt++;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Stop and destroy the heartbeat timer for TCP driver.\r
-\r
-**/\r
-VOID\r
-Tcp4DestroyTimer (\r
- VOID\r
- )\r
-{\r
- ASSERT (mTcp4Timer.RefCnt > 0);\r
-\r
- mTcp4Timer.RefCnt--;\r
-\r
- if (mTcp4Timer.RefCnt > 0) {\r
- return;\r
- }\r
-\r
- gBS->SetTimer (mTcp4Timer.TimerEvent, TimerCancel, 0);\r
- gBS->CloseEvent (mTcp4Timer.TimerEvent);\r
- mTcp4Timer.TimerEvent = NULL;\r
-}\r
-\r
-/**\r
- Callback function which provided by user to remove one node in NetDestroyLinkList process.\r
-\r
- @param[in] Entry The entry to be removed.\r
- @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.\r
-\r
- @retval EFI_SUCCESS The entry has been removed successfully.\r
- @retval Others Fail to remove the entry.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-Tcp4DestroyChildEntryInHandleBuffer (\r
- IN LIST_ENTRY *Entry,\r
- IN VOID *Context\r
- )\r
-{\r
- SOCKET *Sock;\r
- EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
- UINTN NumberOfChildren;\r
- EFI_HANDLE *ChildHandleBuffer;\r
-\r
- if (Entry == NULL || Context == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Sock = NET_LIST_USER_STRUCT_S (Entry, SOCKET, Link, SOCK_SIGNATURE);\r
- ServiceBinding = ((TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;\r
- NumberOfChildren = ((TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;\r
- ChildHandleBuffer = ((TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;\r
-\r
- if (!NetIsInHandleBuffer (Sock->SockHandle, NumberOfChildren, ChildHandleBuffer)) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- return ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle);\r
-}\r
-\r
-/**\r
- The entry point for Tcp4 driver, used to install Tcp4 driver on the ImageHandle.\r
-\r
- @param ImageHandle The firmware allocated handle for this\r
- driver image.\r
- @param SystemTable Pointer to the EFI system table.\r
-\r
- @retval EFI_SUCCESS Driver loaded.\r
- @retval other Driver not loaded.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-Tcp4DriverEntryPoint (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT32 Seed;\r
-\r
- //\r
- // Install the TCP4 Driver Binding Protocol\r
- //\r
- Status = EfiLibInstallDriverBindingComponentName2 (\r
- ImageHandle,\r
- SystemTable,\r
- &mTcp4DriverBinding,\r
- ImageHandle,\r
- &gTcp4ComponentName,\r
- &gTcp4ComponentName2\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- //\r
- // Initialize ISS and random port.\r
- //\r
- Seed = NetRandomInitSeed ();\r
- mTcpGlobalIss = NET_RANDOM (Seed) % mTcpGlobalIss;\r
- mTcp4RandomPort = (UINT16) (TCP4_PORT_KNOWN +\r
- (UINT16) (NET_RANDOM(Seed) % TCP4_PORT_KNOWN));\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Tests to see if this driver supports a given controller.\r
-\r
- If a child device is provided, it further tests to see if this driver supports\r
- creating a handle for the specified child device.\r
-\r
- @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
- @param ControllerHandle The handle of the controller to test. This handle\r
- must support a protocol interface that supplies\r
- an I/O abstraction to the driver.\r
- @param RemainingDevicePath A pointer to the remaining portion of a device path.\r
- This parameter is ignored by device drivers, and is optional for bus drivers.\r
-\r
-\r
- @retval EFI_SUCCESS The device specified by ControllerHandle and\r
- RemainingDevicePath is supported by the driver\r
- specified by This.\r
- @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and\r
- RemainingDevicePath is already being managed by\r
- the driver specified by This.\r
- @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and\r
- RemainingDevicePath is already being managed by a\r
- different driver or an application that requires\r
- exclusive access.\r
- @retval EFI_UNSUPPORTED The device specified by ControllerHandle and\r
- RemainingDevicePath is not supported by the driver\r
- specified by This.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-Tcp4DriverBindingSupported (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Test for the Tcp4ServiceBinding Protocol\r
- //\r
- Status = gBS->OpenProtocol (\r
- ControllerHandle,\r
- &gEfiTcp4ServiceBindingProtocolGuid,\r
- NULL,\r
- This->DriverBindingHandle,\r
- ControllerHandle,\r
- EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- return EFI_ALREADY_STARTED;\r
- }\r
-\r
- //\r
- // Test for the Ip4 Protocol\r
- //\r
- Status = gBS->OpenProtocol (\r
- ControllerHandle,\r
- &gEfiIp4ServiceBindingProtocolGuid,\r
- NULL,\r
- This->DriverBindingHandle,\r
- ControllerHandle,\r
- EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
- );\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Start this driver on ControllerHandle.\r
-\r
- The Start() function is designed to be invoked from the EFI boot service\r
- ConnectController(). As a result, much of the error checking on the parameters\r
- to Start() has been moved into this common boot service. It is legal to call\r
- Start() from other locations, but the following calling restrictions must be\r
- followed or the system behavior will not be deterministic.\r
- 1. ControllerHandle must be a valid EFI_HANDLE.\r
- 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally\r
- aligned EFI_DEVICE_PATH_PROTOCOL.\r
- 3. Prior to calling Start(), the Supported() function for the driver specified\r
- by This must have been called with the same calling parameters, and Supported()\r
- must have returned EFI_SUCCESS.\r
-\r
- @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
- @param ControllerHandle The handle of the controller to start. This handle\r
- must support a protocol interface that supplies\r
- an I/O abstraction to the driver.\r
- @param RemainingDevicePath A pointer to the remaining portion of a device path.\r
- This parameter is ignored by device drivers, and is\r
- optional for bus drivers.\r
-\r
- @retval EFI_SUCCESS The device was started.\r
- @retval EFI_ALREADY_STARTED The device could not be started due to a device error.\r
- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack\r
- of resources.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-Tcp4DriverBindingStart (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
- )\r
-{\r
- EFI_STATUS Status;\r
- TCP4_SERVICE_DATA *TcpServiceData;\r
- IP_IO_OPEN_DATA OpenData;\r
-\r
- TcpServiceData = AllocateZeroPool (sizeof (TCP4_SERVICE_DATA));\r
-\r
- if (NULL == TcpServiceData) {\r
- DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Have no enough"\r
- " resource to create a Tcp Servcie Data\n"));\r
-\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Create a new IP IO to Consume it\r
- //\r
- TcpServiceData->IpIo = IpIoCreate (\r
- This->DriverBindingHandle,\r
- ControllerHandle,\r
- IP_VERSION_4\r
- );\r
- if (NULL == TcpServiceData->IpIo) {\r
-\r
- DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Have no enough"\r
- " resource to create an Ip Io\n"));\r
-\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto ON_ERROR;\r
- }\r
-\r
- //\r
- // Configure and start IpIo.\r
- //\r
- ZeroMem (&OpenData, sizeof (IP_IO_OPEN_DATA));\r
-\r
- CopyMem (\r
- &OpenData.IpConfigData.Ip4CfgData,\r
- &mIp4IoDefaultIpConfigData,\r
- sizeof (EFI_IP4_CONFIG_DATA)\r
- );\r
-\r
- OpenData.IpConfigData.Ip4CfgData.DefaultProtocol = EFI_IP_PROTO_TCP;\r
-\r
- OpenData.PktRcvdNotify = Tcp4RxCallback;\r
- Status = IpIoOpen (TcpServiceData->IpIo, &OpenData);\r
-\r
- if (EFI_ERROR (Status)) {\r
- goto ON_ERROR;\r
- }\r
-\r
- //\r
- // Create the timer event used by TCP driver\r
- //\r
- Status = Tcp4CreateTimer ();\r
- if (EFI_ERROR (Status)) {\r
-\r
- DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Create TcpTimer"\r
- " Event failed with %r\n", Status));\r
-\r
- goto ON_ERROR;\r
- }\r
-\r
- //\r
- // Install the Tcp4ServiceBinding Protocol on the\r
- // controller handle\r
- //\r
- TcpServiceData->Tcp4ServiceBinding = mTcp4ServiceBinding;\r
-\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &ControllerHandle,\r
- &gEfiTcp4ServiceBindingProtocolGuid,\r
- &TcpServiceData->Tcp4ServiceBinding,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
-\r
- DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Install Tcp4 Service Binding"\r
- " Protocol failed for %r\n", Status));\r
-\r
- Tcp4DestroyTimer ();\r
- goto ON_ERROR;\r
- }\r
-\r
- //\r
- // Initialize member in TcpServiceData\r
- //\r
- TcpServiceData->ControllerHandle = ControllerHandle;\r
- TcpServiceData->Signature = TCP4_DRIVER_SIGNATURE;\r
- TcpServiceData->DriverBindingHandle = This->DriverBindingHandle;\r
-\r
- InitializeListHead (&TcpServiceData->SocketList);\r
-\r
- return EFI_SUCCESS;\r
-\r
-ON_ERROR:\r
-\r
- if (TcpServiceData->IpIo != NULL) {\r
- IpIoDestroy (TcpServiceData->IpIo);\r
- TcpServiceData->IpIo = NULL;\r
- }\r
-\r
- FreePool (TcpServiceData);\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Stop this driver on ControllerHandle.\r
-\r
- The Stop() function is designed to be invoked from the EFI boot service\r
- DisconnectController(). As a result, much of the error checking on the parameters\r
- to Stop() has been moved into this common boot service. It is legal to call Stop()\r
- from other locations, but the following calling restrictions must be followed\r
- or the system behavior will not be deterministic.\r
- 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call\r
- to this same driver's Start() function.\r
- 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid\r
- EFI_HANDLE. In addition, all of these handles must have been created in this\r
- driver's Start() function, and the Start() function must have called OpenProtocol()\r
- on ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
-\r
- @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
- @param ControllerHandle A handle to the device being stopped. The handle must\r
- support a bus specific I/O protocol for the driver\r
- to use to stop the device.\r
- @param NumberOfChildren The number of child device handles in ChildHandleBuffer.\r
- @param ChildHandleBuffer An array of child handles to be freed. May be NULL if\r
- NumberOfChildren is 0.\r
-\r
- @retval EFI_SUCCESS The device was stopped.\r
- @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-Tcp4DriverBindingStop (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN UINTN NumberOfChildren,\r
- IN EFI_HANDLE *ChildHandleBuffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HANDLE NicHandle;\r
- EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
- TCP4_SERVICE_DATA *TcpServiceData;\r
- LIST_ENTRY *List;\r
- TCP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;\r
-\r
- // Find the NicHandle where Tcp4 ServiceBinding Protocol is installed.\r
- //\r
- NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);\r
- if (NicHandle == NULL) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Retrieve the TCP driver Data Structure\r
- //\r
- Status = gBS->OpenProtocol (\r
- NicHandle,\r
- &gEfiTcp4ServiceBindingProtocolGuid,\r
- (VOID **) &ServiceBinding,\r
- This->DriverBindingHandle,\r
- ControllerHandle,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR (Status)) {\r
-\r
- DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStop: Locate Tcp4 Service "\r
- " Binding Protocol failed with %r\n", Status));\r
-\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- TcpServiceData = TCP4_FROM_THIS (ServiceBinding);\r
-\r
- if (NumberOfChildren != 0) {\r
- List = &TcpServiceData->SocketList;\r
- Context.ServiceBinding = ServiceBinding;\r
- Context.NumberOfChildren = NumberOfChildren;\r
- Context.ChildHandleBuffer = ChildHandleBuffer;\r
- Status = NetDestroyLinkList (\r
- List,\r
- Tcp4DestroyChildEntryInHandleBuffer,\r
- &Context,\r
- NULL\r
- );\r
- } else if (IsListEmpty (&TcpServiceData->SocketList)) {\r
- //\r
- // Uninstall TCP servicebinding protocol\r
- //\r
- gBS->UninstallMultipleProtocolInterfaces (\r
- NicHandle,\r
- &gEfiTcp4ServiceBindingProtocolGuid,\r
- ServiceBinding,\r
- NULL\r
- );\r
-\r
- //\r
- // Destroy the IpIO consumed by TCP driver\r
- //\r
- IpIoDestroy (TcpServiceData->IpIo);\r
- TcpServiceData->IpIo = NULL;\r
-\r
- //\r
- // Destroy the heartbeat timer.\r
- //\r
- Tcp4DestroyTimer ();\r
-\r
- if (gTcpControllerNameTable != NULL) {\r
- FreeUnicodeStringTable (gTcpControllerNameTable);\r
- gTcpControllerNameTable = NULL;\r
- }\r
-\r
- //\r
- // Release the TCP service data\r
- //\r
- FreePool (TcpServiceData);\r
-\r
- Status = EFI_SUCCESS;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Open Ip4 and device path protocols for a created socket, and insert it in\r
- socket list.\r
-\r
- @param This Pointer to the socket just created\r
- @param Context Context of the socket\r
-\r
- @retval EFI_SUCCESS This protocol is installed successfully.\r
- @retval other Some error occured.\r
-\r
-**/\r
-EFI_STATUS\r
-Tcp4CreateSocketCallback (\r
- IN SOCKET *This,\r
- IN VOID *Context\r
- )\r
-{\r
- EFI_STATUS Status;\r
- TCP4_SERVICE_DATA *TcpServiceData;\r
- EFI_IP4_PROTOCOL *Ip4;\r
-\r
- TcpServiceData = ((TCP4_PROTO_DATA *) This->ProtoReserved)->TcpService;\r
-\r
- //\r
- // Open the default Ip4 protocol of IP_IO BY_DRIVER.\r
- //\r
- Status = gBS->OpenProtocol (\r
- TcpServiceData->IpIo->ChildHandle,\r
- &gEfiIp4ProtocolGuid,\r
- (VOID **) &Ip4,\r
- TcpServiceData->DriverBindingHandle,\r
- This->SockHandle,\r
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Open the device path on the handle where service binding resides on.\r
- //\r
- Status = gBS->OpenProtocol (\r
- TcpServiceData->ControllerHandle,\r
- &gEfiDevicePathProtocolGuid,\r
- (VOID **) &This->ParentDevicePath,\r
- TcpServiceData->DriverBindingHandle,\r
- This->SockHandle,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- gBS->CloseProtocol (\r
- TcpServiceData->IpIo->ChildHandle,\r
- &gEfiIp4ProtocolGuid,\r
- TcpServiceData->DriverBindingHandle,\r
- This->SockHandle\r
- );\r
- } else {\r
- //\r
- // Insert this socket into the SocketList.\r
- //\r
- InsertTailList (&TcpServiceData->SocketList, &This->Link);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Close Ip4 and device path protocols for a socket, and remove it from socket list.\r
-\r
- @param This Pointer to the socket to be removed\r
- @param Context Context of the socket\r
-\r
-**/\r
-VOID\r
-Tcp4DestroySocketCallback (\r
- IN SOCKET *This,\r
- IN VOID *Context\r
- )\r
-{\r
- TCP4_SERVICE_DATA *TcpServiceData;\r
-\r
- TcpServiceData = ((TCP4_PROTO_DATA *) This->ProtoReserved)->TcpService;\r
-\r
- //\r
- // Remove this node from the list.\r
- //\r
- RemoveEntryList (&This->Link);\r
-\r
- //\r
- // Close the Ip4 protocol.\r
- //\r
- gBS->CloseProtocol (\r
- TcpServiceData->IpIo->ChildHandle,\r
- &gEfiIp4ProtocolGuid,\r
- TcpServiceData->DriverBindingHandle,\r
- This->SockHandle\r
- );\r
-}\r
-\r
-/**\r
- Creates a child handle and installs a protocol.\r
-\r
- The CreateChild() function installs a protocol on ChildHandle. If ChildHandle\r
- is a pointer to NULL, then a new handle is created and returned in ChildHandle.\r
- If ChildHandle is not a pointer to NULL, then the protocol installs on the existing\r
- ChildHandle.\r
-\r
- @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
- @param ChildHandle Pointer to the handle of the child to create. If it is NULL, then\r
- a new handle is created. If it is a pointer to an existing UEFI\r
- handle, then the protocol is added to the existing UEFI handle.\r
-\r
- @retval EFI_SUCCES The protocol was added to ChildHandle.\r
- @retval EFI_INVALID_PARAMETER ChildHandle is NULL.\r
- @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create\r
- the child.\r
- @retval other The child handle was not created.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-Tcp4ServiceBindingCreateChild (\r
- IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
- IN OUT EFI_HANDLE *ChildHandle\r
- )\r
-{\r
- SOCKET *Sock;\r
- TCP4_SERVICE_DATA *TcpServiceData;\r
- TCP4_PROTO_DATA TcpProto;\r
- EFI_STATUS Status;\r
- EFI_TPL OldTpl;\r
-\r
- if (NULL == This || NULL == ChildHandle) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
- Status = EFI_SUCCESS;\r
- TcpServiceData = TCP4_FROM_THIS (This);\r
- TcpProto.TcpService = TcpServiceData;\r
- TcpProto.TcpPcb = NULL;\r
-\r
- //\r
- // Create a tcp instance with defualt Tcp default\r
- // sock init data and TcpProto\r
- //\r
- mTcp4DefaultSockData.ProtoData = &TcpProto;\r
- mTcp4DefaultSockData.DataSize = sizeof (TCP4_PROTO_DATA);\r
- mTcp4DefaultSockData.DriverBinding = TcpServiceData->DriverBindingHandle;\r
-\r
- Sock = SockCreateChild (&mTcp4DefaultSockData);\r
- if (NULL == Sock) {\r
- DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingCreateChild: "\r
- "No resource to create a Tcp Child\n"));\r
-\r
- Status = EFI_OUT_OF_RESOURCES;\r
- } else {\r
- *ChildHandle = Sock->SockHandle;\r
- }\r
-\r
- mTcp4DefaultSockData.ProtoData = NULL;\r
-\r
- gBS->RestoreTPL (OldTpl);\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Destroys a child handle with a protocol installed on it.\r
-\r
- The DestroyChild() function does the opposite of CreateChild(). It removes a protocol\r
- that was installed by CreateChild() from ChildHandle. If the removed protocol is the\r
- last protocol on ChildHandle, then ChildHandle is destroyed.\r
-\r
- @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
- @param ChildHandle Handle of the child to destroy\r
-\r
- @retval EFI_SUCCES The protocol was removed from ChildHandle.\r
- @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is\r
- being removed.\r
- @retval EFI_INVALID_PARAMETER Child handle is NULL.\r
- @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle\r
- because its services are being used.\r
- @retval other The child handle was not destroyed.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-Tcp4ServiceBindingDestroyChild (\r
- IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ChildHandle\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_TCP4_PROTOCOL *Tcp4;\r
- SOCKET *Sock;\r
-\r
- if (NULL == This || NULL == ChildHandle) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // retrieve the Tcp4 protocol from ChildHandle\r
- //\r
- Status = gBS->OpenProtocol (\r
- ChildHandle,\r
- &gEfiTcp4ProtocolGuid,\r
- (VOID **) &Tcp4,\r
- mTcp4DriverBinding.DriverBindingHandle,\r
- ChildHandle,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- Status = EFI_UNSUPPORTED;\r
- } else {\r
- //\r
- // destroy this sock and related Tcp protocol control\r
- // block\r
- //\r
- Sock = SOCK_FROM_THIS (Tcp4);\r
-\r
- SockDestroyChild (Sock);\r
- }\r
-\r
- return Status;\r
-}\r
-\r