mirror of https://github.com/acidanthera/audk.git
Sync the latest version from R8.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4400 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
372787b85a
commit
c4a62a12c2
|
@ -213,6 +213,8 @@ extern IP4_ADDR mIp4AllMasks [IP4_MASK_NUM];
|
||||||
extern EFI_IPv4_ADDRESS mZeroIp4Addr;
|
extern EFI_IPv4_ADDRESS mZeroIp4Addr;
|
||||||
|
|
||||||
#define NET_IS_DIGIT(Ch) (('0' <= (Ch)) && ((Ch) <= '9'))
|
#define NET_IS_DIGIT(Ch) (('0' <= (Ch)) && ((Ch) <= '9'))
|
||||||
|
#define NET_ROUNDUP(size, unit) (((size) + (unit) - 1) & (~((unit) - 1)))
|
||||||
|
|
||||||
//
|
//
|
||||||
// Wrap functions to ease the impact of EFI library changes.
|
// Wrap functions to ease the impact of EFI library changes.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1092,12 +1092,6 @@ IpIoCancelTxToken (
|
||||||
Ip = SndEntry->Ip;
|
Ip = SndEntry->Ip;
|
||||||
Ip->Cancel (Ip, SndEntry->SndToken);
|
Ip->Cancel (Ip, SndEntry->SndToken);
|
||||||
|
|
||||||
//
|
|
||||||
// Abort the user token.
|
|
||||||
//
|
|
||||||
SndEntry->SndToken->Status = EFI_ABORTED;
|
|
||||||
IpIoTransmitHandler (NULL, SndEntry);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -413,7 +413,7 @@ ArpDriverBindingStop (
|
||||||
//
|
//
|
||||||
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
|
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
|
||||||
if (NicHandle == NULL) {
|
if (NicHandle == NULL) {
|
||||||
return EFI_SUCCESS;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -429,51 +429,44 @@ ArpDriverBindingStop (
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
ARP_DEBUG_ERROR (("ArpDriverBindingStop: Open ArpSb failed, %r.\n", Status));
|
ARP_DEBUG_ERROR (("ArpDriverBindingStop: Open ArpSb failed, %r.\n", Status));
|
||||||
return Status;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArpService = ARP_SERVICE_DATA_FROM_THIS (ServiceBinding);
|
ArpService = ARP_SERVICE_DATA_FROM_THIS (ServiceBinding);
|
||||||
|
|
||||||
while (!NetListIsEmpty (&ArpService->ChildrenList)) {
|
if (NumberOfChildren == 0) {
|
||||||
//
|
//
|
||||||
// Iterate all the instances.
|
// Uninstall the ARP ServiceBinding protocol.
|
||||||
//
|
//
|
||||||
Instance = NET_LIST_HEAD (&ArpService->ChildrenList, ARP_INSTANCE_DATA, List);
|
gBS->UninstallMultipleProtocolInterfaces (
|
||||||
|
NicHandle,
|
||||||
|
&gEfiArpServiceBindingProtocolGuid,
|
||||||
|
&ArpService->ServiceBinding,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Destroy this arp child.
|
// Clean the arp servicebinding context data and free the memory allocated.
|
||||||
//
|
//
|
||||||
|
ArpCleanService (ArpService);
|
||||||
|
|
||||||
|
NetFreePool (ArpService);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
while (!NetListIsEmpty (&ArpService->ChildrenList)) {
|
||||||
|
Instance = NET_LIST_HEAD (&ArpService->ChildrenList, ARP_INSTANCE_DATA, List);
|
||||||
|
|
||||||
ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
|
ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT (NetListIsEmpty (&ArpService->PendingRequestTable));
|
ASSERT (NetListIsEmpty (&ArpService->PendingRequestTable));
|
||||||
ASSERT (NetListIsEmpty (&ArpService->DeniedCacheTable));
|
ASSERT (NetListIsEmpty (&ArpService->DeniedCacheTable));
|
||||||
ASSERT (NetListIsEmpty (&ArpService->ResolvedCacheTable));
|
ASSERT (NetListIsEmpty (&ArpService->ResolvedCacheTable));
|
||||||
|
|
||||||
//
|
|
||||||
// Uninstall the ARP ServiceBinding protocol.
|
|
||||||
//
|
|
||||||
Status = gBS->UninstallMultipleProtocolInterfaces (
|
|
||||||
NicHandle,
|
|
||||||
&gEfiArpServiceBindingProtocolGuid,
|
|
||||||
&ArpService->ServiceBinding,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
ARP_DEBUG_ERROR (("ArpDriverBindingStop: Failed to uninstall ArpSb, %r.\n", Status));
|
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
return EFI_SUCCESS;
|
||||||
// Clean the arp servicebinding context data and free the memory allocated.
|
|
||||||
//
|
|
||||||
ArpCleanService (ArpService);
|
|
||||||
NetFreePool (ArpService);
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Creates a child handle with a set of I/O services.
|
Creates a child handle with a set of I/O services.
|
||||||
|
|
||||||
|
|
|
@ -229,7 +229,7 @@ Dhcp4CreateService (
|
||||||
//
|
//
|
||||||
Status = gBS->CreateEvent (
|
Status = gBS->CreateEvent (
|
||||||
EVT_NOTIFY_SIGNAL | EVT_TIMER,
|
EVT_NOTIFY_SIGNAL | EVT_TIMER,
|
||||||
TPL_CALLBACK,
|
NET_TPL_TIMER,
|
||||||
DhcpOnTimerTick,
|
DhcpOnTimerTick,
|
||||||
DhcpSb,
|
DhcpSb,
|
||||||
&DhcpSb->Timer
|
&DhcpSb->Timer
|
||||||
|
@ -372,7 +372,7 @@ Dhcp4DriverBindingStop (
|
||||||
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp4ProtocolGuid);
|
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp4ProtocolGuid);
|
||||||
|
|
||||||
if (NicHandle == NULL) {
|
if (NicHandle == NULL) {
|
||||||
return EFI_SUCCESS;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = gBS->OpenProtocol (
|
Status = gBS->OpenProtocol (
|
||||||
|
@ -395,43 +395,38 @@ Dhcp4DriverBindingStop (
|
||||||
}
|
}
|
||||||
|
|
||||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||||
DhcpSb->InDestory = TRUE;
|
|
||||||
|
|
||||||
|
if (NumberOfChildren == 0) {
|
||||||
|
|
||||||
|
DhcpSb->InDestory = TRUE;
|
||||||
|
DhcpSb->ServiceState = DHCP_DESTORY;
|
||||||
|
|
||||||
|
gBS->UninstallProtocolInterface (
|
||||||
|
NicHandle,
|
||||||
|
&gEfiDhcp4ServiceBindingProtocolGuid,
|
||||||
|
ServiceBinding
|
||||||
|
);
|
||||||
|
|
||||||
|
Dhcp4CloseService (DhcpSb);
|
||||||
|
|
||||||
|
NetFreePool (DhcpSb);
|
||||||
|
} else {
|
||||||
//
|
//
|
||||||
// Don't use NET_LIST_FOR_EACH_SAFE here, Dhcp4ServiceBindingDestoryChild
|
// Don't use NET_LIST_FOR_EACH_SAFE here, Dhcp4ServiceBindingDestoryChild
|
||||||
// may cause other child to be deleted.
|
// may cause other child to be deleted.
|
||||||
//
|
//
|
||||||
while (!NetListIsEmpty (&DhcpSb->Children)) {
|
while (!NetListIsEmpty (&DhcpSb->Children)) {
|
||||||
Instance = NET_LIST_HEAD (&DhcpSb->Children, DHCP_PROTOCOL, Link);
|
Instance = NET_LIST_HEAD (&DhcpSb->Children, DHCP_PROTOCOL, Link);
|
||||||
Dhcp4ServiceBindingDestroyChild (ServiceBinding, Instance->Handle);
|
ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DhcpSb->NumChildren != 0) {
|
if (DhcpSb->NumChildren != 0) {
|
||||||
Status = EFI_DEVICE_ERROR;
|
Status = EFI_DEVICE_ERROR;
|
||||||
goto ON_ERROR;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DhcpSb->ServiceState = DHCP_DESTORY;
|
|
||||||
|
|
||||||
Status = gBS->UninstallProtocolInterface (
|
|
||||||
NicHandle,
|
|
||||||
&gEfiDhcp4ServiceBindingProtocolGuid,
|
|
||||||
ServiceBinding
|
|
||||||
);
|
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
goto ON_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
Dhcp4CloseService (DhcpSb);
|
|
||||||
NET_RESTORE_TPL (OldTpl);
|
NET_RESTORE_TPL (OldTpl);
|
||||||
|
|
||||||
NetFreePool (DhcpSb);
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
|
|
||||||
ON_ERROR:
|
|
||||||
DhcpSb->InDestory = FALSE;
|
|
||||||
NET_RESTORE_TPL (OldTpl);
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,6 +455,8 @@ DhcpInitProtocol (
|
||||||
Instance->CompletionEvent = NULL;
|
Instance->CompletionEvent = NULL;
|
||||||
Instance->RenewRebindEvent = NULL;
|
Instance->RenewRebindEvent = NULL;
|
||||||
Instance->Token = NULL;
|
Instance->Token = NULL;
|
||||||
|
Instance->UdpIo = NULL;
|
||||||
|
NetbufQueInit (&Instance->ResponseQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -58,10 +58,6 @@ EfiDhcp4GetModeData (
|
||||||
|
|
||||||
Instance = DHCP_INSTANCE_FROM_THIS (This);
|
Instance = DHCP_INSTANCE_FROM_THIS (This);
|
||||||
|
|
||||||
if (Instance->Signature != DHCP_PROTOCOL_SIGNATURE) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||||
DhcpSb = Instance->Service;
|
DhcpSb = Instance->Service;
|
||||||
|
|
||||||
|
@ -766,6 +762,226 @@ EfiDhcp4Build (
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
EFI_STATUS
|
||||||
|
Dhcp4InstanceConfigUdpIo (
|
||||||
|
IN UDP_IO_PORT *UdpIo,
|
||||||
|
IN VOID *Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DHCP_PROTOCOL *Instance;
|
||||||
|
DHCP_SERVICE *DhcpSb;
|
||||||
|
EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN *Token;
|
||||||
|
EFI_UDP4_CONFIG_DATA UdpConfigData;
|
||||||
|
IP4_ADDR Ip;
|
||||||
|
|
||||||
|
Instance = (DHCP_PROTOCOL *) Context;
|
||||||
|
DhcpSb = Instance->Service;
|
||||||
|
Token = Instance->Token;
|
||||||
|
|
||||||
|
NetZeroMem (&UdpConfigData, sizeof (EFI_UDP4_CONFIG_DATA));
|
||||||
|
|
||||||
|
UdpConfigData.AcceptBroadcast = TRUE;
|
||||||
|
UdpConfigData.AllowDuplicatePort = TRUE;
|
||||||
|
UdpConfigData.TimeToLive = 64;
|
||||||
|
UdpConfigData.DoNotFragment = TRUE;
|
||||||
|
|
||||||
|
Ip = HTONL (DhcpSb->ClientAddr);
|
||||||
|
NetCopyMem (&UdpConfigData.StationAddress, &Ip, sizeof (EFI_IPv4_ADDRESS));
|
||||||
|
|
||||||
|
Ip = HTONL (DhcpSb->Netmask);
|
||||||
|
NetCopyMem (&UdpConfigData.SubnetMask, &Ip, sizeof (EFI_IPv4_ADDRESS));
|
||||||
|
|
||||||
|
if ((Token->ListenPointCount == 0) || (Token->ListenPoints[0].ListenPort == 0)) {
|
||||||
|
UdpConfigData.StationPort = DHCP_CLIENT_PORT;
|
||||||
|
} else {
|
||||||
|
UdpConfigData.StationPort = Token->ListenPoints[0].ListenPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
return UdpIo->Udp->Configure (UdpIo->Udp, &UdpConfigData);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
EFI_STATUS
|
||||||
|
Dhcp4InstanceCreateUdpIo (
|
||||||
|
IN DHCP_PROTOCOL *Instance
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DHCP_SERVICE *DhcpSb;
|
||||||
|
|
||||||
|
ASSERT (Instance->Token != NULL);
|
||||||
|
|
||||||
|
DhcpSb = Instance->Service;
|
||||||
|
Instance->UdpIo = UdpIoCreatePort (DhcpSb->Controller, DhcpSb->Image, Dhcp4InstanceConfigUdpIo, Instance);
|
||||||
|
if (Instance->UdpIo == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
} else {
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
DhcpDummyExtFree (
|
||||||
|
IN VOID *Arg
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Release the packet.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Arg - The packet to release
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
PxeDhcpInput (
|
||||||
|
NET_BUF *UdpPacket,
|
||||||
|
UDP_POINTS *Points,
|
||||||
|
EFI_STATUS IoStatus,
|
||||||
|
VOID *Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DHCP_PROTOCOL *Instance;
|
||||||
|
DHCP_SERVICE *DhcpSb;
|
||||||
|
EFI_DHCP4_HEADER *Head;
|
||||||
|
NET_BUF *Wrap;
|
||||||
|
EFI_DHCP4_PACKET *Packet;
|
||||||
|
EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN *Token;
|
||||||
|
UINT32 Len;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
Wrap = NULL;
|
||||||
|
Instance = (DHCP_PROTOCOL *) Context;
|
||||||
|
Token = Instance->Token;
|
||||||
|
DhcpSb = Instance->Service;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Don't restart receive if error occurs or DHCP is destoried.
|
||||||
|
//
|
||||||
|
if (EFI_ERROR (IoStatus)) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT (UdpPacket != NULL);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate the packet received
|
||||||
|
//
|
||||||
|
if (UdpPacket->TotalSize < sizeof (EFI_DHCP4_HEADER)) {
|
||||||
|
goto RESTART;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copy the DHCP message to a continuous memory block, make the buffer size
|
||||||
|
// of the EFI_DHCP4_PACKET a multiple of 4-byte.
|
||||||
|
//
|
||||||
|
Len = NET_ROUNDUP (sizeof (EFI_DHCP4_PACKET) + UdpPacket->TotalSize - sizeof (EFI_DHCP4_HEADER), 4);
|
||||||
|
Wrap = NetbufAlloc (Len);
|
||||||
|
|
||||||
|
if (Wrap == NULL) {
|
||||||
|
goto RESTART;
|
||||||
|
}
|
||||||
|
|
||||||
|
Packet = (EFI_DHCP4_PACKET *) NetbufAllocSpace (Wrap, Len, NET_BUF_TAIL);
|
||||||
|
Packet->Size = Len;
|
||||||
|
Head = &Packet->Dhcp4.Header;
|
||||||
|
Packet->Length = NetbufCopy (UdpPacket, 0, UdpPacket->TotalSize, (UINT8 *) Head);
|
||||||
|
|
||||||
|
if (Packet->Length != UdpPacket->TotalSize) {
|
||||||
|
goto RESTART;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Is this packet the answer to our packet?
|
||||||
|
//
|
||||||
|
if ((Head->OpCode != BOOTP_REPLY) ||
|
||||||
|
(Head->Xid != Token->Packet->Dhcp4.Header.Xid) ||
|
||||||
|
!NET_MAC_EQUAL (&DhcpSb->Mac, Head->ClientHwAddr, DhcpSb->HwLen)) {
|
||||||
|
goto RESTART;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate the options and retrieve the interested options
|
||||||
|
//
|
||||||
|
if ((Packet->Length > sizeof (EFI_DHCP4_HEADER) + sizeof (UINT32)) &&
|
||||||
|
(Packet->Dhcp4.Magik == DHCP_OPTION_MAGIC) &&
|
||||||
|
EFI_ERROR (DhcpValidateOptions (Packet, NULL))) {
|
||||||
|
|
||||||
|
goto RESTART;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Keep this packet in the ResponseQueue.
|
||||||
|
//
|
||||||
|
NET_GET_REF (Wrap);
|
||||||
|
NetbufQueAppend (&Instance->ResponseQueue, Wrap);
|
||||||
|
|
||||||
|
RESTART:
|
||||||
|
|
||||||
|
NetbufFree (UdpPacket);
|
||||||
|
|
||||||
|
if (Wrap != NULL) {
|
||||||
|
NetbufFree (Wrap);
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = UdpIoRecvDatagram (Instance->UdpIo, PxeDhcpInput, Instance, 0);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
PxeDhcpDone (Instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
PxeDhcpDone (
|
||||||
|
IN DHCP_PROTOCOL *Instance
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN *Token;
|
||||||
|
|
||||||
|
Token = Instance->Token;
|
||||||
|
|
||||||
|
Token->ResponseCount = Instance->ResponseQueue.BufNum;
|
||||||
|
if (Token->ResponseCount != 0) {
|
||||||
|
Token->ResponseList = (EFI_DHCP4_PACKET *) NetAllocatePool (Instance->ResponseQueue.BufSize);
|
||||||
|
if (Token->ResponseList == NULL) {
|
||||||
|
Token->Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
goto SIGNAL_USER;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copy the recieved DHCP responses.
|
||||||
|
//
|
||||||
|
NetbufQueCopy (&Instance->ResponseQueue, 0, Instance->ResponseQueue.BufSize, (UINT8 *) Token->ResponseList);
|
||||||
|
Token->Status = EFI_SUCCESS;
|
||||||
|
} else {
|
||||||
|
Token->ResponseList = NULL;
|
||||||
|
Token->Status = EFI_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
SIGNAL_USER:
|
||||||
|
//
|
||||||
|
// Clean the resources dedicated for this transmit receive transaction.
|
||||||
|
//
|
||||||
|
NetbufQueFlush (&Instance->ResponseQueue);
|
||||||
|
UdpIoCleanPort (Instance->UdpIo);
|
||||||
|
UdpIoFreePort (Instance->UdpIo);
|
||||||
|
Instance->UdpIo = NULL;
|
||||||
|
Instance->Token = NULL;
|
||||||
|
|
||||||
|
if (Token->CompletionEvent != NULL) {
|
||||||
|
gBS->SignalEvent (Token->CompletionEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Transmit and receive a packet through this DHCP service.
|
Transmit and receive a packet through this DHCP service.
|
||||||
|
@ -785,10 +1001,144 @@ EfiDhcp4TransmitReceive (
|
||||||
IN EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN *Token
|
IN EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN *Token
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
DHCP_PROTOCOL *Instance;
|
||||||
|
EFI_TPL OldTpl;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
NET_FRAGMENT Frag;
|
||||||
|
NET_BUF *Wrap;
|
||||||
|
UDP_POINTS EndPoint;
|
||||||
|
IP4_ADDR Ip;
|
||||||
|
DHCP_SERVICE *DhcpSb;
|
||||||
|
IP4_ADDR Gateway;
|
||||||
|
IP4_ADDR SubnetMask;
|
||||||
|
|
||||||
|
if ((This == NULL) || (Token == NULL) || (Token->Packet == NULL)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
Instance = DHCP_INSTANCE_FROM_THIS (This);
|
||||||
|
DhcpSb = Instance->Service;
|
||||||
|
|
||||||
|
if (Instance->Token != NULL) {
|
||||||
//
|
//
|
||||||
// This function is for PXE, leave it for now
|
// The previous call to TransmitReceive is not finished.
|
||||||
//
|
//
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_NOT_READY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Token->Packet->Dhcp4.Magik != DHCP_OPTION_MAGIC) ||
|
||||||
|
(NTOHL (Token->Packet->Dhcp4.Header.Xid) == Instance->Service->Xid) ||
|
||||||
|
(Token->TimeoutValue == 0) ||
|
||||||
|
((Token->ListenPointCount != 0) && (Token->ListenPoints == NULL)) ||
|
||||||
|
EFI_ERROR (DhcpValidateOptions (Token->Packet, NULL)) ||
|
||||||
|
EFI_IP4_EQUAL (&Token->RemoteAddress, &mZeroIp4Addr)) {
|
||||||
|
//
|
||||||
|
// The DHCP packet isn't well-formed, the Transaction ID is already used
|
||||||
|
// , the timeout value is zero, the ListenPoint is invalid,
|
||||||
|
// or the RemoteAddress is zero.
|
||||||
|
//
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DhcpSb->ClientAddr == 0) {
|
||||||
|
|
||||||
|
return EFI_NO_MAPPING;
|
||||||
|
}
|
||||||
|
|
||||||
|
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Save the token and the timeout value.
|
||||||
|
//
|
||||||
|
Instance->Token = Token;
|
||||||
|
Instance->Timeout = Token->TimeoutValue;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create a UDP IO for this transmit receive transaction.
|
||||||
|
//
|
||||||
|
Status = Dhcp4InstanceCreateUdpIo (Instance);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Wrap the DHCP packet into a net buffer.
|
||||||
|
//
|
||||||
|
Frag.Bulk = (UINT8 *) &Token->Packet->Dhcp4;
|
||||||
|
Frag.Len = Token->Packet->Length;
|
||||||
|
Wrap = NetbufFromExt (&Frag, 1, 0, 0, DhcpDummyExtFree, NULL);
|
||||||
|
if (Wrap == NULL) {
|
||||||
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set the local address and local port.
|
||||||
|
//
|
||||||
|
EndPoint.LocalAddr = 0;
|
||||||
|
EndPoint.LocalPort = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set the destination address and destination port.
|
||||||
|
//
|
||||||
|
NetCopyMem (&Ip, &Token->RemoteAddress, sizeof (EFI_IPv4_ADDRESS));
|
||||||
|
EndPoint.RemoteAddr = NTOHL (Ip);
|
||||||
|
|
||||||
|
if (Token->RemotePort == 0) {
|
||||||
|
EndPoint.RemotePort = DHCP_SERVER_PORT;
|
||||||
|
} else {
|
||||||
|
EndPoint.RemotePort = Token->RemotePort;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get the gateway.
|
||||||
|
//
|
||||||
|
SubnetMask = DhcpSb->Netmask;
|
||||||
|
Gateway = 0;
|
||||||
|
if (!IP4_NET_EQUAL (DhcpSb->ClientAddr, EndPoint.RemoteAddr, SubnetMask)) {
|
||||||
|
NetCopyMem (&Gateway, &Token->GatewayAddress, sizeof (EFI_IPv4_ADDRESS));
|
||||||
|
Gateway = NTOHL (Gateway);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Transmit the DHCP packet.
|
||||||
|
//
|
||||||
|
Status = UdpIoSendDatagram (Instance->UdpIo, Wrap, &EndPoint, Gateway, DhcpOnPacketSent, NULL);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
NetbufFree (Wrap);
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Start to receive the DHCP response.
|
||||||
|
//
|
||||||
|
Status = UdpIoRecvDatagram (Instance->UdpIo, PxeDhcpInput, Instance, 0);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ON_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ON_ERROR:
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status) && (Instance->UdpIo != NULL)) {
|
||||||
|
UdpIoCleanPort (Instance->UdpIo);
|
||||||
|
UdpIoFreePort (Instance->UdpIo);
|
||||||
|
Instance->UdpIo = NULL;
|
||||||
|
Instance->Token = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
NET_RESTORE_TPL (OldTpl);
|
||||||
|
|
||||||
|
if (!EFI_ERROR (Status) && (Token->CompletionEvent == NULL)) {
|
||||||
|
//
|
||||||
|
// Keep polling until timeout if no error happens and the CompletionEvent
|
||||||
|
// is NULL.
|
||||||
|
//
|
||||||
|
while (Instance->Timeout != 0) {
|
||||||
|
Instance->UdpIo->Udp->Poll (Instance->UdpIo->Udp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -910,3 +1260,4 @@ EFI_DHCP4_PROTOCOL mDhcp4ProtocolTemplate = {
|
||||||
EfiDhcp4TransmitReceive,
|
EfiDhcp4TransmitReceive,
|
||||||
EfiDhcp4Parse
|
EfiDhcp4Parse
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,9 @@ struct _DHCP_PROTOCOL {
|
||||||
EFI_EVENT RenewRebindEvent;
|
EFI_EVENT RenewRebindEvent;
|
||||||
|
|
||||||
EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN *Token;
|
EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN *Token;
|
||||||
|
UDP_IO_PORT *UdpIo; // The UDP IO used for TransmitReceive.
|
||||||
|
UINT32 Timeout;
|
||||||
|
NET_BUF_QUEUE ResponseQueue;
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -156,4 +159,9 @@ DhcpYieldControl (
|
||||||
IN DHCP_SERVICE *DhcpSb
|
IN DHCP_SERVICE *DhcpSb
|
||||||
);
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
PxeDhcpDone (
|
||||||
|
IN DHCP_PROTOCOL *Instance
|
||||||
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -52,8 +52,6 @@ DhcpInitRequest (
|
||||||
DhcpSb->DhcpState = Dhcp4Init;
|
DhcpSb->DhcpState = Dhcp4Init;
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
DhcpSb->WaitOffer = DHCP_WAIT_OFFER;
|
|
||||||
} else {
|
} else {
|
||||||
DhcpSetState (DhcpSb, Dhcp4Rebooting, FALSE);
|
DhcpSetState (DhcpSb, Dhcp4Rebooting, FALSE);
|
||||||
Status = DhcpSendMessage (DhcpSb, NULL, NULL, DHCP_MSG_REQUEST, NULL);
|
Status = DhcpSendMessage (DhcpSb, NULL, NULL, DHCP_MSG_REQUEST, NULL);
|
||||||
|
@ -225,7 +223,7 @@ DhcpSetState (
|
||||||
// This will clear the retry count. This is also why the rule
|
// This will clear the retry count. This is also why the rule
|
||||||
// first transit the state, then send packets.
|
// first transit the state, then send packets.
|
||||||
//
|
//
|
||||||
if (State == Dhcp4Init) {
|
if (State == Dhcp4Selecting) {
|
||||||
DhcpSb->MaxRetries = DhcpSb->ActiveConfig.DiscoverTryCount;
|
DhcpSb->MaxRetries = DhcpSb->ActiveConfig.DiscoverTryCount;
|
||||||
} else {
|
} else {
|
||||||
DhcpSb->MaxRetries = DhcpSb->ActiveConfig.RequestTryCount;
|
DhcpSb->MaxRetries = DhcpSb->ActiveConfig.RequestTryCount;
|
||||||
|
@ -262,7 +260,7 @@ DhcpSetTransmitTimer (
|
||||||
|
|
||||||
ASSERT (DhcpSb->MaxRetries > DhcpSb->CurRetry);
|
ASSERT (DhcpSb->MaxRetries > DhcpSb->CurRetry);
|
||||||
|
|
||||||
if (DhcpSb->DhcpState == Dhcp4Init) {
|
if (DhcpSb->DhcpState == Dhcp4Selecting) {
|
||||||
Times = DhcpSb->ActiveConfig.DiscoverTimeout;
|
Times = DhcpSb->ActiveConfig.DiscoverTimeout;
|
||||||
} else {
|
} else {
|
||||||
Times = DhcpSb->ActiveConfig.RequestTimeout;
|
Times = DhcpSb->ActiveConfig.RequestTimeout;
|
||||||
|
@ -273,8 +271,11 @@ DhcpSetTransmitTimer (
|
||||||
}
|
}
|
||||||
|
|
||||||
DhcpSb->PacketToLive = Times[DhcpSb->CurRetry];
|
DhcpSb->PacketToLive = Times[DhcpSb->CurRetry];
|
||||||
}
|
|
||||||
|
|
||||||
|
if (DhcpSb->DhcpState == Dhcp4Selecting) {
|
||||||
|
DhcpSb->WaitOffer = DhcpSb->PacketToLive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Compute the lease. If the server grants a permanent lease, just
|
Compute the lease. If the server grants a permanent lease, just
|
||||||
|
@ -519,6 +520,7 @@ DhcpChooseOffer (
|
||||||
{
|
{
|
||||||
EFI_DHCP4_PACKET *Selected;
|
EFI_DHCP4_PACKET *Selected;
|
||||||
EFI_DHCP4_PACKET *NewPacket;
|
EFI_DHCP4_PACKET *NewPacket;
|
||||||
|
EFI_DHCP4_PACKET *TempPacket;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
|
||||||
ASSERT (DhcpSb->LastOffer != NULL);
|
ASSERT (DhcpSb->LastOffer != NULL);
|
||||||
|
@ -542,12 +544,12 @@ DhcpChooseOffer (
|
||||||
|
|
||||||
Selected = DhcpSb->LastOffer;
|
Selected = DhcpSb->LastOffer;
|
||||||
|
|
||||||
if (NewPacket != NULL) {
|
if ((NewPacket != NULL) && !EFI_ERROR (DhcpValidateOptions (NewPacket, NULL))) {
|
||||||
if (EFI_ERROR (DhcpValidateOptions (NewPacket, NULL))) {
|
TempPacket = (EFI_DHCP4_PACKET *) NetAllocatePool (NewPacket->Size);
|
||||||
NetFreePool (NewPacket);
|
if (TempPacket != NULL) {
|
||||||
} else {
|
NetCopyMem (TempPacket, NewPacket, NewPacket->Size);
|
||||||
NetFreePool (Selected);
|
NetFreePool (Selected);
|
||||||
Selected = NewPacket;
|
Selected = TempPacket;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -650,10 +652,6 @@ DhcpHandleSelect (
|
||||||
//
|
//
|
||||||
Head = &Packet->Dhcp4.Header;
|
Head = &Packet->Dhcp4.Header;
|
||||||
|
|
||||||
if (!Ip4IsUnicast (EFI_NTOHL (Head->YourAddr), (Para == NULL ? 0 : Para->NetMask))) {
|
|
||||||
goto ON_EXIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!DHCP_IS_BOOTP (Para) &&
|
if (!DHCP_IS_BOOTP (Para) &&
|
||||||
((Para->DhcpType != DHCP_MSG_OFFER) || (Para->ServerId == 0))) {
|
((Para->DhcpType != DHCP_MSG_OFFER) || (Para->ServerId == 0))) {
|
||||||
goto ON_EXIT;
|
goto ON_EXIT;
|
||||||
|
@ -1495,12 +1493,32 @@ DhcpOnTimerTick (
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
DHCP_SERVICE *DhcpSb;
|
DHCP_SERVICE *DhcpSb;
|
||||||
|
DHCP_PROTOCOL *Instance;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
|
||||||
DhcpSb = (DHCP_SERVICE *) Context;
|
DhcpSb = (DHCP_SERVICE *) Context;
|
||||||
|
Instance = DhcpSb->ActiveChild;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check the retransmit timer first
|
// Check the time to wait offer
|
||||||
|
//
|
||||||
|
if ((DhcpSb->WaitOffer > 0) && (--DhcpSb->WaitOffer == 0)) {
|
||||||
|
//
|
||||||
|
// OK, offer collection finished, select a offer
|
||||||
|
//
|
||||||
|
ASSERT (DhcpSb->DhcpState == Dhcp4Selecting);
|
||||||
|
|
||||||
|
if (DhcpSb->LastOffer == NULL) {
|
||||||
|
goto END_SESSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EFI_ERROR (DhcpChooseOffer (DhcpSb))) {
|
||||||
|
goto END_SESSION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check the retransmit timer
|
||||||
//
|
//
|
||||||
if ((DhcpSb->PacketToLive > 0) && (--DhcpSb->PacketToLive == 0)) {
|
if ((DhcpSb->PacketToLive > 0) && (--DhcpSb->PacketToLive == 0)) {
|
||||||
|
|
||||||
|
@ -1544,21 +1562,6 @@ DhcpOnTimerTick (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((DhcpSb->WaitOffer > 0) && (--DhcpSb->WaitOffer == 0)) {
|
|
||||||
//
|
|
||||||
// OK, offer collection finished, select a offer
|
|
||||||
//
|
|
||||||
ASSERT (DhcpSb->DhcpState == Dhcp4Selecting);
|
|
||||||
|
|
||||||
if (DhcpSb->LastOffer == NULL) {
|
|
||||||
goto END_SESSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (EFI_ERROR (DhcpChooseOffer (DhcpSb))) {
|
|
||||||
goto END_SESSION;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// If an address has been acquired, check whether need to
|
// If an address has been acquired, check whether need to
|
||||||
// refresh or whether it has expired.
|
// refresh or whether it has expired.
|
||||||
|
@ -1622,6 +1625,16 @@ DhcpOnTimerTick (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
if ((Instance != NULL) && (Instance->Token != NULL)) {
|
||||||
|
Instance->Timeout--;
|
||||||
|
if (Instance->Timeout == 0) {
|
||||||
|
PxeDhcpDone (Instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
END_SESSION:
|
END_SESSION:
|
||||||
|
|
|
@ -112,4 +112,12 @@ DhcpCleanLease (
|
||||||
IN DHCP_SERVICE *DhcpSb
|
IN DHCP_SERVICE *DhcpSb
|
||||||
);
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
DhcpOnPacketSent (
|
||||||
|
NET_BUF *Packet,
|
||||||
|
UDP_POINTS *Points,
|
||||||
|
EFI_STATUS IoStatus,
|
||||||
|
VOID *Context
|
||||||
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -343,7 +343,8 @@ Returns:
|
||||||
//
|
//
|
||||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||||
&mDpcHandle,
|
&mDpcHandle,
|
||||||
&gEfiDpcProtocolGuid, &mDpc,
|
&gEfiDpcProtocolGuid,
|
||||||
|
&mDpc,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
|
@ -512,6 +512,7 @@ Ip4DriverBindingStop (
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_TPL OldTpl;
|
EFI_TPL OldTpl;
|
||||||
INTN State;
|
INTN State;
|
||||||
|
BOOLEAN IsArp;
|
||||||
|
|
||||||
//
|
//
|
||||||
// IP4 driver opens the MNP child, ARP children or the IP4_CONFIG protocol
|
// IP4 driver opens the MNP child, ARP children or the IP4_CONFIG protocol
|
||||||
|
@ -549,7 +550,7 @@ Ip4DriverBindingStop (
|
||||||
);
|
);
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return EFI_SUCCESS;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
IpSb = IP4_SERVICE_FROM_PROTOCOL (ServiceBinding);
|
IpSb = IP4_SERVICE_FROM_PROTOCOL (ServiceBinding);
|
||||||
|
@ -594,14 +595,16 @@ Ip4DriverBindingStop (
|
||||||
// service binding is installed on the NIC handle. So, need to open
|
// service binding is installed on the NIC handle. So, need to open
|
||||||
// the protocol info to find the NIC handle.
|
// the protocol info to find the NIC handle.
|
||||||
//
|
//
|
||||||
|
IsArp = FALSE;
|
||||||
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
|
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
|
||||||
|
|
||||||
if (NicHandle == NULL) {
|
if (NicHandle == NULL) {
|
||||||
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiArpProtocolGuid);
|
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiArpProtocolGuid);
|
||||||
|
IsArp = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NicHandle == NULL) {
|
if (NicHandle == NULL) {
|
||||||
return EFI_SUCCESS;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -629,32 +632,23 @@ Ip4DriverBindingStop (
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsArp) {
|
||||||
|
while (!NetListIsEmpty (&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->InDestory = TRUE;
|
IpSb->InDestory = TRUE;
|
||||||
|
|
||||||
State = IpSb->State;
|
State = IpSb->State;
|
||||||
IpSb->State = IP4_SERVICE_DESTORY;
|
IpSb->State = IP4_SERVICE_DESTORY;
|
||||||
|
|
||||||
//
|
|
||||||
// Destory all the children first. If not all children are destoried,
|
|
||||||
// the IP driver can operate correctly, so restore it state. Don't
|
|
||||||
// use NET_LIST_FOR_EACH_SAFE here, because it will cache the next
|
|
||||||
// pointer, which may point to the child that has already been destoried.
|
|
||||||
// For example, if there are two child in the list, the first is UDP
|
|
||||||
// listen child, the send is the MTFTP's child. When Udp child is
|
|
||||||
// destoried, it will destory the MTFTP's child. Then Next point to
|
|
||||||
// a invalid child.
|
|
||||||
//
|
|
||||||
while (!NetListIsEmpty (&IpSb->Children)) {
|
|
||||||
IpInstance = NET_LIST_HEAD (&IpSb->Children, IP4_PROTOCOL, Link);
|
|
||||||
Ip4ServiceBindingDestroyChild (ServiceBinding, IpInstance->Handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IpSb->NumChildren != 0) {
|
|
||||||
IpSb->State = State;
|
|
||||||
Status = EFI_DEVICE_ERROR;
|
|
||||||
goto ON_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Clear the variable data.
|
// Clear the variable data.
|
||||||
//
|
//
|
||||||
|
@ -666,25 +660,60 @@ Ip4DriverBindingStop (
|
||||||
Status = Ip4CleanService (IpSb);
|
Status = Ip4CleanService (IpSb);
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
IpSb->State = State;
|
||||||
goto ON_ERROR;
|
goto ON_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = gBS->UninstallProtocolInterface (
|
gBS->UninstallProtocolInterface (
|
||||||
NicHandle,
|
NicHandle,
|
||||||
&gEfiIp4ServiceBindingProtocolGuid,
|
&gEfiIp4ServiceBindingProtocolGuid,
|
||||||
ServiceBinding
|
ServiceBinding
|
||||||
);
|
);
|
||||||
|
|
||||||
|
NetFreePool (IpSb);
|
||||||
|
} else if (NumberOfChildren == 0) {
|
||||||
|
IpSb->InDestory = TRUE;
|
||||||
|
|
||||||
|
State = IpSb->State;
|
||||||
|
IpSb->State = IP4_SERVICE_DESTORY;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clear the variable data.
|
||||||
|
//
|
||||||
|
Ip4ClearVariableData (IpSb);
|
||||||
|
|
||||||
|
//
|
||||||
|
// OK, clean other resources then uninstall the service binding protocol.
|
||||||
|
//
|
||||||
|
Status = Ip4CleanService (IpSb);
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
IpSb->State = State;
|
||||||
goto ON_ERROR;
|
goto ON_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
NET_RESTORE_TPL (OldTpl);
|
gBS->UninstallProtocolInterface (
|
||||||
|
NicHandle,
|
||||||
|
&gEfiIp4ServiceBindingProtocolGuid,
|
||||||
|
ServiceBinding
|
||||||
|
);
|
||||||
|
|
||||||
NetFreePool (IpSb);
|
NetFreePool (IpSb);
|
||||||
return EFI_SUCCESS;
|
} else {
|
||||||
|
|
||||||
|
while (!NetListIsEmpty (&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:
|
ON_ERROR:
|
||||||
IpSb->InDestory = FALSE;
|
|
||||||
NET_RESTORE_TPL (OldTpl);
|
NET_RESTORE_TPL (OldTpl);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -681,7 +681,6 @@ Ip4CancelReceive (
|
||||||
|
|
||||||
Interface->RecvRequest = NULL;
|
Interface->RecvRequest = NULL;
|
||||||
Interface->Mnp->Cancel (Interface->Mnp, &Token->MnpToken);
|
Interface->Mnp->Cancel (Interface->Mnp, &Token->MnpToken);
|
||||||
Ip4FreeFrameRxToken (Token);
|
|
||||||
|
|
||||||
NET_RESTORE_TPL (OldTpl);
|
NET_RESTORE_TPL (OldTpl);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/** @file
|
/** @file
|
||||||
|
|
||||||
Copyright (c) 2005 - 2006, Intel Corporation
|
Copyright (c) 2005 - 2007, Intel Corporation
|
||||||
All rights reserved. This program and the accompanying materials
|
All rights reserved. This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/** @file
|
/** @file
|
||||||
|
|
||||||
Copyright (c) 2005 - 2006, Intel Corporation
|
Copyright (c) 2005 - 2007, Intel Corporation
|
||||||
All rights reserved. This program and the accompanying materials
|
All rights reserved. This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
|
|
@ -219,11 +219,39 @@ MnpDriverBindingStop (
|
||||||
("MnpDriverBindingStop: Locate MNP Service Binding Protocol failed, %r.\n",
|
("MnpDriverBindingStop: Locate MNP Service Binding Protocol failed, %r.\n",
|
||||||
Status)
|
Status)
|
||||||
);
|
);
|
||||||
goto EXIT;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (ServiceBinding);
|
MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (ServiceBinding);
|
||||||
|
|
||||||
|
if (NumberOfChildren == 0) {
|
||||||
|
//
|
||||||
|
// Uninstall the MNP Service Binding Protocol.
|
||||||
|
//
|
||||||
|
gBS->UninstallMultipleProtocolInterfaces (
|
||||||
|
ControllerHandle,
|
||||||
|
&gEfiManagedNetworkServiceBindingProtocolGuid,
|
||||||
|
ServiceBinding,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Close the openned Snp protocol.
|
||||||
|
//
|
||||||
|
gBS->CloseProtocol (
|
||||||
|
ControllerHandle,
|
||||||
|
&gEfiSimpleNetworkProtocolGuid,
|
||||||
|
This->DriverBindingHandle,
|
||||||
|
ControllerHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Flush the Mnp service data.
|
||||||
|
//
|
||||||
|
MnpFlushServiceData (MnpServiceData);
|
||||||
|
|
||||||
|
NetFreePool (MnpServiceData);
|
||||||
|
} else {
|
||||||
while (!NetListIsEmpty (&MnpServiceData->ChildrenList)) {
|
while (!NetListIsEmpty (&MnpServiceData->ChildrenList)) {
|
||||||
//
|
//
|
||||||
// Don't use NetListRemoveHead here, the remove opreration will be done
|
// Don't use NetListRemoveHead here, the remove opreration will be done
|
||||||
|
@ -237,46 +265,8 @@ MnpDriverBindingStop (
|
||||||
|
|
||||||
ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
|
ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Uninstall the MNP Service Binding Protocol.
|
|
||||||
//
|
|
||||||
Status = gBS->UninstallMultipleProtocolInterfaces (
|
|
||||||
ControllerHandle,
|
|
||||||
&gEfiManagedNetworkServiceBindingProtocolGuid,
|
|
||||||
ServiceBinding,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
|
|
||||||
MNP_DEBUG_ERROR (("MnpDriverBindingStop: Uninstall MNP Service Binding Protocol failed, %r.\n"));
|
|
||||||
goto EXIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Close the openned Snp protocol.
|
|
||||||
//
|
|
||||||
Status = gBS->CloseProtocol (
|
|
||||||
ControllerHandle,
|
|
||||||
&gEfiSimpleNetworkProtocolGuid,
|
|
||||||
This->DriverBindingHandle,
|
|
||||||
ControllerHandle
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
|
|
||||||
MNP_DEBUG_ERROR (("MnpDriverBindingStop: Close SNP Protocol failed, %r.\n", Status));
|
|
||||||
goto EXIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Flush the Mnp service data.
|
|
||||||
//
|
|
||||||
MnpFlushServiceData (MnpServiceData);
|
|
||||||
|
|
||||||
NetFreePool (MnpServiceData);
|
|
||||||
|
|
||||||
EXIT:
|
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -348,7 +348,7 @@ Mtftp4DriverBindingStop (
|
||||||
NicHandle = NetLibGetNicHandle (Controller, &gEfiUdp4ProtocolGuid);
|
NicHandle = NetLibGetNicHandle (Controller, &gEfiUdp4ProtocolGuid);
|
||||||
|
|
||||||
if (NicHandle == NULL) {
|
if (NicHandle == NULL) {
|
||||||
return EFI_SUCCESS;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = gBS->OpenProtocol (
|
Status = gBS->OpenProtocol (
|
||||||
|
@ -371,8 +371,22 @@ Mtftp4DriverBindingStop (
|
||||||
}
|
}
|
||||||
|
|
||||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||||
|
|
||||||
|
if (NumberOfChildren == 0) {
|
||||||
|
|
||||||
MtftpSb->InDestory = TRUE;
|
MtftpSb->InDestory = TRUE;
|
||||||
|
|
||||||
|
gBS->UninstallProtocolInterface (
|
||||||
|
NicHandle,
|
||||||
|
&gEfiMtftp4ServiceBindingProtocolGuid,
|
||||||
|
ServiceBinding
|
||||||
|
);
|
||||||
|
|
||||||
|
Mtftp4CleanService (MtftpSb);
|
||||||
|
|
||||||
|
NetFreePool (MtftpSb);
|
||||||
|
} else {
|
||||||
|
|
||||||
while (!NetListIsEmpty (&MtftpSb->Children)) {
|
while (!NetListIsEmpty (&MtftpSb->Children)) {
|
||||||
Instance = NET_LIST_HEAD (&MtftpSb->Children, MTFTP4_PROTOCOL, Link);
|
Instance = NET_LIST_HEAD (&MtftpSb->Children, MTFTP4_PROTOCOL, Link);
|
||||||
Mtftp4ServiceBindingDestroyChild (ServiceBinding, Instance->Handle);
|
Mtftp4ServiceBindingDestroyChild (ServiceBinding, Instance->Handle);
|
||||||
|
@ -380,28 +394,9 @@ Mtftp4DriverBindingStop (
|
||||||
|
|
||||||
if (MtftpSb->ChildrenNum != 0) {
|
if (MtftpSb->ChildrenNum != 0) {
|
||||||
Status = EFI_DEVICE_ERROR;
|
Status = EFI_DEVICE_ERROR;
|
||||||
goto ON_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = gBS->UninstallProtocolInterface (
|
|
||||||
NicHandle,
|
|
||||||
&gEfiMtftp4ServiceBindingProtocolGuid,
|
|
||||||
ServiceBinding
|
|
||||||
);
|
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
goto ON_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Mtftp4CleanService (MtftpSb);
|
|
||||||
NetFreePool (MtftpSb);
|
|
||||||
|
|
||||||
NET_RESTORE_TPL (OldTpl);
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
|
|
||||||
ON_ERROR:
|
|
||||||
MtftpSb->InDestory = FALSE;
|
|
||||||
|
|
||||||
NET_RESTORE_TPL (OldTpl);
|
NET_RESTORE_TPL (OldTpl);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -585,6 +585,16 @@ Mtftp4ConfigUnicastPort (
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!Config->UseDefaultSetting && !EFI_IP4_EQUAL (&mZeroIp4Addr, &Config->GatewayIp)) {
|
||||||
|
//
|
||||||
|
// The station IP address is manually configured and the Gateway IP is not 0.
|
||||||
|
// Add the default route for this UDP instance.
|
||||||
|
//
|
||||||
|
Status = UdpIo->Udp->Routes (UdpIo->Udp, FALSE, &mZeroIp4Addr, &mZeroIp4Addr, &Config->GatewayIp);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
UdpIo->Udp->Configure (UdpIo->Udp, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -412,6 +412,18 @@ Mtftp4RrqConfigMcastPort (
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!Config->UseDefaultSetting && !EFI_IP4_EQUAL (&mZeroIp4Addr, &Config->GatewayIp)) {
|
||||||
|
//
|
||||||
|
// The station IP address is manually configured and the Gateway IP is not 0.
|
||||||
|
// Add the default route for this UDP instance.
|
||||||
|
//
|
||||||
|
Status = McastIo->Udp->Routes (McastIo->Udp, FALSE, &mZeroIp4Addr, &mZeroIp4Addr, &Config->GatewayIp);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
McastIo->Udp->Configure (McastIo->Udp, NULL);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// join the multicast group
|
// join the multicast group
|
||||||
//
|
//
|
||||||
|
|
|
@ -467,7 +467,7 @@ Mtftp4SendPacket (
|
||||||
Instance->UnicastPort,
|
Instance->UnicastPort,
|
||||||
Packet,
|
Packet,
|
||||||
&UdpPoint,
|
&UdpPoint,
|
||||||
Instance->Gateway,
|
0,
|
||||||
Mtftp4OnPacketSent,
|
Mtftp4OnPacketSent,
|
||||||
Instance
|
Instance
|
||||||
);
|
);
|
||||||
|
@ -524,7 +524,7 @@ Mtftp4Retransmit (
|
||||||
Instance->UnicastPort,
|
Instance->UnicastPort,
|
||||||
Instance->LastPacket,
|
Instance->LastPacket,
|
||||||
&UdpPoint,
|
&UdpPoint,
|
||||||
Instance->Gateway,
|
0,
|
||||||
Mtftp4OnPacketSent,
|
Mtftp4OnPacketSent,
|
||||||
Instance
|
Instance
|
||||||
);
|
);
|
||||||
|
|
|
@ -584,6 +584,7 @@ SockCreate (
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetListInit (&Sock->Link);
|
||||||
NetListInit (&Sock->ConnectionList);
|
NetListInit (&Sock->ConnectionList);
|
||||||
NetListInit (&Sock->ListenTokenList);
|
NetListInit (&Sock->ListenTokenList);
|
||||||
NetListInit (&Sock->RcvTokenList);
|
NetListInit (&Sock->RcvTokenList);
|
||||||
|
|
|
@ -330,6 +330,7 @@ struct _SOCKET {
|
||||||
EFI_HANDLE DriverBinding; // socket't driver binding protocol
|
EFI_HANDLE DriverBinding; // socket't driver binding protocol
|
||||||
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
|
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
|
||||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||||
|
NET_LIST_ENTRY Link;
|
||||||
SOCK_CONFIGURE_STATE ConfigureState;
|
SOCK_CONFIGURE_STATE ConfigureState;
|
||||||
SOCK_TYPE Type;
|
SOCK_TYPE Type;
|
||||||
SOCK_STATE State;
|
SOCK_STATE State;
|
||||||
|
|
|
@ -297,7 +297,7 @@ Tcp4DriverBindingStart (
|
||||||
" resource to create an Ip Io!\n"));
|
" resource to create an Ip Io!\n"));
|
||||||
|
|
||||||
Status = EFI_OUT_OF_RESOURCES;
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
goto ReleaseServiceData;
|
goto ON_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -312,7 +312,7 @@ Tcp4DriverBindingStart (
|
||||||
Status = IpIoOpen (TcpServiceData->IpIo, &OpenData);
|
Status = IpIoOpen (TcpServiceData->IpIo, &OpenData);
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto ReleaseServiceData;
|
goto ON_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -324,7 +324,7 @@ Tcp4DriverBindingStart (
|
||||||
TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Create TcpTimer"
|
TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Create TcpTimer"
|
||||||
" Event failed with %r\n", Status));
|
" Event failed with %r\n", Status));
|
||||||
|
|
||||||
goto ReleaseIpIo;
|
goto ON_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -344,7 +344,8 @@ Tcp4DriverBindingStart (
|
||||||
TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Install Tcp4 Service Binding"
|
TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Install Tcp4 Service Binding"
|
||||||
" Protocol failed for %r\n", Status));
|
" Protocol failed for %r\n", Status));
|
||||||
|
|
||||||
goto ReleaseTimer;
|
Tcp4DestroyTimer ();
|
||||||
|
goto ON_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -354,19 +355,17 @@ Tcp4DriverBindingStart (
|
||||||
TcpServiceData->Signature = TCP4_DRIVER_SIGNATURE;
|
TcpServiceData->Signature = TCP4_DRIVER_SIGNATURE;
|
||||||
TcpServiceData->DriverBindingHandle = This->DriverBindingHandle;
|
TcpServiceData->DriverBindingHandle = This->DriverBindingHandle;
|
||||||
|
|
||||||
|
NetListInit (&TcpServiceData->SocketList);
|
||||||
|
|
||||||
TcpSetVariableData (TcpServiceData);
|
TcpSetVariableData (TcpServiceData);
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
ReleaseTimer:
|
ON_ERROR:
|
||||||
|
|
||||||
Tcp4DestroyTimer ();
|
|
||||||
|
|
||||||
ReleaseIpIo:
|
|
||||||
|
|
||||||
|
if (TcpServiceData->IpIo != NULL) {
|
||||||
IpIoDestroy (TcpServiceData->IpIo);
|
IpIoDestroy (TcpServiceData->IpIo);
|
||||||
|
}
|
||||||
ReleaseServiceData:
|
|
||||||
|
|
||||||
NetFreePool (TcpServiceData);
|
NetFreePool (TcpServiceData);
|
||||||
|
|
||||||
|
@ -398,19 +397,15 @@ Tcp4DriverBindingStop (
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_HANDLE NicHandle;
|
EFI_HANDLE NicHandle;
|
||||||
EFI_SERVICE_BINDING_PROTOCOL *Tcp4ServiceBinding;
|
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
|
||||||
TCP4_SERVICE_DATA *TcpServiceData;
|
TCP4_SERVICE_DATA *TcpServiceData;
|
||||||
TCP_CB *TcpPcb;
|
|
||||||
SOCKET *Sock;
|
SOCKET *Sock;
|
||||||
TCP4_PROTO_DATA *TcpProto;
|
|
||||||
NET_LIST_ENTRY *Entry;
|
|
||||||
NET_LIST_ENTRY *NextEntry;
|
|
||||||
|
|
||||||
// Find the NicHandle where Tcp4 ServiceBinding Protocol is installed.
|
// Find the NicHandle where Tcp4 ServiceBinding Protocol is installed.
|
||||||
//
|
//
|
||||||
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);
|
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);
|
||||||
if (NicHandle == NULL) {
|
if (NicHandle == NULL) {
|
||||||
return EFI_SUCCESS;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -419,7 +414,7 @@ Tcp4DriverBindingStop (
|
||||||
Status = gBS->OpenProtocol (
|
Status = gBS->OpenProtocol (
|
||||||
NicHandle,
|
NicHandle,
|
||||||
&gEfiTcp4ServiceBindingProtocolGuid,
|
&gEfiTcp4ServiceBindingProtocolGuid,
|
||||||
(VOID **) &Tcp4ServiceBinding,
|
(VOID **) &ServiceBinding,
|
||||||
This->DriverBindingHandle,
|
This->DriverBindingHandle,
|
||||||
ControllerHandle,
|
ControllerHandle,
|
||||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||||
|
@ -429,75 +424,26 @@ Tcp4DriverBindingStop (
|
||||||
TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Locate Tcp4 Service "
|
TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Locate Tcp4 Service "
|
||||||
" Binding Protocol failed with %r\n", Status));
|
" Binding Protocol failed with %r\n", Status));
|
||||||
|
|
||||||
return Status;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
TcpServiceData = TCP4_FROM_THIS (Tcp4ServiceBinding);
|
TcpServiceData = TCP4_FROM_THIS (ServiceBinding);
|
||||||
|
|
||||||
//
|
|
||||||
// Kill TCP driver
|
|
||||||
//
|
|
||||||
NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &mTcpRunQue) {
|
|
||||||
TcpPcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Try to destroy this child
|
|
||||||
//
|
|
||||||
Sock = TcpPcb->Sk;
|
|
||||||
TcpProto = (TCP4_PROTO_DATA *) Sock->ProtoReserved;
|
|
||||||
|
|
||||||
if (TcpProto->TcpService == TcpServiceData) {
|
|
||||||
Status = SockDestroyChild (Sock);
|
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
|
|
||||||
TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Destroy Tcp "
|
|
||||||
"instance failed with %r\n", Status));
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &mTcpListenQue) {
|
|
||||||
TcpPcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Try to destroy this child
|
|
||||||
//
|
|
||||||
Sock = TcpPcb->Sk;
|
|
||||||
TcpProto = (TCP4_PROTO_DATA *) Sock->ProtoReserved;
|
|
||||||
|
|
||||||
if (TcpProto->TcpService == TcpServiceData) {
|
|
||||||
Status = SockDestroyChild (TcpPcb->Sk);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
|
|
||||||
TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Destroy Tcp "
|
|
||||||
"instance failed with %r\n", Status));
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (NumberOfChildren == 0) {
|
||||||
//
|
//
|
||||||
// Uninstall TCP servicebinding protocol
|
// Uninstall TCP servicebinding protocol
|
||||||
//
|
//
|
||||||
Status = gBS->UninstallMultipleProtocolInterfaces (
|
gBS->UninstallMultipleProtocolInterfaces (
|
||||||
NicHandle,
|
NicHandle,
|
||||||
&gEfiTcp4ServiceBindingProtocolGuid,
|
&gEfiTcp4ServiceBindingProtocolGuid,
|
||||||
Tcp4ServiceBinding,
|
ServiceBinding,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
|
|
||||||
TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Uninstall TCP service "
|
|
||||||
"binding protocol failed with %r\n", Status));
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Destroy the IpIO consumed by TCP driver
|
// Destroy the IpIO consumed by TCP driver
|
||||||
//
|
//
|
||||||
Status = IpIoDestroy (TcpServiceData->IpIo);
|
IpIoDestroy (TcpServiceData->IpIo);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Destroy the heartbeat timer.
|
// Destroy the heartbeat timer.
|
||||||
|
@ -513,11 +459,18 @@ Tcp4DriverBindingStop (
|
||||||
// Release the TCP service data
|
// Release the TCP service data
|
||||||
//
|
//
|
||||||
NetFreePool (TcpServiceData);
|
NetFreePool (TcpServiceData);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
while (!NetListIsEmpty (&TcpServiceData->SocketList)) {
|
||||||
|
Sock = NET_LIST_HEAD (&TcpServiceData->SocketList, SOCKET, Link);
|
||||||
|
|
||||||
|
ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Creates a child handle with a set of TCP4 services.
|
Creates a child handle with a set of TCP4 services.
|
||||||
|
|
||||||
|
@ -608,9 +561,12 @@ Tcp4ServiceBindingCreateChild (
|
||||||
Sock->SockHandle
|
Sock->SockHandle
|
||||||
);
|
);
|
||||||
SockDestroyChild (Sock);
|
SockDestroyChild (Sock);
|
||||||
|
} else {
|
||||||
|
NetListInsertTail (&TcpServiceData->SocketList, &Sock->Link);
|
||||||
}
|
}
|
||||||
|
|
||||||
ON_EXIT:
|
ON_EXIT:
|
||||||
|
|
||||||
NET_RESTORE_TPL (OldTpl);
|
NET_RESTORE_TPL (OldTpl);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -672,7 +628,9 @@ Tcp4ServiceBindingDestroyChild (
|
||||||
TcpProtoData = (TCP4_PROTO_DATA *) Sock->ProtoReserved;
|
TcpProtoData = (TCP4_PROTO_DATA *) Sock->ProtoReserved;
|
||||||
TcpServiceData = TcpProtoData->TcpService;
|
TcpServiceData = TcpProtoData->TcpService;
|
||||||
|
|
||||||
Status = SockDestroyChild (Sock);
|
NetListRemoveEntry (&Sock->Link);
|
||||||
|
|
||||||
|
SockDestroyChild (Sock);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Close the device path protocol
|
// Close the device path protocol
|
||||||
|
|
|
@ -41,6 +41,7 @@ typedef struct _TCP4_SERVICE_DATA {
|
||||||
EFI_SERVICE_BINDING_PROTOCOL Tcp4ServiceBinding;
|
EFI_SERVICE_BINDING_PROTOCOL Tcp4ServiceBinding;
|
||||||
EFI_HANDLE DriverBindingHandle;
|
EFI_HANDLE DriverBindingHandle;
|
||||||
CHAR16 *MacString;
|
CHAR16 *MacString;
|
||||||
|
NET_LIST_ENTRY SocketList;
|
||||||
} TCP4_SERVICE_DATA;
|
} TCP4_SERVICE_DATA;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -426,6 +426,7 @@ TcpCloneTcb (
|
||||||
{
|
{
|
||||||
TCP_CB *Clone;
|
TCP_CB *Clone;
|
||||||
TCP4_SERVICE_DATA *TcpService;
|
TCP4_SERVICE_DATA *TcpService;
|
||||||
|
EFI_IP4_PROTOCOL *Ip4;
|
||||||
|
|
||||||
Clone = NetAllocatePool (sizeof (TCP_CB));
|
Clone = NetAllocatePool (sizeof (TCP_CB));
|
||||||
|
|
||||||
|
@ -454,10 +455,13 @@ TcpCloneTcb (
|
||||||
|
|
||||||
((TCP4_PROTO_DATA *) (Clone->Sk->ProtoReserved))->TcpPcb = Clone;
|
((TCP4_PROTO_DATA *) (Clone->Sk->ProtoReserved))->TcpPcb = Clone;
|
||||||
|
|
||||||
|
TcpService = ((TCP4_PROTO_DATA *) (Clone->Sk->ProtoReserved))->TcpService;
|
||||||
|
|
||||||
|
NetListInsertTail (&TcpService->SocketList, &Clone->Sk->Link);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Open the device path on the handle where service binding resides on.
|
// Open the device path on the handle where service binding resides on.
|
||||||
//
|
//
|
||||||
TcpService = ((TCP4_PROTO_DATA *) (Clone->Sk->ProtoReserved))->TcpService;
|
|
||||||
gBS->OpenProtocol (
|
gBS->OpenProtocol (
|
||||||
TcpService->ControllerHandle,
|
TcpService->ControllerHandle,
|
||||||
&gEfiDevicePathProtocolGuid,
|
&gEfiDevicePathProtocolGuid,
|
||||||
|
@ -467,6 +471,18 @@ TcpCloneTcb (
|
||||||
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
|
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Open the ip protocol by child controller.
|
||||||
|
//
|
||||||
|
gBS->OpenProtocol (
|
||||||
|
TcpService->IpIo->ChildHandle,
|
||||||
|
&gEfiIp4ProtocolGuid,
|
||||||
|
(VOID **) &Ip4,
|
||||||
|
TcpService->DriverBindingHandle,
|
||||||
|
Clone->Sk->SockHandle,
|
||||||
|
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
|
||||||
|
);
|
||||||
|
|
||||||
return Clone;
|
return Clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,8 @@ Udp4DriverBindingStart (
|
||||||
|
|
||||||
Status = Udp4CreateService (Udp4Service, This->DriverBindingHandle, ControllerHandle);
|
Status = Udp4CreateService (Udp4Service, This->DriverBindingHandle, ControllerHandle);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto FREE_SERVICE;
|
NetFreePool (Udp4Service);
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -136,20 +137,11 @@ Udp4DriverBindingStart (
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto CLEAN_SERVICE;
|
|
||||||
}
|
|
||||||
|
|
||||||
Udp4SetVariableData (Udp4Service);
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
|
|
||||||
CLEAN_SERVICE:
|
|
||||||
|
|
||||||
Udp4CleanService (Udp4Service);
|
Udp4CleanService (Udp4Service);
|
||||||
|
|
||||||
FREE_SERVICE:
|
|
||||||
|
|
||||||
NetFreePool (Udp4Service);
|
NetFreePool (Udp4Service);
|
||||||
|
} else {
|
||||||
|
Udp4SetVariableData (Udp4Service);
|
||||||
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -188,7 +180,7 @@ Udp4DriverBindingStop (
|
||||||
//
|
//
|
||||||
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);
|
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);
|
||||||
if (NicHandle == NULL) {
|
if (NicHandle == NULL) {
|
||||||
return EFI_SUCCESS;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -208,35 +200,30 @@ Udp4DriverBindingStop (
|
||||||
|
|
||||||
Udp4Service = UDP4_SERVICE_DATA_FROM_THIS (ServiceBinding);
|
Udp4Service = UDP4_SERVICE_DATA_FROM_THIS (ServiceBinding);
|
||||||
|
|
||||||
//
|
if (NumberOfChildren == 0) {
|
||||||
// Uninstall the UDP4 ServiceBinding Protocol.
|
|
||||||
//
|
gBS->UninstallMultipleProtocolInterfaces (
|
||||||
Status = gBS->UninstallMultipleProtocolInterfaces (
|
|
||||||
NicHandle,
|
NicHandle,
|
||||||
&gEfiUdp4ServiceBindingProtocolGuid,
|
&gEfiUdp4ServiceBindingProtocolGuid,
|
||||||
&Udp4Service->ServiceBinding,
|
&Udp4Service->ServiceBinding,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return EFI_DEVICE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!NetListIsEmpty (&Udp4Service->ChildrenList)) {
|
|
||||||
//
|
|
||||||
// Destroy all instances.
|
|
||||||
//
|
|
||||||
Instance = NET_LIST_HEAD (&Udp4Service->ChildrenList, UDP4_INSTANCE_DATA, Link);
|
|
||||||
|
|
||||||
ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
Udp4ClearVariableData (Udp4Service);
|
Udp4ClearVariableData (Udp4Service);
|
||||||
|
|
||||||
Udp4CleanService (Udp4Service);
|
Udp4CleanService (Udp4Service);
|
||||||
|
|
||||||
NetFreePool (Udp4Service);
|
NetFreePool (Udp4Service);
|
||||||
|
} else {
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
while (!NetListIsEmpty (&Udp4Service->ChildrenList)) {
|
||||||
|
Instance = NET_LIST_HEAD (&Udp4Service->ChildrenList, UDP4_INSTANCE_DATA, Link);
|
||||||
|
|
||||||
|
ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -277,7 +264,7 @@ Udp4ServiceBindingCreateChild (
|
||||||
//
|
//
|
||||||
// Allocate the instance private data structure.
|
// Allocate the instance private data structure.
|
||||||
//
|
//
|
||||||
Instance = NetAllocatePool (sizeof (UDP4_INSTANCE_DATA));
|
Instance = NetAllocateZeroPool (sizeof (UDP4_INSTANCE_DATA));
|
||||||
if (Instance == NULL) {
|
if (Instance == NULL) {
|
||||||
return EFI_OUT_OF_RESOURCES;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
}
|
}
|
||||||
|
@ -290,7 +277,7 @@ Udp4ServiceBindingCreateChild (
|
||||||
Instance->IpInfo = IpIoAddIp (Udp4Service->IpIo);
|
Instance->IpInfo = IpIoAddIp (Udp4Service->IpIo);
|
||||||
if (Instance->IpInfo == NULL) {
|
if (Instance->IpInfo == NULL) {
|
||||||
Status = EFI_OUT_OF_RESOURCES;
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
goto FREE_INSTANCE;
|
goto ON_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -303,7 +290,7 @@ Udp4ServiceBindingCreateChild (
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto REMOVE_IPINFO;
|
goto ON_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
Instance->ChildHandle = *ChildHandle;
|
Instance->ChildHandle = *ChildHandle;
|
||||||
|
@ -320,7 +307,7 @@ Udp4ServiceBindingCreateChild (
|
||||||
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
|
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto UNINSTALL_PROTOCOL;
|
goto ON_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||||
|
@ -333,22 +320,22 @@ Udp4ServiceBindingCreateChild (
|
||||||
|
|
||||||
NET_RESTORE_TPL (OldTpl);
|
NET_RESTORE_TPL (OldTpl);
|
||||||
|
|
||||||
return Status;
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
UNINSTALL_PROTOCOL:
|
ON_ERROR:
|
||||||
|
|
||||||
|
if (Instance->ChildHandle != NULL) {
|
||||||
gBS->UninstallMultipleProtocolInterfaces (
|
gBS->UninstallMultipleProtocolInterfaces (
|
||||||
Instance->ChildHandle,
|
Instance->ChildHandle,
|
||||||
&gEfiUdp4ProtocolGuid,
|
&gEfiUdp4ProtocolGuid,
|
||||||
&Instance->Udp4Proto,
|
&Instance->Udp4Proto,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
REMOVE_IPINFO:
|
if (Instance->IpInfo != NULL) {
|
||||||
|
|
||||||
IpIoRemoveIp (Udp4Service->IpIo, Instance->IpInfo);
|
IpIoRemoveIp (Udp4Service->IpIo, Instance->IpInfo);
|
||||||
|
}
|
||||||
FREE_INSTANCE:
|
|
||||||
|
|
||||||
Udp4CleanInstance (Instance);
|
Udp4CleanInstance (Instance);
|
||||||
|
|
||||||
|
|
|
@ -153,6 +153,8 @@ Udp4CreateService (
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
IP_IO_OPEN_DATA OpenData;
|
IP_IO_OPEN_DATA OpenData;
|
||||||
|
|
||||||
|
NetZeroMem (Udp4Service, sizeof (UDP4_SERVICE_DATA));
|
||||||
|
|
||||||
Udp4Service->Signature = UDP4_SERVICE_DATA_SIGNATURE;
|
Udp4Service->Signature = UDP4_SERVICE_DATA_SIGNATURE;
|
||||||
Udp4Service->ServiceBinding = mUdp4ServiceBinding;
|
Udp4Service->ServiceBinding = mUdp4ServiceBinding;
|
||||||
Udp4Service->ImageHandle = ImageHandle;
|
Udp4Service->ImageHandle = ImageHandle;
|
||||||
|
@ -184,7 +186,7 @@ Udp4CreateService (
|
||||||
//
|
//
|
||||||
Status = IpIoOpen (Udp4Service->IpIo, &OpenData);
|
Status = IpIoOpen (Udp4Service->IpIo, &OpenData);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto RELEASE_IPIO;
|
goto ON_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -198,7 +200,7 @@ Udp4CreateService (
|
||||||
&Udp4Service->TimeoutEvent
|
&Udp4Service->TimeoutEvent
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto RELEASE_IPIO;
|
goto ON_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -210,18 +212,16 @@ Udp4CreateService (
|
||||||
UDP4_TIMEOUT_INTERVAL
|
UDP4_TIMEOUT_INTERVAL
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto RELEASE_ALL;
|
goto ON_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
Udp4Service->MacString = NULL;
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
RELEASE_ALL:
|
ON_ERROR:
|
||||||
|
|
||||||
|
if (Udp4Service->TimeoutEvent != NULL) {
|
||||||
gBS->CloseEvent (Udp4Service->TimeoutEvent);
|
gBS->CloseEvent (Udp4Service->TimeoutEvent);
|
||||||
|
}
|
||||||
RELEASE_IPIO:
|
|
||||||
|
|
||||||
IpIoDestroy (Udp4Service->IpIo);
|
IpIoDestroy (Udp4Service->IpIo);
|
||||||
|
|
||||||
|
|
|
@ -291,7 +291,7 @@ Udp4Configure (
|
||||||
//
|
//
|
||||||
Udp4FlushRcvdDgram (Instance);
|
Udp4FlushRcvdDgram (Instance);
|
||||||
|
|
||||||
////bugbug ASSERT (NetListIsEmpty (&Instance->DeliveredDgramQue));
|
ASSERT (NetListIsEmpty (&Instance->DeliveredDgramQue));
|
||||||
}
|
}
|
||||||
|
|
||||||
Udp4SetVariableData (Instance->Udp4Service);
|
Udp4SetVariableData (Instance->Udp4Service);
|
||||||
|
|
Loading…
Reference in New Issue