aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_target.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_target.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_target.c99
1 files changed, 84 insertions, 15 deletions
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 */
102static void qlt_24xx_atio_pkt(struct scsi_qla_host *ha, 102static void qlt_24xx_atio_pkt(struct scsi_qla_host *ha,
103 struct atio_from_isp *pkt); 103 struct atio_from_isp *pkt, uint8_t);
104static void qlt_response_pkt(struct scsi_qla_host *ha, response_t *pkt); 104static void qlt_response_pkt(struct scsi_qla_host *ha, response_t *pkt);
105static int qlt_issue_task_mgmt(struct qla_tgt_sess *sess, uint32_t lun, 105static 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
232static void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha, 232static 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 */
5352static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, 5352static 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 */
6386void 6411void
6387qlt_24xx_process_atio_queue(struct scsi_qla_host *vha) 6412qlt_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
6719static void
6720qlt_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
6740void
6741qlt_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
6694int 6763int
6695qlt_mem_alloc(struct qla_hw_data *ha) 6764qlt_mem_alloc(struct qla_hw_data *ha)
6696{ 6765{