[SCSI] iscsi: don't switch states when just cleaning up

If recovery failed or we are in recovery only overwrite the state
if we are going to terminate the session or if we logged back in.

STOP_CONN_SUSPEND and conn_cnt are not used. We only support
a single connection session ATM, so cleanup that code while
we are working around it.

Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index d810aca..9630025 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -492,7 +492,7 @@
 		return;
 	}
 
-	if (session->conn_cnt == 1 || session->leadconn == conn)
+	if (conn->stop_stage == 0)
 		session->state = ISCSI_STATE_FAILED;
 	spin_unlock_irqrestore(&session->lock, flags);
 	set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
@@ -652,7 +652,7 @@
 		 */
 		if (session->state == ISCSI_STATE_IN_RECOVERY) {
 			reason = FAILURE_SESSION_IN_RECOVERY;
-			goto fault;
+			goto reject;
 		}
 
 		if (session->state == ISCSI_STATE_RECOVERY_FAILED)
@@ -1411,8 +1411,8 @@
 	struct iscsi_session *session = conn->session;
 	unsigned long flags;
 
-	mutex_lock(&conn->xmitmutex);
 	set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
+	mutex_lock(&conn->xmitmutex);
 	if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE) {
 		if (session->tt->suspend_conn_recv)
 			session->tt->suspend_conn_recv(conn);
@@ -1498,7 +1498,6 @@
 		 * unblock eh_abort() if it is blocked. re-try all
 		 * commands after successful recovery
 		 */
-		session->conn_cnt++;
 		conn->stop_stage = 0;
 		conn->tmabort_state = TMABORT_INITIAL;
 		session->age++;
@@ -1508,14 +1507,8 @@
 		wake_up(&conn->ehwait);
 		return 0;
 	case STOP_CONN_TERM:
-		session->conn_cnt++;
 		conn->stop_stage = 0;
 		break;
-	case STOP_CONN_SUSPEND:
-		conn->stop_stage = 0;
-		clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx);
-		clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
-		break;
 	default:
 		break;
 	}
@@ -1589,28 +1582,24 @@
 
 	/*
 	 * When this is called for the in_login state, we only want to clean
-	 * up the login task and connection.
+	 * up the login task and connection. We do not need to block and set
+	 * the recovery state again
 	 */
-	if (conn->stop_stage != STOP_CONN_RECOVER)
-		session->conn_cnt--;
+	if (flag == STOP_CONN_TERM)
+		session->state = ISCSI_STATE_TERMINATE;
+	else if (conn->stop_stage != STOP_CONN_RECOVER)
+		session->state = ISCSI_STATE_IN_RECOVERY;
 
 	old_stop_stage = conn->stop_stage;
 	conn->stop_stage = flag;
+	conn->c_stage = ISCSI_CONN_STOPPED;
+	set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
 	spin_unlock_bh(&session->lock);
 
 	if (session->tt->suspend_conn_recv)
 		session->tt->suspend_conn_recv(conn);
 
 	mutex_lock(&conn->xmitmutex);
-	spin_lock_bh(&session->lock);
-	conn->c_stage = ISCSI_CONN_STOPPED;
-	set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
-
-	if (session->conn_cnt == 0 || session->leadconn == conn)
-		session->state = ISCSI_STATE_IN_RECOVERY;
-
-	spin_unlock_bh(&session->lock);
-
 	/*
 	 * for connection level recovery we should not calculate
 	 * header digest. conn->hdr_size used for optimization
@@ -1620,13 +1609,11 @@
 	if (flag == STOP_CONN_RECOVER) {
 		conn->hdrdgst_en = 0;
 		conn->datadgst_en = 0;
-		/*
-		 * if this is called from the eh and and from userspace
-		 * then we only need to block once.
-		 */
 		if (session->state == ISCSI_STATE_IN_RECOVERY &&
-		    old_stop_stage != STOP_CONN_RECOVER)
+		    old_stop_stage != STOP_CONN_RECOVER) {
+			debug_scsi("blocking session\n");
 			iscsi_block_session(session_to_cls(session));
+		}
 	}
 
 	session->tt->terminate_conn(conn);
@@ -1651,20 +1638,6 @@
 	case STOP_CONN_TERM:
 		iscsi_start_session_recovery(session, conn, flag);
 		break;
-	case STOP_CONN_SUSPEND:
-		if (session->tt->suspend_conn_recv)
-			session->tt->suspend_conn_recv(conn);
-
-		mutex_lock(&conn->xmitmutex);
-		spin_lock_bh(&session->lock);
-
-		conn->stop_stage = flag;
-		conn->c_stage = ISCSI_CONN_STOPPED;
-		set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
-
-		spin_unlock_bh(&session->lock);
-		mutex_unlock(&conn->xmitmutex);
-		break;
 	default:
 		printk(KERN_ERR "iscsi: invalid stop flag %d\n", flag);
 	}