include: replace linux/module.h with "struct module" wherever possible
[linux-2.6/next.git] / drivers / s390 / cio / qdio_debug.c
blobbf78bad5891926c38c84a936aceffc8af3205b9c
1 /*
2 * drivers/s390/cio/qdio_debug.c
4 * Copyright IBM Corp. 2008,2009
6 * Author: Jan Glauber (jang@linux.vnet.ibm.com)
7 */
8 #include <linux/seq_file.h>
9 #include <linux/debugfs.h>
10 #include <linux/uaccess.h>
11 #include <linux/export.h>
12 #include <asm/debug.h>
13 #include "qdio_debug.h"
14 #include "qdio.h"
16 debug_info_t *qdio_dbf_setup;
17 debug_info_t *qdio_dbf_error;
19 static struct dentry *debugfs_root;
20 #define QDIO_DEBUGFS_NAME_LEN 10
22 void qdio_allocate_dbf(struct qdio_initialize *init_data,
23 struct qdio_irq *irq_ptr)
25 char text[20];
27 DBF_EVENT("qfmt:%1d", init_data->q_format);
28 DBF_HEX(init_data->adapter_name, 8);
29 DBF_EVENT("qpff%4x", init_data->qib_param_field_format);
30 DBF_HEX(&init_data->qib_param_field, sizeof(void *));
31 DBF_HEX(&init_data->input_slib_elements, sizeof(void *));
32 DBF_HEX(&init_data->output_slib_elements, sizeof(void *));
33 DBF_EVENT("niq:%1d noq:%1d", init_data->no_input_qs,
34 init_data->no_output_qs);
35 DBF_HEX(&init_data->input_handler, sizeof(void *));
36 DBF_HEX(&init_data->output_handler, sizeof(void *));
37 DBF_HEX(&init_data->int_parm, sizeof(long));
38 DBF_HEX(&init_data->input_sbal_addr_array, sizeof(void *));
39 DBF_HEX(&init_data->output_sbal_addr_array, sizeof(void *));
40 DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr);
42 /* allocate trace view for the interface */
43 snprintf(text, 20, "qdio_%s", dev_name(&init_data->cdev->dev));
44 irq_ptr->debug_area = debug_register(text, 2, 1, 16);
45 debug_register_view(irq_ptr->debug_area, &debug_hex_ascii_view);
46 debug_set_level(irq_ptr->debug_area, DBF_WARN);
47 DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf created");
50 static int qstat_show(struct seq_file *m, void *v)
52 unsigned char state;
53 struct qdio_q *q = m->private;
54 int i;
56 if (!q)
57 return 0;
59 seq_printf(m, "DSCI: %d nr_used: %d\n",
60 *(u32 *)q->irq_ptr->dsci, atomic_read(&q->nr_buf_used));
61 seq_printf(m, "ftc: %d last_move: %d\n",
62 q->first_to_check, q->last_move);
63 if (q->is_input_q) {
64 seq_printf(m, "polling: %d ack start: %d ack count: %d\n",
65 q->u.in.polling, q->u.in.ack_start,
66 q->u.in.ack_count);
67 seq_printf(m, "IRQs disabled: %u\n",
68 test_bit(QDIO_QUEUE_IRQS_DISABLED,
69 &q->u.in.queue_irq_state));
71 seq_printf(m, "SBAL states:\n");
72 seq_printf(m, "|0 |8 |16 |24 |32 |40 |48 |56 63|\n");
74 for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) {
75 debug_get_buf_state(q, i, &state);
76 switch (state) {
77 case SLSB_P_INPUT_NOT_INIT:
78 case SLSB_P_OUTPUT_NOT_INIT:
79 seq_printf(m, "N");
80 break;
81 case SLSB_P_INPUT_PRIMED:
82 case SLSB_CU_OUTPUT_PRIMED:
83 seq_printf(m, "+");
84 break;
85 case SLSB_P_INPUT_ACK:
86 seq_printf(m, "A");
87 break;
88 case SLSB_P_INPUT_ERROR:
89 case SLSB_P_OUTPUT_ERROR:
90 seq_printf(m, "x");
91 break;
92 case SLSB_CU_INPUT_EMPTY:
93 case SLSB_P_OUTPUT_EMPTY:
94 seq_printf(m, "-");
95 break;
96 case SLSB_P_INPUT_HALTED:
97 case SLSB_P_OUTPUT_HALTED:
98 seq_printf(m, ".");
99 break;
100 default:
101 seq_printf(m, "?");
103 if (i == 63)
104 seq_printf(m, "\n");
106 seq_printf(m, "\n");
107 seq_printf(m, "|64 |72 |80 |88 |96 |104 |112 | 127|\n");
109 seq_printf(m, "\nSBAL statistics:");
110 if (!q->irq_ptr->perf_stat_enabled) {
111 seq_printf(m, " disabled\n");
112 return 0;
115 seq_printf(m, "\n1 2.. 4.. 8.. "
116 "16.. 32.. 64.. 127\n");
117 for (i = 0; i < ARRAY_SIZE(q->q_stats.nr_sbals); i++)
118 seq_printf(m, "%-10u ", q->q_stats.nr_sbals[i]);
119 seq_printf(m, "\nError NOP Total\n%-10u %-10u %-10u\n\n",
120 q->q_stats.nr_sbal_error, q->q_stats.nr_sbal_nop,
121 q->q_stats.nr_sbal_total);
122 return 0;
125 static int qstat_seq_open(struct inode *inode, struct file *filp)
127 return single_open(filp, qstat_show,
128 filp->f_path.dentry->d_inode->i_private);
131 static const struct file_operations debugfs_fops = {
132 .owner = THIS_MODULE,
133 .open = qstat_seq_open,
134 .read = seq_read,
135 .llseek = seq_lseek,
136 .release = single_release,
139 static char *qperf_names[] = {
140 "Assumed adapter interrupts",
141 "QDIO interrupts",
142 "Requested PCIs",
143 "Inbound tasklet runs",
144 "Inbound tasklet resched",
145 "Inbound tasklet resched2",
146 "Outbound tasklet runs",
147 "SIGA read",
148 "SIGA write",
149 "SIGA sync",
150 "Inbound calls",
151 "Inbound handler",
152 "Inbound stop_polling",
153 "Inbound queue full",
154 "Outbound calls",
155 "Outbound handler",
156 "Outbound queue full",
157 "Outbound fast_requeue",
158 "Outbound target_full",
159 "QEBSM eqbs",
160 "QEBSM eqbs partial",
161 "QEBSM sqbs",
162 "QEBSM sqbs partial",
163 "Discarded interrupts"
166 static int qperf_show(struct seq_file *m, void *v)
168 struct qdio_irq *irq_ptr = m->private;
169 unsigned int *stat;
170 int i;
172 if (!irq_ptr)
173 return 0;
174 if (!irq_ptr->perf_stat_enabled) {
175 seq_printf(m, "disabled\n");
176 return 0;
178 stat = (unsigned int *)&irq_ptr->perf_stat;
180 for (i = 0; i < ARRAY_SIZE(qperf_names); i++)
181 seq_printf(m, "%26s:\t%u\n",
182 qperf_names[i], *(stat + i));
183 return 0;
186 static ssize_t qperf_seq_write(struct file *file, const char __user *ubuf,
187 size_t count, loff_t *off)
189 struct seq_file *seq = file->private_data;
190 struct qdio_irq *irq_ptr = seq->private;
191 struct qdio_q *q;
192 unsigned long val;
193 int ret, i;
195 if (!irq_ptr)
196 return 0;
198 ret = kstrtoul_from_user(ubuf, count, 10, &val);
199 if (ret)
200 return ret;
202 switch (val) {
203 case 0:
204 irq_ptr->perf_stat_enabled = 0;
205 memset(&irq_ptr->perf_stat, 0, sizeof(irq_ptr->perf_stat));
206 for_each_input_queue(irq_ptr, q, i)
207 memset(&q->q_stats, 0, sizeof(q->q_stats));
208 for_each_output_queue(irq_ptr, q, i)
209 memset(&q->q_stats, 0, sizeof(q->q_stats));
210 break;
211 case 1:
212 irq_ptr->perf_stat_enabled = 1;
213 break;
215 return count;
218 static int qperf_seq_open(struct inode *inode, struct file *filp)
220 return single_open(filp, qperf_show,
221 filp->f_path.dentry->d_inode->i_private);
224 static struct file_operations debugfs_perf_fops = {
225 .owner = THIS_MODULE,
226 .open = qperf_seq_open,
227 .read = seq_read,
228 .write = qperf_seq_write,
229 .llseek = seq_lseek,
230 .release = single_release,
232 static void setup_debugfs_entry(struct qdio_q *q, struct ccw_device *cdev)
234 char name[QDIO_DEBUGFS_NAME_LEN];
236 snprintf(name, QDIO_DEBUGFS_NAME_LEN, "%s_%d",
237 q->is_input_q ? "input" : "output",
238 q->nr);
239 q->debugfs_q = debugfs_create_file(name, S_IFREG | S_IRUGO | S_IWUSR,
240 q->irq_ptr->debugfs_dev, q, &debugfs_fops);
241 if (IS_ERR(q->debugfs_q))
242 q->debugfs_q = NULL;
245 void qdio_setup_debug_entries(struct qdio_irq *irq_ptr, struct ccw_device *cdev)
247 struct qdio_q *q;
248 int i;
250 irq_ptr->debugfs_dev = debugfs_create_dir(dev_name(&cdev->dev),
251 debugfs_root);
252 if (IS_ERR(irq_ptr->debugfs_dev))
253 irq_ptr->debugfs_dev = NULL;
255 irq_ptr->debugfs_perf = debugfs_create_file("statistics",
256 S_IFREG | S_IRUGO | S_IWUSR,
257 irq_ptr->debugfs_dev, irq_ptr,
258 &debugfs_perf_fops);
259 if (IS_ERR(irq_ptr->debugfs_perf))
260 irq_ptr->debugfs_perf = NULL;
262 for_each_input_queue(irq_ptr, q, i)
263 setup_debugfs_entry(q, cdev);
264 for_each_output_queue(irq_ptr, q, i)
265 setup_debugfs_entry(q, cdev);
268 void qdio_shutdown_debug_entries(struct qdio_irq *irq_ptr, struct ccw_device *cdev)
270 struct qdio_q *q;
271 int i;
273 for_each_input_queue(irq_ptr, q, i)
274 debugfs_remove(q->debugfs_q);
275 for_each_output_queue(irq_ptr, q, i)
276 debugfs_remove(q->debugfs_q);
277 debugfs_remove(irq_ptr->debugfs_perf);
278 debugfs_remove(irq_ptr->debugfs_dev);
281 int __init qdio_debug_init(void)
283 debugfs_root = debugfs_create_dir("qdio", NULL);
285 qdio_dbf_setup = debug_register("qdio_setup", 16, 1, 16);
286 debug_register_view(qdio_dbf_setup, &debug_hex_ascii_view);
287 debug_set_level(qdio_dbf_setup, DBF_INFO);
288 DBF_EVENT("dbf created\n");
290 qdio_dbf_error = debug_register("qdio_error", 4, 1, 16);
291 debug_register_view(qdio_dbf_error, &debug_hex_ascii_view);
292 debug_set_level(qdio_dbf_error, DBF_INFO);
293 DBF_ERROR("dbf created\n");
294 return 0;
297 void qdio_debug_exit(void)
299 debugfs_remove(debugfs_root);
300 if (qdio_dbf_setup)
301 debug_unregister(qdio_dbf_setup);
302 if (qdio_dbf_error)
303 debug_unregister(qdio_dbf_error);