diff options
author | James Smart <james.smart@emulex.com> | 2011-10-10 21:34:11 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-10-16 12:32:53 -0400 |
commit | f9bb2da11db805fca899a18d7d1bb97860fc2cd5 (patch) | |
tree | f43a24da27b0600fb2e98c035cadf5c930bf2a79 /drivers/scsi | |
parent | 5350d872c19a59ef8eadab1e70db83064c134cfa (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.h | 20 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_debugfs.c | 181 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hw4.h | 88 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 199 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 2 |
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 | ||
999 | static int | ||
1000 | lpfc_debugfs_dif_err_open(struct inode *inode, struct file *file) | ||
1001 | { | ||
1002 | file->private_data = inode->i_private; | ||
1003 | return 0; | ||
1004 | } | ||
1005 | |||
1006 | static ssize_t | ||
1007 | lpfc_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 | |||
1035 | static ssize_t | ||
1036 | lpfc_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 | |||
1072 | static int | ||
1073 | lpfc_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 | ||
3463 | static 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 |
3384 | static const struct file_operations lpfc_debugfs_op_slow_ring_trc = { | 3473 | static 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 | ||
1508 | struct 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 | |||
1497 | struct fcf_record { | 1562 | struct 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 | |||
62 | struct 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 | |||
61 | static void | 68 | static void |
62 | lpfc_release_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb); | 69 | lpfc_release_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb); |
63 | static void | 70 | static 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 | ||
1273 | static inline unsigned | ||
1274 | lpfc_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 | */ | ||
1289 | static int | ||
1290 | lpfc_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 | ||
1344 | struct 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 | |||
1350 | static inline unsigned | ||
1351 | lpfc_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 | |||
1675 | out: | 1847 | out: |
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); |