aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-18 13:06:00 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-18 13:06:00 -0500
commit7b077868cb8bc31aa5a0dad961ecc9f157bff744 (patch)
tree02edce8760040ab5c15c242eb648fb3a342c58d7 /arch
parent16e024f30ce96ef5fa651e2914e19d175a924cab (diff)
parent1f1c96102ff848778cd596e81bdbd45f81a40119 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 update #2 from Martin Schwidefsky: "The main patch is the function measurement blocks extension for PCI to do performance statistics and help with debugging. The other patch is a small cleanup in ccwdev.h." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: s390/ccwdev: Include asm/schid.h. s390/pci: performance statistics and debug infrastructure
Diffstat (limited to 'arch')
-rw-r--r--arch/s390/include/asm/ccwdev.h4
-rw-r--r--arch/s390/include/asm/pci.h39
-rw-r--r--arch/s390/include/asm/pci_debug.h36
-rw-r--r--arch/s390/pci/Makefile2
-rw-r--r--arch/s390/pci/pci.c73
-rw-r--r--arch/s390/pci/pci_clp.c1
-rw-r--r--arch/s390/pci/pci_debug.c193
-rw-r--r--arch/s390/pci/pci_dma.c8
-rw-r--r--arch/s390/pci/pci_event.c2
9 files changed, 350 insertions, 8 deletions
diff --git a/arch/s390/include/asm/ccwdev.h b/arch/s390/include/asm/ccwdev.h
index 6d1f3573f0df..e6061617a50b 100644
--- a/arch/s390/include/asm/ccwdev.h
+++ b/arch/s390/include/asm/ccwdev.h
@@ -12,15 +12,13 @@
12#include <linux/mod_devicetable.h> 12#include <linux/mod_devicetable.h>
13#include <asm/fcx.h> 13#include <asm/fcx.h>
14#include <asm/irq.h> 14#include <asm/irq.h>
15#include <asm/schid.h>
15 16
16/* structs from asm/cio.h */ 17/* structs from asm/cio.h */
17struct irb; 18struct irb;
18struct ccw1; 19struct ccw1;
19struct ccw_dev_id; 20struct ccw_dev_id;
20 21
21/* from asm/schid.h */
22struct subchannel_id;
23
24/* simplified initializers for struct ccw_device: 22/* simplified initializers for struct ccw_device:
25 * CCW_DEVICE and CCW_DEVICE_DEVTYPE initialize one 23 * CCW_DEVICE and CCW_DEVICE_DEVTYPE initialize one
26 * entry in your MODULE_DEVICE_TABLE and set the match_flag correctly */ 24 * entry in your MODULE_DEVICE_TABLE and set the match_flag correctly */
diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h
index a6175ad0c42f..b1fa93c606ad 100644
--- a/arch/s390/include/asm/pci.h
+++ b/arch/s390/include/asm/pci.h
@@ -9,6 +9,7 @@
9#include <asm-generic/pci.h> 9#include <asm-generic/pci.h>
10#include <asm-generic/pci-dma-compat.h> 10#include <asm-generic/pci-dma-compat.h>
11#include <asm/pci_clp.h> 11#include <asm/pci_clp.h>
12#include <asm/pci_debug.h>
12 13
13#define PCIBIOS_MIN_IO 0x1000 14#define PCIBIOS_MIN_IO 0x1000
14#define PCIBIOS_MIN_MEM 0x10000000 15#define PCIBIOS_MIN_MEM 0x10000000
@@ -33,6 +34,25 @@ int pci_proc_domain(struct pci_bus *);
33#define ZPCI_FC_BLOCKED 0x20 34#define ZPCI_FC_BLOCKED 0x20
34#define ZPCI_FC_DMA_ENABLED 0x10 35#define ZPCI_FC_DMA_ENABLED 0x10
35 36
37struct zpci_fmb {
38 u32 format : 8;
39 u32 dma_valid : 1;
40 u32 : 23;
41 u32 samples;
42 u64 last_update;
43 /* hardware counters */
44 u64 ld_ops;
45 u64 st_ops;
46 u64 stb_ops;
47 u64 rpcit_ops;
48 u64 dma_rbytes;
49 u64 dma_wbytes;
50 /* software counters */
51 atomic64_t allocated_pages;
52 atomic64_t mapped_pages;
53 atomic64_t unmapped_pages;
54} __packed __aligned(16);
55
36struct msi_map { 56struct msi_map {
37 unsigned long irq; 57 unsigned long irq;
38 struct msi_desc *msi; 58 struct msi_desc *msi;
@@ -92,7 +112,15 @@ struct zpci_dev {
92 u64 end_dma; /* End of available DMA addresses */ 112 u64 end_dma; /* End of available DMA addresses */
93 u64 dma_mask; /* DMA address space mask */ 113 u64 dma_mask; /* DMA address space mask */
94 114
115 /* Function measurement block */
116 struct zpci_fmb *fmb;
117 u16 fmb_update; /* update interval */
118
95 enum pci_bus_speed max_bus_speed; 119 enum pci_bus_speed max_bus_speed;
120
121 struct dentry *debugfs_dev;
122 struct dentry *debugfs_perf;
123 struct dentry *debugfs_debug;
96}; 124};
97 125
98struct pci_hp_callback_ops { 126struct pci_hp_callback_ops {
@@ -155,4 +183,15 @@ extern struct list_head zpci_list;
155extern struct pci_hp_callback_ops hotplug_ops; 183extern struct pci_hp_callback_ops hotplug_ops;
156extern unsigned int pci_probe; 184extern unsigned int pci_probe;
157 185
186/* FMB */
187int zpci_fmb_enable_device(struct zpci_dev *);
188int zpci_fmb_disable_device(struct zpci_dev *);
189
190/* Debug */
191int zpci_debug_init(void);
192void zpci_debug_exit(void);
193void zpci_debug_init_device(struct zpci_dev *);
194void zpci_debug_exit_device(struct zpci_dev *);
195void zpci_debug_info(struct zpci_dev *, struct seq_file *);
196
158#endif 197#endif
diff --git a/arch/s390/include/asm/pci_debug.h b/arch/s390/include/asm/pci_debug.h
new file mode 100644
index 000000000000..6bbec4265b6e
--- /dev/null
+++ b/arch/s390/include/asm/pci_debug.h
@@ -0,0 +1,36 @@
1#ifndef _S390_ASM_PCI_DEBUG_H
2#define _S390_ASM_PCI_DEBUG_H
3
4#include <asm/debug.h>
5
6extern debug_info_t *pci_debug_msg_id;
7extern debug_info_t *pci_debug_err_id;
8
9#ifdef CONFIG_PCI_DEBUG
10#define zpci_dbg(fmt, args...) \
11 do { \
12 if (pci_debug_msg_id->level >= 2) \
13 debug_sprintf_event(pci_debug_msg_id, 2, fmt , ## args);\
14 } while (0)
15
16#else /* !CONFIG_PCI_DEBUG */
17#define zpci_dbg(fmt, args...) do { } while (0)
18#endif
19
20#define zpci_err(text...) \
21 do { \
22 char debug_buffer[16]; \
23 snprintf(debug_buffer, 16, text); \
24 debug_text_event(pci_debug_err_id, 0, debug_buffer); \
25 } while (0)
26
27static inline void zpci_err_hex(void *addr, int len)
28{
29 while (len > 0) {
30 debug_event(pci_debug_err_id, 0, (void *) addr, len);
31 len -= pci_debug_err_id->buf_size;
32 addr += pci_debug_err_id->buf_size;
33 }
34}
35
36#endif
diff --git a/arch/s390/pci/Makefile b/arch/s390/pci/Makefile
index ab0827b6bc4b..f0f426a113ce 100644
--- a/arch/s390/pci/Makefile
+++ b/arch/s390/pci/Makefile
@@ -3,4 +3,4 @@
3# 3#
4 4
5obj-$(CONFIG_PCI) += pci.o pci_dma.o pci_clp.o pci_msi.o \ 5obj-$(CONFIG_PCI) += pci.o pci_dma.o pci_clp.o pci_msi.o \
6 pci_sysfs.o pci_event.o 6 pci_sysfs.o pci_event.o pci_debug.o
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 7ed38e5e3028..8fa416b8775f 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -98,6 +98,10 @@ EXPORT_SYMBOL_GPL(zpci_iomap_start);
98static int __read_mostly aisb_max; 98static int __read_mostly aisb_max;
99 99
100static struct kmem_cache *zdev_irq_cache; 100static struct kmem_cache *zdev_irq_cache;
101static struct kmem_cache *zdev_fmb_cache;
102
103debug_info_t *pci_debug_msg_id;
104debug_info_t *pci_debug_err_id;
101 105
102static inline int irq_to_msi_nr(unsigned int irq) 106static inline int irq_to_msi_nr(unsigned int irq)
103{ 107{
@@ -216,6 +220,7 @@ struct mod_pci_args {
216 u64 base; 220 u64 base;
217 u64 limit; 221 u64 limit;
218 u64 iota; 222 u64 iota;
223 u64 fmb_addr;
219}; 224};
220 225
221static int mod_pci(struct zpci_dev *zdev, int fn, u8 dmaas, struct mod_pci_args *args) 226static int mod_pci(struct zpci_dev *zdev, int fn, u8 dmaas, struct mod_pci_args *args)
@@ -232,6 +237,7 @@ static int mod_pci(struct zpci_dev *zdev, int fn, u8 dmaas, struct mod_pci_args
232 fib->pba = args->base; 237 fib->pba = args->base;
233 fib->pal = args->limit; 238 fib->pal = args->limit;
234 fib->iota = args->iota; 239 fib->iota = args->iota;
240 fib->fmb_addr = args->fmb_addr;
235 241
236 rc = mpcifc_instr(req, fib); 242 rc = mpcifc_instr(req, fib);
237 free_page((unsigned long) fib); 243 free_page((unsigned long) fib);
@@ -242,7 +248,7 @@ static int mod_pci(struct zpci_dev *zdev, int fn, u8 dmaas, struct mod_pci_args
242int zpci_register_ioat(struct zpci_dev *zdev, u8 dmaas, 248int zpci_register_ioat(struct zpci_dev *zdev, u8 dmaas,
243 u64 base, u64 limit, u64 iota) 249 u64 base, u64 limit, u64 iota)
244{ 250{
245 struct mod_pci_args args = { base, limit, iota }; 251 struct mod_pci_args args = { base, limit, iota, 0 };
246 252
247 WARN_ON_ONCE(iota & 0x3fff); 253 WARN_ON_ONCE(iota & 0x3fff);
248 args.iota |= ZPCI_IOTA_RTTO_FLAG; 254 args.iota |= ZPCI_IOTA_RTTO_FLAG;
@@ -252,7 +258,7 @@ int zpci_register_ioat(struct zpci_dev *zdev, u8 dmaas,
252/* Modify PCI: Unregister I/O address translation parameters */ 258/* Modify PCI: Unregister I/O address translation parameters */
253int zpci_unregister_ioat(struct zpci_dev *zdev, u8 dmaas) 259int zpci_unregister_ioat(struct zpci_dev *zdev, u8 dmaas)
254{ 260{
255 struct mod_pci_args args = { 0, 0, 0 }; 261 struct mod_pci_args args = { 0, 0, 0, 0 };
256 262
257 return mod_pci(zdev, ZPCI_MOD_FC_DEREG_IOAT, dmaas, &args); 263 return mod_pci(zdev, ZPCI_MOD_FC_DEREG_IOAT, dmaas, &args);
258} 264}
@@ -260,11 +266,46 @@ int zpci_unregister_ioat(struct zpci_dev *zdev, u8 dmaas)
260/* Modify PCI: Unregister adapter interruptions */ 266/* Modify PCI: Unregister adapter interruptions */
261static int zpci_unregister_airq(struct zpci_dev *zdev) 267static int zpci_unregister_airq(struct zpci_dev *zdev)
262{ 268{
263 struct mod_pci_args args = { 0, 0, 0 }; 269 struct mod_pci_args args = { 0, 0, 0, 0 };
264 270
265 return mod_pci(zdev, ZPCI_MOD_FC_DEREG_INT, 0, &args); 271 return mod_pci(zdev, ZPCI_MOD_FC_DEREG_INT, 0, &args);
266} 272}
267 273
274/* Modify PCI: Set PCI function measurement parameters */
275int zpci_fmb_enable_device(struct zpci_dev *zdev)
276{
277 struct mod_pci_args args = { 0, 0, 0, 0 };
278
279 if (zdev->fmb)
280 return -EINVAL;
281
282 zdev->fmb = kmem_cache_alloc(zdev_fmb_cache, GFP_KERNEL);
283 if (!zdev->fmb)
284 return -ENOMEM;
285 memset(zdev->fmb, 0, sizeof(*zdev->fmb));
286 WARN_ON((u64) zdev->fmb & 0xf);
287
288 args.fmb_addr = virt_to_phys(zdev->fmb);
289 return mod_pci(zdev, ZPCI_MOD_FC_SET_MEASURE, 0, &args);
290}
291
292/* Modify PCI: Disable PCI function measurement */
293int zpci_fmb_disable_device(struct zpci_dev *zdev)
294{
295 struct mod_pci_args args = { 0, 0, 0, 0 };
296 int rc;
297
298 if (!zdev->fmb)
299 return -EINVAL;
300
301 /* Function measurement is disabled if fmb address is zero */
302 rc = mod_pci(zdev, ZPCI_MOD_FC_SET_MEASURE, 0, &args);
303
304 kmem_cache_free(zdev_fmb_cache, zdev->fmb);
305 zdev->fmb = NULL;
306 return rc;
307}
308
268#define ZPCI_PCIAS_CFGSPC 15 309#define ZPCI_PCIAS_CFGSPC 15
269 310
270static int zpci_cfg_load(struct zpci_dev *zdev, int offset, u32 *val, u8 len) 311static int zpci_cfg_load(struct zpci_dev *zdev, int offset, u32 *val, u8 len)
@@ -633,6 +674,7 @@ static void zpci_remove_device(struct pci_dev *pdev)
633 dev_info(&pdev->dev, "Removing device %u\n", zdev->domain); 674 dev_info(&pdev->dev, "Removing device %u\n", zdev->domain);
634 zdev->state = ZPCI_FN_STATE_CONFIGURED; 675 zdev->state = ZPCI_FN_STATE_CONFIGURED;
635 zpci_dma_exit_device(zdev); 676 zpci_dma_exit_device(zdev);
677 zpci_fmb_disable_device(zdev);
636 zpci_sysfs_remove_device(&pdev->dev); 678 zpci_sysfs_remove_device(&pdev->dev);
637 zpci_unmap_resources(pdev); 679 zpci_unmap_resources(pdev);
638 list_del(&zdev->entry); /* can be called from init */ 680 list_del(&zdev->entry); /* can be called from init */
@@ -799,6 +841,16 @@ static void zpci_irq_exit(void)
799 kfree(bucket); 841 kfree(bucket);
800} 842}
801 843
844void zpci_debug_info(struct zpci_dev *zdev, struct seq_file *m)
845{
846 if (!zdev)
847 return;
848
849 seq_printf(m, "global irq retries: %u\n", atomic_read(&irq_retries));
850 seq_printf(m, "aibv[0]:%016lx aibv[1]:%016lx aisb:%016lx\n",
851 get_imap(0)->aibv, get_imap(1)->aibv, *bucket->aisb);
852}
853
802static struct resource *zpci_alloc_bus_resource(unsigned long start, unsigned long size, 854static struct resource *zpci_alloc_bus_resource(unsigned long start, unsigned long size,
803 unsigned long flags, int domain) 855 unsigned long flags, int domain)
804{ 856{
@@ -994,6 +1046,8 @@ int zpci_scan_device(struct zpci_dev *zdev)
994 goto out; 1046 goto out;
995 } 1047 }
996 1048
1049 zpci_debug_init_device(zdev);
1050 zpci_fmb_enable_device(zdev);
997 zpci_map_resources(zdev); 1051 zpci_map_resources(zdev);
998 pci_bus_add_devices(zdev->bus); 1052 pci_bus_add_devices(zdev->bus);
999 1053
@@ -1020,6 +1074,11 @@ static int zpci_mem_init(void)
1020 if (!zdev_irq_cache) 1074 if (!zdev_irq_cache)
1021 goto error_zdev; 1075 goto error_zdev;
1022 1076
1077 zdev_fmb_cache = kmem_cache_create("PCI_FMB_cache", sizeof(struct zpci_fmb),
1078 16, 0, NULL);
1079 if (!zdev_fmb_cache)
1080 goto error_fmb;
1081
1023 /* TODO: use realloc */ 1082 /* TODO: use realloc */
1024 zpci_iomap_start = kzalloc(ZPCI_IOMAP_MAX_ENTRIES * sizeof(*zpci_iomap_start), 1083 zpci_iomap_start = kzalloc(ZPCI_IOMAP_MAX_ENTRIES * sizeof(*zpci_iomap_start),
1025 GFP_KERNEL); 1084 GFP_KERNEL);
@@ -1028,6 +1087,8 @@ static int zpci_mem_init(void)
1028 return 0; 1087 return 0;
1029 1088
1030error_iomap: 1089error_iomap:
1090 kmem_cache_destroy(zdev_fmb_cache);
1091error_fmb:
1031 kmem_cache_destroy(zdev_irq_cache); 1092 kmem_cache_destroy(zdev_irq_cache);
1032error_zdev: 1093error_zdev:
1033 return -ENOMEM; 1094 return -ENOMEM;
@@ -1037,6 +1098,7 @@ static void zpci_mem_exit(void)
1037{ 1098{
1038 kfree(zpci_iomap_start); 1099 kfree(zpci_iomap_start);
1039 kmem_cache_destroy(zdev_irq_cache); 1100 kmem_cache_destroy(zdev_irq_cache);
1101 kmem_cache_destroy(zdev_fmb_cache);
1040} 1102}
1041 1103
1042unsigned int pci_probe = 1; 1104unsigned int pci_probe = 1;
@@ -1066,6 +1128,10 @@ static int __init pci_base_init(void)
1066 test_facility(69), test_facility(70), 1128 test_facility(69), test_facility(70),
1067 test_facility(71)); 1129 test_facility(71));
1068 1130
1131 rc = zpci_debug_init();
1132 if (rc)
1133 return rc;
1134
1069 rc = zpci_mem_init(); 1135 rc = zpci_mem_init();
1070 if (rc) 1136 if (rc)
1071 goto out_mem; 1137 goto out_mem;
@@ -1098,6 +1164,7 @@ out_irq:
1098out_hash: 1164out_hash:
1099 zpci_mem_exit(); 1165 zpci_mem_exit();
1100out_mem: 1166out_mem:
1167 zpci_debug_exit();
1101 return rc; 1168 return rc;
1102} 1169}
1103subsys_initcall(pci_base_init); 1170subsys_initcall(pci_base_init);
diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c
index 7f4ce8d874a4..2c847143cbd1 100644
--- a/arch/s390/pci/pci_clp.c
+++ b/arch/s390/pci/pci_clp.c
@@ -51,6 +51,7 @@ static void clp_store_query_pci_fngrp(struct zpci_dev *zdev,
51 zdev->tlb_refresh = response->refresh; 51 zdev->tlb_refresh = response->refresh;
52 zdev->dma_mask = response->dasm; 52 zdev->dma_mask = response->dasm;
53 zdev->msi_addr = response->msia; 53 zdev->msi_addr = response->msia;
54 zdev->fmb_update = response->mui;
54 55
55 pr_debug("Supported number of MSI vectors: %u\n", response->noi); 56 pr_debug("Supported number of MSI vectors: %u\n", response->noi);
56 switch (response->version) { 57 switch (response->version) {
diff --git a/arch/s390/pci/pci_debug.c b/arch/s390/pci/pci_debug.c
new file mode 100644
index 000000000000..a303c95346cb
--- /dev/null
+++ b/arch/s390/pci/pci_debug.c
@@ -0,0 +1,193 @@
1/*
2 * Copyright IBM Corp. 2012
3 *
4 * Author(s):
5 * Jan Glauber <jang@linux.vnet.ibm.com>
6 */
7
8#define COMPONENT "zPCI"
9#define pr_fmt(fmt) COMPONENT ": " fmt
10
11#include <linux/kernel.h>
12#include <linux/seq_file.h>
13#include <linux/debugfs.h>
14#include <linux/pci.h>
15#include <asm/debug.h>
16
17#include <asm/pci_dma.h>
18
19static struct dentry *debugfs_root;
20
21static char *pci_perf_names[] = {
22 /* hardware counters */
23 "Load operations",
24 "Store operations",
25 "Store block operations",
26 "Refresh operations",
27 "DMA read bytes",
28 "DMA write bytes",
29 /* software counters */
30 "Allocated pages",
31 "Mapped pages",
32 "Unmapped pages",
33};
34
35static int pci_perf_show(struct seq_file *m, void *v)
36{
37 struct zpci_dev *zdev = m->private;
38 u64 *stat;
39 int i;
40
41 if (!zdev)
42 return 0;
43 if (!zdev->fmb)
44 return seq_printf(m, "FMB statistics disabled\n");
45
46 /* header */
47 seq_printf(m, "FMB @ %p\n", zdev->fmb);
48 seq_printf(m, "Update interval: %u ms\n", zdev->fmb_update);
49 seq_printf(m, "Samples: %u\n", zdev->fmb->samples);
50 seq_printf(m, "Last update TOD: %Lx\n", zdev->fmb->last_update);
51
52 /* hardware counters */
53 stat = (u64 *) &zdev->fmb->ld_ops;
54 for (i = 0; i < 4; i++)
55 seq_printf(m, "%26s:\t%llu\n",
56 pci_perf_names[i], *(stat + i));
57 if (zdev->fmb->dma_valid)
58 for (i = 4; i < 6; i++)
59 seq_printf(m, "%26s:\t%llu\n",
60 pci_perf_names[i], *(stat + i));
61 /* software counters */
62 for (i = 6; i < ARRAY_SIZE(pci_perf_names); i++)
63 seq_printf(m, "%26s:\t%llu\n",
64 pci_perf_names[i],
65 atomic64_read((atomic64_t *) (stat + i)));
66
67 return 0;
68}
69
70static ssize_t pci_perf_seq_write(struct file *file, const char __user *ubuf,
71 size_t count, loff_t *off)
72{
73 struct zpci_dev *zdev = ((struct seq_file *) file->private_data)->private;
74 unsigned long val;
75 int rc;
76
77 if (!zdev)
78 return 0;
79
80 rc = kstrtoul_from_user(ubuf, count, 10, &val);
81 if (rc)
82 return rc;
83
84 switch (val) {
85 case 0:
86 rc = zpci_fmb_disable_device(zdev);
87 if (rc)
88 return rc;
89 break;
90 case 1:
91 rc = zpci_fmb_enable_device(zdev);
92 if (rc)
93 return rc;
94 break;
95 }
96 return count;
97}
98
99static int pci_perf_seq_open(struct inode *inode, struct file *filp)
100{
101 return single_open(filp, pci_perf_show,
102 filp->f_path.dentry->d_inode->i_private);
103}
104
105static const struct file_operations debugfs_pci_perf_fops = {
106 .open = pci_perf_seq_open,
107 .read = seq_read,
108 .write = pci_perf_seq_write,
109 .llseek = seq_lseek,
110 .release = single_release,
111};
112
113static int pci_debug_show(struct seq_file *m, void *v)
114{
115 struct zpci_dev *zdev = m->private;
116
117 zpci_debug_info(zdev, m);
118 return 0;
119}
120
121static int pci_debug_seq_open(struct inode *inode, struct file *filp)
122{
123 return single_open(filp, pci_debug_show,
124 filp->f_path.dentry->d_inode->i_private);
125}
126
127static const struct file_operations debugfs_pci_debug_fops = {
128 .open = pci_debug_seq_open,
129 .read = seq_read,
130 .llseek = seq_lseek,
131 .release = single_release,
132};
133
134void zpci_debug_init_device(struct zpci_dev *zdev)
135{
136 zdev->debugfs_dev = debugfs_create_dir(dev_name(&zdev->pdev->dev),
137 debugfs_root);
138 if (IS_ERR(zdev->debugfs_dev))
139 zdev->debugfs_dev = NULL;
140
141 zdev->debugfs_perf = debugfs_create_file("statistics",
142 S_IFREG | S_IRUGO | S_IWUSR,
143 zdev->debugfs_dev, zdev,
144 &debugfs_pci_perf_fops);
145 if (IS_ERR(zdev->debugfs_perf))
146 zdev->debugfs_perf = NULL;
147
148 zdev->debugfs_debug = debugfs_create_file("debug",
149 S_IFREG | S_IRUGO | S_IWUSR,
150 zdev->debugfs_dev, zdev,
151 &debugfs_pci_debug_fops);
152 if (IS_ERR(zdev->debugfs_debug))
153 zdev->debugfs_debug = NULL;
154}
155
156void zpci_debug_exit_device(struct zpci_dev *zdev)
157{
158 debugfs_remove(zdev->debugfs_perf);
159 debugfs_remove(zdev->debugfs_debug);
160 debugfs_remove(zdev->debugfs_dev);
161}
162
163int __init zpci_debug_init(void)
164{
165 /* event trace buffer */
166 pci_debug_msg_id = debug_register("pci_msg", 16, 1, 16 * sizeof(long));
167 if (!pci_debug_msg_id)
168 return -EINVAL;
169 debug_register_view(pci_debug_msg_id, &debug_sprintf_view);
170 debug_set_level(pci_debug_msg_id, 3);
171 zpci_dbg("Debug view initialized\n");
172
173 /* error log */
174 pci_debug_err_id = debug_register("pci_error", 2, 1, 16);
175 if (!pci_debug_err_id)
176 return -EINVAL;
177 debug_register_view(pci_debug_err_id, &debug_hex_ascii_view);
178 debug_set_level(pci_debug_err_id, 6);
179 zpci_err("Debug view initialized\n");
180
181 debugfs_root = debugfs_create_dir("pci", NULL);
182 return 0;
183}
184
185void zpci_debug_exit(void)
186{
187 if (pci_debug_msg_id)
188 debug_unregister(pci_debug_msg_id);
189 if (pci_debug_err_id)
190 debug_unregister(pci_debug_err_id);
191
192 debugfs_remove(debugfs_root);
193}
diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c
index c64b4b294b0a..6138468b420f 100644
--- a/arch/s390/pci/pci_dma.c
+++ b/arch/s390/pci/pci_dma.c
@@ -291,8 +291,10 @@ static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page,
291 if (direction == DMA_NONE || direction == DMA_TO_DEVICE) 291 if (direction == DMA_NONE || direction == DMA_TO_DEVICE)
292 flags |= ZPCI_TABLE_PROTECTED; 292 flags |= ZPCI_TABLE_PROTECTED;
293 293
294 if (!dma_update_trans(zdev, pa, dma_addr, size, flags)) 294 if (!dma_update_trans(zdev, pa, dma_addr, size, flags)) {
295 atomic64_add(nr_pages, (atomic64_t *) &zdev->fmb->mapped_pages);
295 return dma_addr + offset; 296 return dma_addr + offset;
297 }
296 298
297out_free: 299out_free:
298 dma_free_iommu(zdev, iommu_page_index, nr_pages); 300 dma_free_iommu(zdev, iommu_page_index, nr_pages);
@@ -315,6 +317,7 @@ static void s390_dma_unmap_pages(struct device *dev, dma_addr_t dma_addr,
315 ZPCI_TABLE_PROTECTED | ZPCI_PTE_INVALID)) 317 ZPCI_TABLE_PROTECTED | ZPCI_PTE_INVALID))
316 dev_err(dev, "Failed to unmap addr: %Lx\n", dma_addr); 318 dev_err(dev, "Failed to unmap addr: %Lx\n", dma_addr);
317 319
320 atomic64_add(npages, (atomic64_t *) &zdev->fmb->unmapped_pages);
318 iommu_page_index = (dma_addr - zdev->start_dma) >> PAGE_SHIFT; 321 iommu_page_index = (dma_addr - zdev->start_dma) >> PAGE_SHIFT;
319 dma_free_iommu(zdev, iommu_page_index, npages); 322 dma_free_iommu(zdev, iommu_page_index, npages);
320} 323}
@@ -323,6 +326,7 @@ static void *s390_dma_alloc(struct device *dev, size_t size,
323 dma_addr_t *dma_handle, gfp_t flag, 326 dma_addr_t *dma_handle, gfp_t flag,
324 struct dma_attrs *attrs) 327 struct dma_attrs *attrs)
325{ 328{
329 struct zpci_dev *zdev = get_zdev(container_of(dev, struct pci_dev, dev));
326 struct page *page; 330 struct page *page;
327 unsigned long pa; 331 unsigned long pa;
328 dma_addr_t map; 332 dma_addr_t map;
@@ -331,6 +335,8 @@ static void *s390_dma_alloc(struct device *dev, size_t size,
331 page = alloc_pages(flag, get_order(size)); 335 page = alloc_pages(flag, get_order(size));
332 if (!page) 336 if (!page)
333 return NULL; 337 return NULL;
338
339 atomic64_add(size / PAGE_SIZE, (atomic64_t *) &zdev->fmb->allocated_pages);
334 pa = page_to_phys(page); 340 pa = page_to_phys(page);
335 memset((void *) pa, 0, size); 341 memset((void *) pa, 0, size);
336 342
diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c
index dbed8cd3370c..ec62e3a0dc09 100644
--- a/arch/s390/pci/pci_event.c
+++ b/arch/s390/pci/pci_event.c
@@ -45,6 +45,8 @@ static void zpci_event_log_err(struct zpci_ccdf_err *ccdf)
45{ 45{
46 struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid); 46 struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
47 47
48 zpci_err("SEI error CCD:\n");
49 zpci_err_hex(ccdf, sizeof(*ccdf));
48 dev_err(&zdev->pdev->dev, "event code: 0x%x\n", ccdf->pec); 50 dev_err(&zdev->pdev->dev, "event code: 0x%x\n", ccdf->pec);
49} 51}
50 52