1
2
3
4
5
6
7
8
9#define KMSG_COMPONENT "zpci"
10#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
11
12#include <linux/kernel.h>
13#include <linux/pci.h>
14#include <asm/pci_debug.h>
15#include <asm/pci_dma.h>
16#include <asm/sclp.h>
17
18#include "pci_bus.h"
19
20
21struct zpci_ccdf_err {
22 u32 reserved1;
23 u32 fh;
24 u32 fid;
25 u32 ett : 4;
26 u32 mvn : 12;
27 u32 dmaas : 8;
28 u32 : 6;
29 u32 q : 1;
30 u32 rw : 1;
31 u64 faddr;
32 u32 reserved3;
33 u16 reserved4;
34 u16 pec;
35} __packed;
36
37
38struct zpci_ccdf_avail {
39 u32 reserved1;
40 u32 fh;
41 u32 fid;
42 u32 reserved2;
43 u32 reserved3;
44 u32 reserved4;
45 u32 reserved5;
46 u16 reserved6;
47 u16 pec;
48} __packed;
49
50static void __zpci_event_error(struct zpci_ccdf_err *ccdf)
51{
52 struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
53 struct pci_dev *pdev = NULL;
54
55 zpci_err("error CCDF:\n");
56 zpci_err_hex(ccdf, sizeof(*ccdf));
57
58 if (zdev)
59 pdev = pci_get_slot(zdev->zbus->bus, zdev->devfn);
60
61 pr_err("%s: Event 0x%x reports an error for PCI function 0x%x\n",
62 pdev ? pci_name(pdev) : "n/a", ccdf->pec, ccdf->fid);
63
64 if (!pdev)
65 return;
66
67 pdev->error_state = pci_channel_io_perm_failure;
68 pci_dev_put(pdev);
69}
70
71void zpci_event_error(void *data)
72{
73 if (zpci_is_enabled())
74 __zpci_event_error(data);
75}
76
77static void zpci_event_hard_deconfigured(struct zpci_dev *zdev, u32 fh)
78{
79 zdev->fh = fh;
80
81
82
83 zpci_bus_remove_device(zdev, true);
84
85
86
87 if (zdev->dma_table)
88 zpci_dma_exit_device(zdev);
89 if (zdev_enabled(zdev))
90 zpci_disable_device(zdev);
91 zdev->state = ZPCI_FN_STATE_STANDBY;
92}
93
94static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
95{
96 struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
97 enum zpci_state state;
98
99 zpci_err("avail CCDF:\n");
100 zpci_err_hex(ccdf, sizeof(*ccdf));
101
102 switch (ccdf->pec) {
103 case 0x0301:
104 if (!zdev) {
105 zdev = zpci_create_device(ccdf->fid, ccdf->fh, ZPCI_FN_STATE_CONFIGURED);
106 if (IS_ERR(zdev))
107 break;
108 } else {
109
110 if (zdev->state != ZPCI_FN_STATE_STANDBY)
111 break;
112 zdev->state = ZPCI_FN_STATE_CONFIGURED;
113 }
114 zpci_scan_configured_device(zdev, ccdf->fh);
115 break;
116 case 0x0302:
117 if (!zdev)
118 zpci_create_device(ccdf->fid, ccdf->fh, ZPCI_FN_STATE_STANDBY);
119 else
120 zdev->fh = ccdf->fh;
121 break;
122 case 0x0303:
123 if (zdev) {
124
125
126
127 if (zdev->state != ZPCI_FN_STATE_CONFIGURED)
128 break;
129 zdev->fh = ccdf->fh;
130 zpci_deconfigure_device(zdev);
131 }
132 break;
133 case 0x0304:
134 if (zdev) {
135
136
137
138 if (zdev->state == ZPCI_FN_STATE_CONFIGURED)
139 zpci_event_hard_deconfigured(zdev, ccdf->fh);
140
141 if (!clp_get_state(zdev->fid, &state) &&
142 state == ZPCI_FN_STATE_RESERVED) {
143 zpci_device_reserved(zdev);
144 }
145 }
146 break;
147 case 0x0306:
148 zpci_remove_reserved_devices();
149 clp_scan_pci_devices();
150 break;
151 case 0x0308:
152 if (!zdev)
153 break;
154 zpci_device_reserved(zdev);
155 break;
156 default:
157 break;
158 }
159}
160
161void zpci_event_availability(void *data)
162{
163 if (zpci_is_enabled())
164 __zpci_event_availability(data);
165}
166