]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/IScsiDxe/IScsiProto.c
NetworkPkg IScsiDxe: Fix build error for lastest VS2015 compiler
[mirror_edk2.git] / NetworkPkg / IScsiDxe / IScsiProto.c
index 72c90a7fe8c997550a639318810964e187b8b1eb..50923654644194d77b2bc8cc77ea39d660dbc457 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   The implementation of iSCSI protocol based on RFC3720.\r
 \r
-Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2016, 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
@@ -138,7 +138,11 @@ IScsiConnLogin (
   //\r
   // Start the timer, and wait Timeout seconds to establish the TCP connection.\r
   //\r
-  Status = gBS->SetTimer (Conn->TimeoutEvent, TimerRelative, Timeout * TICKS_PER_MS);\r
+  Status = gBS->SetTimer (\r
+                  Conn->TimeoutEvent,\r
+                  TimerRelative,\r
+                  MultU64x32 (Timeout, TICKS_PER_MS)\r
+                  );\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
@@ -228,7 +232,7 @@ IScsiCreateConnection (
   Conn->PartialRspRcvd  = FALSE;\r
   Conn->ParamNegotiated = FALSE;\r
   Conn->Cid             = Session->NextCid++;\r
-  Conn->Ipv6Flag        = mPrivate->Ipv6Flag;\r
+  Conn->Ipv6Flag        = NvData->IpMode == IP_MODE_IP6 || Session->ConfigData->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP6;\r
 \r
   Status = gBS->CreateEvent (\r
                   EVT_TIMER,\r
@@ -259,15 +263,16 @@ IScsiCreateConnection (
     CopyMem (&Tcp4IoConfig->Gateway, &NvData->Gateway, sizeof (EFI_IPv4_ADDRESS));\r
     CopyMem (&Tcp4IoConfig->RemoteIp, &NvData->TargetIp, sizeof (EFI_IPv4_ADDRESS));\r
 \r
-    Tcp4IoConfig->RemotePort = NvData->TargetPort;\r
-    Tcp4IoConfig->ActiveFlag = TRUE;\r
-\r
+    Tcp4IoConfig->RemotePort  = NvData->TargetPort;\r
+    Tcp4IoConfig->ActiveFlag  = TRUE;\r
+    Tcp4IoConfig->StationPort = 0;\r
   } else {\r
     Tcp6IoConfig = &TcpIoConfig.Tcp6IoConfigData;\r
   \r
     CopyMem (&Tcp6IoConfig->RemoteIp, &NvData->TargetIp, sizeof (EFI_IPv6_ADDRESS));\r
-    Tcp6IoConfig->RemotePort = NvData->TargetPort;\r
-    Tcp6IoConfig->ActiveFlag = TRUE;\r
+    Tcp6IoConfig->RemotePort  = NvData->TargetPort;\r
+    Tcp6IoConfig->ActiveFlag  = TRUE;\r
+    Tcp6IoConfig->StationPort = 0;\r
   }\r
 \r
   //\r
@@ -308,6 +313,98 @@ IScsiDestroyConnection (
   FreePool (Conn);\r
 }\r
 \r
+/**\r
+  Retrieve the IPv6 Address/Prefix/Gateway from the established TCP connection, these informations\r
+  will be filled in the iSCSI Boot Firmware Table.\r
+\r
+  @param[in]  Conn             The connection used in the iSCSI login phase.\r
+\r
+  @retval     EFI_SUCCESS      Get the NIC information successfully.\r
+  @retval     Others           Other errors as indicated.\r
+  \r
+**/\r
+EFI_STATUS\r
+IScsiGetIp6NicInfo (\r
+  IN ISCSI_CONNECTION  *Conn\r
+  )\r
+{\r
+  ISCSI_SESSION_CONFIG_NVDATA  *NvData;\r
+  EFI_TCP6_PROTOCOL            *Tcp6;\r
+  EFI_IP6_MODE_DATA            Ip6ModeData;\r
+  EFI_STATUS                   Status;\r
+  EFI_IPv6_ADDRESS             *TargetIp;\r
+  UINTN                        Index;\r
+  UINT8                        SubnetPrefixLength;\r
+  UINTN                        RouteEntry;\r
+\r
+  NvData   = &Conn->Session->ConfigData->SessionConfigData;\r
+  TargetIp = &NvData->TargetIp.v6;\r
+  Tcp6     = Conn->TcpIo.Tcp.Tcp6;\r
+\r
+  ZeroMem (&Ip6ModeData, sizeof (EFI_IP6_MODE_DATA));\r
+  Status = Tcp6->GetModeData (\r
+                   Tcp6,\r
+                   NULL,\r
+                   NULL,\r
+                   &Ip6ModeData,\r
+                   NULL,\r
+                   NULL\r
+                   );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  if (!Ip6ModeData.IsConfigured) {\r
+    Status = EFI_ABORTED;\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  IP6_COPY_ADDRESS (&NvData->LocalIp, &Ip6ModeData.ConfigData.StationAddress);\r
+\r
+  NvData->PrefixLength = 0;\r
+  for (Index = 0; Index < Ip6ModeData.AddressCount; Index++) {\r
+    if (EFI_IP6_EQUAL (&NvData->LocalIp.v6, &Ip6ModeData.AddressList[Index].Address)) {\r
+      NvData->PrefixLength = Ip6ModeData.AddressList[Index].PrefixLength;\r
+      break;\r
+    }\r
+  }\r
+\r
+  SubnetPrefixLength = 0;\r
+  RouteEntry = Ip6ModeData.RouteCount;\r
+  for (Index = 0; Index < Ip6ModeData.RouteCount; Index++) {\r
+    if (NetIp6IsNetEqual (TargetIp, &Ip6ModeData.RouteTable[Index].Destination, Ip6ModeData.RouteTable[Index].PrefixLength)) {\r
+      if (SubnetPrefixLength < Ip6ModeData.RouteTable[Index].PrefixLength) {\r
+        SubnetPrefixLength = Ip6ModeData.RouteTable[Index].PrefixLength;\r
+        RouteEntry = Index;\r
+      }\r
+    }\r
+  }\r
+  if (RouteEntry != Ip6ModeData.RouteCount) {\r
+    IP6_COPY_ADDRESS (&NvData->Gateway, &Ip6ModeData.RouteTable[RouteEntry].Gateway);\r
+  }\r
+\r
+ON_EXIT:\r
+  if (Ip6ModeData.AddressList != NULL) {\r
+    FreePool (Ip6ModeData.AddressList);\r
+  }\r
+  if (Ip6ModeData.GroupTable!= NULL) {\r
+    FreePool (Ip6ModeData.GroupTable);\r
+  }\r
+  if (Ip6ModeData.RouteTable!= NULL) {\r
+    FreePool (Ip6ModeData.RouteTable);\r
+  }\r
+  if (Ip6ModeData.NeighborCache!= NULL) {\r
+    FreePool (Ip6ModeData.NeighborCache);\r
+  }\r
+  if (Ip6ModeData.PrefixTable!= NULL) {\r
+    FreePool (Ip6ModeData.PrefixTable);\r
+  }\r
+  if (Ip6ModeData.IcmpTypeList!= NULL) {\r
+    FreePool (Ip6ModeData.IcmpTypeList);\r
+  }\r
+\r
+  return Status;\r
+}\r
 \r
 /**\r
   Login the iSCSI session.\r
@@ -379,7 +476,7 @@ IScsiSessionLogin (
   if (!EFI_ERROR (Status)) {\r
     Session->State = SESSION_STATE_LOGGED_IN;\r
 \r
-    if (!mPrivate->Ipv6Flag) {\r
+    if (!Conn->Ipv6Flag) {\r
       ProtocolGuid = &gEfiTcp4ProtocolGuid;      \r
     } else {\r
       ProtocolGuid = &gEfiTcp6ProtocolGuid;\r
@@ -395,6 +492,10 @@ IScsiSessionLogin (
                     );\r
 \r
     ASSERT_EFI_ERROR (Status);\r
+\r
+    if (Conn->Ipv6Flag) {\r
+      Status = IScsiGetIp6NicInfo (Conn);\r
+    }\r
   }\r
 \r
   return Status;\r
@@ -507,6 +608,8 @@ IScsiReceiveLoginRsp (
   EFI_STATUS  Status;\r
   NET_BUF     *Pdu;\r
 \r
+  Pdu = NULL;\r
+\r
   //\r
   // Receive the iSCSI login response.\r
   //\r
@@ -632,7 +735,10 @@ IScsiPrepareLoginReq (
   }\r
 \r
   LoginReq = (ISCSI_LOGIN_REQUEST *) NetbufAllocSpace (Nbuf, sizeof (ISCSI_LOGIN_REQUEST), NET_BUF_TAIL);\r
-  ASSERT (LoginReq != NULL);\r
+  if (LoginReq == NULL) {\r
+    NetbufFree (Nbuf);\r
+    return NULL;\r
+  }\r
   ZeroMem (LoginReq, sizeof (ISCSI_LOGIN_REQUEST));\r
 \r
   //\r
@@ -1146,7 +1252,10 @@ IScsiReceivePdu (
   }\r
 \r
   Header = NetbufAllocSpace (PduHdr, Len, NET_BUF_TAIL);\r
-  ASSERT (Header != NULL);\r
+  if (Header == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto ON_EXIT;\r
+  }\r
   InsertTailList (NbufList, &PduHdr->List);\r
 \r
   //\r
@@ -2217,7 +2326,10 @@ IScsiNewDataOutPdu (
   InsertTailList (NbufList, &PduHdr->List);\r
 \r
   DataOutHdr  = (ISCSI_SCSI_DATA_OUT *) NetbufAllocSpace (PduHdr, sizeof (ISCSI_SCSI_DATA_OUT), NET_BUF_TAIL);\r
-  ASSERT (DataOutHdr != NULL);\r
+  if (DataOutHdr == NULL) {\r
+    IScsiFreeNbufList (NbufList);\r
+    return NULL;\r
+  }\r
   XferContext = &Tcb->XferContext;\r
 \r
   ZeroMem (DataOutHdr, sizeof (ISCSI_SCSI_DATA_OUT));\r
@@ -2723,6 +2835,7 @@ IScsiOnNopInRcvd (
   @retval EFI_DEVICE_ERROR     Session state was not as required.\r
   @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
   @retval EFI_PROTOCOL_ERROR   There is no such data in the net buffer.\r
+  @retval EFI_NOT_READY        The target can not accept new commands.\r
   @retval Others               Other errors as indicated.\r
 \r
 **/\r
@@ -2755,7 +2868,8 @@ IScsiExecuteScsiCommand (
   Timeout       = 0;\r
 \r
   if (Session->State != SESSION_STATE_LOGGED_IN) {\r
-    return EFI_DEVICE_ERROR;\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto ON_EXIT;\r
   }\r
 \r
   Conn = NET_LIST_USER_STRUCT_S (\r
@@ -2900,15 +3014,6 @@ ON_EXIT:
     IScsiDelTcb (Tcb);\r
   }\r
 \r
-  if ((Status != EFI_SUCCESS) && (Status != EFI_NOT_READY)) {\r
-    //\r
-    // Reinstate the session.\r
-    //\r
-    if (EFI_ERROR (IScsiSessionReinstatement (Session))) {\r
-      Status = EFI_DEVICE_ERROR;\r
-    }\r
-  }\r
-\r
   return Status;\r
 }\r
 \r
@@ -2929,7 +3034,7 @@ IScsiSessionReinstatement (
 {\r
   EFI_STATUS    Status;\r
 \r
-  ASSERT (Session->State == SESSION_STATE_LOGGED_IN);\r
+  ASSERT (Session->State != SESSION_STATE_FREE);\r
 \r
   //\r
   // Abort the session and re-init it.\r