xref: /OK3568_Linux_fs/kernel/arch/s390/pci/pci_debug.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  *  Copyright IBM Corp. 2012,2015
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  *  Author(s):
6*4882a593Smuzhiyun  *    Jan Glauber <jang@linux.vnet.ibm.com>
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #define KMSG_COMPONENT "zpci"
10*4882a593Smuzhiyun #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include <linux/kernel.h>
13*4882a593Smuzhiyun #include <linux/seq_file.h>
14*4882a593Smuzhiyun #include <linux/debugfs.h>
15*4882a593Smuzhiyun #include <linux/export.h>
16*4882a593Smuzhiyun #include <linux/pci.h>
17*4882a593Smuzhiyun #include <asm/debug.h>
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #include <asm/pci_dma.h>
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun static struct dentry *debugfs_root;
22*4882a593Smuzhiyun debug_info_t *pci_debug_msg_id;
23*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pci_debug_msg_id);
24*4882a593Smuzhiyun debug_info_t *pci_debug_err_id;
25*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pci_debug_err_id);
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun static char *pci_common_names[] = {
28*4882a593Smuzhiyun 	"Load operations",
29*4882a593Smuzhiyun 	"Store operations",
30*4882a593Smuzhiyun 	"Store block operations",
31*4882a593Smuzhiyun 	"Refresh operations",
32*4882a593Smuzhiyun };
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun static char *pci_fmt0_names[] = {
35*4882a593Smuzhiyun 	"DMA read bytes",
36*4882a593Smuzhiyun 	"DMA write bytes",
37*4882a593Smuzhiyun };
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun static char *pci_fmt1_names[] = {
40*4882a593Smuzhiyun 	"Received bytes",
41*4882a593Smuzhiyun 	"Received packets",
42*4882a593Smuzhiyun 	"Transmitted bytes",
43*4882a593Smuzhiyun 	"Transmitted packets",
44*4882a593Smuzhiyun };
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun static char *pci_fmt2_names[] = {
47*4882a593Smuzhiyun 	"Consumed work units",
48*4882a593Smuzhiyun 	"Maximum work units",
49*4882a593Smuzhiyun };
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun static char *pci_fmt3_names[] = {
52*4882a593Smuzhiyun 	"Transmitted bytes",
53*4882a593Smuzhiyun };
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun static char *pci_sw_names[] = {
56*4882a593Smuzhiyun 	"Allocated pages",
57*4882a593Smuzhiyun 	"Mapped pages",
58*4882a593Smuzhiyun 	"Unmapped pages",
59*4882a593Smuzhiyun };
60*4882a593Smuzhiyun 
pci_fmb_show(struct seq_file * m,char * name[],int length,u64 * data)61*4882a593Smuzhiyun static void pci_fmb_show(struct seq_file *m, char *name[], int length,
62*4882a593Smuzhiyun 			 u64 *data)
63*4882a593Smuzhiyun {
64*4882a593Smuzhiyun 	int i;
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 	for (i = 0; i < length; i++, data++)
67*4882a593Smuzhiyun 		seq_printf(m, "%26s:\t%llu\n", name[i], *data);
68*4882a593Smuzhiyun }
69*4882a593Smuzhiyun 
pci_sw_counter_show(struct seq_file * m)70*4882a593Smuzhiyun static void pci_sw_counter_show(struct seq_file *m)
71*4882a593Smuzhiyun {
72*4882a593Smuzhiyun 	struct zpci_dev *zdev = m->private;
73*4882a593Smuzhiyun 	atomic64_t *counter = &zdev->allocated_pages;
74*4882a593Smuzhiyun 	int i;
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(pci_sw_names); i++, counter++)
77*4882a593Smuzhiyun 		seq_printf(m, "%26s:\t%llu\n", pci_sw_names[i],
78*4882a593Smuzhiyun 			   atomic64_read(counter));
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun 
pci_perf_show(struct seq_file * m,void * v)81*4882a593Smuzhiyun static int pci_perf_show(struct seq_file *m, void *v)
82*4882a593Smuzhiyun {
83*4882a593Smuzhiyun 	struct zpci_dev *zdev = m->private;
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 	if (!zdev)
86*4882a593Smuzhiyun 		return 0;
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun 	mutex_lock(&zdev->lock);
89*4882a593Smuzhiyun 	if (!zdev->fmb) {
90*4882a593Smuzhiyun 		mutex_unlock(&zdev->lock);
91*4882a593Smuzhiyun 		seq_puts(m, "FMB statistics disabled\n");
92*4882a593Smuzhiyun 		return 0;
93*4882a593Smuzhiyun 	}
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun 	/* header */
96*4882a593Smuzhiyun 	seq_printf(m, "Update interval: %u ms\n", zdev->fmb_update);
97*4882a593Smuzhiyun 	seq_printf(m, "Samples: %u\n", zdev->fmb->samples);
98*4882a593Smuzhiyun 	seq_printf(m, "Last update TOD: %Lx\n", zdev->fmb->last_update);
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	pci_fmb_show(m, pci_common_names, ARRAY_SIZE(pci_common_names),
101*4882a593Smuzhiyun 		     &zdev->fmb->ld_ops);
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun 	switch (zdev->fmb->format) {
104*4882a593Smuzhiyun 	case 0:
105*4882a593Smuzhiyun 		if (!(zdev->fmb->fmt_ind & ZPCI_FMB_DMA_COUNTER_VALID))
106*4882a593Smuzhiyun 			break;
107*4882a593Smuzhiyun 		pci_fmb_show(m, pci_fmt0_names, ARRAY_SIZE(pci_fmt0_names),
108*4882a593Smuzhiyun 			     &zdev->fmb->fmt0.dma_rbytes);
109*4882a593Smuzhiyun 		break;
110*4882a593Smuzhiyun 	case 1:
111*4882a593Smuzhiyun 		pci_fmb_show(m, pci_fmt1_names, ARRAY_SIZE(pci_fmt1_names),
112*4882a593Smuzhiyun 			     &zdev->fmb->fmt1.rx_bytes);
113*4882a593Smuzhiyun 		break;
114*4882a593Smuzhiyun 	case 2:
115*4882a593Smuzhiyun 		pci_fmb_show(m, pci_fmt2_names, ARRAY_SIZE(pci_fmt2_names),
116*4882a593Smuzhiyun 			     &zdev->fmb->fmt2.consumed_work_units);
117*4882a593Smuzhiyun 		break;
118*4882a593Smuzhiyun 	case 3:
119*4882a593Smuzhiyun 		pci_fmb_show(m, pci_fmt3_names, ARRAY_SIZE(pci_fmt3_names),
120*4882a593Smuzhiyun 			     &zdev->fmb->fmt3.tx_bytes);
121*4882a593Smuzhiyun 		break;
122*4882a593Smuzhiyun 	default:
123*4882a593Smuzhiyun 		seq_puts(m, "Unknown format\n");
124*4882a593Smuzhiyun 	}
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun 	pci_sw_counter_show(m);
127*4882a593Smuzhiyun 	mutex_unlock(&zdev->lock);
128*4882a593Smuzhiyun 	return 0;
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun 
pci_perf_seq_write(struct file * file,const char __user * ubuf,size_t count,loff_t * off)131*4882a593Smuzhiyun static ssize_t pci_perf_seq_write(struct file *file, const char __user *ubuf,
132*4882a593Smuzhiyun 				  size_t count, loff_t *off)
133*4882a593Smuzhiyun {
134*4882a593Smuzhiyun 	struct zpci_dev *zdev = ((struct seq_file *) file->private_data)->private;
135*4882a593Smuzhiyun 	unsigned long val;
136*4882a593Smuzhiyun 	int rc;
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 	if (!zdev)
139*4882a593Smuzhiyun 		return 0;
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 	rc = kstrtoul_from_user(ubuf, count, 10, &val);
142*4882a593Smuzhiyun 	if (rc)
143*4882a593Smuzhiyun 		return rc;
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun 	mutex_lock(&zdev->lock);
146*4882a593Smuzhiyun 	switch (val) {
147*4882a593Smuzhiyun 	case 0:
148*4882a593Smuzhiyun 		rc = zpci_fmb_disable_device(zdev);
149*4882a593Smuzhiyun 		break;
150*4882a593Smuzhiyun 	case 1:
151*4882a593Smuzhiyun 		rc = zpci_fmb_enable_device(zdev);
152*4882a593Smuzhiyun 		break;
153*4882a593Smuzhiyun 	}
154*4882a593Smuzhiyun 	mutex_unlock(&zdev->lock);
155*4882a593Smuzhiyun 	return rc ? rc : count;
156*4882a593Smuzhiyun }
157*4882a593Smuzhiyun 
pci_perf_seq_open(struct inode * inode,struct file * filp)158*4882a593Smuzhiyun static int pci_perf_seq_open(struct inode *inode, struct file *filp)
159*4882a593Smuzhiyun {
160*4882a593Smuzhiyun 	return single_open(filp, pci_perf_show,
161*4882a593Smuzhiyun 			   file_inode(filp)->i_private);
162*4882a593Smuzhiyun }
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun static const struct file_operations debugfs_pci_perf_fops = {
165*4882a593Smuzhiyun 	.open	 = pci_perf_seq_open,
166*4882a593Smuzhiyun 	.read	 = seq_read,
167*4882a593Smuzhiyun 	.write	 = pci_perf_seq_write,
168*4882a593Smuzhiyun 	.llseek  = seq_lseek,
169*4882a593Smuzhiyun 	.release = single_release,
170*4882a593Smuzhiyun };
171*4882a593Smuzhiyun 
zpci_debug_init_device(struct zpci_dev * zdev,const char * name)172*4882a593Smuzhiyun void zpci_debug_init_device(struct zpci_dev *zdev, const char *name)
173*4882a593Smuzhiyun {
174*4882a593Smuzhiyun 	zdev->debugfs_dev = debugfs_create_dir(name, debugfs_root);
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 	debugfs_create_file("statistics", S_IFREG | S_IRUGO | S_IWUSR,
177*4882a593Smuzhiyun 			    zdev->debugfs_dev, zdev, &debugfs_pci_perf_fops);
178*4882a593Smuzhiyun }
179*4882a593Smuzhiyun 
zpci_debug_exit_device(struct zpci_dev * zdev)180*4882a593Smuzhiyun void zpci_debug_exit_device(struct zpci_dev *zdev)
181*4882a593Smuzhiyun {
182*4882a593Smuzhiyun 	debugfs_remove_recursive(zdev->debugfs_dev);
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun 
zpci_debug_init(void)185*4882a593Smuzhiyun int __init zpci_debug_init(void)
186*4882a593Smuzhiyun {
187*4882a593Smuzhiyun 	/* event trace buffer */
188*4882a593Smuzhiyun 	pci_debug_msg_id = debug_register("pci_msg", 8, 1, 8 * sizeof(long));
189*4882a593Smuzhiyun 	if (!pci_debug_msg_id)
190*4882a593Smuzhiyun 		return -EINVAL;
191*4882a593Smuzhiyun 	debug_register_view(pci_debug_msg_id, &debug_sprintf_view);
192*4882a593Smuzhiyun 	debug_set_level(pci_debug_msg_id, 3);
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun 	/* error log */
195*4882a593Smuzhiyun 	pci_debug_err_id = debug_register("pci_error", 2, 1, 16);
196*4882a593Smuzhiyun 	if (!pci_debug_err_id)
197*4882a593Smuzhiyun 		return -EINVAL;
198*4882a593Smuzhiyun 	debug_register_view(pci_debug_err_id, &debug_hex_ascii_view);
199*4882a593Smuzhiyun 	debug_set_level(pci_debug_err_id, 6);
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun 	debugfs_root = debugfs_create_dir("pci", NULL);
202*4882a593Smuzhiyun 	return 0;
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun 
zpci_debug_exit(void)205*4882a593Smuzhiyun void zpci_debug_exit(void)
206*4882a593Smuzhiyun {
207*4882a593Smuzhiyun 	debug_unregister(pci_debug_msg_id);
208*4882a593Smuzhiyun 	debug_unregister(pci_debug_err_id);
209*4882a593Smuzhiyun 	debugfs_remove(debugfs_root);
210*4882a593Smuzhiyun }
211