]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c
Add 'file not found' debug message to MTFTP.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Mtftp4Dxe / Mtftp4Impl.c
index 34c5aeaa7ffac94b0633dd4f5482070e74d825ab..03b7f28171a3e5befa9049ec1f9b7c97f141d401 100644 (file)
@@ -1,8 +1,8 @@
 /** @file\r
   Interface routine for Mtftp4.\r
   \r
-Copyright (c) 2006 - 2007, Intel Corporation<BR>\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r
+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
 http://opensource.org/licenses/bsd-license.php<BR>\r
@@ -16,50 +16,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include "Mtftp4Impl.h"\r
 \r
 \r
-/**\r
-  Reads the current operational settings.\r
-\r
-  The GetModeData()function reads the current operational settings of this \r
-  EFI MTFTPv4 Protocol driver instance.\r
-\r
-  @param  This                   Pointer to the EFI_MTFTP4_PROTOCOL instance.\r
-  @param  ModeData               Pointer to storage for the EFI MTFTPv4 Protocol\r
-                                 driver mode data. \r
-\r
-  @retval EFI_SUCCESS            The configuration data was successfully returned.\r
-  @retval EFI_OUT_OF_RESOURCES   The required mode data could not be allocated.\r
-  @retval EFI_INVALID_PARAMETER  This is NULL or ModeData is NULL.\r
-  \r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EfiMtftp4GetModeData (\r
-  IN     EFI_MTFTP4_PROTOCOL    *This,\r
-     OUT EFI_MTFTP4_MODE_DATA  *ModeData\r
-  )\r
-{\r
-  MTFTP4_PROTOCOL  *Instance;\r
-  EFI_TPL          OldTpl;\r
-\r
-  if ((This == NULL) || (ModeData == NULL)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
-  Instance                         = MTFTP4_PROTOCOL_FROM_THIS (This);\r
-  CopyMem(&ModeData->ConfigData, &Instance->Config, sizeof (Instance->Config));\r
-  ModeData->SupportedOptionCount   = MTFTP4_SUPPORTED_OPTIONS;\r
-  ModeData->SupportedOptoins       = (UINT8 **) mMtftp4SupportedOptions;\r
-  ModeData->UnsupportedOptionCount = 0;\r
-  ModeData->UnsupportedOptoins     = NULL;\r
-\r
-  gBS->RestoreTPL (OldTpl);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
 /**\r
   Clean up the MTFTP session to get ready for new operation.\r
 \r
@@ -94,7 +50,7 @@ Mtftp4CleanOperation (
   }\r
 \r
   ASSERT (Instance->UnicastPort != NULL);\r
-  UdpIoCleanPort (Instance->UnicastPort);\r
+  UdpIoCleanIo (Instance->UnicastPort);\r
 \r
   if (Instance->LastPacket != NULL) {\r
     NetbufFree (Instance->LastPacket);\r
@@ -102,14 +58,20 @@ Mtftp4CleanOperation (
   }\r
 \r
   if (Instance->McastUdpPort != NULL) {\r
-    UdpIoFreePort (Instance->McastUdpPort);\r
+    gBS->CloseProtocol (\r
+           Instance->McastUdpPort->UdpHandle,\r
+           &gEfiUdp4ProtocolGuid,\r
+           gMtftp4DriverBinding.DriverBindingHandle,\r
+           Instance->Handle\r
+           );\r
+    UdpIoFreeIo (Instance->McastUdpPort);\r
     Instance->McastUdpPort = NULL;\r
   }\r
 \r
   NET_LIST_FOR_EACH_SAFE (Entry, Next, &Instance->Blocks) {\r
     Block = NET_LIST_USER_STRUCT (Entry, MTFTP4_BLOCK_RANGE, Link);\r
     RemoveEntryList (Entry);\r
-    gBS->FreePool (Block);\r
+    FreePool (Block);\r
   }\r
 \r
   ZeroMem (&Instance->RequestOption, sizeof (MTFTP4_OPTION));\r
@@ -132,132 +94,6 @@ Mtftp4CleanOperation (
 }\r
 \r
 \r
-/**\r
-  Initializes, changes, or resets the default operational setting for this \r
-  EFI MTFTPv4 Protocol driver instance.\r
-  \r
-  The Configure() function is used to set and change the configuration data for \r
-  this EFI MTFTPv4 Protocol driver instance. The configuration data can be reset \r
-  to startup defaults by calling Configure() with MtftpConfigData set to NULL. \r
-  Whenever the instance is reset, any pending operation is aborted. By changing \r
-  the EFI MTFTPv4 Protocol driver instance configuration data, the client can \r
-  connect to different MTFTPv4 servers. The configuration parameters in \r
-  MtftpConfigData are used as the default parameters in later MTFTPv4 operations \r
-  and can be overridden in later operations.\r
-  \r
-  @param  This                   Pointer to the EFI_MTFTP4_PROTOCOL instance\r
-  @param  ConfigData             MtftpConfigDataPointer to the configuration data \r
-                                 structure\r
-\r
-  @retval EFI_SUCCESS            The EFI MTFTPv4 Protocol driver was configured \r
-                                 successfully.\r
-  @retval EFI_INVALID_PARAMETER  One or more following conditions are TRUE:\r
-                                 1.This is NULL.\r
-                                 2.MtftpConfigData.UseDefaultSetting is FALSE and \r
-                                   MtftpConfigData.StationIp is not a valid IPv4 \r
-                                   unicast address.\r
-                                 3.MtftpCofigData.UseDefaultSetting is FALSE and \r
-                                   MtftpConfigData.SubnetMask is invalid.\r
-                                 4.MtftpCofigData.ServerIp is not a valid IPv4 \r
-                                   unicast address.\r
-                                 5.MtftpConfigData.UseDefaultSetting is FALSE and \r
-                                   MtftpConfigData.GatewayIp is not a valid IPv4 \r
-                                   unicast address or is not in the same subnet \r
-                                   with station address.\r
-  @retval EFI_ACCESS_DENIED      The EFI configuration could not be changed at this \r
-                                 time because there is one MTFTP background operation \r
-                                 in progress.\r
-  @retval EFI_NO_MAPPING         When using a default address, configuration \r
-                                 (DHCP, BOOTP, RARP, etc.) has not finished yet.\r
-  @retval EFI_UNSUPPORTED        A configuration protocol (DHCP, BOOTP, RARP, etc.) \r
-                                 could not be located when clients choose to use \r
-                                 the default address settings.\r
-  @retval EFI_OUT_OF_RESOURCES   The EFI MTFTPv4 Protocol driver instance data could \r
-                                 not be allocated.\r
-  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred. \r
-                                 The EFI MTFTPv4 Protocol driver instance is not \r
-                                 configured.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EfiMtftp4Configure (\r
-  IN EFI_MTFTP4_PROTOCOL    *This,\r
-  IN EFI_MTFTP4_CONFIG_DATA *ConfigData\r
-  )\r
-{\r
-  MTFTP4_PROTOCOL           *Instance;\r
-  EFI_TPL                   OldTpl;\r
-  IP4_ADDR                  Ip;\r
-  IP4_ADDR                  Netmask;\r
-  IP4_ADDR                  Gateway;\r
-  IP4_ADDR                  ServerIp;\r
-\r
-  if (This == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Instance = MTFTP4_PROTOCOL_FROM_THIS (This);\r
-\r
-  if (ConfigData == NULL) {\r
-    //\r
-    // Reset the operation if ConfigData is NULL\r
-    //\r
-    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
-    Mtftp4CleanOperation (Instance, EFI_ABORTED);\r
-    ZeroMem (&Instance->Config, sizeof (EFI_MTFTP4_CONFIG_DATA));\r
-    Instance->State = MTFTP4_STATE_UNCONFIGED;\r
-\r
-    gBS->RestoreTPL (OldTpl);\r
-\r
-  } else {\r
-    //\r
-    // Configure the parameters for new operation.\r
-    //\r
-    CopyMem (&Ip, &ConfigData->StationIp, sizeof (IP4_ADDR));\r
-    CopyMem (&Netmask, &ConfigData->SubnetMask, sizeof (IP4_ADDR));\r
-    CopyMem (&Gateway, &ConfigData->GatewayIp, sizeof (IP4_ADDR));\r
-    CopyMem (&ServerIp, &ConfigData->ServerIp, sizeof (IP4_ADDR));\r
-\r
-    Ip       = NTOHL (Ip);\r
-    Netmask  = NTOHL (Netmask);\r
-    Gateway  = NTOHL (Gateway);\r
-    ServerIp = NTOHL (ServerIp);\r
-\r
-    if (!Ip4IsUnicast (ServerIp, 0)) {\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-\r
-    if (!ConfigData->UseDefaultSetting &&\r
-       ((!IP4_IS_VALID_NETMASK (Netmask) || !Ip4IsUnicast (Ip, Netmask)))) {\r
-\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-\r
-    if ((Gateway != 0) &&\r
-        (!IP4_NET_EQUAL (Gateway, Ip, Netmask) || !Ip4IsUnicast (Gateway, Netmask))) {\r
-\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-\r
-    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
-    if ((Instance->State == MTFTP4_STATE_CONFIGED) && (Instance->Operation != 0)) {\r
-      gBS->RestoreTPL (OldTpl);\r
-      return EFI_ACCESS_DENIED;\r
-    }\r
-\r
-    CopyMem(&Instance->Config, ConfigData, sizeof (*ConfigData));;\r
-    Instance->State = MTFTP4_STATE_CONFIGED;\r
-\r
-    gBS->RestoreTPL (OldTpl);\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
 /**\r
   Check packet for GetInfo. \r
   \r
@@ -273,6 +109,7 @@ EfiMtftp4Configure (
 \r
 **/\r
 EFI_STATUS\r
+EFIAPI\r
 Mtftp4GetInfoCheckPacket (\r
   IN EFI_MTFTP4_PROTOCOL    *This,\r
   IN EFI_MTFTP4_TOKEN       *Token,\r
@@ -280,13 +117,12 @@ Mtftp4GetInfoCheckPacket (
   IN EFI_MTFTP4_PACKET      *Packet\r
   )\r
 {\r
-  MTFTP4_PROTOCOL           *Instance;\r
   MTFTP4_GETINFO_STATE      *State;\r
   EFI_STATUS                Status;\r
   UINT16                    OpCode;\r
+  EFI_MTFTP4_ERROR_HEADER  *ErrorHeader;\r
 \r
-  Instance = MTFTP4_PROTOCOL_FROM_THIS (This);\r
-  State    = &Instance->GetInfoState;\r
+  State   = (MTFTP4_GETINFO_STATE *) Token->Context;\r
   OpCode   = NTOHS (Packet->OpCode);\r
 \r
   //\r
@@ -294,6 +130,12 @@ Mtftp4GetInfoCheckPacket (
   //\r
   switch (OpCode) {\r
   case EFI_MTFTP4_OPCODE_ERROR:\r
+    ErrorHeader = (EFI_MTFTP4_ERROR_HEADER *) Packet;\r
+    if (ErrorHeader->ErrorCode == EFI_MTFTP4_ERRORCODE_FILE_NOT_FOUND) {\r
+      DEBUG ((EFI_D_ERROR, "TFTP error code 1 (File Not Found)\n"));\r
+    } else {\r
+      DEBUG ((EFI_D_ERROR, "TFTP error code %d\n", ErrorHeader->ErrorCode));\r
+    }\r
     State->Status = EFI_TFTP_ERROR;\r
     break;\r
 \r
@@ -323,68 +165,6 @@ Mtftp4GetInfoCheckPacket (
 }\r
 \r
 \r
-/**\r
-  Parses the options in an MTFTPv4 OACK packet.\r
-  \r
-  The ParseOptions() function parses the option fields in an MTFTPv4 OACK packet \r
-  and returns the number of options that were found and optionally a list of \r
-  pointers to the options in the packet.\r
-  If one or more of the option fields are not valid, then EFI_PROTOCOL_ERROR is \r
-  returned and *OptionCount and *OptionList stop at the last valid option.\r
-  The OptionList is allocated by this function, and caller should free it when used.\r
-\r
-  @param  This                   Pointer to the EFI_MTFTP4_PROTOCOL instance.\r
-  @param  PacketLen              Length of the OACK packet to be parsed.\r
-  @param  Packet                 Pointer to the OACK packet to be parsed. \r
-  @param  OptionCount            Pointer to the number of options in following OptionList.\r
-  @param  OptionList             Pointer to EFI_MTFTP4_OPTION storage. Call the \r
-                                 EFI Boot Service FreePool() to release theOptionList\r
-                                 if the options in this OptionList are not needed \r
-                                 any more\r
-\r
-  @retval EFI_SUCCESS            The OACK packet was valid and the OptionCount and\r
-                                 OptionList parameters have been updated.\r
-  @retval EFI_INVALID_PARAMETER  One or more of the following conditions is TRUE:\r
-                                 1.PacketLen is 0.\r
-                                 2.Packet is NULL or Packet is not a valid MTFTPv4 packet.\r
-                                 3.OptionCount is NULL.\r
-  @retval EFI_NOT_FOUND          No options were found in the OACK packet.\r
-  @retval EFI_OUT_OF_RESOURCES   Storage for the OptionList array cannot be allocated.\r
-  @retval EFI_PROTOCOL_ERROR     One or more of the option fields is invalid.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EfiMtftp4ParseOptions (\r
-  IN     EFI_MTFTP4_PROTOCOL    *This,\r
-  IN     UINT32                 PacketLen,\r
-  IN     EFI_MTFTP4_PACKET      *Packet,\r
-     OUT UINT32                 *OptionCount,\r
-     OUT EFI_MTFTP4_OPTION      **OptionList          OPTIONAL\r
-  )\r
-{\r
-  EFI_STATUS                Status;\r
-\r
-  if ((This == NULL) || (PacketLen < MTFTP4_OPCODE_LEN) ||\r
-      (Packet == NULL) || (OptionCount == NULL)) {\r
-\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Status = Mtftp4ExtractOptions (Packet, PacketLen, OptionCount, OptionList);\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  if (*OptionCount == 0) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
 /**\r
   Check whether the override data is valid. \r
   \r
@@ -411,7 +191,7 @@ Mtftp4OverrideValid (
   IP4_ADDR                  Gateway;\r
 \r
   CopyMem (&Ip, &Override->ServerIp, sizeof (IP4_ADDR));\r
-  if (!Ip4IsUnicast (NTOHL (Ip), 0)) {\r
+  if (!NetIp4IsUnicast (NTOHL (Ip), 0)) {\r
     return FALSE;\r
   }\r
 \r
@@ -427,7 +207,7 @@ Mtftp4OverrideValid (
     Netmask = NTOHL (Netmask);\r
     Ip      = NTOHL (Ip);\r
 \r
-    if (!Ip4IsUnicast (Gateway, Netmask) || !IP4_NET_EQUAL (Gateway, Ip, Netmask)) {\r
+    if (!NetIp4IsUnicast (Gateway, Netmask) || !IP4_NET_EQUAL (Gateway, Ip, Netmask)) {\r
       return FALSE;\r
     }\r
   }\r
@@ -444,9 +224,8 @@ Mtftp4OverrideValid (
   the UDP is reconfigured.\r
 \r
   @param  Instance               The Mtftp instance\r
-  @param  UdpPort                The UDP port to poll\r
-  @param  UdpCfgData             The UDP configure data to reconfigure the UDP\r
-                                 port.\r
+  @param  UdpIo                  The UDP_IO to poll\r
+  @param  UdpCfgData             The UDP configure data to reconfigure the UDP_IO\r
 \r
   @retval TRUE                   The default address is retrieved and UDP is reconfigured.\r
   @retval FALSE                  Some error occured.\r
@@ -455,7 +234,7 @@ Mtftp4OverrideValid (
 BOOLEAN\r
 Mtftp4GetMapping (\r
   IN MTFTP4_PROTOCOL        *Instance,\r
-  IN UDP_IO_PORT            *UdpPort,\r
+  IN UDP_IO                 *UdpIo,\r
   IN EFI_UDP4_CONFIG_DATA   *UdpCfgData\r
   )\r
 {\r
@@ -467,7 +246,7 @@ Mtftp4GetMapping (
   ASSERT (Instance->Config.UseDefaultSetting);\r
 \r
   Service = Instance->Service;\r
-  Udp     = UdpPort->Udp;\r
+  Udp     = UdpIo->Protocol.Udp4;\r
 \r
   Status = gBS->SetTimer (\r
                   Service->TimerToGetMap,\r
@@ -496,7 +275,7 @@ Mtftp4GetMapping (
 /**\r
   Configure the UDP port for unicast receiving.\r
 \r
-  @param  UdpIo                  The UDP port\r
+  @param  UdpIo                  The UDP_IO instance\r
   @param  Instance               The MTFTP session\r
 \r
   @retval EFI_SUCCESS            The UDP port is successfully configured for the\r
@@ -505,7 +284,7 @@ Mtftp4GetMapping (
 **/\r
 EFI_STATUS\r
 Mtftp4ConfigUnicastPort (\r
-  IN UDP_IO_PORT            *UdpIo,\r
+  IN UDP_IO                 *UdpIo,\r
   IN MTFTP4_PROTOCOL        *Instance\r
   )\r
 {\r
@@ -534,7 +313,7 @@ Mtftp4ConfigUnicastPort (
   Ip = HTONL (Instance->ServerIp);\r
   CopyMem (&UdpConfig.RemoteAddress, &Ip, sizeof (EFI_IPv4_ADDRESS));\r
 \r
-  Status = UdpIo->Udp->Configure (UdpIo->Udp, &UdpConfig);\r
+  Status = UdpIo->Protocol.Udp4->Configure (UdpIo->Protocol.Udp4, &UdpConfig);\r
 \r
   if ((Status == EFI_NO_MAPPING) && Mtftp4GetMapping (Instance, UdpIo, &UdpConfig)) {\r
     return EFI_SUCCESS;\r
@@ -545,9 +324,15 @@ Mtftp4ConfigUnicastPort (
     // 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
+    Status = UdpIo->Protocol.Udp4->Routes (\r
+                                     UdpIo->Protocol.Udp4,\r
+                                     FALSE,\r
+                                     &mZeroIp4Addr,\r
+                                     &mZeroIp4Addr,\r
+                                     &Config->GatewayIp\r
+                                     );\r
     if (EFI_ERROR (Status)) {\r
-      UdpIo->Udp->Configure (UdpIo->Udp, NULL);\r
+      UdpIo->Protocol.Udp4->Configure (UdpIo->Protocol.Udp4, NULL);\r
     }\r
   }\r
   return Status;\r
@@ -743,6 +528,240 @@ ON_ERROR:
 }\r
 \r
 \r
+/**\r
+  Reads the current operational settings.\r
+\r
+  The GetModeData()function reads the current operational settings of this \r
+  EFI MTFTPv4 Protocol driver instance.\r
+\r
+  @param  This                   Pointer to the EFI_MTFTP4_PROTOCOL instance.\r
+  @param  ModeData               Pointer to storage for the EFI MTFTPv4 Protocol\r
+                                 driver mode data. \r
+\r
+  @retval EFI_SUCCESS            The configuration data was successfully returned.\r
+  @retval EFI_OUT_OF_RESOURCES   The required mode data could not be allocated.\r
+  @retval EFI_INVALID_PARAMETER  This is NULL or ModeData is NULL.\r
+  \r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EfiMtftp4GetModeData (\r
+  IN     EFI_MTFTP4_PROTOCOL    *This,\r
+     OUT EFI_MTFTP4_MODE_DATA  *ModeData\r
+  )\r
+{\r
+  MTFTP4_PROTOCOL  *Instance;\r
+  EFI_TPL          OldTpl;\r
+\r
+  if ((This == NULL) || (ModeData == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+  Instance                         = MTFTP4_PROTOCOL_FROM_THIS (This);\r
+  CopyMem(&ModeData->ConfigData, &Instance->Config, sizeof (Instance->Config));\r
+  ModeData->SupportedOptionCount   = MTFTP4_SUPPORTED_OPTIONS;\r
+  ModeData->SupportedOptoins       = (UINT8 **) mMtftp4SupportedOptions;\r
+  ModeData->UnsupportedOptionCount = 0;\r
+  ModeData->UnsupportedOptoins     = NULL;\r
+\r
+  gBS->RestoreTPL (OldTpl);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+/**\r
+  Initializes, changes, or resets the default operational setting for this \r
+  EFI MTFTPv4 Protocol driver instance.\r
+  \r
+  The Configure() function is used to set and change the configuration data for \r
+  this EFI MTFTPv4 Protocol driver instance. The configuration data can be reset \r
+  to startup defaults by calling Configure() with MtftpConfigData set to NULL. \r
+  Whenever the instance is reset, any pending operation is aborted. By changing \r
+  the EFI MTFTPv4 Protocol driver instance configuration data, the client can \r
+  connect to different MTFTPv4 servers. The configuration parameters in \r
+  MtftpConfigData are used as the default parameters in later MTFTPv4 operations \r
+  and can be overridden in later operations.\r
+  \r
+  @param  This                   Pointer to the EFI_MTFTP4_PROTOCOL instance\r
+  @param  ConfigData             MtftpConfigDataPointer to the configuration data \r
+                                 structure\r
+\r
+  @retval EFI_SUCCESS            The EFI MTFTPv4 Protocol driver was configured \r
+                                 successfully.\r
+  @retval EFI_INVALID_PARAMETER  One or more following conditions are TRUE:\r
+                                 1.This is NULL.\r
+                                 2.MtftpConfigData.UseDefaultSetting is FALSE and \r
+                                   MtftpConfigData.StationIp is not a valid IPv4 \r
+                                   unicast address.\r
+                                 3.MtftpCofigData.UseDefaultSetting is FALSE and \r
+                                   MtftpConfigData.SubnetMask is invalid.\r
+                                 4.MtftpCofigData.ServerIp is not a valid IPv4 \r
+                                   unicast address.\r
+                                 5.MtftpConfigData.UseDefaultSetting is FALSE and \r
+                                   MtftpConfigData.GatewayIp is not a valid IPv4 \r
+                                   unicast address or is not in the same subnet \r
+                                   with station address.\r
+  @retval EFI_ACCESS_DENIED      The EFI configuration could not be changed at this \r
+                                 time because there is one MTFTP background operation \r
+                                 in progress.\r
+  @retval EFI_NO_MAPPING         When using a default address, configuration \r
+                                 (DHCP, BOOTP, RARP, etc.) has not finished yet.\r
+  @retval EFI_UNSUPPORTED        A configuration protocol (DHCP, BOOTP, RARP, etc.) \r
+                                 could not be located when clients choose to use \r
+                                 the default address settings.\r
+  @retval EFI_OUT_OF_RESOURCES   The EFI MTFTPv4 Protocol driver instance data could \r
+                                 not be allocated.\r
+  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred. \r
+                                 The EFI MTFTPv4 Protocol driver instance is not \r
+                                 configured.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EfiMtftp4Configure (\r
+  IN EFI_MTFTP4_PROTOCOL    *This,\r
+  IN EFI_MTFTP4_CONFIG_DATA *ConfigData\r
+  )\r
+{\r
+  MTFTP4_PROTOCOL           *Instance;\r
+  EFI_TPL                   OldTpl;\r
+  IP4_ADDR                  Ip;\r
+  IP4_ADDR                  Netmask;\r
+  IP4_ADDR                  Gateway;\r
+  IP4_ADDR                  ServerIp;\r
+\r
+  if (This == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Instance = MTFTP4_PROTOCOL_FROM_THIS (This);\r
+\r
+  if (ConfigData == NULL) {\r
+    //\r
+    // Reset the operation if ConfigData is NULL\r
+    //\r
+    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+    Mtftp4CleanOperation (Instance, EFI_ABORTED);\r
+    ZeroMem (&Instance->Config, sizeof (EFI_MTFTP4_CONFIG_DATA));\r
+    Instance->State = MTFTP4_STATE_UNCONFIGED;\r
+\r
+    gBS->RestoreTPL (OldTpl);\r
+\r
+  } else {\r
+    //\r
+    // Configure the parameters for new operation.\r
+    //\r
+    CopyMem (&Ip, &ConfigData->StationIp, sizeof (IP4_ADDR));\r
+    CopyMem (&Netmask, &ConfigData->SubnetMask, sizeof (IP4_ADDR));\r
+    CopyMem (&Gateway, &ConfigData->GatewayIp, sizeof (IP4_ADDR));\r
+    CopyMem (&ServerIp, &ConfigData->ServerIp, sizeof (IP4_ADDR));\r
+\r
+    Ip       = NTOHL (Ip);\r
+    Netmask  = NTOHL (Netmask);\r
+    Gateway  = NTOHL (Gateway);\r
+    ServerIp = NTOHL (ServerIp);\r
+\r
+    if (!NetIp4IsUnicast (ServerIp, 0)) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    if (!ConfigData->UseDefaultSetting &&\r
+       ((!IP4_IS_VALID_NETMASK (Netmask) || !NetIp4IsUnicast (Ip, Netmask)))) {\r
+\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    if ((Gateway != 0) &&\r
+        (!IP4_NET_EQUAL (Gateway, Ip, Netmask) || !NetIp4IsUnicast (Gateway, Netmask))) {\r
+\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+    if ((Instance->State == MTFTP4_STATE_CONFIGED) && (Instance->Operation != 0)) {\r
+      gBS->RestoreTPL (OldTpl);\r
+      return EFI_ACCESS_DENIED;\r
+    }\r
+\r
+    CopyMem(&Instance->Config, ConfigData, sizeof (*ConfigData));;\r
+    Instance->State = MTFTP4_STATE_CONFIGED;\r
+\r
+    gBS->RestoreTPL (OldTpl);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+/**\r
+  Parses the options in an MTFTPv4 OACK packet.\r
+  \r
+  The ParseOptions() function parses the option fields in an MTFTPv4 OACK packet \r
+  and returns the number of options that were found and optionally a list of \r
+  pointers to the options in the packet.\r
+  If one or more of the option fields are not valid, then EFI_PROTOCOL_ERROR is \r
+  returned and *OptionCount and *OptionList stop at the last valid option.\r
+  The OptionList is allocated by this function, and caller should free it when used.\r
+\r
+  @param  This                   Pointer to the EFI_MTFTP4_PROTOCOL instance.\r
+  @param  PacketLen              Length of the OACK packet to be parsed.\r
+  @param  Packet                 Pointer to the OACK packet to be parsed. \r
+  @param  OptionCount            Pointer to the number of options in following OptionList.\r
+  @param  OptionList             Pointer to EFI_MTFTP4_OPTION storage. Call the \r
+                                 EFI Boot Service FreePool() to release theOptionList\r
+                                 if the options in this OptionList are not needed \r
+                                 any more\r
+\r
+  @retval EFI_SUCCESS            The OACK packet was valid and the OptionCount and\r
+                                 OptionList parameters have been updated.\r
+  @retval EFI_INVALID_PARAMETER  One or more of the following conditions is TRUE:\r
+                                 1.PacketLen is 0.\r
+                                 2.Packet is NULL or Packet is not a valid MTFTPv4 packet.\r
+                                 3.OptionCount is NULL.\r
+  @retval EFI_NOT_FOUND          No options were found in the OACK packet.\r
+  @retval EFI_OUT_OF_RESOURCES   Storage for the OptionList array cannot be allocated.\r
+  @retval EFI_PROTOCOL_ERROR     One or more of the option fields is invalid.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EfiMtftp4ParseOptions (\r
+  IN     EFI_MTFTP4_PROTOCOL    *This,\r
+  IN     UINT32                 PacketLen,\r
+  IN     EFI_MTFTP4_PACKET      *Packet,\r
+     OUT UINT32                 *OptionCount,\r
+     OUT EFI_MTFTP4_OPTION      **OptionList          OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+\r
+  if ((This == NULL) || (PacketLen < MTFTP4_OPCODE_LEN) ||\r
+      (Packet == NULL) || (OptionCount == NULL)) {\r
+\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = Mtftp4ExtractOptions (Packet, PacketLen, OptionCount, OptionList);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  if (*OptionCount == 0) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
 /**\r
   Downloads a file from an MTFTPv4 server.\r
   \r
@@ -770,6 +789,7 @@ ON_ERROR:
   @retval EFI_TIMEOUT           No responses were received from the MTFTPv4 server.\r
   @retval EFI_TFTP_ERROR        An MTFTPv4 ERROR packet was received.\r
   @retval EFI_DEVICE_ERROR      An unexpected network error or system error occurred.\r
+  @retval EFI_NO_MEDIA          There was a media error.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -929,8 +949,8 @@ EfiMtftp4ReadDirectory (
                                  parameters. If NULL, the default parameters that \r
                                  were set in the EFI_MTFTP4_PROTOCOL.Configure() \r
                                  function are used\r
-  @param  Filename               Pointer to ASCIIZ file name string\r
-  @param  ModeStr                Pointer to ASCIIZ mode string. If NULL, "octet" \r
+  @param  Filename               Pointer to null-terminated ASCII file name string\r
+  @param  ModeStr                Pointer to null-terminated ASCII mode string. If NULL, "octet" \r
                                  will be used\r
   @param  OptionCount            Number of option/value string pairs in OptionList\r
   @param  OptionList             Pointer to array of option/value string pairs. \r
@@ -965,7 +985,8 @@ EfiMtftp4ReadDirectory (
                                  in the Buffer.\r
   @retval EFI_TIMEOUT            No responses were received from the MTFTPv4 server.\r
   @retval EFI_DEVICE_ERROR       An unexpected network error or system error occurred.\r
-  \r
+  @retval EFI_NO_MEDIA           There was a media error.\r
+\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -981,8 +1002,7 @@ EfiMtftp4GetInfo (
   )\r
 {\r
   EFI_MTFTP4_TOKEN          Token;\r
-  MTFTP4_PROTOCOL           *Instance;\r
-  MTFTP4_GETINFO_STATE      *State;\r
+  MTFTP4_GETINFO_STATE      State;\r
   EFI_STATUS                Status;\r
 \r
   if ((This == NULL) || (Filename == NULL) || (PacketLength == NULL) ||\r
@@ -995,11 +1015,9 @@ EfiMtftp4GetInfo (
   }\r
 \r
   *PacketLength         = 0;\r
-  Instance              = MTFTP4_PROTOCOL_FROM_THIS (This);\r
-  State                 = &Instance->GetInfoState;\r
-  State->Packet         = Packet;\r
-  State->PacketLen      = PacketLength;\r
-  State->Status         = EFI_SUCCESS;\r
+  State.Packet          = Packet;\r
+  State.PacketLen       = PacketLength;\r
+  State.Status          = EFI_SUCCESS;\r
 \r
   //\r
   // Fill in the Token to issue an synchronous ReadFile operation\r
@@ -1013,6 +1031,7 @@ EfiMtftp4GetInfo (
   Token.OptionList      = OptionList;\r
   Token.BufferSize      = 0;\r
   Token.Buffer          = NULL;\r
+  Token.Context         = &State;\r
   Token.CheckPacket     = Mtftp4GetInfoCheckPacket;\r
   Token.TimeoutCallback = NULL;\r
   Token.PacketNeeded    = NULL;\r
@@ -1020,7 +1039,7 @@ EfiMtftp4GetInfo (
   Status                = EfiMtftp4ReadFile (This, &Token);\r
 \r
   if (EFI_ABORTED == Status) {\r
-    return State->Status;\r
+    return State.Status;\r
   }\r
 \r
   return Status;\r
@@ -1067,11 +1086,11 @@ EfiMtftp4Poll (
 \r
   if (Instance->State == MTFTP4_STATE_UNCONFIGED) {\r
     return EFI_NOT_STARTED;\r
-  } else if (Instance->State == MTFTP4_STATE_DESTORY) {\r
+  } else if (Instance->State == MTFTP4_STATE_DESTROY) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
-  Udp = Instance->UnicastPort->Udp;\r
+  Udp = Instance->UnicastPort->Protocol.Udp4;\r
   return Udp->Poll (Udp);\r
 }\r
 \r