2 * QLogic Fibre Channel HBA Driver
3 * Copyright (c) 2003-2005 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
*ha
= s
->private;
23 mutex_lock(&ha
->fce_mutex
);
25 seq_printf(s
, "FCE Trace Buffer\n");
26 seq_printf(s
, "In Pointer = %llx\n\n", (unsigned long long)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]);
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
++) {
37 seq_printf(s
, "\n%llx: ",
38 (unsigned long long)((cnt
* 4) + fce_start
));
41 seq_printf(s
, "%08x", *fce
++);
44 seq_printf(s
, "\nEnd\n");
46 mutex_unlock(&ha
->fce_mutex
);
52 qla2x00_dfs_fce_open(struct inode
*inode
, struct file
*file
)
54 scsi_qla_host_t
*ha
= inode
->i_private
;
57 if (!ha
->flags
.fce_enabled
)
60 mutex_lock(&ha
->fce_mutex
);
62 /* Pause tracing to flush FCE buffers. */
63 rval
= qla2x00_disable_fce_trace(ha
, &ha
->fce_wr
, &ha
->fce_rd
);
65 qla_printk(KERN_WARNING
, ha
,
66 "DebugFS: Unable to disable FCE (%d).\n", rval
);
68 ha
->flags
.fce_enabled
= 0;
70 mutex_unlock(&ha
->fce_mutex
);
72 return single_open(file
, qla2x00_dfs_fce_show
, ha
);
76 qla2x00_dfs_fce_release(struct inode
*inode
, struct file
*file
)
78 scsi_qla_host_t
*ha
= inode
->i_private
;
81 if (ha
->flags
.fce_enabled
)
84 mutex_lock(&ha
->fce_mutex
);
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
);
92 qla_printk(KERN_WARNING
, ha
,
93 "DebugFS: Unable to reinitialize FCE (%d).\n", rval
);
94 ha
->flags
.fce_enabled
= 0;
97 mutex_unlock(&ha
->fce_mutex
);
99 return single_release(inode
, file
);
102 static const struct file_operations dfs_fce_ops
= {
103 .open
= qla2x00_dfs_fce_open
,
106 .release
= qla2x00_dfs_fce_release
,
110 qla2x00_dfs_setup(scsi_qla_host_t
*ha
)
117 if (qla2x00_dfs_root
)
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");
132 mutex_init(&ha
->fce_mutex
);
133 ha
->dfs_dir
= debugfs_create_dir(ha
->host_str
, qla2x00_dfs_root
);
135 qla_printk(KERN_NOTICE
, ha
,
136 "DebugFS: Unable to create ha directory.\n");
140 atomic_inc(&qla2x00_dfs_root_count
);
143 ha
->dfs_fce
= debugfs_create_file("fce", S_IRUSR
, ha
->dfs_dir
, ha
,
146 qla_printk(KERN_NOTICE
, ha
,
147 "DebugFS: Unable to fce node.\n");
155 qla2x00_dfs_remove(scsi_qla_host_t
*ha
)
158 debugfs_remove(ha
->dfs_fce
);
163 debugfs_remove(ha
->dfs_dir
);
165 atomic_dec(&qla2x00_dfs_root_count
);
168 if (atomic_read(&qla2x00_dfs_root_count
) == 0 &&
170 debugfs_remove(qla2x00_dfs_root
);
171 qla2x00_dfs_root
= NULL
;