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}
v5.9
  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		strlcpy(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: %Lx  Last AI: %Lx\n",
109		   q->timestamp, last_ai_time);
110	seq_printf(m, "nr_used: %d  ftc: %d\n",
111		   atomic_read(&q->nr_buf_used), q->first_to_check);
112	if (q->is_input_q) {
113		seq_printf(m, "batch start: %u  batch count: %u\n",
114			   q->u.in.batch_start, q->u.in.batch_count);
115		seq_printf(m, "DSCI: %x   IRQs disabled: %u\n",
116			   *(u8 *)q->irq_ptr->dsci,
117			   test_bit(QDIO_IRQ_DISABLED,
118				    &q->irq_ptr->poll_state));
119	}
120	seq_printf(m, "SBAL states:\n");
121	seq_printf(m, "|0      |8      |16     |24     |32     |40     |48     |56  63|\n");
122
123	for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) {
124		debug_get_buf_state(q, i, &state);
125		switch (state) {
126		case SLSB_P_INPUT_NOT_INIT:
127		case SLSB_P_OUTPUT_NOT_INIT:
128			seq_printf(m, "N");
129			break;
130		case SLSB_P_OUTPUT_PENDING:
131			seq_printf(m, "P");
132			break;
133		case SLSB_P_INPUT_PRIMED:
134		case SLSB_CU_OUTPUT_PRIMED:
135			seq_printf(m, "+");
136			break;
137		case SLSB_P_INPUT_ACK:
138			seq_printf(m, "A");
139			break;
140		case SLSB_P_INPUT_ERROR:
141		case SLSB_P_OUTPUT_ERROR:
142			seq_printf(m, "x");
143			break;
144		case SLSB_CU_INPUT_EMPTY:
145		case SLSB_P_OUTPUT_EMPTY:
146			seq_printf(m, "-");
147			break;
148		case SLSB_P_INPUT_HALTED:
149		case SLSB_P_OUTPUT_HALTED:
150			seq_printf(m, ".");
151			break;
152		default:
153			seq_printf(m, "?");
154		}
155		if (i == 63)
156			seq_printf(m, "\n");
157	}
158	seq_printf(m, "\n");
159	seq_printf(m, "|64     |72     |80     |88     |96     |104    |112    |   127|\n");
160
161	seq_printf(m, "\nSBAL statistics:");
162	if (!q->irq_ptr->perf_stat_enabled) {
163		seq_printf(m, " disabled\n");
164		return 0;
165	}
166
167	seq_printf(m, "\n1          2..        4..        8..        "
168		   "16..       32..       64..       128\n");
169	for (i = 0; i < ARRAY_SIZE(q->q_stats.nr_sbals); i++)
170		seq_printf(m, "%-10u ", q->q_stats.nr_sbals[i]);
171	seq_printf(m, "\nError      NOP        Total\n%-10u %-10u %-10u\n\n",
172		   q->q_stats.nr_sbal_error, q->q_stats.nr_sbal_nop,
173		   q->q_stats.nr_sbal_total);
174	return 0;
175}
176
177DEFINE_SHOW_ATTRIBUTE(qstat);
178
179static int ssqd_show(struct seq_file *m, void *v)
180{
181	struct ccw_device *cdev = m->private;
182	struct qdio_ssqd_desc ssqd;
183	int rc;
184
185	rc = qdio_get_ssqd_desc(cdev, &ssqd);
186	if (rc)
187		return rc;
188
189	seq_hex_dump(m, "", DUMP_PREFIX_NONE, 16, 4, &ssqd, sizeof(ssqd),
190		     false);
191	return 0;
192}
193
194DEFINE_SHOW_ATTRIBUTE(ssqd);
 
 
 
 
 
 
195
196static char *qperf_names[] = {
197	"Assumed adapter interrupts",
198	"QDIO interrupts",
199	"Requested PCIs",
200	"Inbound tasklet runs",
201	"Inbound tasklet resched",
202	"Inbound tasklet resched2",
203	"Outbound tasklet runs",
204	"SIGA read",
205	"SIGA write",
206	"SIGA sync",
207	"Inbound calls",
208	"Inbound handler",
209	"Inbound stop_polling",
210	"Inbound queue full",
211	"Outbound calls",
212	"Outbound handler",
213	"Outbound queue full",
214	"Outbound fast_requeue",
215	"Outbound target_full",
216	"QEBSM eqbs",
217	"QEBSM eqbs partial",
218	"QEBSM sqbs",
219	"QEBSM sqbs partial",
220	"Discarded interrupts"
221};
222
223static int qperf_show(struct seq_file *m, void *v)
224{
225	struct qdio_irq *irq_ptr = m->private;
226	unsigned int *stat;
227	int i;
228
229	if (!irq_ptr)
230		return 0;
231	if (!irq_ptr->perf_stat_enabled) {
232		seq_printf(m, "disabled\n");
233		return 0;
234	}
235	stat = (unsigned int *)&irq_ptr->perf_stat;
236
237	for (i = 0; i < ARRAY_SIZE(qperf_names); i++)
238		seq_printf(m, "%26s:\t%u\n",
239			   qperf_names[i], *(stat + i));
240	return 0;
241}
242
243static ssize_t qperf_seq_write(struct file *file, const char __user *ubuf,
244			       size_t count, loff_t *off)
245{
246	struct seq_file *seq = file->private_data;
247	struct qdio_irq *irq_ptr = seq->private;
248	struct qdio_q *q;
249	unsigned long val;
250	int ret, i;
251
252	if (!irq_ptr)
253		return 0;
254
255	ret = kstrtoul_from_user(ubuf, count, 10, &val);
256	if (ret)
257		return ret;
258
259	switch (val) {
260	case 0:
261		irq_ptr->perf_stat_enabled = 0;
262		memset(&irq_ptr->perf_stat, 0, sizeof(irq_ptr->perf_stat));
263		for_each_input_queue(irq_ptr, q, i)
264			memset(&q->q_stats, 0, sizeof(q->q_stats));
265		for_each_output_queue(irq_ptr, q, i)
266			memset(&q->q_stats, 0, sizeof(q->q_stats));
267		break;
268	case 1:
269		irq_ptr->perf_stat_enabled = 1;
270		break;
271	}
272	return count;
273}
274
275static int qperf_seq_open(struct inode *inode, struct file *filp)
276{
277	return single_open(filp, qperf_show,
278			   file_inode(filp)->i_private);
279}
280
281static const struct file_operations debugfs_perf_fops = {
282	.owner	 = THIS_MODULE,
283	.open	 = qperf_seq_open,
284	.read	 = seq_read,
285	.write	 = qperf_seq_write,
286	.llseek  = seq_lseek,
287	.release = single_release,
288};
289
290static void setup_debugfs_entry(struct dentry *parent, struct qdio_q *q)
291{
292	char name[QDIO_DEBUGFS_NAME_LEN];
293
294	snprintf(name, QDIO_DEBUGFS_NAME_LEN, "%s_%d",
295		 q->is_input_q ? "input" : "output",
296		 q->nr);
297	debugfs_create_file(name, 0444, parent, q, &qstat_fops);
 
 
 
298}
299
300void qdio_setup_debug_entries(struct qdio_irq *irq_ptr)
301{
302	struct qdio_q *q;
303	int i;
304
305	irq_ptr->debugfs_dev = debugfs_create_dir(dev_name(&irq_ptr->cdev->dev),
306						  debugfs_root);
307	debugfs_create_file("statistics", S_IFREG | S_IRUGO | S_IWUSR,
308			    irq_ptr->debugfs_dev, irq_ptr, &debugfs_perf_fops);
309	debugfs_create_file("ssqd", 0444, irq_ptr->debugfs_dev, irq_ptr->cdev,
310			    &ssqd_fops);
 
 
 
 
 
311
312	for_each_input_queue(irq_ptr, q, i)
313		setup_debugfs_entry(irq_ptr->debugfs_dev, q);
314	for_each_output_queue(irq_ptr, q, i)
315		setup_debugfs_entry(irq_ptr->debugfs_dev, q);
316}
317
318void qdio_shutdown_debug_entries(struct qdio_irq *irq_ptr)
319{
320	debugfs_remove_recursive(irq_ptr->debugfs_dev);
 
 
 
 
 
 
 
 
321}
322
323int __init qdio_debug_init(void)
324{
325	debugfs_root = debugfs_create_dir("qdio", NULL);
326
327	qdio_dbf_setup = debug_register("qdio_setup", 16, 1, 16);
328	debug_register_view(qdio_dbf_setup, &debug_hex_ascii_view);
329	debug_set_level(qdio_dbf_setup, DBF_INFO);
330	DBF_EVENT("dbf created\n");
331
332	qdio_dbf_error = debug_register("qdio_error", 4, 1, 16);
333	debug_register_view(qdio_dbf_error, &debug_hex_ascii_view);
334	debug_set_level(qdio_dbf_error, DBF_INFO);
335	DBF_ERROR("dbf created\n");
336	return 0;
337}
338
339void qdio_debug_exit(void)
340{
341	qdio_clear_dbf_list();
342	debugfs_remove_recursive(debugfs_root);
343	debug_unregister(qdio_dbf_setup);
344	debug_unregister(qdio_dbf_error);
 
345}