2 * QLogic Fibre Channel HBA Driver
3 * Copyright (c) 2003-2014 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_tgt_sess_show(struct seq_file *s, void *unused)
18 scsi_qla_host_t *vha = s->private;
19 struct qla_hw_data *ha = vha->hw;
21 struct fc_port *sess = NULL;
22 struct qla_tgt *tgt= vha->vha_tgt.qla_tgt;
24 seq_printf(s, "%s\n",vha->host_str);
26 seq_printf(s, "Port ID Port Name Handle\n");
28 spin_lock_irqsave(&ha->tgt.sess_lock, flags);
29 list_for_each_entry(sess, &vha->vp_fcports, list)
30 seq_printf(s, "%02x:%02x:%02x %8phC %d\n",
31 sess->d_id.b.domain, sess->d_id.b.area,
32 sess->d_id.b.al_pa, sess->port_name,
34 spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
41 qla2x00_dfs_tgt_sess_open(struct inode *inode, struct file *file)
43 scsi_qla_host_t *vha = inode->i_private;
44 return single_open(file, qla2x00_dfs_tgt_sess_show, vha);
48 static const struct file_operations dfs_tgt_sess_ops = {
49 .open = qla2x00_dfs_tgt_sess_open,
52 .release = single_release,
56 qla_dfs_fw_resource_cnt_show(struct seq_file *s, void *unused)
58 struct scsi_qla_host *vha = s->private;
59 struct qla_hw_data *ha = vha->hw;
61 seq_puts(s, "FW Resource count\n\n");
62 seq_printf(s, "Original TGT exchg count[%d]\n",
63 ha->orig_fw_tgt_xcb_count);
64 seq_printf(s, "current TGT exchg count[%d]\n",
65 ha->cur_fw_tgt_xcb_count);
66 seq_printf(s, "original Initiator Exchange count[%d]\n",
67 ha->orig_fw_xcb_count);
68 seq_printf(s, "Current Initiator Exchange count[%d]\n",
69 ha->cur_fw_xcb_count);
70 seq_printf(s, "Original IOCB count[%d]\n", ha->orig_fw_iocb_count);
71 seq_printf(s, "Current IOCB count[%d]\n", ha->cur_fw_iocb_count);
72 seq_printf(s, "MAX VP count[%d]\n", ha->max_npiv_vports);
73 seq_printf(s, "MAX FCF count[%d]\n", ha->fw_max_fcf_count);
79 qla_dfs_fw_resource_cnt_open(struct inode *inode, struct file *file)
81 struct scsi_qla_host *vha = inode->i_private;
82 return single_open(file, qla_dfs_fw_resource_cnt_show, vha);
85 static const struct file_operations dfs_fw_resource_cnt_ops = {
86 .open = qla_dfs_fw_resource_cnt_open,
89 .release = single_release,
93 qla_dfs_tgt_counters_show(struct seq_file *s, void *unused)
95 struct scsi_qla_host *vha = s->private;
97 seq_puts(s, "Target Counters\n");
98 seq_printf(s, "qla_core_sbt_cmd = %lld\n",
99 vha->tgt_counters.qla_core_sbt_cmd);
100 seq_printf(s, "qla_core_ret_sta_ctio = %lld\n",
101 vha->tgt_counters.qla_core_ret_sta_ctio);
102 seq_printf(s, "qla_core_ret_ctio = %lld\n",
103 vha->tgt_counters.qla_core_ret_ctio);
104 seq_printf(s, "core_qla_que_buf = %lld\n",
105 vha->tgt_counters.core_qla_que_buf);
106 seq_printf(s, "core_qla_snd_status = %lld\n",
107 vha->tgt_counters.core_qla_snd_status);
108 seq_printf(s, "core_qla_free_cmd = %lld\n",
109 vha->tgt_counters.core_qla_free_cmd);
110 seq_printf(s, "num alloc iocb failed = %lld\n",
111 vha->tgt_counters.num_alloc_iocb_failed);
112 seq_printf(s, "num term exchange sent = %lld\n",
113 vha->tgt_counters.num_term_xchg_sent);
114 seq_printf(s, "num Q full sent = %lld\n",
115 vha->tgt_counters.num_q_full_sent);
118 seq_printf(s, "DIF Inp Bytes = %lld\n",
119 vha->qla_stats.qla_dif_stats.dif_input_bytes);
120 seq_printf(s, "DIF Outp Bytes = %lld\n",
121 vha->qla_stats.qla_dif_stats.dif_output_bytes);
122 seq_printf(s, "DIF Inp Req = %lld\n",
123 vha->qla_stats.qla_dif_stats.dif_input_requests);
124 seq_printf(s, "DIF Outp Req = %lld\n",
125 vha->qla_stats.qla_dif_stats.dif_output_requests);
126 seq_printf(s, "DIF Guard err = %d\n",
127 vha->qla_stats.qla_dif_stats.dif_guard_err);
128 seq_printf(s, "DIF Ref tag err = %d\n",
129 vha->qla_stats.qla_dif_stats.dif_ref_tag_err);
130 seq_printf(s, "DIF App tag err = %d\n",
131 vha->qla_stats.qla_dif_stats.dif_app_tag_err);
136 qla_dfs_tgt_counters_open(struct inode *inode, struct file *file)
138 struct scsi_qla_host *vha = inode->i_private;
139 return single_open(file, qla_dfs_tgt_counters_show, vha);
142 static const struct file_operations dfs_tgt_counters_ops = {
143 .open = qla_dfs_tgt_counters_open,
146 .release = single_release,
150 qla2x00_dfs_fce_show(struct seq_file *s, void *unused)
152 scsi_qla_host_t *vha = s->private;
156 struct qla_hw_data *ha = vha->hw;
158 mutex_lock(&ha->fce_mutex);
160 seq_puts(s, "FCE Trace Buffer\n");
161 seq_printf(s, "In Pointer = %llx\n\n", (unsigned long long)ha->fce_wr);
162 seq_printf(s, "Base = %llx\n\n", (unsigned long long) ha->fce_dma);
163 seq_puts(s, "FCE Enable Registers\n");
164 seq_printf(s, "%08x %08x %08x %08x %08x %08x\n",
165 ha->fce_mb[0], ha->fce_mb[2], ha->fce_mb[3], ha->fce_mb[4],
166 ha->fce_mb[5], ha->fce_mb[6]);
168 fce = (uint32_t *) ha->fce;
169 fce_start = (unsigned long long) ha->fce_dma;
170 for (cnt = 0; cnt < fce_calc_size(ha->fce_bufs) / 4; cnt++) {
172 seq_printf(s, "\n%llx: ",
173 (unsigned long long)((cnt * 4) + fce_start));
176 seq_printf(s, "%08x", *fce++);
179 seq_puts(s, "\nEnd\n");
181 mutex_unlock(&ha->fce_mutex);
187 qla2x00_dfs_fce_open(struct inode *inode, struct file *file)
189 scsi_qla_host_t *vha = inode->i_private;
190 struct qla_hw_data *ha = vha->hw;
193 if (!ha->flags.fce_enabled)
196 mutex_lock(&ha->fce_mutex);
198 /* Pause tracing to flush FCE buffers. */
199 rval = qla2x00_disable_fce_trace(vha, &ha->fce_wr, &ha->fce_rd);
201 ql_dbg(ql_dbg_user, vha, 0x705c,
202 "DebugFS: Unable to disable FCE (%d).\n", rval);
204 ha->flags.fce_enabled = 0;
206 mutex_unlock(&ha->fce_mutex);
208 return single_open(file, qla2x00_dfs_fce_show, vha);
212 qla2x00_dfs_fce_release(struct inode *inode, struct file *file)
214 scsi_qla_host_t *vha = inode->i_private;
215 struct qla_hw_data *ha = vha->hw;
218 if (ha->flags.fce_enabled)
221 mutex_lock(&ha->fce_mutex);
223 /* Re-enable FCE tracing. */
224 ha->flags.fce_enabled = 1;
225 memset(ha->fce, 0, fce_calc_size(ha->fce_bufs));
226 rval = qla2x00_enable_fce_trace(vha, ha->fce_dma, ha->fce_bufs,
227 ha->fce_mb, &ha->fce_bufs);
229 ql_dbg(ql_dbg_user, vha, 0x700d,
230 "DebugFS: Unable to reinitialize FCE (%d).\n", rval);
231 ha->flags.fce_enabled = 0;
234 mutex_unlock(&ha->fce_mutex);
236 return single_release(inode, file);
239 static const struct file_operations dfs_fce_ops = {
240 .open = qla2x00_dfs_fce_open,
243 .release = qla2x00_dfs_fce_release,
247 qla2x00_dfs_setup(scsi_qla_host_t *vha)
249 struct qla_hw_data *ha = vha->hw;
251 if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) &&
257 if (qla2x00_dfs_root)
260 atomic_set(&qla2x00_dfs_root_count, 0);
261 qla2x00_dfs_root = debugfs_create_dir(QLA2XXX_DRIVER_NAME, NULL);
262 if (!qla2x00_dfs_root) {
263 ql_log(ql_log_warn, vha, 0x00f7,
264 "Unable to create debugfs root directory.\n");
272 mutex_init(&ha->fce_mutex);
273 ha->dfs_dir = debugfs_create_dir(vha->host_str, qla2x00_dfs_root);
275 ql_log(ql_log_warn, vha, 0x00f8,
276 "Unable to create debugfs ha directory.\n");
280 atomic_inc(&qla2x00_dfs_root_count);
283 ha->dfs_fw_resource_cnt = debugfs_create_file("fw_resource_count",
284 S_IRUSR, ha->dfs_dir, vha, &dfs_fw_resource_cnt_ops);
285 if (!ha->dfs_fw_resource_cnt) {
286 ql_log(ql_log_warn, vha, 0x00fd,
287 "Unable to create debugFS fw_resource_count node.\n");
291 ha->dfs_tgt_counters = debugfs_create_file("tgt_counters", S_IRUSR,
292 ha->dfs_dir, vha, &dfs_tgt_counters_ops);
293 if (!ha->dfs_tgt_counters) {
294 ql_log(ql_log_warn, vha, 0xd301,
295 "Unable to create debugFS tgt_counters node.\n");
299 ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, vha,
302 ql_log(ql_log_warn, vha, 0x00f9,
303 "Unable to create debugfs fce node.\n");
307 ha->tgt.dfs_tgt_sess = debugfs_create_file("tgt_sess",
308 S_IRUSR, ha->dfs_dir, vha, &dfs_tgt_sess_ops);
309 if (!ha->tgt.dfs_tgt_sess) {
310 ql_log(ql_log_warn, vha, 0xffff,
311 "Unable to create debugFS tgt_sess node.\n");
320 qla2x00_dfs_remove(scsi_qla_host_t *vha)
322 struct qla_hw_data *ha = vha->hw;
324 if (ha->tgt.dfs_tgt_sess) {
325 debugfs_remove(ha->tgt.dfs_tgt_sess);
326 ha->tgt.dfs_tgt_sess = NULL;
329 if (ha->dfs_fw_resource_cnt) {
330 debugfs_remove(ha->dfs_fw_resource_cnt);
331 ha->dfs_fw_resource_cnt = NULL;
334 if (ha->dfs_tgt_counters) {
335 debugfs_remove(ha->dfs_tgt_counters);
336 ha->dfs_tgt_counters = NULL;
340 debugfs_remove(ha->dfs_fce);
345 debugfs_remove(ha->dfs_dir);
347 atomic_dec(&qla2x00_dfs_root_count);
350 if (atomic_read(&qla2x00_dfs_root_count) == 0 &&
352 debugfs_remove(qla2x00_dfs_root);
353 qla2x00_dfs_root = NULL;