]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/s390/cio/qdio_debug.c
bluetooth: kill unused fops field in struct bt_sock_list
[mirror_ubuntu-artful-kernel.git] / drivers / s390 / cio / qdio_debug.c
CommitLineData
779e6e1c 1/*
a53c8fab 2 * Copyright IBM Corp. 2008, 2009
779e6e1c
JG
3 *
4 * Author: Jan Glauber (jang@linux.vnet.ibm.com)
5 */
779e6e1c
JG
6#include <linux/seq_file.h>
7#include <linux/debugfs.h>
3a4c5d59
HC
8#include <linux/uaccess.h>
9#include <linux/export.h>
779e6e1c
JG
10#include <asm/debug.h>
11#include "qdio_debug.h"
12#include "qdio.h"
13
14debug_info_t *qdio_dbf_setup;
22f99347 15debug_info_t *qdio_dbf_error;
779e6e1c
JG
16
17static struct dentry *debugfs_root;
3f09bb89 18#define QDIO_DEBUGFS_NAME_LEN 10
779e6e1c 19
22f99347
JG
20void qdio_allocate_dbf(struct qdio_initialize *init_data,
21 struct qdio_irq *irq_ptr)
779e6e1c 22{
22f99347
JG
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));
22f99347
JG
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");
779e6e1c
JG
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
a2b86019
JG
57 seq_printf(m, "Timestamp: %Lx Last AI: %Lx\n",
58 q->timestamp, last_ai_time);
59 seq_printf(m, "nr_used: %d ftc: %d last_move: %d\n",
60 atomic_read(&q->nr_buf_used),
d36deae7
JG
61 q->first_to_check, q->last_move);
62 if (q->is_input_q) {
63 seq_printf(m, "polling: %d ack start: %d ack count: %d\n",
64 q->u.in.polling, q->u.in.ack_start,
65 q->u.in.ack_count);
a2b86019
JG
66 seq_printf(m, "DSCI: %d IRQs disabled: %u\n",
67 *(u32 *)q->irq_ptr->dsci,
d36deae7
JG
68 test_bit(QDIO_QUEUE_IRQS_DISABLED,
69 &q->u.in.queue_irq_state));
70 }
d307297f 71 seq_printf(m, "SBAL states:\n");
50f769df 72 seq_printf(m, "|0 |8 |16 |24 |32 |40 |48 |56 63|\n");
779e6e1c 73
779e6e1c 74 for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) {
60b5df2f 75 debug_get_buf_state(q, i, &state);
779e6e1c
JG
76 switch (state) {
77 case SLSB_P_INPUT_NOT_INIT:
78 case SLSB_P_OUTPUT_NOT_INIT:
79 seq_printf(m, "N");
80 break;
104ea556 81 case SLSB_P_OUTPUT_PENDING:
82 seq_printf(m, "P");
83 break;
779e6e1c
JG
84 case SLSB_P_INPUT_PRIMED:
85 case SLSB_CU_OUTPUT_PRIMED:
86 seq_printf(m, "+");
87 break;
88 case SLSB_P_INPUT_ACK:
89 seq_printf(m, "A");
90 break;
91 case SLSB_P_INPUT_ERROR:
92 case SLSB_P_OUTPUT_ERROR:
93 seq_printf(m, "x");
94 break;
95 case SLSB_CU_INPUT_EMPTY:
96 case SLSB_P_OUTPUT_EMPTY:
97 seq_printf(m, "-");
98 break;
99 case SLSB_P_INPUT_HALTED:
100 case SLSB_P_OUTPUT_HALTED:
101 seq_printf(m, ".");
102 break;
103 default:
104 seq_printf(m, "?");
105 }
106 if (i == 63)
107 seq_printf(m, "\n");
108 }
109 seq_printf(m, "\n");
50f769df 110 seq_printf(m, "|64 |72 |80 |88 |96 |104 |112 | 127|\n");
d307297f
JG
111
112 seq_printf(m, "\nSBAL statistics:");
113 if (!q->irq_ptr->perf_stat_enabled) {
114 seq_printf(m, " disabled\n");
115 return 0;
116 }
117
118 seq_printf(m, "\n1 2.. 4.. 8.. "
119 "16.. 32.. 64.. 127\n");
120 for (i = 0; i < ARRAY_SIZE(q->q_stats.nr_sbals); i++)
121 seq_printf(m, "%-10u ", q->q_stats.nr_sbals[i]);
122 seq_printf(m, "\nError NOP Total\n%-10u %-10u %-10u\n\n",
123 q->q_stats.nr_sbal_error, q->q_stats.nr_sbal_nop,
124 q->q_stats.nr_sbal_total);
779e6e1c
JG
125 return 0;
126}
127
779e6e1c
JG
128static int qstat_seq_open(struct inode *inode, struct file *filp)
129{
130 return single_open(filp, qstat_show,
496ad9aa 131 file_inode(filp)->i_private);
779e6e1c
JG
132}
133
828c0950 134static const struct file_operations debugfs_fops = {
779e6e1c
JG
135 .owner = THIS_MODULE,
136 .open = qstat_seq_open,
137 .read = seq_read,
779e6e1c
JG
138 .llseek = seq_lseek,
139 .release = single_release,
140};
141
6486cda6
JG
142static char *qperf_names[] = {
143 "Assumed adapter interrupts",
144 "QDIO interrupts",
145 "Requested PCIs",
146 "Inbound tasklet runs",
147 "Inbound tasklet resched",
148 "Inbound tasklet resched2",
149 "Outbound tasklet runs",
150 "SIGA read",
151 "SIGA write",
152 "SIGA sync",
153 "Inbound calls",
154 "Inbound handler",
155 "Inbound stop_polling",
156 "Inbound queue full",
157 "Outbound calls",
158 "Outbound handler",
0195843b 159 "Outbound queue full",
6486cda6
JG
160 "Outbound fast_requeue",
161 "Outbound target_full",
162 "QEBSM eqbs",
163 "QEBSM eqbs partial",
164 "QEBSM sqbs",
d36deae7
JG
165 "QEBSM sqbs partial",
166 "Discarded interrupts"
6486cda6
JG
167};
168
169static int qperf_show(struct seq_file *m, void *v)
170{
171 struct qdio_irq *irq_ptr = m->private;
172 unsigned int *stat;
173 int i;
174
175 if (!irq_ptr)
176 return 0;
177 if (!irq_ptr->perf_stat_enabled) {
178 seq_printf(m, "disabled\n");
179 return 0;
180 }
181 stat = (unsigned int *)&irq_ptr->perf_stat;
182
183 for (i = 0; i < ARRAY_SIZE(qperf_names); i++)
184 seq_printf(m, "%26s:\t%u\n",
185 qperf_names[i], *(stat + i));
186 return 0;
187}
188
189static ssize_t qperf_seq_write(struct file *file, const char __user *ubuf,
190 size_t count, loff_t *off)
191{
192 struct seq_file *seq = file->private_data;
193 struct qdio_irq *irq_ptr = seq->private;
d307297f 194 struct qdio_q *q;
6486cda6 195 unsigned long val;
d307297f 196 int ret, i;
6486cda6
JG
197
198 if (!irq_ptr)
199 return 0;
af6df871
PH
200
201 ret = kstrtoul_from_user(ubuf, count, 10, &val);
202 if (ret)
6486cda6
JG
203 return ret;
204
205 switch (val) {
206 case 0:
207 irq_ptr->perf_stat_enabled = 0;
208 memset(&irq_ptr->perf_stat, 0, sizeof(irq_ptr->perf_stat));
d307297f
JG
209 for_each_input_queue(irq_ptr, q, i)
210 memset(&q->q_stats, 0, sizeof(q->q_stats));
211 for_each_output_queue(irq_ptr, q, i)
212 memset(&q->q_stats, 0, sizeof(q->q_stats));
6486cda6
JG
213 break;
214 case 1:
215 irq_ptr->perf_stat_enabled = 1;
216 break;
217 }
218 return count;
219}
220
221static int qperf_seq_open(struct inode *inode, struct file *filp)
222{
223 return single_open(filp, qperf_show,
496ad9aa 224 file_inode(filp)->i_private);
6486cda6
JG
225}
226
227static struct file_operations debugfs_perf_fops = {
228 .owner = THIS_MODULE,
229 .open = qperf_seq_open,
230 .read = seq_read,
231 .write = qperf_seq_write,
232 .llseek = seq_lseek,
233 .release = single_release,
234};
aa2383f8
SR
235
236static void setup_debugfs_entry(struct qdio_q *q)
779e6e1c 237{
2c780914 238 char name[QDIO_DEBUGFS_NAME_LEN];
779e6e1c 239
3f09bb89 240 snprintf(name, QDIO_DEBUGFS_NAME_LEN, "%s_%d",
2c780914
JG
241 q->is_input_q ? "input" : "output",
242 q->nr);
3f09bb89
JG
243 q->debugfs_q = debugfs_create_file(name, S_IFREG | S_IRUGO | S_IWUSR,
244 q->irq_ptr->debugfs_dev, q, &debugfs_fops);
245 if (IS_ERR(q->debugfs_q))
246 q->debugfs_q = NULL;
779e6e1c
JG
247}
248
249void qdio_setup_debug_entries(struct qdio_irq *irq_ptr, struct ccw_device *cdev)
250{
251 struct qdio_q *q;
252 int i;
253
3f09bb89
JG
254 irq_ptr->debugfs_dev = debugfs_create_dir(dev_name(&cdev->dev),
255 debugfs_root);
256 if (IS_ERR(irq_ptr->debugfs_dev))
257 irq_ptr->debugfs_dev = NULL;
6486cda6
JG
258
259 irq_ptr->debugfs_perf = debugfs_create_file("statistics",
260 S_IFREG | S_IRUGO | S_IWUSR,
261 irq_ptr->debugfs_dev, irq_ptr,
262 &debugfs_perf_fops);
263 if (IS_ERR(irq_ptr->debugfs_perf))
264 irq_ptr->debugfs_perf = NULL;
265
779e6e1c 266 for_each_input_queue(irq_ptr, q, i)
aa2383f8 267 setup_debugfs_entry(q);
779e6e1c 268 for_each_output_queue(irq_ptr, q, i)
aa2383f8 269 setup_debugfs_entry(q);
779e6e1c
JG
270}
271
aa2383f8 272void qdio_shutdown_debug_entries(struct qdio_irq *irq_ptr)
779e6e1c
JG
273{
274 struct qdio_q *q;
275 int i;
276
779e6e1c 277 for_each_input_queue(irq_ptr, q, i)
3f09bb89 278 debugfs_remove(q->debugfs_q);
779e6e1c 279 for_each_output_queue(irq_ptr, q, i)
3f09bb89 280 debugfs_remove(q->debugfs_q);
6486cda6 281 debugfs_remove(irq_ptr->debugfs_perf);
3f09bb89 282 debugfs_remove(irq_ptr->debugfs_dev);
779e6e1c
JG
283}
284
285int __init qdio_debug_init(void)
286{
3f09bb89 287 debugfs_root = debugfs_create_dir("qdio", NULL);
22f99347
JG
288
289 qdio_dbf_setup = debug_register("qdio_setup", 16, 1, 16);
290 debug_register_view(qdio_dbf_setup, &debug_hex_ascii_view);
291 debug_set_level(qdio_dbf_setup, DBF_INFO);
292 DBF_EVENT("dbf created\n");
293
294 qdio_dbf_error = debug_register("qdio_error", 4, 1, 16);
295 debug_register_view(qdio_dbf_error, &debug_hex_ascii_view);
296 debug_set_level(qdio_dbf_error, DBF_INFO);
297 DBF_ERROR("dbf created\n");
298 return 0;
779e6e1c
JG
299}
300
301void qdio_debug_exit(void)
302{
303 debugfs_remove(debugfs_root);
22f99347
JG
304 if (qdio_dbf_setup)
305 debug_unregister(qdio_dbf_setup);
306 if (qdio_dbf_error)
307 debug_unregister(qdio_dbf_error);
779e6e1c 308}