diff options
| author | James Smart <james.smart@emulex.com> | 2012-03-01 22:37:42 -0500 |
|---|---|---|
| committer | James Bottomley <JBottomley@Parallels.com> | 2012-03-27 03:26:33 -0400 |
| commit | 9a6b09c071a5f66ed3c359d8631e07b34a9e738f (patch) | |
| tree | e295ef167f092f2e3d160f54b12c5583ae6c6728 | |
| parent | cf9712403f384f9e832f489e7f41ab535c8f1a74 (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.c | 32 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 309 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.h | 10 |
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 @@ | |||
| 51 | int _dump_buf_done; | 51 | int _dump_buf_done; |
| 52 | 52 | ||
| 53 | static char *dif_op_str[] = { | 53 | static 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 | |||
| 63 | static char *dif_grd_str[] = { | ||
| 64 | "NO_GUARD", | ||
| 65 | "DIF_CRC", | ||
| 66 | "DIX_IP", | ||
| 61 | }; | 67 | }; |
| 62 | 68 | ||
| 63 | struct scsi_dif_tuple { | 69 | struct 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 | **/ |
| 1302 | static int | 1309 | static int |
| 1303 | lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc, | 1310 | lpfc_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 | ||
