diff options
author | Arun Easi <arun.easi@qlogic.com> | 2011-08-16 14:29:23 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-08-27 10:13:52 -0400 |
commit | e02587d777bfb398f70709fd3a92fa0154959003 (patch) | |
tree | 41f590c4cce0d636c70ab265ea7313abed833f6c /drivers/scsi/qla2xxx/qla_iocb.c | |
parent | 8cb2049c744809193ed3707a37c09676a24599ee (diff) |
[SCSI] qla2xxx: T10 DIF - Fix incorrect error reporting.
This fix:
- Disables app tag peeking; correct tag check will be added when the
SCSI API is available.
- Always derive ref_tag from scsi_get_lba()
- Removes incorrect swap of FCP_LUN in FCP_CMND
- Moves app-tag error check before ref-tag check. The reason being,
currently there is no interface in SCSI to retrieve the app-tag
for protection I/Os, so driver puts zero for app-tag in the
firmware interface, but requests not to validate it, but when a
ref-tag error is detected by firmware, it would put
expected/actual tags for all the protection tags (guard/app/ref).
As driver checks for app tag error first, a ref-tag error is
incorrectly flagged as app-tag error.
- Convert HBA specific checks to capability based.
Signed-off-by: Arun Easi <arun.easi@qlogic.com>
Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_iocb.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_iocb.c | 55 |
1 files changed, 21 insertions, 34 deletions
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 09ad3ce60064..dbec89622a0f 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -709,12 +709,11 @@ struct fw_dif_context { | |||
709 | * | 709 | * |
710 | */ | 710 | */ |
711 | static inline void | 711 | static inline void |
712 | qla24xx_set_t10dif_tags(struct scsi_cmnd *cmd, struct fw_dif_context *pkt, | 712 | qla24xx_set_t10dif_tags(srb_t *sp, struct fw_dif_context *pkt, |
713 | unsigned int protcnt) | 713 | unsigned int protcnt) |
714 | { | 714 | { |
715 | struct sd_dif_tuple *spt; | 715 | struct scsi_cmnd *cmd = sp->cmd; |
716 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); | 716 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); |
717 | unsigned char op = scsi_get_prot_op(cmd); | ||
718 | 717 | ||
719 | switch (scsi_get_prot_type(cmd)) { | 718 | switch (scsi_get_prot_type(cmd)) { |
720 | case SCSI_PROT_DIF_TYPE0: | 719 | case SCSI_PROT_DIF_TYPE0: |
@@ -724,6 +723,10 @@ qla24xx_set_t10dif_tags(struct scsi_cmnd *cmd, struct fw_dif_context *pkt, | |||
724 | */ | 723 | */ |
725 | pkt->ref_tag = cpu_to_le32((uint32_t) | 724 | pkt->ref_tag = cpu_to_le32((uint32_t) |
726 | (0xffffffff & scsi_get_lba(cmd))); | 725 | (0xffffffff & scsi_get_lba(cmd))); |
726 | |||
727 | if (!qla2x00_hba_err_chk_enabled(sp)) | ||
728 | break; | ||
729 | |||
727 | pkt->ref_tag_mask[0] = 0xff; | 730 | pkt->ref_tag_mask[0] = 0xff; |
728 | pkt->ref_tag_mask[1] = 0xff; | 731 | pkt->ref_tag_mask[1] = 0xff; |
729 | pkt->ref_tag_mask[2] = 0xff; | 732 | pkt->ref_tag_mask[2] = 0xff; |
@@ -735,20 +738,16 @@ qla24xx_set_t10dif_tags(struct scsi_cmnd *cmd, struct fw_dif_context *pkt, | |||
735 | * match LBA in CDB + N | 738 | * match LBA in CDB + N |
736 | */ | 739 | */ |
737 | case SCSI_PROT_DIF_TYPE2: | 740 | case SCSI_PROT_DIF_TYPE2: |
738 | if (!qla2x00_hba_err_chk_enabled(op)) | 741 | pkt->app_tag = __constant_cpu_to_le16(0); |
739 | break; | 742 | pkt->app_tag_mask[0] = 0x0; |
740 | 743 | pkt->app_tag_mask[1] = 0x0; | |
741 | if (scsi_prot_sg_count(cmd)) { | ||
742 | spt = page_address(sg_page(scsi_prot_sglist(cmd))) + | ||
743 | scsi_prot_sglist(cmd)[0].offset; | ||
744 | pkt->app_tag = swab32(spt->app_tag); | ||
745 | pkt->app_tag_mask[0] = 0xff; | ||
746 | pkt->app_tag_mask[1] = 0xff; | ||
747 | } | ||
748 | 744 | ||
749 | pkt->ref_tag = cpu_to_le32((uint32_t) | 745 | pkt->ref_tag = cpu_to_le32((uint32_t) |
750 | (0xffffffff & scsi_get_lba(cmd))); | 746 | (0xffffffff & scsi_get_lba(cmd))); |
751 | 747 | ||
748 | if (!qla2x00_hba_err_chk_enabled(sp)) | ||
749 | break; | ||
750 | |||
752 | /* enable ALL bytes of the ref tag */ | 751 | /* enable ALL bytes of the ref tag */ |
753 | pkt->ref_tag_mask[0] = 0xff; | 752 | pkt->ref_tag_mask[0] = 0xff; |
754 | pkt->ref_tag_mask[1] = 0xff; | 753 | pkt->ref_tag_mask[1] = 0xff; |
@@ -768,26 +767,15 @@ qla24xx_set_t10dif_tags(struct scsi_cmnd *cmd, struct fw_dif_context *pkt, | |||
768 | * 16 bit app tag. | 767 | * 16 bit app tag. |
769 | */ | 768 | */ |
770 | case SCSI_PROT_DIF_TYPE1: | 769 | case SCSI_PROT_DIF_TYPE1: |
771 | if (!qla2x00_hba_err_chk_enabled(op)) | 770 | pkt->ref_tag = cpu_to_le32((uint32_t) |
771 | (0xffffffff & scsi_get_lba(cmd))); | ||
772 | pkt->app_tag = __constant_cpu_to_le16(0); | ||
773 | pkt->app_tag_mask[0] = 0x0; | ||
774 | pkt->app_tag_mask[1] = 0x0; | ||
775 | |||
776 | if (!qla2x00_hba_err_chk_enabled(sp)) | ||
772 | break; | 777 | break; |
773 | 778 | ||
774 | if (protcnt && (op == SCSI_PROT_WRITE_STRIP || | ||
775 | op == SCSI_PROT_WRITE_PASS)) { | ||
776 | spt = page_address(sg_page(scsi_prot_sglist(cmd))) + | ||
777 | scsi_prot_sglist(cmd)[0].offset; | ||
778 | ql_dbg(ql_dbg_io, vha, 0x3008, | ||
779 | "LBA from user %p, lba = 0x%x for cmd=%p.\n", | ||
780 | spt, (int)spt->ref_tag, cmd); | ||
781 | pkt->ref_tag = swab32(spt->ref_tag); | ||
782 | pkt->app_tag_mask[0] = 0x0; | ||
783 | pkt->app_tag_mask[1] = 0x0; | ||
784 | } else { | ||
785 | pkt->ref_tag = cpu_to_le32((uint32_t) | ||
786 | (0xffffffff & scsi_get_lba(cmd))); | ||
787 | pkt->app_tag = __constant_cpu_to_le16(0); | ||
788 | pkt->app_tag_mask[0] = 0x0; | ||
789 | pkt->app_tag_mask[1] = 0x0; | ||
790 | } | ||
791 | /* enable ALL bytes of the ref tag */ | 779 | /* enable ALL bytes of the ref tag */ |
792 | pkt->ref_tag_mask[0] = 0xff; | 780 | pkt->ref_tag_mask[0] = 0xff; |
793 | pkt->ref_tag_mask[1] = 0xff; | 781 | pkt->ref_tag_mask[1] = 0xff; |
@@ -1208,7 +1196,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | |||
1208 | 1196 | ||
1209 | INIT_LIST_HEAD(&crc_ctx_pkt->dsd_list); | 1197 | INIT_LIST_HEAD(&crc_ctx_pkt->dsd_list); |
1210 | 1198 | ||
1211 | qla24xx_set_t10dif_tags(cmd, (struct fw_dif_context *) | 1199 | qla24xx_set_t10dif_tags(sp, (struct fw_dif_context *) |
1212 | &crc_ctx_pkt->ref_tag, tot_prot_dsds); | 1200 | &crc_ctx_pkt->ref_tag, tot_prot_dsds); |
1213 | 1201 | ||
1214 | cmd_pkt->crc_context_address[0] = cpu_to_le32(LSD(crc_ctx_dma)); | 1202 | cmd_pkt->crc_context_address[0] = cpu_to_le32(LSD(crc_ctx_dma)); |
@@ -1237,7 +1225,6 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | |||
1237 | fcp_cmnd->additional_cdb_len |= 2; | 1225 | fcp_cmnd->additional_cdb_len |= 2; |
1238 | 1226 | ||
1239 | int_to_scsilun(sp->cmd->device->lun, &fcp_cmnd->lun); | 1227 | int_to_scsilun(sp->cmd->device->lun, &fcp_cmnd->lun); |
1240 | host_to_fcp_swap((uint8_t *)&fcp_cmnd->lun, sizeof(fcp_cmnd->lun)); | ||
1241 | memcpy(fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len); | 1228 | memcpy(fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len); |
1242 | cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(fcp_cmnd_len); | 1229 | cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(fcp_cmnd_len); |
1243 | cmd_pkt->fcp_cmnd_dseg_address[0] = cpu_to_le32( | 1230 | cmd_pkt->fcp_cmnd_dseg_address[0] = cpu_to_le32( |
@@ -1289,7 +1276,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | |||
1289 | BUG(); | 1276 | BUG(); |
1290 | } | 1277 | } |
1291 | 1278 | ||
1292 | if (!qla2x00_hba_err_chk_enabled(scsi_get_prot_op(cmd))) | 1279 | if (!qla2x00_hba_err_chk_enabled(sp)) |
1293 | fw_prot_opts |= 0x10; /* Disable Guard tag checking */ | 1280 | fw_prot_opts |= 0x10; /* Disable Guard tag checking */ |
1294 | 1281 | ||
1295 | if (!bundling) { | 1282 | if (!bundling) { |