diff options
| -rw-r--r-- | drivers/scsi/qla2xxx/Makefile | 2 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.c | 22 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.h | 19 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 10 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_dfs.c | 175 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_fw.h | 7 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 13 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 73 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 87 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 11 |
10 files changed, 405 insertions, 14 deletions
diff --git a/drivers/scsi/qla2xxx/Makefile b/drivers/scsi/qla2xxx/Makefile index 71ddb5db4944..c51fd1f86639 100644 --- a/drivers/scsi/qla2xxx/Makefile +++ b/drivers/scsi/qla2xxx/Makefile | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \ | 1 | qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \ |
| 2 | qla_dbg.o qla_sup.o qla_attr.o qla_mid.o | 2 | qla_dbg.o qla_sup.o qla_attr.o qla_mid.o qla_dfs.o |
| 3 | 3 | ||
| 4 | obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o | 4 | obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 796c4ce87831..d88e98c476b0 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
| @@ -1051,6 +1051,7 @@ qla25xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
| 1051 | struct qla25xx_fw_dump *fw; | 1051 | struct qla25xx_fw_dump *fw; |
| 1052 | uint32_t ext_mem_cnt; | 1052 | uint32_t ext_mem_cnt; |
| 1053 | void *nxt; | 1053 | void *nxt; |
| 1054 | struct qla2xxx_fce_chain *fcec; | ||
| 1054 | 1055 | ||
| 1055 | risc_address = ext_mem_cnt = 0; | 1056 | risc_address = ext_mem_cnt = 0; |
| 1056 | flags = 0; | 1057 | flags = 0; |
| @@ -1321,10 +1322,31 @@ qla25xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
| 1321 | if (rval != QLA_SUCCESS) | 1322 | if (rval != QLA_SUCCESS) |
| 1322 | goto qla25xx_fw_dump_failed_0; | 1323 | goto qla25xx_fw_dump_failed_0; |
| 1323 | 1324 | ||
| 1325 | /* Fibre Channel Trace Buffer. */ | ||
| 1324 | nxt = qla2xxx_copy_queues(ha, nxt); | 1326 | nxt = qla2xxx_copy_queues(ha, nxt); |
| 1325 | if (ha->eft) | 1327 | if (ha->eft) |
| 1326 | memcpy(nxt, ha->eft, ntohl(ha->fw_dump->eft_size)); | 1328 | memcpy(nxt, ha->eft, ntohl(ha->fw_dump->eft_size)); |
| 1327 | 1329 | ||
| 1330 | /* Fibre Channel Event Buffer. */ | ||
| 1331 | if (!ha->fce) | ||
| 1332 | goto qla25xx_fw_dump_failed_0; | ||
| 1333 | |||
| 1334 | ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT); | ||
| 1335 | |||
| 1336 | fcec = nxt + ntohl(ha->fw_dump->eft_size); | ||
| 1337 | fcec->type = __constant_htonl(DUMP_CHAIN_FCE | DUMP_CHAIN_LAST); | ||
| 1338 | fcec->chain_size = htonl(sizeof(struct qla2xxx_fce_chain) + | ||
| 1339 | fce_calc_size(ha->fce_bufs)); | ||
| 1340 | fcec->size = htonl(fce_calc_size(ha->fce_bufs)); | ||
| 1341 | fcec->addr_l = htonl(LSD(ha->fce_dma)); | ||
| 1342 | fcec->addr_h = htonl(MSD(ha->fce_dma)); | ||
| 1343 | |||
| 1344 | iter_reg = fcec->eregs; | ||
| 1345 | for (cnt = 0; cnt < 8; cnt++) | ||
| 1346 | *iter_reg++ = htonl(ha->fce_mb[cnt]); | ||
| 1347 | |||
| 1348 | memcpy(iter_reg, ha->fce, ntohl(fcec->size)); | ||
| 1349 | |||
| 1328 | qla25xx_fw_dump_failed_0: | 1350 | qla25xx_fw_dump_failed_0: |
| 1329 | if (rval != QLA_SUCCESS) { | 1351 | if (rval != QLA_SUCCESS) { |
| 1330 | qla_printk(KERN_WARNING, ha, | 1352 | qla_printk(KERN_WARNING, ha, |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index a50ecf0b7c84..524598afc81c 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h | |||
| @@ -256,6 +256,25 @@ struct qla25xx_fw_dump { | |||
| 256 | #define EFT_BYTES_PER_BUFFER 0x4000 | 256 | #define EFT_BYTES_PER_BUFFER 0x4000 |
| 257 | #define EFT_SIZE ((EFT_BYTES_PER_BUFFER) * (EFT_NUM_BUFFERS)) | 257 | #define EFT_SIZE ((EFT_BYTES_PER_BUFFER) * (EFT_NUM_BUFFERS)) |
| 258 | 258 | ||
| 259 | #define FCE_NUM_BUFFERS 64 | ||
| 260 | #define FCE_BYTES_PER_BUFFER 0x400 | ||
| 261 | #define FCE_SIZE ((FCE_BYTES_PER_BUFFER) * (FCE_NUM_BUFFERS)) | ||
| 262 | #define fce_calc_size(b) ((FCE_BYTES_PER_BUFFER) * (b)) | ||
| 263 | |||
| 264 | struct qla2xxx_fce_chain { | ||
| 265 | uint32_t type; | ||
| 266 | uint32_t chain_size; | ||
| 267 | |||
| 268 | uint32_t size; | ||
| 269 | uint32_t addr_l; | ||
| 270 | uint32_t addr_h; | ||
| 271 | uint32_t eregs[8]; | ||
| 272 | }; | ||
| 273 | |||
| 274 | #define DUMP_CHAIN_VARIANT 0x80000000 | ||
| 275 | #define DUMP_CHAIN_FCE 0x7FFFFAF0 | ||
| 276 | #define DUMP_CHAIN_LAST 0x80000000 | ||
| 277 | |||
| 259 | struct qla2xxx_fw_dump { | 278 | struct qla2xxx_fw_dump { |
| 260 | uint8_t signature[4]; | 279 | uint8_t signature[4]; |
| 261 | uint32_t version; | 280 | uint32_t version; |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 3f934bdce6ae..6f129da37589 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
| @@ -2156,6 +2156,7 @@ typedef struct scsi_qla_host { | |||
| 2156 | uint32_t gpsc_supported :1; | 2156 | uint32_t gpsc_supported :1; |
| 2157 | uint32_t vsan_enabled :1; | 2157 | uint32_t vsan_enabled :1; |
| 2158 | uint32_t npiv_supported :1; | 2158 | uint32_t npiv_supported :1; |
| 2159 | uint32_t fce_enabled :1; | ||
| 2159 | } flags; | 2160 | } flags; |
| 2160 | 2161 | ||
| 2161 | atomic_t loop_state; | 2162 | atomic_t loop_state; |
| @@ -2449,6 +2450,15 @@ typedef struct scsi_qla_host { | |||
| 2449 | dma_addr_t eft_dma; | 2450 | dma_addr_t eft_dma; |
| 2450 | void *eft; | 2451 | void *eft; |
| 2451 | 2452 | ||
| 2453 | struct dentry *dfs_dir; | ||
| 2454 | struct dentry *dfs_fce; | ||
| 2455 | dma_addr_t fce_dma; | ||
| 2456 | void *fce; | ||
| 2457 | uint32_t fce_bufs; | ||
| 2458 | uint16_t fce_mb[8]; | ||
| 2459 | uint64_t fce_wr, fce_rd; | ||
| 2460 | struct mutex fce_mutex; | ||
| 2461 | |||
| 2452 | uint8_t host_str[16]; | 2462 | uint8_t host_str[16]; |
| 2453 | uint32_t pci_attr; | 2463 | uint32_t pci_attr; |
| 2454 | uint16_t chip_revision; | 2464 | uint16_t chip_revision; |
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c new file mode 100644 index 000000000000..1479c60441c8 --- /dev/null +++ b/drivers/scsi/qla2xxx/qla_dfs.c | |||
| @@ -0,0 +1,175 @@ | |||
| 1 | /* | ||
| 2 | * QLogic Fibre Channel HBA Driver | ||
| 3 | * Copyright (c) 2003-2005 QLogic Corporation | ||
| 4 | * | ||
| 5 | * See LICENSE.qla2xxx for copyright and licensing details. | ||
| 6 | */ | ||
| 7 | #include "qla_def.h" | ||
| 8 | |||
| 9 | #include <linux/debugfs.h> | ||
| 10 | #include <linux/seq_file.h> | ||
| 11 | |||
| 12 | static struct dentry *qla2x00_dfs_root; | ||
| 13 | static atomic_t qla2x00_dfs_root_count; | ||
| 14 | |||
| 15 | static int | ||
| 16 | qla2x00_dfs_fce_show(struct seq_file *s, void *unused) | ||
| 17 | { | ||
| 18 | scsi_qla_host_t *ha = s->private; | ||
| 19 | uint32_t cnt; | ||
| 20 | uint32_t *fce; | ||
| 21 | uint64_t fce_start; | ||
| 22 | |||
| 23 | mutex_lock(&ha->fce_mutex); | ||
| 24 | |||
| 25 | seq_printf(s, "FCE Trace Buffer\n"); | ||
| 26 | seq_printf(s, "In Pointer = %llx\n\n", ha->fce_wr); | ||
| 27 | seq_printf(s, "Base = %llx\n\n", (unsigned long long) ha->fce_dma); | ||
| 28 | seq_printf(s, "FCE Enable Registers\n"); | ||
| 29 | seq_printf(s, "%08x %08x %08x %08x %08x %08x\n", | ||
| 30 | ha->fce_mb[0], ha->fce_mb[2], ha->fce_mb[3], ha->fce_mb[4], | ||
| 31 | ha->fce_mb[5], ha->fce_mb[6]); | ||
| 32 | |||
| 33 | fce = (uint32_t *) ha->fce; | ||
| 34 | fce_start = (unsigned long long) ha->fce_dma; | ||
| 35 | for (cnt = 0; cnt < fce_calc_size(ha->fce_bufs) / 4; cnt++) { | ||
| 36 | if (cnt % 8 == 0) | ||
| 37 | seq_printf(s, "\n%llx: ", | ||
| 38 | (unsigned long long)((cnt * 4) + fce_start)); | ||
| 39 | else | ||
| 40 | seq_printf(s, " "); | ||
| 41 | seq_printf(s, "%08x", *fce++); | ||
| 42 | } | ||
| 43 | |||
| 44 | seq_printf(s, "\nEnd\n"); | ||
| 45 | |||
| 46 | mutex_unlock(&ha->fce_mutex); | ||
| 47 | |||
| 48 | return 0; | ||
| 49 | } | ||
| 50 | |||
| 51 | static int | ||
| 52 | qla2x00_dfs_fce_open(struct inode *inode, struct file *file) | ||
| 53 | { | ||
| 54 | scsi_qla_host_t *ha = inode->i_private; | ||
| 55 | int rval; | ||
| 56 | |||
| 57 | if (!ha->flags.fce_enabled) | ||
| 58 | goto out; | ||
| 59 | |||
| 60 | mutex_lock(&ha->fce_mutex); | ||
| 61 | |||
| 62 | /* Pause tracing to flush FCE buffers. */ | ||
| 63 | rval = qla2x00_disable_fce_trace(ha, &ha->fce_wr, &ha->fce_rd); | ||
| 64 | if (rval) | ||
| 65 | qla_printk(KERN_WARNING, ha, | ||
| 66 | "DebugFS: Unable to disable FCE (%d).\n", rval); | ||
| 67 | |||
| 68 | ha->flags.fce_enabled = 0; | ||
| 69 | |||
| 70 | mutex_unlock(&ha->fce_mutex); | ||
| 71 | out: | ||
| 72 | return single_open(file, qla2x00_dfs_fce_show, ha); | ||
| 73 | } | ||
| 74 | |||
| 75 | static int | ||
| 76 | qla2x00_dfs_fce_release(struct inode *inode, struct file *file) | ||
| 77 | { | ||
| 78 | scsi_qla_host_t *ha = inode->i_private; | ||
| 79 | int rval; | ||
| 80 | |||
| 81 | if (ha->flags.fce_enabled) | ||
| 82 | goto out; | ||
| 83 | |||
| 84 | mutex_lock(&ha->fce_mutex); | ||
| 85 | |||
| 86 | /* Re-enable FCE tracing. */ | ||
| 87 | ha->flags.fce_enabled = 1; | ||
| 88 | memset(ha->fce, 0, fce_calc_size(ha->fce_bufs)); | ||
| 89 | rval = qla2x00_enable_fce_trace(ha, ha->fce_dma, ha->fce_bufs, | ||
| 90 | ha->fce_mb, &ha->fce_bufs); | ||
| 91 | if (rval) { | ||
| 92 | qla_printk(KERN_WARNING, ha, | ||
| 93 | "DebugFS: Unable to reinitialize FCE (%d).\n", rval); | ||
| 94 | ha->flags.fce_enabled = 0; | ||
| 95 | } | ||
| 96 | |||
| 97 | mutex_unlock(&ha->fce_mutex); | ||
| 98 | out: | ||
| 99 | return single_release(inode, file); | ||
| 100 | } | ||
| 101 | |||
| 102 | static const struct file_operations dfs_fce_ops = { | ||
| 103 | .open = qla2x00_dfs_fce_open, | ||
| 104 | .read = seq_read, | ||
| 105 | .llseek = seq_lseek, | ||
| 106 | .release = qla2x00_dfs_fce_release, | ||
| 107 | }; | ||
| 108 | |||
| 109 | int | ||
| 110 | qla2x00_dfs_setup(scsi_qla_host_t *ha) | ||
| 111 | { | ||
| 112 | if (!IS_QLA25XX(ha)) | ||
| 113 | goto out; | ||
| 114 | if (!ha->fce) | ||
| 115 | goto out; | ||
| 116 | |||
| 117 | if (qla2x00_dfs_root) | ||
| 118 | goto create_dir; | ||
| 119 | |||
| 120 | atomic_set(&qla2x00_dfs_root_count, 0); | ||
| 121 | qla2x00_dfs_root = debugfs_create_dir(QLA2XXX_DRIVER_NAME, NULL); | ||
| 122 | if (!qla2x00_dfs_root) { | ||
| 123 | qla_printk(KERN_NOTICE, ha, | ||
| 124 | "DebugFS: Unable to create root directory.\n"); | ||
| 125 | goto out; | ||
| 126 | } | ||
| 127 | |||
| 128 | create_dir: | ||
| 129 | if (ha->dfs_dir) | ||
| 130 | goto create_nodes; | ||
| 131 | |||
| 132 | mutex_init(&ha->fce_mutex); | ||
| 133 | ha->dfs_dir = debugfs_create_dir(ha->host_str, qla2x00_dfs_root); | ||
| 134 | if (!ha->dfs_dir) { | ||
| 135 | qla_printk(KERN_NOTICE, ha, | ||
| 136 | "DebugFS: Unable to create ha directory.\n"); | ||
| 137 | goto out; | ||
| 138 | } | ||
| 139 | |||
| 140 | atomic_inc(&qla2x00_dfs_root_count); | ||
| 141 | |||
| 142 | create_nodes: | ||
| 143 | ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, ha, | ||
| 144 | &dfs_fce_ops); | ||
| 145 | if (!ha->dfs_fce) { | ||
| 146 | qla_printk(KERN_NOTICE, ha, | ||
| 147 | "DebugFS: Unable to fce node.\n"); | ||
| 148 | goto out; | ||
| 149 | } | ||
| 150 | out: | ||
| 151 | return 0; | ||
| 152 | } | ||
| 153 | |||
| 154 | int | ||
| 155 | qla2x00_dfs_remove(scsi_qla_host_t *ha) | ||
| 156 | { | ||
| 157 | if (ha->dfs_fce) { | ||
| 158 | debugfs_remove(ha->dfs_fce); | ||
| 159 | ha->dfs_fce = NULL; | ||
| 160 | } | ||
| 161 | |||
| 162 | if (ha->dfs_dir) { | ||
| 163 | debugfs_remove(ha->dfs_dir); | ||
| 164 | ha->dfs_dir = NULL; | ||
| 165 | atomic_dec(&qla2x00_dfs_root_count); | ||
| 166 | } | ||
| 167 | |||
| 168 | if (atomic_read(&qla2x00_dfs_root_count) == 0 && | ||
| 169 | qla2x00_dfs_root) { | ||
| 170 | debugfs_remove(qla2x00_dfs_root); | ||
| 171 | qla2x00_dfs_root = NULL; | ||
| 172 | } | ||
| 173 | |||
| 174 | return 0; | ||
| 175 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index ef14bcde712a..9337e138ed63 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h | |||
| @@ -959,6 +959,13 @@ struct device_reg_24xx { | |||
| 959 | #define TC_EFT_ENABLE 4 | 959 | #define TC_EFT_ENABLE 4 |
| 960 | #define TC_EFT_DISABLE 5 | 960 | #define TC_EFT_DISABLE 5 |
| 961 | 961 | ||
| 962 | #define TC_FCE_ENABLE 8 | ||
| 963 | #define TC_FCE_OPTIONS 0 | ||
| 964 | #define TC_FCE_DEFAULT_RX_SIZE 2112 | ||
| 965 | #define TC_FCE_DEFAULT_TX_SIZE 2112 | ||
| 966 | #define TC_FCE_DISABLE 9 | ||
| 967 | #define TC_FCE_DISABLE_TRACE BIT_0 | ||
| 968 | |||
| 962 | /* MID Support ***************************************************************/ | 969 | /* MID Support ***************************************************************/ |
| 963 | 970 | ||
| 964 | #define MIN_MULTI_ID_FABRIC 64 /* Must be power-of-2. */ | 971 | #define MIN_MULTI_ID_FABRIC 64 /* Must be power-of-2. */ |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 2fd31fdafcc9..ba35fc26ce6b 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
| @@ -233,6 +233,13 @@ extern int | |||
| 233 | qla2x00_disable_eft_trace(scsi_qla_host_t *); | 233 | qla2x00_disable_eft_trace(scsi_qla_host_t *); |
| 234 | 234 | ||
| 235 | extern int | 235 | extern int |
| 236 | qla2x00_enable_fce_trace(scsi_qla_host_t *, dma_addr_t, uint16_t , uint16_t *, | ||
| 237 | uint32_t *); | ||
| 238 | |||
| 239 | extern int | ||
| 240 | qla2x00_disable_fce_trace(scsi_qla_host_t *, uint64_t *, uint64_t *); | ||
| 241 | |||
| 242 | extern int | ||
| 236 | qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t); | 243 | qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t); |
| 237 | 244 | ||
| 238 | extern int | 245 | extern int |
| @@ -334,4 +341,10 @@ extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *); | |||
| 334 | extern void qla2x00_init_host_attr(scsi_qla_host_t *); | 341 | extern void qla2x00_init_host_attr(scsi_qla_host_t *); |
| 335 | extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *); | 342 | extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *); |
| 336 | extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *); | 343 | extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *); |
| 344 | |||
| 345 | /* | ||
| 346 | * Global Function Prototypes in qla_dfs.c source file. | ||
| 347 | */ | ||
| 348 | extern int qla2x00_dfs_setup(scsi_qla_host_t *); | ||
| 349 | extern int qla2x00_dfs_remove(scsi_qla_host_t *); | ||
| 337 | #endif /* _QLA_GBL_H */ | 350 | #endif /* _QLA_GBL_H */ |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index da2cce011520..cacfd2509387 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
| @@ -732,9 +732,9 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) | |||
| 732 | { | 732 | { |
| 733 | int rval; | 733 | int rval; |
| 734 | uint32_t dump_size, fixed_size, mem_size, req_q_size, rsp_q_size, | 734 | uint32_t dump_size, fixed_size, mem_size, req_q_size, rsp_q_size, |
| 735 | eft_size; | 735 | eft_size, fce_size; |
| 736 | dma_addr_t eft_dma; | 736 | dma_addr_t tc_dma; |
| 737 | void *eft; | 737 | void *tc; |
| 738 | 738 | ||
| 739 | if (ha->fw_dump) { | 739 | if (ha->fw_dump) { |
| 740 | qla_printk(KERN_WARNING, ha, | 740 | qla_printk(KERN_WARNING, ha, |
| @@ -743,7 +743,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) | |||
| 743 | } | 743 | } |
| 744 | 744 | ||
| 745 | ha->fw_dumped = 0; | 745 | ha->fw_dumped = 0; |
| 746 | fixed_size = mem_size = eft_size = 0; | 746 | fixed_size = mem_size = eft_size = fce_size = 0; |
| 747 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { | 747 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { |
| 748 | fixed_size = sizeof(struct qla2100_fw_dump); | 748 | fixed_size = sizeof(struct qla2100_fw_dump); |
| 749 | } else if (IS_QLA23XX(ha)) { | 749 | } else if (IS_QLA23XX(ha)) { |
| @@ -758,20 +758,20 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) | |||
| 758 | sizeof(uint32_t); | 758 | sizeof(uint32_t); |
| 759 | 759 | ||
| 760 | /* Allocate memory for Extended Trace Buffer. */ | 760 | /* Allocate memory for Extended Trace Buffer. */ |
| 761 | eft = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &eft_dma, | 761 | tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma, |
| 762 | GFP_KERNEL); | 762 | GFP_KERNEL); |
| 763 | if (!eft) { | 763 | if (!tc) { |
| 764 | qla_printk(KERN_WARNING, ha, "Unable to allocate " | 764 | qla_printk(KERN_WARNING, ha, "Unable to allocate " |
| 765 | "(%d KB) for EFT.\n", EFT_SIZE / 1024); | 765 | "(%d KB) for EFT.\n", EFT_SIZE / 1024); |
| 766 | goto cont_alloc; | 766 | goto cont_alloc; |
| 767 | } | 767 | } |
| 768 | 768 | ||
| 769 | rval = qla2x00_enable_eft_trace(ha, eft_dma, EFT_NUM_BUFFERS); | 769 | rval = qla2x00_enable_eft_trace(ha, tc_dma, EFT_NUM_BUFFERS); |
| 770 | if (rval) { | 770 | if (rval) { |
| 771 | qla_printk(KERN_WARNING, ha, "Unable to initialize " | 771 | qla_printk(KERN_WARNING, ha, "Unable to initialize " |
| 772 | "EFT (%d).\n", rval); | 772 | "EFT (%d).\n", rval); |
| 773 | dma_free_coherent(&ha->pdev->dev, EFT_SIZE, eft, | 773 | dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc, |
| 774 | eft_dma); | 774 | tc_dma); |
| 775 | goto cont_alloc; | 775 | goto cont_alloc; |
| 776 | } | 776 | } |
| 777 | 777 | ||
| @@ -779,9 +779,41 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) | |||
| 779 | EFT_SIZE / 1024); | 779 | EFT_SIZE / 1024); |
| 780 | 780 | ||
| 781 | eft_size = EFT_SIZE; | 781 | eft_size = EFT_SIZE; |
| 782 | memset(eft, 0, eft_size); | 782 | memset(tc, 0, eft_size); |
| 783 | ha->eft_dma = eft_dma; | 783 | ha->eft_dma = tc_dma; |
| 784 | ha->eft = eft; | 784 | ha->eft = tc; |
| 785 | |||
| 786 | /* Allocate memory for Fibre Channel Event Buffer. */ | ||
| 787 | if (!IS_QLA25XX(ha)) | ||
| 788 | goto cont_alloc; | ||
| 789 | |||
| 790 | tc = dma_alloc_coherent(&ha->pdev->dev, FCE_SIZE, &tc_dma, | ||
| 791 | GFP_KERNEL); | ||
| 792 | if (!tc) { | ||
| 793 | qla_printk(KERN_WARNING, ha, "Unable to allocate " | ||
| 794 | "(%d KB) for FCE.\n", FCE_SIZE / 1024); | ||
| 795 | goto cont_alloc; | ||
| 796 | } | ||
| 797 | |||
| 798 | memset(tc, 0, FCE_SIZE); | ||
| 799 | rval = qla2x00_enable_fce_trace(ha, tc_dma, FCE_NUM_BUFFERS, | ||
| 800 | ha->fce_mb, &ha->fce_bufs); | ||
| 801 | if (rval) { | ||
| 802 | qla_printk(KERN_WARNING, ha, "Unable to initialize " | ||
| 803 | "FCE (%d).\n", rval); | ||
| 804 | dma_free_coherent(&ha->pdev->dev, FCE_SIZE, tc, | ||
| 805 | tc_dma); | ||
| 806 | ha->flags.fce_enabled = 0; | ||
| 807 | goto cont_alloc; | ||
| 808 | } | ||
| 809 | |||
| 810 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for FCE...\n", | ||
| 811 | FCE_SIZE / 1024); | ||
| 812 | |||
| 813 | fce_size = sizeof(struct qla2xxx_fce_chain) + EFT_SIZE; | ||
| 814 | ha->flags.fce_enabled = 1; | ||
| 815 | ha->fce_dma = tc_dma; | ||
| 816 | ha->fce = tc; | ||
| 785 | } | 817 | } |
| 786 | cont_alloc: | 818 | cont_alloc: |
| 787 | req_q_size = ha->request_q_length * sizeof(request_t); | 819 | req_q_size = ha->request_q_length * sizeof(request_t); |
| @@ -789,7 +821,7 @@ cont_alloc: | |||
| 789 | 821 | ||
| 790 | dump_size = offsetof(struct qla2xxx_fw_dump, isp); | 822 | dump_size = offsetof(struct qla2xxx_fw_dump, isp); |
| 791 | dump_size += fixed_size + mem_size + req_q_size + rsp_q_size + | 823 | dump_size += fixed_size + mem_size + req_q_size + rsp_q_size + |
| 792 | eft_size; | 824 | eft_size + fce_size; |
| 793 | 825 | ||
| 794 | ha->fw_dump = vmalloc(dump_size); | 826 | ha->fw_dump = vmalloc(dump_size); |
| 795 | if (!ha->fw_dump) { | 827 | if (!ha->fw_dump) { |
| @@ -3247,6 +3279,21 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) | |||
| 3247 | "(%d).\n", rval); | 3279 | "(%d).\n", rval); |
| 3248 | } | 3280 | } |
| 3249 | } | 3281 | } |
| 3282 | |||
| 3283 | if (ha->fce) { | ||
| 3284 | ha->flags.fce_enabled = 1; | ||
| 3285 | memset(ha->fce, 0, | ||
| 3286 | fce_calc_size(ha->fce_bufs)); | ||
| 3287 | rval = qla2x00_enable_fce_trace(ha, | ||
| 3288 | ha->fce_dma, ha->fce_bufs, ha->fce_mb, | ||
| 3289 | &ha->fce_bufs); | ||
| 3290 | if (rval) { | ||
| 3291 | qla_printk(KERN_WARNING, ha, | ||
| 3292 | "Unable to reinitialize FCE " | ||
| 3293 | "(%d).\n", rval); | ||
| 3294 | ha->flags.fce_enabled = 0; | ||
| 3295 | } | ||
| 3296 | } | ||
| 3250 | } else { /* failed the ISP abort */ | 3297 | } else { /* failed the ISP abort */ |
| 3251 | ha->flags.online = 1; | 3298 | ha->flags.online = 1; |
| 3252 | if (test_bit(ISP_ABORT_RETRY, &ha->dpc_flags)) { | 3299 | if (test_bit(ISP_ABORT_RETRY, &ha->dpc_flags)) { |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 7c6aa4ec8f4f..99d29fff836d 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
| @@ -2415,6 +2415,93 @@ qla2x00_disable_eft_trace(scsi_qla_host_t *ha) | |||
| 2415 | } | 2415 | } |
| 2416 | 2416 | ||
| 2417 | int | 2417 | int |
| 2418 | qla2x00_enable_fce_trace(scsi_qla_host_t *ha, dma_addr_t fce_dma, | ||
| 2419 | uint16_t buffers, uint16_t *mb, uint32_t *dwords) | ||
| 2420 | { | ||
| 2421 | int rval; | ||
| 2422 | mbx_cmd_t mc; | ||
| 2423 | mbx_cmd_t *mcp = &mc; | ||
| 2424 | |||
| 2425 | if (!IS_QLA25XX(ha)) | ||
| 2426 | return QLA_FUNCTION_FAILED; | ||
| 2427 | |||
| 2428 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | ||
| 2429 | |||
| 2430 | mcp->mb[0] = MBC_TRACE_CONTROL; | ||
| 2431 | mcp->mb[1] = TC_FCE_ENABLE; | ||
| 2432 | mcp->mb[2] = LSW(fce_dma); | ||
| 2433 | mcp->mb[3] = MSW(fce_dma); | ||
| 2434 | mcp->mb[4] = LSW(MSD(fce_dma)); | ||
| 2435 | mcp->mb[5] = MSW(MSD(fce_dma)); | ||
| 2436 | mcp->mb[6] = buffers; | ||
| 2437 | mcp->mb[7] = TC_AEN_DISABLE; | ||
| 2438 | mcp->mb[8] = 0; | ||
| 2439 | mcp->mb[9] = TC_FCE_DEFAULT_RX_SIZE; | ||
| 2440 | mcp->mb[10] = TC_FCE_DEFAULT_TX_SIZE; | ||
| 2441 | mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2| | ||
| 2442 | MBX_1|MBX_0; | ||
| 2443 | mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | ||
| 2444 | mcp->tov = 30; | ||
| 2445 | mcp->flags = 0; | ||
| 2446 | rval = qla2x00_mailbox_command(ha, mcp); | ||
| 2447 | if (rval != QLA_SUCCESS) { | ||
| 2448 | DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n", | ||
| 2449 | __func__, ha->host_no, rval, mcp->mb[0], mcp->mb[1])); | ||
| 2450 | } else { | ||
| 2451 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); | ||
| 2452 | |||
| 2453 | if (mb) | ||
| 2454 | memcpy(mb, mcp->mb, 8 * sizeof(*mb)); | ||
| 2455 | if (dwords) | ||
| 2456 | *dwords = mcp->mb[6]; | ||
| 2457 | } | ||
| 2458 | |||
| 2459 | return rval; | ||
| 2460 | } | ||
| 2461 | |||
| 2462 | int | ||
| 2463 | qla2x00_disable_fce_trace(scsi_qla_host_t *ha, uint64_t *wr, uint64_t *rd) | ||
| 2464 | { | ||
| 2465 | int rval; | ||
| 2466 | mbx_cmd_t mc; | ||
| 2467 | mbx_cmd_t *mcp = &mc; | ||
| 2468 | |||
| 2469 | if (!IS_FWI2_CAPABLE(ha)) | ||
| 2470 | return QLA_FUNCTION_FAILED; | ||
| 2471 | |||
| 2472 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | ||
| 2473 | |||
| 2474 | mcp->mb[0] = MBC_TRACE_CONTROL; | ||
| 2475 | mcp->mb[1] = TC_FCE_DISABLE; | ||
| 2476 | mcp->mb[2] = TC_FCE_DISABLE_TRACE; | ||
| 2477 | mcp->out_mb = MBX_2|MBX_1|MBX_0; | ||
| 2478 | mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2| | ||
| 2479 | MBX_1|MBX_0; | ||
| 2480 | mcp->tov = 30; | ||
| 2481 | mcp->flags = 0; | ||
| 2482 | rval = qla2x00_mailbox_command(ha, mcp); | ||
| 2483 | if (rval != QLA_SUCCESS) { | ||
| 2484 | DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n", | ||
| 2485 | __func__, ha->host_no, rval, mcp->mb[0], mcp->mb[1])); | ||
| 2486 | } else { | ||
| 2487 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); | ||
| 2488 | |||
| 2489 | if (wr) | ||
| 2490 | *wr = (uint64_t) mcp->mb[5] << 48 | | ||
| 2491 | (uint64_t) mcp->mb[4] << 32 | | ||
| 2492 | (uint64_t) mcp->mb[3] << 16 | | ||
| 2493 | (uint64_t) mcp->mb[2]; | ||
| 2494 | if (rd) | ||
| 2495 | *rd = (uint64_t) mcp->mb[9] << 48 | | ||
| 2496 | (uint64_t) mcp->mb[8] << 32 | | ||
| 2497 | (uint64_t) mcp->mb[7] << 16 | | ||
| 2498 | (uint64_t) mcp->mb[6]; | ||
| 2499 | } | ||
| 2500 | |||
| 2501 | return rval; | ||
| 2502 | } | ||
| 2503 | |||
| 2504 | int | ||
| 2418 | qla2x00_read_sfp(scsi_qla_host_t *ha, dma_addr_t sfp_dma, uint16_t addr, | 2505 | qla2x00_read_sfp(scsi_qla_host_t *ha, dma_addr_t sfp_dma, uint16_t addr, |
| 2419 | uint16_t off, uint16_t count) | 2506 | uint16_t off, uint16_t count) |
| 2420 | { | 2507 | { |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 63938d74a571..8d1408e18efd 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
| @@ -1791,6 +1791,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 1791 | 1791 | ||
| 1792 | qla2x00_init_host_attr(ha); | 1792 | qla2x00_init_host_attr(ha); |
| 1793 | 1793 | ||
| 1794 | qla2x00_dfs_setup(ha); | ||
| 1795 | |||
| 1794 | qla_printk(KERN_INFO, ha, "\n" | 1796 | qla_printk(KERN_INFO, ha, "\n" |
| 1795 | " QLogic Fibre Channel HBA Driver: %s\n" | 1797 | " QLogic Fibre Channel HBA Driver: %s\n" |
| 1796 | " QLogic %s - %s\n" | 1798 | " QLogic %s - %s\n" |
| @@ -1822,6 +1824,8 @@ qla2x00_remove_one(struct pci_dev *pdev) | |||
| 1822 | 1824 | ||
| 1823 | ha = pci_get_drvdata(pdev); | 1825 | ha = pci_get_drvdata(pdev); |
| 1824 | 1826 | ||
| 1827 | qla2x00_dfs_remove(ha); | ||
| 1828 | |||
| 1825 | qla2x00_free_sysfs_attr(ha); | 1829 | qla2x00_free_sysfs_attr(ha); |
| 1826 | 1830 | ||
| 1827 | fc_remove_host(ha->host); | 1831 | fc_remove_host(ha->host); |
| @@ -1855,6 +1859,9 @@ qla2x00_free_device(scsi_qla_host_t *ha) | |||
| 1855 | kthread_stop(t); | 1859 | kthread_stop(t); |
| 1856 | } | 1860 | } |
| 1857 | 1861 | ||
| 1862 | if (ha->flags.fce_enabled) | ||
| 1863 | qla2x00_disable_fce_trace(ha, NULL, NULL); | ||
| 1864 | |||
| 1858 | if (ha->eft) | 1865 | if (ha->eft) |
| 1859 | qla2x00_disable_eft_trace(ha); | 1866 | qla2x00_disable_eft_trace(ha); |
| 1860 | 1867 | ||
| @@ -2212,6 +2219,10 @@ qla2x00_mem_free(scsi_qla_host_t *ha) | |||
| 2212 | /* free sp pool */ | 2219 | /* free sp pool */ |
| 2213 | qla2x00_free_sp_pool(ha); | 2220 | qla2x00_free_sp_pool(ha); |
| 2214 | 2221 | ||
| 2222 | if (ha->fce) | ||
| 2223 | dma_free_coherent(&ha->pdev->dev, FCE_SIZE, ha->fce, | ||
| 2224 | ha->fce_dma); | ||
| 2225 | |||
| 2215 | if (ha->fw_dump) { | 2226 | if (ha->fw_dump) { |
| 2216 | if (ha->eft) | 2227 | if (ha->eft) |
| 2217 | dma_free_coherent(&ha->pdev->dev, | 2228 | dma_free_coherent(&ha->pdev->dev, |
