diff options
author | James Smart <James.Smart@Emulex.Com> | 2008-12-04 22:40:02 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-12-29 12:24:28 -0500 |
commit | e2a0a9d69ce224c6f5b72515d81150e6bf4a905a (patch) | |
tree | fdd6d82431841c31c80cbabc24927fbb94c59cd6 /drivers/scsi/lpfc/lpfc_debugfs.c | |
parent | 81301a9b05c3690bf32bf4ef37d941f0f870a7ba (diff) |
[SCSI] lpfc 8.3.0 : Add BlockGuard support (T10-DIF) code
Add SCSI data path, error handling, and debugfs code to complete
BlockGuard support.
Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_debugfs.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_debugfs.c | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 771920bdde44..992009a9470f 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c | |||
@@ -907,6 +907,91 @@ out: | |||
907 | return rc; | 907 | return rc; |
908 | } | 908 | } |
909 | 909 | ||
910 | static int | ||
911 | lpfc_debugfs_dumpData_open(struct inode *inode, struct file *file) | ||
912 | { | ||
913 | struct lpfc_debug *debug; | ||
914 | int rc = -ENOMEM; | ||
915 | |||
916 | if (!_dump_buf_data) | ||
917 | return -EBUSY; | ||
918 | |||
919 | debug = kmalloc(sizeof(*debug), GFP_KERNEL); | ||
920 | if (!debug) | ||
921 | goto out; | ||
922 | |||
923 | /* Round to page boundry */ | ||
924 | printk(KERN_ERR "BLKGRD %s: _dump_buf_data=0x%p\n", | ||
925 | __func__, _dump_buf_data); | ||
926 | debug->buffer = _dump_buf_data; | ||
927 | if (!debug->buffer) { | ||
928 | kfree(debug); | ||
929 | goto out; | ||
930 | } | ||
931 | |||
932 | debug->len = (1 << _dump_buf_data_order) << PAGE_SHIFT; | ||
933 | file->private_data = debug; | ||
934 | |||
935 | rc = 0; | ||
936 | out: | ||
937 | return rc; | ||
938 | } | ||
939 | |||
940 | static int | ||
941 | lpfc_debugfs_dumpDif_open(struct inode *inode, struct file *file) | ||
942 | { | ||
943 | struct lpfc_debug *debug; | ||
944 | int rc = -ENOMEM; | ||
945 | |||
946 | if (!_dump_buf_dif) | ||
947 | return -EBUSY; | ||
948 | |||
949 | debug = kmalloc(sizeof(*debug), GFP_KERNEL); | ||
950 | if (!debug) | ||
951 | goto out; | ||
952 | |||
953 | /* Round to page boundry */ | ||
954 | printk(KERN_ERR "BLKGRD %s: _dump_buf_dif=0x%p file=%s\n", __func__, | ||
955 | _dump_buf_dif, file->f_dentry->d_name.name); | ||
956 | debug->buffer = _dump_buf_dif; | ||
957 | if (!debug->buffer) { | ||
958 | kfree(debug); | ||
959 | goto out; | ||
960 | } | ||
961 | |||
962 | debug->len = (1 << _dump_buf_dif_order) << PAGE_SHIFT; | ||
963 | file->private_data = debug; | ||
964 | |||
965 | rc = 0; | ||
966 | out: | ||
967 | return rc; | ||
968 | } | ||
969 | |||
970 | static ssize_t | ||
971 | lpfc_debugfs_dumpDataDif_write(struct file *file, const char __user *buf, | ||
972 | size_t nbytes, loff_t *ppos) | ||
973 | { | ||
974 | /* | ||
975 | * The Data/DIF buffers only save one failing IO | ||
976 | * The write op is used as a reset mechanism after an IO has | ||
977 | * already been saved to the next one can be saved | ||
978 | */ | ||
979 | spin_lock(&_dump_buf_lock); | ||
980 | |||
981 | memset((void *)_dump_buf_data, 0, | ||
982 | ((1 << PAGE_SHIFT) << _dump_buf_data_order)); | ||
983 | memset((void *)_dump_buf_dif, 0, | ||
984 | ((1 << PAGE_SHIFT) << _dump_buf_dif_order)); | ||
985 | |||
986 | _dump_buf_done = 0; | ||
987 | |||
988 | spin_unlock(&_dump_buf_lock); | ||
989 | |||
990 | return nbytes; | ||
991 | } | ||
992 | |||
993 | |||
994 | |||
910 | /** | 995 | /** |
911 | * lpfc_debugfs_nodelist_open - Open the nodelist debugfs file. | 996 | * lpfc_debugfs_nodelist_open - Open the nodelist debugfs file. |
912 | * @inode: The inode pointer that contains a vport pointer. | 997 | * @inode: The inode pointer that contains a vport pointer. |
@@ -1035,6 +1120,17 @@ lpfc_debugfs_release(struct inode *inode, struct file *file) | |||
1035 | return 0; | 1120 | return 0; |
1036 | } | 1121 | } |
1037 | 1122 | ||
1123 | static int | ||
1124 | lpfc_debugfs_dumpDataDif_release(struct inode *inode, struct file *file) | ||
1125 | { | ||
1126 | struct lpfc_debug *debug = file->private_data; | ||
1127 | |||
1128 | debug->buffer = NULL; | ||
1129 | kfree(debug); | ||
1130 | |||
1131 | return 0; | ||
1132 | } | ||
1133 | |||
1038 | #undef lpfc_debugfs_op_disc_trc | 1134 | #undef lpfc_debugfs_op_disc_trc |
1039 | static struct file_operations lpfc_debugfs_op_disc_trc = { | 1135 | static struct file_operations lpfc_debugfs_op_disc_trc = { |
1040 | .owner = THIS_MODULE, | 1136 | .owner = THIS_MODULE, |
@@ -1080,6 +1176,26 @@ static struct file_operations lpfc_debugfs_op_dumpHostSlim = { | |||
1080 | .release = lpfc_debugfs_release, | 1176 | .release = lpfc_debugfs_release, |
1081 | }; | 1177 | }; |
1082 | 1178 | ||
1179 | #undef lpfc_debugfs_op_dumpData | ||
1180 | static struct file_operations lpfc_debugfs_op_dumpData = { | ||
1181 | .owner = THIS_MODULE, | ||
1182 | .open = lpfc_debugfs_dumpData_open, | ||
1183 | .llseek = lpfc_debugfs_lseek, | ||
1184 | .read = lpfc_debugfs_read, | ||
1185 | .write = lpfc_debugfs_dumpDataDif_write, | ||
1186 | .release = lpfc_debugfs_dumpDataDif_release, | ||
1187 | }; | ||
1188 | |||
1189 | #undef lpfc_debugfs_op_dumpDif | ||
1190 | static struct file_operations lpfc_debugfs_op_dumpDif = { | ||
1191 | .owner = THIS_MODULE, | ||
1192 | .open = lpfc_debugfs_dumpDif_open, | ||
1193 | .llseek = lpfc_debugfs_lseek, | ||
1194 | .read = lpfc_debugfs_read, | ||
1195 | .write = lpfc_debugfs_dumpDataDif_write, | ||
1196 | .release = lpfc_debugfs_dumpDataDif_release, | ||
1197 | }; | ||
1198 | |||
1083 | #undef lpfc_debugfs_op_slow_ring_trc | 1199 | #undef lpfc_debugfs_op_slow_ring_trc |
1084 | static struct file_operations lpfc_debugfs_op_slow_ring_trc = { | 1200 | static struct file_operations lpfc_debugfs_op_slow_ring_trc = { |
1085 | .owner = THIS_MODULE, | 1201 | .owner = THIS_MODULE, |
@@ -1176,6 +1292,32 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) | |||
1176 | goto debug_failed; | 1292 | goto debug_failed; |
1177 | } | 1293 | } |
1178 | 1294 | ||
1295 | /* Setup dumpData */ | ||
1296 | snprintf(name, sizeof(name), "dumpData"); | ||
1297 | phba->debug_dumpData = | ||
1298 | debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, | ||
1299 | phba->hba_debugfs_root, | ||
1300 | phba, &lpfc_debugfs_op_dumpData); | ||
1301 | if (!phba->debug_dumpData) { | ||
1302 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, | ||
1303 | "0800 Cannot create debugfs dumpData\n"); | ||
1304 | goto debug_failed; | ||
1305 | } | ||
1306 | |||
1307 | /* Setup dumpDif */ | ||
1308 | snprintf(name, sizeof(name), "dumpDif"); | ||
1309 | phba->debug_dumpDif = | ||
1310 | debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, | ||
1311 | phba->hba_debugfs_root, | ||
1312 | phba, &lpfc_debugfs_op_dumpDif); | ||
1313 | if (!phba->debug_dumpDif) { | ||
1314 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, | ||
1315 | "0801 Cannot create debugfs dumpDif\n"); | ||
1316 | goto debug_failed; | ||
1317 | } | ||
1318 | |||
1319 | |||
1320 | |||
1179 | /* Setup slow ring trace */ | 1321 | /* Setup slow ring trace */ |
1180 | if (lpfc_debugfs_max_slow_ring_trc) { | 1322 | if (lpfc_debugfs_max_slow_ring_trc) { |
1181 | num = lpfc_debugfs_max_slow_ring_trc - 1; | 1323 | num = lpfc_debugfs_max_slow_ring_trc - 1; |
@@ -1340,6 +1482,16 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport) | |||
1340 | debugfs_remove(phba->debug_dumpHostSlim); /* HostSlim */ | 1482 | debugfs_remove(phba->debug_dumpHostSlim); /* HostSlim */ |
1341 | phba->debug_dumpHostSlim = NULL; | 1483 | phba->debug_dumpHostSlim = NULL; |
1342 | } | 1484 | } |
1485 | if (phba->debug_dumpData) { | ||
1486 | debugfs_remove(phba->debug_dumpData); /* dumpData */ | ||
1487 | phba->debug_dumpData = NULL; | ||
1488 | } | ||
1489 | |||
1490 | if (phba->debug_dumpDif) { | ||
1491 | debugfs_remove(phba->debug_dumpDif); /* dumpDif */ | ||
1492 | phba->debug_dumpDif = NULL; | ||
1493 | } | ||
1494 | |||
1343 | if (phba->slow_ring_trc) { | 1495 | if (phba->slow_ring_trc) { |
1344 | kfree(phba->slow_ring_trc); | 1496 | kfree(phba->slow_ring_trc); |
1345 | phba->slow_ring_trc = NULL; | 1497 | phba->slow_ring_trc = NULL; |