Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[SCSI] lpfc 8.3.27: T10 additions for SLI4



Added T10 DIFF error injection code.
Added T10 DIFF structure definitions for SLI4 devices.

Signed-off-by: default avatarAlex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: default avatarJames Smart <james.smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 5350d872
Loading
Loading
Loading
Loading
+18 −2
Original line number Diff line number Diff line
@@ -848,6 +848,22 @@ struct lpfc_hba {
	struct dentry *debug_dumpHBASlim;
	struct dentry *debug_dumpData;   /* BlockGuard BPL */
	struct dentry *debug_dumpDif;    /* BlockGuard BPL */
	struct dentry *debug_InjErrLBA;  /* LBA to inject errors at */
	struct dentry *debug_writeGuard; /* inject write guard_tag errors */
	struct dentry *debug_writeApp;   /* inject write app_tag errors */
	struct dentry *debug_writeRef;   /* inject write ref_tag errors */
	struct dentry *debug_readApp;    /* inject read app_tag errors */
	struct dentry *debug_readRef;    /* inject read ref_tag errors */

	/* T10 DIF error injection */
	uint32_t lpfc_injerr_wgrd_cnt;
	uint32_t lpfc_injerr_wapp_cnt;
	uint32_t lpfc_injerr_wref_cnt;
	uint32_t lpfc_injerr_rapp_cnt;
	uint32_t lpfc_injerr_rref_cnt;
	sector_t lpfc_injerr_lba;
#define LPFC_INJERR_LBA_OFF	(sector_t)0xffffffffffffffff

	struct dentry *debug_slow_ring_trc;
	struct lpfc_debugfs_trc *slow_ring_trc;
	atomic_t slow_ring_trc_cnt;
+181 −0
Original line number Diff line number Diff line
@@ -996,6 +996,85 @@ lpfc_debugfs_dumpDataDif_write(struct file *file, const char __user *buf,
	return nbytes;
}

static int
lpfc_debugfs_dif_err_open(struct inode *inode, struct file *file)
{
	file->private_data = inode->i_private;
	return 0;
}

static ssize_t
lpfc_debugfs_dif_err_read(struct file *file, char __user *buf,
	size_t nbytes, loff_t *ppos)
{
	struct dentry *dent = file->f_dentry;
	struct lpfc_hba *phba = file->private_data;
	char cbuf[16];
	int cnt = 0;

	if (dent == phba->debug_writeGuard)
		cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_wgrd_cnt);
	else if (dent == phba->debug_writeApp)
		cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_wapp_cnt);
	else if (dent == phba->debug_writeRef)
		cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_wref_cnt);
	else if (dent == phba->debug_readApp)
		cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_rapp_cnt);
	else if (dent == phba->debug_readRef)
		cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_rref_cnt);
	else if (dent == phba->debug_InjErrLBA)
		cnt = snprintf(cbuf, 16, "0x%lx\n",
				 (unsigned long) phba->lpfc_injerr_lba);
	else
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
			 "0547 Unknown debugfs error injection entry\n");

	return simple_read_from_buffer(buf, nbytes, ppos, &cbuf, cnt);
}

static ssize_t
lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf,
	size_t nbytes, loff_t *ppos)
{
	struct dentry *dent = file->f_dentry;
	struct lpfc_hba *phba = file->private_data;
	char dstbuf[32];
	unsigned long tmp;
	int size;

	memset(dstbuf, 0, 32);
	size = (nbytes < 32) ? nbytes : 32;
	if (copy_from_user(dstbuf, buf, size))
		return 0;

	if (strict_strtoul(dstbuf, 0, &tmp))
		return 0;

	if (dent == phba->debug_writeGuard)
		phba->lpfc_injerr_wgrd_cnt = (uint32_t)tmp;
	else if (dent == phba->debug_writeApp)
		phba->lpfc_injerr_wapp_cnt = (uint32_t)tmp;
	else if (dent == phba->debug_writeRef)
		phba->lpfc_injerr_wref_cnt = (uint32_t)tmp;
	else if (dent == phba->debug_readApp)
		phba->lpfc_injerr_rapp_cnt = (uint32_t)tmp;
	else if (dent == phba->debug_readRef)
		phba->lpfc_injerr_rref_cnt = (uint32_t)tmp;
	else if (dent == phba->debug_InjErrLBA)
		phba->lpfc_injerr_lba = (sector_t)tmp;
	else
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
			 "0548 Unknown debugfs error injection entry\n");

	return nbytes;
}

static int
lpfc_debugfs_dif_err_release(struct inode *inode, struct file *file)
{
	return 0;
}

/**
 * lpfc_debugfs_nodelist_open - Open the nodelist debugfs file
 * @inode: The inode pointer that contains a vport pointer.
@@ -3380,6 +3459,16 @@ static const struct file_operations lpfc_debugfs_op_dumpDif = {
	.release =      lpfc_debugfs_dumpDataDif_release,
};

#undef lpfc_debugfs_op_dif_err
static const struct file_operations lpfc_debugfs_op_dif_err = {
	.owner =	THIS_MODULE,
	.open =		lpfc_debugfs_dif_err_open,
	.llseek =	lpfc_debugfs_lseek,
	.read =		lpfc_debugfs_dif_err_read,
	.write =	lpfc_debugfs_dif_err_write,
	.release =	lpfc_debugfs_dif_err_release,
};

#undef lpfc_debugfs_op_slow_ring_trc
static const struct file_operations lpfc_debugfs_op_slow_ring_trc = {
	.owner =        THIS_MODULE,
@@ -3788,6 +3877,74 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
			goto debug_failed;
		}

		/* Setup DIF Error Injections */
		snprintf(name, sizeof(name), "InjErrLBA");
		phba->debug_InjErrLBA =
			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
			phba->hba_debugfs_root,
			phba, &lpfc_debugfs_op_dif_err);
		if (!phba->debug_InjErrLBA) {
			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
				"0807 Cannot create debugfs InjErrLBA\n");
			goto debug_failed;
		}
		phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;

		snprintf(name, sizeof(name), "writeGuardInjErr");
		phba->debug_writeGuard =
			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
			phba->hba_debugfs_root,
			phba, &lpfc_debugfs_op_dif_err);
		if (!phba->debug_writeGuard) {
			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
				"0802 Cannot create debugfs writeGuard\n");
			goto debug_failed;
		}

		snprintf(name, sizeof(name), "writeAppInjErr");
		phba->debug_writeApp =
			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
			phba->hba_debugfs_root,
			phba, &lpfc_debugfs_op_dif_err);
		if (!phba->debug_writeApp) {
			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
				"0803 Cannot create debugfs writeApp\n");
			goto debug_failed;
		}

		snprintf(name, sizeof(name), "writeRefInjErr");
		phba->debug_writeRef =
			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
			phba->hba_debugfs_root,
			phba, &lpfc_debugfs_op_dif_err);
		if (!phba->debug_writeRef) {
			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
				"0804 Cannot create debugfs writeRef\n");
			goto debug_failed;
		}

		snprintf(name, sizeof(name), "readAppInjErr");
		phba->debug_readApp =
			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
			phba->hba_debugfs_root,
			phba, &lpfc_debugfs_op_dif_err);
		if (!phba->debug_readApp) {
			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
				"0805 Cannot create debugfs readApp\n");
			goto debug_failed;
		}

		snprintf(name, sizeof(name), "readRefInjErr");
		phba->debug_readRef =
			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
			phba->hba_debugfs_root,
			phba, &lpfc_debugfs_op_dif_err);
		if (!phba->debug_readRef) {
			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
				"0806 Cannot create debugfs readApp\n");
			goto debug_failed;
		}

		/* Setup slow ring trace */
		if (lpfc_debugfs_max_slow_ring_trc) {
			num = lpfc_debugfs_max_slow_ring_trc - 1;
@@ -4090,6 +4247,30 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport)
			debugfs_remove(phba->debug_dumpDif); /* dumpDif */
			phba->debug_dumpDif = NULL;
		}
		if (phba->debug_InjErrLBA) {
			debugfs_remove(phba->debug_InjErrLBA); /* InjErrLBA */
			phba->debug_InjErrLBA = NULL;
		}
		if (phba->debug_writeGuard) {
			debugfs_remove(phba->debug_writeGuard); /* writeGuard */
			phba->debug_writeGuard = NULL;
		}
		if (phba->debug_writeApp) {
			debugfs_remove(phba->debug_writeApp); /* writeApp */
			phba->debug_writeApp = NULL;
		}
		if (phba->debug_writeRef) {
			debugfs_remove(phba->debug_writeRef); /* writeRef */
			phba->debug_writeRef = NULL;
		}
		if (phba->debug_readApp) {
			debugfs_remove(phba->debug_readApp); /* readApp */
			phba->debug_readApp = NULL;
		}
		if (phba->debug_readRef) {
			debugfs_remove(phba->debug_readRef); /* readRef */
			phba->debug_readRef = NULL;
		}

		if (phba->slow_ring_trc) {
			kfree(phba->slow_ring_trc);
+84 −4
Original line number Diff line number Diff line
@@ -1484,16 +1484,81 @@ struct sli4_sge { /* SLI-4 */
	uint32_t addr_lo;

	uint32_t word2;
#define lpfc_sli4_sge_offset_SHIFT	0 /* Offset of buffer - Not used*/
#define lpfc_sli4_sge_offset_MASK	0x1FFFFFFF
#define lpfc_sli4_sge_offset_SHIFT	0
#define lpfc_sli4_sge_offset_MASK	0x07FFFFFF
#define lpfc_sli4_sge_offset_WORD	word2
#define lpfc_sli4_sge_last_SHIFT	31 /* Last SEG in the SGL sets
						this  flag !! */
#define lpfc_sli4_sge_type_SHIFT	27
#define lpfc_sli4_sge_type_MASK		0x0000000F
#define lpfc_sli4_sge_type_WORD		word2
#define LPFC_SGE_TYPE_DATA		0x0
#define LPFC_SGE_TYPE_DIF		0x4
#define LPFC_SGE_TYPE_LSP		0x5
#define LPFC_SGE_TYPE_PEDIF		0x6
#define LPFC_SGE_TYPE_PESEED		0x7
#define LPFC_SGE_TYPE_DISEED		0x8
#define LPFC_SGE_TYPE_ENC		0x9
#define LPFC_SGE_TYPE_ATM		0xA
#define LPFC_SGE_TYPE_SKIP		0xC
#define lpfc_sli4_sge_last_SHIFT	31 /* Last SEG in the SGL sets it */
#define lpfc_sli4_sge_last_MASK		0x00000001
#define lpfc_sli4_sge_last_WORD		word2
	uint32_t sge_len;
};

struct sli4_sge_diseed {	/* SLI-4 */
	uint32_t ref_tag;
	uint32_t ref_tag_tran;

	uint32_t word2;
#define lpfc_sli4_sge_dif_apptran_SHIFT	0
#define lpfc_sli4_sge_dif_apptran_MASK	0x0000FFFF
#define lpfc_sli4_sge_dif_apptran_WORD	word2
#define lpfc_sli4_sge_dif_af_SHIFT	24
#define lpfc_sli4_sge_dif_af_MASK	0x00000001
#define lpfc_sli4_sge_dif_af_WORD	word2
#define lpfc_sli4_sge_dif_na_SHIFT	25
#define lpfc_sli4_sge_dif_na_MASK	0x00000001
#define lpfc_sli4_sge_dif_na_WORD	word2
#define lpfc_sli4_sge_dif_hi_SHIFT	26
#define lpfc_sli4_sge_dif_hi_MASK	0x00000001
#define lpfc_sli4_sge_dif_hi_WORD	word2
#define lpfc_sli4_sge_dif_type_SHIFT	27
#define lpfc_sli4_sge_dif_type_MASK	0x0000000F
#define lpfc_sli4_sge_dif_type_WORD	word2
#define lpfc_sli4_sge_dif_last_SHIFT	31 /* Last SEG in the SGL sets it */
#define lpfc_sli4_sge_dif_last_MASK	0x00000001
#define lpfc_sli4_sge_dif_last_WORD	word2
	uint32_t word3;
#define lpfc_sli4_sge_dif_apptag_SHIFT	0
#define lpfc_sli4_sge_dif_apptag_MASK	0x0000FFFF
#define lpfc_sli4_sge_dif_apptag_WORD	word3
#define lpfc_sli4_sge_dif_bs_SHIFT	16
#define lpfc_sli4_sge_dif_bs_MASK	0x00000007
#define lpfc_sli4_sge_dif_bs_WORD	word3
#define lpfc_sli4_sge_dif_ai_SHIFT	19
#define lpfc_sli4_sge_dif_ai_MASK	0x00000001
#define lpfc_sli4_sge_dif_ai_WORD	word3
#define lpfc_sli4_sge_dif_me_SHIFT	20
#define lpfc_sli4_sge_dif_me_MASK	0x00000001
#define lpfc_sli4_sge_dif_me_WORD	word3
#define lpfc_sli4_sge_dif_re_SHIFT	21
#define lpfc_sli4_sge_dif_re_MASK	0x00000001
#define lpfc_sli4_sge_dif_re_WORD	word3
#define lpfc_sli4_sge_dif_ce_SHIFT	22
#define lpfc_sli4_sge_dif_ce_MASK	0x00000001
#define lpfc_sli4_sge_dif_ce_WORD	word3
#define lpfc_sli4_sge_dif_nr_SHIFT	23
#define lpfc_sli4_sge_dif_nr_MASK	0x00000001
#define lpfc_sli4_sge_dif_nr_WORD	word3
#define lpfc_sli4_sge_dif_oprx_SHIFT	24
#define lpfc_sli4_sge_dif_oprx_MASK	0x0000000F
#define lpfc_sli4_sge_dif_oprx_WORD	word3
#define lpfc_sli4_sge_dif_optx_SHIFT	28
#define lpfc_sli4_sge_dif_optx_MASK	0x0000000F
#define lpfc_sli4_sge_dif_optx_WORD	word3
/* optx and oprx use BG_OP_IN defines in lpfc_hw.h */
};

struct fcf_record {
	uint32_t max_rcv_size;
	uint32_t fka_adv_period;
@@ -3023,6 +3088,9 @@ struct wqe_common {
#define wqe_ctxt_tag_MASK     0x0000FFFF
#define wqe_ctxt_tag_WORD     word6
	uint32_t word7;
#define wqe_dif_SHIFT         0
#define wqe_dif_MASK          0x00000003
#define wqe_dif_WORD          word7
#define wqe_ct_SHIFT          2
#define wqe_ct_MASK           0x00000003
#define wqe_ct_WORD           word7
@@ -3035,12 +3103,21 @@ struct wqe_common {
#define wqe_class_SHIFT       16
#define wqe_class_MASK        0x00000007
#define wqe_class_WORD        word7
#define wqe_ar_SHIFT          19
#define wqe_ar_MASK           0x00000001
#define wqe_ar_WORD           word7
#define wqe_ag_SHIFT          wqe_ar_SHIFT
#define wqe_ag_MASK           wqe_ar_MASK
#define wqe_ag_WORD           wqe_ar_WORD
#define wqe_pu_SHIFT          20
#define wqe_pu_MASK           0x00000003
#define wqe_pu_WORD           word7
#define wqe_erp_SHIFT         22
#define wqe_erp_MASK          0x00000001
#define wqe_erp_WORD          word7
#define wqe_conf_SHIFT        wqe_erp_SHIFT
#define wqe_conf_MASK         wqe_erp_MASK
#define wqe_conf_WORD         wqe_erp_WORD
#define wqe_lnk_SHIFT         23
#define wqe_lnk_MASK          0x00000001
#define wqe_lnk_WORD          word7
@@ -3099,6 +3176,9 @@ struct wqe_common {
#define wqe_xc_SHIFT          21
#define wqe_xc_MASK           0x00000001
#define wqe_xc_WORD           word10
#define wqe_sr_SHIFT          22
#define wqe_sr_MASK           0x00000001
#define wqe_sr_WORD           word10
#define wqe_ccpe_SHIFT        23
#define wqe_ccpe_MASK         0x00000001
#define wqe_ccpe_WORD         word10
+186 −13
Original line number Diff line number Diff line
@@ -58,6 +58,13 @@ static char *dif_op_str[] = {
	"SCSI_PROT_READ_PASS",
	"SCSI_PROT_WRITE_PASS",
};

struct scsi_dif_tuple {
	__be16 guard_tag;       /* Checksum */
	__be16 app_tag;         /* Opaque storage */
	__be32 ref_tag;         /* Target LBA or indirect LBA */
};

static void
lpfc_release_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb);
static void
@@ -1263,6 +1270,174 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
	return 0;
}

static inline unsigned
lpfc_cmd_blksize(struct scsi_cmnd *sc)
{
	return sc->device->sector_size;
}

#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
/*
 * Given a scsi cmnd, determine the BlockGuard tags to be used with it
 * @sc: The SCSI command to examine
 * @reftag: (out) BlockGuard reference tag for transmitted data
 * @apptag: (out) BlockGuard application tag for transmitted data
 * @new_guard (in) Value to replace CRC with if needed
 *
 * Returns (1) if error injection was performed, (0) otherwise
 */
static int
lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc,
		uint32_t *reftag, uint16_t *apptag, uint32_t new_guard)
{
	struct scatterlist *sgpe; /* s/g prot entry */
	struct scatterlist *sgde; /* s/g data entry */
	struct scsi_dif_tuple *src;
	uint32_t op = scsi_get_prot_op(sc);
	uint32_t blksize;
	uint32_t numblks;
	sector_t lba;
	int rc = 0;

	if (op == SCSI_PROT_NORMAL)
		return 0;

	lba = scsi_get_lba(sc);
	if (phba->lpfc_injerr_lba != LPFC_INJERR_LBA_OFF) {
		blksize = lpfc_cmd_blksize(sc);
		numblks = (scsi_bufflen(sc) + blksize - 1) / blksize;

		/* Make sure we have the right LBA if one is specified */
		if ((phba->lpfc_injerr_lba < lba) ||
			(phba->lpfc_injerr_lba >= (lba + numblks)))
			return 0;
	}

	sgpe = scsi_prot_sglist(sc);
	sgde = scsi_sglist(sc);

	/* Should we change the Reference Tag */
	if (reftag) {
		/*
		 * If we are SCSI_PROT_WRITE_STRIP, the protection data is
		 * being stripped from the wire, thus it doesn't matter.
		 */
		if ((op == SCSI_PROT_WRITE_PASS) ||
			(op == SCSI_PROT_WRITE_INSERT)) {
			if (phba->lpfc_injerr_wref_cnt) {

				/* DEADBEEF will be the reftag on the wire */
				*reftag = 0xDEADBEEF;
				phba->lpfc_injerr_wref_cnt--;
				phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
				rc = 1;

				lpfc_printf_log(phba, KERN_ERR, LOG_BG,
					"9081 BLKGRD: Injecting reftag error: "
					"write lba x%lx\n", (unsigned long)lba);
			}
		} else {
			if (phba->lpfc_injerr_rref_cnt) {
				*reftag = 0xDEADBEEF;
				phba->lpfc_injerr_rref_cnt--;
				phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
				rc = 1;

				lpfc_printf_log(phba, KERN_ERR, LOG_BG,
					"9076 BLKGRD: Injecting reftag error: "
					"read lba x%lx\n", (unsigned long)lba);
			}
		}
	}

	/* Should we change the Application Tag */
	if (apptag) {
		/*
		 * If we are SCSI_PROT_WRITE_STRIP, the protection data is
		 * being stripped from the wire, thus it doesn't matter.
		 */
		if ((op == SCSI_PROT_WRITE_PASS) ||
			(op == SCSI_PROT_WRITE_INSERT)) {
			if (phba->lpfc_injerr_wapp_cnt) {

				/* DEAD will be the apptag on the wire */
				*apptag = 0xDEAD;
				phba->lpfc_injerr_wapp_cnt--;
				phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
				rc = 1;

				lpfc_printf_log(phba, KERN_ERR, LOG_BG,
					"9077 BLKGRD: Injecting apptag error: "
					"write lba x%lx\n", (unsigned long)lba);
			}
		} else {
			if (phba->lpfc_injerr_rapp_cnt) {
				*apptag = 0xDEAD;
				phba->lpfc_injerr_rapp_cnt--;
				phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
				rc = 1;

				lpfc_printf_log(phba, KERN_ERR, LOG_BG,
					"9078 BLKGRD: Injecting apptag error: "
					"read lba x%lx\n", (unsigned long)lba);
			}
		}
	}

	/* Should we change the Guard Tag */

	/*
	 * If we are SCSI_PROT_WRITE_INSERT, the protection data is
	 * being on the wire is being fully generated on the HBA.
	 * The host cannot change it or force an error.
	 */
	if (((op == SCSI_PROT_WRITE_STRIP) ||
		(op == SCSI_PROT_WRITE_PASS)) &&
		phba->lpfc_injerr_wgrd_cnt) {
		if (sgpe) {
			src = (struct scsi_dif_tuple *)sg_virt(sgpe);
			/*
			 * Just inject an error in the first
			 * prot block.
			 */
			lpfc_printf_log(phba, KERN_ERR, LOG_BG,
				"9079 BLKGRD: Injecting guard error: "
				"write lba x%lx oldGuard x%x refTag x%x\n",
				(unsigned long)lba, src->guard_tag,
				src->ref_tag);

			src->guard_tag = (uint16_t)new_guard;
			phba->lpfc_injerr_wgrd_cnt--;
			phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
			rc = 1;

		} else {
			blksize = lpfc_cmd_blksize(sc);
			/*
			 * Jump past the first data block
			 * and inject an error in the
			 * prot data. The prot data is already
			 * embedded after the regular data.
			 */
			src = (struct scsi_dif_tuple *)
					(sg_virt(sgde) + blksize);

			lpfc_printf_log(phba, KERN_ERR, LOG_BG,
				"9080 BLKGRD: Injecting guard error: "
				"write lba x%lx oldGuard x%x refTag x%x\n",
				(unsigned long)lba, src->guard_tag,
				src->ref_tag);

			src->guard_tag = (uint16_t)new_guard;
			phba->lpfc_injerr_wgrd_cnt--;
			phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
			rc = 1;
		}
	}
	return rc;
}
#endif

/*
 * Given a scsi cmnd, determine the BlockGuard opcodes to be used with it
 * @sc: The SCSI command to examine
@@ -1341,18 +1516,6 @@ lpfc_sc_to_bg_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc,
	return ret;
}

struct scsi_dif_tuple {
	__be16 guard_tag;       /* Checksum */
	__be16 app_tag;         /* Opaque storage */
	__be32 ref_tag;         /* Target LBA or indirect LBA */
};

static inline unsigned
lpfc_cmd_blksize(struct scsi_cmnd *sc)
{
	return sc->device->sector_size;
}

/*
 * This function sets up buffer list for protection groups of
 * type LPFC_PG_TYPE_NO_DIF
@@ -1401,6 +1564,11 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
	blksize = lpfc_cmd_blksize(sc);
	reftag = scsi_get_lba(sc) & 0xffffffff;

#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
	/* reftag is the only error we can inject here */
	lpfc_bg_err_inject(phba, sc, &reftag, 0, 0);
#endif

	/* setup PDE5 with what we have */
	pde5 = (struct lpfc_pde5 *) bpl;
	memset(pde5, 0, sizeof(struct lpfc_pde5));
@@ -1532,6 +1700,11 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
	blksize = lpfc_cmd_blksize(sc);
	reftag = scsi_get_lba(sc) & 0xffffffff;

#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
	/* reftag / guard tag are the only errors we can inject here */
	lpfc_bg_err_inject(phba, sc, &reftag, 0, 0xDEAD);
#endif

	split_offset = 0;
	do {
		/* setup PDE5 with what we have */
@@ -1671,7 +1844,6 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
		}

	} while (!alldone);

out:

	return num_bde;
@@ -2075,6 +2247,7 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
			else
				bf_set(lpfc_sli4_sge_last, sgl, 0);
			bf_set(lpfc_sli4_sge_offset, sgl, dma_offset);
			bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_DATA);
			sgl->word2 = cpu_to_le32(sgl->word2);
			sgl->sge_len = cpu_to_le32(dma_len);
			dma_offset += dma_len;
+2 −0
Original line number Diff line number Diff line
@@ -7538,6 +7538,8 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
				if (inbound == 1)
					offset = 0;
				bf_set(lpfc_sli4_sge_offset, sgl, offset);
				bf_set(lpfc_sli4_sge_type, sgl,
					LPFC_SGE_TYPE_DATA);
				offset += bde.tus.f.bdeSize;
			}
			sgl->word2 = cpu_to_le32(sgl->word2);