diff options
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 1 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 1 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 6 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 44 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_target.c | 99 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_target.h | 4 |
7 files changed, 129 insertions, 28 deletions
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index c4fc32e9aaf9..96c5ffe1e831 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -2936,6 +2936,7 @@ struct qlt_hw_data { | |||
2936 | uint32_t leak_exchg_thresh_hold; | 2936 | uint32_t leak_exchg_thresh_hold; |
2937 | spinlock_t sess_lock; | 2937 | spinlock_t sess_lock; |
2938 | int rspq_vector_cpuid; | 2938 | int rspq_vector_cpuid; |
2939 | spinlock_t atio_lock ____cacheline_aligned; | ||
2939 | }; | 2940 | }; |
2940 | 2941 | ||
2941 | #define MAX_QFULL_CMDS_ALLOC 8192 | 2942 | #define MAX_QFULL_CMDS_ALLOC 8192 |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index a1b538444cd2..0103e468e357 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -778,5 +778,6 @@ extern int qla_get_exlogin_status(scsi_qla_host_t *, uint16_t *, | |||
778 | extern int qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr); | 778 | extern int qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr); |
779 | extern int qla_get_exchoffld_status(scsi_qla_host_t *, uint16_t *, uint16_t *); | 779 | extern int qla_get_exchoffld_status(scsi_qla_host_t *, uint16_t *, uint16_t *); |
780 | extern int qla_set_exchoffld_mem_cfg(scsi_qla_host_t *, dma_addr_t); | 780 | extern int qla_set_exchoffld_mem_cfg(scsi_qla_host_t *, dma_addr_t); |
781 | extern void qlt_handle_abts_recv(struct scsi_qla_host *, response_t *); | ||
781 | 782 | ||
782 | #endif /* _QLA_GBL_H */ | 783 | #endif /* _QLA_GBL_H */ |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 35d1ea8a58d1..993dd25279ff 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -4919,7 +4919,7 @@ qla2x00_restart_isp(scsi_qla_host_t *vha) | |||
4919 | struct qla_hw_data *ha = vha->hw; | 4919 | struct qla_hw_data *ha = vha->hw; |
4920 | struct req_que *req = ha->req_q_map[0]; | 4920 | struct req_que *req = ha->req_q_map[0]; |
4921 | struct rsp_que *rsp = ha->rsp_q_map[0]; | 4921 | struct rsp_que *rsp = ha->rsp_q_map[0]; |
4922 | unsigned long flags; | 4922 | unsigned long flags, flags2; |
4923 | 4923 | ||
4924 | /* If firmware needs to be loaded */ | 4924 | /* If firmware needs to be loaded */ |
4925 | if (qla2x00_isp_firmware(vha)) { | 4925 | if (qla2x00_isp_firmware(vha)) { |
@@ -4948,8 +4948,10 @@ qla2x00_restart_isp(scsi_qla_host_t *vha) | |||
4948 | * while we weren't online. | 4948 | * while we weren't online. |
4949 | */ | 4949 | */ |
4950 | spin_lock_irqsave(&ha->hardware_lock, flags); | 4950 | spin_lock_irqsave(&ha->hardware_lock, flags); |
4951 | spin_lock_irqsave(&ha->tgt.atio_lock, flags2); | ||
4951 | if (qla_tgt_mode_enabled(vha)) | 4952 | if (qla_tgt_mode_enabled(vha)) |
4952 | qlt_24xx_process_atio_queue(vha); | 4953 | qlt_24xx_process_atio_queue(vha, 1); |
4954 | spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2); | ||
4953 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 4955 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
4954 | 4956 | ||
4955 | set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); | 4957 | set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 3e89122e6db0..d4d65eb0e9b4 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -2605,8 +2605,14 @@ process_err: | |||
2605 | qla24xx_els_ct_entry(vha, rsp->req, pkt, ELS_IOCB_TYPE); | 2605 | qla24xx_els_ct_entry(vha, rsp->req, pkt, ELS_IOCB_TYPE); |
2606 | break; | 2606 | break; |
2607 | case ABTS_RECV_24XX: | 2607 | case ABTS_RECV_24XX: |
2608 | /* ensure that the ATIO queue is empty */ | 2608 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { |
2609 | qlt_24xx_process_atio_queue(vha); | 2609 | /* ensure that the ATIO queue is empty */ |
2610 | qlt_handle_abts_recv(vha, (response_t *)pkt); | ||
2611 | break; | ||
2612 | } else { | ||
2613 | /* drop through */ | ||
2614 | qlt_24xx_process_atio_queue(vha, 1); | ||
2615 | } | ||
2610 | case ABTS_RESP_24XX: | 2616 | case ABTS_RESP_24XX: |
2611 | case CTIO_TYPE7: | 2617 | case CTIO_TYPE7: |
2612 | case NOTIFY_ACK_TYPE: | 2618 | case NOTIFY_ACK_TYPE: |
@@ -2773,13 +2779,22 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
2773 | case INTR_RSP_QUE_UPDATE_83XX: | 2779 | case INTR_RSP_QUE_UPDATE_83XX: |
2774 | qla24xx_process_response_queue(vha, rsp); | 2780 | qla24xx_process_response_queue(vha, rsp); |
2775 | break; | 2781 | break; |
2776 | case INTR_ATIO_QUE_UPDATE: | 2782 | case INTR_ATIO_QUE_UPDATE:{ |
2777 | qlt_24xx_process_atio_queue(vha); | 2783 | unsigned long flags2; |
2784 | spin_lock_irqsave(&ha->tgt.atio_lock, flags2); | ||
2785 | qlt_24xx_process_atio_queue(vha, 1); | ||
2786 | spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2); | ||
2778 | break; | 2787 | break; |
2779 | case INTR_ATIO_RSP_QUE_UPDATE: | 2788 | } |
2780 | qlt_24xx_process_atio_queue(vha); | 2789 | case INTR_ATIO_RSP_QUE_UPDATE: { |
2790 | unsigned long flags2; | ||
2791 | spin_lock_irqsave(&ha->tgt.atio_lock, flags2); | ||
2792 | qlt_24xx_process_atio_queue(vha, 1); | ||
2793 | spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2); | ||
2794 | |||
2781 | qla24xx_process_response_queue(vha, rsp); | 2795 | qla24xx_process_response_queue(vha, rsp); |
2782 | break; | 2796 | break; |
2797 | } | ||
2783 | default: | 2798 | default: |
2784 | ql_dbg(ql_dbg_async, vha, 0x504f, | 2799 | ql_dbg(ql_dbg_async, vha, 0x504f, |
2785 | "Unrecognized interrupt type (%d).\n", stat * 0xff); | 2800 | "Unrecognized interrupt type (%d).\n", stat * 0xff); |
@@ -2938,13 +2953,22 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
2938 | case INTR_RSP_QUE_UPDATE_83XX: | 2953 | case INTR_RSP_QUE_UPDATE_83XX: |
2939 | qla24xx_process_response_queue(vha, rsp); | 2954 | qla24xx_process_response_queue(vha, rsp); |
2940 | break; | 2955 | break; |
2941 | case INTR_ATIO_QUE_UPDATE: | 2956 | case INTR_ATIO_QUE_UPDATE:{ |
2942 | qlt_24xx_process_atio_queue(vha); | 2957 | unsigned long flags2; |
2958 | spin_lock_irqsave(&ha->tgt.atio_lock, flags2); | ||
2959 | qlt_24xx_process_atio_queue(vha, 1); | ||
2960 | spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2); | ||
2943 | break; | 2961 | break; |
2944 | case INTR_ATIO_RSP_QUE_UPDATE: | 2962 | } |
2945 | qlt_24xx_process_atio_queue(vha); | 2963 | case INTR_ATIO_RSP_QUE_UPDATE: { |
2964 | unsigned long flags2; | ||
2965 | spin_lock_irqsave(&ha->tgt.atio_lock, flags2); | ||
2966 | qlt_24xx_process_atio_queue(vha, 1); | ||
2967 | spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2); | ||
2968 | |||
2946 | qla24xx_process_response_queue(vha, rsp); | 2969 | qla24xx_process_response_queue(vha, rsp); |
2947 | break; | 2970 | break; |
2971 | } | ||
2948 | default: | 2972 | default: |
2949 | ql_dbg(ql_dbg_async, vha, 0x5051, | 2973 | ql_dbg(ql_dbg_async, vha, 0x5051, |
2950 | "Unrecognized interrupt type (%d).\n", stat & 0xff); | 2974 | "Unrecognized interrupt type (%d).\n", stat & 0xff); |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 0484acb3ff16..eff8bea0dab3 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -2337,6 +2337,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2337 | INIT_LIST_HEAD(&ha->tgt.q_full_list); | 2337 | INIT_LIST_HEAD(&ha->tgt.q_full_list); |
2338 | spin_lock_init(&ha->tgt.q_full_lock); | 2338 | spin_lock_init(&ha->tgt.q_full_lock); |
2339 | spin_lock_init(&ha->tgt.sess_lock); | 2339 | spin_lock_init(&ha->tgt.sess_lock); |
2340 | spin_lock_init(&ha->tgt.atio_lock); | ||
2341 | |||
2340 | 2342 | ||
2341 | /* Clear our data area */ | 2343 | /* Clear our data area */ |
2342 | ha->bars = bars; | 2344 | ha->bars = bars; |
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index d3cd271eb127..ac7a7549c669 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c | |||
@@ -100,7 +100,7 @@ enum fcp_resp_rsp_codes { | |||
100 | */ | 100 | */ |
101 | /* Predefs for callbacks handed to qla2xxx LLD */ | 101 | /* Predefs for callbacks handed to qla2xxx LLD */ |
102 | static void qlt_24xx_atio_pkt(struct scsi_qla_host *ha, | 102 | static void qlt_24xx_atio_pkt(struct scsi_qla_host *ha, |
103 | struct atio_from_isp *pkt); | 103 | struct atio_from_isp *pkt, uint8_t); |
104 | static void qlt_response_pkt(struct scsi_qla_host *ha, response_t *pkt); | 104 | static void qlt_response_pkt(struct scsi_qla_host *ha, response_t *pkt); |
105 | static int qlt_issue_task_mgmt(struct qla_tgt_sess *sess, uint32_t lun, | 105 | static int qlt_issue_task_mgmt(struct qla_tgt_sess *sess, uint32_t lun, |
106 | int fn, void *iocb, int flags); | 106 | int fn, void *iocb, int flags); |
@@ -230,7 +230,7 @@ static inline void qlt_decr_num_pend_cmds(struct scsi_qla_host *vha) | |||
230 | } | 230 | } |
231 | 231 | ||
232 | static void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha, | 232 | static void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha, |
233 | struct atio_from_isp *atio) | 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, |
236 | "%s: qla_target(%d): type %x ox_id %04x\n", | 236 | "%s: qla_target(%d): type %x ox_id %04x\n", |
@@ -251,7 +251,7 @@ static void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha, | |||
251 | atio->u.isp24.fcp_hdr.d_id[2]); | 251 | atio->u.isp24.fcp_hdr.d_id[2]); |
252 | break; | 252 | break; |
253 | } | 253 | } |
254 | qlt_24xx_atio_pkt(host, atio); | 254 | qlt_24xx_atio_pkt(host, atio, ha_locked); |
255 | break; | 255 | break; |
256 | } | 256 | } |
257 | 257 | ||
@@ -274,7 +274,7 @@ static void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha, | |||
274 | break; | 274 | break; |
275 | } | 275 | } |
276 | } | 276 | } |
277 | qlt_24xx_atio_pkt(host, atio); | 277 | qlt_24xx_atio_pkt(host, atio, ha_locked); |
278 | break; | 278 | break; |
279 | } | 279 | } |
280 | 280 | ||
@@ -1211,7 +1211,7 @@ void qlt_stop_phase2(struct qla_tgt *tgt) | |||
1211 | 1211 | ||
1212 | mutex_lock(&vha->vha_tgt.tgt_mutex); | 1212 | mutex_lock(&vha->vha_tgt.tgt_mutex); |
1213 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1213 | spin_lock_irqsave(&ha->hardware_lock, flags); |
1214 | while (tgt->irq_cmd_count != 0) { | 1214 | while ((tgt->irq_cmd_count != 0) || (tgt->atio_irq_cmd_count != 0)) { |
1215 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1215 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
1216 | udelay(2); | 1216 | udelay(2); |
1217 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1217 | spin_lock_irqsave(&ha->hardware_lock, flags); |
@@ -5350,11 +5350,12 @@ qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha, | |||
5350 | /* ha->hardware_lock supposed to be held on entry */ | 5350 | /* ha->hardware_lock supposed to be held on entry */ |
5351 | /* called via callback from qla2xxx */ | 5351 | /* called via callback from qla2xxx */ |
5352 | static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, | 5352 | static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, |
5353 | struct atio_from_isp *atio) | 5353 | struct atio_from_isp *atio, uint8_t ha_locked) |
5354 | { | 5354 | { |
5355 | struct qla_hw_data *ha = vha->hw; | 5355 | struct qla_hw_data *ha = vha->hw; |
5356 | struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; | 5356 | struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; |
5357 | int rc; | 5357 | int rc; |
5358 | unsigned long flags; | ||
5358 | 5359 | ||
5359 | if (unlikely(tgt == NULL)) { | 5360 | if (unlikely(tgt == NULL)) { |
5360 | ql_dbg(ql_dbg_io, vha, 0x3064, | 5361 | ql_dbg(ql_dbg_io, vha, 0x3064, |
@@ -5366,7 +5367,7 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, | |||
5366 | * Otherwise, some commands can stuck. | 5367 | * Otherwise, some commands can stuck. |
5367 | */ | 5368 | */ |
5368 | 5369 | ||
5369 | tgt->irq_cmd_count++; | 5370 | tgt->atio_irq_cmd_count++; |
5370 | 5371 | ||
5371 | switch (atio->u.raw.entry_type) { | 5372 | switch (atio->u.raw.entry_type) { |
5372 | case ATIO_TYPE7: | 5373 | case ATIO_TYPE7: |
@@ -5376,7 +5377,11 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, | |||
5376 | "qla_target(%d): ATIO_TYPE7 " | 5377 | "qla_target(%d): ATIO_TYPE7 " |
5377 | "received with UNKNOWN exchange address, " | 5378 | "received with UNKNOWN exchange address, " |
5378 | "sending QUEUE_FULL\n", vha->vp_idx); | 5379 | "sending QUEUE_FULL\n", vha->vp_idx); |
5380 | if (!ha_locked) | ||
5381 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
5379 | qlt_send_busy(vha, atio, SAM_STAT_TASK_SET_FULL); | 5382 | qlt_send_busy(vha, atio, SAM_STAT_TASK_SET_FULL); |
5383 | if (!ha_locked) | ||
5384 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
5380 | break; | 5385 | break; |
5381 | } | 5386 | } |
5382 | 5387 | ||
@@ -5385,7 +5390,7 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, | |||
5385 | if (likely(atio->u.isp24.fcp_cmnd.task_mgmt_flags == 0)) { | 5390 | if (likely(atio->u.isp24.fcp_cmnd.task_mgmt_flags == 0)) { |
5386 | rc = qlt_chk_qfull_thresh_hold(vha, atio); | 5391 | rc = qlt_chk_qfull_thresh_hold(vha, atio); |
5387 | if (rc != 0) { | 5392 | if (rc != 0) { |
5388 | tgt->irq_cmd_count--; | 5393 | tgt->atio_irq_cmd_count--; |
5389 | return; | 5394 | return; |
5390 | } | 5395 | } |
5391 | rc = qlt_handle_cmd_for_atio(vha, atio); | 5396 | rc = qlt_handle_cmd_for_atio(vha, atio); |
@@ -5394,11 +5399,20 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, | |||
5394 | } | 5399 | } |
5395 | if (unlikely(rc != 0)) { | 5400 | if (unlikely(rc != 0)) { |
5396 | if (rc == -ESRCH) { | 5401 | if (rc == -ESRCH) { |
5402 | if (!ha_locked) | ||
5403 | spin_lock_irqsave | ||
5404 | (&ha->hardware_lock, flags); | ||
5405 | |||
5397 | #if 1 /* With TERM EXCHANGE some FC cards refuse to boot */ | 5406 | #if 1 /* With TERM EXCHANGE some FC cards refuse to boot */ |
5398 | qlt_send_busy(vha, atio, SAM_STAT_BUSY); | 5407 | qlt_send_busy(vha, atio, SAM_STAT_BUSY); |
5399 | #else | 5408 | #else |
5400 | qlt_send_term_exchange(vha, NULL, atio, 1); | 5409 | qlt_send_term_exchange(vha, NULL, atio, 1); |
5401 | #endif | 5410 | #endif |
5411 | |||
5412 | if (!ha_locked) | ||
5413 | spin_unlock_irqrestore | ||
5414 | (&ha->hardware_lock, flags); | ||
5415 | |||
5402 | } else { | 5416 | } else { |
5403 | if (tgt->tgt_stop) { | 5417 | if (tgt->tgt_stop) { |
5404 | ql_dbg(ql_dbg_tgt, vha, 0xe059, | 5418 | ql_dbg(ql_dbg_tgt, vha, 0xe059, |
@@ -5410,7 +5424,13 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, | |||
5410 | "qla_target(%d): Unable to send " | 5424 | "qla_target(%d): Unable to send " |
5411 | "command to target, sending BUSY " | 5425 | "command to target, sending BUSY " |
5412 | "status.\n", vha->vp_idx); | 5426 | "status.\n", vha->vp_idx); |
5427 | if (!ha_locked) | ||
5428 | spin_lock_irqsave( | ||
5429 | &ha->hardware_lock, flags); | ||
5413 | qlt_send_busy(vha, atio, SAM_STAT_BUSY); | 5430 | qlt_send_busy(vha, atio, SAM_STAT_BUSY); |
5431 | if (!ha_locked) | ||
5432 | spin_unlock_irqrestore( | ||
5433 | &ha->hardware_lock, flags); | ||
5414 | } | 5434 | } |
5415 | } | 5435 | } |
5416 | } | 5436 | } |
@@ -5427,7 +5447,12 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, | |||
5427 | break; | 5447 | break; |
5428 | } | 5448 | } |
5429 | ql_dbg(ql_dbg_tgt, vha, 0xe02e, "%s", "IMMED_NOTIFY ATIO"); | 5449 | ql_dbg(ql_dbg_tgt, vha, 0xe02e, "%s", "IMMED_NOTIFY ATIO"); |
5450 | |||
5451 | if (!ha_locked) | ||
5452 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
5430 | qlt_handle_imm_notify(vha, (struct imm_ntfy_from_isp *)atio); | 5453 | qlt_handle_imm_notify(vha, (struct imm_ntfy_from_isp *)atio); |
5454 | if (!ha_locked) | ||
5455 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
5431 | break; | 5456 | break; |
5432 | } | 5457 | } |
5433 | 5458 | ||
@@ -5438,7 +5463,7 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, | |||
5438 | break; | 5463 | break; |
5439 | } | 5464 | } |
5440 | 5465 | ||
5441 | tgt->irq_cmd_count--; | 5466 | tgt->atio_irq_cmd_count--; |
5442 | } | 5467 | } |
5443 | 5468 | ||
5444 | /* ha->hardware_lock supposed to be held on entry */ | 5469 | /* ha->hardware_lock supposed to be held on entry */ |
@@ -6384,7 +6409,7 @@ qlt_init_atio_q_entries(struct scsi_qla_host *vha) | |||
6384 | * @ha: SCSI driver HA context | 6409 | * @ha: SCSI driver HA context |
6385 | */ | 6410 | */ |
6386 | void | 6411 | void |
6387 | qlt_24xx_process_atio_queue(struct scsi_qla_host *vha) | 6412 | qlt_24xx_process_atio_queue(struct scsi_qla_host *vha, uint8_t ha_locked) |
6388 | { | 6413 | { |
6389 | struct qla_hw_data *ha = vha->hw; | 6414 | struct qla_hw_data *ha = vha->hw; |
6390 | struct atio_from_isp *pkt; | 6415 | struct atio_from_isp *pkt; |
@@ -6397,7 +6422,8 @@ qlt_24xx_process_atio_queue(struct scsi_qla_host *vha) | |||
6397 | pkt = (struct atio_from_isp *)ha->tgt.atio_ring_ptr; | 6422 | pkt = (struct atio_from_isp *)ha->tgt.atio_ring_ptr; |
6398 | cnt = pkt->u.raw.entry_count; | 6423 | cnt = pkt->u.raw.entry_count; |
6399 | 6424 | ||
6400 | qlt_24xx_atio_pkt_all_vps(vha, (struct atio_from_isp *)pkt); | 6425 | qlt_24xx_atio_pkt_all_vps(vha, (struct atio_from_isp *)pkt, |
6426 | ha_locked); | ||
6401 | 6427 | ||
6402 | for (i = 0; i < cnt; i++) { | 6428 | for (i = 0; i < cnt; i++) { |
6403 | ha->tgt.atio_ring_index++; | 6429 | ha->tgt.atio_ring_index++; |
@@ -6681,16 +6707,59 @@ qla83xx_msix_atio_q(int irq, void *dev_id) | |||
6681 | ha = rsp->hw; | 6707 | ha = rsp->hw; |
6682 | vha = pci_get_drvdata(ha->pdev); | 6708 | vha = pci_get_drvdata(ha->pdev); |
6683 | 6709 | ||
6684 | spin_lock_irqsave(&ha->hardware_lock, flags); | 6710 | spin_lock_irqsave(&ha->tgt.atio_lock, flags); |
6685 | 6711 | ||
6686 | qlt_24xx_process_atio_queue(vha); | 6712 | qlt_24xx_process_atio_queue(vha, 0); |
6687 | qla24xx_process_response_queue(vha, rsp); | ||
6688 | 6713 | ||
6689 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 6714 | spin_unlock_irqrestore(&ha->tgt.atio_lock, flags); |
6690 | 6715 | ||
6691 | return IRQ_HANDLED; | 6716 | return IRQ_HANDLED; |
6692 | } | 6717 | } |
6693 | 6718 | ||
6719 | static void | ||
6720 | qlt_handle_abts_recv_work(struct work_struct *work) | ||
6721 | { | ||
6722 | struct qla_tgt_sess_op *op = container_of(work, | ||
6723 | struct qla_tgt_sess_op, work); | ||
6724 | scsi_qla_host_t *vha = op->vha; | ||
6725 | struct qla_hw_data *ha = vha->hw; | ||
6726 | unsigned long flags; | ||
6727 | |||
6728 | if (qla2x00_reset_active(vha) || (op->chip_reset != ha->chip_reset)) | ||
6729 | return; | ||
6730 | |||
6731 | spin_lock_irqsave(&ha->tgt.atio_lock, flags); | ||
6732 | qlt_24xx_process_atio_queue(vha, 0); | ||
6733 | spin_unlock_irqrestore(&ha->tgt.atio_lock, flags); | ||
6734 | |||
6735 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
6736 | qlt_response_pkt_all_vps(vha, (response_t *)&op->atio); | ||
6737 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
6738 | } | ||
6739 | |||
6740 | void | ||
6741 | qlt_handle_abts_recv(struct scsi_qla_host *vha, response_t *pkt) | ||
6742 | { | ||
6743 | struct qla_tgt_sess_op *op; | ||
6744 | |||
6745 | op = kzalloc(sizeof(*op), GFP_ATOMIC); | ||
6746 | |||
6747 | if (!op) { | ||
6748 | /* do not reach for ATIO queue here. This is best effort err | ||
6749 | * recovery at this point. | ||
6750 | */ | ||
6751 | qlt_response_pkt_all_vps(vha, pkt); | ||
6752 | return; | ||
6753 | } | ||
6754 | |||
6755 | memcpy(&op->atio, pkt, sizeof(*pkt)); | ||
6756 | op->vha = vha; | ||
6757 | op->chip_reset = vha->hw->chip_reset; | ||
6758 | INIT_WORK(&op->work, qlt_handle_abts_recv_work); | ||
6759 | queue_work(qla_tgt_wq, &op->work); | ||
6760 | return; | ||
6761 | } | ||
6762 | |||
6694 | int | 6763 | int |
6695 | qlt_mem_alloc(struct qla_hw_data *ha) | 6764 | qlt_mem_alloc(struct qla_hw_data *ha) |
6696 | { | 6765 | { |
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h index f5dbeabefcb7..71b2865ba3c8 100644 --- a/drivers/scsi/qla2xxx/qla_target.h +++ b/drivers/scsi/qla2xxx/qla_target.h | |||
@@ -835,6 +835,7 @@ struct qla_tgt { | |||
835 | * HW lock. | 835 | * HW lock. |
836 | */ | 836 | */ |
837 | int irq_cmd_count; | 837 | int irq_cmd_count; |
838 | int atio_irq_cmd_count; | ||
838 | 839 | ||
839 | int datasegs_per_cmd, datasegs_per_cont, sg_tablesize; | 840 | int datasegs_per_cmd, datasegs_per_cont, sg_tablesize; |
840 | 841 | ||
@@ -883,6 +884,7 @@ struct qla_tgt { | |||
883 | 884 | ||
884 | struct qla_tgt_sess_op { | 885 | struct qla_tgt_sess_op { |
885 | struct scsi_qla_host *vha; | 886 | struct scsi_qla_host *vha; |
887 | uint32_t chip_reset; | ||
886 | struct atio_from_isp atio; | 888 | struct atio_from_isp atio; |
887 | struct work_struct work; | 889 | struct work_struct work; |
888 | struct list_head cmd_list; | 890 | struct list_head cmd_list; |
@@ -1155,7 +1157,7 @@ extern void qlt_enable_vha(struct scsi_qla_host *); | |||
1155 | extern void qlt_vport_create(struct scsi_qla_host *, struct qla_hw_data *); | 1157 | extern void qlt_vport_create(struct scsi_qla_host *, struct qla_hw_data *); |
1156 | extern void qlt_rff_id(struct scsi_qla_host *, struct ct_sns_req *); | 1158 | extern void qlt_rff_id(struct scsi_qla_host *, struct ct_sns_req *); |
1157 | extern void qlt_init_atio_q_entries(struct scsi_qla_host *); | 1159 | extern void qlt_init_atio_q_entries(struct scsi_qla_host *); |
1158 | extern void qlt_24xx_process_atio_queue(struct scsi_qla_host *); | 1160 | extern void qlt_24xx_process_atio_queue(struct scsi_qla_host *, uint8_t); |
1159 | extern void qlt_24xx_config_rings(struct scsi_qla_host *); | 1161 | extern void qlt_24xx_config_rings(struct scsi_qla_host *); |
1160 | extern void qlt_24xx_config_nvram_stage1(struct scsi_qla_host *, | 1162 | extern void qlt_24xx_config_nvram_stage1(struct scsi_qla_host *, |
1161 | struct nvram_24xx *); | 1163 | struct nvram_24xx *); |