aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/s390/include/asm/pci.h4
-rw-r--r--arch/s390/pci/Makefile3
-rw-r--r--arch/s390/pci/pci_event.c93
3 files changed, 99 insertions, 1 deletions
diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h
index e9dc0090ac43..d3597dcfec33 100644
--- a/arch/s390/include/asm/pci.h
+++ b/arch/s390/include/asm/pci.h
@@ -127,6 +127,10 @@ void zpci_teardown_msi_irq(struct zpci_dev *, struct msi_desc *);
127int zpci_msihash_init(void); 127int zpci_msihash_init(void);
128void zpci_msihash_exit(void); 128void zpci_msihash_exit(void);
129 129
130/* Error handling and recovery */
131void zpci_event_error(void *);
132void zpci_event_availability(void *);
133
130/* Helpers */ 134/* Helpers */
131struct zpci_dev *get_zdev(struct pci_dev *); 135struct zpci_dev *get_zdev(struct pci_dev *);
132struct zpci_dev *get_zdev_by_fid(u32); 136struct zpci_dev *get_zdev_by_fid(u32);
diff --git a/arch/s390/pci/Makefile b/arch/s390/pci/Makefile
index 4590596d8b25..7e36f42ba086 100644
--- a/arch/s390/pci/Makefile
+++ b/arch/s390/pci/Makefile
@@ -2,4 +2,5 @@
2# Makefile for the s390 PCI subsystem. 2# Makefile for the s390 PCI subsystem.
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_event.o
diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c
new file mode 100644
index 000000000000..dbed8cd3370c
--- /dev/null
+++ b/arch/s390/pci/pci_event.c
@@ -0,0 +1,93 @@
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/pci.h>
13
14/* Content Code Description for PCI Function Error */
15struct zpci_ccdf_err {
16 u32 reserved1;
17 u32 fh; /* function handle */
18 u32 fid; /* function id */
19 u32 ett : 4; /* expected table type */
20 u32 mvn : 12; /* MSI vector number */
21 u32 dmaas : 8; /* DMA address space */
22 u32 : 6;
23 u32 q : 1; /* event qualifier */
24 u32 rw : 1; /* read/write */
25 u64 faddr; /* failing address */
26 u32 reserved3;
27 u16 reserved4;
28 u16 pec; /* PCI event code */
29} __packed;
30
31/* Content Code Description for PCI Function Availability */
32struct zpci_ccdf_avail {
33 u32 reserved1;
34 u32 fh; /* function handle */
35 u32 fid; /* function id */
36 u32 reserved2;
37 u32 reserved3;
38 u32 reserved4;
39 u32 reserved5;
40 u16 reserved6;
41 u16 pec; /* PCI event code */
42} __packed;
43
44static void zpci_event_log_err(struct zpci_ccdf_err *ccdf)
45{
46 struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
47
48 dev_err(&zdev->pdev->dev, "event code: 0x%x\n", ccdf->pec);
49}
50
51static void zpci_event_log_avail(struct zpci_ccdf_avail *ccdf)
52{
53 struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
54
55 pr_err("%s%s: availability event: fh: 0x%x fid: 0x%x event code: 0x%x reason:",
56 (zdev) ? dev_driver_string(&zdev->pdev->dev) : "?",
57 (zdev) ? dev_name(&zdev->pdev->dev) : "?",
58 ccdf->fh, ccdf->fid, ccdf->pec);
59 print_hex_dump(KERN_CONT, "ccdf", DUMP_PREFIX_OFFSET,
60 16, 1, ccdf, sizeof(*ccdf), false);
61
62 switch (ccdf->pec) {
63 case 0x0301:
64 zpci_enable_device(zdev);
65 break;
66 case 0x0302:
67 clp_add_pci_device(ccdf->fid, ccdf->fh, 0);
68 break;
69 case 0x0306:
70 clp_find_pci_devices();
71 break;
72 default:
73 break;
74 }
75}
76
77void zpci_event_error(void *data)
78{
79 struct zpci_ccdf_err *ccdf = data;
80 struct zpci_dev *zdev;
81
82 zpci_event_log_err(ccdf);
83 zdev = get_zdev_by_fid(ccdf->fid);
84 if (!zdev) {
85 pr_err("Error event for unknown fid: %x", ccdf->fid);
86 return;
87 }
88}
89
90void zpci_event_availability(void *data)
91{
92 zpci_event_log_avail(data);
93}