Index: /trunk/src/VBox/Devices/Storage/ISCSIHDDCore.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/ISCSIHDDCore.cpp	(revision 30940)
+++ /trunk/src/VBox/Devices/Storage/ISCSIHDDCore.cpp	(revision 30941)
@@ -251,4 +251,14 @@
     ISCSISTATE_IN_LOGOUT
 } ISCSISTATE;
+
+/**
+ * iSCSI PDU send flags (and maybe more in the future). */
+typedef enum ISCSIPDUFLAGS
+{
+    /** No special flags */
+    ISCSIPDU_DEFAULT = 0,
+    /** Do not attempt to re-attach to the target if the connection is lost */
+    ISCSIPDU_NO_REATTACH = RT_BIT(1)
+} ISCSIPDUFLAGS;
 
 
@@ -490,5 +500,5 @@
 /* iSCSI low-level functions (only to be used from the iSCSI high-level functions). */
 static uint32_t iscsiNewITT(PISCSIIMAGE pImage);
-static int iscsiSendPDU(PISCSIIMAGE pImage, PISCSIREQ paReq, uint32_t cnReq);
+static int iscsiSendPDU(PISCSIIMAGE pImage, PISCSIREQ paReq, uint32_t cnReq, uint32_t uFlags);
 static int iscsiRecvPDU(PISCSIIMAGE pImage, uint32_t itt, PISCSIRES paRes, uint32_t cnRes);
 static int drvISCSIValidatePDU(PISCSIRES paRes, uint32_t cnRes);
@@ -626,4 +636,5 @@
                 pImage->pInterfaceNetCallbacks->pfnClientClose(pImage->Socket);
                 pImage->Socket = NIL_RTSOCKET;
+                pImage->state = ISCSISTATE_FREE;
                 rc = VERR_NET_CONNECTION_RESET;
                 break;
@@ -711,5 +722,5 @@
     unsigned int i;
 
-    LogFlow(("iscsiTransportWrite: cnRequest=%d (%s:%d)\n", cnRequest, pImage->pszHostname, pImage->uPort));
+    LogFlowFunc(("cnRequest=%d (%s:%d)\n", cnRequest, pImage->pszHostname, pImage->uPort));
     if (pImage->Socket == NIL_RTSOCKET)
     {
@@ -766,5 +777,5 @@
     }
 
-    LogFlow(("iscsiTransportWrite: returns %Rrc\n", rc));
+    LogFlowFunc(("returns %Rrc\n", rc));
     return rc;
 }
@@ -1085,5 +1096,5 @@
         cnISCSIReq++;
 
-        rc = iscsiSendPDU(pImage, aISCSIReq, cnISCSIReq);
+        rc = iscsiSendPDU(pImage, aISCSIReq, cnISCSIReq, ISCSIPDU_NO_REATTACH);
         if (RT_SUCCESS(rc))
         {
@@ -1347,5 +1358,5 @@
     ISCSIREQ aISCSIReq[4];
     uint32_t aReqBHS[12];
-    LogFlow(("iscsiDetach: entering\n"));
+    LogFlowFunc(("entering\n"));
 
     RTSemMutexRequest(pImage->Mutex, RT_INDEFINITE_WAIT);
@@ -1377,5 +1388,5 @@
         cnISCSIReq++;
 
-        rc = iscsiSendPDU(pImage, aISCSIReq, cnISCSIReq);
+        rc = iscsiSendPDU(pImage, aISCSIReq, cnISCSIReq, ISCSIPDU_NO_REATTACH);
         if (RT_SUCCESS(rc))
         {
@@ -1415,5 +1426,5 @@
     RTSemMutexRelease(pImage->Mutex);
 
-    LogFlow(("iscsiDetach: leaving\n"));
+    LogFlowFunc(("leaving\n"));
     LogRel(("iSCSI: logout to target %s\n", pImage->pszTargetName));
     return VINF_SUCCESS;
@@ -1447,5 +1458,5 @@
     bool final = false;
 
-    LogFlow(("iscsiCommand: entering, CmdSN=%d\n", pImage->CmdSN));
+    LogFlowFunc(("entering, CmdSN=%d\n", pImage->CmdSN));
 
     Assert(pRequest->enmXfer != SCSIXFER_TO_FROM_TARGET);   /**< @todo not yet supported, would require AHS. */
@@ -1504,5 +1515,5 @@
     }
 
-    rc = iscsiSendPDU(pImage, aISCSIReq, cnISCSIReq);
+    rc = iscsiSendPDU(pImage, aISCSIReq, cnISCSIReq, ISCSIPDU_DEFAULT);
     if (RT_FAILURE(rc))
         goto out_release;
@@ -1647,5 +1658,5 @@
 
 out:
-    LogFlow(("iscsiCommand: returns %Rrc\n", rc));
+    LogFlowFunc(("returns %Rrc\n", rc));
     return rc;
 }
@@ -1677,6 +1688,8 @@
  * @param   paReq       Pointer to array of iSCSI request sections.
  * @param   cnReq       Number of valid iSCSI request sections in the array.
+ * @param   uFlags      Flags controlling the exact send semantics.
  */
-static int iscsiSendPDU(PISCSIIMAGE pImage, PISCSIREQ paReq, uint32_t cnReq)
+static int iscsiSendPDU(PISCSIIMAGE pImage, PISCSIREQ paReq, uint32_t cnReq,
+                        uint32_t uFlags)
 {
     int rc = VINF_SUCCESS;
@@ -1684,5 +1697,4 @@
      * needs cleaning up of timeout/disconnect handling a bit, as otherwise
      * too many incorrect errors are signalled. */
-    Assert(pImage->paCurrReq == NULL);
     Assert(cnReq >= 1);
     Assert(paReq[0].cbSeg >= ISCSI_BHS_SIZE);
@@ -1693,5 +1705,6 @@
         if (RT_SUCCESS(rc))
             break;
-        if (rc != VERR_BROKEN_PIPE && rc != VERR_NET_CONNECTION_REFUSED)
+        if (   (uFlags & ISCSIPDU_NO_REATTACH)
+            || (rc != VERR_BROKEN_PIPE && rc != VERR_NET_CONNECTION_REFUSED))
             break;
         /* No point in reestablishing the connection for a logout */
@@ -1754,5 +1767,5 @@
                 if (pImage->paCurrReq != NULL)
                 {
-                    rc = iscsiSendPDU(pImage, pImage->paCurrReq, pImage->cnCurrReq);
+                    rc = iscsiSendPDU(pImage, pImage->paCurrReq, pImage->cnCurrReq, ISCSIPDU_DEFAULT);
                     if (RT_FAILURE(rc))
                         break;
@@ -1874,5 +1887,5 @@
                 cnISCSIReq++;
 
-                iscsiSendPDU(pImage, aISCSIReq, cnISCSIReq);
+                iscsiSendPDU(pImage, aISCSIReq, cnISCSIReq, ISCSIPDU_NO_REATTACH);
             }
         }
@@ -1964,5 +1977,5 @@
         default:
             /* Do some logging, ignore PDU. */
-            LogFlow(("drvISCSIValidatePDU: ignore unhandled PDU, first word %#08x\n", RT_N2H_U32(pcrgResBHS[0])));
+            LogFlowFunc(("ignore unhandled PDU, first word %#08x\n", RT_N2H_U32(pcrgResBHS[0])));
             return VERR_PARSE_ERROR;
     }
