aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2011-10-10 21:34:11 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-10-16 12:32:53 -0400
commitf9bb2da11db805fca899a18d7d1bb97860fc2cd5 (patch)
treef43a24da27b0600fb2e98c035cadf5c930bf2a79 /drivers/scsi
parent5350d872c19a59ef8eadab1e70db83064c134cfa (diff)
[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: Alex Iannicelli <alex.iannicelli@emulex.com> Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/lpfc/lpfc.h20
-rw-r--r--drivers/scsi/lpfc/lpfc_debugfs.c181
-rw-r--r--drivers/scsi/lpfc/lpfc_hw4.h88
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c199
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c2
5 files changed, 471 insertions, 19 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index c088a36d1f3..bb4c8e0584e 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -846,8 +846,24 @@ struct lpfc_hba {
846 struct dentry *debug_hbqinfo; 846 struct dentry *debug_hbqinfo;
847 struct dentry *debug_dumpHostSlim; 847 struct dentry *debug_dumpHostSlim;
848 struct dentry *debug_dumpHBASlim; 848 struct dentry *debug_dumpHBASlim;
849 struct dentry *debug_dumpData; /* BlockGuard BPL*/ 849 struct dentry *debug_dumpData; /* BlockGuard BPL */
850 struct dentry *debug_dumpDif; /* BlockGuard BPL*/ 850 struct dentry *debug_dumpDif; /* BlockGuard BPL */
851 struct dentry *debug_InjErrLBA; /* LBA to inject errors at */
852 struct dentry *debug_writeGuard; /* inject write guard_tag errors */
853 struct dentry *debug_writeApp; /* inject write app_tag errors */
854 struct dentry *debug_writeRef; /* inject write ref_tag errors */
855 struct dentry *debug_readApp; /* inject read app_tag errors */
856 struct dentry *debug_readRef; /* inject read ref_tag errors */
857
858 /* T10 DIF error injection */
859 uint32_t lpfc_injerr_wgrd_cnt;
860 uint32_t lpfc_injerr_wapp_cnt;
861 uint32_t lpfc_injerr_wref_cnt;
862 uint32_t lpfc_injerr_rapp_cnt;
863 uint32_t lpfc_injerr_rref_cnt;
864 sector_t lpfc_injerr_lba;
865#define LPFC_INJERR_LBA_OFF (sector_t)0xffffffffffffffff
866
851 struct dentry *debug_slow_ring_trc; 867 struct dentry *debug_slow_ring_trc;
852 struct lpfc_debugfs_trc *slow_ring_trc; 868 struct lpfc_debugfs_trc *slow_ring_trc;
853 atomic_t slow_ring_trc_cnt; 869 atomic_t slow_ring_trc_cnt;
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index a0424dd90e4..2cd844f7058 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -996,6 +996,85 @@ lpfc_debugfs_dumpDataDif_write(struct file *file, const char __user *buf,
996 return nbytes; 996 return nbytes;
997} 997}
998 998
999static int
1000lpfc_debugfs_dif_err_open(struct inode *inode, struct file *file)
1001{
1002 file->private_data = inode->i_private;
1003 return 0;
1004}
1005
1006static ssize_t
1007lpfc_debugfs_dif_err_read(struct file *file, char __user *buf,
1008 size_t nbytes, loff_t *ppos)
1009{
1010 struct dentry *dent = file->f_dentry;
1011 struct lpfc_hba *phba = file->private_data;
1012 char cbuf[16];
1013 int cnt = 0;
1014
1015 if (dent == phba->debug_writeGuard)
1016 cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_wgrd_cnt);
1017 else if (dent == phba->debug_writeApp)
1018 cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_wapp_cnt);
1019 else if (dent == phba->debug_writeRef)
1020 cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_wref_cnt);
1021 else if (dent == phba->debug_readApp)
1022 cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_rapp_cnt);
1023 else if (dent == phba->debug_readRef)
1024 cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_rref_cnt);
1025 else if (dent == phba->debug_InjErrLBA)
1026 cnt = snprintf(cbuf, 16, "0x%lx\n",
1027 (unsigned long) phba->lpfc_injerr_lba);
1028 else
1029 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
1030 "0547 Unknown debugfs error injection entry\n");
1031
1032 return simple_read_from_buffer(buf, nbytes, ppos, &cbuf, cnt);
1033}
1034
1035static ssize_t
1036lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf,
1037 size_t nbytes, loff_t *ppos)
1038{
1039 struct dentry *dent = file->f_dentry;
1040 struct lpfc_hba *phba = file->private_data;
1041 char dstbuf[32];
1042 unsigned long tmp;
1043 int size;
1044
1045 memset(dstbuf, 0, 32);
1046 size = (nbytes < 32) ? nbytes : 32;
1047 if (copy_from_user(dstbuf, buf, size))
1048 return 0;
1049
1050 if (strict_strtoul(dstbuf, 0, &tmp))
1051 return 0;
1052
1053 if (dent == phba->debug_writeGuard)
1054 phba->lpfc_injerr_wgrd_cnt = (uint32_t)tmp;
1055 else if (dent == phba->debug_writeApp)
1056 phba->lpfc_injerr_wapp_cnt = (uint32_t)tmp;
1057 else if (dent == phba->debug_writeRef)
1058 phba->lpfc_injerr_wref_cnt = (uint32_t)tmp;
1059 else if (dent == phba->debug_readApp)
1060 phba->lpfc_injerr_rapp_cnt = (uint32_t)tmp;
1061 else if (dent == phba->debug_readRef)
1062 phba->lpfc_injerr_rref_cnt = (uint32_t)tmp;
1063 else if (dent == phba->debug_InjErrLBA)
1064 phba->lpfc_injerr_lba = (sector_t)tmp;
1065 else
1066 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
1067 "0548 Unknown debugfs error injection entry\n");
1068
1069 return nbytes;
1070}
1071
1072static int
1073lpfc_debugfs_dif_err_release(struct inode *inode, struct file *file)
1074{
1075 return 0;
1076}
1077
999/** 1078/**
1000 * lpfc_debugfs_nodelist_open - Open the nodelist debugfs file 1079 * lpfc_debugfs_nodelist_open - Open the nodelist debugfs file
1001 * @inode: The inode pointer that contains a vport pointer. 1080 * @inode: The inode pointer that contains a vport pointer.
@@ -3380,6 +3459,16 @@ static const struct file_operations lpfc_debugfs_op_dumpDif = {
3380 .release = lpfc_debugfs_dumpDataDif_release, 3459 .release = lpfc_debugfs_dumpDataDif_release,
3381}; 3460};
3382 3461
3462#undef lpfc_debugfs_op_dif_err
3463static const struct file_operations lpfc_debugfs_op_dif_err = {
3464 .owner = THIS_MODULE,
3465 .open = lpfc_debugfs_dif_err_open,
3466 .llseek = lpfc_debugfs_lseek,
3467 .read = lpfc_debugfs_dif_err_read,
3468 .write = lpfc_debugfs_dif_err_write,
3469 .release = lpfc_debugfs_dif_err_release,
3470};
3471
3383#undef lpfc_debugfs_op_slow_ring_trc 3472#undef lpfc_debugfs_op_slow_ring_trc
3384static const struct file_operations lpfc_debugfs_op_slow_ring_trc = { 3473static const struct file_operations lpfc_debugfs_op_slow_ring_trc = {
3385 .owner = THIS_MODULE, 3474 .owner = THIS_MODULE,
@@ -3788,6 +3877,74 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
3788 goto debug_failed; 3877 goto debug_failed;
3789 } 3878 }
3790 3879
3880 /* Setup DIF Error Injections */
3881 snprintf(name, sizeof(name), "InjErrLBA");
3882 phba->debug_InjErrLBA =
3883 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
3884 phba->hba_debugfs_root,
3885 phba, &lpfc_debugfs_op_dif_err);
3886 if (!phba->debug_InjErrLBA) {
3887 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
3888 "0807 Cannot create debugfs InjErrLBA\n");
3889 goto debug_failed;
3890 }
3891 phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
3892
3893 snprintf(name, sizeof(name), "writeGuardInjErr");
3894 phba->debug_writeGuard =
3895 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
3896 phba->hba_debugfs_root,
3897 phba, &lpfc_debugfs_op_dif_err);
3898 if (!phba->debug_writeGuard) {
3899 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
3900 "0802 Cannot create debugfs writeGuard\n");
3901 goto debug_failed;
3902 }
3903
3904 snprintf(name, sizeof(name), "writeAppInjErr");
3905 phba->debug_writeApp =
3906 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
3907 phba->hba_debugfs_root,
3908 phba, &lpfc_debugfs_op_dif_err);
3909 if (!phba->debug_writeApp) {
3910 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
3911 "0803 Cannot create debugfs writeApp\n");
3912 goto debug_failed;
3913 }
3914
3915 snprintf(name, sizeof(name), "writeRefInjErr");
3916 phba->debug_writeRef =
3917 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
3918 phba->hba_debugfs_root,
3919 phba, &lpfc_debugfs_op_dif_err);
3920 if (!phba->debug_writeRef) {
3921 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
3922 "0804 Cannot create debugfs writeRef\n");
3923 goto debug_failed;
3924 }
3925
3926 snprintf(name, sizeof(name), "readAppInjErr");
3927 phba->debug_readApp =
3928 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
3929 phba->hba_debugfs_root,
3930 phba, &lpfc_debugfs_op_dif_err);
3931 if (!phba->debug_readApp) {
3932 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
3933 "0805 Cannot create debugfs readApp\n");
3934 goto debug_failed;
3935 }
3936
3937 snprintf(name, sizeof(name), "readRefInjErr");
3938 phba->debug_readRef =
3939 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
3940 phba->hba_debugfs_root,
3941 phba, &lpfc_debugfs_op_dif_err);
3942 if (!phba->debug_readRef) {
3943 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
3944 "0806 Cannot create debugfs readApp\n");
3945 goto debug_failed;
3946 }
3947
3791 /* Setup slow ring trace */ 3948 /* Setup slow ring trace */
3792 if (lpfc_debugfs_max_slow_ring_trc) { 3949 if (lpfc_debugfs_max_slow_ring_trc) {
3793 num = lpfc_debugfs_max_slow_ring_trc - 1; 3950 num = lpfc_debugfs_max_slow_ring_trc - 1;
@@ -4090,6 +4247,30 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport)
4090 debugfs_remove(phba->debug_dumpDif); /* dumpDif */ 4247 debugfs_remove(phba->debug_dumpDif); /* dumpDif */
4091 phba->debug_dumpDif = NULL; 4248 phba->debug_dumpDif = NULL;
4092 } 4249 }
4250 if (phba->debug_InjErrLBA) {
4251 debugfs_remove(phba->debug_InjErrLBA); /* InjErrLBA */
4252 phba->debug_InjErrLBA = NULL;
4253 }
4254 if (phba->debug_writeGuard) {
4255 debugfs_remove(phba->debug_writeGuard); /* writeGuard */
4256 phba->debug_writeGuard = NULL;
4257 }
4258 if (phba->debug_writeApp) {
4259 debugfs_remove(phba->debug_writeApp); /* writeApp */
4260 phba->debug_writeApp = NULL;
4261 }
4262 if (phba->debug_writeRef) {
4263 debugfs_remove(phba->debug_writeRef); /* writeRef */
4264 phba->debug_writeRef = NULL;
4265 }
4266 if (phba->debug_readApp) {
4267 debugfs_remove(phba->debug_readApp); /* readApp */
4268 phba->debug_readApp = NULL;
4269 }
4270 if (phba->debug_readRef) {
4271 debugfs_remove(phba->debug_readRef); /* readRef */
4272 phba->debug_readRef = NULL;
4273 }
4093 4274
4094 if (phba->slow_ring_trc) { 4275 if (phba->slow_ring_trc) {
4095 kfree(phba->slow_ring_trc); 4276 kfree(phba->slow_ring_trc);
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 1a417135b73..98d21521f53 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -1484,16 +1484,81 @@ struct sli4_sge { /* SLI-4 */
1484 uint32_t addr_lo; 1484 uint32_t addr_lo;
1485 1485
1486 uint32_t word2; 1486 uint32_t word2;
1487#define lpfc_sli4_sge_offset_SHIFT 0 /* Offset of buffer - Not used*/ 1487#define lpfc_sli4_sge_offset_SHIFT 0
1488#define lpfc_sli4_sge_offset_MASK 0x1FFFFFFF 1488#define lpfc_sli4_sge_offset_MASK 0x07FFFFFF
1489#define lpfc_sli4_sge_offset_WORD word2 1489#define lpfc_sli4_sge_offset_WORD word2
1490#define lpfc_sli4_sge_last_SHIFT 31 /* Last SEG in the SGL sets 1490#define lpfc_sli4_sge_type_SHIFT 27
1491 this flag !! */ 1491#define lpfc_sli4_sge_type_MASK 0x0000000F
1492#define lpfc_sli4_sge_type_WORD word2
1493#define LPFC_SGE_TYPE_DATA 0x0
1494#define LPFC_SGE_TYPE_DIF 0x4
1495#define LPFC_SGE_TYPE_LSP 0x5
1496#define LPFC_SGE_TYPE_PEDIF 0x6
1497#define LPFC_SGE_TYPE_PESEED 0x7
1498#define LPFC_SGE_TYPE_DISEED 0x8
1499#define LPFC_SGE_TYPE_ENC 0x9
1500#define LPFC_SGE_TYPE_ATM 0xA
1501#define LPFC_SGE_TYPE_SKIP 0xC
1502#define lpfc_sli4_sge_last_SHIFT 31 /* Last SEG in the SGL sets it */
1492#define lpfc_sli4_sge_last_MASK 0x00000001 1503#define lpfc_sli4_sge_last_MASK 0x00000001
1493#define lpfc_sli4_sge_last_WORD word2 1504#define lpfc_sli4_sge_last_WORD word2
1494 uint32_t sge_len; 1505 uint32_t sge_len;
1495}; 1506};
1496 1507
1508struct sli4_sge_diseed { /* SLI-4 */
1509 uint32_t ref_tag;
1510 uint32_t ref_tag_tran;
1511
1512 uint32_t word2;
1513#define lpfc_sli4_sge_dif_apptran_SHIFT 0
1514#define lpfc_sli4_sge_dif_apptran_MASK 0x0000FFFF
1515#define lpfc_sli4_sge_dif_apptran_WORD word2
1516#define lpfc_sli4_sge_dif_af_SHIFT 24
1517#define lpfc_sli4_sge_dif_af_MASK 0x00000001
1518#define lpfc_sli4_sge_dif_af_WORD word2
1519#define lpfc_sli4_sge_dif_na_SHIFT 25
1520#define lpfc_sli4_sge_dif_na_MASK 0x00000001
1521#define lpfc_sli4_sge_dif_na_WORD word2
1522#define lpfc_sli4_sge_dif_hi_SHIFT 26
1523#define lpfc_sli4_sge_dif_hi_MASK 0x00000001
1524#define lpfc_sli4_sge_dif_hi_WORD word2
1525#define lpfc_sli4_sge_dif_type_SHIFT 27
1526#define lpfc_sli4_sge_dif_type_MASK 0x0000000F
1527#define lpfc_sli4_sge_dif_type_WORD word2
1528#define lpfc_sli4_sge_dif_last_SHIFT 31 /* Last SEG in the SGL sets it */
1529#define lpfc_sli4_sge_dif_last_MASK 0x00000001
1530#define lpfc_sli4_sge_dif_last_WORD word2
1531 uint32_t word3;
1532#define lpfc_sli4_sge_dif_apptag_SHIFT 0
1533#define lpfc_sli4_sge_dif_apptag_MASK 0x0000FFFF
1534#define lpfc_sli4_sge_dif_apptag_WORD word3
1535#define lpfc_sli4_sge_dif_bs_SHIFT 16
1536#define lpfc_sli4_sge_dif_bs_MASK 0x00000007
1537#define lpfc_sli4_sge_dif_bs_WORD word3
1538#define lpfc_sli4_sge_dif_ai_SHIFT 19
1539#define lpfc_sli4_sge_dif_ai_MASK 0x00000001
1540#define lpfc_sli4_sge_dif_ai_WORD word3
1541#define lpfc_sli4_sge_dif_me_SHIFT 20
1542#define lpfc_sli4_sge_dif_me_MASK 0x00000001
1543#define lpfc_sli4_sge_dif_me_WORD word3
1544#define lpfc_sli4_sge_dif_re_SHIFT 21
1545#define lpfc_sli4_sge_dif_re_MASK 0x00000001
1546#define lpfc_sli4_sge_dif_re_WORD word3
1547#define lpfc_sli4_sge_dif_ce_SHIFT 22
1548#define lpfc_sli4_sge_dif_ce_MASK 0x00000001
1549#define lpfc_sli4_sge_dif_ce_WORD word3
1550#define lpfc_sli4_sge_dif_nr_SHIFT 23
1551#define lpfc_sli4_sge_dif_nr_MASK 0x00000001
1552#define lpfc_sli4_sge_dif_nr_WORD word3
1553#define lpfc_sli4_sge_dif_oprx_SHIFT 24
1554#define lpfc_sli4_sge_dif_oprx_MASK 0x0000000F
1555#define lpfc_sli4_sge_dif_oprx_WORD word3
1556#define lpfc_sli4_sge_dif_optx_SHIFT 28
1557#define lpfc_sli4_sge_dif_optx_MASK 0x0000000F
1558#define lpfc_sli4_sge_dif_optx_WORD word3
1559/* optx and oprx use BG_OP_IN defines in lpfc_hw.h */
1560};
1561
1497struct fcf_record { 1562struct fcf_record {
1498 uint32_t max_rcv_size; 1563 uint32_t max_rcv_size;
1499 uint32_t fka_adv_period; 1564 uint32_t fka_adv_period;
@@ -3023,6 +3088,9 @@ struct wqe_common {
3023#define wqe_ctxt_tag_MASK 0x0000FFFF 3088#define wqe_ctxt_tag_MASK 0x0000FFFF
3024#define wqe_ctxt_tag_WORD word6 3089#define wqe_ctxt_tag_WORD word6
3025 uint32_t word7; 3090 uint32_t word7;
3091#define wqe_dif_SHIFT 0
3092#define wqe_dif_MASK 0x00000003
3093#define wqe_dif_WORD word7
3026#define wqe_ct_SHIFT 2 3094#define wqe_ct_SHIFT 2
3027#define wqe_ct_MASK 0x00000003 3095#define wqe_ct_MASK 0x00000003
3028#define wqe_ct_WORD word7 3096#define wqe_ct_WORD word7
@@ -3035,12 +3103,21 @@ struct wqe_common {
3035#define wqe_class_SHIFT 16 3103#define wqe_class_SHIFT 16
3036#define wqe_class_MASK 0x00000007 3104#define wqe_class_MASK 0x00000007
3037#define wqe_class_WORD word7 3105#define wqe_class_WORD word7
3106#define wqe_ar_SHIFT 19
3107#define wqe_ar_MASK 0x00000001
3108#define wqe_ar_WORD word7
3109#define wqe_ag_SHIFT wqe_ar_SHIFT
3110#define wqe_ag_MASK wqe_ar_MASK
3111#define wqe_ag_WORD wqe_ar_WORD
3038#define wqe_pu_SHIFT 20 3112#define wqe_pu_SHIFT 20
3039#define wqe_pu_MASK 0x00000003 3113#define wqe_pu_MASK 0x00000003
3040#define wqe_pu_WORD word7 3114#define wqe_pu_WORD word7
3041#define wqe_erp_SHIFT 22 3115#define wqe_erp_SHIFT 22
3042#define wqe_erp_MASK 0x00000001 3116#define wqe_erp_MASK 0x00000001
3043#define wqe_erp_WORD word7 3117#define wqe_erp_WORD word7
3118#define wqe_conf_SHIFT wqe_erp_SHIFT
3119#define wqe_conf_MASK wqe_erp_MASK
3120#define wqe_conf_WORD wqe_erp_WORD
3044#define wqe_lnk_SHIFT 23 3121#define wqe_lnk_SHIFT 23
3045#define wqe_lnk_MASK 0x00000001 3122#define wqe_lnk_MASK 0x00000001
3046#define wqe_lnk_WORD word7 3123#define wqe_lnk_WORD word7
@@ -3099,6 +3176,9 @@ struct wqe_common {
3099#define wqe_xc_SHIFT 21 3176#define wqe_xc_SHIFT 21
3100#define wqe_xc_MASK 0x00000001 3177#define wqe_xc_MASK 0x00000001
3101#define wqe_xc_WORD word10 3178#define wqe_xc_WORD word10
3179#define wqe_sr_SHIFT 22
3180#define wqe_sr_MASK 0x00000001
3181#define wqe_sr_WORD word10
3102#define wqe_ccpe_SHIFT 23 3182#define wqe_ccpe_SHIFT 23
3103#define wqe_ccpe_MASK 0x00000001 3183#define wqe_ccpe_MASK 0x00000001
3104#define wqe_ccpe_WORD word10 3184#define wqe_ccpe_WORD word10
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 2a3c9c92427..5b8790b3cf4 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -58,6 +58,13 @@ static char *dif_op_str[] = {
58 "SCSI_PROT_READ_PASS", 58 "SCSI_PROT_READ_PASS",
59 "SCSI_PROT_WRITE_PASS", 59 "SCSI_PROT_WRITE_PASS",
60}; 60};
61
62struct scsi_dif_tuple {
63 __be16 guard_tag; /* Checksum */
64 __be16 app_tag; /* Opaque storage */
65 __be32 ref_tag; /* Target LBA or indirect LBA */
66};
67
61static void 68static void
62lpfc_release_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb); 69lpfc_release_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb);
63static void 70static void
@@ -1263,6 +1270,174 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
1263 return 0; 1270 return 0;
1264} 1271}
1265 1272
1273static inline unsigned
1274lpfc_cmd_blksize(struct scsi_cmnd *sc)
1275{
1276 return sc->device->sector_size;
1277}
1278
1279#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1280/*
1281 * Given a scsi cmnd, determine the BlockGuard tags to be used with it
1282 * @sc: The SCSI command to examine
1283 * @reftag: (out) BlockGuard reference tag for transmitted data
1284 * @apptag: (out) BlockGuard application tag for transmitted data
1285 * @new_guard (in) Value to replace CRC with if needed
1286 *
1287 * Returns (1) if error injection was performed, (0) otherwise
1288 */
1289static int
1290lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc,
1291 uint32_t *reftag, uint16_t *apptag, uint32_t new_guard)
1292{
1293 struct scatterlist *sgpe; /* s/g prot entry */
1294 struct scatterlist *sgde; /* s/g data entry */
1295 struct scsi_dif_tuple *src;
1296 uint32_t op = scsi_get_prot_op(sc);
1297 uint32_t blksize;
1298 uint32_t numblks;
1299 sector_t lba;
1300 int rc = 0;
1301
1302 if (op == SCSI_PROT_NORMAL)
1303 return 0;
1304
1305 lba = scsi_get_lba(sc);
1306 if (phba->lpfc_injerr_lba != LPFC_INJERR_LBA_OFF) {
1307 blksize = lpfc_cmd_blksize(sc);
1308 numblks = (scsi_bufflen(sc) + blksize - 1) / blksize;
1309
1310 /* Make sure we have the right LBA if one is specified */
1311 if ((phba->lpfc_injerr_lba < lba) ||
1312 (phba->lpfc_injerr_lba >= (lba + numblks)))
1313 return 0;
1314 }
1315
1316 sgpe = scsi_prot_sglist(sc);
1317 sgde = scsi_sglist(sc);
1318
1319 /* Should we change the Reference Tag */
1320 if (reftag) {
1321 /*
1322 * If we are SCSI_PROT_WRITE_STRIP, the protection data is
1323 * being stripped from the wire, thus it doesn't matter.
1324 */
1325 if ((op == SCSI_PROT_WRITE_PASS) ||
1326 (op == SCSI_PROT_WRITE_INSERT)) {
1327 if (phba->lpfc_injerr_wref_cnt) {
1328
1329 /* DEADBEEF will be the reftag on the wire */
1330 *reftag = 0xDEADBEEF;
1331 phba->lpfc_injerr_wref_cnt--;
1332 phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
1333 rc = 1;
1334
1335 lpfc_printf_log(phba, KERN_ERR, LOG_BG,
1336 "9081 BLKGRD: Injecting reftag error: "
1337 "write lba x%lx\n", (unsigned long)lba);
1338 }
1339 } else {
1340 if (phba->lpfc_injerr_rref_cnt) {
1341 *reftag = 0xDEADBEEF;
1342 phba->lpfc_injerr_rref_cnt--;
1343 phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
1344 rc = 1;
1345
1346 lpfc_printf_log(phba, KERN_ERR, LOG_BG,
1347 "9076 BLKGRD: Injecting reftag error: "
1348 "read lba x%lx\n", (unsigned long)lba);
1349 }
1350 }
1351 }
1352
1353 /* Should we change the Application Tag */
1354 if (apptag) {
1355 /*
1356 * If we are SCSI_PROT_WRITE_STRIP, the protection data is
1357 * being stripped from the wire, thus it doesn't matter.
1358 */
1359 if ((op == SCSI_PROT_WRITE_PASS) ||
1360 (op == SCSI_PROT_WRITE_INSERT)) {
1361 if (phba->lpfc_injerr_wapp_cnt) {
1362
1363 /* DEAD will be the apptag on the wire */
1364 *apptag = 0xDEAD;
1365 phba->lpfc_injerr_wapp_cnt--;
1366 phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
1367 rc = 1;
1368
1369 lpfc_printf_log(phba, KERN_ERR, LOG_BG,
1370 "9077 BLKGRD: Injecting apptag error: "
1371 "write lba x%lx\n", (unsigned long)lba);
1372 }
1373 } else {
1374 if (phba->lpfc_injerr_rapp_cnt) {
1375 *apptag = 0xDEAD;
1376 phba->lpfc_injerr_rapp_cnt--;
1377 phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
1378 rc = 1;
1379
1380 lpfc_printf_log(phba, KERN_ERR, LOG_BG,
1381 "9078 BLKGRD: Injecting apptag error: "
1382 "read lba x%lx\n", (unsigned long)lba);
1383 }
1384 }
1385 }
1386
1387 /* Should we change the Guard Tag */
1388
1389 /*
1390 * If we are SCSI_PROT_WRITE_INSERT, the protection data is
1391 * being on the wire is being fully generated on the HBA.
1392 * The host cannot change it or force an error.
1393 */
1394 if (((op == SCSI_PROT_WRITE_STRIP) ||
1395 (op == SCSI_PROT_WRITE_PASS)) &&
1396 phba->lpfc_injerr_wgrd_cnt) {
1397 if (sgpe) {
1398 src = (struct scsi_dif_tuple *)sg_virt(sgpe);
1399 /*
1400 * Just inject an error in the first
1401 * prot block.
1402 */
1403 lpfc_printf_log(phba, KERN_ERR, LOG_BG,
1404 "9079 BLKGRD: Injecting guard error: "
1405 "write lba x%lx oldGuard x%x refTag x%x\n",
1406 (unsigned long)lba, src->guard_tag,
1407 src->ref_tag);
1408
1409 src->guard_tag = (uint16_t)new_guard;
1410 phba->lpfc_injerr_wgrd_cnt--;
1411 phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
1412 rc = 1;
1413
1414 } else {
1415 blksize = lpfc_cmd_blksize(sc);
1416 /*
1417 * Jump past the first data block
1418 * and inject an error in the
1419 * prot data. The prot data is already
1420 * embedded after the regular data.
1421 */
1422 src = (struct scsi_dif_tuple *)
1423 (sg_virt(sgde) + blksize);
1424
1425 lpfc_printf_log(phba, KERN_ERR, LOG_BG,
1426 "9080 BLKGRD: Injecting guard error: "
1427 "write lba x%lx oldGuard x%x refTag x%x\n",
1428 (unsigned long)lba, src->guard_tag,
1429 src->ref_tag);
1430
1431 src->guard_tag = (uint16_t)new_guard;
1432 phba->lpfc_injerr_wgrd_cnt--;
1433 phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
1434 rc = 1;
1435 }
1436 }
1437 return rc;
1438}
1439#endif
1440
1266/* 1441/*
1267 * Given a scsi cmnd, determine the BlockGuard opcodes to be used with it 1442 * Given a scsi cmnd, determine the BlockGuard opcodes to be used with it
1268 * @sc: The SCSI command to examine 1443 * @sc: The SCSI command to examine
@@ -1341,18 +1516,6 @@ lpfc_sc_to_bg_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc,
1341 return ret; 1516 return ret;
1342} 1517}
1343 1518
1344struct scsi_dif_tuple {
1345 __be16 guard_tag; /* Checksum */
1346 __be16 app_tag; /* Opaque storage */
1347 __be32 ref_tag; /* Target LBA or indirect LBA */
1348};
1349
1350static inline unsigned
1351lpfc_cmd_blksize(struct scsi_cmnd *sc)
1352{
1353 return sc->device->sector_size;
1354}
1355
1356/* 1519/*
1357 * This function sets up buffer list for protection groups of 1520 * This function sets up buffer list for protection groups of
1358 * type LPFC_PG_TYPE_NO_DIF 1521 * type LPFC_PG_TYPE_NO_DIF
@@ -1401,6 +1564,11 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
1401 blksize = lpfc_cmd_blksize(sc); 1564 blksize = lpfc_cmd_blksize(sc);
1402 reftag = scsi_get_lba(sc) & 0xffffffff; 1565 reftag = scsi_get_lba(sc) & 0xffffffff;
1403 1566
1567#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1568 /* reftag is the only error we can inject here */
1569 lpfc_bg_err_inject(phba, sc, &reftag, 0, 0);
1570#endif
1571
1404 /* setup PDE5 with what we have */ 1572 /* setup PDE5 with what we have */
1405 pde5 = (struct lpfc_pde5 *) bpl; 1573 pde5 = (struct lpfc_pde5 *) bpl;
1406 memset(pde5, 0, sizeof(struct lpfc_pde5)); 1574 memset(pde5, 0, sizeof(struct lpfc_pde5));
@@ -1532,6 +1700,11 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
1532 blksize = lpfc_cmd_blksize(sc); 1700 blksize = lpfc_cmd_blksize(sc);
1533 reftag = scsi_get_lba(sc) & 0xffffffff; 1701 reftag = scsi_get_lba(sc) & 0xffffffff;
1534 1702
1703#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1704 /* reftag / guard tag are the only errors we can inject here */
1705 lpfc_bg_err_inject(phba, sc, &reftag, 0, 0xDEAD);
1706#endif
1707
1535 split_offset = 0; 1708 split_offset = 0;
1536 do { 1709 do {
1537 /* setup PDE5 with what we have */ 1710 /* setup PDE5 with what we have */
@@ -1671,7 +1844,6 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
1671 } 1844 }
1672 1845
1673 } while (!alldone); 1846 } while (!alldone);
1674
1675out: 1847out:
1676 1848
1677 return num_bde; 1849 return num_bde;
@@ -2075,6 +2247,7 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
2075 else 2247 else
2076 bf_set(lpfc_sli4_sge_last, sgl, 0); 2248 bf_set(lpfc_sli4_sge_last, sgl, 0);
2077 bf_set(lpfc_sli4_sge_offset, sgl, dma_offset); 2249 bf_set(lpfc_sli4_sge_offset, sgl, dma_offset);
2250 bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_DATA);
2078 sgl->word2 = cpu_to_le32(sgl->word2); 2251 sgl->word2 = cpu_to_le32(sgl->word2);
2079 sgl->sge_len = cpu_to_le32(dma_len); 2252 sgl->sge_len = cpu_to_le32(dma_len);
2080 dma_offset += dma_len; 2253 dma_offset += dma_len;
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index c430aada02b..4d4104f38c9 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -7538,6 +7538,8 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
7538 if (inbound == 1) 7538 if (inbound == 1)
7539 offset = 0; 7539 offset = 0;
7540 bf_set(lpfc_sli4_sge_offset, sgl, offset); 7540 bf_set(lpfc_sli4_sge_offset, sgl, offset);
7541 bf_set(lpfc_sli4_sge_type, sgl,
7542 LPFC_SGE_TYPE_DATA);
7541 offset += bde.tus.f.bdeSize; 7543 offset += bde.tus.f.bdeSize;
7542 } 7544 }
7543 sgl->word2 = cpu_to_le32(sgl->word2); 7545 sgl->word2 = cpu_to_le32(sgl->word2);