aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r--drivers/scsi/qla2xxx/Makefile2
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.c22
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.h19
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h10
-rw-r--r--drivers/scsi/qla2xxx/qla_dfs.c175
-rw-r--r--drivers/scsi/qla2xxx/qla_fw.h7
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h13
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c73
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c87
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c11
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 @@
1qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \ 1qla2xxx-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
4obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o 4obj-$(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
1328qla25xx_fw_dump_failed_0: 1350qla25xx_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
264struct 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
259struct qla2xxx_fw_dump { 278struct 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
12static struct dentry *qla2x00_dfs_root;
13static atomic_t qla2x00_dfs_root_count;
14
15static int
16qla2x00_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
51static int
52qla2x00_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);
71out:
72 return single_open(file, qla2x00_dfs_fce_show, ha);
73}
74
75static int
76qla2x00_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);
98out:
99 return single_release(inode, file);
100}
101
102static 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
109int
110qla2x00_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
128create_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
142create_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 }
150out:
151 return 0;
152}
153
154int
155qla2x00_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
233qla2x00_disable_eft_trace(scsi_qla_host_t *); 233qla2x00_disable_eft_trace(scsi_qla_host_t *);
234 234
235extern int 235extern int
236qla2x00_enable_fce_trace(scsi_qla_host_t *, dma_addr_t, uint16_t , uint16_t *,
237 uint32_t *);
238
239extern int
240qla2x00_disable_fce_trace(scsi_qla_host_t *, uint64_t *, uint64_t *);
241
242extern int
236qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t); 243qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t);
237 244
238extern int 245extern int
@@ -334,4 +341,10 @@ extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *);
334extern void qla2x00_init_host_attr(scsi_qla_host_t *); 341extern void qla2x00_init_host_attr(scsi_qla_host_t *);
335extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *); 342extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *);
336extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *); 343extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *);
344
345/*
346 * Global Function Prototypes in qla_dfs.c source file.
347 */
348extern int qla2x00_dfs_setup(scsi_qla_host_t *);
349extern 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 }
786cont_alloc: 818cont_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
2417int 2417int
2418qla2x00_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
2462int
2463qla2x00_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
2504int
2418qla2x00_read_sfp(scsi_qla_host_t *ha, dma_addr_t sfp_dma, uint16_t addr, 2505qla2x00_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,