aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2012-03-01 22:37:42 -0500
committerJames Bottomley <JBottomley@Parallels.com>2012-03-27 03:26:33 -0400
commit9a6b09c071a5f66ed3c359d8631e07b34a9e738f (patch)
treee295ef167f092f2e3d160f54b12c5583ae6c6728
parentcf9712403f384f9e832f489e7f41ab535c8f1a74 (diff)
[SCSI] lpfc 8.3.30: Enhancements for T10 DIF debugfs error injection
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>
-rw-r--r--drivers/scsi/lpfc/lpfc_debugfs.c32
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c309
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.h10
3 files changed, 203 insertions, 148 deletions
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index 22e17be04d8a..c4269ee57e9c 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -1010,25 +1010,28 @@ lpfc_debugfs_dif_err_read(struct file *file, char __user *buf,
1010{ 1010{
1011 struct dentry *dent = file->f_dentry; 1011 struct dentry *dent = file->f_dentry;
1012 struct lpfc_hba *phba = file->private_data; 1012 struct lpfc_hba *phba = file->private_data;
1013 char cbuf[16]; 1013 char cbuf[32];
1014 int cnt = 0; 1014 int cnt = 0;
1015 1015
1016 if (dent == phba->debug_writeGuard) 1016 if (dent == phba->debug_writeGuard)
1017 cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_wgrd_cnt); 1017 cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wgrd_cnt);
1018 else if (dent == phba->debug_writeApp) 1018 else if (dent == phba->debug_writeApp)
1019 cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_wapp_cnt); 1019 cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wapp_cnt);
1020 else if (dent == phba->debug_writeRef) 1020 else if (dent == phba->debug_writeRef)
1021 cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_wref_cnt); 1021 cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wref_cnt);
1022 else if (dent == phba->debug_readGuard) 1022 else if (dent == phba->debug_readGuard)
1023 cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_rgrd_cnt); 1023 cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rgrd_cnt);
1024 else if (dent == phba->debug_readApp) 1024 else if (dent == phba->debug_readApp)
1025 cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_rapp_cnt); 1025 cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rapp_cnt);
1026 else if (dent == phba->debug_readRef) 1026 else if (dent == phba->debug_readRef)
1027 cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_rref_cnt); 1027 cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rref_cnt);
1028 else if (dent == phba->debug_InjErrLBA) 1028 else if (dent == phba->debug_InjErrLBA) {
1029 cnt = snprintf(cbuf, 16, "0x%lx\n", 1029 if (phba->lpfc_injerr_lba == (unsigned long)(-1))
1030 cnt = snprintf(cbuf, 32, "off\n");
1031 else
1032 cnt = snprintf(cbuf, 32, "0x%lx\n",
1030 (unsigned long) phba->lpfc_injerr_lba); 1033 (unsigned long) phba->lpfc_injerr_lba);
1031 else 1034 } else
1032 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 1035 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
1033 "0547 Unknown debugfs error injection entry\n"); 1036 "0547 Unknown debugfs error injection entry\n");
1034 1037
@@ -1042,7 +1045,7 @@ lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf,
1042 struct dentry *dent = file->f_dentry; 1045 struct dentry *dent = file->f_dentry;
1043 struct lpfc_hba *phba = file->private_data; 1046 struct lpfc_hba *phba = file->private_data;
1044 char dstbuf[32]; 1047 char dstbuf[32];
1045 unsigned long tmp; 1048 unsigned long tmp = 0;
1046 int size; 1049 int size;
1047 1050
1048 memset(dstbuf, 0, 32); 1051 memset(dstbuf, 0, 32);
@@ -1050,7 +1053,12 @@ lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf,
1050 if (copy_from_user(dstbuf, buf, size)) 1053 if (copy_from_user(dstbuf, buf, size))
1051 return 0; 1054 return 0;
1052 1055
1053 if (strict_strtoul(dstbuf, 0, &tmp)) 1056 if (dent == phba->debug_InjErrLBA) {
1057 if ((buf[0] == 'o') && (buf[1] == 'f') && (buf[2] == 'f'))
1058 tmp = (unsigned long)(-1);
1059 }
1060
1061 if ((tmp == 0) && (kstrtoul(dstbuf, 0, &tmp)))
1054 return 0; 1062 return 0;
1055 1063
1056 if (dent == phba->debug_writeGuard) 1064 if (dent == phba->debug_writeGuard)
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index efc055b6bac4..8021c9e1fb9f 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -1,4 +1,4 @@
1/******************************************************************* 1/******************************************************************r
2 * This file is part of the Emulex Linux Device Driver for * 2 * This file is part of the Emulex Linux Device Driver for *
3 * Fibre Channel Host Bus Adapters. * 3 * Fibre Channel Host Bus Adapters. *
4 * Copyright (C) 2004-2012 Emulex. All rights reserved. * 4 * Copyright (C) 2004-2012 Emulex. All rights reserved. *
@@ -39,8 +39,8 @@
39#include "lpfc_sli4.h" 39#include "lpfc_sli4.h"
40#include "lpfc_nl.h" 40#include "lpfc_nl.h"
41#include "lpfc_disc.h" 41#include "lpfc_disc.h"
42#include "lpfc_scsi.h"
43#include "lpfc.h" 42#include "lpfc.h"
43#include "lpfc_scsi.h"
44#include "lpfc_logmsg.h" 44#include "lpfc_logmsg.h"
45#include "lpfc_crtn.h" 45#include "lpfc_crtn.h"
46#include "lpfc_vport.h" 46#include "lpfc_vport.h"
@@ -51,13 +51,19 @@
51int _dump_buf_done; 51int _dump_buf_done;
52 52
53static char *dif_op_str[] = { 53static char *dif_op_str[] = {
54 "SCSI_PROT_NORMAL", 54 "PROT_NORMAL",
55 "SCSI_PROT_READ_INSERT", 55 "PROT_READ_INSERT",
56 "SCSI_PROT_WRITE_STRIP", 56 "PROT_WRITE_STRIP",
57 "SCSI_PROT_READ_STRIP", 57 "PROT_READ_STRIP",
58 "SCSI_PROT_WRITE_INSERT", 58 "PROT_WRITE_INSERT",
59 "SCSI_PROT_READ_PASS", 59 "PROT_READ_PASS",
60 "SCSI_PROT_WRITE_PASS", 60 "PROT_WRITE_PASS",
61};
62
63static char *dif_grd_str[] = {
64 "NO_GUARD",
65 "DIF_CRC",
66 "DIX_IP",
61}; 67};
62 68
63struct scsi_dif_tuple { 69struct scsi_dif_tuple {
@@ -1281,10 +1287,14 @@ lpfc_cmd_blksize(struct scsi_cmnd *sc)
1281 1287
1282#ifdef CONFIG_SCSI_LPFC_DEBUG_FS 1288#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1283 1289
1284#define BG_ERR_INIT 1 1290/* Return if if error injection is detected by Initiator */
1285#define BG_ERR_TGT 2 1291#define BG_ERR_INIT 0x1
1286#define BG_ERR_SWAP 3 1292/* Return if if error injection is detected by Target */
1287#define BG_ERR_CHECK 4 1293#define BG_ERR_TGT 0x2
1294/* Return if if swapping CSUM<-->CRC is required for error injection */
1295#define BG_ERR_SWAP 0x10
1296/* Return if disabling Guard/Ref/App checking is required for error injection */
1297#define BG_ERR_CHECK 0x20
1288 1298
1289/** 1299/**
1290 * lpfc_bg_err_inject - Determine if we should inject an error 1300 * lpfc_bg_err_inject - Determine if we should inject an error
@@ -1294,10 +1304,7 @@ lpfc_cmd_blksize(struct scsi_cmnd *sc)
1294 * @apptag: (out) BlockGuard application tag for transmitted data 1304 * @apptag: (out) BlockGuard application tag for transmitted data
1295 * @new_guard (in) Value to replace CRC with if needed 1305 * @new_guard (in) Value to replace CRC with if needed
1296 * 1306 *
1297 * Returns (1) if error injection is detected by Initiator 1307 * Returns BG_ERR_* bit mask or 0 if request ignored
1298 * Returns (2) if error injection is detected by Target
1299 * Returns (3) if swapping CSUM->CRC is required for error injection
1300 * Returns (4) disabling Guard/Ref/App checking is required for error injection
1301 **/ 1308 **/
1302static int 1309static int
1303lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc, 1310lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc,
@@ -1305,6 +1312,7 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc,
1305{ 1312{
1306 struct scatterlist *sgpe; /* s/g prot entry */ 1313 struct scatterlist *sgpe; /* s/g prot entry */
1307 struct scatterlist *sgde; /* s/g data entry */ 1314 struct scatterlist *sgde; /* s/g data entry */
1315 struct lpfc_scsi_buf *lpfc_cmd = NULL;
1308 struct scsi_dif_tuple *src = NULL; 1316 struct scsi_dif_tuple *src = NULL;
1309 uint32_t op = scsi_get_prot_op(sc); 1317 uint32_t op = scsi_get_prot_op(sc);
1310 uint32_t blksize; 1318 uint32_t blksize;
@@ -1336,6 +1344,7 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc,
1336 blockoff = numblks; 1344 blockoff = numblks;
1337 src = (struct scsi_dif_tuple *)sg_virt(sgpe); 1345 src = (struct scsi_dif_tuple *)sg_virt(sgpe);
1338 src += blockoff; 1346 src += blockoff;
1347 lpfc_cmd = (struct lpfc_scsi_buf *)sc->host_scribble;
1339 } 1348 }
1340 } 1349 }
1341 1350
@@ -1344,56 +1353,71 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc,
1344 if (phba->lpfc_injerr_wref_cnt) { 1353 if (phba->lpfc_injerr_wref_cnt) {
1345 switch (op) { 1354 switch (op) {
1346 case SCSI_PROT_WRITE_PASS: 1355 case SCSI_PROT_WRITE_PASS:
1347 if (blockoff && src) { 1356 if (src) {
1348 /* Insert error