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:
vanjeff 2007-12-18 07:01:23 +00:00
parent 372787b85a
commit c4a62a12c2
26 changed files with 790 additions and 424 deletions

View File

@ -212,7 +212,9 @@ 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.
// //

View File

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

View File

@ -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.
// //
ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle); ArpCleanService (ArpService);
NetFreePool (ArpService);
} else {
while (!NetListIsEmpty (&ArpService->ChildrenList)) {
Instance = NET_LIST_HEAD (&ArpService->ChildrenList, ARP_INSTANCE_DATA, List);
ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
}
ASSERT (NetListIsEmpty (&ArpService->PendingRequestTable));
ASSERT (NetListIsEmpty (&ArpService->DeniedCacheTable));
ASSERT (NetListIsEmpty (&ArpService->ResolvedCacheTable));
} }
ASSERT (NetListIsEmpty (&ArpService->PendingRequestTable)); return EFI_SUCCESS;
ASSERT (NetListIsEmpty (&ArpService->DeniedCacheTable));
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;
}
//
// 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.

View File

@ -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 (
@ -394,44 +394,39 @@ Dhcp4DriverBindingStop (
return EFI_SUCCESS; return EFI_SUCCESS;
} }
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK); OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
DhcpSb->InDestory = TRUE;
// if (NumberOfChildren == 0) {
// Don't use NET_LIST_FOR_EACH_SAFE here, Dhcp4ServiceBindingDestoryChild
// may cause other child to be deleted. DhcpSb->InDestory = TRUE;
// DhcpSb->ServiceState = DHCP_DESTORY;
while (!NetListIsEmpty (&DhcpSb->Children)) {
Instance = NET_LIST_HEAD (&DhcpSb->Children, DHCP_PROTOCOL, Link); gBS->UninstallProtocolInterface (
Dhcp4ServiceBindingDestroyChild (ServiceBinding, Instance->Handle); NicHandle,
&gEfiDhcp4ServiceBindingProtocolGuid,
ServiceBinding
);
Dhcp4CloseService (DhcpSb);
NetFreePool (DhcpSb);
} else {
//
// Don't use NET_LIST_FOR_EACH_SAFE here, Dhcp4ServiceBindingDestoryChild
// may cause other child to be deleted.
//
while (!NetListIsEmpty (&DhcpSb->Children)) {
Instance = NET_LIST_HEAD (&DhcpSb->Children, DHCP_PROTOCOL, Link);
ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
}
if (DhcpSb->NumChildren != 0) {
Status = EFI_DEVICE_ERROR;
}
} }
if (DhcpSb->NumChildren != 0) {
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);
} }

View File

@ -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) {
//
// The previous call to TransmitReceive is not finished.
//
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);
// //
// This function is for PXE, leave it for now // Save the token and the timeout value.
// //
return EFI_UNSUPPORTED; 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
}; };

View File

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

View File

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

View File

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

View File

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

View File

@ -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,62 +632,88 @@ Ip4DriverBindingStop (
return EFI_SUCCESS; return EFI_SUCCESS;
} }
IpSb->InDestory = TRUE; if (IsArp) {
while (!NetListIsEmpty (&IpSb->Children)) {
IpInstance = NET_LIST_HEAD (&IpSb->Children, IP4_PROTOCOL, Link);
State = IpSb->State; ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle);
IpSb->State = IP4_SERVICE_DESTORY; }
// if (IpSb->NumChildren != 0) {
// Destory all the children first. If not all children are destoried, Status = EFI_DEVICE_ERROR;
// the IP driver can operate correctly, so restore it state. Don't goto ON_ERROR;
// 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 IpSb->InDestory = TRUE;
// 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 State = IpSb->State;
// a invalid child. IpSb->State = IP4_SERVICE_DESTORY;
//
while (!NetListIsEmpty (&IpSb->Children)) { //
IpInstance = NET_LIST_HEAD (&IpSb->Children, IP4_PROTOCOL, Link); // Clear the variable data.
Ip4ServiceBindingDestroyChild (ServiceBinding, IpInstance->Handle); //
Ip4ClearVariableData (IpSb);
//
// OK, clean other resources then uninstall the service binding protocol.
//
Status = Ip4CleanService (IpSb);
if (EFI_ERROR (Status)) {
IpSb->State = State;
goto ON_ERROR;
}
gBS->UninstallProtocolInterface (
NicHandle,
&gEfiIp4ServiceBindingProtocolGuid,
ServiceBinding
);
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)) {
IpSb->State = State;
goto ON_ERROR;
}
gBS->UninstallProtocolInterface (
NicHandle,
&gEfiIp4ServiceBindingProtocolGuid,
ServiceBinding
);
NetFreePool (IpSb);
} 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;
}
} }
if (IpSb->NumChildren != 0) {
IpSb->State = State;
Status = EFI_DEVICE_ERROR;
goto ON_ERROR;
}
//
// Clear the variable data.
//
Ip4ClearVariableData (IpSb);
//
// OK, clean other resources then uninstall the service binding protocol.
//
Status = Ip4CleanService (IpSb);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
Status = gBS->UninstallProtocolInterface (
NicHandle,
&gEfiIp4ServiceBindingProtocolGuid,
ServiceBinding
);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
NET_RESTORE_TPL (OldTpl);
NetFreePool (IpSb);
return EFI_SUCCESS;
ON_ERROR: ON_ERROR:
IpSb->InDestory = FALSE;
NET_RESTORE_TPL (OldTpl); NET_RESTORE_TPL (OldTpl);
return Status; return Status;
} }

View File

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

View File

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

View File

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

View File

@ -219,64 +219,54 @@ 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);
while (!NetListIsEmpty (&MnpServiceData->ChildrenList)) { if (NumberOfChildren == 0) {
// //
// Don't use NetListRemoveHead here, the remove opreration will be done // Uninstall the MNP Service Binding Protocol.
// in ServiceBindingDestroyChild.
// //
Instance = NET_LIST_HEAD ( gBS->UninstallMultipleProtocolInterfaces (
&MnpServiceData->ChildrenList, ControllerHandle,
MNP_INSTANCE_DATA, &gEfiManagedNetworkServiceBindingProtocolGuid,
InstEntry ServiceBinding,
); NULL
);
ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle); //
// 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)) {
//
// Don't use NetListRemoveHead here, the remove opreration will be done
// in ServiceBindingDestroyChild.
//
Instance = NET_LIST_HEAD (
&MnpServiceData->ChildrenList,
MNP_INSTANCE_DATA,
InstEntry
);
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;
} }

View File

@ -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 (
@ -370,38 +370,33 @@ Mtftp4DriverBindingStop (
return EFI_SUCCESS; return EFI_SUCCESS;
} }
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK); OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
MtftpSb->InDestory = TRUE;
while (!NetListIsEmpty (&MtftpSb->Children)) { if (NumberOfChildren == 0) {
Instance = NET_LIST_HEAD (&MtftpSb->Children, MTFTP4_PROTOCOL, Link);
Mtftp4ServiceBindingDestroyChild (ServiceBinding, Instance->Handle); MtftpSb->InDestory = TRUE;
gBS->UninstallProtocolInterface (
NicHandle,
&gEfiMtftp4ServiceBindingProtocolGuid,
ServiceBinding
);
Mtftp4CleanService (MtftpSb);
NetFreePool (MtftpSb);
} else {
while (!NetListIsEmpty (&MtftpSb->Children)) {
Instance = NET_LIST_HEAD (&MtftpSb->Children, MTFTP4_PROTOCOL, Link);
Mtftp4ServiceBindingDestroyChild (ServiceBinding, Instance->Handle);
}
if (MtftpSb->ChildrenNum != 0) {
Status = EFI_DEVICE_ERROR;
}
} }
if (MtftpSb->ChildrenNum != 0) {
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;
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 (); if (TcpServiceData->IpIo != NULL) {
IpIoDestroy (TcpServiceData->IpIo);
ReleaseIpIo: }
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,95 +424,53 @@ 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);
// if (NumberOfChildren == 0) {
// Kill TCP driver //
// // Uninstall TCP servicebinding protocol
NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &mTcpRunQue) { //
TcpPcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List); gBS->UninstallMultipleProtocolInterfaces (
NicHandle,
&gEfiTcp4ServiceBindingProtocolGuid,
ServiceBinding,
NULL
);
// //
// Try to destroy this child // Destroy the IpIO consumed by TCP driver
// //
Sock = TcpPcb->Sk; IpIoDestroy (TcpServiceData->IpIo);
TcpProto = (TCP4_PROTO_DATA *) Sock->ProtoReserved;
if (TcpProto->TcpService == TcpServiceData) { //
Status = SockDestroyChild (Sock); // Destroy the heartbeat timer.
//
Tcp4DestroyTimer ();
if (EFI_ERROR (Status)) { //
// Clear the variable.
//
TcpClearVariableData (TcpServiceData);
TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Destroy Tcp " //
"instance failed with %r\n", Status)); // Release the TCP service data
return Status; //
} NetFreePool (TcpServiceData);
} else {
while (!NetListIsEmpty (&TcpServiceData->SocketList)) {
Sock = NET_LIST_HEAD (&TcpServiceData->SocketList, SOCKET, Link);
ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle);
} }
} }
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;
}
}
}
//
// Uninstall TCP servicebinding protocol
//
Status = gBS->UninstallMultipleProtocolInterfaces (
NicHandle,
&gEfiTcp4ServiceBindingProtocolGuid,
Tcp4ServiceBinding,
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
//
Status = IpIoDestroy (TcpServiceData->IpIo);
//
// Destroy the heartbeat timer.
//
Tcp4DestroyTimer ();
//
// Clear the variable.
//
TcpClearVariableData (TcpServiceData);
//
// Release the TCP service data
//
NetFreePool (TcpServiceData);
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

View File

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

View File

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

View File

@ -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,21 +137,12 @@ Udp4DriverBindingStart (
NULL NULL
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
goto CLEAN_SERVICE; Udp4CleanService (Udp4Service);
NetFreePool (Udp4Service);
} else {
Udp4SetVariableData (Udp4Service);
} }
Udp4SetVariableData (Udp4Service);
return Status;
CLEAN_SERVICE:
Udp4CleanService (Udp4Service);
FREE_SERVICE:
NetFreePool (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)) { Udp4ClearVariableData (Udp4Service);
return EFI_DEVICE_ERROR;
Udp4CleanService (Udp4Service);
NetFreePool (Udp4Service);
} else {
while (!NetListIsEmpty (&Udp4Service->ChildrenList)) {
Instance = NET_LIST_HEAD (&Udp4Service->ChildrenList, UDP4_INSTANCE_DATA, Link);
ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);
}
} }
while (!NetListIsEmpty (&Udp4Service->ChildrenList)) { return Status;
//
// Destroy all instances.
//
Instance = NET_LIST_HEAD (&Udp4Service->ChildrenList, UDP4_INSTANCE_DATA, Link);
ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);
}
Udp4ClearVariableData (Udp4Service);
Udp4CleanService (Udp4Service);
NetFreePool (Udp4Service);
return EFI_SUCCESS;
} }
@ -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:
gBS->UninstallMultipleProtocolInterfaces ( if (Instance->ChildHandle != NULL) {
Instance->ChildHandle, gBS->UninstallMultipleProtocolInterfaces (
&gEfiUdp4ProtocolGuid, Instance->ChildHandle,
&Instance->Udp4Proto, &gEfiUdp4ProtocolGuid,
NULL &Instance->Udp4Proto,
); NULL
);
}
REMOVE_IPINFO: if (Instance->IpInfo != NULL) {
IpIoRemoveIp (Udp4Service->IpIo, Instance->IpInfo);
IpIoRemoveIp (Udp4Service->IpIo, Instance->IpInfo); }
FREE_INSTANCE:
Udp4CleanInstance (Instance); Udp4CleanInstance (Instance);

View File

@ -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:
gBS->CloseEvent (Udp4Service->TimeoutEvent); if (Udp4Service->TimeoutEvent != NULL) {
gBS->CloseEvent (Udp4Service->TimeoutEvent);
RELEASE_IPIO: }
IpIoDestroy (Udp4Service->IpIo); IpIoDestroy (Udp4Service->IpIo);

View File

@ -291,7 +291,7 @@ Udp4Configure (
// //
Udp4FlushRcvdDgram (Instance); Udp4FlushRcvdDgram (Instance);
////bugbug ASSERT (NetListIsEmpty (&Instance->DeliveredDgramQue)); ASSERT (NetListIsEmpty (&Instance->DeliveredDgramQue));
} }
Udp4SetVariableData (Instance->Udp4Service); Udp4SetVariableData (Instance->Udp4Service);