1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright IBM Corp. 2012,2015
6 * Jan Glauber <jang@linux.vnet.ibm.com>
9 #define KMSG_COMPONENT "zpci"
10 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
12 #include <linux/kernel.h>
13 #include <linux/seq_file.h>
14 #include <linux/debugfs.h>
15 #include <linux/export.h>
16 #include <linux/pci.h>
17 #include <asm/debug.h>
19 #include <asm/pci_dma.h>
21 static struct dentry
*debugfs_root
;
22 debug_info_t
*pci_debug_msg_id
;
23 EXPORT_SYMBOL_GPL(pci_debug_msg_id
);
24 debug_info_t
*pci_debug_err_id
;
25 EXPORT_SYMBOL_GPL(pci_debug_err_id
);
27 static char *pci_common_names
[] = {
30 "Store block operations",
34 static char *pci_fmt0_names
[] = {
39 static char *pci_fmt1_names
[] = {
43 "Transmitted packets",
46 static char *pci_fmt2_names
[] = {
47 "Consumed work units",
51 static char *pci_fmt3_names
[] = {
55 static char *pci_sw_names
[] = {
61 static void pci_fmb_show(struct seq_file
*m
, char *name
[], int length
,
66 for (i
= 0; i
< length
; i
++, data
++)
67 seq_printf(m
, "%26s:\t%llu\n", name
[i
], *data
);
70 static void pci_sw_counter_show(struct seq_file
*m
)
72 struct zpci_dev
*zdev
= m
->private;
73 atomic64_t
*counter
= &zdev
->allocated_pages
;
76 for (i
= 0; i
< ARRAY_SIZE(pci_sw_names
); i
++, counter
++)
77 seq_printf(m
, "%26s:\t%lu\n", pci_sw_names
[i
],
78 atomic64_read(counter
));
81 static int pci_perf_show(struct seq_file
*m
, void *v
)
83 struct zpci_dev
*zdev
= m
->private;
88 mutex_lock(&zdev
->lock
);
90 mutex_unlock(&zdev
->lock
);
91 seq_puts(m
, "FMB statistics disabled\n");
96 seq_printf(m
, "Update interval: %u ms\n", zdev
->fmb_update
);
97 seq_printf(m
, "Samples: %u\n", zdev
->fmb
->samples
);
98 seq_printf(m
, "Last update TOD: %Lx\n", zdev
->fmb
->last_update
);
100 pci_fmb_show(m
, pci_common_names
, ARRAY_SIZE(pci_common_names
),
103 switch (zdev
->fmb
->format
) {
105 if (!(zdev
->fmb
->fmt_ind
& ZPCI_FMB_DMA_COUNTER_VALID
))
107 pci_fmb_show(m
, pci_fmt0_names
, ARRAY_SIZE(pci_fmt0_names
),
108 &zdev
->fmb
->fmt0
.dma_rbytes
);
111 pci_fmb_show(m
, pci_fmt1_names
, ARRAY_SIZE(pci_fmt1_names
),
112 &zdev
->fmb
->fmt1
.rx_bytes
);
115 pci_fmb_show(m
, pci_fmt2_names
, ARRAY_SIZE(pci_fmt2_names
),
116 &zdev
->fmb
->fmt2
.consumed_work_units
);
119 pci_fmb_show(m
, pci_fmt3_names
, ARRAY_SIZE(pci_fmt3_names
),
120 &zdev
->fmb
->fmt3
.tx_bytes
);
123 seq_puts(m
, "Unknown format\n");
126 pci_sw_counter_show(m
);
127 mutex_unlock(&zdev
->lock
);
131 static ssize_t
pci_perf_seq_write(struct file
*file
, const char __user
*ubuf
,
132 size_t count
, loff_t
*off
)
134 struct zpci_dev
*zdev
= ((struct seq_file
*) file
->private_data
)->private;
141 rc
= kstrtoul_from_user(ubuf
, count
, 10, &val
);
145 mutex_lock(&zdev
->lock
);
148 rc
= zpci_fmb_disable_device(zdev
);
151 rc
= zpci_fmb_enable_device(zdev
);
154 mutex_unlock(&zdev
->lock
);
155 return rc
? rc
: count
;
158 static int pci_perf_seq_open(struct inode
*inode
, struct file
*filp
)
160 return single_open(filp
, pci_perf_show
,
161 file_inode(filp
)->i_private
);
164 static const struct file_operations debugfs_pci_perf_fops
= {
165 .open
= pci_perf_seq_open
,
167 .write
= pci_perf_seq_write
,
169 .release
= single_release
,
172 void zpci_debug_init_device(struct zpci_dev
*zdev
, const char *name
)
174 zdev
->debugfs_dev
= debugfs_create_dir(name
, debugfs_root
);
175 if (IS_ERR(zdev
->debugfs_dev
))
176 zdev
->debugfs_dev
= NULL
;
178 zdev
->debugfs_perf
= debugfs_create_file("statistics",
179 S_IFREG
| S_IRUGO
| S_IWUSR
,
180 zdev
->debugfs_dev
, zdev
,
181 &debugfs_pci_perf_fops
);
182 if (IS_ERR(zdev
->debugfs_perf
))
183 zdev
->debugfs_perf
= NULL
;
186 void zpci_debug_exit_device(struct zpci_dev
*zdev
)
188 debugfs_remove(zdev
->debugfs_perf
);
189 debugfs_remove(zdev
->debugfs_dev
);
192 int __init
zpci_debug_init(void)
194 /* event trace buffer */
195 pci_debug_msg_id
= debug_register("pci_msg", 8, 1, 8 * sizeof(long));
196 if (!pci_debug_msg_id
)
198 debug_register_view(pci_debug_msg_id
, &debug_sprintf_view
);
199 debug_set_level(pci_debug_msg_id
, 3);
202 pci_debug_err_id
= debug_register("pci_error", 2, 1, 16);
203 if (!pci_debug_err_id
)
205 debug_register_view(pci_debug_err_id
, &debug_hex_ascii_view
);
206 debug_set_level(pci_debug_err_id
, 6);
208 debugfs_root
= debugfs_create_dir("pci", NULL
);
212 void zpci_debug_exit(void)
214 debug_unregister(pci_debug_msg_id
);
215 debug_unregister(pci_debug_err_id
);
216 debugfs_remove(debugfs_root
);