diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_isr.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 138 |
1 files changed, 79 insertions, 59 deletions
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 21b31d6359c8..76e79f350a22 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -1354,9 +1354,7 @@ skip_rio: if (!vha->vp_idx) { if (ha->flags.fawwpn_enabled && (ha->current_topology == ISP_CFG_F)) { - void *wwpn = ha->init_cb->port_name; - - memcpy(vha->port_name, wwpn, WWN_SIZE); + memcpy(vha->port_name, ha->port_name, WWN_SIZE); fc_host_port_name(vha->host) = wwn_to_u64(vha->port_name); ql_dbg(ql_dbg_init + ql_dbg_verbose, @@ -1761,6 +1759,9 @@ global_port_update: break; case MBA_DPORT_DIAGNOSTICS: + if ((mb[1] & 0xF) == AEN_DONE_DIAG_TEST_WITH_NOERR || + (mb[1] & 0xF) == AEN_DONE_DIAG_TEST_WITH_ERR) + vha->dport_status &= ~DPORT_DIAG_IN_PROGRESS; ql_dbg(ql_dbg_async, vha, 0x5052, "D-Port Diagnostics: %04x %04x %04x %04x\n", mb[0], mb[1], mb[2], mb[3]); @@ -2245,9 +2246,9 @@ qla24xx_els_ct_entry(scsi_qla_host_t *v, struct req_que *req, res = DID_ERROR << 16; } - if (logit) { - if (sp->remap.remapped && - ((u8 *)sp->remap.rsp.buf)[0] == ELS_LS_RJT) { + if (sp->remap.remapped && + ((u8 *)sp->remap.rsp.buf)[0] == ELS_LS_RJT) { + if (logit) { ql_dbg(ql_dbg_user, vha, 0x503f, "%s IOCB Done LS_RJT hdl=%x comp_status=0x%x\n", type, sp->handle, comp_status); @@ -2259,18 +2260,24 @@ qla24xx_els_ct_entry(scsi_qla_host_t *v, struct req_que *req, pkt)->total_byte_count), e->s_id[0], e->s_id[2], e->s_id[1], e->d_id[2], e->d_id[1], e->d_id[0]); - } else { - ql_log(ql_log_info, vha, 0x503f, - "%s IOCB Done hdl=%x comp_status=0x%x\n", - type, sp->handle, comp_status); - ql_log(ql_log_info, vha, 0x503f, - "subcode 1=0x%x subcode 2=0x%x bytes=0x%x %02x%02x%02x -> %02x%02x%02x\n", - fw_status[1], fw_status[2], - le32_to_cpu(((struct els_sts_entry_24xx *) - pkt)->total_byte_count), - e->s_id[0], e->s_id[2], e->s_id[1], - e->d_id[2], e->d_id[1], e->d_id[0]); } + if (sp->fcport && sp->fcport->flags & FCF_FCSP_DEVICE && + sp->type == SRB_ELS_CMD_HST_NOLOGIN) { + ql_dbg(ql_dbg_edif, vha, 0x911e, + "%s rcv reject. Sched delete\n", __func__); + qlt_schedule_sess_for_deletion(sp->fcport); + } + } else if (logit) { + ql_log(ql_log_info, vha, 0x503f, + "%s IOCB Done hdl=%x comp_status=0x%x\n", + type, sp->handle, comp_status); + ql_log(ql_log_info, vha, 0x503f, + "subcode 1=0x%x subcode 2=0x%x bytes=0x%x %02x%02x%02x -> %02x%02x%02x\n", + fw_status[1], fw_status[2], + le32_to_cpu(((struct els_sts_entry_24xx *) + pkt)->total_byte_count), + e->s_id[0], e->s_id[2], e->s_id[1], + e->d_id[2], e->d_id[1], e->d_id[0]); } } goto els_ct_done; @@ -2639,7 +2646,7 @@ static void qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, } if (unlikely(logit)) - ql_log(ql_dbg_io, fcport->vha, 0x5060, + ql_dbg(ql_dbg_io, fcport->vha, 0x5060, "NVME-%s ERR Handling - hdl=%x status(%x) tr_len:%x resid=%x ox_id=%x\n", sp->name, sp->handle, comp_status, fd->transferred_length, le32_to_cpu(sts->residual_len), @@ -3426,6 +3433,7 @@ check_scsi_status: case CS_PORT_UNAVAILABLE: case CS_TIMEOUT: case CS_RESET: + case CS_EDIF_INV_REQ: /* * We are going to have the fc class block the rport @@ -3496,7 +3504,7 @@ check_scsi_status: out: if (logit) - ql_log(ql_dbg_io, fcport->vha, 0x3022, + ql_dbg(ql_dbg_io, fcport->vha, 0x3022, "FCP command status: 0x%x-0x%x (0x%x) nexus=%ld:%d:%llu portid=%02x%02x%02x oxid=0x%x cdb=%10phN len=0x%x rsp_info=0x%x resid=0x%x fw_resid=0x%x sp=%p cp=%p.\n", comp_status, scsi_status, res, vha->host_no, cp->device->id, cp->device->lun, fcport->d_id.b.domain, @@ -3712,12 +3720,11 @@ void qla24xx_nvme_ls4_iocb(struct scsi_qla_host *vha, * Return: 0 all iocbs has arrived, xx- all iocbs have not arrived. */ static int qla_chk_cont_iocb_avail(struct scsi_qla_host *vha, - struct rsp_que *rsp, response_t *pkt) + struct rsp_que *rsp, response_t *pkt, u32 rsp_q_in) { - int start_pkt_ring_index, end_pkt_ring_index, n_ring_index; - response_t *end_pkt; + int start_pkt_ring_index; + u32 iocb_cnt = 0; int rc = 0; - u32 rsp_q_in; if (pkt->entry_count == 1) return rc; @@ -3728,34 +3735,18 @@ static int qla_chk_cont_iocb_avail(struct scsi_qla_host *vha, else start_pkt_ring_index = rsp->ring_index - 1; - if ((start_pkt_ring_index + pkt->entry_count) >= rsp->length) - end_pkt_ring_index = start_pkt_ring_index + pkt->entry_count - - rsp->length - 1; + if (rsp_q_in < start_pkt_ring_index) + /* q in ptr is wrapped */ + iocb_cnt = rsp->length - start_pkt_ring_index + rsp_q_in; else - end_pkt_ring_index = start_pkt_ring_index + pkt->entry_count - 1; + iocb_cnt = rsp_q_in - start_pkt_ring_index; - end_pkt = rsp->ring + end_pkt_ring_index; - - /* next pkt = end_pkt + 1 */ - n_ring_index = end_pkt_ring_index + 1; - if (n_ring_index >= rsp->length) - n_ring_index = 0; - - rsp_q_in = rsp->qpair->use_shadow_reg ? *rsp->in_ptr : - rd_reg_dword(rsp->rsp_q_in); - - /* rsp_q_in is either wrapped or pointing beyond endpkt */ - if ((rsp_q_in < start_pkt_ring_index && rsp_q_in < n_ring_index) || - rsp_q_in >= n_ring_index) - /* all IOCBs arrived. */ - rc = 0; - else + if (iocb_cnt < pkt->entry_count) rc = -EIO; - ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x5091, - "%s - ring %p pkt %p end pkt %p entry count %#x rsp_q_in %d rc %d\n", - __func__, rsp->ring, pkt, end_pkt, pkt->entry_count, - rsp_q_in, rc); + ql_dbg(ql_dbg_init, vha, 0x5091, + "%s - ring %p pkt %p entry count %d iocb_cnt %d rsp_q_in %d rc %d\n", + __func__, rsp->ring, pkt, pkt->entry_count, iocb_cnt, rsp_q_in, rc); return rc; } @@ -3772,6 +3763,8 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, struct qla_hw_data *ha = vha->hw; struct purex_entry_24xx *purex_entry; struct purex_item *pure_item; + u16 rsp_in = 0, cur_ring_index; + int follow_inptr, is_shadow_hba; if (!ha->flags.fw_started) return; @@ -3781,8 +3774,27 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, qla_cpu_update(rsp->qpair, smp_processor_id()); } - while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) { +#define __update_rsp_in(_update, _is_shadow_hba, _rsp, _rsp_in) \ + do { \ + if (_update) { \ + _rsp_in = _is_shadow_hba ? *(_rsp)->in_ptr : \ + rd_reg_dword_relaxed((_rsp)->rsp_q_in); \ + } \ + } while (0) + + is_shadow_hba = IS_SHADOW_REG_CAPABLE(ha); + follow_inptr = is_shadow_hba ? ql2xrspq_follow_inptr : + ql2xrspq_follow_inptr_legacy; + + __update_rsp_in(follow_inptr, is_shadow_hba, rsp, rsp_in); + + while ((likely(follow_inptr && + rsp->ring_index != rsp_in && + rsp->ring_ptr->signature != RESPONSE_PROCESSED)) || + (!follow_inptr && + rsp->ring_ptr->signature != RESPONSE_PROCESSED)) { pkt = (struct sts_entry_24xx *)rsp->ring_ptr; + cur_ring_index = rsp->ring_index; rsp->ring_index++; if (rsp->ring_index == rsp->length) { @@ -3894,6 +3906,8 @@ process_err: } pure_item = qla27xx_copy_fpin_pkt(vha, (void **)&pkt, &rsp); + __update_rsp_in(follow_inptr, is_shadow_hba, + rsp, rsp_in); if (!pure_item) break; qla24xx_queue_purex_item(vha, pure_item, @@ -3901,7 +3915,17 @@ process_err: break; case ELS_AUTH_ELS: - if (qla_chk_cont_iocb_avail(vha, rsp, (response_t *)pkt)) { + if (qla_chk_cont_iocb_avail(vha, rsp, (response_t *)pkt, rsp_in)) { + /* + * ring_ptr and ring_index were + * pre-incremented above. Reset them + * back to current. Wait for next + * interrupt with all IOCBs to arrive + * and re-process. + */ + rsp->ring_ptr = (response_t *)pkt; + rsp->ring_index = cur_ring_index; + ql_dbg(ql_dbg_init, vha, 0x5091, "Defer processing ELS opcode %#x...\n", purex_entry->els_frame_payload[3]); @@ -4420,16 +4444,12 @@ msix_register_fail: } /* Enable MSI-X vector for response queue update for queue 0 */ - if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { - if (ha->msixbase && ha->mqiobase && - (ha->max_rsp_queues > 1 || ha->max_req_queues > 1 || - ql2xmqsupport)) - ha->mqenable = 1; - } else - if (ha->mqiobase && - (ha->max_rsp_queues > 1 || ha->max_req_queues > 1 || - ql2xmqsupport)) - ha->mqenable = 1; + if (IS_MQUE_CAPABLE(ha) && + (ha->msixbase && ha->mqiobase && ha->max_qpairs)) + ha->mqenable = 1; + else + ha->mqenable = 0; + ql_dbg(ql_dbg_multiq, vha, 0xc005, "mqiobase=%p, max_rsp_queues=%d, max_req_queues=%d.\n", ha->mqiobase, ha->max_rsp_queues, ha->max_req_queues); |