Commit 0f65ff68 authored by James Smart's avatar James Smart Committed by James Bottomley
Browse files

[SCSI] lpfc 8.3.10: Update SLI interface areas



- Clear LPFC_DRIVER_ABORTED on FCP command completion.
- Clear exchange busy flag when I/O is aborted and found on aborted list.
- Free sglq when XRI_ABORTED event is processed before release of IOCB.
- Only process iocb as aborted when LPFC_DRIVER_ABORTED is set.

Signed-off-by: default avatarJames Smart <james.smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent e40a02c1
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -509,7 +509,6 @@ struct lpfc_hba {
	int (*lpfc_hba_down_link)
		(struct lpfc_hba *);


	/* SLI4 specific HBA data structure */
	struct lpfc_sli4_hba sli4_hba;

+1 −1
Original line number Diff line number Diff line
@@ -385,7 +385,7 @@ void lpfc_parse_fcoe_conf(struct lpfc_hba *, uint8_t *, uint32_t);
int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int);
void lpfc_start_fdiscs(struct lpfc_hba *phba);
struct lpfc_vport *lpfc_find_vport_by_vpid(struct lpfc_hba *, uint16_t);

struct lpfc_sglq *__lpfc_get_active_sglq(struct lpfc_hba *, uint16_t);
#define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code)
#define HBA_EVENT_RSCN                   5
#define HBA_EVENT_LINK_UP                2
+15 −8
Original line number Diff line number Diff line
@@ -6234,6 +6234,7 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
		lpfc_mbx_unreg_vpi(vport);
		spin_lock_irq(shost->host_lock);
		vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
		if (phba->sli_rev == LPFC_SLI_REV4)
			vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
		spin_unlock_irq(shost->host_lock);
	}
@@ -6812,21 +6813,27 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba,
	struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL;
	unsigned long iflag = 0;

	spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock, iflag);
	spin_lock_irqsave(&phba->hbalock, iflag);
	spin_lock(&phba->sli4_hba.abts_sgl_list_lock);
	list_for_each_entry_safe(sglq_entry, sglq_next,
			&phba->sli4_hba.lpfc_abts_els_sgl_list, list) {
		if (sglq_entry->sli4_xritag == xri) {
			list_del(&sglq_entry->list);
			spin_unlock_irqrestore(
					&phba->sli4_hba.abts_sgl_list_lock,
					 iflag);
			spin_lock_irqsave(&phba->hbalock, iflag);

			list_add_tail(&sglq_entry->list,
				&phba->sli4_hba.lpfc_sgl_list);
			sglq_entry->state = SGL_FREED;
			spin_unlock(&phba->sli4_hba.abts_sgl_list_lock);
			spin_unlock_irqrestore(&phba->hbalock, iflag);
			return;
		}
	}
	spin_unlock_irqrestore(&phba->sli4_hba.abts_sgl_list_lock, iflag);
	spin_unlock(&phba->sli4_hba.abts_sgl_list_lock);
	sglq_entry = __lpfc_get_active_sglq(phba, xri);
	if (!sglq_entry || (sglq_entry->sli4_xritag != xri)) {
		spin_unlock_irqrestore(&phba->hbalock, iflag);
		return;
	}
	sglq_entry->state = SGL_XRI_ABORTED;
	spin_unlock_irqrestore(&phba->hbalock, iflag);
	return;
}
+7 −0
Original line number Diff line number Diff line
@@ -822,6 +822,8 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba)
	LIST_HEAD(aborts);
	int ret;
	unsigned long iflag = 0;
	struct lpfc_sglq *sglq_entry = NULL;

	ret = lpfc_hba_down_post_s3(phba);
	if (ret)
		return ret;
@@ -837,6 +839,10 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba)
	 * list.
	 */
	spin_lock(&phba->sli4_hba.abts_sgl_list_lock);
	list_for_each_entry(sglq_entry,
		&phba->sli4_hba.lpfc_abts_els_sgl_list, list)
		sglq_entry->state = SGL_FREED;

	list_splice_init(&phba->sli4_hba.lpfc_abts_els_sgl_list,
			&phba->sli4_hba.lpfc_sgl_list);
	spin_unlock(&phba->sli4_hba.abts_sgl_list_lock);
@@ -4412,6 +4418,7 @@ lpfc_init_sgl_list(struct lpfc_hba *phba)

		/* The list order is used by later block SGL registraton */
		spin_lock_irq(&phba->hbalock);
		sglq_entry->state = SGL_FREED;
		list_add_tail(&sglq_entry->list, &phba->sli4_hba.lpfc_sgl_list);
		phba->sli4_hba.lpfc_els_sgl_array[i] = sglq_entry;
		phba->sli4_hba.total_sglq_bufs++;
+28 −7
Original line number Diff line number Diff line
@@ -620,23 +620,40 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *phba,
	uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri);
	struct lpfc_scsi_buf *psb, *next_psb;
	unsigned long iflag = 0;
	struct lpfc_iocbq *iocbq;
	int i;

	spin_lock_irqsave(&phba->sli4_hba.abts_scsi_buf_list_lock, iflag);
	spin_lock_irqsave(&phba->hbalock, iflag);
	spin_lock(&phba->sli4_hba.abts_scsi_buf_list_lock);
	list_for_each_entry_safe(psb, next_psb,
		&phba->sli4_hba.lpfc_abts_scsi_buf_list, list) {
		if (psb->cur_iocbq.sli4_xritag == xri) {
			list_del(&psb->list);
			psb->exch_busy = 0;
			psb->status = IOSTAT_SUCCESS;
			spin_unlock_irqrestore(
				&phba->sli4_hba.abts_scsi_buf_list_lock,
				iflag);
			spin_unlock(
				&phba->sli4_hba.abts_scsi_buf_list_lock);
			spin_unlock_irqrestore(&phba->hbalock, iflag);
			lpfc_release_scsi_buf_s4(phba, psb);
			return;
		}
	}
	spin_unlock_irqrestore(&phba->sli4_hba.abts_scsi_buf_list_lock,
				iflag);
	spin_unlock(&phba->sli4_hba.abts_scsi_buf_list_lock);
	for (i = 1; i <= phba->sli.last_iotag; i++) {
		iocbq = phba->sli.iocbq_lookup[i];

		if (!(iocbq->iocb_flag &  LPFC_IO_FCP) ||
			(iocbq->iocb_flag & LPFC_IO_LIBDFC))
			continue;
		if (iocbq->sli4_xritag != xri)
			continue;
		psb = container_of(iocbq, struct lpfc_scsi_buf, cur_iocbq);
		psb->exch_busy = 0;
		spin_unlock_irqrestore(&phba->hbalock, iflag);
		return;

	}
	spin_unlock_irqrestore(&phba->hbalock, iflag);
}

/**
@@ -1006,6 +1023,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
	struct scatterlist *sgel = NULL;
	struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd;
	struct ulp_bde64 *bpl = lpfc_cmd->fcp_bpl;
	struct lpfc_iocbq *iocbq = &lpfc_cmd->cur_iocbq;
	IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb;
	struct ulp_bde64 *data_bde = iocb_cmd->unsli3.fcp_ext.dbde;
	dma_addr_t physaddr;
@@ -1056,6 +1074,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
			physaddr = sg_dma_address(sgel);
			if (phba->sli_rev == 3 &&
			    !(phba->sli3_options & LPFC_SLI3_BG_ENABLED) &&
			    !(iocbq->iocb_flag & DSS_SECURITY_OP) &&
			    nseg <= LPFC_EXT_DATA_BDE_COUNT) {
				data_bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
				data_bde->tus.f.bdeSize = sg_dma_len(sgel);
@@ -1082,7 +1101,8 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
	 * explicitly reinitialized since all iocb memory resources are reused.
	 */
	if (phba->sli_rev == 3 &&
	    !(phba->sli3_options & LPFC_SLI3_BG_ENABLED)) {
	    !(phba->sli3_options & LPFC_SLI3_BG_ENABLED) &&
	    !(iocbq->iocb_flag & DSS_SECURITY_OP)) {
		if (num_bde > LPFC_EXT_DATA_BDE_COUNT) {
			/*
			 * The extended IOCB format can only fit 3 BDE or a BPL.
@@ -1107,6 +1127,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
	} else {
		iocb_cmd->un.fcpi64.bdl.bdeSize =
			((num_bde + 2) * sizeof(struct ulp_bde64));
		iocb_cmd->unsli3.fcp_ext.ebde_count = (num_bde + 1);
	}
	fcp_cmnd->fcpDl = cpu_to_be32(scsi_bufflen(scsi_cmnd));

Loading