]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/IScsiDxe/IScsiProto.c
Update code to support VS2013 tool chain.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / IScsiDxe / IScsiProto.c
index a370e29a5c398a785269d91f513919a7422dbc8b..cb1f79b16aa3e6dc11a33d8c88822da62cbdab99 100644 (file)
@@ -1,8 +1,8 @@
 /** @file\r
   The implementation of iSCSI protocol based on RFC3720.\r
 \r
-Copyright (c) 2004 - 2008, Intel Corporation.<BR>\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2004 - 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\r
@@ -215,7 +215,7 @@ IScsiCreateConnection (
                   &Conn->TimeoutEvent\r
                   );\r
   if (EFI_ERROR (Status)) {\r
-    gBS->FreePool (Conn);\r
+    FreePool (Conn);\r
     return NULL;\r
   }\r
 \r
@@ -225,8 +225,8 @@ IScsiCreateConnection (
   // set the default connection-only parameters\r
   //\r
   Conn->MaxRecvDataSegmentLength  = DEFAULT_MAX_RECV_DATA_SEG_LEN;\r
-  Conn->HeaderDigest              = ISCSI_DIGEST_NONE;\r
-  Conn->DataDigest                = ISCSI_DIGEST_NONE;\r
+  Conn->HeaderDigest              = IScsiDigestNone;\r
+  Conn->DataDigest                = IScsiDigestNone;\r
 \r
   CopyMem (&Tcp4IoConfig.LocalIp, &Session->ConfigData.NvData.LocalIp, sizeof (EFI_IPv4_ADDRESS));\r
   CopyMem (&Tcp4IoConfig.SubnetMask, &Session->ConfigData.NvData.SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
@@ -246,7 +246,7 @@ IScsiCreateConnection (
             );\r
   if (EFI_ERROR (Status)) {\r
     gBS->CloseEvent (Conn->TimeoutEvent);\r
-    gBS->FreePool (Conn);\r
+    FreePool (Conn);\r
     Conn = NULL;\r
   }\r
 \r
@@ -266,7 +266,7 @@ IScsiDestroyConnection (
   Tcp4IoDestroySocket (&Conn->Tcp4Io);\r
   NetbufQueFlush (&Conn->RspQue);\r
   gBS->CloseEvent (Conn->TimeoutEvent);\r
-  gBS->FreePool (Conn);\r
+  FreePool (Conn);\r
 }\r
 \r
 /**\r
@@ -276,7 +276,9 @@ IScsiDestroyConnection (
 \r
   @retval EFI_SUCCESS          The iSCSI session login procedure finished.\r
   @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
+  @retval EFI_NO_MEDIA         There was a media error.\r
   @retval Others               Other errors as indicated.\r
+\r
 **/\r
 EFI_STATUS\r
 IScsiSessionLogin (\r
@@ -287,9 +289,24 @@ IScsiSessionLogin (
   ISCSI_SESSION     *Session;\r
   ISCSI_CONNECTION  *Conn;\r
   EFI_TCP4_PROTOCOL *Tcp4;\r
+  BOOLEAN           MediaPresent;\r
 \r
   Session = &Private->Session;\r
 \r
+  //\r
+  // Check media status before session login\r
+  //\r
+  MediaPresent = TRUE;\r
+  NetLibDetectMedia (Private->Controller, &MediaPresent);\r
+  if (!MediaPresent) {\r
+    return EFI_NO_MEDIA;\r
+  }\r
+\r
+  //\r
+  // Set session identifier\r
+  //\r
+  CopyMem (Session->Isid, Session->ConfigData.NvData.IsId, 6);\r
+\r
   //\r
   // Create a connection for the session.\r
   //\r
@@ -376,6 +393,8 @@ IScsiReceiveLoginRsp (
   EFI_STATUS  Status;\r
   NET_BUF     *Pdu;\r
 \r
+  Pdu = NULL;\r
+\r
   //\r
   // Receive the iSCSI login response.\r
   //\r
@@ -386,6 +405,7 @@ IScsiReceiveLoginRsp (
   //\r
   // A Login Response is received, process it.\r
   //\r
+  ASSERT (Pdu != NULL);\r
   Status = IScsiProcessLoginRsp (Conn, Pdu);\r
 \r
   NetbufFree (Pdu);\r
@@ -423,6 +443,9 @@ IScsiAddKeyValuePair (
   CHAR8               *Data;\r
 \r
   LoginReq    = (ISCSI_LOGIN_REQUEST *) NetbufGetByte (Pdu, 0, NULL);\r
+  if (LoginReq == NULL) {\r
+    return EFI_PROTOCOL_ERROR;\r
+  }\r
   DataSegLen  = NTOH24 (LoginReq->DataSegmentLength);\r
 \r
   KeyLen      = (UINT32) AsciiStrLen (Key);\r
@@ -589,6 +612,9 @@ IScsiProcessLoginRsp (
   Session   = Conn->Session;\r
 \r
   LoginRsp  = (ISCSI_LOGIN_RESPONSE *) NetbufGetByte (Pdu, 0, NULL);\r
+  if (LoginRsp == NULL) {\r
+    return EFI_PROTOCOL_ERROR;\r
+  }\r
   if (!ISCSI_CHECK_OPCODE (LoginRsp, ISCSI_OPCODE_LOGIN_RSP)) {\r
     //\r
     // It's not a Login Response\r
@@ -675,6 +701,14 @@ IScsiProcessLoginRsp (
   LoginRsp->MaxCmdSN  = NTOHL (LoginRsp->MaxCmdSN);\r
 \r
   if ((Conn->CurrentStage == ISCSI_SECURITY_NEGOTIATION) && (Conn->CHAPStep == ISCSI_CHAP_INITIAL)) {\r
+    //\r
+    // If the Login Request is a leading Login Request, the target MUST use\r
+    // the value presented in CmdSN as the target value for ExpCmdSN.\r
+    //\r
+    if ((Session->State == SESSION_STATE_FREE) && (Session->CmdSN != LoginRsp->ExpCmdSN)) {\r
+      return EFI_PROTOCOL_ERROR;\r
+    }\r
+\r
     //\r
     // It's the initial Login Response, initialize the local ExpStatSN, MaxCmdSN\r
     // and ExpCmdSN.\r
@@ -868,6 +902,7 @@ IScsiUpdateTargetAddress (
   @param[in]  Arg The opaque parameter.\r
 **/\r
 VOID\r
+EFIAPI\r
 IScsiFreeNbufList (\r
   VOID *Arg\r
   )\r
@@ -875,7 +910,7 @@ IScsiFreeNbufList (
   ASSERT (Arg != NULL);\r
 \r
   NetbufFreeList ((LIST_ENTRY     *) Arg);\r
-  gBS->FreePool (Arg);\r
+  FreePool (Arg);\r
 }\r
 \r
 /**\r
@@ -884,6 +919,7 @@ IScsiFreeNbufList (
   @param[in]   Arg  The opaque parameter.\r
 **/\r
 VOID\r
+EFIAPI\r
 IScsiNbufExtFree (\r
   VOID *Arg\r
   )\r
@@ -944,7 +980,7 @@ IScsiReceivePdu (
   Len     = sizeof (ISCSI_BASIC_HEADER) + (HeaderDigest ? sizeof (UINT32) : 0);\r
   PduHdr  = NetbufAlloc (Len);\r
   if (PduHdr == NULL) {\r
-    gBS->FreePool (NbufList);\r
+    FreePool (NbufList);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
@@ -1134,7 +1170,7 @@ IScsiCheckOpParams (
   //\r
   KeyValueList = IScsiBuildKeyValueList (Data, Len);\r
   if (KeyValueList == NULL) {\r
-    gBS->FreePool (Data);\r
+    FreePool (Data);\r
     return Status;\r
   }\r
   //\r
@@ -1146,11 +1182,11 @@ IScsiCheckOpParams (
   }\r
 \r
   if (AsciiStrCmp (Value, "CRC32") == 0) {\r
-    if (Conn->HeaderDigest != ISCSI_DIGEST_CRC32) {\r
+    if (Conn->HeaderDigest != IScsiDigestCRC32) {\r
       goto ON_ERROR;\r
     }\r
   } else if (AsciiStrCmp (Value, ISCSI_KEY_VALUE_NONE) == 0) {\r
-    Conn->HeaderDigest = ISCSI_DIGEST_NONE;\r
+    Conn->HeaderDigest = IScsiDigestNone;\r
   } else {\r
     goto ON_ERROR;\r
   }\r
@@ -1163,11 +1199,11 @@ IScsiCheckOpParams (
   }\r
 \r
   if (AsciiStrCmp (Value, "CRC32") == 0) {\r
-    if (Conn->DataDigest != ISCSI_DIGEST_CRC32) {\r
+    if (Conn->DataDigest != IScsiDigestCRC32) {\r
       goto ON_ERROR;\r
     }\r
   } else if (AsciiStrCmp (Value, ISCSI_KEY_VALUE_NONE) == 0) {\r
-    Conn->DataDigest = ISCSI_DIGEST_NONE;\r
+    Conn->DataDigest = IScsiDigestNone;\r
   } else {\r
     goto ON_ERROR;\r
   }\r
@@ -1337,7 +1373,7 @@ ON_ERROR:
 \r
   IScsiFreeKeyValueList (KeyValueList);\r
 \r
-  gBS->FreePool (Data);\r
+  FreePool (Data);\r
 \r
   return Status;\r
 }\r
@@ -1361,10 +1397,10 @@ IScsiFillOpParams (
 \r
   Session = Conn->Session;\r
 \r
-  AsciiSPrint (Value, sizeof (Value), "%a", (Conn->HeaderDigest == ISCSI_DIGEST_CRC32) ? "None,CRC32" : "None");\r
+  AsciiSPrint (Value, sizeof (Value), "%a", (Conn->HeaderDigest == IScsiDigestCRC32) ? "None,CRC32" : "None");\r
   IScsiAddKeyValuePair (Pdu, ISCSI_KEY_HEADER_DIGEST, Value);\r
 \r
-  AsciiSPrint (Value, sizeof (Value), "%a", (Conn->DataDigest == ISCSI_DIGEST_CRC32) ? "None,CRC32" : "None");\r
+  AsciiSPrint (Value, sizeof (Value), "%a", (Conn->DataDigest == IScsiDigestCRC32) ? "None,CRC32" : "None");\r
   IScsiAddKeyValuePair (Pdu, ISCSI_KEY_DATA_DIGEST, Value);\r
 \r
   AsciiSPrint (Value, sizeof (Value), "%d", Session->ErrorRecoveryLevel);\r
@@ -1485,7 +1521,7 @@ IScsiBuildKeyValueList (
       Data++;\r
       Len--;\r
     } else {\r
-      gBS->FreePool (KeyValuePair);\r
+      FreePool (KeyValuePair);\r
       goto ON_ERROR;\r
     }\r
 \r
@@ -1534,7 +1570,7 @@ IScsiGetValueByKeyFromList (
       Value = KeyValuePair->Value;\r
 \r
       RemoveEntryList (&KeyValuePair->List);\r
-      gBS->FreePool (KeyValuePair);\r
+      FreePool (KeyValuePair);\r
       break;\r
     }\r
   }\r
@@ -1559,10 +1595,10 @@ IScsiFreeKeyValueList (
     Entry         = NetListRemoveHead (KeyValueList);\r
     KeyValuePair  = NET_LIST_USER_STRUCT (Entry, ISCSI_KEY_VALUE_PAIR, List);\r
 \r
-    gBS->FreePool (KeyValuePair);\r
+    FreePool (KeyValuePair);\r
   }\r
 \r
-  gBS->FreePool (KeyValueList);\r
+  FreePool (KeyValueList);\r
 }\r
 \r
 /**\r
@@ -1678,7 +1714,7 @@ IScsiDelTcb (
 {\r
   RemoveEntryList (&Tcb->Link);\r
 \r
-  gBS->FreePool (Tcb);\r
+  FreePool (Tcb);\r
 }\r
 \r
 /**\r
@@ -1854,10 +1890,10 @@ IScsiNewScsiCmdPdu (
   ScsiCmd->CmdSN            = NTOHL (Tcb->CmdSN);\r
   ScsiCmd->ExpStatSN        = NTOHL (Tcb->Conn->ExpStatSN);\r
 \r
-  CopyMem (ScsiCmd->CDB, Packet->Cdb, sizeof (ScsiCmd->CDB));\r
+  CopyMem (ScsiCmd->Cdb, Packet->Cdb, sizeof (ScsiCmd->Cdb));\r
 \r
   if (Packet->CdbLength > 16) {\r
-    Header->Length  = NTOHS (Packet->CdbLength - 15);\r
+    Header->Length  = NTOHS ((UINT16) (Packet->CdbLength - 15));\r
     Header->Type    = ISCSI_AHS_TYPE_EXT_CDB;\r
 \r
     CopyMem (Header + 1, (UINT8 *) Packet->Cdb + 16, Packet->CdbLength - 16);\r
@@ -1969,7 +2005,7 @@ IScsiNewDataOutPdu (
   //\r
   PduHdr = NetbufAlloc (sizeof (ISCSI_SCSI_DATA_OUT));\r
   if (PduHdr == NULL) {\r
-    gBS->FreePool (NbufList);\r
+    FreePool (NbufList);\r
     return NULL;\r
   }\r
   //\r
@@ -2042,6 +2078,7 @@ IScsiGenerateDataOutPduSequence (
   NET_BUF             *DataOutPdu;\r
   ISCSI_CONNECTION    *Conn;\r
   ISCSI_XFER_CONTEXT  *XferContext;\r
+  UINT8               *DataOutPacket;\r
 \r
   PduList = AllocatePool (sizeof (LIST_ENTRY));\r
   if (PduList == NULL) {\r
@@ -2085,7 +2122,14 @@ IScsiGenerateDataOutPduSequence (
   //\r
   // Set the F bit for the last data out PDU in this sequence.\r
   //\r
-  ISCSI_SET_FLAG (NetbufGetByte (DataOutPdu, 0, NULL), ISCSI_BHS_FLAG_FINAL);\r
+  DataOutPacket = NetbufGetByte (DataOutPdu, 0, NULL);\r
+  if (DataOutPacket == NULL) {\r
+    IScsiFreeNbufList (PduList);\r
+    PduList = NULL;\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  ISCSI_SET_FLAG (DataOutPacket, ISCSI_BHS_FLAG_FINAL);\r
 \r
 ON_EXIT:\r
 \r
@@ -2166,6 +2210,9 @@ IScsiOnDataInRcvd (
   EFI_STATUS          Status;\r
 \r
   DataInHdr                   = (ISCSI_SCSI_DATA_IN *) NetbufGetByte (Pdu, 0, NULL);\r
+  if (DataInHdr == NULL) {\r
+    return EFI_PROTOCOL_ERROR;\r
+  }\r
 \r
   DataInHdr->InitiatorTaskTag = NTOHL (DataInHdr->InitiatorTaskTag);\r
   DataInHdr->ExpCmdSN         = NTOHL (DataInHdr->ExpCmdSN);\r
@@ -2254,11 +2301,14 @@ IScsiOnR2TRcvd (
   UINT8                   *Data;\r
 \r
   R2THdr = (ISCSI_READY_TO_TRANSFER *) NetbufGetByte (Pdu, 0, NULL);\r
+  if (R2THdr == NULL) {\r
+    return EFI_PROTOCOL_ERROR;\r
+  }\r
 \r
   R2THdr->InitiatorTaskTag = NTOHL (R2THdr->InitiatorTaskTag);\r
   R2THdr->TargetTransferTag = NTOHL (R2THdr->TargetTransferTag);\r
   R2THdr->StatSN = NTOHL (R2THdr->StatSN);\r
-  R2THdr->R2TSN = NTOHL (R2THdr->R2TSN);\r
+  R2THdr->R2TSeqNum = NTOHL (R2THdr->R2TSeqNum);\r
   R2THdr->BufferOffset = NTOHL (R2THdr->BufferOffset);\r
   R2THdr->DesiredDataTransferLength = NTOHL (R2THdr->DesiredDataTransferLength);\r
 \r
@@ -2268,7 +2318,7 @@ IScsiOnR2TRcvd (
   //\r
   // Check the sequence number.\r
   //\r
-  Status = IScsiCheckSN (&Tcb->ExpDataSN, R2THdr->R2TSN);\r
+  Status = IScsiCheckSN (&Tcb->ExpDataSN, R2THdr->R2TSeqNum);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
@@ -2317,6 +2367,9 @@ IScsiOnScsiRspRcvd (
   UINT32            DataSegLen;\r
 \r
   ScsiRspHdr                    = (SCSI_RESPONSE *) NetbufGetByte (Pdu, 0, NULL);\r
+  if (ScsiRspHdr == NULL) {\r
+    return EFI_PROTOCOL_ERROR;\r
+  }\r
 \r
   ScsiRspHdr->InitiatorTaskTag  = NTOHL (ScsiRspHdr->InitiatorTaskTag);\r
   if (ScsiRspHdr->InitiatorTaskTag != Tcb->InitiatorTaskTag) {\r
@@ -2379,6 +2432,9 @@ IScsiOnScsiRspRcvd (
   DataSegLen = ISCSI_GET_DATASEG_LEN (ScsiRspHdr);\r
   if (DataSegLen != 0) {\r
     SenseData               = (ISCSI_SENSE_DATA *) NetbufGetByte (Pdu, sizeof (SCSI_RESPONSE), NULL);\r
+    if (SenseData == NULL) {\r
+      return EFI_PROTOCOL_ERROR;\r
+    }\r
 \r
     SenseData->Length       = NTOHS (SenseData->Length);\r
 \r
@@ -2413,6 +2469,9 @@ IScsiOnNopInRcvd (
   EFI_STATUS    Status;\r
 \r
   NopInHdr            = (ISCSI_NOP_IN *) NetbufGetByte (Pdu, 0, NULL);\r
+  if (NopInHdr == NULL) {\r
+    return EFI_PROTOCOL_ERROR;\r
+  }\r
 \r
   NopInHdr->StatSN    = NTOHL (NopInHdr->StatSN);\r
   NopInHdr->ExpCmdSN  = NTOHL (NopInHdr->ExpCmdSN);\r
@@ -2447,6 +2506,7 @@ IScsiOnNopInRcvd (
                                the Packet.\r
   @retval EFI_DEVICE_ERROR     Session state was not as required.\r
   @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
+  @retval EFI_NOT_READY        The target can not accept new commands.\r
   @retval Others               Other errors as indicated.\r
 **/\r
 EFI_STATUS\r
@@ -2468,7 +2528,7 @@ IScsiExecuteScsiCommand (
   UINT8                   *Data;\r
   ISCSI_IN_BUFFER_CONTEXT InBufferContext;\r
   UINT64                  Timeout;\r
-  UINT8                   *Buffer;\r
+  UINT8                   *PduHdr;\r
 \r
   Private       = ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU (PassThru);\r
   Session       = &Private->Session;\r
@@ -2478,7 +2538,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
@@ -2506,8 +2567,13 @@ IScsiExecuteScsiCommand (
   }\r
 \r
   XferContext         = &Tcb->XferContext;\r
-  Buffer              = NetbufGetByte (Pdu, 0, NULL);\r
-  XferContext->Offset = ISCSI_GET_DATASEG_LEN (Buffer);\r
+  PduHdr              = NetbufGetByte (Pdu, 0, NULL);\r
+  if (PduHdr == NULL) {\r
+    Status = EFI_PROTOCOL_ERROR;\r
+    NetbufFree (Pdu);\r
+    goto ON_EXIT;\r
+  }\r
+  XferContext->Offset = ISCSI_GET_DATASEG_LEN (PduHdr);\r
 \r
   //\r
   // Transmit the SCSI Command PDU.\r
@@ -2563,7 +2629,13 @@ IScsiExecuteScsiCommand (
       goto ON_EXIT;\r
     }\r
 \r
-    switch (ISCSI_GET_OPCODE (NetbufGetByte (Pdu, 0, NULL))) {\r
+    PduHdr = NetbufGetByte (Pdu, 0, NULL);\r
+    if (PduHdr == NULL) {\r
+      Status = EFI_PROTOCOL_ERROR;\r
+      NetbufFree (Pdu);\r
+      goto ON_EXIT;\r
+    }\r
+    switch (ISCSI_GET_OPCODE (PduHdr)) {\r
     case ISCSI_OPCODE_SCSI_DATA_IN:\r
       Status = IScsiOnDataInRcvd (Pdu, Tcb, Packet);\r
       break;\r
@@ -2610,15 +2682,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 (Private))) {\r
-      Status = EFI_DEVICE_ERROR;\r
-    }\r
-  }\r
-\r
   return Status;\r
 }\r
 \r
@@ -2639,7 +2702,7 @@ IScsiSessionReinstatement (
   EFI_STATUS    Status;\r
 \r
   Session = &Private->Session;\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
@@ -2667,21 +2730,10 @@ IScsiSessionInit (
   IN BOOLEAN            Recovery\r
   )\r
 {\r
-  UINT32  Random;\r
-\r
   if (!Recovery) {\r
     Session->Signature  = ISCSI_SESSION_SIGNATURE;\r
     Session->State      = SESSION_STATE_FREE;\r
 \r
-    Random              = NET_RANDOM (NetRandomInitSeed ());\r
-\r
-    Session->Isid[0]    = ISID_BYTE_0;\r
-    Session->Isid[1]    = ISID_BYTE_1;\r
-    Session->Isid[2]    = ISID_BYTE_2;\r
-    Session->Isid[3]    = ISID_BYTE_3;\r
-    Session->Isid[4]    = (UINT8) Random;\r
-    Session->Isid[5]    = (UINT8) (Random >> 8);\r
-\r
     InitializeListHead (&Session->Conns);\r
     InitializeListHead (&Session->TcbList);\r
   }\r