diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-29 20:22:03 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-29 20:22:03 -0400 |
commit | a6ce22a5f61ba838b43763bf1e5be399f9dee4d0 (patch) | |
tree | 2abed83e85724bd45c5b0b842b9ce36d1c4ca160 /drivers/scsi/libiscsi.c | |
parent | 4e950f6f0189f65f8bf069cf2272649ef418f5e4 (diff) | |
parent | 09120a8cd38dbdb0c9a59ff8456cf88b510e6baa (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6: (28 commits)
[SCSI] mpt fusion: Changes in mptctl.c for logging support
[SCSI] mpt fusion: Changes in mptfc.c mptlan.c mptsas.c and mptspi.c for logging support
[SCSI] mpt fusion: Changes in mptscsih.c for logging support
[SCSI] mpt fusion: Changes in mptbase.c for logging support
[SCSI] mpt fusion: logging support in Kconfig, Makefile, mptbase.h and addition of mptdebug.h
[SCSI] libsas: Fix potential NULL dereference in sas_smp_get_phy_events()
[SCSI] bsg: Fix build for CONFIG_BLOCK=n
[SCSI] aacraid: fix Sunrise Lake reset handling
[SCSI] aacraid: add SCSI SYNCHONIZE_CACHE range checking
[SCSI] add easyRAID to the no report luns blacklist
[SCSI] advansys: lindent and other large, uninteresting changes
[SCSI] aic79xx, aic7xxx: Fix incorrect width setting
[SCSI] qla2xxx: fix to honor ignored parameters in sysfs attributes
[SCSI] aacraid: draw line in sand, sundry cleanup and version update
[SCSI] iscsi_tcp: Turn off bounce buffers
[SCSI] libiscsi: fix cmd seqeunce number checking
[SCSI] iscsi_tcp, ib_iser Enable module refcounting for iscsi host template
[SCSI] libiscsi: make sure session is not blocked when removing host
[SCSI] libsas: Remove PCI dependencies
[SCSI] simscsi: convert to use the data buffer accessors
...
Diffstat (limited to 'drivers/scsi/libiscsi.c')
-rw-r--r-- | drivers/scsi/libiscsi.c | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 4d85ce100192..5606d1e62978 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
@@ -596,9 +596,16 @@ static void iscsi_prep_mtask(struct iscsi_conn *conn, | |||
596 | nop->cmdsn = cpu_to_be32(session->cmdsn); | 596 | nop->cmdsn = cpu_to_be32(session->cmdsn); |
597 | if (hdr->itt != RESERVED_ITT) { | 597 | if (hdr->itt != RESERVED_ITT) { |
598 | hdr->itt = build_itt(mtask->itt, conn->id, session->age); | 598 | hdr->itt = build_itt(mtask->itt, conn->id, session->age); |
599 | /* | ||
600 | * TODO: We always use immediate, so we never hit this. | ||
601 | * If we start to send tmfs or nops as non-immediate then | ||
602 | * we should start checking the cmdsn numbers for mgmt tasks. | ||
603 | */ | ||
599 | if (conn->c_stage == ISCSI_CONN_STARTED && | 604 | if (conn->c_stage == ISCSI_CONN_STARTED && |
600 | !(hdr->opcode & ISCSI_OP_IMMEDIATE)) | 605 | !(hdr->opcode & ISCSI_OP_IMMEDIATE)) { |
606 | session->queued_cmdsn++; | ||
601 | session->cmdsn++; | 607 | session->cmdsn++; |
608 | } | ||
602 | } | 609 | } |
603 | 610 | ||
604 | if (session->tt->init_mgmt_task) | 611 | if (session->tt->init_mgmt_task) |
@@ -641,9 +648,11 @@ static int iscsi_check_cmdsn_window_closed(struct iscsi_conn *conn) | |||
641 | /* | 648 | /* |
642 | * Check for iSCSI window and take care of CmdSN wrap-around | 649 | * Check for iSCSI window and take care of CmdSN wrap-around |
643 | */ | 650 | */ |
644 | if (!iscsi_sna_lte(session->cmdsn, session->max_cmdsn)) { | 651 | if (!iscsi_sna_lte(session->queued_cmdsn, session->max_cmdsn)) { |
645 | debug_scsi("iSCSI CmdSN closed. MaxCmdSN %u CmdSN %u\n", | 652 | debug_scsi("iSCSI CmdSN closed. ExpCmdSn %u MaxCmdSN %u " |
646 | session->max_cmdsn, session->cmdsn); | 653 | "CmdSN %u/%u\n", session->exp_cmdsn, |
654 | session->max_cmdsn, session->cmdsn, | ||
655 | session->queued_cmdsn); | ||
647 | return -ENOSPC; | 656 | return -ENOSPC; |
648 | } | 657 | } |
649 | return 0; | 658 | return 0; |
@@ -722,11 +731,6 @@ check_mgmt: | |||
722 | 731 | ||
723 | /* process command queue */ | 732 | /* process command queue */ |
724 | while (!list_empty(&conn->xmitqueue)) { | 733 | while (!list_empty(&conn->xmitqueue)) { |
725 | rc = iscsi_check_cmdsn_window_closed(conn); | ||
726 | if (rc) { | ||
727 | spin_unlock_bh(&conn->session->lock); | ||
728 | return rc; | ||
729 | } | ||
730 | /* | 734 | /* |
731 | * iscsi tcp may readd the task to the xmitqueue to send | 735 | * iscsi tcp may readd the task to the xmitqueue to send |
732 | * write data | 736 | * write data |
@@ -834,12 +838,6 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
834 | goto fault; | 838 | goto fault; |
835 | } | 839 | } |
836 | 840 | ||
837 | /* | ||
838 | * We check this here and in data xmit, because if we get to the point | ||
839 | * that this check is hitting the window then we have enough IO in | ||
840 | * flight and enough IO waiting to be transmitted it is better | ||
841 | * to let the scsi/block layer queue up. | ||
842 | */ | ||
843 | if (iscsi_check_cmdsn_window_closed(conn)) { | 841 | if (iscsi_check_cmdsn_window_closed(conn)) { |
844 | reason = FAILURE_WINDOW_CLOSED; | 842 | reason = FAILURE_WINDOW_CLOSED; |
845 | goto reject; | 843 | goto reject; |
@@ -850,6 +848,8 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
850 | reason = FAILURE_OOM; | 848 | reason = FAILURE_OOM; |
851 | goto reject; | 849 | goto reject; |
852 | } | 850 | } |
851 | session->queued_cmdsn++; | ||
852 | |||
853 | sc->SCp.phase = session->age; | 853 | sc->SCp.phase = session->age; |
854 | sc->SCp.ptr = (char *)ctask; | 854 | sc->SCp.ptr = (char *)ctask; |
855 | 855 | ||
@@ -1140,7 +1140,13 @@ static void fail_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, | |||
1140 | if (!sc) | 1140 | if (!sc) |
1141 | return; | 1141 | return; |
1142 | 1142 | ||
1143 | if (ctask->state != ISCSI_TASK_PENDING) | 1143 | if (ctask->state == ISCSI_TASK_PENDING) |
1144 | /* | ||
1145 | * cmd never made it to the xmit thread, so we should not count | ||
1146 | * the cmd in the sequencing | ||
1147 | */ | ||
1148 | conn->session->queued_cmdsn--; | ||
1149 | else | ||
1144 | conn->session->tt->cleanup_cmd_task(conn, ctask); | 1150 | conn->session->tt->cleanup_cmd_task(conn, ctask); |
1145 | iscsi_ctask_mtask_cleanup(ctask); | 1151 | iscsi_ctask_mtask_cleanup(ctask); |
1146 | 1152 | ||
@@ -1392,7 +1398,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit, | |||
1392 | session->state = ISCSI_STATE_FREE; | 1398 | session->state = ISCSI_STATE_FREE; |
1393 | session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX; | 1399 | session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX; |
1394 | session->cmds_max = cmds_max; | 1400 | session->cmds_max = cmds_max; |
1395 | session->cmdsn = initial_cmdsn; | 1401 | session->queued_cmdsn = session->cmdsn = initial_cmdsn; |
1396 | session->exp_cmdsn = initial_cmdsn + 1; | 1402 | session->exp_cmdsn = initial_cmdsn + 1; |
1397 | session->max_cmdsn = initial_cmdsn + 1; | 1403 | session->max_cmdsn = initial_cmdsn + 1; |
1398 | session->max_r2t = 1; | 1404 | session->max_r2t = 1; |
@@ -1473,6 +1479,7 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session) | |||
1473 | struct iscsi_session *session = iscsi_hostdata(shost->hostdata); | 1479 | struct iscsi_session *session = iscsi_hostdata(shost->hostdata); |
1474 | struct module *owner = cls_session->transport->owner; | 1480 | struct module *owner = cls_session->transport->owner; |
1475 | 1481 | ||
1482 | iscsi_unblock_session(cls_session); | ||
1476 | scsi_remove_host(shost); | 1483 | scsi_remove_host(shost); |
1477 | 1484 | ||
1478 | iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds); | 1485 | iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds); |
@@ -1615,11 +1622,8 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) | |||
1615 | kfree(conn->persistent_address); | 1622 | kfree(conn->persistent_address); |
1616 | __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, | 1623 | __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, |
1617 | sizeof(void*)); | 1624 | sizeof(void*)); |
1618 | if (session->leadconn == conn) { | 1625 | if (session->leadconn == conn) |
1619 | session->leadconn = NULL; | 1626 | session->leadconn = NULL; |
1620 | /* no connections exits.. reset sequencing */ | ||
1621 | session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1; | ||
1622 | } | ||
1623 | spin_unlock_bh(&session->lock); | 1627 | spin_unlock_bh(&session->lock); |
1624 | 1628 | ||
1625 | kfifo_free(conn->mgmtqueue); | 1629 | kfifo_free(conn->mgmtqueue); |
@@ -1649,6 +1653,7 @@ int iscsi_conn_start(struct iscsi_cls_conn *cls_conn) | |||
1649 | spin_lock_bh(&session->lock); | 1653 | spin_lock_bh(&session->lock); |
1650 | conn->c_stage = ISCSI_CONN_STARTED; | 1654 | conn->c_stage = ISCSI_CONN_STARTED; |
1651 | session->state = ISCSI_STATE_LOGGED_IN; | 1655 | session->state = ISCSI_STATE_LOGGED_IN; |
1656 | session->queued_cmdsn = session->cmdsn; | ||
1652 | 1657 | ||
1653 | switch(conn->stop_stage) { | 1658 | switch(conn->stop_stage) { |
1654 | case STOP_CONN_RECOVER: | 1659 | case STOP_CONN_RECOVER: |