2007-07-24 10:06:37 +02:00
|
|
|
/** @file
|
|
|
|
|
|
|
|
Copyright (c) 2005 - 2007, 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
|
|
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
|
|
|
|
Module Name:
|
|
|
|
|
|
|
|
Tcp4Driver.c
|
|
|
|
|
|
|
|
Abstract:
|
|
|
|
|
|
|
|
|
|
|
|
**/
|
|
|
|
|
|
|
|
#include "Tcp4Main.h"
|
|
|
|
|
|
|
|
|
2008-12-06 00:47:55 +01:00
|
|
|
UINT16 mTcp4RandomPort;
|
2007-09-30 05:08:02 +02:00
|
|
|
extern EFI_COMPONENT_NAME_PROTOCOL gTcp4ComponentName;
|
|
|
|
extern EFI_COMPONENT_NAME2_PROTOCOL gTcp4ComponentName2;
|
2007-07-24 10:06:37 +02:00
|
|
|
|
|
|
|
TCP4_HEARTBEAT_TIMER mTcp4Timer = {
|
|
|
|
NULL,
|
|
|
|
0
|
|
|
|
};
|
|
|
|
|
|
|
|
EFI_TCP4_PROTOCOL mTcp4ProtocolTemplate = {
|
|
|
|
Tcp4GetModeData,
|
|
|
|
Tcp4Configure,
|
|
|
|
Tcp4Routes,
|
|
|
|
Tcp4Connect,
|
|
|
|
Tcp4Accept,
|
|
|
|
Tcp4Transmit,
|
|
|
|
Tcp4Receive,
|
|
|
|
Tcp4Close,
|
|
|
|
Tcp4Cancel,
|
|
|
|
Tcp4Poll
|
|
|
|
};
|
|
|
|
|
|
|
|
SOCK_INIT_DATA mTcp4DefaultSockData = {
|
|
|
|
SOCK_STREAM,
|
2007-07-25 07:32:10 +02:00
|
|
|
(SOCK_STATE) 0,
|
2007-07-24 10:06:37 +02:00
|
|
|
NULL,
|
|
|
|
TCP_BACKLOG,
|
|
|
|
TCP_SND_BUF_SIZE,
|
|
|
|
TCP_RCV_BUF_SIZE,
|
|
|
|
&mTcp4ProtocolTemplate,
|
2008-01-29 09:47:42 +01:00
|
|
|
Tcp4CreateSocketCallback,
|
|
|
|
Tcp4DestroySocketCallback,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
0,
|
2007-07-24 10:06:37 +02:00
|
|
|
Tcp4Dispatcher,
|
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
|
|
|
EFI_DRIVER_BINDING_PROTOCOL mTcp4DriverBinding = {
|
|
|
|
Tcp4DriverBindingSupported,
|
|
|
|
Tcp4DriverBindingStart,
|
|
|
|
Tcp4DriverBindingStop,
|
|
|
|
0xa,
|
|
|
|
NULL,
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
EFI_SERVICE_BINDING_PROTOCOL mTcp4ServiceBinding = {
|
|
|
|
Tcp4ServiceBindingCreateChild,
|
|
|
|
Tcp4ServiceBindingDestroyChild
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Create and start the heartbeat timer for TCP driver.
|
|
|
|
|
|
|
|
@retval EFI_SUCCESS The timer is successfully created and started.
|
|
|
|
@retval other The timer is not created.
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
Tcp4CreateTimer (
|
|
|
|
VOID
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
|
|
|
|
Status = EFI_SUCCESS;
|
|
|
|
|
|
|
|
if (mTcp4Timer.RefCnt == 0) {
|
|
|
|
|
|
|
|
Status = gBS->CreateEvent (
|
|
|
|
EVT_TIMER | EVT_NOTIFY_SIGNAL,
|
2008-02-14 10:40:22 +01:00
|
|
|
TPL_NOTIFY,
|
2007-07-24 10:06:37 +02:00
|
|
|
TcpTicking,
|
|
|
|
NULL,
|
|
|
|
&mTcp4Timer.TimerEvent
|
|
|
|
);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
|
|
|
|
|
|
Status = gBS->SetTimer (
|
|
|
|
mTcp4Timer.TimerEvent,
|
|
|
|
TimerPeriodic,
|
|
|
|
(UINT64) (TICKS_PER_SECOND / TCP_TICK_HZ)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
|
|
|
|
|
|
mTcp4Timer.RefCnt++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Stop and destroy the heartbeat timer for TCP driver.
|
2008-11-28 09:32:24 +01:00
|
|
|
|
2007-07-24 10:06:37 +02:00
|
|
|
**/
|
|
|
|
VOID
|
2008-12-06 00:47:55 +01:00
|
|
|
Tcp4DestroyTimer (
|
|
|
|
VOID
|
|
|
|
)
|
2007-07-24 10:06:37 +02:00
|
|
|
{
|
|
|
|
ASSERT (mTcp4Timer.RefCnt > 0);
|
|
|
|
|
|
|
|
mTcp4Timer.RefCnt--;
|
|
|
|
|
|
|
|
if (mTcp4Timer.RefCnt > 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
gBS->SetTimer (mTcp4Timer.TimerEvent, TimerCancel, 0);
|
|
|
|
gBS->CloseEvent (mTcp4Timer.TimerEvent);
|
|
|
|
mTcp4Timer.TimerEvent = NULL;
|
|
|
|
}
|
|
|
|
|
2008-11-28 09:32:24 +01:00
|
|
|
/**
|
2008-12-06 00:47:55 +01:00
|
|
|
The entry point for Tcp4 driver, used to install Tcp4 driver on the ImageHandle.
|
2008-11-28 09:32:24 +01:00
|
|
|
|
|
|
|
@param ImageHandle The firmware allocated handle for this
|
|
|
|
driver image.
|
|
|
|
@param SystemTable Pointer to the EFI system table.
|
|
|
|
|
|
|
|
@retval EFI_SUCCESS Driver loaded.
|
|
|
|
@retval other Driver not loaded.
|
2007-07-24 10:06:37 +02:00
|
|
|
|
2008-11-28 09:32:24 +01:00
|
|
|
**/
|
2007-07-24 10:06:37 +02:00
|
|
|
EFI_STATUS
|
|
|
|
EFIAPI
|
|
|
|
Tcp4DriverEntryPoint (
|
|
|
|
IN EFI_HANDLE ImageHandle,
|
|
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
UINT32 Seed;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Install the TCP4 Driver Binding Protocol
|
|
|
|
//
|
2007-09-30 05:08:02 +02:00
|
|
|
Status = EfiLibInstallDriverBindingComponentName2 (
|
2007-07-24 10:06:37 +02:00
|
|
|
ImageHandle,
|
|
|
|
SystemTable,
|
|
|
|
&mTcp4DriverBinding,
|
|
|
|
ImageHandle,
|
|
|
|
&gTcp4ComponentName,
|
2007-09-30 05:08:02 +02:00
|
|
|
&gTcp4ComponentName2
|
2007-07-24 10:06:37 +02:00
|
|
|
);
|
2007-09-28 08:02:01 +02:00
|
|
|
ASSERT_EFI_ERROR (Status);
|
2007-07-24 10:06:37 +02:00
|
|
|
//
|
|
|
|
// Initialize ISS and random port.
|
|
|
|
//
|
|
|
|
Seed = NetRandomInitSeed ();
|
|
|
|
mTcpGlobalIss = NET_RANDOM (Seed) % mTcpGlobalIss;
|
2008-12-06 00:47:55 +01:00
|
|
|
mTcp4RandomPort = (UINT16) (TCP4_PORT_KNOWN +
|
2007-07-25 07:32:10 +02:00
|
|
|
(UINT16) (NET_RANDOM(Seed) % TCP4_PORT_KNOWN));
|
2007-07-24 10:06:37 +02:00
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Test to see if this driver supports ControllerHandle.
|
|
|
|
|
|
|
|
@param This Protocol instance pointer.
|
|
|
|
@param ControllerHandle Handle of device to test.
|
|
|
|
@param 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
|
|
|
|
Tcp4DriverBindingSupported (
|
2008-12-06 00:47:55 +01:00
|
|
|
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
2007-07-24 10:06:37 +02:00
|
|
|
IN EFI_HANDLE ControllerHandle,
|
2008-12-06 00:47:55 +01:00
|
|
|
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
2007-07-24 10:06:37 +02:00
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Test for the Tcp4ServiceBinding Protocol
|
|
|
|
//
|
|
|
|
Status = gBS->OpenProtocol (
|
|
|
|
ControllerHandle,
|
|
|
|
&gEfiTcp4ServiceBindingProtocolGuid,
|
|
|
|
NULL,
|
|
|
|
This->DriverBindingHandle,
|
|
|
|
ControllerHandle,
|
|
|
|
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
|
|
|
);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
|
|
return EFI_ALREADY_STARTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Test for the Ip4 Protocol
|
|
|
|
//
|
|
|
|
Status = gBS->OpenProtocol (
|
|
|
|
ControllerHandle,
|
|
|
|
&gEfiIp4ServiceBindingProtocolGuid,
|
|
|
|
NULL,
|
|
|
|
This->DriverBindingHandle,
|
|
|
|
ControllerHandle,
|
|
|
|
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
|
|
|
);
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Start this driver on ControllerHandle.
|
|
|
|
|
|
|
|
@param This Protocol instance pointer.
|
|
|
|
@param ControllerHandle Handle of device to bind driver to.
|
|
|
|
@param 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 (
|
2008-12-06 00:47:55 +01:00
|
|
|
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
2007-07-24 10:06:37 +02:00
|
|
|
IN EFI_HANDLE ControllerHandle,
|
2008-12-06 00:47:55 +01:00
|
|
|
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
2007-07-24 10:06:37 +02:00
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
TCP4_SERVICE_DATA *TcpServiceData;
|
|
|
|
IP_IO_OPEN_DATA OpenData;
|
|
|
|
|
2008-02-14 10:40:22 +01:00
|
|
|
TcpServiceData = AllocateZeroPool (sizeof (TCP4_SERVICE_DATA));
|
2007-07-24 10:06:37 +02:00
|
|
|
|
|
|
|
if (NULL == TcpServiceData) {
|
2008-02-14 10:40:22 +01:00
|
|
|
DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Have no enough"
|
2007-07-24 10:06:37 +02:00
|
|
|
" resource to create a Tcp Servcie Data!\n"));
|
|
|
|
|
|
|
|
return EFI_OUT_OF_RESOURCES;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Create a new IP IO to Consume it
|
|
|
|
//
|
|
|
|
TcpServiceData->IpIo = IpIoCreate (This->DriverBindingHandle, ControllerHandle);
|
|
|
|
if (NULL == TcpServiceData->IpIo) {
|
|
|
|
|
2008-02-14 10:40:22 +01:00
|
|
|
DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Have no enough"
|
2007-07-24 10:06:37 +02:00
|
|
|
" resource to create an Ip Io!\n"));
|
|
|
|
|
|
|
|
Status = EFI_OUT_OF_RESOURCES;
|
2007-12-18 08:01:23 +01:00
|
|
|
goto ON_ERROR;
|
2007-07-24 10:06:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Configure and start IpIo.
|
|
|
|
//
|
2008-02-14 10:40:22 +01:00
|
|
|
ZeroMem (&OpenData, sizeof (IP_IO_OPEN_DATA));
|
2007-07-24 10:06:37 +02:00
|
|
|
|
2007-08-23 04:19:41 +02:00
|
|
|
CopyMem (&OpenData.IpConfigData, &mIpIoDefaultIpConfigData, sizeof (OpenData.IpConfigData));
|
2007-07-24 10:06:37 +02:00
|
|
|
OpenData.IpConfigData.DefaultProtocol = EFI_IP_PROTO_TCP;
|
|
|
|
|
|
|
|
OpenData.PktRcvdNotify = Tcp4RxCallback;
|
|
|
|
Status = IpIoOpen (TcpServiceData->IpIo, &OpenData);
|
|
|
|
|
|
|
|
if (EFI_ERROR (Status)) {
|
2007-12-18 08:01:23 +01:00
|
|
|
goto ON_ERROR;
|
2007-07-24 10:06:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Create the timer event used by TCP driver
|
|
|
|
//
|
|
|
|
Status = Tcp4CreateTimer ();
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
|
2008-02-14 10:40:22 +01:00
|
|
|
DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Create TcpTimer"
|
2007-07-24 10:06:37 +02:00
|
|
|
" Event failed with %r\n", Status));
|
|
|
|
|
2007-12-18 08:01:23 +01:00
|
|
|
goto ON_ERROR;
|
2007-07-24 10:06:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Install the Tcp4ServiceBinding Protocol on the
|
|
|
|
// controller handle
|
|
|
|
//
|
|
|
|
TcpServiceData->Tcp4ServiceBinding = mTcp4ServiceBinding;
|
|
|
|
|
|
|
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
|
|
|
&ControllerHandle,
|
|
|
|
&gEfiTcp4ServiceBindingProtocolGuid,
|
|
|
|
&TcpServiceData->Tcp4ServiceBinding,
|
|
|
|
NULL
|
|
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
|
2008-02-14 10:40:22 +01:00
|
|
|
DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStart: Install Tcp4 Service Binding"
|
2007-07-24 10:06:37 +02:00
|
|
|
" Protocol failed for %r\n", Status));
|
|
|
|
|
2007-12-18 08:01:23 +01:00
|
|
|
Tcp4DestroyTimer ();
|
|
|
|
goto ON_ERROR;
|
2007-07-24 10:06:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Initialize member in TcpServiceData
|
|
|
|
//
|
|
|
|
TcpServiceData->ControllerHandle = ControllerHandle;
|
|
|
|
TcpServiceData->Signature = TCP4_DRIVER_SIGNATURE;
|
|
|
|
TcpServiceData->DriverBindingHandle = This->DriverBindingHandle;
|
|
|
|
|
2008-02-14 10:40:22 +01:00
|
|
|
InitializeListHead (&TcpServiceData->SocketList);
|
2007-12-18 08:01:23 +01:00
|
|
|
|
2007-07-24 10:06:37 +02:00
|
|
|
TcpSetVariableData (TcpServiceData);
|
|
|
|
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
|
2007-12-18 08:01:23 +01:00
|
|
|
ON_ERROR:
|
2007-07-24 10:06:37 +02:00
|
|
|
|
2007-12-18 08:01:23 +01:00
|
|
|
if (TcpServiceData->IpIo != NULL) {
|
|
|
|
IpIoDestroy (TcpServiceData->IpIo);
|
|
|
|
}
|
2007-07-24 10:06:37 +02:00
|
|
|
|
2008-02-14 10:40:22 +01:00
|
|
|
gBS->FreePool (TcpServiceData);
|
2007-07-24 10:06:37 +02:00
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Stop this driver on ControllerHandle.
|
|
|
|
|
|
|
|
@param This Protocol instance pointer.
|
|
|
|
@param ControllerHandle Handle of device to stop driver on.
|
|
|
|
@param NumberOfChildren Number of Handles in ChildHandleBuffer. If number
|
|
|
|
of children is zero stop the entire bus driver.
|
|
|
|
@param ChildHandleBuffer List of Child Handles to Stop.
|
|
|
|
|
|
|
|
@retval EFI_SUCCESS This driver is removed from ControllerHandle.
|
|
|
|
@retval other This driver is not removed from ControllerHandle.
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
EFIAPI
|
|
|
|
Tcp4DriverBindingStop (
|
|
|
|
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
|
|
|
IN EFI_HANDLE ControllerHandle,
|
|
|
|
IN UINTN NumberOfChildren,
|
|
|
|
IN EFI_HANDLE *ChildHandleBuffer
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
EFI_HANDLE NicHandle;
|
2007-12-18 08:01:23 +01:00
|
|
|
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
|
2007-07-24 10:06:37 +02:00
|
|
|
TCP4_SERVICE_DATA *TcpServiceData;
|
|
|
|
SOCKET *Sock;
|
|
|
|
|
|
|
|
// Find the NicHandle where Tcp4 ServiceBinding Protocol is installed.
|
|
|
|
//
|
|
|
|
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);
|
|
|
|
if (NicHandle == NULL) {
|
2007-12-18 08:01:23 +01:00
|
|
|
return EFI_DEVICE_ERROR;
|
2007-07-24 10:06:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Retrieve the TCP driver Data Structure
|
|
|
|
//
|
|
|
|
Status = gBS->OpenProtocol (
|
|
|
|
NicHandle,
|
|
|
|
&gEfiTcp4ServiceBindingProtocolGuid,
|
2007-12-18 08:01:23 +01:00
|
|
|
(VOID **) &ServiceBinding,
|
2007-07-24 10:06:37 +02:00
|
|
|
This->DriverBindingHandle,
|
|
|
|
ControllerHandle,
|
|
|
|
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
|
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
|
2008-02-14 10:40:22 +01:00
|
|
|
DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingStop: Locate Tcp4 Service "
|
2007-07-24 10:06:37 +02:00
|
|
|
" Binding Protocol failed with %r\n", Status));
|
|
|
|
|
2007-12-18 08:01:23 +01:00
|
|
|
return EFI_DEVICE_ERROR;
|
2007-07-24 10:06:37 +02:00
|
|
|
}
|
|
|
|
|
2007-12-18 08:01:23 +01:00
|
|
|
TcpServiceData = TCP4_FROM_THIS (ServiceBinding);
|
2007-07-24 10:06:37 +02:00
|
|
|
|
2007-12-18 08:01:23 +01:00
|
|
|
if (NumberOfChildren == 0) {
|
2007-07-24 10:06:37 +02:00
|
|
|
//
|
2007-12-18 08:01:23 +01:00
|
|
|
// Uninstall TCP servicebinding protocol
|
2007-07-24 10:06:37 +02:00
|
|
|
//
|
2007-12-18 08:01:23 +01:00
|
|
|
gBS->UninstallMultipleProtocolInterfaces (
|
|
|
|
NicHandle,
|
|
|
|
&gEfiTcp4ServiceBindingProtocolGuid,
|
|
|
|
ServiceBinding,
|
|
|
|
NULL
|
|
|
|
);
|
2007-07-24 10:06:37 +02:00
|
|
|
|
2007-12-18 08:01:23 +01:00
|
|
|
//
|
|
|
|
// Destroy the IpIO consumed by TCP driver
|
|
|
|
//
|
|
|
|
IpIoDestroy (TcpServiceData->IpIo);
|
2007-07-24 10:06:37 +02:00
|
|
|
|
2007-12-18 08:01:23 +01:00
|
|
|
//
|
|
|
|
// Destroy the heartbeat timer.
|
|
|
|
//
|
|
|
|
Tcp4DestroyTimer ();
|
2007-07-24 10:06:37 +02:00
|
|
|
|
2007-12-18 08:01:23 +01:00
|
|
|
//
|
|
|
|
// Clear the variable.
|
|
|
|
//
|
|
|
|
TcpClearVariableData (TcpServiceData);
|
2007-07-24 10:06:37 +02:00
|
|
|
|
|
|
|
//
|
2007-12-18 08:01:23 +01:00
|
|
|
// Release the TCP service data
|
2007-07-24 10:06:37 +02:00
|
|
|
//
|
2008-02-14 10:40:22 +01:00
|
|
|
gBS->FreePool (TcpServiceData);
|
2007-12-18 08:01:23 +01:00
|
|
|
} else {
|
2007-07-24 10:06:37 +02:00
|
|
|
|
2008-02-14 10:40:22 +01:00
|
|
|
while (!IsListEmpty (&TcpServiceData->SocketList)) {
|
2007-12-18 08:01:23 +01:00
|
|
|
Sock = NET_LIST_HEAD (&TcpServiceData->SocketList, SOCKET, Link);
|
2007-07-24 10:06:37 +02:00
|
|
|
|
2007-12-18 08:01:23 +01:00
|
|
|
ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle);
|
2007-07-24 10:06:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2008-12-06 00:47:55 +01:00
|
|
|
/**
|
|
|
|
Open Ip4 and device path protocols for a created socket, and insert it in
|
|
|
|
socket list.
|
|
|
|
|
|
|
|
@param This Pointer to the socket just created
|
|
|
|
@param Context Context of the socket
|
|
|
|
|
|
|
|
@retval EFI_SUCCESS This protocol is installed successfully.
|
|
|
|
@retval other Some error occured.
|
|
|
|
|
|
|
|
**/
|
2008-01-29 09:47:42 +01:00
|
|
|
EFI_STATUS
|
|
|
|
Tcp4CreateSocketCallback (
|
|
|
|
IN SOCKET *This,
|
|
|
|
IN VOID *Context
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
TCP4_SERVICE_DATA *TcpServiceData;
|
|
|
|
EFI_IP4_PROTOCOL *Ip4;
|
|
|
|
|
|
|
|
TcpServiceData = ((TCP4_PROTO_DATA *) This->ProtoReserved)->TcpService;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Open the default Ip4 protocol of IP_IO BY_DRIVER.
|
|
|
|
//
|
|
|
|
Status = gBS->OpenProtocol (
|
|
|
|
TcpServiceData->IpIo->ChildHandle,
|
|
|
|
&gEfiIp4ProtocolGuid,
|
|
|
|
(VOID **) &Ip4,
|
|
|
|
TcpServiceData->DriverBindingHandle,
|
|
|
|
This->SockHandle,
|
|
|
|
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
|
|
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Open the device path on the handle where service binding resides on.
|
|
|
|
//
|
|
|
|
Status = gBS->OpenProtocol (
|
|
|
|
TcpServiceData->ControllerHandle,
|
|
|
|
&gEfiDevicePathProtocolGuid,
|
|
|
|
(VOID **) &This->ParentDevicePath,
|
|
|
|
TcpServiceData->DriverBindingHandle,
|
|
|
|
This->SockHandle,
|
|
|
|
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
|
|
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
gBS->CloseProtocol (
|
|
|
|
TcpServiceData->IpIo->ChildHandle,
|
|
|
|
&gEfiIp4ProtocolGuid,
|
|
|
|
TcpServiceData->DriverBindingHandle,
|
|
|
|
This->SockHandle
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
//
|
|
|
|
// Insert this socket into the SocketList.
|
|
|
|
//
|
2008-02-14 10:40:22 +01:00
|
|
|
InsertTailList (&TcpServiceData->SocketList, &This->Link);
|
2008-01-29 09:47:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2008-12-06 00:47:55 +01:00
|
|
|
/**
|
|
|
|
Close Ip4 and device path protocols for a socket, and remove it from socket list.
|
|
|
|
|
|
|
|
@param This Pointer to the socket to be removed
|
|
|
|
@param Context Context of the socket
|
|
|
|
|
|
|
|
**/
|
2008-01-29 09:47:42 +01:00
|
|
|
VOID
|
|
|
|
Tcp4DestroySocketCallback (
|
|
|
|
IN SOCKET *This,
|
|
|
|
IN VOID *Context
|
|
|
|
)
|
|
|
|
{
|
|
|
|
TCP4_SERVICE_DATA *TcpServiceData;
|
|
|
|
|
|
|
|
TcpServiceData = ((TCP4_PROTO_DATA *) This->ProtoReserved)->TcpService;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Remove this node from the list.
|
|
|
|
//
|
2008-02-14 10:40:22 +01:00
|
|
|
RemoveEntryList (&This->Link);
|
2008-01-29 09:47:42 +01:00
|
|
|
|
|
|
|
//
|
|
|
|
// Close the device path protocol
|
|
|
|
//
|
|
|
|
gBS->CloseProtocol (
|
|
|
|
TcpServiceData->ControllerHandle,
|
|
|
|
&gEfiDevicePathProtocolGuid,
|
|
|
|
TcpServiceData->DriverBindingHandle,
|
|
|
|
This->SockHandle
|
|
|
|
);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Close the Ip4 protocol.
|
|
|
|
//
|
|
|
|
gBS->CloseProtocol (
|
|
|
|
TcpServiceData->IpIo->ChildHandle,
|
|
|
|
&gEfiIp4ProtocolGuid,
|
|
|
|
TcpServiceData->DriverBindingHandle,
|
|
|
|
This->SockHandle
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2007-07-24 10:06:37 +02:00
|
|
|
/**
|
|
|
|
Creates a child handle with a set of TCP4 services.
|
|
|
|
|
|
|
|
@param This Protocol instance pointer.
|
|
|
|
@param ChildHandle Pointer to the handle of the child to create. If
|
|
|
|
it is NULL, then a new handle is created. If it is
|
|
|
|
not NULL, then the I/O services are added to the
|
|
|
|
existing child handle.
|
|
|
|
|
|
|
|
@retval EFI_SUCCESS The child handle is created.
|
|
|
|
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
|
|
|
@retval EFI_OUT_OF_RESOURCES There are not enough resources to create the
|
|
|
|
child.
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
EFIAPI
|
|
|
|
Tcp4ServiceBindingCreateChild (
|
|
|
|
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
|
|
|
IN EFI_HANDLE *ChildHandle
|
|
|
|
)
|
|
|
|
{
|
|
|
|
SOCKET *Sock;
|
|
|
|
TCP4_SERVICE_DATA *TcpServiceData;
|
|
|
|
TCP4_PROTO_DATA TcpProto;
|
|
|
|
EFI_STATUS Status;
|
|
|
|
EFI_TPL OldTpl;
|
|
|
|
|
|
|
|
if (NULL == This || NULL == ChildHandle) {
|
|
|
|
return EFI_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
2008-02-14 10:40:22 +01:00
|
|
|
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
2008-01-29 09:47:42 +01:00
|
|
|
Status = EFI_SUCCESS;
|
2007-07-24 10:06:37 +02:00
|
|
|
TcpServiceData = TCP4_FROM_THIS (This);
|
|
|
|
TcpProto.TcpService = TcpServiceData;
|
|
|
|
TcpProto.TcpPcb = NULL;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Create a tcp instance with defualt Tcp default
|
|
|
|
// sock init data and TcpProto
|
|
|
|
//
|
2008-01-29 09:47:42 +01:00
|
|
|
mTcp4DefaultSockData.ProtoData = &TcpProto;
|
|
|
|
mTcp4DefaultSockData.DataSize = sizeof (TCP4_PROTO_DATA);
|
2007-07-24 10:06:37 +02:00
|
|
|
mTcp4DefaultSockData.DriverBinding = TcpServiceData->DriverBindingHandle;
|
2008-02-14 10:40:22 +01:00
|
|
|
|
2008-01-29 09:47:42 +01:00
|
|
|
Sock = SockCreateChild (&mTcp4DefaultSockData);
|
2007-07-24 10:06:37 +02:00
|
|
|
if (NULL == Sock) {
|
2008-02-14 10:40:22 +01:00
|
|
|
DEBUG ((EFI_D_ERROR, "Tcp4DriverBindingCreateChild: "
|
2007-07-24 10:06:37 +02:00
|
|
|
"No resource to create a Tcp Child\n"));
|
|
|
|
|
|
|
|
Status = EFI_OUT_OF_RESOURCES;
|
2007-12-18 08:01:23 +01:00
|
|
|
} else {
|
2008-01-29 09:47:42 +01:00
|
|
|
*ChildHandle = Sock->SockHandle;
|
2007-07-24 10:06:37 +02:00
|
|
|
}
|
|
|
|
|
2008-02-14 10:40:22 +01:00
|
|
|
gBS->RestoreTPL (OldTpl);
|
2007-07-24 10:06:37 +02:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Destroys a child handle with a set of UDP4 services.
|
|
|
|
|
|
|
|
@param This Protocol instance pointer.
|
|
|
|
@param ChildHandle Handle of the child to be destroyed.
|
|
|
|
|
|
|
|
@retval EFI_SUCCESS The TCP4 services are removed from the child
|
|
|
|
handle.
|
|
|
|
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
|
|
|
@retval other The child handle is not destroyed.
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
EFIAPI
|
|
|
|
Tcp4ServiceBindingDestroyChild (
|
|
|
|
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
|
|
|
IN EFI_HANDLE ChildHandle
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
EFI_TCP4_PROTOCOL *Tcp4;
|
|
|
|
SOCKET *Sock;
|
|
|
|
EFI_TPL OldTpl;
|
|
|
|
|
|
|
|
if (NULL == This || NULL == ChildHandle) {
|
|
|
|
return EFI_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
2008-02-14 10:40:22 +01:00
|
|
|
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
2007-07-24 10:06:37 +02:00
|
|
|
|
|
|
|
//
|
|
|
|
// retrieve the Tcp4 protocol from ChildHandle
|
|
|
|
//
|
|
|
|
Status = gBS->OpenProtocol (
|
|
|
|
ChildHandle,
|
|
|
|
&gEfiTcp4ProtocolGuid,
|
|
|
|
(VOID **) &Tcp4,
|
|
|
|
mTcp4DriverBinding.DriverBindingHandle,
|
|
|
|
ChildHandle,
|
|
|
|
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
|
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
Status = EFI_UNSUPPORTED;
|
2008-01-29 09:47:42 +01:00
|
|
|
} else {
|
|
|
|
//
|
|
|
|
// destroy this sock and related Tcp protocol control
|
|
|
|
// block
|
|
|
|
//
|
|
|
|
Sock = SOCK_FROM_THIS (Tcp4);
|
2007-08-27 11:17:26 +02:00
|
|
|
|
2008-01-29 09:47:42 +01:00
|
|
|
SockDestroyChild (Sock);
|
|
|
|
}
|
2007-07-24 10:06:37 +02:00
|
|
|
|
2008-02-14 10:40:22 +01:00
|
|
|
gBS->RestoreTPL (OldTpl);
|
2007-07-24 10:06:37 +02:00
|
|
|
return Status;
|
|
|
|
}
|
2008-01-29 09:47:42 +01:00
|
|
|
|