diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_scsi.c')
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 488 | 
1 files changed, 295 insertions, 193 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index efc055b6bac..88f3a83dbd2 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -39,8 +39,8 @@  #include "lpfc_sli4.h"  #include "lpfc_nl.h"  #include "lpfc_disc.h" -#include "lpfc_scsi.h"  #include "lpfc.h" +#include "lpfc_scsi.h"  #include "lpfc_logmsg.h"  #include "lpfc_crtn.h"  #include "lpfc_vport.h" @@ -51,13 +51,19 @@  int _dump_buf_done;  static char *dif_op_str[] = { -	"SCSI_PROT_NORMAL", -	"SCSI_PROT_READ_INSERT", -	"SCSI_PROT_WRITE_STRIP", -	"SCSI_PROT_READ_STRIP", -	"SCSI_PROT_WRITE_INSERT", -	"SCSI_PROT_READ_PASS", -	"SCSI_PROT_WRITE_PASS", +	"PROT_NORMAL", +	"PROT_READ_INSERT", +	"PROT_WRITE_STRIP", +	"PROT_READ_STRIP", +	"PROT_WRITE_INSERT", +	"PROT_READ_PASS", +	"PROT_WRITE_PASS", +}; + +static char *dif_grd_str[] = { +	"NO_GUARD", +	"DIF_CRC", +	"DIX_IP",  };  struct scsi_dif_tuple { @@ -1281,10 +1287,14 @@ lpfc_cmd_blksize(struct scsi_cmnd *sc)  #ifdef CONFIG_SCSI_LPFC_DEBUG_FS -#define BG_ERR_INIT	1 -#define BG_ERR_TGT	2 -#define BG_ERR_SWAP	3 -#define BG_ERR_CHECK	4 +/* Return if if error injection is detected by Initiator */ +#define BG_ERR_INIT	0x1 +/* Return if if error injection is detected by Target */ +#define BG_ERR_TGT	0x2 +/* Return if if swapping CSUM<-->CRC is required for error injection */ +#define BG_ERR_SWAP	0x10 +/* Return if disabling Guard/Ref/App checking is required for error injection */ +#define BG_ERR_CHECK	0x20  /**   * lpfc_bg_err_inject - Determine if we should inject an error @@ -1294,10 +1304,7 @@ lpfc_cmd_blksize(struct scsi_cmnd *sc)   * @apptag: (out) BlockGuard application tag for transmitted data   * @new_guard (in) Value to replace CRC with if needed   * - * Returns (1) if error injection is detected by Initiator - * Returns (2) if error injection is detected by Target - * Returns (3) if swapping CSUM->CRC is required for error injection - * Returns (4) disabling Guard/Ref/App checking is required for error injection + * Returns BG_ERR_* bit mask or 0 if request ignored   **/  static int  lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc, @@ -1305,7 +1312,10 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc,  {  	struct scatterlist *sgpe; /* s/g prot entry */  	struct scatterlist *sgde; /* s/g data entry */ +	struct lpfc_scsi_buf *lpfc_cmd = NULL;  	struct scsi_dif_tuple *src = NULL; +	struct lpfc_nodelist *ndlp; +	struct lpfc_rport_data *rdata;  	uint32_t op = scsi_get_prot_op(sc);  	uint32_t blksize;  	uint32_t numblks; @@ -1318,8 +1328,9 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc,  	sgpe = scsi_prot_sglist(sc);  	sgde = scsi_sglist(sc); -  	lba = scsi_get_lba(sc); + +	/* First check if we need to match the LBA */  	if (phba->lpfc_injerr_lba != LPFC_INJERR_LBA_OFF) {  		blksize = lpfc_cmd_blksize(sc);  		numblks = (scsi_bufflen(sc) + blksize - 1) / blksize; @@ -1334,66 +1345,123 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc,  				sizeof(struct scsi_dif_tuple);  			if (numblks < blockoff)  				blockoff = numblks; -			src = (struct scsi_dif_tuple *)sg_virt(sgpe); -			src += blockoff;  		}  	} +	/* Next check if we need to match the remote NPortID or WWPN */ +	rdata = sc->device->hostdata; +	if (rdata && rdata->pnode) { +		ndlp = rdata->pnode; + +		/* Make sure we have the right NPortID if one is specified */ +		if (phba->lpfc_injerr_nportid  && +			(phba->lpfc_injerr_nportid != ndlp->nlp_DID)) +			return 0; + +		/* +		 * Make sure we have the right WWPN if one is specified. +		 * wwn[0] should be a non-zero NAA in a good WWPN. +		 */ +		if (phba->lpfc_injerr_wwpn.u.wwn[0]  && +			(memcmp(&ndlp->nlp_portname, &phba->lpfc_injerr_wwpn, +				sizeof(struct lpfc_name)) != 0)) +			return 0; +	} + +	/* Setup a ptr to the protection data if the SCSI host provides it */ +	if (sgpe) { +		src = (struct scsi_dif_tuple *)sg_virt(sgpe); +		src += blockoff; +		lpfc_cmd = (struct lpfc_scsi_buf *)sc->host_scribble; +	} +  	/* Should we change the Reference Tag */  	if (reftag) {  		if (phba->lpfc_injerr_wref_cnt) {  			switch (op) {  			case SCSI_PROT_WRITE_PASS: -				if (blockoff && src) { -					/* Insert error in middle of the IO */ +				if (src) { +					/* +					 * For WRITE_PASS, force the error +					 * to be sent on the wire. It should +					 * be detected by the Target. +					 * If blockoff != 0 error will be +					 * inserted in middle of the IO. +					 */  					lpfc_printf_log(phba, KERN_ERR, LOG_BG,  					"9076 BLKGRD: Injecting reftag error: "  					"write lba x%lx + x%x oldrefTag x%x\n",  					(unsigned long)lba, blockoff, -					src->ref_tag); +					be32_to_cpu(src->ref_tag));  					/* -					 * NOTE, this will change ref tag in -					 * the memory location forever! +					 * Save the old ref_tag so we can +					 * restore it on completion.  					 */ -					src->ref_tag = 0xDEADBEEF; +					if (lpfc_cmd) { +						lpfc_cmd->prot_data_type = +							LPFC_INJERR_REFTAG; +						lpfc_cmd->prot_data_segment = +							src; +						lpfc_cmd->prot_data = +							src->ref_tag; +					} +					src->ref_tag = cpu_to_be32(0xDEADBEEF);  					phba->lpfc_injerr_wref_cnt--; -					phba->lpfc_injerr_lba = -						LPFC_INJERR_LBA_OFF; -					rc = BG_ERR_CHECK; +					if (phba->lpfc_injerr_wref_cnt == 0) { +						phba->lpfc_injerr_nportid = 0; +						phba->lpfc_injerr_lba = +							LPFC_INJERR_LBA_OFF; +						memset(&phba->lpfc_injerr_wwpn, +						  0, sizeof(struct lpfc_name)); +					} +					rc = BG_ERR_TGT | BG_ERR_CHECK; +  					break;  				}  				/* Drop thru */ -			case SCSI_PROT_WRITE_STRIP: +			case SCSI_PROT_WRITE_INSERT:  				/* -				 * For WRITE_STRIP and WRITE_PASS, -				 * force the error on data -				 * being copied from SLI-Host to SLI-Port. +				 * For WRITE_INSERT, force the error +				 * to be sent on the wire. It should be +				 * detected by the Target.  				 */ +				/* DEADBEEF will be the reftag on the wire */  				*reftag = 0xDEADBEEF;  				phba->lpfc_injerr_wref_cnt--; -				phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; -				rc = BG_ERR_INIT; +				if (phba->lpfc_injerr_wref_cnt == 0) { +					phba->lpfc_injerr_nportid = 0; +					phba->lpfc_injerr_lba = +					LPFC_INJERR_LBA_OFF; +					memset(&phba->lpfc_injerr_wwpn, +						0, sizeof(struct lpfc_name)); +				} +				rc = BG_ERR_TGT | BG_ERR_CHECK;  				lpfc_printf_log(phba, KERN_ERR, LOG_BG, -					"9077 BLKGRD: Injecting reftag error: " +					"9078 BLKGRD: Injecting reftag error: "  					"write lba x%lx\n", (unsigned long)lba);  				break; -			case SCSI_PROT_WRITE_INSERT: +			case SCSI_PROT_WRITE_STRIP:  				/* -				 * For WRITE_INSERT, force the -				 * error to be sent on the wire. It should be -				 * detected by the Target. +				 * For WRITE_STRIP and WRITE_PASS, +				 * force the error on data +				 * being copied from SLI-Host to SLI-Port.  				 */ -				/* DEADBEEF will be the reftag on the wire */  				*reftag = 0xDEADBEEF;  				phba->lpfc_injerr_wref_cnt--; -				phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; -				rc = BG_ERR_TGT; +				if (phba->lpfc_injerr_wref_cnt == 0) { +					phba->lpfc_injerr_nportid = 0; +					phba->lpfc_injerr_lba = +						LPFC_INJERR_LBA_OFF; +					memset(&phba->lpfc_injerr_wwpn, +						0, sizeof(struct lpfc_name)); +				} +				rc = BG_ERR_INIT;  				lpfc_printf_log(phba, KERN_ERR, LOG_BG, -					"9078 BLKGRD: Injecting reftag error: " +					"9077 BLKGRD: Injecting reftag error: "  					"write lba x%lx\n", (unsigned long)lba);  				break;  			} @@ -1401,11 +1469,6 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc,  		if (phba->lpfc_injerr_rref_cnt) {  			switch (op) {  			case SCSI_PROT_READ_INSERT: -				/* -				 * For READ_INSERT, it doesn't make sense -				 * to change the reftag. -				 */ -				break;  			case SCSI_PROT_READ_STRIP:  			case SCSI_PROT_READ_PASS:  				/* @@ -1415,7 +1478,13 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc,  				 */  				*reftag = 0xDEADBEEF;  				phba->lpfc_injerr_rref_cnt--; -				phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; +				if (phba->lpfc_injerr_rref_cnt == 0) { +					phba->lpfc_injerr_nportid = 0; +					phba->lpfc_injerr_lba = +						LPFC_INJERR_LBA_OFF; +					memset(&phba->lpfc_injerr_wwpn, +						0, sizeof(struct lpfc_name)); +				}  				rc = BG_ERR_INIT;  				lpfc_printf_log(phba, KERN_ERR, LOG_BG, @@ -1431,56 +1500,87 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc,  		if (phba->lpfc_injerr_wapp_cnt) {  			switch (op) {  			case SCSI_PROT_WRITE_PASS: -				if (blockoff && src) { -					/* Insert error in middle of the IO */ +				if (src) { +					/* +					 * For WRITE_PASS, force the error +					 * to be sent on the wire. It should +					 * be detected by the Target. +					 * If blockoff != 0 error will be +					 * inserted in middle of the IO. +					 */  					lpfc_printf_log(phba, KERN_ERR, LOG_BG,  					"9080 BLKGRD: Injecting apptag error: "  					"write lba x%lx + x%x oldappTag x%x\n",  					(unsigned long)lba, blockoff, -					src->app_tag); +					be16_to_cpu(src->app_tag));  					/* -					 * NOTE, this will change app tag in -					 * the memory location forever! +					 * Save the old app_tag so we can +					 * restore it on completion.  					 */ -					src->app_tag = 0xDEAD; +					if (lpfc_cmd) { +						lpfc_cmd->prot_data_type = +							LPFC_INJERR_APPTAG; +						lpfc_cmd->prot_data_segment = +							src; +						lpfc_cmd->prot_data = +							src->app_tag; +					} +					src->app_tag = cpu_to_be16(0xDEAD);  					phba->lpfc_injerr_wapp_cnt--; -					phba->lpfc_injerr_lba = -						LPFC_INJERR_LBA_OFF; -					rc = BG_ERR_CHECK; +					if (phba->lpfc_injerr_wapp_cnt == 0) { +						phba->lpfc_injerr_nportid = 0; +						phba->lpfc_injerr_lba = +							LPFC_INJERR_LBA_OFF; +						memset(&phba->lpfc_injerr_wwpn, +						  0, sizeof(struct lpfc_name)); +					} +					rc = BG_ERR_TGT | BG_ERR_CHECK;  					break;  				}  				/* Drop thru */ -			case SCSI_PROT_WRITE_STRIP: +			case SCSI_PROT_WRITE_INSERT:  				/* -				 * For WRITE_STRIP and WRITE_PASS, -				 * force the error on data -				 * being copied from SLI-Host to SLI-Port. +				 * For WRITE_INSERT, force the +				 * error to be sent on the wire. It should be +				 * detected by the Target.  				 */ +				/* DEAD will be the apptag on the wire */  				*apptag = 0xDEAD;  				phba->lpfc_injerr_wapp_cnt--; -				phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; -				rc = BG_ERR_INIT; +				if (phba->lpfc_injerr_wapp_cnt == 0) { +					phba->lpfc_injerr_nportid = 0; +					phba->lpfc_injerr_lba = +						LPFC_INJERR_LBA_OFF; +					memset(&phba->lpfc_injerr_wwpn, +						0, sizeof(struct lpfc_name)); +				} +				rc = BG_ERR_TGT | BG_ERR_CHECK;  				lpfc_printf_log(phba, KERN_ERR, LOG_BG, -					"0812 BLKGRD: Injecting apptag error: " +					"0813 BLKGRD: Injecting apptag error: "  					"write lba x%lx\n", (unsigned long)lba);  				break; -			case SCSI_PROT_WRITE_INSERT: +			case SCSI_PROT_WRITE_STRIP:  				/* -				 * For WRITE_INSERT, force the -				 * error to be sent on the wire. It should be -				 * detected by the Target. +				 * For WRITE_STRIP and WRITE_PASS, +				 * force the error on data +				 * being copied from SLI-Host to SLI-Port.  				 */ -				/* DEAD will be the apptag on the wire */  				*apptag = 0xDEAD;  				phba->lpfc_injerr_wapp_cnt--; -				phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; -				rc = BG_ERR_TGT; +				if (phba->lpfc_injerr_wapp_cnt == 0) { +					phba->lpfc_injerr_nportid = 0; +					phba->lpfc_injerr_lba = +						LPFC_INJERR_LBA_OFF; +					memset(&phba->lpfc_injerr_wwpn, +						0, sizeof(struct lpfc_name)); +				} +				rc = BG_ERR_INIT;  				lpfc_printf_log(phba, KERN_ERR, LOG_BG, -					"0813 BLKGRD: Injecting apptag error: " +					"0812 BLKGRD: Injecting apptag error: "  					"write lba x%lx\n", (unsigned long)lba);  				break;  			} @@ -1488,11 +1588,6 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc,  		if (phba->lpfc_injerr_rapp_cnt) {  			switch (op) {  			case SCSI_PROT_READ_INSERT: -				/* -				 * For READ_INSERT, it doesn't make sense -				 * to change the apptag. -				 */ -				break;  			case SCSI_PROT_READ_STRIP:  			case SCSI_PROT_READ_PASS:  				/* @@ -1502,7 +1597,13 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc,  				 */  				*apptag = 0xDEAD;  				phba->lpfc_injerr_rapp_cnt--; -				phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; +				if (phba->lpfc_injerr_rapp_cnt == 0) { +					phba->lpfc_injerr_nportid = 0; +					phba->lpfc_injerr_lba = +						LPFC_INJERR_LBA_OFF; +					memset(&phba->lpfc_injerr_wwpn, +						0, sizeof(struct lpfc_name)); +				}  				rc = BG_ERR_INIT;  				lpfc_printf_log(phba, KERN_ERR, LOG_BG, @@ -1519,57 +1620,51 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc,  		if (phba->lpfc_injerr_wgrd_cnt) {  			switch (op) {  			case SCSI_PROT_WRITE_PASS: -				if (blockoff && src) { -					/* Insert error in middle of the IO */ - -					lpfc_printf_log(phba, KERN_ERR, LOG_BG, -					"0815 BLKGRD: Injecting guard error: " -					"write lba x%lx + x%x oldgrdTag x%x\n", -					(unsigned long)lba, blockoff, -					src->guard_tag); - -					/* -					 * NOTE, this will change guard tag in -					 * the memory location forever! -					 */ -					src->guard_tag = 0xDEAD; -					phba->lpfc_injerr_wgrd_cnt--; -					phba->lpfc_injerr_lba = -						LPFC_INJERR_LBA_OFF; -					rc = BG_ERR_CHECK; -					break; -				} +				rc = BG_ERR_CHECK;  				/* Drop thru */ -			case SCSI_PROT_WRITE_STRIP: + +			case SCSI_PROT_WRITE_INSERT:  				/* -				 * For WRITE_STRIP and WRITE_PASS, -				 * force the error on data -				 * being copied from SLI-Host to SLI-Port. +				 * For WRITE_INSERT, force the +				 * error to be sent on the wire. It should be +				 * detected by the Target.  				 */  				phba->lpfc_injerr_wgrd_cnt--; -				phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; +				if (phba->lpfc_injerr_wgrd_cnt == 0) { +					phba->lpfc_injerr_nportid = 0; +					phba->lpfc_injerr_lba = +						LPFC_INJERR_LBA_OFF; +					memset(&phba->lpfc_injerr_wwpn, +						0, sizeof(struct lpfc_name)); +				} -				rc = BG_ERR_SWAP; +				rc |= BG_ERR_TGT | BG_ERR_SWAP;  				/* Signals the caller to swap CRC->CSUM */  				lpfc_printf_log(phba, KERN_ERR, LOG_BG, -					"0816 BLKGRD: Injecting guard error: " +					"0817 BLKGRD: Injecting guard error: "  					"write lba x%lx\n", (unsigned long)lba);  				break; -			case SCSI_PROT_WRITE_INSERT: +			case SCSI_PROT_WRITE_STRIP:  				/* -				 * For WRITE_INSERT, force the -				 * error to be sent on the wire. It should be -				 * detected by the Target. +				 * For WRITE_STRIP and WRITE_PASS, +				 * force the error on data +				 * being copied from SLI-Host to SLI-Port.  				 */  				phba->lpfc_injerr_wgrd_cnt--; -				phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; +				if (phba->lpfc_injerr_wgrd_cnt == 0) { +					phba->lpfc_injerr_nportid = 0; +					phba->lpfc_injerr_lba = +						LPFC_INJERR_LBA_OFF; +					memset(&phba->lpfc_injerr_wwpn, +						0, sizeof(struct lpfc_name)); +				} -				rc = BG_ERR_SWAP; +				rc = BG_ERR_INIT | BG_ERR_SWAP;  				/* Signals the caller to swap CRC->CSUM */  				lpfc_printf_log(phba, KERN_ERR, LOG_BG, -					"0817 BLKGRD: Injecting guard error: " +					"0816 BLKGRD: Injecting guard error: "  					"write lba x%lx\n", (unsigned long)lba);  				break;  			} @@ -1577,11 +1672,6 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc,  		if (phba->lpfc_injerr_rgrd_cnt) {  			switch (op) {  			case SCSI_PROT_READ_INSERT: -				/* -				 * For READ_INSERT, it doesn't make sense -				 * to change the guard tag. -				 */ -				break;  			case SCSI_PROT_READ_STRIP:  			case SCSI_PROT_READ_PASS:  				/* @@ -1589,11 +1679,16 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc,  				 * error on data being read off the wire. It  				 * should force an IO error to the driver.  				 */ -				*apptag = 0xDEAD;  				phba->lpfc_injerr_rgrd_cnt--; -				phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; +				if (phba->lpfc_injerr_rgrd_cnt == 0) { +					phba->lpfc_injerr_nportid = 0; +					phba->lpfc_injerr_lba = +						LPFC_INJERR_LBA_OFF; +					memset(&phba->lpfc_injerr_wwpn, +						0, sizeof(struct lpfc_name)); +				} -				rc = BG_ERR_SWAP; +				rc = BG_ERR_INIT | BG_ERR_SWAP;  				/* Signals the caller to swap CRC->CSUM */  				lpfc_printf_log(phba, KERN_ERR, LOG_BG, @@ -1629,20 +1724,20 @@ lpfc_sc_to_bg_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc,  		switch (scsi_get_prot_op(sc)) {  		case SCSI_PROT_READ_INSERT:  		case SCSI_PROT_WRITE_STRIP: -			*txop = BG_OP_IN_CSUM_OUT_NODIF;  			*rxop = BG_OP_IN_NODIF_OUT_CSUM; +			*txop = BG_OP_IN_CSUM_OUT_NODIF;  			break;  		case SCSI_PROT_READ_STRIP:  		case SCSI_PROT_WRITE_INSERT: -			*txop = BG_OP_IN_NODIF_OUT_CRC;  			*rxop = BG_OP_IN_CRC_OUT_NODIF; +			*txop = BG_OP_IN_NODIF_OUT_CRC;  			break;  		case SCSI_PROT_READ_PASS:  		case SCSI_PROT_WRITE_PASS: -			*txop = BG_OP_IN_CSUM_OUT_CRC;  			*rxop = BG_OP_IN_CRC_OUT_CSUM; +			*txop = BG_OP_IN_CSUM_OUT_CRC;  			break;  		case SCSI_PROT_NORMAL: @@ -1658,20 +1753,20 @@ lpfc_sc_to_bg_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc,  		switch (scsi_get_prot_op(sc)) {  		case SCSI_PROT_READ_STRIP:  		case SCSI_PROT_WRITE_INSERT: -			*txop = BG_OP_IN_NODIF_OUT_CRC;  			*rxop = BG_OP_IN_CRC_OUT_NODIF; +			*txop = BG_OP_IN_NODIF_OUT_CRC;  			break;  		case SCSI_PROT_READ_PASS:  		case SCSI_PROT_WRITE_PASS: -			*txop = BG_OP_IN_CRC_OUT_CRC;  			*rxop = BG_OP_IN_CRC_OUT_CRC; +			*txop = BG_OP_IN_CRC_OUT_CRC;  			break;  		case SCSI_PROT_READ_INSERT:  		case SCSI_PROT_WRITE_STRIP: -			*txop = BG_OP_IN_CRC_OUT_NODIF;  			*rxop = BG_OP_IN_NODIF_OUT_CRC; +			*txop = BG_OP_IN_CRC_OUT_NODIF;  			break;  		case SCSI_PROT_NORMAL: @@ -1710,20 +1805,20 @@ lpfc_bg_err_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc,  		switch (scsi_get_prot_op(sc)) {  		case SCSI_PROT_READ_INSERT:  		case SCSI_PROT_WRITE_STRIP: -			*txop = BG_OP_IN_CRC_OUT_NODIF;  			*rxop = BG_OP_IN_NODIF_OUT_CRC; +			*txop = BG_OP_IN_CRC_OUT_NODIF;  			break;  		case SCSI_PROT_READ_STRIP:  		case SCSI_PROT_WRITE_INSERT: -			*txop = BG_OP_IN_NODIF_OUT_CSUM;  			*rxop = BG_OP_IN_CSUM_OUT_NODIF; +			*txop = BG_OP_IN_NODIF_OUT_CSUM;  			break;  		case SCSI_PROT_READ_PASS:  		case SCSI_PROT_WRITE_PASS: -			*txop = BG_OP_IN_CRC_OUT_CRC; -			*rxop = BG_OP_IN_CRC_OUT_CRC; +			*rxop = BG_OP_IN_CSUM_OUT_CRC; +			*txop = BG_OP_IN_CRC_OUT_CSUM;  			break;  		case SCSI_PROT_NORMAL: @@ -1735,20 +1830,20 @@ lpfc_bg_err_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc,  		switch (scsi_get_prot_op(sc)) {  		case SCSI_PROT_READ_STRIP:  		case SCSI_PROT_WRITE_INSERT: -			*txop = BG_OP_IN_NODIF_OUT_CSUM;  			*rxop = BG_OP_IN_CSUM_OUT_NODIF; +			*txop = BG_OP_IN_NODIF_OUT_CSUM;  			break;  		case SCSI_PROT_READ_PASS:  		case SCSI_PROT_WRITE_PASS: -			*txop = BG_OP_IN_CSUM_OUT_CRC; -			*rxop = BG_OP_IN_CRC_OUT_CSUM; +			*rxop = BG_OP_IN_CSUM_OUT_CSUM; +			*txop = BG_OP_IN_CSUM_OUT_CSUM;  			break;  		case SCSI_PROT_READ_INSERT:  		case SCSI_PROT_WRITE_STRIP: -			*txop = BG_OP_IN_CSUM_OUT_NODIF;  			*rxop = BG_OP_IN_NODIF_OUT_CSUM; +			*txop = BG_OP_IN_CSUM_OUT_NODIF;  			break;  		case SCSI_PROT_NORMAL: @@ -1817,11 +1912,11 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc,  	reftag = (uint32_t)scsi_get_lba(sc); /* Truncate LBA */  #ifdef CONFIG_SCSI_LPFC_DEBUG_FS -	rc = lpfc_bg_err_inject(phba, sc, &reftag, 0, 1); +	rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1);  	if (rc) { -		if (rc == BG_ERR_SWAP) +		if (rc & BG_ERR_SWAP)  			lpfc_bg_err_opcodes(phba, sc, &txop, &rxop); -		if (rc == BG_ERR_CHECK) +		if (rc & BG_ERR_CHECK)  			checking = 0;  	}  #endif @@ -1964,11 +2059,11 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,  	reftag = (uint32_t)scsi_get_lba(sc); /* Truncate LBA */  #ifdef CONFIG_SCSI_LPFC_DEBUG_FS -	rc = lpfc_bg_err_inject(phba, sc, &reftag, 0, 1); +	rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1);  	if (rc) { -		if (rc == BG_ERR_SWAP) +		if (rc & BG_ERR_SWAP)  			lpfc_bg_err_opcodes(phba, sc, &txop, &rxop); -		if (rc == BG_ERR_CHECK) +		if (rc & BG_ERR_CHECK)  			checking = 0;  	}  #endif @@ -2172,11 +2267,11 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc,  	reftag = (uint32_t)scsi_get_lba(sc); /* Truncate LBA */  #ifdef CONFIG_SCSI_LPFC_DEBUG_FS -	rc = lpfc_bg_err_inject(phba, sc, &reftag, 0, 1); +	rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1);  	if (rc) { -		if (rc == BG_ERR_SWAP) +		if (rc & BG_ERR_SWAP)  			lpfc_bg_err_opcodes(phba, sc, &txop, &rxop); -		if (rc == BG_ERR_CHECK) +		if (rc & BG_ERR_CHECK)  			checking = 0;  	}  #endif @@ -2312,11 +2407,11 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,  	reftag = (uint32_t)scsi_get_lba(sc); /* Truncate LBA */  #ifdef CONFIG_SCSI_LPFC_DEBUG_FS -	rc = lpfc_bg_err_inject(phba, sc, &reftag, 0, 1); +	rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1);  	if (rc) { -		if (rc == BG_ERR_SWAP) +		if (rc & BG_ERR_SWAP)  			lpfc_bg_err_opcodes(phba, sc, &txop, &rxop); -		if (rc == BG_ERR_CHECK) +		if (rc & BG_ERR_CHECK)  			checking = 0;  	}  #endif @@ -2788,7 +2883,7 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd,  		/* No error was reported - problem in FW? */  		cmd->result = ScsiResult(DID_ERROR, 0);  		lpfc_printf_log(phba, KERN_ERR, LOG_BG, -			"9057 BLKGRD: no errors reported!\n"); +			"9057 BLKGRD: Unknown error reported!\n");  	}  out: @@ -3460,6 +3555,37 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,  	/* pick up SLI4 exhange busy status from HBA */  	lpfc_cmd->exch_busy = pIocbOut->iocb_flag & LPFC_EXCHANGE_BUSY; +#ifdef CONFIG_SCSI_LPFC_DEBUG_FS +	if (lpfc_cmd->prot_data_type) { +		struct scsi_dif_tuple *src = NULL; + +		src =  (struct scsi_dif_tuple *)lpfc_cmd->prot_data_segment; +		/* +		 * Used to restore any changes to protection +		 * data for error injection. +		 */ +		switch (lpfc_cmd->prot_data_type) { +		case LPFC_INJERR_REFTAG: +			src->ref_tag = +				lpfc_cmd->prot_data; +			break; +		case LPFC_INJERR_APPTAG: +			src->app_tag = +				(uint16_t)lpfc_cmd->prot_data; +			break; +		case LPFC_INJERR_GUARD: +			src->guard_tag = +				(uint16_t)lpfc_cmd->prot_data; +			break; +		default: +			break; +		} + +		lpfc_cmd->prot_data = 0; +		lpfc_cmd->prot_data_type = 0; +		lpfc_cmd->prot_data_segment = NULL; +	} +#endif  	if (pnode && NLP_CHK_NODE_ACT(pnode))  		atomic_dec(&pnode->cmd_pending); @@ -4061,15 +4187,6 @@ lpfc_queuecommand_lck(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))  		cmnd->result = err;  		goto out_fail_command;  	} -	/* -	 * Do not let the mid-layer retry I/O too fast. If an I/O is retried -	 * without waiting a bit then indicate that the device is busy. -	 */ -	if (cmnd->retries && -	    time_before(jiffies, (cmnd->jiffies_at_alloc + -				  msecs_to_jiffies(LPFC_RETRY_PAUSE * -						   cmnd->retries)))) -		return SCSI_MLQUEUE_DEVICE_BUSY;  	ndlp = rdata->pnode;  	if ((scsi_get_prot_op(cmnd) != SCSI_PROT_NORMAL) && @@ -4119,63 +4236,48 @@ lpfc_queuecommand_lck(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))  	if (scsi_get_prot_op(cmnd) != SCSI_PROT_NORMAL) {  		if (vport->phba->cfg_enable_bg) {  			lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG, -				"9033 BLKGRD: rcvd protected cmd:%02x op:%02x " -				"str=%s\n", -				cmnd->cmnd[0], scsi_get_prot_op(cmnd), -				dif_op_str[scsi_get_prot_op(cmnd)]); -			lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG, -				"9034 BLKGRD: CDB: %02x %02x %02x %02x %02x " -				"%02x %02x %02x %02x %02x\n", -				cmnd->cmnd[0], cmnd->cmnd[1], cmnd->cmnd[2], -				cmnd->cmnd[3], cmnd->cmnd[4], cmnd->cmnd[5], -				cmnd->cmnd[6], cmnd->cmnd[7], cmnd->cmnd[8], -				cmnd->cmnd[9]); +				"9033 BLKGRD: rcvd protected cmd:%02x op=%s " +				"guard=%s\n", cmnd->cmnd[0], +				dif_op_str[scsi_get_prot_op(cmnd)], +				dif_grd_str[scsi_host_get_guard(shost)]);  			if (cmnd->cmnd[0] == READ_10)  				lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,  					"9035 BLKGRD: READ @ sector %llu, " -					"count %u\n", +					"cnt %u, rpt %d\n",  					(unsigned long long)scsi_get_lba(cmnd), -					blk_rq_sectors(cmnd->request)); +					blk_rq_sectors(cmnd->request), +					(cmnd->cmnd[1]>>5));  			else if (cmnd->cmnd[0] == WRITE_10)  				lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,  					"9036 BLKGRD: WRITE @ sector %llu, " -					"count %u cmd=%p\n", +					"cnt %u, wpt %d\n",  					(unsigned long long)scsi_get_lba(cmnd),  					blk_rq_sectors(cmnd->request), -					cmnd); +					(cmnd->cmnd[1]>>5));  		}  		err = lpfc_bg_scsi_prep_dma_buf(phba, lpfc_cmd);  	} else {  		if (vport->phba->cfg_enable_bg) {  			lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG, -					"9038 BLKGRD: rcvd unprotected cmd:" -					"%02x op:%02x str=%s\n", -					cmnd->cmnd[0], scsi_get_prot_op(cmnd), -					dif_op_str[scsi_get_prot_op(cmnd)]); -				lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG, -					"9039 BLKGRD: CDB: %02x %02x %02x " -					"%02x %02x %02x %02x %02x %02x %02x\n", -					cmnd->cmnd[0], cmnd->cmnd[1], -					cmnd->cmnd[2], cmnd->cmnd[3], -					cmnd->cmnd[4], cmnd->cmnd[5], -					cmnd->cmnd[6], cmnd->cmnd[7], -					cmnd->cmnd[8], cmnd->cmnd[9]); +				"9038 BLKGRD: rcvd unprotected cmd:" +				"%02x op=%s guard=%s\n", cmnd->cmnd[0], +				dif_op_str[scsi_get_prot_op(cmnd)], +				dif_grd_str[scsi_host_get_guard(shost)]);  			if (cmnd->cmnd[0] == READ_10)  				lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,  					"9040 dbg: READ @ sector %llu, " -					"count %u\n", +					"cnt %u, rpt %d\n",  					(unsigned long long)scsi_get_lba(cmnd), -					 blk_rq_sectors(cmnd->request)); +					 blk_rq_sectors(cmnd->request), +					(cmnd->cmnd[1]>>5));  			else if (cmnd->cmnd[0] == WRITE_10)  				lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG, -					 "9041 dbg: WRITE @ sector %llu, " -					 "count %u cmd=%p\n", -					 (unsigned long long)scsi_get_lba(cmnd), -					 blk_rq_sectors(cmnd->request), cmnd); -			else -				lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG, -					 "9042 dbg: parser not implemented\n"); +					"9041 dbg: WRITE @ sector %llu, " +					"cnt %u, wpt %d\n", +					(unsigned long long)scsi_get_lba(cmnd), +					blk_rq_sectors(cmnd->request), +					(cmnd->cmnd[1]>>5));  		}  		err = lpfc_scsi_prep_dma_buf(phba, lpfc_cmd);  	}  |