Linux Audio

Check our new training course

Loading...
v3.1
 
  1/*
  2 *  drivers/s390/cio/qdio_debug.c
  3 *
  4 *  Copyright IBM Corp. 2008,2009
  5 *
  6 *  Author: Jan Glauber (jang@linux.vnet.ibm.com)
  7 */
  8#include <linux/seq_file.h>
  9#include <linux/debugfs.h>
 
 
 
 10#include <asm/debug.h>
 11#include "qdio_debug.h"
 12#include "qdio.h"
 13
 14debug_info_t *qdio_dbf_setup;
 15debug_info_t *qdio_dbf_error;
 16
 17static struct dentry *debugfs_root;
 18#define QDIO_DEBUGFS_NAME_LEN	10
 
 
 
 
 
 
 
 19
 20void qdio_allocate_dbf(struct qdio_initialize *init_data,
 21		       struct qdio_irq *irq_ptr)
 
 
 22{
 23	char text[20];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 24
 25	DBF_EVENT("qfmt:%1d", init_data->q_format);
 26	DBF_HEX(init_data->adapter_name, 8);
 27	DBF_EVENT("qpff%4x", init_data->qib_param_field_format);
 28	DBF_HEX(&init_data->qib_param_field, sizeof(void *));
 29	DBF_HEX(&init_data->input_slib_elements, sizeof(void *));
 30	DBF_HEX(&init_data->output_slib_elements, sizeof(void *));
 31	DBF_EVENT("niq:%1d noq:%1d", init_data->no_input_qs,
 32		  init_data->no_output_qs);
 33	DBF_HEX(&init_data->input_handler, sizeof(void *));
 34	DBF_HEX(&init_data->output_handler, sizeof(void *));
 35	DBF_HEX(&init_data->int_parm, sizeof(long));
 36	DBF_HEX(&init_data->input_sbal_addr_array, sizeof(void *));
 37	DBF_HEX(&init_data->output_sbal_addr_array, sizeof(void *));
 38	DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr);
 39
 40	/* allocate trace view for the interface */
 41	snprintf(text, 20, "qdio_%s", dev_name(&init_data->cdev->dev));
 42	irq_ptr->debug_area = debug_register(text, 2, 1, 16);
 43	debug_register_view(irq_ptr->debug_area, &debug_hex_ascii_view);
 44	debug_set_level(irq_ptr->debug_area, DBF_WARN);
 45	DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf created");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 46}
 47
 48static int qstat_show(struct seq_file *m, void *v)
 49{
 50	unsigned char state;
 51	struct qdio_q *q = m->private;
 52	int i;
 53
 54	if (!q)
 55		return 0;
 56
 57	seq_printf(m, "DSCI: %d   nr_used: %d\n",
 58		   *(u32 *)q->irq_ptr->dsci, atomic_read(&q->nr_buf_used));
 59	seq_printf(m, "ftc: %d  last_move: %d\n",
 60		   q->first_to_check, q->last_move);
 
 61	if (q->is_input_q) {
 62		seq_printf(m, "polling: %d  ack start: %d  ack count: %d\n",
 63			   q->u.in.polling, q->u.in.ack_start,
 64			   q->u.in.ack_count);
 65		seq_printf(m, "IRQs disabled: %u\n",
 66			   test_bit(QDIO_QUEUE_IRQS_DISABLED,
 67			   &q->u.in.queue_irq_state));
 68	}
 69	seq_printf(m, "SBAL states:\n");
 70	seq_printf(m, "|0      |8      |16     |24     |32     |40     |48     |56  63|\n");
 71
 72	for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) {
 73		debug_get_buf_state(q, i, &state);
 74		switch (state) {
 75		case SLSB_P_INPUT_NOT_INIT:
 76		case SLSB_P_OUTPUT_NOT_INIT:
 77			seq_printf(m, "N");
 78			break;
 
 
 
 79		case SLSB_P_INPUT_PRIMED:
 80		case SLSB_CU_OUTPUT_PRIMED:
 81			seq_printf(m, "+");
 82			break;
 83		case SLSB_P_INPUT_ACK:
 84			seq_printf(m, "A");
 85			break;
 86		case SLSB_P_INPUT_ERROR:
 87		case SLSB_P_OUTPUT_ERROR:
 88			seq_printf(m, "x");
 89			break;
 90		case SLSB_CU_INPUT_EMPTY:
 91		case SLSB_P_OUTPUT_EMPTY:
 92			seq_printf(m, "-");
 93			break;
 94		case SLSB_P_INPUT_HALTED:
 95		case SLSB_P_OUTPUT_HALTED:
 96			seq_printf(m, ".");
 97			break;
 98		default:
 99			seq_printf(m, "?");
100		}
101		if (i == 63)
102			seq_printf(m, "\n");
103	}
104	seq_printf(m, "\n");
105	seq_printf(m, "|64     |72     |80     |88     |96     |104    |112    |   127|\n");
106
107	seq_printf(m, "\nSBAL statistics:");
108	if (!q->irq_ptr->perf_stat_enabled) {
109		seq_printf(m, " disabled\n");
110		return 0;
111	}
112
113	seq_printf(m, "\n1          2..        4..        8..        "
114		   "16..       32..       64..       127\n");
115	for (i = 0; i < ARRAY_SIZE(q->q_stats.nr_sbals); i++)
116		seq_printf(m, "%-10u ", q->q_stats.nr_sbals[i]);
117	seq_printf(m, "\nError      NOP        Total\n%-10u %-10u %-10u\n\n",
118		   q->q_stats.nr_sbal_error, q->q_stats.nr_sbal_nop,
119		   q->q_stats.nr_sbal_total);
120	return 0;
121}
122
123static int qstat_seq_open(struct inode *inode, struct file *filp)
 
 
124{
125	return single_open(filp, qstat_show,
126			   filp->f_path.dentry->d_inode->i_private);
 
 
 
 
 
 
 
 
 
127}
128
129static const struct file_operations debugfs_fops = {
130	.owner	 = THIS_MODULE,
131	.open	 = qstat_seq_open,
132	.read	 = seq_read,
133	.llseek  = seq_lseek,
134	.release = single_release,
135};
136
137static char *qperf_names[] = {
138	"Assumed adapter interrupts",
139	"QDIO interrupts",
140	"Requested PCIs",
141	"Inbound tasklet runs",
142	"Inbound tasklet resched",
143	"Inbound tasklet resched2",
144	"Outbound tasklet runs",
145	"SIGA read",
146	"SIGA write",
147	"SIGA sync",
148	"Inbound calls",
149	"Inbound handler",
150	"Inbound stop_polling",
151	"Inbound queue full",
152	"Outbound calls",
153	"Outbound handler",
154	"Outbound queue full",
155	"Outbound fast_requeue",
156	"Outbound target_full",
157	"QEBSM eqbs",
158	"QEBSM eqbs partial",
159	"QEBSM sqbs",
160	"QEBSM sqbs partial",
161	"Discarded interrupts"
162};
163
164static int qperf_show(struct seq_file *m, void *v)
165{
166	struct qdio_irq *irq_ptr = m->private;
167	unsigned int *stat;
168	int i;
169
170	if (!irq_ptr)
171		return 0;
172	if (!irq_ptr->perf_stat_enabled) {
173		seq_printf(m, "disabled\n");
174		return 0;
175	}
176	stat = (unsigned int *)&irq_ptr->perf_stat;
177
178	for (i = 0; i < ARRAY_SIZE(qperf_names); i++)
179		seq_printf(m, "%26s:\t%u\n",
180			   qperf_names[i], *(stat + i));
181	return 0;
182}
183
184static ssize_t qperf_seq_write(struct file *file, const char __user *ubuf,
185			       size_t count, loff_t *off)
186{
187	struct seq_file *seq = file->private_data;
188	struct qdio_irq *irq_ptr = seq->private;
189	struct qdio_q *q;
190	unsigned long val;
191	int ret, i;
192
193	if (!irq_ptr)
194		return 0;
195
196	ret = kstrtoul_from_user(ubuf, count, 10, &val);
197	if (ret)
198		return ret;
199
200	switch (val) {
201	case 0:
202		irq_ptr->perf_stat_enabled = 0;
203		memset(&irq_ptr->perf_stat, 0, sizeof(irq_ptr->perf_stat));
204		for_each_input_queue(irq_ptr, q, i)
205			memset(&q->q_stats, 0, sizeof(q->q_stats));
206		for_each_output_queue(irq_ptr, q, i)
207			memset(&q->q_stats, 0, sizeof(q->q_stats));
208		break;
209	case 1:
210		irq_ptr->perf_stat_enabled = 1;
211		break;
212	}
213	return count;
214}
215
216static int qperf_seq_open(struct inode *inode, struct file *filp)
217{
218	return single_open(filp, qperf_show,
219			   filp->f_path.dentry->d_inode->i_private);
220}
221
222static struct file_operations debugfs_perf_fops = {
223	.owner	 = THIS_MODULE,
224	.open	 = qperf_seq_open,
225	.read	 = seq_read,
226	.write	 = qperf_seq_write,
227	.llseek  = seq_lseek,
228	.release = single_release,
229};
230static void setup_debugfs_entry(struct qdio_q *q, struct ccw_device *cdev)
 
231{
232	char name[QDIO_DEBUGFS_NAME_LEN];
233
234	snprintf(name, QDIO_DEBUGFS_NAME_LEN, "%s_%d",
235		 q->is_input_q ? "input" : "output",
236		 q->nr);
237	q->debugfs_q = debugfs_create_file(name, S_IFREG | S_IRUGO | S_IWUSR,
238				q->irq_ptr->debugfs_dev, q, &debugfs_fops);
239	if (IS_ERR(q->debugfs_q))
240		q->debugfs_q = NULL;
241}
242
243void qdio_setup_debug_entries(struct qdio_irq *irq_ptr, struct ccw_device *cdev)
244{
245	struct qdio_q *q;
246	int i;
247
248	irq_ptr->debugfs_dev = debugfs_create_dir(dev_name(&cdev->dev),
249						  debugfs_root);
250	if (IS_ERR(irq_ptr->debugfs_dev))
251		irq_ptr->debugfs_dev = NULL;
252
253	irq_ptr->debugfs_perf = debugfs_create_file("statistics",
254				S_IFREG | S_IRUGO | S_IWUSR,
255				irq_ptr->debugfs_dev, irq_ptr,
256				&debugfs_perf_fops);
257	if (IS_ERR(irq_ptr->debugfs_perf))
258		irq_ptr->debugfs_perf = NULL;
259
260	for_each_input_queue(irq_ptr, q, i)
261		setup_debugfs_entry(q, cdev);
262	for_each_output_queue(irq_ptr, q, i)
263		setup_debugfs_entry(q, cdev);
264}
265
266void qdio_shutdown_debug_entries(struct qdio_irq *irq_ptr, struct ccw_device *cdev)
267{
268	struct qdio_q *q;
269	int i;
270
271	for_each_input_queue(irq_ptr, q, i)
272		debugfs_remove(q->debugfs_q);
273	for_each_output_queue(irq_ptr, q, i)
274		debugfs_remove(q->debugfs_q);
275	debugfs_remove(irq_ptr->debugfs_perf);
276	debugfs_remove(irq_ptr->debugfs_dev);
277}
278
279int __init qdio_debug_init(void)
280{
281	debugfs_root = debugfs_create_dir("qdio", NULL);
282
283	qdio_dbf_setup = debug_register("qdio_setup", 16, 1, 16);
284	debug_register_view(qdio_dbf_setup, &debug_hex_ascii_view);
285	debug_set_level(qdio_dbf_setup, DBF_INFO);
286	DBF_EVENT("dbf created\n");
287
288	qdio_dbf_error = debug_register("qdio_error", 4, 1, 16);
289	debug_register_view(qdio_dbf_error, &debug_hex_ascii_view);
290	debug_set_level(qdio_dbf_error, DBF_INFO);
291	DBF_ERROR("dbf created\n");
292	return 0;
293}
294
295void qdio_debug_exit(void)
296{
297	debugfs_remove(debugfs_root);
298	if (qdio_dbf_setup)
299		debug_unregister(qdio_dbf_setup);
300	if (qdio_dbf_error)
301		debug_unregister(qdio_dbf_error);
302}
v6.9.4
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 *  Copyright IBM Corp. 2008, 2009
 
 
  4 *
  5 *  Author: Jan Glauber (jang@linux.vnet.ibm.com)
  6 */
  7#include <linux/seq_file.h>
  8#include <linux/debugfs.h>
  9#include <linux/uaccess.h>
 10#include <linux/export.h>
 11#include <linux/slab.h>
 12#include <asm/debug.h>
 13#include "qdio_debug.h"
 14#include "qdio.h"
 15
 16debug_info_t *qdio_dbf_setup;
 17debug_info_t *qdio_dbf_error;
 18
 19static struct dentry *debugfs_root;
 20#define QDIO_DEBUGFS_NAME_LEN	10
 21#define QDIO_DBF_NAME_LEN	20
 22
 23struct qdio_dbf_entry {
 24	char dbf_name[QDIO_DBF_NAME_LEN];
 25	debug_info_t *dbf_info;
 26	struct list_head dbf_list;
 27};
 28
 29static LIST_HEAD(qdio_dbf_list);
 30static DEFINE_MUTEX(qdio_dbf_list_mutex);
 31
 32static debug_info_t *qdio_get_dbf_entry(char *name)
 33{
 34	struct qdio_dbf_entry *entry;
 35	debug_info_t *rc = NULL;
 36
 37	mutex_lock(&qdio_dbf_list_mutex);
 38	list_for_each_entry(entry, &qdio_dbf_list, dbf_list) {
 39		if (strcmp(entry->dbf_name, name) == 0) {
 40			rc = entry->dbf_info;
 41			break;
 42		}
 43	}
 44	mutex_unlock(&qdio_dbf_list_mutex);
 45	return rc;
 46}
 47
 48static void qdio_clear_dbf_list(void)
 49{
 50	struct qdio_dbf_entry *entry, *tmp;
 51
 52	mutex_lock(&qdio_dbf_list_mutex);
 53	list_for_each_entry_safe(entry, tmp, &qdio_dbf_list, dbf_list) {
 54		list_del(&entry->dbf_list);
 55		debug_unregister(entry->dbf_info);
 56		kfree(entry);
 57	}
 58	mutex_unlock(&qdio_dbf_list_mutex);
 59}
 60
 61int qdio_allocate_dbf(struct qdio_irq *irq_ptr)
 62{
 63	char text[QDIO_DBF_NAME_LEN];
 64	struct qdio_dbf_entry *new_entry;
 65
 
 
 
 
 
 
 
 
 
 
 
 
 
 66	DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr);
 67
 68	/* allocate trace view for the interface */
 69	snprintf(text, QDIO_DBF_NAME_LEN, "qdio_%s",
 70		 dev_name(&irq_ptr->cdev->dev));
 71	irq_ptr->debug_area = qdio_get_dbf_entry(text);
 72	if (irq_ptr->debug_area)
 73		DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf reused");
 74	else {
 75		irq_ptr->debug_area = debug_register(text, 2, 1, 16);
 76		if (!irq_ptr->debug_area)
 77			return -ENOMEM;
 78		if (debug_register_view(irq_ptr->debug_area,
 79						&debug_hex_ascii_view)) {
 80			debug_unregister(irq_ptr->debug_area);
 81			return -ENOMEM;
 82		}
 83		debug_set_level(irq_ptr->debug_area, DBF_WARN);
 84		DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf created");
 85		new_entry = kzalloc(sizeof(struct qdio_dbf_entry), GFP_KERNEL);
 86		if (!new_entry) {
 87			debug_unregister(irq_ptr->debug_area);
 88			return -ENOMEM;
 89		}
 90		strscpy(new_entry->dbf_name, text, QDIO_DBF_NAME_LEN);
 91		new_entry->dbf_info = irq_ptr->debug_area;
 92		mutex_lock(&qdio_dbf_list_mutex);
 93		list_add(&new_entry->dbf_list, &qdio_dbf_list);
 94		mutex_unlock(&qdio_dbf_list_mutex);
 95	}
 96	return 0;
 97}
 98
 99static int qstat_show(struct seq_file *m, void *v)
100{
101	unsigned char state;
102	struct qdio_q *q = m->private;
103	int i;
104
105	if (!q)
106		return 0;
107
108	seq_printf(m, "Timestamp: %llx\n", q->timestamp);
109	seq_printf(m, "Last Data IRQ: %llx  Last AI: %llx\n",
110		   q->irq_ptr->last_data_irq_time, last_ai_time);
111	seq_printf(m, "nr_used: %d  ftc: %d\n",
112		   atomic_read(&q->nr_buf_used), q->first_to_check);
113	if (q->is_input_q) {
114		seq_printf(m, "batch start: %u  batch count: %u\n",
115			   q->u.in.batch_start, q->u.in.batch_count);
116		seq_printf(m, "DSCI: %x   IRQs disabled: %u\n",
117			   *(u8 *)q->irq_ptr->dsci,
118			   test_bit(QDIO_IRQ_DISABLED,
119				    &q->irq_ptr->poll_state));
120	}
121	seq_printf(m, "SBAL states:\n");
122	seq_printf(m, "|0      |8      |16     |24     |32     |40     |48     |56  63|\n");
123
124	for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) {
125		debug_get_buf_state(q, i, &state);
126		switch (state) {
127		case SLSB_P_INPUT_NOT_INIT:
128		case SLSB_P_OUTPUT_NOT_INIT:
129			seq_printf(m, "N");
130			break;
131		case SLSB_P_OUTPUT_PENDING:
132			seq_printf(m, "P");
133			break;
134		case SLSB_P_INPUT_PRIMED:
135		case SLSB_CU_OUTPUT_PRIMED:
136			seq_printf(m, "+");
137			break;
138		case SLSB_P_INPUT_ACK:
139			seq_printf(m, "A");
140			break;
141		case SLSB_P_INPUT_ERROR:
142		case SLSB_P_OUTPUT_ERROR:
143			seq_printf(m, "x");
144			break;
145		case SLSB_CU_INPUT_EMPTY:
146		case SLSB_P_OUTPUT_EMPTY:
147			seq_printf(m, "-");
148			break;
149		case SLSB_P_INPUT_HALTED:
150		case SLSB_P_OUTPUT_HALTED:
151			seq_printf(m, ".");
152			break;
153		default:
154			seq_printf(m, "?");
155		}
156		if (i == 63)
157			seq_printf(m, "\n");
158	}
159	seq_printf(m, "\n");
160	seq_printf(m, "|64     |72     |80     |88     |96     |104    |112    |   127|\n");
161
162	seq_printf(m, "\nSBAL statistics:");
163	if (!q->irq_ptr->perf_stat_enabled) {
164		seq_printf(m, " disabled\n");
165		return 0;
166	}
167
168	seq_printf(m, "\n1          2..        4..        8..        "
169		   "16..       32..       64..       128\n");
170	for (i = 0; i < ARRAY_SIZE(q->q_stats.nr_sbals); i++)
171		seq_printf(m, "%-10u ", q->q_stats.nr_sbals[i]);
172	seq_printf(m, "\nError      NOP        Total\n%-10u %-10u %-10u\n\n",
173		   q->q_stats.nr_sbal_error, q->q_stats.nr_sbal_nop,
174		   q->q_stats.nr_sbal_total);
175	return 0;
176}
177
178DEFINE_SHOW_ATTRIBUTE(qstat);
179
180static int ssqd_show(struct seq_file *m, void *v)
181{
182	struct ccw_device *cdev = m->private;
183	struct qdio_ssqd_desc ssqd;
184	int rc;
185
186	rc = qdio_get_ssqd_desc(cdev, &ssqd);
187	if (rc)
188		return rc;
189
190	seq_hex_dump(m, "", DUMP_PREFIX_NONE, 16, 4, &ssqd, sizeof(ssqd),
191		     false);
192	return 0;
193}
194
195DEFINE_SHOW_ATTRIBUTE(ssqd);
 
 
 
 
 
 
196
197static char *qperf_names[] = {
198	"Assumed adapter interrupts",
199	"QDIO interrupts",
 
 
 
 
 
200	"SIGA read",
201	"SIGA write",
202	"SIGA sync",
203	"Inbound calls",
 
204	"Inbound stop_polling",
205	"Inbound queue full",
206	"Outbound calls",
 
207	"Outbound queue full",
208	"Outbound fast_requeue",
209	"Outbound target_full",
210	"QEBSM eqbs",
211	"QEBSM eqbs partial",
212	"QEBSM sqbs",
213	"QEBSM sqbs partial",
214	"Discarded interrupts"
215};
216
217static int qperf_show(struct seq_file *m, void *v)
218{
219	struct qdio_irq *irq_ptr = m->private;
220	unsigned int *stat;
221	int i;
222
223	if (!irq_ptr)
224		return 0;
225	if (!irq_ptr->perf_stat_enabled) {
226		seq_printf(m, "disabled\n");
227		return 0;
228	}
229	stat = (unsigned int *)&irq_ptr->perf_stat;
230
231	for (i = 0; i < ARRAY_SIZE(qperf_names); i++)
232		seq_printf(m, "%26s:\t%u\n",
233			   qperf_names[i], *(stat + i));
234	return 0;
235}
236
237static ssize_t qperf_seq_write(struct file *file, const char __user *ubuf,
238			       size_t count, loff_t *off)
239{
240	struct seq_file *seq = file->private_data;
241	struct qdio_irq *irq_ptr = seq->private;
242	struct qdio_q *q;
243	unsigned long val;
244	int ret, i;
245
246	if (!irq_ptr)
247		return 0;
248
249	ret = kstrtoul_from_user(ubuf, count, 10, &val);
250	if (ret)
251		return ret;
252
253	switch (val) {
254	case 0:
255		irq_ptr->perf_stat_enabled = 0;
256		memset(&irq_ptr->perf_stat, 0, sizeof(irq_ptr->perf_stat));
257		for_each_input_queue(irq_ptr, q, i)
258			memset(&q->q_stats, 0, sizeof(q->q_stats));
259		for_each_output_queue(irq_ptr, q, i)
260			memset(&q->q_stats, 0, sizeof(q->q_stats));
261		break;
262	case 1:
263		irq_ptr->perf_stat_enabled = 1;
264		break;
265	}
266	return count;
267}
268
269static int qperf_seq_open(struct inode *inode, struct file *filp)
270{
271	return single_open(filp, qperf_show,
272			   file_inode(filp)->i_private);
273}
274
275static const struct file_operations debugfs_perf_fops = {
276	.owner	 = THIS_MODULE,
277	.open	 = qperf_seq_open,
278	.read	 = seq_read,
279	.write	 = qperf_seq_write,
280	.llseek  = seq_lseek,
281	.release = single_release,
282};
283
284static void setup_debugfs_entry(struct dentry *parent, struct qdio_q *q)
285{
286	char name[QDIO_DEBUGFS_NAME_LEN];
287
288	snprintf(name, QDIO_DEBUGFS_NAME_LEN, "%s_%d",
289		 q->is_input_q ? "input" : "output",
290		 q->nr);
291	debugfs_create_file(name, 0444, parent, q, &qstat_fops);
 
 
 
292}
293
294void qdio_setup_debug_entries(struct qdio_irq *irq_ptr)
295{
296	struct qdio_q *q;
297	int i;
298
299	irq_ptr->debugfs_dev = debugfs_create_dir(dev_name(&irq_ptr->cdev->dev),
300						  debugfs_root);
301	debugfs_create_file("statistics", S_IFREG | S_IRUGO | S_IWUSR,
302			    irq_ptr->debugfs_dev, irq_ptr, &debugfs_perf_fops);
303	debugfs_create_file("ssqd", 0444, irq_ptr->debugfs_dev, irq_ptr->cdev,
304			    &ssqd_fops);
 
 
 
 
 
305
306	for_each_input_queue(irq_ptr, q, i)
307		setup_debugfs_entry(irq_ptr->debugfs_dev, q);
308	for_each_output_queue(irq_ptr, q, i)
309		setup_debugfs_entry(irq_ptr->debugfs_dev, q);
310}
311
312void qdio_shutdown_debug_entries(struct qdio_irq *irq_ptr)
313{
314	debugfs_remove_recursive(irq_ptr->debugfs_dev);
 
 
 
 
 
 
 
 
315}
316
317int __init qdio_debug_init(void)
318{
319	debugfs_root = debugfs_create_dir("qdio", NULL);
320
321	qdio_dbf_setup = debug_register("qdio_setup", 16, 1, 16);
322	debug_register_view(qdio_dbf_setup, &debug_hex_ascii_view);
323	debug_set_level(qdio_dbf_setup, DBF_INFO);
324	DBF_EVENT("dbf created\n");
325
326	qdio_dbf_error = debug_register("qdio_error", 4, 1, 16);
327	debug_register_view(qdio_dbf_error, &debug_hex_ascii_view);
328	debug_set_level(qdio_dbf_error, DBF_INFO);
329	DBF_ERROR("dbf created\n");
330	return 0;
331}
332
333void qdio_debug_exit(void)
334{
335	qdio_clear_dbf_list();
336	debugfs_remove_recursive(debugfs_root);
337	debug_unregister(qdio_dbf_setup);
338	debug_unregister(qdio_dbf_error);
 
339}