diff options
Diffstat (limited to 'drivers/scsi/qla2xxx')
-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, |