#include <Library/DebugLib.h>\r
#include <Library/UefiBootServicesTableLib.h>\r
#include <Library/MemoryAllocationLib.h>\r
+#include <library/BaseMemoryLib.h>\r
+\r
+STATIC\r
+VOID\r
+EFIAPI\r
+UdpIoOnDgramSentDpc (\r
+ IN VOID *Context\r
+ );\r
\r
STATIC\r
VOID\r
EFI_UDP4_TRANSMIT_DATA *UdpTxData;\r
EFI_STATUS Status;\r
UINT32 Count;\r
+ IP4_ADDR Ip;\r
\r
Token = NetAllocatePool (sizeof (UDP_TX_TOKEN) +\r
sizeof (EFI_UDP4_FRAGMENT_DATA) * (Packet->BlockOpNum - 1));\r
\r
Status = gBS->CreateEvent (\r
EVT_NOTIFY_SIGNAL,\r
- TPL_CALLBACK,\r
+ NET_TPL_EVENT,\r
UdpIoOnDgramSent,\r
Token,\r
&UdpToken->Event\r
UdpTxData->GatewayAddress = NULL;\r
\r
if (EndPoint != NULL) {\r
- EFI_IP4 (Token->UdpSession.SourceAddress) = HTONL (EndPoint->LocalAddr);\r
- EFI_IP4 (Token->UdpSession.DestinationAddress) = HTONL (EndPoint->RemoteAddr);\r
- Token->UdpSession.SourcePort = EndPoint->LocalPort;\r
- Token->UdpSession.DestinationPort = EndPoint->RemotePort;\r
- UdpTxData->UdpSessionData = &Token->UdpSession;\r
+ Ip = HTONL (EndPoint->LocalAddr);\r
+ NetCopyMem (&Token->UdpSession.SourceAddress, &Ip, sizeof (EFI_IPv4_ADDRESS));\r
+\r
+ Ip = HTONL (EndPoint->RemoteAddr);\r
+ NetCopyMem (&Token->UdpSession.DestinationAddress, &Ip, sizeof (EFI_IPv4_ADDRESS));\r
+\r
+ Token->UdpSession.SourcePort = EndPoint->LocalPort;\r
+ Token->UdpSession.DestinationPort = EndPoint->RemotePort;\r
+ UdpTxData->UdpSessionData = &Token->UdpSession;\r
}\r
\r
if (Gateway != 0) {\r
- EFI_IP4 (Token->Gateway) = HTONL (Gateway);\r
+ Ip = HTONL (Gateway);\r
+ NetCopyMem (&Token->Gateway, &Ip, sizeof (EFI_IPv4_ADDRESS));\r
+\r
UdpTxData->GatewayAddress = &Token->Gateway;\r
}\r
\r
\r
Status = gBS->CreateEvent (\r
EVT_NOTIFY_SIGNAL,\r
- TPL_CALLBACK,\r
+ NET_TPL_EVENT,\r
UdpIoOnDgramRcvd,\r
Token,\r
&Token->UdpToken.Event\r
Status = gBS->OpenProtocol (\r
UdpIo->UdpHandle,\r
&gEfiUdp4ProtocolGuid,\r
- &UdpIo->Udp,\r
+ (VOID **) &UdpIo->Udp,\r
Image,\r
Controller,\r
EFI_OPEN_PROTOCOL_BY_DRIVER\r
Token = NET_LIST_USER_STRUCT (Entry, UDP_TX_TOKEN, Link);\r
\r
if ((ToCancel == NULL) || (ToCancel (Token, Context))) {\r
- NetListRemoveEntry (Entry);\r
UdpIo->Udp->Cancel (UdpIo->Udp, &Token->UdpToken);\r
- Token->CallBack (Token->Packet, NULL, IoStatus, Token->Context);\r
- UdpIoFreeTxToken (Token);\r
}\r
}\r
}\r
UdpIoCancelDgrams (UdpIo, EFI_ABORTED, NULL, NULL);\r
\r
if ((RxToken = UdpIo->RecvRequest) != NULL) {\r
- UdpIo->RecvRequest = NULL;\r
UdpIo->Udp->Cancel (UdpIo->Udp, &RxToken->UdpToken);\r
- UdpIoFreeRxToken (RxToken);\r
}\r
\r
//\r
UdpIo->UdpHandle\r
);\r
\r
- NetListRemoveEntry (&UdpIo->Link);\r
+ if (!IsListEmpty(&UdpIo->Link)) {\r
+ NetListRemoveEntry (&UdpIo->Link);\r
+ }\r
+\r
NetFreePool (UdpIo);\r
return EFI_SUCCESS;\r
}\r
UdpIoCancelDgrams (UdpIo, EFI_ABORTED, NULL, NULL);\r
\r
if ((RxToken = UdpIo->RecvRequest) != NULL) {\r
- UdpIo->RecvRequest = NULL;\r
UdpIo->Udp->Cancel (UdpIo->Udp, &RxToken->UdpToken);\r
- UdpIoFreeRxToken (RxToken);\r
}\r
\r
UdpIo->Udp->Configure (UdpIo->Udp, NULL);\r
It will remove the packet from the local list then call\r
the packet owner's callback function.\r
\r
- @param Event The event signalled.\r
@param Context The UDP TX Token.\r
\r
@return None\r
STATIC\r
VOID\r
EFIAPI\r
-UdpIoOnDgramSent (\r
- IN EFI_EVENT Event,\r
+UdpIoOnDgramSentDpc (\r
IN VOID *Context\r
)\r
{\r
UdpIoFreeTxToken (Token);\r
}\r
\r
+/**\r
+ Request UdpIoOnDgramSentDpc as a DPC at TPL_CALLBACK.\r
+\r
+ @param Event The event signalled.\r
+ @param Context The UDP TX Token.\r
+\r
+ @return None\r
+\r
+**/\r
+STATIC\r
+VOID\r
+EFIAPI\r
+UdpIoOnDgramSent (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ //\r
+ // Request UdpIoOnDgramSentDpc as a DPC at TPL_CALLBACK\r
+ //\r
+ NetLibQueueDpc (TPL_CALLBACK, UdpIoOnDgramSentDpc, Context);\r
+}\r
+\r
\r
/**\r
Send a packet through the UDP IO port.\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
+ //\r
+ // Insert the tx token into SendDatagram list before transmitting it. Remove\r
+ // it from the list if the returned status is not EFI_SUCCESS.\r
+ //\r
+ NetListInsertHead (&UdpIo->SentDatagram, &Token->Link);\r
Status = UdpIo->Udp->Transmit (UdpIo->Udp, &Token->UdpToken);\r
-\r
if (EFI_ERROR (Status)) {\r
+ NetListRemoveEntry (&Token->Link);\r
UdpIoFreeTxToken (Token);\r
return Status;\r
}\r
\r
- NetListInsertHead (&UdpIo->SentDatagram, &Token->Link);\r
return EFI_SUCCESS;\r
}\r
\r
UdpIoFreeRxToken (Token);\r
}\r
\r
-\r
/**\r
The event handle for UDP receive request. It will build\r
a NET_BUF from the recieved UDP data, then deliver it\r
to the receiver.\r
\r
- @param Event The UDP receive request event\r
@param Context The UDP RX token.\r
\r
@return None\r
STATIC\r
VOID\r
EFIAPI\r
-UdpIoOnDgramRcvd (\r
- IN EFI_EVENT Event,\r
+UdpIoOnDgramRcvdDpc (\r
IN VOID *Context\r
)\r
{\r
UdpRxData = UdpToken->Packet.RxData;\r
\r
if (EFI_ERROR (UdpToken->Status) || (UdpRxData == NULL)) {\r
- Token->CallBack (NULL, NULL, UdpToken->Status, Token->Context);\r
- UdpIoFreeRxToken (Token);\r
+ if (UdpToken->Status != EFI_ABORTED) {\r
+ //\r
+ // Invoke the CallBack only if the reception is not actively aborted.\r
+ //\r
+ Token->CallBack (NULL, NULL, UdpToken->Status, Token->Context);\r
+ }\r
\r
- goto ON_EXIT;\r
+ UdpIoFreeRxToken (Token);\r
+ return;\r
}\r
\r
//\r
Token->CallBack (NULL, NULL, EFI_OUT_OF_RESOURCES, Token->Context);\r
\r
UdpIoFreeRxToken (Token);\r
- goto ON_EXIT;\r
+ return;\r
}\r
\r
UdpSession = &UdpRxData->UdpSession;\r
- Points.LocalAddr = EFI_NTOHL (UdpSession->DestinationAddress);\r
Points.LocalPort = UdpSession->DestinationPort;\r
- Points.RemoteAddr = EFI_NTOHL (UdpSession->SourceAddress);\r
Points.RemotePort = UdpSession->SourcePort;\r
\r
+ NetCopyMem (&Points.LocalAddr, &UdpSession->DestinationAddress, sizeof (IP4_ADDR));\r
+ NetCopyMem (&Points.RemoteAddr, &UdpSession->SourceAddress, sizeof (IP4_ADDR));\r
+ Points.LocalAddr = NTOHL (Points.LocalAddr);\r
+ Points.RemoteAddr = NTOHL (Points.RemoteAddr);\r
+\r
Token->CallBack (Netbuf, &Points, EFI_SUCCESS, Token->Context);\r
+}\r
\r
-ON_EXIT:\r
- return;\r
+/**\r
+ Request UdpIoOnDgramRcvdDpc as a DPC at TPL_CALLBACK.\r
+\r
+ @param Event The UDP receive request event.\r
+ @param Context The UDP RX token.\r
+\r
+ @return None\r
+\r
+**/\r
+STATIC\r
+VOID\r
+EFIAPI\r
+UdpIoOnDgramRcvd (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Request UdpIoOnDgramRcvdDpc as a DPC at TPL_CALLBACK\r
+\r
+Arguments:\r
+\r
+ Event - The UDP receive request event\r
+ Context - The UDP RX token.\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ //\r
+ // Request UdpIoOnDgramRcvdDpc as a DPC at TPL_CALLBACK\r
+ //\r
+ NetLibQueueDpc (TPL_CALLBACK, UdpIoOnDgramRcvdDpc, Context);\r
}\r
\r
\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
+ UdpIo->RecvRequest = Token;\r
Status = UdpIo->Udp->Receive (UdpIo->Udp, &Token->UdpToken);\r
\r
if (EFI_ERROR (Status)) {\r
+ UdpIo->RecvRequest = NULL;\r
UdpIoFreeRxToken (Token);\r
- return Status;\r
}\r
\r
- UdpIo->RecvRequest = Token;\r
- return EFI_SUCCESS;\r
+ return Status;\r
}\r