2 * QLogic Fibre Channel HBA Driver
3 * Copyright (c) 2003-2013 QLogic Corporation
5 * See LICENSE.qla2xxx for copyright and licensing details.
9 #include <linux/debugfs.h>
10 #include <linux/seq_file.h>
12 static struct dentry
*qla2x00_dfs_root
;
13 static atomic_t qla2x00_dfs_root_count
;
16 qla2x00_dfs_fce_show(struct seq_file
*s
, void *unused
)
18 scsi_qla_host_t
*vha
= s
->private;
22 struct qla_hw_data
*ha
= vha
->hw
;
24 mutex_lock(&ha
->fce_mutex
);
26 seq_printf(s
, "FCE Trace Buffer\n");
27 seq_printf(s
, "In Pointer = %llx\n\n", (unsigned long long)ha
->fce_wr
);
28 seq_printf(s
, "Base = %llx\n\n", (unsigned long long) ha
->fce_dma
);
29 seq_printf(s
, "FCE Enable Registers\n");
30 seq_printf(s
, "%08x %08x %08x %08x %08x %08x\n",
31 ha
->fce_mb
[0], ha
->fce_mb
[2], ha
->fce_mb
[3], ha
->fce_mb
[4],
32 ha
->fce_mb
[5], ha
->fce_mb
[6]);
34 fce
= (uint32_t *) ha
->fce
;
35 fce_start
= (unsigned long long) ha
->fce_dma
;
36 for (cnt
= 0; cnt
< fce_calc_size(ha
->fce_bufs
) / 4; cnt
++) {
38 seq_printf(s
, "\n%llx: ",
39 (unsigned long long)((cnt
* 4) + fce_start
));
42 seq_printf(s
, "%08x", *fce
++);
45 seq_printf(s
, "\nEnd\n");
47 mutex_unlock(&ha
->fce_mutex
);
53 qla2x00_dfs_fce_open(struct inode
*inode
, struct file
*file
)
55 scsi_qla_host_t
*vha
= inode
->i_private
;
56 struct qla_hw_data
*ha
= vha
->hw
;
59 if (!ha
->flags
.fce_enabled
)
62 mutex_lock(&ha
->fce_mutex
);
64 /* Pause tracing to flush FCE buffers. */
65 rval
= qla2x00_disable_fce_trace(vha
, &ha
->fce_wr
, &ha
->fce_rd
);
67 ql_dbg(ql_dbg_user
, vha
, 0x705c,
68 "DebugFS: Unable to disable FCE (%d).\n", rval
);
70 ha
->flags
.fce_enabled
= 0;
72 mutex_unlock(&ha
->fce_mutex
);
74 return single_open(file
, qla2x00_dfs_fce_show
, vha
);
78 qla2x00_dfs_fce_release(struct inode
*inode
, struct file
*file
)
80 scsi_qla_host_t
*vha
= inode
->i_private
;
81 struct qla_hw_data
*ha
= vha
->hw
;
84 if (ha
->flags
.fce_enabled
)
87 mutex_lock(&ha
->fce_mutex
);
89 /* Re-enable FCE tracing. */
90 ha
->flags
.fce_enabled
= 1;
91 memset(ha
->fce
, 0, fce_calc_size(ha
->fce_bufs
));
92 rval
= qla2x00_enable_fce_trace(vha
, ha
->fce_dma
, ha
->fce_bufs
,
93 ha
->fce_mb
, &ha
->fce_bufs
);
95 ql_dbg(ql_dbg_user
, vha
, 0x700d,
96 "DebugFS: Unable to reinitialize FCE (%d).\n", rval
);
97 ha
->flags
.fce_enabled
= 0;
100 mutex_unlock(&ha
->fce_mutex
);
102 return single_release(inode
, file
);
105 static const struct file_operations dfs_fce_ops
= {
106 .open
= qla2x00_dfs_fce_open
,
109 .release
= qla2x00_dfs_fce_release
,
113 qla2x00_dfs_setup(scsi_qla_host_t
*vha
)
115 struct qla_hw_data
*ha
= vha
->hw
;
117 if (!IS_QLA25XX(ha
) && !IS_QLA81XX(ha
) && !IS_QLA83XX(ha
))
122 if (qla2x00_dfs_root
)
125 atomic_set(&qla2x00_dfs_root_count
, 0);
126 qla2x00_dfs_root
= debugfs_create_dir(QLA2XXX_DRIVER_NAME
, NULL
);
127 if (!qla2x00_dfs_root
) {
128 ql_log(ql_log_warn
, vha
, 0x00f7,
129 "Unable to create debugfs root directory.\n");
137 mutex_init(&ha
->fce_mutex
);
138 ha
->dfs_dir
= debugfs_create_dir(vha
->host_str
, qla2x00_dfs_root
);
140 ql_log(ql_log_warn
, vha
, 0x00f8,
141 "Unable to create debugfs ha directory.\n");
145 atomic_inc(&qla2x00_dfs_root_count
);
148 ha
->dfs_fce
= debugfs_create_file("fce", S_IRUSR
, ha
->dfs_dir
, vha
,
151 ql_log(ql_log_warn
, vha
, 0x00f9,
152 "Unable to create debugfs fce node.\n");
160 qla2x00_dfs_remove(scsi_qla_host_t
*vha
)
162 struct qla_hw_data
*ha
= vha
->hw
;
164 debugfs_remove(ha
->dfs_fce
);
169 debugfs_remove(ha
->dfs_dir
);
171 atomic_dec(&qla2x00_dfs_root_count
);
174 if (atomic_read(&qla2x00_dfs_root_count
) == 0 &&
176 debugfs_remove(qla2x00_dfs_root
);
177 qla2x00_dfs_root
= NULL
;