提交 9c6aa9d7 编写于 作者: J James Smart 提交者: James Bottomley

[SCSI] lpfc 8.3.40: Fix BlockGuard error checking

Signed-off-by: NJames Smart <james.smart@emulex.com>
Signed-off-by: NJames Bottomley <JBottomley@Parallels.com>
上级 3bf41ba9
...@@ -68,14 +68,12 @@ struct scsi_dif_tuple { ...@@ -68,14 +68,12 @@ struct scsi_dif_tuple {
__be32 ref_tag; /* Target LBA or indirect LBA */ __be32 ref_tag; /* Target LBA or indirect LBA */
}; };
#if !defined(SCSI_PROT_GUARD_CHECK) || !defined(SCSI_PROT_REF_CHECK)
#define scsi_prot_flagged(sc, flg) sc
#endif
static void static void
lpfc_release_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb); lpfc_release_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb);
static void static void
lpfc_release_scsi_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb); lpfc_release_scsi_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb);
static int
lpfc_prot_group_type(struct lpfc_hba *phba, struct scsi_cmnd *sc);
static void static void
lpfc_debug_save_data(struct lpfc_hba *phba, struct scsi_cmnd *cmnd) lpfc_debug_save_data(struct lpfc_hba *phba, struct scsi_cmnd *cmnd)
...@@ -134,6 +132,30 @@ lpfc_debug_save_dif(struct lpfc_hba *phba, struct scsi_cmnd *cmnd) ...@@ -134,6 +132,30 @@ lpfc_debug_save_dif(struct lpfc_hba *phba, struct scsi_cmnd *cmnd)
} }
} }
static inline unsigned
lpfc_cmd_blksize(struct scsi_cmnd *sc)
{
return sc->device->sector_size;
}
#define LPFC_CHECK_PROTECT_GUARD 1
#define LPFC_CHECK_PROTECT_REF 2
static inline unsigned
lpfc_cmd_protect(struct scsi_cmnd *sc, int flag)
{
return 1;
}
static inline unsigned
lpfc_cmd_guard_csum(struct scsi_cmnd *sc)
{
if (lpfc_prot_group_type(NULL, sc) == LPFC_PG_TYPE_NO_DIF)
return 0;
if (scsi_host_get_guard(sc->device->host) == SHOST_DIX_GUARD_IP)
return 1;
return 0;
}
/** /**
* lpfc_sli4_set_rsp_sgl_last - Set the last bit in the response sge. * lpfc_sli4_set_rsp_sgl_last - Set the last bit in the response sge.
* @phba: Pointer to HBA object. * @phba: Pointer to HBA object.
...@@ -1409,12 +1431,6 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) ...@@ -1409,12 +1431,6 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
return 0; return 0;
} }
static inline unsigned
lpfc_cmd_blksize(struct scsi_cmnd *sc)
{
return sc->device->sector_size;
}
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
/* Return if if error injection is detected by Initiator */ /* Return if if error injection is detected by Initiator */
...@@ -1847,10 +1863,9 @@ static int ...@@ -1847,10 +1863,9 @@ static int
lpfc_sc_to_bg_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc, lpfc_sc_to_bg_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc,
uint8_t *txop, uint8_t *rxop) uint8_t *txop, uint8_t *rxop)
{ {
uint8_t guard_type = scsi_host_get_guard(sc->device->host);
uint8_t ret = 0; uint8_t ret = 0;
if (guard_type == SHOST_DIX_GUARD_IP) { if (lpfc_cmd_guard_csum(sc)) {
switch (scsi_get_prot_op(sc)) { switch (scsi_get_prot_op(sc)) {
case SCSI_PROT_READ_INSERT: case SCSI_PROT_READ_INSERT:
case SCSI_PROT_WRITE_STRIP: case SCSI_PROT_WRITE_STRIP:
...@@ -1928,10 +1943,9 @@ static int ...@@ -1928,10 +1943,9 @@ static int
lpfc_bg_err_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc, lpfc_bg_err_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc,
uint8_t *txop, uint8_t *rxop) uint8_t *txop, uint8_t *rxop)
{ {
uint8_t guard_type = scsi_host_get_guard(sc->device->host);
uint8_t ret = 0; uint8_t ret = 0;
if (guard_type == SHOST_DIX_GUARD_IP) { if (lpfc_cmd_guard_csum(sc)) {
switch (scsi_get_prot_op(sc)) { switch (scsi_get_prot_op(sc)) {
case SCSI_PROT_READ_INSERT: case SCSI_PROT_READ_INSERT:
case SCSI_PROT_WRITE_STRIP: case SCSI_PROT_WRITE_STRIP:
...@@ -2078,12 +2092,12 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc, ...@@ -2078,12 +2092,12 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
* protection data is automatically generated, not checked. * protection data is automatically generated, not checked.
*/ */
if (datadir == DMA_FROM_DEVICE) { if (datadir == DMA_FROM_DEVICE) {
if (scsi_prot_flagged(sc, SCSI_PROT_GUARD_CHECK)) if (lpfc_cmd_protect(sc, LPFC_CHECK_PROTECT_GUARD))
bf_set(pde6_ce, pde6, checking); bf_set(pde6_ce, pde6, checking);
else else
bf_set(pde6_ce, pde6, 0); bf_set(pde6_ce, pde6, 0);
if (scsi_prot_flagged(sc, SCSI_PROT_REF_CHECK)) if (lpfc_cmd_protect(sc, LPFC_CHECK_PROTECT_REF))
bf_set(pde6_re, pde6, checking); bf_set(pde6_re, pde6, checking);
else else
bf_set(pde6_re, pde6, 0); bf_set(pde6_re, pde6, 0);
...@@ -2240,12 +2254,12 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, ...@@ -2240,12 +2254,12 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
bf_set(pde6_optx, pde6, txop); bf_set(pde6_optx, pde6, txop);
bf_set(pde6_oprx, pde6, rxop); bf_set(pde6_oprx, pde6, rxop);
if (scsi_prot_flagged(sc, SCSI_PROT_GUARD_CHECK)) if (lpfc_cmd_protect(sc, LPFC_CHECK_PROTECT_GUARD))
bf_set(pde6_ce, pde6, checking); bf_set(pde6_ce, pde6, checking);
else else
bf_set(pde6_ce, pde6, 0); bf_set(pde6_ce, pde6, 0);
if (scsi_prot_flagged(sc, SCSI_PROT_REF_CHECK)) if (lpfc_cmd_protect(sc, LPFC_CHECK_PROTECT_REF))
bf_set(pde6_re, pde6, checking); bf_set(pde6_re, pde6, checking);
else else
bf_set(pde6_re, pde6, 0); bf_set(pde6_re, pde6, 0);
...@@ -2454,12 +2468,12 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc, ...@@ -2454,12 +2468,12 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
* protection data is automatically generated, not checked. * protection data is automatically generated, not checked.
*/ */
if (sc->sc_data_direction == DMA_FROM_DEVICE) { if (sc->sc_data_direction == DMA_FROM_DEVICE) {
if (scsi_prot_flagged(sc, SCSI_PROT_GUARD_CHECK)) if (lpfc_cmd_protect(sc, LPFC_CHECK_PROTECT_GUARD))
bf_set(lpfc_sli4_sge_dif_ce, diseed, checking); bf_set(lpfc_sli4_sge_dif_ce, diseed, checking);
else else
bf_set(lpfc_sli4_sge_dif_ce, diseed, 0); bf_set(lpfc_sli4_sge_dif_ce, diseed, 0);
if (scsi_prot_flagged(sc, SCSI_PROT_REF_CHECK)) if (lpfc_cmd_protect(sc, LPFC_CHECK_PROTECT_REF))
bf_set(lpfc_sli4_sge_dif_re, diseed, checking); bf_set(lpfc_sli4_sge_dif_re, diseed, checking);
else else
bf_set(lpfc_sli4_sge_dif_re, diseed, 0); bf_set(lpfc_sli4_sge_dif_re, diseed, 0);
...@@ -2610,7 +2624,7 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, ...@@ -2610,7 +2624,7 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
diseed->ref_tag = cpu_to_le32(reftag); diseed->ref_tag = cpu_to_le32(reftag);
diseed->ref_tag_tran = diseed->ref_tag; diseed->ref_tag_tran = diseed->ref_tag;
if (scsi_prot_flagged(sc, SCSI_PROT_GUARD_CHECK)) { if (lpfc_cmd_protect(sc, LPFC_CHECK_PROTECT_GUARD)) {
bf_set(lpfc_sli4_sge_dif_ce, diseed, checking); bf_set(lpfc_sli4_sge_dif_ce, diseed, checking);
} else { } else {
...@@ -2629,7 +2643,7 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, ...@@ -2629,7 +2643,7 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
} }
if (scsi_prot_flagged(sc, SCSI_PROT_REF_CHECK)) if (lpfc_cmd_protect(sc, LPFC_CHECK_PROTECT_REF))
bf_set(lpfc_sli4_sge_dif_re, diseed, checking); bf_set(lpfc_sli4_sge_dif_re, diseed, checking);
else else
bf_set(lpfc_sli4_sge_dif_re, diseed, 0); bf_set(lpfc_sli4_sge_dif_re, diseed, 0);
...@@ -2792,11 +2806,12 @@ lpfc_prot_group_type(struct lpfc_hba *phba, struct scsi_cmnd *sc) ...@@ -2792,11 +2806,12 @@ lpfc_prot_group_type(struct lpfc_hba *phba, struct scsi_cmnd *sc)
ret = LPFC_PG_TYPE_DIF_BUF; ret = LPFC_PG_TYPE_DIF_BUF;
break; break;
default: default:
lpfc_printf_log(phba, KERN_ERR, LOG_FCP, if (phba)
"9021 Unsupported protection op:%d\n", op); lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
"9021 Unsupported protection op:%d\n",
op);
break; break;
} }
return ret; return ret;
} }
...@@ -2821,22 +2836,22 @@ lpfc_bg_scsi_adjust_dl(struct lpfc_hba *phba, ...@@ -2821,22 +2836,22 @@ lpfc_bg_scsi_adjust_dl(struct lpfc_hba *phba,
/* Check if there is protection data on the wire */ /* Check if there is protection data on the wire */
if (sc->sc_data_direction == DMA_FROM_DEVICE) { if (sc->sc_data_direction == DMA_FROM_DEVICE) {
/* Read */ /* Read check for protection data */
if (scsi_get_prot_op(sc) == SCSI_PROT_READ_INSERT) if (scsi_get_prot_op(sc) == SCSI_PROT_READ_INSERT)
return fcpdl; return fcpdl;
} else { } else {
/* Write */ /* Write check for protection data */
if (scsi_get_prot_op(sc) == SCSI_PROT_WRITE_STRIP) if (scsi_get_prot_op(sc) == SCSI_PROT_WRITE_STRIP)
return fcpdl; return fcpdl;
} }
/* /*
* If we are in DIF Type 1 mode every data block has a 8 byte * If we are in DIF Type 1 mode every data block has a 8 byte
* DIF (trailer) attached to it. Must ajust FCP data length. * DIF (trailer) attached to it. Must ajust FCP data length
* to account for the protection data.
*/ */
if (scsi_prot_flagged(sc, SCSI_PROT_TRANSFER_PI)) fcpdl += (fcpdl / lpfc_cmd_blksize(sc)) * 8;
fcpdl += (fcpdl / lpfc_cmd_blksize(sc)) * 8;
return fcpdl; return fcpdl;
} }
...@@ -3090,25 +3105,10 @@ lpfc_calc_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) ...@@ -3090,25 +3105,10 @@ lpfc_calc_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
goto skipit; goto skipit;
} }
/* App Tag checking */ /* First Guard Tag checking */
app_tag = src->app_tag;
if (chk_app && (app_tag != start_app_tag)) {
err_type = BGS_APPTAG_ERR_MASK;
goto out;
}
/* Reference Tag checking */
ref_tag = be32_to_cpu(src->ref_tag);
if (chk_ref && (ref_tag != start_ref_tag)) {
err_type = BGS_REFTAG_ERR_MASK;
goto out;
}
start_ref_tag++;
/* Guard Tag checking */
if (chk_guard) { if (chk_guard) {
guard_tag = src->guard_tag; guard_tag = src->guard_tag;
if (guard_type == SHOST_DIX_GUARD_IP) if (lpfc_cmd_guard_csum(cmd))
sum = lpfc_bg_csum(data_src, sum = lpfc_bg_csum(data_src,
blksize); blksize);
else else
...@@ -3119,6 +3119,21 @@ lpfc_calc_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) ...@@ -3119,6 +3119,21 @@ lpfc_calc_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
goto out; goto out;
} }
} }
/* Reference Tag checking */
ref_tag = be32_to_cpu(src->ref_tag);
if (chk_ref && (ref_tag != start_ref_tag)) {
err_type = BGS_REFTAG_ERR_MASK;
goto out;
}
start_ref_tag++;
/* App Tag checking */
app_tag = src->app_tag;
if (chk_app && (app_tag != start_app_tag)) {
err_type = BGS_APPTAG_ERR_MASK;
goto out;
}
skipit: skipit:
len -= sizeof(struct scsi_dif_tuple); len -= sizeof(struct scsi_dif_tuple);
if (len < 0) if (len < 0)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册