aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libiscsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libiscsi.c')
-rw-r--r--drivers/scsi/libiscsi.c55
1 files changed, 14 insertions, 41 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index d810acae45f7..963002598995 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -492,7 +492,7 @@ void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err)
492 return; 492 return;
493 } 493 }
494 494
495 if (session->conn_cnt == 1 || session->leadconn == conn) 495 if (conn->stop_stage == 0)
496 session->state = ISCSI_STATE_FAILED; 496 session->state = ISCSI_STATE_FAILED;
497 spin_unlock_irqrestore(&session->lock, flags); 497 spin_unlock_irqrestore(&session->lock, flags);
498 set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); 498 set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
@@ -652,7 +652,7 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
652 */ 652 */
653 if (session->state == ISCSI_STATE_IN_RECOVERY) { 653 if (session->state == ISCSI_STATE_IN_RECOVERY) {
654 reason = FAILURE_SESSION_IN_RECOVERY; 654 reason = FAILURE_SESSION_IN_RECOVERY;
655 goto fault; 655 goto reject;
656 } 656 }
657 657
658 if (session->state == ISCSI_STATE_RECOVERY_FAILED) 658 if (session->state == ISCSI_STATE_RECOVERY_FAILED)
@@ -1411,8 +1411,8 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
1411 struct iscsi_session *session = conn->session; 1411 struct iscsi_session *session = conn->session;
1412 unsigned long flags; 1412 unsigned long flags;
1413 1413
1414 mutex_lock(&conn->xmitmutex);
1415 set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); 1414 set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
1415 mutex_lock(&conn->xmitmutex);
1416 if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE) { 1416 if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE) {
1417 if (session->tt->suspend_conn_recv) 1417 if (session->tt->suspend_conn_recv)
1418 session->tt->suspend_conn_recv(conn); 1418 session->tt->suspend_conn_recv(conn);
@@ -1498,7 +1498,6 @@ int iscsi_conn_start(struct iscsi_cls_conn *cls_conn)
1498 * unblock eh_abort() if it is blocked. re-try all 1498 * unblock eh_abort() if it is blocked. re-try all
1499 * commands after successful recovery 1499 * commands after successful recovery
1500 */ 1500 */
1501 session->conn_cnt++;
1502 conn->stop_stage = 0; 1501 conn->stop_stage = 0;
1503 conn->tmabort_state = TMABORT_INITIAL; 1502 conn->tmabort_state = TMABORT_INITIAL;
1504 session->age++; 1503 session->age++;
@@ -1508,13 +1507,7 @@ int iscsi_conn_start(struct iscsi_cls_conn *cls_conn)
1508 wake_up(&conn->ehwait); 1507 wake_up(&conn->ehwait);
1509 return 0; 1508 return 0;
1510 case STOP_CONN_TERM: 1509 case STOP_CONN_TERM:
1511 session->conn_cnt++;
1512 conn->stop_stage = 0;
1513 break;
1514 case STOP_CONN_SUSPEND:
1515 conn->stop_stage = 0; 1510 conn->stop_stage = 0;
1516 clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx);
1517 clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
1518 break; 1511 break;
1519 default: 1512 default:
1520 break; 1513 break;
@@ -1589,28 +1582,24 @@ static void iscsi_start_session_recovery(struct iscsi_session *session,
1589 1582
1590 /* 1583 /*
1591 * When this is called for the in_login state, we only want to clean 1584 * When this is called for the in_login state, we only want to clean
1592 * up the login task and connection. 1585 * up the login task and connection. We do not need to block and set
1586 * the recovery state again
1593 */ 1587 */
1594 if (conn->stop_stage != STOP_CONN_RECOVER) 1588 if (flag == STOP_CONN_TERM)
1595 session->conn_cnt--; 1589 session->state = ISCSI_STATE_TERMINATE;
1590 else if (conn->stop_stage != STOP_CONN_RECOVER)
1591 session->state = ISCSI_STATE_IN_RECOVERY;
1596 1592
1597 old_stop_stage = conn->stop_stage; 1593 old_stop_stage = conn->stop_stage;
1598 conn->stop_stage = flag; 1594 conn->stop_stage = flag;
1595 conn->c_stage = ISCSI_CONN_STOPPED;
1596 set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
1599 spin_unlock_bh(&session->lock); 1597 spin_unlock_bh(&session->lock);
1600 1598
1601 if (session->tt->suspend_conn_recv) 1599 if (session->tt->suspend_conn_recv)
1602 session->tt->suspend_conn_recv(conn); 1600 session->tt->suspend_conn_recv(conn);
1603 1601
1604 mutex_lock(&conn->xmitmutex); 1602 mutex_lock(&conn->xmitmutex);
1605 spin_lock_bh(&session->lock);
1606 conn->c_stage = ISCSI_CONN_STOPPED;
1607 set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
1608
1609 if (session->conn_cnt == 0 || session->leadconn == conn)
1610 session->state = ISCSI_STATE_IN_RECOVERY;
1611
1612 spin_unlock_bh(&session->lock);
1613
1614 /* 1603 /*
1615 * for connection level recovery we should not calculate 1604 * for connection level recovery we should not calculate
1616 * header digest. conn->hdr_size used for optimization 1605 * header digest. conn->hdr_size used for optimization
@@ -1620,13 +1609,11 @@ static void iscsi_start_session_recovery(struct iscsi_session *session,
1620 if (flag == STOP_CONN_RECOVER) { 1609 if (flag == STOP_CONN_RECOVER) {
1621 conn->hdrdgst_en = 0; 1610 conn->hdrdgst_en = 0;
1622 conn->datadgst_en = 0; 1611 conn->datadgst_en = 0;
1623 /*
1624 * if this is called from the eh and and from userspace
1625 * then we only need to block once.
1626 */
1627 if (session->state == ISCSI_STATE_IN_RECOVERY && 1612 if (session->state == ISCSI_STATE_IN_RECOVERY &&
1628 old_stop_stage != STOP_CONN_RECOVER) 1613 old_stop_stage != STOP_CONN_RECOVER) {
1614 debug_scsi("blocking session\n");
1629 iscsi_block_session(session_to_cls(session)); 1615 iscsi_block_session(session_to_cls(session));
1616 }
1630 } 1617 }
1631 1618
1632 session->tt->terminate_conn(conn); 1619 session->tt->terminate_conn(conn);
@@ -1651,20 +1638,6 @@ void iscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
1651 case STOP_CONN_TERM: 1638 case STOP_CONN_TERM:
1652 iscsi_start_session_recovery(session, conn, flag); 1639 iscsi_start_session_recovery(session, conn, flag);
1653 break; 1640 break;
1654 case STOP_CONN_SUSPEND:
1655 if (session->tt->suspend_conn_recv)
1656 session->tt->suspend_conn_recv(conn);
1657
1658 mutex_lock(&conn->xmitmutex);
1659 spin_lock_bh(&session->lock);
1660
1661 conn->stop_stage = flag;
1662 conn->c_stage = ISCSI_CONN_STOPPED;
1663 set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
1664
1665 spin_unlock_bh(&session->lock);
1666 mutex_unlock(&conn->xmitmutex);
1667 break;
1668 default: 1641 default:
1669 printk(KERN_ERR "iscsi: invalid stop flag %d\n", flag); 1642 printk(KERN_ERR "iscsi: invalid stop flag %d\n", flag);
1670 } 1643 }