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.c69
1 files changed, 33 insertions, 36 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index c542d0e95e68..2865ebd557ef 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -481,8 +481,8 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
481 break; 481 break;
482 case ISCSI_OP_ASYNC_EVENT: 482 case ISCSI_OP_ASYNC_EVENT:
483 conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; 483 conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
484 /* we need sth like iscsi_async_event_rsp() */ 484 if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen))
485 rc = ISCSI_ERR_BAD_OPCODE; 485 rc = ISCSI_ERR_CONN_FAILED;
486 break; 486 break;
487 default: 487 default:
488 rc = ISCSI_ERR_BAD_OPCODE; 488 rc = ISCSI_ERR_BAD_OPCODE;
@@ -578,6 +578,27 @@ void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err)
578} 578}
579EXPORT_SYMBOL_GPL(iscsi_conn_failure); 579EXPORT_SYMBOL_GPL(iscsi_conn_failure);
580 580
581static int iscsi_xmit_imm_task(struct iscsi_conn *conn)
582{
583 struct iscsi_hdr *hdr = conn->mtask->hdr;
584 int rc, was_logout = 0;
585
586 if ((hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT) {
587 conn->session->state = ISCSI_STATE_IN_RECOVERY;
588 iscsi_block_session(session_to_cls(conn->session));
589 was_logout = 1;
590 }
591 rc = conn->session->tt->xmit_mgmt_task(conn, conn->mtask);
592 if (rc)
593 return rc;
594
595 if (was_logout) {
596 set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
597 return -ENODATA;
598 }
599 return 0;
600}
601
581/** 602/**
582 * iscsi_data_xmit - xmit any command into the scheduled connection 603 * iscsi_data_xmit - xmit any command into the scheduled connection
583 * @conn: iscsi connection 604 * @conn: iscsi connection
@@ -623,7 +644,7 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
623 conn->ctask = NULL; 644 conn->ctask = NULL;
624 } 645 }
625 if (conn->mtask) { 646 if (conn->mtask) {
626 rc = tt->xmit_mgmt_task(conn, conn->mtask); 647 rc = iscsi_xmit_imm_task(conn);
627 if (rc) 648 if (rc)
628 goto again; 649 goto again;
629 /* done with this in-progress mtask */ 650 /* done with this in-progress mtask */
@@ -638,7 +659,7 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
638 list_add_tail(&conn->mtask->running, 659 list_add_tail(&conn->mtask->running,
639 &conn->mgmt_run_list); 660 &conn->mgmt_run_list);
640 spin_unlock_bh(&conn->session->lock); 661 spin_unlock_bh(&conn->session->lock);
641 rc = tt->xmit_mgmt_task(conn, conn->mtask); 662 rc = iscsi_xmit_imm_task(conn);
642 if (rc) 663 if (rc)
643 goto again; 664 goto again;
644 } 665 }
@@ -661,8 +682,6 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
661 spin_unlock_bh(&conn->session->lock); 682 spin_unlock_bh(&conn->session->lock);
662 683
663 rc = tt->xmit_cmd_task(conn, conn->ctask); 684 rc = tt->xmit_cmd_task(conn, conn->ctask);
664 if (rc)
665 goto again;
666 685
667 spin_lock_bh(&conn->session->lock); 686 spin_lock_bh(&conn->session->lock);
668 __iscsi_put_ctask(conn->ctask); 687 __iscsi_put_ctask(conn->ctask);
@@ -778,6 +797,10 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
778 } 797 }
779 798
780 conn = session->leadconn; 799 conn = session->leadconn;
800 if (!conn) {
801 reason = FAILURE_SESSION_FREED;
802 goto fault;
803 }
781 804
782 if (!__kfifo_get(session->cmdpool.queue, (void*)&ctask, 805 if (!__kfifo_get(session->cmdpool.queue, (void*)&ctask,
783 sizeof(void*))) { 806 sizeof(void*))) {
@@ -1377,7 +1400,6 @@ iscsi_session_setup(struct iscsi_transport *iscsit,
1377 } 1400 }
1378 1401
1379 spin_lock_init(&session->lock); 1402 spin_lock_init(&session->lock);
1380 INIT_LIST_HEAD(&session->connections);
1381 1403
1382 /* initialize immediate command pool */ 1404 /* initialize immediate command pool */
1383 if (iscsi_pool_init(&session->mgmtpool, session->mgmtpool_max, 1405 if (iscsi_pool_init(&session->mgmtpool, session->mgmtpool_max,
@@ -1580,16 +1602,11 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
1580 kfree(conn->persistent_address); 1602 kfree(conn->persistent_address);
1581 __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, 1603 __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask,
1582 sizeof(void*)); 1604 sizeof(void*));
1583 list_del(&conn->item); 1605 if (session->leadconn == conn) {
1584 if (list_empty(&session->connections))
1585 session->leadconn = NULL; 1606 session->leadconn = NULL;
1586 if (session->leadconn && session->leadconn == conn)
1587 session->leadconn = container_of(session->connections.next,
1588 struct iscsi_conn, item);
1589
1590 if (session->leadconn == NULL)
1591 /* no connections exits.. reset sequencing */ 1607 /* no connections exits.. reset sequencing */
1592 session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1; 1608 session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1;
1609 }
1593 spin_unlock_bh(&session->lock); 1610 spin_unlock_bh(&session->lock);
1594 1611
1595 kfifo_free(conn->immqueue); 1612 kfifo_free(conn->immqueue);
@@ -1777,32 +1794,12 @@ int iscsi_conn_bind(struct iscsi_cls_session *cls_session,
1777 struct iscsi_cls_conn *cls_conn, int is_leading) 1794 struct iscsi_cls_conn *cls_conn, int is_leading)
1778{ 1795{
1779 struct iscsi_session *session = class_to_transport_session(cls_session); 1796 struct iscsi_session *session = class_to_transport_session(cls_session);
1780 struct iscsi_conn *tmp = ERR_PTR(-EEXIST), *conn = cls_conn->dd_data; 1797 struct iscsi_conn *conn = cls_conn->dd_data;
1781 1798
1782 /* lookup for existing connection */
1783 spin_lock_bh(&session->lock); 1799 spin_lock_bh(&session->lock);
1784 list_for_each_entry(tmp, &session->connections, item) {
1785 if (tmp == conn) {
1786 if (conn->c_stage != ISCSI_CONN_STOPPED ||
1787 conn->stop_stage == STOP_CONN_TERM) {
1788 printk(KERN_ERR "iscsi: can't bind "
1789 "non-stopped connection (%d:%d)\n",
1790 conn->c_stage, conn->stop_stage);
1791 spin_unlock_bh(&session->lock);
1792 return -EIO;
1793 }
1794 break;
1795 }
1796 }
1797 if (tmp != conn) {
1798 /* bind new iSCSI connection to session */
1799 conn->session = session;
1800 list_add(&conn->item, &session->connections);
1801 }
1802 spin_unlock_bh(&session->lock);
1803
1804 if (is_leading) 1800 if (is_leading)
1805 session->leadconn = conn; 1801 session->leadconn = conn;
1802 spin_unlock_bh(&session->lock);
1806 1803
1807 /* 1804 /*
1808 * Unblock xmitworker(), Login Phase will pass through. 1805 * Unblock xmitworker(), Login Phase will pass through.