aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
authorDilip Kumar Uppugandla <dilip@purestorage.com>2015-12-17 14:57:11 -0500
committerNicholas Bellinger <nab@linux-iscsi.org>2016-01-07 16:57:50 -0500
commit3bb67df5b5f880a1c9c1086308cf2b981d824da5 (patch)
tree4c186864e131f65f338b9c81d19d5d6ac3efd4d0 /drivers/scsi/qla2xxx
parente7b42e335f129f0685ab94bcd34104163df38323 (diff)
qla2xxx: Check for online flag instead of active reset when transmitting responses
Driver has following initialization sequence for Target mode 1. Driver initialization starts 2. ISP Abort is scheduled when the target is enabled. qla2xxx [0000:04:00.0]-4807:25: ISP abort scheduled qla2xxx [0000:04:00.0]-00af:25: Performing ISP error recovery - ha=ffff880caa9e0000. 3. DPC thread starts the ISP Abort 4. While DPC is resetting the chip and initializing the firmware, we get async events from the firmware about P2P mode, LOOP UP and PORT UPDATE. 5. PRLI from a initiator is delivered to us followed by a PLOGI and then a SCSI command which creates a session. 6. If the SCSI command is a WRITE in this case, we issue XFR RDY and it gets dropped as can be seen with messages RESET-XFR because ISP Abort is still active qla2xxx [0000:04:00.0]-e902:25: RESET-XFR active/old-count/new-count = 1/1/1. 7. If the SCSI command is a READ, we issue RESPONSE and they get dropped as well because Abort is still active. qla2xxx [0000:04:00.0]-e901:25: RESET-RSP active/old-count/new-count = 1/1/1 8. Now eventually, ISP Abort finishes clearing the DPC flags. qla2xxx [0000:04:00.0]-8822:25: qla2x00_abort_isp succeeded. qla2xxx [0000:04:00.0]-4808:25: ISP abort end. 9. Since we dropped SCSI commands silently (without any responses sent to the initiator) initiator waits for a SCSI timeout (which is 60 seconds in our case), Sends an ABTS which fails since there no se_cmd found for the tag that ABTS is referencing as the commands were cleaned up in Step 6 and 7. 10. Initiator send an IO after the ABTS which succeed fine. To fix the above case, the following changes have been made: - To prevent target from dropping commands silently, use the online flag instead to check for an active chip reset. Once the port is online during a chip reset phase, we are good to process the commands. - Clean up qla2x00_restart_isp to not set the online flag and process ATIO as it is unnecessary. During a chip reset, interrupts are enabled only after setting the online flag to 1, so ATIO's won't be missed and hence no need to process ATIO's after setting the online flag. Signed-off-by: Dilip Kumar Uppugandla <dilip@purestorage.com> Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c34
-rw-r--r--drivers/scsi/qla2xxx/qla_target.c34
2 files changed, 37 insertions, 31 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 993dd25279ff..52a87657c7dd 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -3065,6 +3065,26 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
3065 atomic_set(&vha->loop_state, LOOP_READY); 3065 atomic_set(&vha->loop_state, LOOP_READY);
3066 ql_dbg(ql_dbg_disc, vha, 0x2069, 3066 ql_dbg(ql_dbg_disc, vha, 0x2069,
3067 "LOOP READY.\n"); 3067 "LOOP READY.\n");
3068
3069 /*
3070 * Process any ATIO queue entries that came in
3071 * while we weren't online.
3072 */
3073 if (qla_tgt_mode_enabled(vha)) {
3074 if (IS_QLA27XX(ha) || IS_QLA83XX(ha)) {
3075 spin_lock_irqsave(&ha->tgt.atio_lock,
3076 flags);
3077 qlt_24xx_process_atio_queue(vha, 0);
3078 spin_unlock_irqrestore(
3079 &ha->tgt.atio_lock, flags);
3080 } else {
3081 spin_lock_irqsave(&ha->hardware_lock,
3082 flags);
3083 qlt_24xx_process_atio_queue(vha, 1);
3084 spin_unlock_irqrestore(
3085 &ha->hardware_lock, flags);
3086 }
3087 }
3068 } 3088 }
3069 } 3089 }
3070 3090
@@ -4919,7 +4939,6 @@ qla2x00_restart_isp(scsi_qla_host_t *vha)
4919 struct qla_hw_data *ha = vha->hw; 4939 struct qla_hw_data *ha = vha->hw;
4920 struct req_que *req = ha->req_q_map[0]; 4940 struct req_que *req = ha->req_q_map[0];
4921 struct rsp_que *rsp = ha->rsp_q_map[0]; 4941 struct rsp_que *rsp = ha->rsp_q_map[0];
4922 unsigned long flags, flags2;
4923 4942
4924 /* If firmware needs to be loaded */ 4943 /* If firmware needs to be loaded */
4925 if (qla2x00_isp_firmware(vha)) { 4944 if (qla2x00_isp_firmware(vha)) {
@@ -4941,19 +4960,6 @@ qla2x00_restart_isp(scsi_qla_host_t *vha)
4941 /* Issue a marker after FW becomes ready. */ 4960 /* Issue a marker after FW becomes ready. */
4942 qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL); 4961 qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL);
4943 4962
4944 vha->flags.online = 1;
4945
4946 /*
4947 * Process any ATIO queue entries that came in
4948 * while we weren't online.
4949 */
4950 spin_lock_irqsave(&ha->hardware_lock, flags);
4951 spin_lock_irqsave(&ha->tgt.atio_lock, flags2);
4952 if (qla_tgt_mode_enabled(vha))
4953 qlt_24xx_process_atio_queue(vha, 1);
4954 spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2);
4955 spin_unlock_irqrestore(&ha->hardware_lock, flags);
4956
4957 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); 4963 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
4958 } 4964 }
4959 4965
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index da35f51ea256..c7ab9e69c881 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -229,7 +229,7 @@ static inline void qlt_decr_num_pend_cmds(struct scsi_qla_host *vha)
229 spin_unlock_irqrestore(&vha->hw->tgt.q_full_lock, flags); 229 spin_unlock_irqrestore(&vha->hw->tgt.q_full_lock, flags);
230} 230}
231 231
232static void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha, 232static bool qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
233 struct atio_from_isp *atio, uint8_t ha_locked) 233 struct atio_from_isp *atio, uint8_t ha_locked)
234{ 234{
235 ql_dbg(ql_dbg_tgt, vha, 0xe072, 235 ql_dbg(ql_dbg_tgt, vha, 0xe072,
@@ -285,7 +285,7 @@ static void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
285 break; 285 break;
286 } 286 }
287 287
288 return; 288 return false;
289} 289}
290 290
291void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt) 291void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt)
@@ -1738,15 +1738,15 @@ void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd)
1738 1738
1739 spin_lock_irqsave(&ha->hardware_lock, flags); 1739 spin_lock_irqsave(&ha->hardware_lock, flags);
1740 1740
1741 if (qla2x00_reset_active(vha) || mcmd->reset_count != ha->chip_reset) { 1741 if (!vha->flags.online || mcmd->reset_count != ha->chip_reset) {
1742 /* 1742 /*
1743 * Either a chip reset is active or this request was from 1743 * Either the port is not online or this request was from
1744 * previous life, just abort the processing. 1744 * previous life, just abort the processing.
1745 */ 1745 */
1746 ql_dbg(ql_dbg_async, vha, 0xe100, 1746 ql_dbg(ql_dbg_async, vha, 0xe100,
1747 "RESET-TMR active/old-count/new-count = %d/%d/%d.\n", 1747 "RESET-TMR online/active/old-count/new-count = %d/%d/%d/%d.\n",
1748 qla2x00_reset_active(vha), mcmd->reset_count, 1748 vha->flags.online, qla2x00_reset_active(vha),
1749 ha->chip_reset); 1749 mcmd->reset_count, ha->chip_reset);
1750 ha->tgt.tgt_ops->free_mcmd(mcmd); 1750 ha->tgt.tgt_ops->free_mcmd(mcmd);
1751 spin_unlock_irqrestore(&ha->hardware_lock, flags); 1751 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1752 return; 1752 return;
@@ -2693,17 +2693,17 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
2693 else 2693 else
2694 vha->tgt_counters.core_qla_que_buf++; 2694 vha->tgt_counters.core_qla_que_buf++;
2695 2695
2696 if (qla2x00_reset_active(vha) || cmd->reset_count != ha->chip_reset) { 2696 if (!vha->flags.online || cmd->reset_count != ha->chip_reset) {
2697 /* 2697 /*
2698 * Either a chip reset is active or this request was from 2698 * Either the port is not online or this request was from
2699 * previous life, just abort the processing. 2699 * previous life, just abort the processing.
2700 */ 2700 */
2701 cmd->state = QLA_TGT_STATE_PROCESSED; 2701 cmd->state = QLA_TGT_STATE_PROCESSED;
2702 qlt_abort_cmd_on_host_reset(cmd->vha, cmd); 2702 qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
2703 ql_dbg(ql_dbg_async, vha, 0xe101, 2703 ql_dbg(ql_dbg_async, vha, 0xe101,
2704 "RESET-RSP active/old-count/new-count = %d/%d/%d.\n", 2704 "RESET-RSP online/active/old-count/new-count = %d/%d/%d/%d.\n",
2705 qla2x00_reset_active(vha), cmd->reset_count, 2705 vha->flags.online, qla2x00_reset_active(vha),
2706 ha->chip_reset); 2706 cmd->reset_count, ha->chip_reset);
2707 spin_unlock_irqrestore(&ha->hardware_lock, flags); 2707 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2708 return 0; 2708 return 0;
2709 } 2709 }
@@ -2834,18 +2834,18 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
2834 2834
2835 spin_lock_irqsave(&ha->hardware_lock, flags); 2835 spin_lock_irqsave(&ha->hardware_lock, flags);
2836 2836
2837 if (qla2x00_reset_active(vha) || (cmd->reset_count != ha->chip_reset) || 2837 if (!vha->flags.online || (cmd->reset_count != ha->chip_reset) ||
2838 (cmd->sess && cmd->sess->deleted == QLA_SESS_DELETION_IN_PROGRESS)) { 2838 (cmd->sess && cmd->sess->deleted == QLA_SESS_DELETION_IN_PROGRESS)) {
2839 /* 2839 /*
2840 * Either a chip reset is active or this request was from 2840 * Either the port is not online or this request was from
2841 * previous life, just abort the processing. 2841 * previous life, just abort the processing.
2842 */ 2842 */
2843 cmd->state = QLA_TGT_STATE_NEED_DATA; 2843 cmd->state = QLA_TGT_STATE_NEED_DATA;
2844 qlt_abort_cmd_on_host_reset(cmd->vha, cmd); 2844 qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
2845 ql_dbg(ql_dbg_async, vha, 0xe102, 2845 ql_dbg(ql_dbg_async, vha, 0xe102,
2846 "RESET-XFR active/old-count/new-count = %d/%d/%d.\n", 2846 "RESET-XFR online/active/old-count/new-count = %d/%d/%d/%d.\n",
2847 qla2x00_reset_active(vha), cmd->reset_count, 2847 vha->flags.online, qla2x00_reset_active(vha),
2848 ha->chip_reset); 2848 cmd->reset_count, ha->chip_reset);
2849 spin_unlock_irqrestore(&ha->hardware_lock, flags); 2849 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2850 return 0; 2850 return 0;
2851 } 2851 }