2 * drivers/s390/cio/qdio_debug.c
4 * Copyright IBM Corp. 2008
6 * Author: Jan Glauber (jang@linux.vnet.ibm.com)
8 #include <linux/proc_fs.h>
9 #include <linux/seq_file.h>
10 #include <linux/debugfs.h>
12 #include <asm/debug.h>
13 #include "qdio_debug.h"
16 debug_info_t
*qdio_dbf_setup
;
17 debug_info_t
*qdio_dbf_trace
;
19 static struct dentry
*debugfs_root
;
20 #define MAX_DEBUGFS_QUEUES 32
21 static struct dentry
*debugfs_queues
[MAX_DEBUGFS_QUEUES
] = { NULL
};
22 static DEFINE_MUTEX(debugfs_mutex
);
24 void qdio_allocate_do_dbf(struct qdio_initialize
*init_data
)
28 sprintf(dbf_text
, "qfmt:%x", init_data
->q_format
);
29 QDIO_DBF_TEXT0(0, setup
, dbf_text
);
30 QDIO_DBF_HEX0(0, setup
, init_data
->adapter_name
, 8);
31 sprintf(dbf_text
, "qpff%4x", init_data
->qib_param_field_format
);
32 QDIO_DBF_TEXT0(0, setup
, dbf_text
);
33 QDIO_DBF_HEX0(0, setup
, &init_data
->qib_param_field
, sizeof(void *));
34 QDIO_DBF_HEX0(0, setup
, &init_data
->input_slib_elements
, sizeof(void *));
35 QDIO_DBF_HEX0(0, setup
, &init_data
->output_slib_elements
, sizeof(void *));
36 sprintf(dbf_text
, "niq:%4x", init_data
->no_input_qs
);
37 QDIO_DBF_TEXT0(0, setup
, dbf_text
);
38 sprintf(dbf_text
, "noq:%4x", init_data
->no_output_qs
);
39 QDIO_DBF_TEXT0(0, setup
, dbf_text
);
40 QDIO_DBF_HEX0(0, setup
, &init_data
->input_handler
, sizeof(void *));
41 QDIO_DBF_HEX0(0, setup
, &init_data
->output_handler
, sizeof(void *));
42 QDIO_DBF_HEX0(0, setup
, &init_data
->int_parm
, sizeof(long));
43 QDIO_DBF_HEX0(0, setup
, &init_data
->flags
, sizeof(long));
44 QDIO_DBF_HEX0(0, setup
, &init_data
->input_sbal_addr_array
, sizeof(void *));
45 QDIO_DBF_HEX0(0, setup
, &init_data
->output_sbal_addr_array
, sizeof(void *));
48 static void qdio_unregister_dbf_views(void)
51 debug_unregister(qdio_dbf_setup
);
53 debug_unregister(qdio_dbf_trace
);
56 static int qdio_register_dbf_views(void)
58 qdio_dbf_setup
= debug_register("qdio_setup", QDIO_DBF_SETUP_PAGES
,
59 QDIO_DBF_SETUP_NR_AREAS
,
63 debug_register_view(qdio_dbf_setup
, &debug_hex_ascii_view
);
64 debug_set_level(qdio_dbf_setup
, QDIO_DBF_SETUP_LEVEL
);
66 qdio_dbf_trace
= debug_register("qdio_trace", QDIO_DBF_TRACE_PAGES
,
67 QDIO_DBF_TRACE_NR_AREAS
,
71 debug_register_view(qdio_dbf_trace
, &debug_hex_ascii_view
);
72 debug_set_level(qdio_dbf_trace
, QDIO_DBF_TRACE_LEVEL
);
75 qdio_unregister_dbf_views();
79 static int qstat_show(struct seq_file
*m
, void *v
)
82 struct qdio_q
*q
= m
->private;
88 seq_printf(m
, "device state indicator: %d\n", *q
->irq_ptr
->dsci
);
89 seq_printf(m
, "nr_used: %d\n", atomic_read(&q
->nr_buf_used
));
90 seq_printf(m
, "ftc: %d\n", q
->first_to_check
);
91 seq_printf(m
, "last_move_ftc: %d\n", q
->last_move_ftc
);
92 seq_printf(m
, "polling: %d\n", q
->u
.in
.polling
);
93 seq_printf(m
, "slsb buffer states:\n");
96 for (i
= 0; i
< QDIO_MAX_BUFFERS_PER_Q
; i
++) {
97 get_buf_state(q
, i
, &state
);
99 case SLSB_P_INPUT_NOT_INIT
:
100 case SLSB_P_OUTPUT_NOT_INIT
:
103 case SLSB_P_INPUT_PRIMED
:
104 case SLSB_CU_OUTPUT_PRIMED
:
107 case SLSB_P_INPUT_ACK
:
110 case SLSB_P_INPUT_ERROR
:
111 case SLSB_P_OUTPUT_ERROR
:
114 case SLSB_CU_INPUT_EMPTY
:
115 case SLSB_P_OUTPUT_EMPTY
:
118 case SLSB_P_INPUT_HALTED
:
119 case SLSB_P_OUTPUT_HALTED
:
132 static ssize_t
qstat_seq_write(struct file
*file
, const char __user
*buf
,
133 size_t count
, loff_t
*off
)
135 struct seq_file
*seq
= file
->private_data
;
136 struct qdio_q
*q
= seq
->private;
142 xchg(q
->irq_ptr
->dsci
, 1);
144 tasklet_schedule(&q
->tasklet
);
149 static int qstat_seq_open(struct inode
*inode
, struct file
*filp
)
151 return single_open(filp
, qstat_show
,
152 filp
->f_path
.dentry
->d_inode
->i_private
);
155 static void get_queue_name(struct qdio_q
*q
, struct ccw_device
*cdev
, char *name
)
157 memset(name
, 0, sizeof(name
));
158 sprintf(name
, "%s", cdev
->dev
.bus_id
);
160 sprintf(name
+ strlen(name
), "_input");
162 sprintf(name
+ strlen(name
), "_output");
163 sprintf(name
+ strlen(name
), "_%d", q
->nr
);
166 static void remove_debugfs_entry(struct qdio_q
*q
)
170 for (i
= 0; i
< MAX_DEBUGFS_QUEUES
; i
++) {
171 if (!debugfs_queues
[i
])
173 if (debugfs_queues
[i
]->d_inode
->i_private
== q
) {
174 debugfs_remove(debugfs_queues
[i
]);
175 debugfs_queues
[i
] = NULL
;
180 static struct file_operations debugfs_fops
= {
181 .owner
= THIS_MODULE
,
182 .open
= qstat_seq_open
,
184 .write
= qstat_seq_write
,
186 .release
= single_release
,
189 static void setup_debugfs_entry(struct qdio_q
*q
, struct ccw_device
*cdev
)
194 while (debugfs_queues
[i
] != NULL
) {
196 if (i
>= MAX_DEBUGFS_QUEUES
)
199 get_queue_name(q
, cdev
, name
);
200 debugfs_queues
[i
] = debugfs_create_file(name
, S_IFREG
| S_IRUGO
| S_IWUSR
,
201 debugfs_root
, q
, &debugfs_fops
);
204 void qdio_setup_debug_entries(struct qdio_irq
*irq_ptr
, struct ccw_device
*cdev
)
209 mutex_lock(&debugfs_mutex
);
210 for_each_input_queue(irq_ptr
, q
, i
)
211 setup_debugfs_entry(q
, cdev
);
212 for_each_output_queue(irq_ptr
, q
, i
)
213 setup_debugfs_entry(q
, cdev
);
214 mutex_unlock(&debugfs_mutex
);
217 void qdio_shutdown_debug_entries(struct qdio_irq
*irq_ptr
, struct ccw_device
*cdev
)
222 mutex_lock(&debugfs_mutex
);
223 for_each_input_queue(irq_ptr
, q
, i
)
224 remove_debugfs_entry(q
);
225 for_each_output_queue(irq_ptr
, q
, i
)
226 remove_debugfs_entry(q
);
227 mutex_unlock(&debugfs_mutex
);
230 int __init
qdio_debug_init(void)
232 debugfs_root
= debugfs_create_dir("qdio_queues", NULL
);
233 return qdio_register_dbf_views();
236 void qdio_debug_exit(void)
238 debugfs_remove(debugfs_root
);
239 qdio_unregister_dbf_views();