mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-10-31 03:03:46 +01:00 
			
		
		
		
	Sync the latest version from R8.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4400 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
		
							parent
							
								
									372787b85a
								
							
						
					
					
						commit
						c4a62a12c2
					
				| @ -212,7 +212,9 @@ extern IP4_ADDR mIp4AllMasks [IP4_MASK_NUM]; | ||||
| 
 | ||||
| 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.
 | ||||
| //
 | ||||
|  | ||||
| @ -1092,12 +1092,6 @@ IpIoCancelTxToken ( | ||||
|       Ip = SndEntry->Ip; | ||||
|       Ip->Cancel (Ip, SndEntry->SndToken); | ||||
| 
 | ||||
|       //
 | ||||
|       // Abort the user token.
 | ||||
|       //
 | ||||
|       SndEntry->SndToken->Status = EFI_ABORTED; | ||||
|       IpIoTransmitHandler (NULL, SndEntry); | ||||
| 
 | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @ -413,7 +413,7 @@ ArpDriverBindingStop ( | ||||
|   //
 | ||||
|   NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid); | ||||
|   if (NicHandle == NULL) { | ||||
|     return EFI_SUCCESS; | ||||
|     return EFI_DEVICE_ERROR; | ||||
|   } | ||||
| 
 | ||||
|   //
 | ||||
| @ -429,51 +429,44 @@ ArpDriverBindingStop ( | ||||
|                   ); | ||||
|   if (EFI_ERROR (Status)) { | ||||
|     ARP_DEBUG_ERROR (("ArpDriverBindingStop: Open ArpSb failed, %r.\n", Status)); | ||||
|     return Status; | ||||
|     return EFI_DEVICE_ERROR; | ||||
|   } | ||||
| 
 | ||||
|   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)); | ||||
|   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; | ||||
|   return EFI_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|   Creates a child handle with a set of I/O services. | ||||
| 
 | ||||
|  | ||||
| @ -229,7 +229,7 @@ Dhcp4CreateService ( | ||||
|   //
 | ||||
|   Status = gBS->CreateEvent ( | ||||
|                   EVT_NOTIFY_SIGNAL | EVT_TIMER, | ||||
|                   TPL_CALLBACK, | ||||
|                   NET_TPL_TIMER, | ||||
|                   DhcpOnTimerTick, | ||||
|                   DhcpSb, | ||||
|                   &DhcpSb->Timer | ||||
| @ -372,7 +372,7 @@ Dhcp4DriverBindingStop ( | ||||
|   NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp4ProtocolGuid); | ||||
| 
 | ||||
|   if (NicHandle == NULL) { | ||||
|     return EFI_SUCCESS; | ||||
|     return EFI_DEVICE_ERROR; | ||||
|   } | ||||
| 
 | ||||
|    Status = gBS->OpenProtocol ( | ||||
| @ -394,44 +394,39 @@ Dhcp4DriverBindingStop ( | ||||
|     return EFI_SUCCESS; | ||||
|   } | ||||
| 
 | ||||
|   OldTpl            = NET_RAISE_TPL (NET_TPL_LOCK); | ||||
|   DhcpSb->InDestory = TRUE; | ||||
|   OldTpl = NET_RAISE_TPL (NET_TPL_LOCK); | ||||
| 
 | ||||
|   //
 | ||||
|   // 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); | ||||
|     Dhcp4ServiceBindingDestroyChild (ServiceBinding, Instance->Handle); | ||||
|   if (NumberOfChildren == 0) { | ||||
| 
 | ||||
|     DhcpSb->InDestory    = TRUE; | ||||
|     DhcpSb->ServiceState = DHCP_DESTORY; | ||||
| 
 | ||||
|     gBS->UninstallProtocolInterface ( | ||||
|            NicHandle, | ||||
|            &gEfiDhcp4ServiceBindingProtocolGuid, | ||||
|            ServiceBinding | ||||
|            ); | ||||
| 
 | ||||
|     Dhcp4CloseService (DhcpSb); | ||||
| 
 | ||||
|     NetFreePool (DhcpSb); | ||||
|   } else { | ||||
|     //
 | ||||
|     // Don't use NET_LIST_FOR_EACH_SAFE here, Dhcp4ServiceBindingDestoryChild
 | ||||
|     // 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); | ||||
| 
 | ||||
|   NetFreePool (DhcpSb); | ||||
|   return EFI_SUCCESS; | ||||
| 
 | ||||
| ON_ERROR: | ||||
|   DhcpSb->InDestory = FALSE; | ||||
|   NET_RESTORE_TPL (OldTpl); | ||||
|   return Status; | ||||
| } | ||||
| 
 | ||||
| @ -460,6 +455,8 @@ DhcpInitProtocol ( | ||||
|   Instance->CompletionEvent   = NULL; | ||||
|   Instance->RenewRebindEvent  = NULL; | ||||
|   Instance->Token             = NULL; | ||||
|   Instance->UdpIo             = NULL; | ||||
|   NetbufQueInit (&Instance->ResponseQueue); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -57,11 +57,7 @@ EfiDhcp4GetModeData ( | ||||
|   } | ||||
| 
 | ||||
|   Instance = DHCP_INSTANCE_FROM_THIS (This); | ||||
| 
 | ||||
|   if (Instance->Signature != DHCP_PROTOCOL_SIGNATURE) { | ||||
|     return EFI_INVALID_PARAMETER; | ||||
|   } | ||||
| 
 | ||||
|    | ||||
|   OldTpl  = NET_RAISE_TPL (NET_TPL_LOCK); | ||||
|   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. | ||||
| @ -785,10 +1001,144 @@ EfiDhcp4TransmitReceive ( | ||||
|   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, | ||||
|   EfiDhcp4Parse | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -77,6 +77,9 @@ struct _DHCP_PROTOCOL { | ||||
|   EFI_EVENT                         RenewRebindEvent; | ||||
| 
 | ||||
|   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 | ||||
|   ); | ||||
| 
 | ||||
| VOID | ||||
| PxeDhcpDone ( | ||||
|   IN DHCP_PROTOCOL  *Instance | ||||
|   ); | ||||
| 
 | ||||
| #endif | ||||
|  | ||||
| @ -52,8 +52,6 @@ DhcpInitRequest ( | ||||
|       DhcpSb->DhcpState = Dhcp4Init; | ||||
|       return Status; | ||||
|     } | ||||
| 
 | ||||
|     DhcpSb->WaitOffer = DHCP_WAIT_OFFER; | ||||
|   } else { | ||||
|     DhcpSetState (DhcpSb, Dhcp4Rebooting, FALSE); | ||||
|     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
 | ||||
|   // first transit the state, then send packets.
 | ||||
|   //
 | ||||
|   if (State == Dhcp4Init) { | ||||
|   if (State == Dhcp4Selecting) { | ||||
|     DhcpSb->MaxRetries = DhcpSb->ActiveConfig.DiscoverTryCount; | ||||
|   } else { | ||||
|     DhcpSb->MaxRetries = DhcpSb->ActiveConfig.RequestTryCount; | ||||
| @ -262,7 +260,7 @@ DhcpSetTransmitTimer ( | ||||
| 
 | ||||
|   ASSERT (DhcpSb->MaxRetries > DhcpSb->CurRetry); | ||||
| 
 | ||||
|   if (DhcpSb->DhcpState == Dhcp4Init) { | ||||
|   if (DhcpSb->DhcpState == Dhcp4Selecting) { | ||||
|     Times = DhcpSb->ActiveConfig.DiscoverTimeout; | ||||
|   } else { | ||||
|     Times = DhcpSb->ActiveConfig.RequestTimeout; | ||||
| @ -273,8 +271,11 @@ DhcpSetTransmitTimer ( | ||||
|   } | ||||
| 
 | ||||
|   DhcpSb->PacketToLive = Times[DhcpSb->CurRetry]; | ||||
| } | ||||
| 
 | ||||
|   if (DhcpSb->DhcpState == Dhcp4Selecting) { | ||||
|     DhcpSb->WaitOffer = DhcpSb->PacketToLive; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|   Compute the lease. If the server grants a permanent lease, just | ||||
| @ -519,6 +520,7 @@ DhcpChooseOffer ( | ||||
| { | ||||
|   EFI_DHCP4_PACKET          *Selected; | ||||
|   EFI_DHCP4_PACKET          *NewPacket; | ||||
|   EFI_DHCP4_PACKET          *TempPacket; | ||||
|   EFI_STATUS                Status; | ||||
| 
 | ||||
|   ASSERT (DhcpSb->LastOffer != NULL); | ||||
| @ -542,12 +544,12 @@ DhcpChooseOffer ( | ||||
| 
 | ||||
|   Selected = DhcpSb->LastOffer; | ||||
| 
 | ||||
|   if (NewPacket != NULL) { | ||||
|     if (EFI_ERROR (DhcpValidateOptions (NewPacket, NULL))) { | ||||
|       NetFreePool (NewPacket); | ||||
|     } else { | ||||
|   if ((NewPacket != NULL) && !EFI_ERROR (DhcpValidateOptions (NewPacket, NULL))) { | ||||
|     TempPacket = (EFI_DHCP4_PACKET *) NetAllocatePool (NewPacket->Size); | ||||
|     if (TempPacket != NULL) { | ||||
|       NetCopyMem (TempPacket, NewPacket, NewPacket->Size); | ||||
|       NetFreePool (Selected); | ||||
|       Selected = NewPacket; | ||||
|       Selected = TempPacket; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| @ -650,10 +652,6 @@ DhcpHandleSelect ( | ||||
|   //
 | ||||
|   Head = &Packet->Dhcp4.Header; | ||||
| 
 | ||||
|   if (!Ip4IsUnicast (EFI_NTOHL (Head->YourAddr), (Para == NULL ? 0 : Para->NetMask))) { | ||||
|     goto ON_EXIT; | ||||
|   } | ||||
| 
 | ||||
|   if (!DHCP_IS_BOOTP (Para) && | ||||
|      ((Para->DhcpType != DHCP_MSG_OFFER) || (Para->ServerId == 0))) { | ||||
|     goto ON_EXIT; | ||||
| @ -1495,12 +1493,32 @@ DhcpOnTimerTick ( | ||||
|   ) | ||||
| { | ||||
|   DHCP_SERVICE              *DhcpSb; | ||||
|   DHCP_PROTOCOL             *Instance; | ||||
|   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)) { | ||||
| 
 | ||||
| @ -1543,22 +1561,7 @@ 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
 | ||||
|   // 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 ; | ||||
| 
 | ||||
| END_SESSION: | ||||
|  | ||||
| @ -112,4 +112,12 @@ DhcpCleanLease ( | ||||
|   IN DHCP_SERVICE           *DhcpSb | ||||
|   ); | ||||
| 
 | ||||
| VOID | ||||
| DhcpOnPacketSent ( | ||||
|   NET_BUF                   *Packet, | ||||
|   UDP_POINTS                *Points, | ||||
|   EFI_STATUS                IoStatus, | ||||
|   VOID                      *Context | ||||
|   ); | ||||
| 
 | ||||
| #endif | ||||
|  | ||||
| @ -343,7 +343,8 @@ Returns: | ||||
|   //
 | ||||
|   Status = gBS->InstallMultipleProtocolInterfaces ( | ||||
|                   &mDpcHandle, | ||||
|                   &gEfiDpcProtocolGuid, &mDpc, | ||||
|                   &gEfiDpcProtocolGuid,  | ||||
|                   &mDpc, | ||||
|                   NULL | ||||
|                   ); | ||||
|   ASSERT_EFI_ERROR (Status); | ||||
|  | ||||
| @ -512,6 +512,7 @@ Ip4DriverBindingStop ( | ||||
|   EFI_STATUS                    Status; | ||||
|   EFI_TPL                       OldTpl; | ||||
|   INTN                          State; | ||||
|   BOOLEAN                       IsArp; | ||||
| 
 | ||||
|   //
 | ||||
|   // IP4 driver opens the MNP child, ARP children or the IP4_CONFIG protocol
 | ||||
| @ -549,7 +550,7 @@ Ip4DriverBindingStop ( | ||||
|                     ); | ||||
| 
 | ||||
|     if (EFI_ERROR (Status)) { | ||||
|       return EFI_SUCCESS; | ||||
|       return EFI_DEVICE_ERROR; | ||||
|     } | ||||
| 
 | ||||
|     IpSb = IP4_SERVICE_FROM_PROTOCOL (ServiceBinding); | ||||
| @ -594,14 +595,16 @@ Ip4DriverBindingStop ( | ||||
|   // service binding is installed on the NIC handle. So, need to open
 | ||||
|   // the protocol info to find the NIC handle.
 | ||||
|   //
 | ||||
|   IsArp     = FALSE; | ||||
|   NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid); | ||||
| 
 | ||||
|   if (NicHandle == NULL) { | ||||
|     NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiArpProtocolGuid); | ||||
|     IsArp     = TRUE; | ||||
|   } | ||||
| 
 | ||||
|   if (NicHandle == NULL) { | ||||
|     return EFI_SUCCESS; | ||||
|     return EFI_DEVICE_ERROR; | ||||
|   } | ||||
| 
 | ||||
|   //
 | ||||
| @ -629,62 +632,88 @@ Ip4DriverBindingStop ( | ||||
|     return EFI_SUCCESS; | ||||
|   } | ||||
| 
 | ||||
|   IpSb->InDestory = TRUE; | ||||
|   if (IsArp) { | ||||
|     while (!NetListIsEmpty (&IpSb->Children)) { | ||||
|       IpInstance = NET_LIST_HEAD (&IpSb->Children, IP4_PROTOCOL, Link); | ||||
| 
 | ||||
|   State           = IpSb->State; | ||||
|   IpSb->State     = IP4_SERVICE_DESTORY; | ||||
|       ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle); | ||||
|     } | ||||
| 
 | ||||
|   //
 | ||||
|   // Destory all the children first. If not all children are destoried,
 | ||||
|   // the IP driver can operate correctly, so restore it state. Don't
 | ||||
|   // use NET_LIST_FOR_EACH_SAFE here, because it will cache the next
 | ||||
|   // pointer, which may point to the child that has already been destoried.
 | ||||
|   // For example, if there are two child in the list, the first is UDP
 | ||||
|   // listen child, the send is the MTFTP's child. When Udp child is
 | ||||
|   // destoried, it will destory the MTFTP's child. Then Next point to
 | ||||
|   // a invalid child.
 | ||||
|   //
 | ||||
|   while (!NetListIsEmpty (&IpSb->Children)) { | ||||
|     IpInstance = NET_LIST_HEAD (&IpSb->Children, IP4_PROTOCOL, Link); | ||||
|     Ip4ServiceBindingDestroyChild (ServiceBinding, IpInstance->Handle); | ||||
|     if (IpSb->NumChildren != 0) { | ||||
|       Status = EFI_DEVICE_ERROR; | ||||
|       goto ON_ERROR; | ||||
|     } | ||||
| 
 | ||||
|     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 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: | ||||
|   IpSb->InDestory = FALSE; | ||||
| 
 | ||||
|   NET_RESTORE_TPL (OldTpl); | ||||
|   return Status; | ||||
| } | ||||
|  | ||||
| @ -681,7 +681,6 @@ Ip4CancelReceive ( | ||||
| 
 | ||||
|     Interface->RecvRequest = NULL; | ||||
|     Interface->Mnp->Cancel (Interface->Mnp, &Token->MnpToken); | ||||
|     Ip4FreeFrameRxToken (Token); | ||||
| 
 | ||||
|     NET_RESTORE_TPL (OldTpl); | ||||
|   } | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /** @file
 | ||||
| 
 | ||||
| Copyright (c) 2005 - 2006, Intel Corporation | ||||
| Copyright (c) 2005 - 2007, Intel Corporation                                                          | ||||
| All rights reserved. This program and the accompanying materials | ||||
| are licensed and made available under the terms and conditions of the BSD License | ||||
| which accompanies this distribution.  The full text of the license may be found at | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /** @file
 | ||||
| 
 | ||||
| Copyright (c) 2005 - 2006, Intel Corporation | ||||
| Copyright (c) 2005 - 2007, Intel Corporation                                                          | ||||
| All rights reserved. This program and the accompanying materials | ||||
| are licensed and made available under the terms and conditions of the BSD License | ||||
| which accompanies this distribution.  The full text of the license may be found at | ||||
|  | ||||
| @ -219,64 +219,54 @@ MnpDriverBindingStop ( | ||||
|       ("MnpDriverBindingStop: Locate MNP Service Binding Protocol failed, %r.\n", | ||||
|       Status) | ||||
|       ); | ||||
|     goto EXIT; | ||||
|     return EFI_DEVICE_ERROR; | ||||
|   } | ||||
| 
 | ||||
|   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
 | ||||
|     // in ServiceBindingDestroyChild.
 | ||||
|     // Uninstall the MNP Service Binding Protocol.
 | ||||
|     //
 | ||||
|     Instance = NET_LIST_HEAD ( | ||||
|                 &MnpServiceData->ChildrenList, | ||||
|                 MNP_INSTANCE_DATA, | ||||
|                 InstEntry | ||||
|                 ); | ||||
|     gBS->UninstallMultipleProtocolInterfaces ( | ||||
|            ControllerHandle, | ||||
|            &gEfiManagedNetworkServiceBindingProtocolGuid, | ||||
|            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; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -348,7 +348,7 @@ Mtftp4DriverBindingStop ( | ||||
|   NicHandle = NetLibGetNicHandle (Controller, &gEfiUdp4ProtocolGuid); | ||||
| 
 | ||||
|   if (NicHandle == NULL) { | ||||
|     return EFI_SUCCESS; | ||||
|     return EFI_DEVICE_ERROR; | ||||
|   } | ||||
| 
 | ||||
|   Status = gBS->OpenProtocol ( | ||||
| @ -370,38 +370,33 @@ Mtftp4DriverBindingStop ( | ||||
|     return EFI_SUCCESS; | ||||
|   } | ||||
| 
 | ||||
|   OldTpl             = NET_RAISE_TPL (NET_TPL_LOCK); | ||||
|   MtftpSb->InDestory = TRUE; | ||||
|   OldTpl = NET_RAISE_TPL (NET_TPL_LOCK); | ||||
| 
 | ||||
|   while (!NetListIsEmpty (&MtftpSb->Children)) { | ||||
|     Instance = NET_LIST_HEAD (&MtftpSb->Children, MTFTP4_PROTOCOL, Link); | ||||
|     Mtftp4ServiceBindingDestroyChild (ServiceBinding, Instance->Handle); | ||||
|   if (NumberOfChildren == 0) { | ||||
| 
 | ||||
|     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); | ||||
|   return Status; | ||||
| } | ||||
|  | ||||
| @ -585,6 +585,16 @@ Mtftp4ConfigUnicastPort ( | ||||
|     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; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -412,6 +412,18 @@ Mtftp4RrqConfigMcastPort ( | ||||
|     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
 | ||||
|   //
 | ||||
| @ -534,22 +546,22 @@ Mtftp4RrqHandleOack ( | ||||
| 
 | ||||
|         return Status; | ||||
|       } | ||||
| 
 | ||||
|      | ||||
|       //
 | ||||
|       // Update the parameters used.
 | ||||
|       //
 | ||||
|       if (Reply.BlkSize != 0) { | ||||
|         Instance->BlkSize = Reply.BlkSize; | ||||
|       } | ||||
| 
 | ||||
|        | ||||
|       if (Reply.Timeout != 0) { | ||||
|         Instance->Timeout = Reply.Timeout; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|       }   | ||||
|     }     | ||||
|      | ||||
|   } else { | ||||
|     Instance->Master = TRUE; | ||||
| 
 | ||||
|      | ||||
|     if (Reply.BlkSize != 0) { | ||||
|       Instance->BlkSize = Reply.BlkSize; | ||||
|     } | ||||
| @ -558,7 +570,7 @@ Mtftp4RrqHandleOack ( | ||||
|       Instance->Timeout = Reply.Timeout; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|    | ||||
|   //
 | ||||
|   // Send an ACK to (Expected - 1) which is 0 for unicast download,
 | ||||
|   // or tell the server we want to receive the Expected block.
 | ||||
|  | ||||
| @ -467,7 +467,7 @@ Mtftp4SendPacket ( | ||||
|              Instance->UnicastPort, | ||||
|              Packet, | ||||
|              &UdpPoint, | ||||
|              Instance->Gateway, | ||||
|              0, | ||||
|              Mtftp4OnPacketSent, | ||||
|              Instance | ||||
|              ); | ||||
| @ -524,7 +524,7 @@ Mtftp4Retransmit ( | ||||
|              Instance->UnicastPort, | ||||
|              Instance->LastPacket, | ||||
|              &UdpPoint, | ||||
|              Instance->Gateway, | ||||
|              0, | ||||
|              Mtftp4OnPacketSent, | ||||
|              Instance | ||||
|              ); | ||||
|  | ||||
| @ -584,6 +584,7 @@ SockCreate ( | ||||
|     return NULL; | ||||
|   } | ||||
| 
 | ||||
|   NetListInit (&Sock->Link); | ||||
|   NetListInit (&Sock->ConnectionList); | ||||
|   NetListInit (&Sock->ListenTokenList); | ||||
|   NetListInit (&Sock->RcvTokenList); | ||||
|  | ||||
| @ -330,6 +330,7 @@ struct _SOCKET { | ||||
|   EFI_HANDLE            DriverBinding;  // socket't driver binding protocol
 | ||||
|   EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath; | ||||
|   EFI_DEVICE_PATH_PROTOCOL  *DevicePath; | ||||
|   NET_LIST_ENTRY            Link;   | ||||
|   SOCK_CONFIGURE_STATE  ConfigureState; | ||||
|   SOCK_TYPE             Type; | ||||
|   SOCK_STATE            State; | ||||
|  | ||||
| @ -297,7 +297,7 @@ Tcp4DriverBindingStart ( | ||||
|       " resource to create an Ip Io!\n")); | ||||
| 
 | ||||
|     Status = EFI_OUT_OF_RESOURCES; | ||||
|     goto ReleaseServiceData; | ||||
|     goto ON_ERROR; | ||||
|   } | ||||
| 
 | ||||
|   //
 | ||||
| @ -312,7 +312,7 @@ Tcp4DriverBindingStart ( | ||||
|   Status                 = IpIoOpen (TcpServiceData->IpIo, &OpenData); | ||||
| 
 | ||||
|   if (EFI_ERROR (Status)) { | ||||
|       goto ReleaseServiceData; | ||||
|     goto ON_ERROR; | ||||
|   } | ||||
| 
 | ||||
|   //
 | ||||
| @ -324,7 +324,7 @@ Tcp4DriverBindingStart ( | ||||
|     TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Create TcpTimer" | ||||
|       " Event failed with %r\n", Status)); | ||||
| 
 | ||||
|     goto ReleaseIpIo; | ||||
|     goto ON_ERROR; | ||||
|   } | ||||
| 
 | ||||
|   //
 | ||||
| @ -344,7 +344,8 @@ Tcp4DriverBindingStart ( | ||||
|     TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Install Tcp4 Service Binding" | ||||
|       " Protocol failed for %r\n", Status)); | ||||
| 
 | ||||
|     goto ReleaseTimer; | ||||
|     Tcp4DestroyTimer (); | ||||
|     goto ON_ERROR; | ||||
|   } | ||||
| 
 | ||||
|   //
 | ||||
| @ -354,19 +355,17 @@ Tcp4DriverBindingStart ( | ||||
|   TcpServiceData->Signature           = TCP4_DRIVER_SIGNATURE; | ||||
|   TcpServiceData->DriverBindingHandle = This->DriverBindingHandle; | ||||
| 
 | ||||
|   NetListInit (&TcpServiceData->SocketList); | ||||
| 
 | ||||
|   TcpSetVariableData (TcpServiceData); | ||||
| 
 | ||||
|   return EFI_SUCCESS; | ||||
| 
 | ||||
| ReleaseTimer: | ||||
| ON_ERROR: | ||||
| 
 | ||||
|   Tcp4DestroyTimer (); | ||||
| 
 | ||||
| ReleaseIpIo: | ||||
| 
 | ||||
|   IpIoDestroy (TcpServiceData->IpIo); | ||||
| 
 | ||||
| ReleaseServiceData: | ||||
|   if (TcpServiceData->IpIo != NULL) { | ||||
|     IpIoDestroy (TcpServiceData->IpIo); | ||||
|   } | ||||
| 
 | ||||
|   NetFreePool (TcpServiceData); | ||||
| 
 | ||||
| @ -398,19 +397,15 @@ Tcp4DriverBindingStop ( | ||||
| { | ||||
|   EFI_STATUS                          Status; | ||||
|   EFI_HANDLE                          NicHandle; | ||||
|   EFI_SERVICE_BINDING_PROTOCOL        *Tcp4ServiceBinding; | ||||
|   EFI_SERVICE_BINDING_PROTOCOL        *ServiceBinding; | ||||
|   TCP4_SERVICE_DATA                   *TcpServiceData; | ||||
|   TCP_CB                              *TcpPcb; | ||||
|   SOCKET                              *Sock; | ||||
|   TCP4_PROTO_DATA                     *TcpProto; | ||||
|   NET_LIST_ENTRY                      *Entry; | ||||
|   NET_LIST_ENTRY                      *NextEntry; | ||||
| 
 | ||||
|   // Find the NicHandle where Tcp4 ServiceBinding Protocol is installed.
 | ||||
|   //
 | ||||
|   NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid); | ||||
|   if (NicHandle == NULL) { | ||||
|     return EFI_SUCCESS; | ||||
|     return EFI_DEVICE_ERROR; | ||||
|   } | ||||
| 
 | ||||
|   //
 | ||||
| @ -419,7 +414,7 @@ Tcp4DriverBindingStop ( | ||||
|   Status = gBS->OpenProtocol ( | ||||
|                   NicHandle, | ||||
|                   &gEfiTcp4ServiceBindingProtocolGuid, | ||||
|                   (VOID **) &Tcp4ServiceBinding, | ||||
|                   (VOID **) &ServiceBinding, | ||||
|                   This->DriverBindingHandle, | ||||
|                   ControllerHandle, | ||||
|                   EFI_OPEN_PROTOCOL_GET_PROTOCOL | ||||
| @ -429,95 +424,53 @@ Tcp4DriverBindingStop ( | ||||
|     TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Locate Tcp4 Service " | ||||
|       " Binding Protocol failed with %r\n", Status)); | ||||
| 
 | ||||
|     return Status; | ||||
|     return EFI_DEVICE_ERROR; | ||||
|   } | ||||
| 
 | ||||
|   TcpServiceData = TCP4_FROM_THIS (Tcp4ServiceBinding); | ||||
|   TcpServiceData = TCP4_FROM_THIS (ServiceBinding); | ||||
| 
 | ||||
|   //
 | ||||
|   // Kill TCP driver
 | ||||
|   //
 | ||||
|   NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &mTcpRunQue) { | ||||
|     TcpPcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List); | ||||
|   if (NumberOfChildren == 0) { | ||||
|     //
 | ||||
|     // Uninstall TCP servicebinding protocol
 | ||||
|     //
 | ||||
|     gBS->UninstallMultipleProtocolInterfaces ( | ||||
|            NicHandle, | ||||
|            &gEfiTcp4ServiceBindingProtocolGuid, | ||||
|            ServiceBinding, | ||||
|            NULL | ||||
|            ); | ||||
| 
 | ||||
|     //
 | ||||
|     // Try to destroy this child
 | ||||
|     // Destroy the IpIO consumed by TCP driver
 | ||||
|     //
 | ||||
|     Sock     = TcpPcb->Sk; | ||||
|     TcpProto = (TCP4_PROTO_DATA *) Sock->ProtoReserved; | ||||
|     IpIoDestroy (TcpServiceData->IpIo); | ||||
| 
 | ||||
|     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)); | ||||
|         return Status; | ||||
|       } | ||||
|     //
 | ||||
|     // Release the TCP service data
 | ||||
|     //
 | ||||
|     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; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|   Creates a child handle with a set of TCP4 services. | ||||
| 
 | ||||
| @ -608,9 +561,12 @@ Tcp4ServiceBindingCreateChild ( | ||||
|            Sock->SockHandle | ||||
|            ); | ||||
|     SockDestroyChild (Sock); | ||||
|   } else { | ||||
|     NetListInsertTail (&TcpServiceData->SocketList, &Sock->Link); | ||||
|   } | ||||
| 
 | ||||
| ON_EXIT: | ||||
| 
 | ||||
|   NET_RESTORE_TPL (OldTpl); | ||||
|   return Status; | ||||
| } | ||||
| @ -672,7 +628,9 @@ Tcp4ServiceBindingDestroyChild ( | ||||
|   TcpProtoData   = (TCP4_PROTO_DATA *) Sock->ProtoReserved; | ||||
|   TcpServiceData = TcpProtoData->TcpService; | ||||
| 
 | ||||
|   Status = SockDestroyChild (Sock); | ||||
|   NetListRemoveEntry (&Sock->Link); | ||||
| 
 | ||||
|   SockDestroyChild (Sock); | ||||
| 
 | ||||
|   //
 | ||||
|   // Close the device path protocol
 | ||||
|  | ||||
| @ -41,6 +41,7 @@ typedef struct _TCP4_SERVICE_DATA { | ||||
|   EFI_SERVICE_BINDING_PROTOCOL  Tcp4ServiceBinding; | ||||
|   EFI_HANDLE                    DriverBindingHandle; | ||||
|   CHAR16                        *MacString; | ||||
|   NET_LIST_ENTRY                SocketList; | ||||
| } TCP4_SERVICE_DATA; | ||||
| 
 | ||||
| //
 | ||||
|  | ||||
| @ -426,6 +426,7 @@ TcpCloneTcb ( | ||||
| { | ||||
|   TCP_CB               *Clone; | ||||
|   TCP4_SERVICE_DATA  *TcpService; | ||||
|   EFI_IP4_PROTOCOL   *Ip4; | ||||
| 
 | ||||
|   Clone = NetAllocatePool (sizeof (TCP_CB)); | ||||
| 
 | ||||
| @ -454,10 +455,13 @@ TcpCloneTcb ( | ||||
| 
 | ||||
|   ((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.
 | ||||
|   //
 | ||||
|   TcpService = ((TCP4_PROTO_DATA *) (Clone->Sk->ProtoReserved))->TcpService; | ||||
|   gBS->OpenProtocol ( | ||||
|          TcpService->ControllerHandle, | ||||
|          &gEfiDevicePathProtocolGuid, | ||||
| @ -467,6 +471,18 @@ TcpCloneTcb ( | ||||
|          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; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -123,7 +123,8 @@ Udp4DriverBindingStart ( | ||||
| 
 | ||||
|   Status = Udp4CreateService (Udp4Service, This->DriverBindingHandle, ControllerHandle); | ||||
|   if (EFI_ERROR (Status)) { | ||||
|     goto FREE_SERVICE; | ||||
|     NetFreePool (Udp4Service); | ||||
|     return Status; | ||||
|   } | ||||
| 
 | ||||
|   //
 | ||||
| @ -136,21 +137,12 @@ Udp4DriverBindingStart ( | ||||
|                   NULL | ||||
|                   ); | ||||
|   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; | ||||
| } | ||||
| 
 | ||||
| @ -188,7 +180,7 @@ Udp4DriverBindingStop ( | ||||
|   //
 | ||||
|   NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid); | ||||
|   if (NicHandle == NULL) { | ||||
|     return EFI_SUCCESS; | ||||
|     return EFI_DEVICE_ERROR; | ||||
|   } | ||||
| 
 | ||||
|   //
 | ||||
| @ -208,35 +200,30 @@ Udp4DriverBindingStop ( | ||||
| 
 | ||||
|   Udp4Service = UDP4_SERVICE_DATA_FROM_THIS (ServiceBinding); | ||||
| 
 | ||||
|   //
 | ||||
|   // Uninstall the UDP4 ServiceBinding Protocol.
 | ||||
|   //
 | ||||
|   Status = gBS->UninstallMultipleProtocolInterfaces ( | ||||
|                   NicHandle, | ||||
|                   &gEfiUdp4ServiceBindingProtocolGuid, | ||||
|                   &Udp4Service->ServiceBinding, | ||||
|                   NULL | ||||
|                   ); | ||||
|   if (EFI_ERROR (Status)) { | ||||
|     return EFI_DEVICE_ERROR; | ||||
|   if (NumberOfChildren == 0) { | ||||
| 
 | ||||
|     gBS->UninstallMultipleProtocolInterfaces ( | ||||
|            NicHandle, | ||||
|            &gEfiUdp4ServiceBindingProtocolGuid, | ||||
|            &Udp4Service->ServiceBinding, | ||||
|            NULL | ||||
|            ); | ||||
| 
 | ||||
|     Udp4ClearVariableData (Udp4Service); | ||||
| 
 | ||||
|     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)) { | ||||
|     //
 | ||||
|     // 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; | ||||
|   return Status; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| @ -277,7 +264,7 @@ Udp4ServiceBindingCreateChild ( | ||||
|   //
 | ||||
|   // Allocate the instance private data structure.
 | ||||
|   //
 | ||||
|   Instance = NetAllocatePool (sizeof (UDP4_INSTANCE_DATA)); | ||||
|   Instance = NetAllocateZeroPool (sizeof (UDP4_INSTANCE_DATA)); | ||||
|   if (Instance == NULL) { | ||||
|     return EFI_OUT_OF_RESOURCES; | ||||
|   } | ||||
| @ -290,7 +277,7 @@ Udp4ServiceBindingCreateChild ( | ||||
|   Instance->IpInfo = IpIoAddIp (Udp4Service->IpIo); | ||||
|   if (Instance->IpInfo == NULL) { | ||||
|     Status = EFI_OUT_OF_RESOURCES; | ||||
|     goto FREE_INSTANCE; | ||||
|     goto ON_ERROR; | ||||
|   } | ||||
| 
 | ||||
|   //
 | ||||
| @ -303,7 +290,7 @@ Udp4ServiceBindingCreateChild ( | ||||
|                   NULL | ||||
|                   ); | ||||
|   if (EFI_ERROR (Status)) { | ||||
|     goto REMOVE_IPINFO; | ||||
|     goto ON_ERROR; | ||||
|   } | ||||
| 
 | ||||
|   Instance->ChildHandle = *ChildHandle; | ||||
| @ -320,7 +307,7 @@ Udp4ServiceBindingCreateChild ( | ||||
|                   EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER | ||||
|                   ); | ||||
|   if (EFI_ERROR (Status)) { | ||||
|     goto UNINSTALL_PROTOCOL; | ||||
|     goto ON_ERROR; | ||||
|   } | ||||
| 
 | ||||
|   OldTpl = NET_RAISE_TPL (NET_TPL_LOCK); | ||||
| @ -333,22 +320,22 @@ Udp4ServiceBindingCreateChild ( | ||||
| 
 | ||||
|   NET_RESTORE_TPL (OldTpl); | ||||
| 
 | ||||
|   return Status; | ||||
|   return EFI_SUCCESS; | ||||
| 
 | ||||
| UNINSTALL_PROTOCOL: | ||||
| ON_ERROR: | ||||
| 
 | ||||
|   gBS->UninstallMultipleProtocolInterfaces ( | ||||
|          Instance->ChildHandle, | ||||
|          &gEfiUdp4ProtocolGuid, | ||||
|          &Instance->Udp4Proto, | ||||
|          NULL | ||||
|          ); | ||||
|   if (Instance->ChildHandle != NULL) { | ||||
|     gBS->UninstallMultipleProtocolInterfaces ( | ||||
|            Instance->ChildHandle, | ||||
|            &gEfiUdp4ProtocolGuid, | ||||
|            &Instance->Udp4Proto, | ||||
|            NULL | ||||
|            ); | ||||
|   } | ||||
| 
 | ||||
| REMOVE_IPINFO: | ||||
| 
 | ||||
|   IpIoRemoveIp (Udp4Service->IpIo, Instance->IpInfo); | ||||
| 
 | ||||
| FREE_INSTANCE: | ||||
|   if (Instance->IpInfo != NULL) { | ||||
|     IpIoRemoveIp (Udp4Service->IpIo, Instance->IpInfo); | ||||
|   } | ||||
| 
 | ||||
|   Udp4CleanInstance (Instance); | ||||
| 
 | ||||
|  | ||||
| @ -153,6 +153,8 @@ Udp4CreateService ( | ||||
|   EFI_STATUS       Status; | ||||
|   IP_IO_OPEN_DATA  OpenData; | ||||
| 
 | ||||
|   NetZeroMem (Udp4Service, sizeof (UDP4_SERVICE_DATA)); | ||||
| 
 | ||||
|   Udp4Service->Signature        = UDP4_SERVICE_DATA_SIGNATURE; | ||||
|   Udp4Service->ServiceBinding   = mUdp4ServiceBinding; | ||||
|   Udp4Service->ImageHandle      = ImageHandle; | ||||
| @ -184,7 +186,7 @@ Udp4CreateService ( | ||||
|   //
 | ||||
|   Status = IpIoOpen (Udp4Service->IpIo, &OpenData); | ||||
|   if (EFI_ERROR (Status)) { | ||||
|     goto RELEASE_IPIO; | ||||
|     goto ON_ERROR; | ||||
|   } | ||||
| 
 | ||||
|   //
 | ||||
| @ -198,7 +200,7 @@ Udp4CreateService ( | ||||
|                   &Udp4Service->TimeoutEvent | ||||
|                   ); | ||||
|   if (EFI_ERROR (Status)) { | ||||
|     goto RELEASE_IPIO; | ||||
|     goto ON_ERROR; | ||||
|   } | ||||
| 
 | ||||
|   //
 | ||||
| @ -210,18 +212,16 @@ Udp4CreateService ( | ||||
|                   UDP4_TIMEOUT_INTERVAL | ||||
|                   ); | ||||
|   if (EFI_ERROR (Status)) { | ||||
|     goto RELEASE_ALL; | ||||
|     goto ON_ERROR; | ||||
|   } | ||||
| 
 | ||||
|   Udp4Service->MacString = NULL; | ||||
| 
 | ||||
|   return EFI_SUCCESS; | ||||
| 
 | ||||
| RELEASE_ALL: | ||||
| ON_ERROR: | ||||
| 
 | ||||
|   gBS->CloseEvent (Udp4Service->TimeoutEvent); | ||||
| 
 | ||||
| RELEASE_IPIO: | ||||
|   if (Udp4Service->TimeoutEvent != NULL) { | ||||
|     gBS->CloseEvent (Udp4Service->TimeoutEvent); | ||||
|   } | ||||
| 
 | ||||
|   IpIoDestroy (Udp4Service->IpIo); | ||||
| 
 | ||||
|  | ||||
| @ -291,7 +291,7 @@ Udp4Configure ( | ||||
|     //
 | ||||
|     Udp4FlushRcvdDgram (Instance); | ||||
| 
 | ||||
| ////bugbug    ASSERT (NetListIsEmpty (&Instance->DeliveredDgramQue));
 | ||||
|     ASSERT (NetListIsEmpty (&Instance->DeliveredDgramQue)); | ||||
|   } | ||||
| 
 | ||||
|   Udp4SetVariableData (Instance->Udp4Service); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user