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}
v4.17
  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_initialize *init_data,
 62		       struct qdio_irq *irq_ptr)
 63{
 64	char text[QDIO_DBF_NAME_LEN];
 65	struct qdio_dbf_entry *new_entry;
 66
 67	DBF_EVENT("qfmt:%1d", init_data->q_format);
 68	DBF_HEX(init_data->adapter_name, 8);
 69	DBF_EVENT("qpff%4x", init_data->qib_param_field_format);
 70	DBF_HEX(&init_data->qib_param_field, sizeof(void *));
 71	DBF_HEX(&init_data->input_slib_elements, sizeof(void *));
 72	DBF_HEX(&init_data->output_slib_elements, sizeof(void *));
 73	DBF_EVENT("niq:%1d noq:%1d", init_data->no_input_qs,
 74		  init_data->no_output_qs);
 75	DBF_HEX(&init_data->input_handler, sizeof(void *));
 76	DBF_HEX(&init_data->output_handler, sizeof(void *));
 77	DBF_HEX(&init_data->int_parm, sizeof(long));
 78	DBF_HEX(&init_data->input_sbal_addr_array, sizeof(void *));
 79	DBF_HEX(&init_data->output_sbal_addr_array, sizeof(void *));
 80	DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr);
 81
 82	/* allocate trace view for the interface */
 83	snprintf(text, QDIO_DBF_NAME_LEN, "qdio_%s",
 84					dev_name(&init_data->cdev->dev));
 85	irq_ptr->debug_area = qdio_get_dbf_entry(text);
 86	if (irq_ptr->debug_area)
 87		DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf reused");
 88	else {
 89		irq_ptr->debug_area = debug_register(text, 2, 1, 16);
 90		if (!irq_ptr->debug_area)
 91			return -ENOMEM;
 92		if (debug_register_view(irq_ptr->debug_area,
 93						&debug_hex_ascii_view)) {
 94			debug_unregister(irq_ptr->debug_area);
 95			return -ENOMEM;
 96		}
 97		debug_set_level(irq_ptr->debug_area, DBF_WARN);
 98		DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf created");
 99		new_entry = kzalloc(sizeof(struct qdio_dbf_entry), GFP_KERNEL);
100		if (!new_entry) {
101			debug_unregister(irq_ptr->debug_area);
102			return -ENOMEM;
103		}
104		strlcpy(new_entry->dbf_name, text, QDIO_DBF_NAME_LEN);
105		new_entry->dbf_info = irq_ptr->debug_area;
106		mutex_lock(&qdio_dbf_list_mutex);
107		list_add(&new_entry->dbf_list, &qdio_dbf_list);
108		mutex_unlock(&qdio_dbf_list_mutex);
109	}
110	return 0;
111}
112
113static int qstat_show(struct seq_file *m, void *v)
114{
115	unsigned char state;
116	struct qdio_q *q = m->private;
117	int i;
118
119	if (!q)
120		return 0;
121
122	seq_printf(m, "Timestamp: %Lx  Last AI: %Lx\n",
123		   q->timestamp, last_ai_time);
124	seq_printf(m, "nr_used: %d  ftc: %d  last_move: %d\n",
125		   atomic_read(&q->nr_buf_used),
126		   q->first_to_check, q->last_move);
127	if (q->is_input_q) {
128		seq_printf(m, "polling: %d  ack start: %d  ack count: %d\n",
129			   q->u.in.polling, q->u.in.ack_start,
130			   q->u.in.ack_count);
131		seq_printf(m, "DSCI: %d   IRQs disabled: %u\n",
132			   *(u32 *)q->irq_ptr->dsci,
133			   test_bit(QDIO_QUEUE_IRQS_DISABLED,
134			   &q->u.in.queue_irq_state));
135	}
136	seq_printf(m, "SBAL states:\n");
137	seq_printf(m, "|0      |8      |16     |24     |32     |40     |48     |56  63|\n");
138
139	for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) {
140		debug_get_buf_state(q, i, &state);
141		switch (state) {
142		case SLSB_P_INPUT_NOT_INIT:
143		case SLSB_P_OUTPUT_NOT_INIT:
144			seq_printf(m, "N");
145			break;
146		case SLSB_P_OUTPUT_PENDING:
147			seq_printf(m, "P");
148			break;
149		case SLSB_P_INPUT_PRIMED:
150		case SLSB_CU_OUTPUT_PRIMED:
151			seq_printf(m, "+");
152			break;
153		case SLSB_P_INPUT_ACK:
154			seq_printf(m, "A");
155			break;
156		case SLSB_P_INPUT_ERROR:
157		case SLSB_P_OUTPUT_ERROR:
158			seq_printf(m, "x");
159			break;
160		case SLSB_CU_INPUT_EMPTY:
161		case SLSB_P_OUTPUT_EMPTY:
162			seq_printf(m, "-");
163			break;
164		case SLSB_P_INPUT_HALTED:
165		case SLSB_P_OUTPUT_HALTED:
166			seq_printf(m, ".");
167			break;
168		default:
169			seq_printf(m, "?");
170		}
171		if (i == 63)
172			seq_printf(m, "\n");
173	}
174	seq_printf(m, "\n");
175	seq_printf(m, "|64     |72     |80     |88     |96     |104    |112    |   127|\n");
176
177	seq_printf(m, "\nSBAL statistics:");
178	if (!q->irq_ptr->perf_stat_enabled) {
179		seq_printf(m, " disabled\n");
180		return 0;
181	}
182
183	seq_printf(m, "\n1          2..        4..        8..        "
184		   "16..       32..       64..       127\n");
185	for (i = 0; i < ARRAY_SIZE(q->q_stats.nr_sbals); i++)
186		seq_printf(m, "%-10u ", q->q_stats.nr_sbals[i]);
187	seq_printf(m, "\nError      NOP        Total\n%-10u %-10u %-10u\n\n",
188		   q->q_stats.nr_sbal_error, q->q_stats.nr_sbal_nop,
189		   q->q_stats.nr_sbal_total);
190	return 0;
191}
192
193static int qstat_seq_open(struct inode *inode, struct file *filp)
194{
195	return single_open(filp, qstat_show,
196			   file_inode(filp)->i_private);
197}
198
199static const struct file_operations debugfs_fops = {
200	.owner	 = THIS_MODULE,
201	.open	 = qstat_seq_open,
202	.read	 = seq_read,
203	.llseek  = seq_lseek,
204	.release = single_release,
205};
206
207static char *qperf_names[] = {
208	"Assumed adapter interrupts",
209	"QDIO interrupts",
210	"Requested PCIs",
211	"Inbound tasklet runs",
212	"Inbound tasklet resched",
213	"Inbound tasklet resched2",
214	"Outbound tasklet runs",
215	"SIGA read",
216	"SIGA write",
217	"SIGA sync",
218	"Inbound calls",
219	"Inbound handler",
220	"Inbound stop_polling",
221	"Inbound queue full",
222	"Outbound calls",
223	"Outbound handler",
224	"Outbound queue full",
225	"Outbound fast_requeue",
226	"Outbound target_full",
227	"QEBSM eqbs",
228	"QEBSM eqbs partial",
229	"QEBSM sqbs",
230	"QEBSM sqbs partial",
231	"Discarded interrupts"
232};
233
234static int qperf_show(struct seq_file *m, void *v)
235{
236	struct qdio_irq *irq_ptr = m->private;
237	unsigned int *stat;
238	int i;
239
240	if (!irq_ptr)
241		return 0;
242	if (!irq_ptr->perf_stat_enabled) {
243		seq_printf(m, "disabled\n");
244		return 0;
245	}
246	stat = (unsigned int *)&irq_ptr->perf_stat;
247
248	for (i = 0; i < ARRAY_SIZE(qperf_names); i++)
249		seq_printf(m, "%26s:\t%u\n",
250			   qperf_names[i], *(stat + i));
251	return 0;
252}
253
254static ssize_t qperf_seq_write(struct file *file, const char __user *ubuf,
255			       size_t count, loff_t *off)
256{
257	struct seq_file *seq = file->private_data;
258	struct qdio_irq *irq_ptr = seq->private;
259	struct qdio_q *q;
260	unsigned long val;
261	int ret, i;
262
263	if (!irq_ptr)
264		return 0;
265
266	ret = kstrtoul_from_user(ubuf, count, 10, &val);
267	if (ret)
268		return ret;
269
270	switch (val) {
271	case 0:
272		irq_ptr->perf_stat_enabled = 0;
273		memset(&irq_ptr->perf_stat, 0, sizeof(irq_ptr->perf_stat));
274		for_each_input_queue(irq_ptr, q, i)
275			memset(&q->q_stats, 0, sizeof(q->q_stats));
276		for_each_output_queue(irq_ptr, q, i)
277			memset(&q->q_stats, 0, sizeof(q->q_stats));
278		break;
279	case 1:
280		irq_ptr->perf_stat_enabled = 1;
281		break;
282	}
283	return count;
284}
285
286static int qperf_seq_open(struct inode *inode, struct file *filp)
287{
288	return single_open(filp, qperf_show,
289			   file_inode(filp)->i_private);
290}
291
292static const struct file_operations debugfs_perf_fops = {
293	.owner	 = THIS_MODULE,
294	.open	 = qperf_seq_open,
295	.read	 = seq_read,
296	.write	 = qperf_seq_write,
297	.llseek  = seq_lseek,
298	.release = single_release,
299};
300
301static void setup_debugfs_entry(struct qdio_q *q)
302{
303	char name[QDIO_DEBUGFS_NAME_LEN];
304
305	snprintf(name, QDIO_DEBUGFS_NAME_LEN, "%s_%d",
306		 q->is_input_q ? "input" : "output",
307		 q->nr);
308	q->debugfs_q = debugfs_create_file(name, S_IFREG | S_IRUGO | S_IWUSR,
309				q->irq_ptr->debugfs_dev, q, &debugfs_fops);
310	if (IS_ERR(q->debugfs_q))
311		q->debugfs_q = NULL;
312}
313
314void qdio_setup_debug_entries(struct qdio_irq *irq_ptr, struct ccw_device *cdev)
315{
316	struct qdio_q *q;
317	int i;
318
319	irq_ptr->debugfs_dev = debugfs_create_dir(dev_name(&cdev->dev),
320						  debugfs_root);
321	if (IS_ERR(irq_ptr->debugfs_dev))
322		irq_ptr->debugfs_dev = NULL;
323
324	irq_ptr->debugfs_perf = debugfs_create_file("statistics",
325				S_IFREG | S_IRUGO | S_IWUSR,
326				irq_ptr->debugfs_dev, irq_ptr,
327				&debugfs_perf_fops);
328	if (IS_ERR(irq_ptr->debugfs_perf))
329		irq_ptr->debugfs_perf = NULL;
330
331	for_each_input_queue(irq_ptr, q, i)
332		setup_debugfs_entry(q);
333	for_each_output_queue(irq_ptr, q, i)
334		setup_debugfs_entry(q);
335}
336
337void qdio_shutdown_debug_entries(struct qdio_irq *irq_ptr)
338{
339	struct qdio_q *q;
340	int i;
341
342	for_each_input_queue(irq_ptr, q, i)
343		debugfs_remove(q->debugfs_q);
344	for_each_output_queue(irq_ptr, q, i)
345		debugfs_remove(q->debugfs_q);
346	debugfs_remove(irq_ptr->debugfs_perf);
347	debugfs_remove(irq_ptr->debugfs_dev);
348}
349
350int __init qdio_debug_init(void)
351{
352	debugfs_root = debugfs_create_dir("qdio", NULL);
353
354	qdio_dbf_setup = debug_register("qdio_setup", 16, 1, 16);
355	debug_register_view(qdio_dbf_setup, &debug_hex_ascii_view);
356	debug_set_level(qdio_dbf_setup, DBF_INFO);
357	DBF_EVENT("dbf created\n");
358
359	qdio_dbf_error = debug_register("qdio_error", 4, 1, 16);
360	debug_register_view(qdio_dbf_error, &debug_hex_ascii_view);
361	debug_set_level(qdio_dbf_error, DBF_INFO);
362	DBF_ERROR("dbf created\n");
363	return 0;
364}
365
366void qdio_debug_exit(void)
367{
368	qdio_clear_dbf_list();
369	debugfs_remove(debugfs_root);
370	debug_unregister(qdio_dbf_setup);
371	debug_unregister(qdio_dbf_error);
 
 
372}