aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_iocb.c
diff options
context:
space:
mode:
authorArun Easi <arun.easi@qlogic.com>2011-08-16 14:29:23 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-08-27 10:13:52 -0400
commite02587d777bfb398f70709fd3a92fa0154959003 (patch)
tree41f590c4cce0d636c70ab265ea7313abed833f6c /drivers/scsi/qla2xxx/qla_iocb.c
parent8cb2049c744809193ed3707a37c09676a24599ee (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.c55
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 */
711static inline void 711static inline void
712qla24xx_set_t10dif_tags(struct scsi_cmnd *cmd, struct fw_dif_context *pkt, 712qla24xx_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) {