summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_sli.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-08-15 22:06:26 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2018-08-15 22:06:26 -0700
commit72f02ba66bd83b54054da20eae550123de84da6f (patch)
tree96a8360400e040aa2e38e7352594dbbc485461db /drivers/scsi/lpfc/lpfc_sli.c
parentdb06f826ec12bf0701ea7fc0a3c0aa00b84417c8 (diff)
parent51372570ac3c919b036e760f4ca449e81cf8e995 (diff)
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley: "This is mostly updates to the usual drivers: mpt3sas, lpfc, qla2xxx, hisi_sas, smartpqi, megaraid_sas, arcmsr. In addition, with the continuing absence of Nic we have target updates for tcmu and target core (all with reviews and acks). The biggest observable change is going to be that we're (again) trying to switch to mulitqueue as the default (a user can still override the setting on the kernel command line). Other major core stuff is the removal of the remaining Microchannel drivers, an update of the internal timers and some reworks of completion and result handling" * tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (203 commits) scsi: core: use blk_mq_run_hw_queues in scsi_kick_queue scsi: ufs: remove unnecessary query(DM) UPIU trace scsi: qla2xxx: Fix issue reported by static checker for qla2x00_els_dcmd2_sp_done() scsi: aacraid: Spelling fix in comment scsi: mpt3sas: Fix calltrace observed while running IO & reset scsi: aic94xx: fix an error code in aic94xx_init() scsi: st: remove redundant pointer STbuffer scsi: qla2xxx: Update driver version to 10.00.00.08-k scsi: qla2xxx: Migrate NVME N2N handling into state machine scsi: qla2xxx: Save frame payload size from ICB scsi: qla2xxx: Fix stalled relogin scsi: qla2xxx: Fix race between switch cmd completion and timeout scsi: qla2xxx: Fix Management Server NPort handle reservation logic scsi: qla2xxx: Flush mailbox commands on chip reset scsi: qla2xxx: Fix unintended Logout scsi: qla2xxx: Fix session state stuck in Get Port DB scsi: qla2xxx: Fix redundant fc_rport registration scsi: qla2xxx: Silent erroneous message scsi: qla2xxx: Prevent sysfs access when chip is down scsi: qla2xxx: Add longer window for chip reset ...
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c50
1 files changed, 37 insertions, 13 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 6f3c00a233ec..9830bdb6e072 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -145,6 +145,7 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe128 *wqe)
uint32_t idx;
uint32_t i = 0;
uint8_t *tmp;
+ u32 if_type;
/* sanity check on queue memory */
if (unlikely(!q))
@@ -199,8 +200,14 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe128 *wqe)
q->queue_id);
} else {
bf_set(lpfc_wq_db_list_fm_num_posted, &doorbell, 1);
- bf_set(lpfc_wq_db_list_fm_index, &doorbell, host_index);
bf_set(lpfc_wq_db_list_fm_id, &doorbell, q->queue_id);
+
+ /* Leave bits <23:16> clear for if_type 6 dpp */
+ if_type = bf_get(lpfc_sli_intf_if_type,
+ &q->phba->sli4_hba.sli_intf);
+ if (if_type != LPFC_SLI_INTF_IF_TYPE_6)
+ bf_set(lpfc_wq_db_list_fm_index, &doorbell,
+ host_index);
}
} else if (q->db_format == LPFC_DB_RING_FORMAT) {
bf_set(lpfc_wq_db_ring_fm_num_posted, &doorbell, 1);
@@ -4591,7 +4598,7 @@ lpfc_sli_brdrestart_s3(struct lpfc_hba *phba)
spin_unlock_irq(&phba->hbalock);
memset(&psli->lnk_stat_offsets, 0, sizeof(psli->lnk_stat_offsets));
- psli->stats_start = get_seconds();
+ psli->stats_start = ktime_get_seconds();
/* Give the INITFF and Post time to settle. */
mdelay(100);
@@ -4638,7 +4645,7 @@ lpfc_sli_brdrestart_s4(struct lpfc_hba *phba)
spin_unlock_irq(&phba->hbalock);
memset(&psli->lnk_stat_offsets, 0, sizeof(psli->lnk_stat_offsets));
- psli->stats_start = get_seconds();
+ psli->stats_start = ktime_get_seconds();
/* Reset HBA AER if it was enabled, note hba_flag was reset above */
if (hba_aer_enabled)
@@ -9110,8 +9117,8 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
}
/* Note, word 10 is already initialized to 0 */
- /* Don't set PBDE for Perf hints, just fcp_embed_pbde */
- if (phba->fcp_embed_pbde)
+ /* Don't set PBDE for Perf hints, just lpfc_enable_pbde */
+ if (phba->cfg_enable_pbde)
bf_set(wqe_pbde, &wqe->fcp_iwrite.wqe_com, 1);
else
bf_set(wqe_pbde, &wqe->fcp_iwrite.wqe_com, 0);
@@ -9174,8 +9181,8 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
}
/* Note, word 10 is already initialized to 0 */
- /* Don't set PBDE for Perf hints, just fcp_embed_pbde */
- if (phba->fcp_embed_pbde)
+ /* Don't set PBDE for Perf hints, just lpfc_enable_pbde */
+ if (phba->cfg_enable_pbde)
bf_set(wqe_pbde, &wqe->fcp_iread.wqe_com, 1);
else
bf_set(wqe_pbde, &wqe->fcp_iread.wqe_com, 0);
@@ -10696,6 +10703,12 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
spin_lock_irq(&phba->hbalock);
if (phba->sli_rev < LPFC_SLI_REV4) {
+ if (irsp->ulpCommand == CMD_ABORT_XRI_CX &&
+ irsp->ulpStatus == IOSTAT_LOCAL_REJECT &&
+ irsp->un.ulpWord[4] == IOERR_ABORT_REQUESTED) {
+ spin_unlock_irq(&phba->hbalock);
+ goto release_iocb;
+ }
if (abort_iotag != 0 &&
abort_iotag <= phba->sli.last_iotag)
abort_iocb =
@@ -10717,6 +10730,7 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
spin_unlock_irq(&phba->hbalock);
}
+release_iocb:
lpfc_sli_release_iocbq(phba, cmdiocb);
return;
}
@@ -10773,6 +10787,7 @@ lpfc_sli_abort_iotag_issue(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
IOCB_t *iabt = NULL;
int retval;
unsigned long iflags;
+ struct lpfc_nodelist *ndlp;
lockdep_assert_held(&phba->hbalock);
@@ -10803,9 +10818,13 @@ lpfc_sli_abort_iotag_issue(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
if (phba->sli_rev == LPFC_SLI_REV4) {
iabt->un.acxri.abortIoTag = cmdiocb->sli4_xritag;
iabt->un.acxri.abortContextTag = cmdiocb->iotag;
- }
- else
+ } else {
iabt->un.acxri.abortIoTag = icmd->ulpIoTag;
+ if (pring->ringno == LPFC_ELS_RING) {
+ ndlp = (struct lpfc_nodelist *)(cmdiocb->context1);
+ iabt->un.acxri.abortContextTag = ndlp->nlp_rpi;
+ }
+ }
iabt->ulpLe = 1;
iabt->ulpClass = icmd->ulpClass;
@@ -11084,10 +11103,11 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, struct lpfc_vport *vport,
struct lpfc_scsi_buf *lpfc_cmd;
int rc = 1;
- if (!(iocbq->iocb_flag & LPFC_IO_FCP))
+ if (iocbq->vport != vport)
return rc;
- if (iocbq->vport != vport)
+ if (!(iocbq->iocb_flag & LPFC_IO_FCP) ||
+ !(iocbq->iocb_flag & LPFC_IO_ON_TXCMPLQ))
return rc;
lpfc_cmd = container_of(iocbq, struct lpfc_scsi_buf, cur_iocbq);
@@ -11097,13 +11117,13 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, struct lpfc_vport *vport,
switch (ctx_cmd) {
case LPFC_CTX_LUN:
- if ((lpfc_cmd->rdata->pnode) &&
+ if ((lpfc_cmd->rdata) && (lpfc_cmd->rdata->pnode) &&
(lpfc_cmd->rdata->pnode->nlp_sid == tgt_id) &&
(scsilun_to_int(&lpfc_cmd->fcp_cmnd->fcp_lun) == lun_id))
rc = 0;
break;
case LPFC_CTX_TGT:
- if ((lpfc_cmd->rdata->pnode) &&
+ if ((lpfc_cmd->rdata) && (lpfc_cmd->rdata->pnode) &&
(lpfc_cmd->rdata->pnode->nlp_sid == tgt_id))
rc = 0;
break;
@@ -11218,6 +11238,10 @@ lpfc_sli_abort_iocb(struct lpfc_vport *vport, struct lpfc_sli_ring *pring,
int errcnt = 0, ret_val = 0;
int i;
+ /* all I/Os are in process of being flushed */
+ if (phba->hba_flag & HBA_FCP_IOQ_FLUSH)
+ return errcnt;
+
for (i = 1; i <= phba->sli.last_iotag; i++) {
iocbq = phba->sli.iocbq_lookup[i];