]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Sync the latest version from R8.
authorvanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 18 Dec 2007 07:01:23 +0000 (07:01 +0000)
committervanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 18 Dec 2007 07:01:23 +0000 (07:01 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4400 6f19259b-4bc3-4df7-8a09-765794883524

26 files changed:
MdeModulePkg/Include/Library/NetLib.h
MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.c
MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.c
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.h
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.c
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.h
MdeModulePkg/Universal/Network/DpcDxe/Dpc.c
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4If.c
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c
MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.c
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.c
MdeModulePkg/Universal/Network/Tcp4Dxe/SockImpl.c
MdeModulePkg/Universal/Network/Tcp4Dxe/Socket.h
MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c
MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.h
MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Misc.c
MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Driver.c
MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c
MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Main.c

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