Commit 270c66be9b4a6f2be53ef3aec5dc8e7b07782ec9

Authored by Yu Zhao
Committed by Jesse Barnes
1 parent 0927678f55

PCI: fix AER capability check

The 'use pci_find_ext_capability everywhere' cleanup brought a new bug,
which makes the AER stop working.  Fix it by actually using find_ext_cap
instead of just find_cap.  Drop the unused config space size define while
we're at it.

Signed-off-by: Yu Zhao <yu.zhao@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>

Showing 4 changed files with 5 additions and 12 deletions Inline Diff

Documentation/PCI/pcieaer-howto.txt
1 The PCI Express Advanced Error Reporting Driver Guide HOWTO 1 The PCI Express Advanced Error Reporting Driver Guide HOWTO
2 T. Long Nguyen <tom.l.nguyen@intel.com> 2 T. Long Nguyen <tom.l.nguyen@intel.com>
3 Yanmin Zhang <yanmin.zhang@intel.com> 3 Yanmin Zhang <yanmin.zhang@intel.com>
4 07/29/2006 4 07/29/2006
5 5
6 6
7 1. Overview 7 1. Overview
8 8
9 1.1 About this guide 9 1.1 About this guide
10 10
11 This guide describes the basics of the PCI Express Advanced Error 11 This guide describes the basics of the PCI Express Advanced Error
12 Reporting (AER) driver and provides information on how to use it, as 12 Reporting (AER) driver and provides information on how to use it, as
13 well as how to enable the drivers of endpoint devices to conform with 13 well as how to enable the drivers of endpoint devices to conform with
14 PCI Express AER driver. 14 PCI Express AER driver.
15 15
16 1.2 Copyright © Intel Corporation 2006. 16 1.2 Copyright © Intel Corporation 2006.
17 17
18 1.3 What is the PCI Express AER Driver? 18 1.3 What is the PCI Express AER Driver?
19 19
20 PCI Express error signaling can occur on the PCI Express link itself 20 PCI Express error signaling can occur on the PCI Express link itself
21 or on behalf of transactions initiated on the link. PCI Express 21 or on behalf of transactions initiated on the link. PCI Express
22 defines two error reporting paradigms: the baseline capability and 22 defines two error reporting paradigms: the baseline capability and
23 the Advanced Error Reporting capability. The baseline capability is 23 the Advanced Error Reporting capability. The baseline capability is
24 required of all PCI Express components providing a minimum defined 24 required of all PCI Express components providing a minimum defined
25 set of error reporting requirements. Advanced Error Reporting 25 set of error reporting requirements. Advanced Error Reporting
26 capability is implemented with a PCI Express advanced error reporting 26 capability is implemented with a PCI Express advanced error reporting
27 extended capability structure providing more robust error reporting. 27 extended capability structure providing more robust error reporting.
28 28
29 The PCI Express AER driver provides the infrastructure to support PCI 29 The PCI Express AER driver provides the infrastructure to support PCI
30 Express Advanced Error Reporting capability. The PCI Express AER 30 Express Advanced Error Reporting capability. The PCI Express AER
31 driver provides three basic functions: 31 driver provides three basic functions:
32 32
33 - Gathers the comprehensive error information if errors occurred. 33 - Gathers the comprehensive error information if errors occurred.
34 - Reports error to the users. 34 - Reports error to the users.
35 - Performs error recovery actions. 35 - Performs error recovery actions.
36 36
37 AER driver only attaches root ports which support PCI-Express AER 37 AER driver only attaches root ports which support PCI-Express AER
38 capability. 38 capability.
39 39
40 40
41 2. User Guide 41 2. User Guide
42 42
43 2.1 Include the PCI Express AER Root Driver into the Linux Kernel 43 2.1 Include the PCI Express AER Root Driver into the Linux Kernel
44 44
45 The PCI Express AER Root driver is a Root Port service driver attached 45 The PCI Express AER Root driver is a Root Port service driver attached
46 to the PCI Express Port Bus driver. If a user wants to use it, the driver 46 to the PCI Express Port Bus driver. If a user wants to use it, the driver
47 has to be compiled. Option CONFIG_PCIEAER supports this capability. It 47 has to be compiled. Option CONFIG_PCIEAER supports this capability. It
48 depends on CONFIG_PCIEPORTBUS, so pls. set CONFIG_PCIEPORTBUS=y and 48 depends on CONFIG_PCIEPORTBUS, so pls. set CONFIG_PCIEPORTBUS=y and
49 CONFIG_PCIEAER = y. 49 CONFIG_PCIEAER = y.
50 50
51 2.2 Load PCI Express AER Root Driver 51 2.2 Load PCI Express AER Root Driver
52 There is a case where a system has AER support in BIOS. Enabling the AER 52 There is a case where a system has AER support in BIOS. Enabling the AER
53 Root driver and having AER support in BIOS may result unpredictable 53 Root driver and having AER support in BIOS may result unpredictable
54 behavior. To avoid this conflict, a successful load of the AER Root driver 54 behavior. To avoid this conflict, a successful load of the AER Root driver
55 requires ACPI _OSC support in the BIOS to allow the AER Root driver to 55 requires ACPI _OSC support in the BIOS to allow the AER Root driver to
56 request for native control of AER. See the PCI FW 3.0 Specification for 56 request for native control of AER. See the PCI FW 3.0 Specification for
57 details regarding OSC usage. Currently, lots of firmwares don't provide 57 details regarding OSC usage. Currently, lots of firmwares don't provide
58 _OSC support while they use PCI Express. To support such firmwares, 58 _OSC support while they use PCI Express. To support such firmwares,
59 forceload, a parameter of type bool, could enable AER to continue to 59 forceload, a parameter of type bool, could enable AER to continue to
60 be initiated although firmwares have no _OSC support. To enable the 60 be initiated although firmwares have no _OSC support. To enable the
61 walkaround, pls. add aerdriver.forceload=y to kernel boot parameter line 61 walkaround, pls. add aerdriver.forceload=y to kernel boot parameter line
62 when booting kernel. Note that forceload=n by default. 62 when booting kernel. Note that forceload=n by default.
63 63
64 2.3 AER error output 64 2.3 AER error output
65 When a PCI-E AER error is captured, an error message will be outputed to 65 When a PCI-E AER error is captured, an error message will be outputed to
66 console. If it's a correctable error, it is outputed as a warning. 66 console. If it's a correctable error, it is outputed as a warning.
67 Otherwise, it is printed as an error. So users could choose different 67 Otherwise, it is printed as an error. So users could choose different
68 log level to filter out correctable error messages. 68 log level to filter out correctable error messages.
69 69
70 Below shows an example. 70 Below shows an example.
71 +------ PCI-Express Device Error -----+ 71 +------ PCI-Express Device Error -----+
72 Error Severity : Uncorrected (Fatal) 72 Error Severity : Uncorrected (Fatal)
73 PCIE Bus Error type : Transaction Layer 73 PCIE Bus Error type : Transaction Layer
74 Unsupported Request : First 74 Unsupported Request : First
75 Requester ID : 0500 75 Requester ID : 0500
76 VendorID=8086h, DeviceID=0329h, Bus=05h, Device=00h, Function=00h 76 VendorID=8086h, DeviceID=0329h, Bus=05h, Device=00h, Function=00h
77 TLB Header: 77 TLB Header:
78 04000001 00200a03 05010000 00050100 78 04000001 00200a03 05010000 00050100
79 79
80 In the example, 'Requester ID' means the ID of the device who sends 80 In the example, 'Requester ID' means the ID of the device who sends
81 the error message to root port. Pls. refer to pci express specs for 81 the error message to root port. Pls. refer to pci express specs for
82 other fields. 82 other fields.
83 83
84 84
85 3. Developer Guide 85 3. Developer Guide
86 86
87 To enable AER aware support requires a software driver to configure 87 To enable AER aware support requires a software driver to configure
88 the AER capability structure within its device and to provide callbacks. 88 the AER capability structure within its device and to provide callbacks.
89 89
90 To support AER better, developers need understand how AER does work 90 To support AER better, developers need understand how AER does work
91 firstly. 91 firstly.
92 92
93 PCI Express errors are classified into two types: correctable errors 93 PCI Express errors are classified into two types: correctable errors
94 and uncorrectable errors. This classification is based on the impacts 94 and uncorrectable errors. This classification is based on the impacts
95 of those errors, which may result in degraded performance or function 95 of those errors, which may result in degraded performance or function
96 failure. 96 failure.
97 97
98 Correctable errors pose no impacts on the functionality of the 98 Correctable errors pose no impacts on the functionality of the
99 interface. The PCI Express protocol can recover without any software 99 interface. The PCI Express protocol can recover without any software
100 intervention or any loss of data. These errors are detected and 100 intervention or any loss of data. These errors are detected and
101 corrected by hardware. Unlike correctable errors, uncorrectable 101 corrected by hardware. Unlike correctable errors, uncorrectable
102 errors impact functionality of the interface. Uncorrectable errors 102 errors impact functionality of the interface. Uncorrectable errors
103 can cause a particular transaction or a particular PCI Express link 103 can cause a particular transaction or a particular PCI Express link
104 to be unreliable. Depending on those error conditions, uncorrectable 104 to be unreliable. Depending on those error conditions, uncorrectable
105 errors are further classified into non-fatal errors and fatal errors. 105 errors are further classified into non-fatal errors and fatal errors.
106 Non-fatal errors cause the particular transaction to be unreliable, 106 Non-fatal errors cause the particular transaction to be unreliable,
107 but the PCI Express link itself is fully functional. Fatal errors, on 107 but the PCI Express link itself is fully functional. Fatal errors, on
108 the other hand, cause the link to be unreliable. 108 the other hand, cause the link to be unreliable.
109 109
110 When AER is enabled, a PCI Express device will automatically send an 110 When AER is enabled, a PCI Express device will automatically send an
111 error message to the PCIE root port above it when the device captures 111 error message to the PCIE root port above it when the device captures
112 an error. The Root Port, upon receiving an error reporting message, 112 an error. The Root Port, upon receiving an error reporting message,
113 internally processes and logs the error message in its PCI Express 113 internally processes and logs the error message in its PCI Express
114 capability structure. Error information being logged includes storing 114 capability structure. Error information being logged includes storing
115 the error reporting agent's requestor ID into the Error Source 115 the error reporting agent's requestor ID into the Error Source
116 Identification Registers and setting the error bits of the Root Error 116 Identification Registers and setting the error bits of the Root Error
117 Status Register accordingly. If AER error reporting is enabled in Root 117 Status Register accordingly. If AER error reporting is enabled in Root
118 Error Command Register, the Root Port generates an interrupt if an 118 Error Command Register, the Root Port generates an interrupt if an
119 error is detected. 119 error is detected.
120 120
121 Note that the errors as described above are related to the PCI Express 121 Note that the errors as described above are related to the PCI Express
122 hierarchy and links. These errors do not include any device specific 122 hierarchy and links. These errors do not include any device specific
123 errors because device specific errors will still get sent directly to 123 errors because device specific errors will still get sent directly to
124 the device driver. 124 the device driver.
125 125
126 3.1 Configure the AER capability structure 126 3.1 Configure the AER capability structure
127 127
128 AER aware drivers of PCI Express component need change the device 128 AER aware drivers of PCI Express component need change the device
129 control registers to enable AER. They also could change AER registers, 129 control registers to enable AER. They also could change AER registers,
130 including mask and severity registers. Helper function 130 including mask and severity registers. Helper function
131 pci_enable_pcie_error_reporting could be used to enable AER. See 131 pci_enable_pcie_error_reporting could be used to enable AER. See
132 section 3.3. 132 section 3.3.
133 133
134 3.2. Provide callbacks 134 3.2. Provide callbacks
135 135
136 3.2.1 callback reset_link to reset pci express link 136 3.2.1 callback reset_link to reset pci express link
137 137
138 This callback is used to reset the pci express physical link when a 138 This callback is used to reset the pci express physical link when a
139 fatal error happens. The root port aer service driver provides a 139 fatal error happens. The root port aer service driver provides a
140 default reset_link function, but different upstream ports might 140 default reset_link function, but different upstream ports might
141 have different specifications to reset pci express link, so all 141 have different specifications to reset pci express link, so all
142 upstream ports should provide their own reset_link functions. 142 upstream ports should provide their own reset_link functions.
143 143
144 In struct pcie_port_service_driver, a new pointer, reset_link, is 144 In struct pcie_port_service_driver, a new pointer, reset_link, is
145 added. 145 added.
146 146
147 pci_ers_result_t (*reset_link) (struct pci_dev *dev); 147 pci_ers_result_t (*reset_link) (struct pci_dev *dev);
148 148
149 Section 3.2.2.2 provides more detailed info on when to call 149 Section 3.2.2.2 provides more detailed info on when to call
150 reset_link. 150 reset_link.
151 151
152 3.2.2 PCI error-recovery callbacks 152 3.2.2 PCI error-recovery callbacks
153 153
154 The PCI Express AER Root driver uses error callbacks to coordinate 154 The PCI Express AER Root driver uses error callbacks to coordinate
155 with downstream device drivers associated with a hierarchy in question 155 with downstream device drivers associated with a hierarchy in question
156 when performing error recovery actions. 156 when performing error recovery actions.
157 157
158 Data struct pci_driver has a pointer, err_handler, to point to 158 Data struct pci_driver has a pointer, err_handler, to point to
159 pci_error_handlers who consists of a couple of callback function 159 pci_error_handlers who consists of a couple of callback function
160 pointers. AER driver follows the rules defined in 160 pointers. AER driver follows the rules defined in
161 pci-error-recovery.txt except pci express specific parts (e.g. 161 pci-error-recovery.txt except pci express specific parts (e.g.
162 reset_link). Pls. refer to pci-error-recovery.txt for detailed 162 reset_link). Pls. refer to pci-error-recovery.txt for detailed
163 definitions of the callbacks. 163 definitions of the callbacks.
164 164
165 Below sections specify when to call the error callback functions. 165 Below sections specify when to call the error callback functions.
166 166
167 3.2.2.1 Correctable errors 167 3.2.2.1 Correctable errors
168 168
169 Correctable errors pose no impacts on the functionality of 169 Correctable errors pose no impacts on the functionality of
170 the interface. The PCI Express protocol can recover without any 170 the interface. The PCI Express protocol can recover without any
171 software intervention or any loss of data. These errors do not 171 software intervention or any loss of data. These errors do not
172 require any recovery actions. The AER driver clears the device's 172 require any recovery actions. The AER driver clears the device's
173 correctable error status register accordingly and logs these errors. 173 correctable error status register accordingly and logs these errors.
174 174
175 3.2.2.2 Non-correctable (non-fatal and fatal) errors 175 3.2.2.2 Non-correctable (non-fatal and fatal) errors
176 176
177 If an error message indicates a non-fatal error, performing link reset 177 If an error message indicates a non-fatal error, performing link reset
178 at upstream is not required. The AER driver calls error_detected(dev, 178 at upstream is not required. The AER driver calls error_detected(dev,
179 pci_channel_io_normal) to all drivers associated within a hierarchy in 179 pci_channel_io_normal) to all drivers associated within a hierarchy in
180 question. for example, 180 question. for example,
181 EndPoint<==>DownstreamPort B<==>UpstreamPort A<==>RootPort. 181 EndPoint<==>DownstreamPort B<==>UpstreamPort A<==>RootPort.
182 If Upstream port A captures an AER error, the hierarchy consists of 182 If Upstream port A captures an AER error, the hierarchy consists of
183 Downstream port B and EndPoint. 183 Downstream port B and EndPoint.
184 184
185 A driver may return PCI_ERS_RESULT_CAN_RECOVER, 185 A driver may return PCI_ERS_RESULT_CAN_RECOVER,
186 PCI_ERS_RESULT_DISCONNECT, or PCI_ERS_RESULT_NEED_RESET, depending on 186 PCI_ERS_RESULT_DISCONNECT, or PCI_ERS_RESULT_NEED_RESET, depending on
187 whether it can recover or the AER driver calls mmio_enabled as next. 187 whether it can recover or the AER driver calls mmio_enabled as next.
188 188
189 If an error message indicates a fatal error, kernel will broadcast 189 If an error message indicates a fatal error, kernel will broadcast
190 error_detected(dev, pci_channel_io_frozen) to all drivers within 190 error_detected(dev, pci_channel_io_frozen) to all drivers within
191 a hierarchy in question. Then, performing link reset at upstream is 191 a hierarchy in question. Then, performing link reset at upstream is
192 necessary. As different kinds of devices might use different approaches 192 necessary. As different kinds of devices might use different approaches
193 to reset link, AER port service driver is required to provide the 193 to reset link, AER port service driver is required to provide the
194 function to reset link. Firstly, kernel looks for if the upstream 194 function to reset link. Firstly, kernel looks for if the upstream
195 component has an aer driver. If it has, kernel uses the reset_link 195 component has an aer driver. If it has, kernel uses the reset_link
196 callback of the aer driver. If the upstream component has no aer driver 196 callback of the aer driver. If the upstream component has no aer driver
197 and the port is downstream port, we will use the aer driver of the 197 and the port is downstream port, we will use the aer driver of the
198 root port who reports the AER error. As for upstream ports, 198 root port who reports the AER error. As for upstream ports,
199 they should provide their own aer service drivers with reset_link 199 they should provide their own aer service drivers with reset_link
200 function. If error_detected returns PCI_ERS_RESULT_CAN_RECOVER and 200 function. If error_detected returns PCI_ERS_RESULT_CAN_RECOVER and
201 reset_link returns PCI_ERS_RESULT_RECOVERED, the error handling goes 201 reset_link returns PCI_ERS_RESULT_RECOVERED, the error handling goes
202 to mmio_enabled. 202 to mmio_enabled.
203 203
204 3.3 helper functions 204 3.3 helper functions
205 205
206 3.3.1 int pci_find_aer_capability(struct pci_dev *dev); 206 3.3.1 int pci_enable_pcie_error_reporting(struct pci_dev *dev);
207 pci_find_aer_capability locates the PCI Express AER capability
208 in the device configuration space. If the device doesn't support
209 PCI-Express AER, the function returns 0.
210
211 3.3.2 int pci_enable_pcie_error_reporting(struct pci_dev *dev);
212 pci_enable_pcie_error_reporting enables the device to send error 207 pci_enable_pcie_error_reporting enables the device to send error
213 messages to root port when an error is detected. Note that devices 208 messages to root port when an error is detected. Note that devices
214 don't enable the error reporting by default, so device drivers need 209 don't enable the error reporting by default, so device drivers need
215 call this function to enable it. 210 call this function to enable it.
216 211
217 3.3.3 int pci_disable_pcie_error_reporting(struct pci_dev *dev); 212 3.3.2 int pci_disable_pcie_error_reporting(struct pci_dev *dev);
218 pci_disable_pcie_error_reporting disables the device to send error 213 pci_disable_pcie_error_reporting disables the device to send error
219 messages to root port when an error is detected. 214 messages to root port when an error is detected.
220 215
221 3.3.4 int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev); 216 3.3.3 int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev);
222 pci_cleanup_aer_uncorrect_error_status cleanups the uncorrectable 217 pci_cleanup_aer_uncorrect_error_status cleanups the uncorrectable
223 error status register. 218 error status register.
224 219
225 3.4 Frequent Asked Questions 220 3.4 Frequent Asked Questions
226 221
227 Q: What happens if a PCI Express device driver does not provide an 222 Q: What happens if a PCI Express device driver does not provide an
228 error recovery handler (pci_driver->err_handler is equal to NULL)? 223 error recovery handler (pci_driver->err_handler is equal to NULL)?
229 224
230 A: The devices attached with the driver won't be recovered. If the 225 A: The devices attached with the driver won't be recovered. If the
231 error is fatal, kernel will print out warning messages. Please refer 226 error is fatal, kernel will print out warning messages. Please refer
232 to section 3 for more information. 227 to section 3 for more information.
233 228
234 Q: What happens if an upstream port service driver does not provide 229 Q: What happens if an upstream port service driver does not provide
235 callback reset_link? 230 callback reset_link?
236 231
237 A: Fatal error recovery will fail if the errors are reported by the 232 A: Fatal error recovery will fail if the errors are reported by the
238 upstream ports who are attached by the service driver. 233 upstream ports who are attached by the service driver.
239 234
240 Q: How does this infrastructure deal with driver that is not PCI 235 Q: How does this infrastructure deal with driver that is not PCI
241 Express aware? 236 Express aware?
242 237
243 A: This infrastructure calls the error callback functions of the 238 A: This infrastructure calls the error callback functions of the
244 driver when an error happens. But if the driver is not aware of 239 driver when an error happens. But if the driver is not aware of
245 PCI Express, the device might not report its own errors to root 240 PCI Express, the device might not report its own errors to root
246 port. 241 port.
247 242
248 Q: What modifications will that driver need to make it compatible 243 Q: What modifications will that driver need to make it compatible
249 with the PCI Express AER Root driver? 244 with the PCI Express AER Root driver?
250 245
251 A: It could call the helper functions to enable AER in devices and 246 A: It could call the helper functions to enable AER in devices and
252 cleanup uncorrectable status register. Pls. refer to section 3.3. 247 cleanup uncorrectable status register. Pls. refer to section 3.3.
253 248
254 249
drivers/pci/pcie/aer/aerdrv_core.c
1 /* 1 /*
2 * drivers/pci/pcie/aer/aerdrv_core.c 2 * drivers/pci/pcie/aer/aerdrv_core.c
3 * 3 *
4 * This file is subject to the terms and conditions of the GNU General Public 4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive 5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details. 6 * for more details.
7 * 7 *
8 * This file implements the core part of PCI-Express AER. When an pci-express 8 * This file implements the core part of PCI-Express AER. When an pci-express
9 * error is delivered, an error message will be collected and printed to 9 * error is delivered, an error message will be collected and printed to
10 * console, then, an error recovery procedure will be executed by following 10 * console, then, an error recovery procedure will be executed by following
11 * the pci error recovery rules. 11 * the pci error recovery rules.
12 * 12 *
13 * Copyright (C) 2006 Intel Corp. 13 * Copyright (C) 2006 Intel Corp.
14 * Tom Long Nguyen (tom.l.nguyen@intel.com) 14 * Tom Long Nguyen (tom.l.nguyen@intel.com)
15 * Zhang Yanmin (yanmin.zhang@intel.com) 15 * Zhang Yanmin (yanmin.zhang@intel.com)
16 * 16 *
17 */ 17 */
18 18
19 #include <linux/module.h> 19 #include <linux/module.h>
20 #include <linux/pci.h> 20 #include <linux/pci.h>
21 #include <linux/kernel.h> 21 #include <linux/kernel.h>
22 #include <linux/errno.h> 22 #include <linux/errno.h>
23 #include <linux/pm.h> 23 #include <linux/pm.h>
24 #include <linux/suspend.h> 24 #include <linux/suspend.h>
25 #include <linux/delay.h> 25 #include <linux/delay.h>
26 #include "aerdrv.h" 26 #include "aerdrv.h"
27 27
28 static int forceload; 28 static int forceload;
29 module_param(forceload, bool, 0); 29 module_param(forceload, bool, 0);
30 30
31 int pci_enable_pcie_error_reporting(struct pci_dev *dev) 31 int pci_enable_pcie_error_reporting(struct pci_dev *dev)
32 { 32 {
33 u16 reg16 = 0; 33 u16 reg16 = 0;
34 int pos; 34 int pos;
35 35
36 pos = pci_find_capability(dev, PCI_CAP_ID_EXP); 36 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
37 if (!pos) 37 if (!pos)
38 return -EIO; 38 return -EIO;
39 39
40 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); 40 pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
41 if (!pos) 41 if (!pos)
42 return -EIO; 42 return -EIO;
43 43
44 pci_read_config_word(dev, pos+PCI_EXP_DEVCTL, &reg16); 44 pci_read_config_word(dev, pos+PCI_EXP_DEVCTL, &reg16);
45 reg16 = reg16 | 45 reg16 = reg16 |
46 PCI_EXP_DEVCTL_CERE | 46 PCI_EXP_DEVCTL_CERE |
47 PCI_EXP_DEVCTL_NFERE | 47 PCI_EXP_DEVCTL_NFERE |
48 PCI_EXP_DEVCTL_FERE | 48 PCI_EXP_DEVCTL_FERE |
49 PCI_EXP_DEVCTL_URRE; 49 PCI_EXP_DEVCTL_URRE;
50 pci_write_config_word(dev, pos+PCI_EXP_DEVCTL, 50 pci_write_config_word(dev, pos+PCI_EXP_DEVCTL,
51 reg16); 51 reg16);
52 return 0; 52 return 0;
53 } 53 }
54 54
55 int pci_disable_pcie_error_reporting(struct pci_dev *dev) 55 int pci_disable_pcie_error_reporting(struct pci_dev *dev)
56 { 56 {
57 u16 reg16 = 0; 57 u16 reg16 = 0;
58 int pos; 58 int pos;
59 59
60 pos = pci_find_capability(dev, PCI_CAP_ID_EXP); 60 pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
61 if (!pos) 61 if (!pos)
62 return -EIO; 62 return -EIO;
63 63
64 pci_read_config_word(dev, pos+PCI_EXP_DEVCTL, &reg16); 64 pci_read_config_word(dev, pos+PCI_EXP_DEVCTL, &reg16);
65 reg16 = reg16 & ~(PCI_EXP_DEVCTL_CERE | 65 reg16 = reg16 & ~(PCI_EXP_DEVCTL_CERE |
66 PCI_EXP_DEVCTL_NFERE | 66 PCI_EXP_DEVCTL_NFERE |
67 PCI_EXP_DEVCTL_FERE | 67 PCI_EXP_DEVCTL_FERE |
68 PCI_EXP_DEVCTL_URRE); 68 PCI_EXP_DEVCTL_URRE);
69 pci_write_config_word(dev, pos+PCI_EXP_DEVCTL, 69 pci_write_config_word(dev, pos+PCI_EXP_DEVCTL,
70 reg16); 70 reg16);
71 return 0; 71 return 0;
72 } 72 }
73 73
74 int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev) 74 int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev)
75 { 75 {
76 int pos; 76 int pos;
77 u32 status, mask; 77 u32 status, mask;
78 78
79 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); 79 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
80 if (!pos) 80 if (!pos)
81 return -EIO; 81 return -EIO;
82 82
83 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status); 83 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status);
84 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &mask); 84 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &mask);
85 if (dev->error_state == pci_channel_io_normal) 85 if (dev->error_state == pci_channel_io_normal)
86 status &= ~mask; /* Clear corresponding nonfatal bits */ 86 status &= ~mask; /* Clear corresponding nonfatal bits */
87 else 87 else
88 status &= mask; /* Clear corresponding fatal bits */ 88 status &= mask; /* Clear corresponding fatal bits */
89 pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status); 89 pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status);
90 90
91 return 0; 91 return 0;
92 } 92 }
93 93
94 #if 0 94 #if 0
95 int pci_cleanup_aer_correct_error_status(struct pci_dev *dev) 95 int pci_cleanup_aer_correct_error_status(struct pci_dev *dev)
96 { 96 {
97 int pos; 97 int pos;
98 u32 status; 98 u32 status;
99 99
100 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); 100 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
101 if (!pos) 101 if (!pos)
102 return -EIO; 102 return -EIO;
103 103
104 pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &status); 104 pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &status);
105 pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, status); 105 pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, status);
106 106
107 return 0; 107 return 0;
108 } 108 }
109 #endif /* 0 */ 109 #endif /* 0 */
110 110
111 static int find_device_iter(struct device *device, void *data) 111 static int find_device_iter(struct device *device, void *data)
112 { 112 {
113 struct pci_dev *dev; 113 struct pci_dev *dev;
114 u16 id = *(unsigned long *)data; 114 u16 id = *(unsigned long *)data;
115 u8 secondary, subordinate, d_bus = id >> 8; 115 u8 secondary, subordinate, d_bus = id >> 8;
116 116
117 if (device->bus == &pci_bus_type) { 117 if (device->bus == &pci_bus_type) {
118 dev = to_pci_dev(device); 118 dev = to_pci_dev(device);
119 if (id == ((dev->bus->number << 8) | dev->devfn)) { 119 if (id == ((dev->bus->number << 8) | dev->devfn)) {
120 /* 120 /*
121 * Device ID match 121 * Device ID match
122 */ 122 */
123 *(unsigned long*)data = (unsigned long)device; 123 *(unsigned long*)data = (unsigned long)device;
124 return 1; 124 return 1;
125 } 125 }
126 126
127 /* 127 /*
128 * If device is P2P, check if it is an upstream? 128 * If device is P2P, check if it is an upstream?
129 */ 129 */
130 if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE) { 130 if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE) {
131 pci_read_config_byte(dev, PCI_SECONDARY_BUS, 131 pci_read_config_byte(dev, PCI_SECONDARY_BUS,
132 &secondary); 132 &secondary);
133 pci_read_config_byte(dev, PCI_SUBORDINATE_BUS, 133 pci_read_config_byte(dev, PCI_SUBORDINATE_BUS,
134 &subordinate); 134 &subordinate);
135 if (d_bus >= secondary && d_bus <= subordinate) { 135 if (d_bus >= secondary && d_bus <= subordinate) {
136 *(unsigned long*)data = (unsigned long)device; 136 *(unsigned long*)data = (unsigned long)device;
137 return 1; 137 return 1;
138 } 138 }
139 } 139 }
140 } 140 }
141 141
142 return 0; 142 return 0;
143 } 143 }
144 144
145 /** 145 /**
146 * find_source_device - search through device hierarchy for source device 146 * find_source_device - search through device hierarchy for source device
147 * @parent: pointer to Root Port pci_dev data structure 147 * @parent: pointer to Root Port pci_dev data structure
148 * @id: device ID of agent who sends an error message to this Root Port 148 * @id: device ID of agent who sends an error message to this Root Port
149 * 149 *
150 * Invoked when error is detected at the Root Port. 150 * Invoked when error is detected at the Root Port.
151 */ 151 */
152 static struct device* find_source_device(struct pci_dev *parent, u16 id) 152 static struct device* find_source_device(struct pci_dev *parent, u16 id)
153 { 153 {
154 struct pci_dev *dev = parent; 154 struct pci_dev *dev = parent;
155 struct device *device; 155 struct device *device;
156 unsigned long device_addr; 156 unsigned long device_addr;
157 int status; 157 int status;
158 158
159 /* Is Root Port an agent that sends error message? */ 159 /* Is Root Port an agent that sends error message? */
160 if (id == ((dev->bus->number << 8) | dev->devfn)) 160 if (id == ((dev->bus->number << 8) | dev->devfn))
161 return &dev->dev; 161 return &dev->dev;
162 162
163 do { 163 do {
164 device_addr = id; 164 device_addr = id;
165 if ((status = device_for_each_child(&dev->dev, 165 if ((status = device_for_each_child(&dev->dev,
166 &device_addr, find_device_iter))) { 166 &device_addr, find_device_iter))) {
167 device = (struct device*)device_addr; 167 device = (struct device*)device_addr;
168 dev = to_pci_dev(device); 168 dev = to_pci_dev(device);
169 if (id == ((dev->bus->number << 8) | dev->devfn)) 169 if (id == ((dev->bus->number << 8) | dev->devfn))
170 return device; 170 return device;
171 } 171 }
172 }while (status); 172 }while (status);
173 173
174 return NULL; 174 return NULL;
175 } 175 }
176 176
177 static void report_error_detected(struct pci_dev *dev, void *data) 177 static void report_error_detected(struct pci_dev *dev, void *data)
178 { 178 {
179 pci_ers_result_t vote; 179 pci_ers_result_t vote;
180 struct pci_error_handlers *err_handler; 180 struct pci_error_handlers *err_handler;
181 struct aer_broadcast_data *result_data; 181 struct aer_broadcast_data *result_data;
182 result_data = (struct aer_broadcast_data *) data; 182 result_data = (struct aer_broadcast_data *) data;
183 183
184 dev->error_state = result_data->state; 184 dev->error_state = result_data->state;
185 185
186 if (!dev->driver || 186 if (!dev->driver ||
187 !dev->driver->err_handler || 187 !dev->driver->err_handler ||
188 !dev->driver->err_handler->error_detected) { 188 !dev->driver->err_handler->error_detected) {
189 if (result_data->state == pci_channel_io_frozen && 189 if (result_data->state == pci_channel_io_frozen &&
190 !(dev->hdr_type & PCI_HEADER_TYPE_BRIDGE)) { 190 !(dev->hdr_type & PCI_HEADER_TYPE_BRIDGE)) {
191 /* 191 /*
192 * In case of fatal recovery, if one of down- 192 * In case of fatal recovery, if one of down-
193 * stream device has no driver. We might be 193 * stream device has no driver. We might be
194 * unable to recover because a later insmod 194 * unable to recover because a later insmod
195 * of a driver for this device is unaware of 195 * of a driver for this device is unaware of
196 * its hw state. 196 * its hw state.
197 */ 197 */
198 dev_printk(KERN_DEBUG, &dev->dev, "device has %s\n", 198 dev_printk(KERN_DEBUG, &dev->dev, "device has %s\n",
199 dev->driver ? 199 dev->driver ?
200 "no AER-aware driver" : "no driver"); 200 "no AER-aware driver" : "no driver");
201 } 201 }
202 return; 202 return;
203 } 203 }
204 204
205 err_handler = dev->driver->err_handler; 205 err_handler = dev->driver->err_handler;
206 vote = err_handler->error_detected(dev, result_data->state); 206 vote = err_handler->error_detected(dev, result_data->state);
207 result_data->result = merge_result(result_data->result, vote); 207 result_data->result = merge_result(result_data->result, vote);
208 return; 208 return;
209 } 209 }
210 210
211 static void report_mmio_enabled(struct pci_dev *dev, void *data) 211 static void report_mmio_enabled(struct pci_dev *dev, void *data)
212 { 212 {
213 pci_ers_result_t vote; 213 pci_ers_result_t vote;
214 struct pci_error_handlers *err_handler; 214 struct pci_error_handlers *err_handler;
215 struct aer_broadcast_data *result_data; 215 struct aer_broadcast_data *result_data;
216 result_data = (struct aer_broadcast_data *) data; 216 result_data = (struct aer_broadcast_data *) data;
217 217
218 if (!dev->driver || 218 if (!dev->driver ||
219 !dev->driver->err_handler || 219 !dev->driver->err_handler ||
220 !dev->driver->err_handler->mmio_enabled) 220 !dev->driver->err_handler->mmio_enabled)
221 return; 221 return;
222 222
223 err_handler = dev->driver->err_handler; 223 err_handler = dev->driver->err_handler;
224 vote = err_handler->mmio_enabled(dev); 224 vote = err_handler->mmio_enabled(dev);
225 result_data->result = merge_result(result_data->result, vote); 225 result_data->result = merge_result(result_data->result, vote);
226 return; 226 return;
227 } 227 }
228 228
229 static void report_slot_reset(struct pci_dev *dev, void *data) 229 static void report_slot_reset(struct pci_dev *dev, void *data)
230 { 230 {
231 pci_ers_result_t vote; 231 pci_ers_result_t vote;
232 struct pci_error_handlers *err_handler; 232 struct pci_error_handlers *err_handler;
233 struct aer_broadcast_data *result_data; 233 struct aer_broadcast_data *result_data;
234 result_data = (struct aer_broadcast_data *) data; 234 result_data = (struct aer_broadcast_data *) data;
235 235
236 if (!dev->driver || 236 if (!dev->driver ||
237 !dev->driver->err_handler || 237 !dev->driver->err_handler ||
238 !dev->driver->err_handler->slot_reset) 238 !dev->driver->err_handler->slot_reset)
239 return; 239 return;
240 240
241 err_handler = dev->driver->err_handler; 241 err_handler = dev->driver->err_handler;
242 vote = err_handler->slot_reset(dev); 242 vote = err_handler->slot_reset(dev);
243 result_data->result = merge_result(result_data->result, vote); 243 result_data->result = merge_result(result_data->result, vote);
244 return; 244 return;
245 } 245 }
246 246
247 static void report_resume(struct pci_dev *dev, void *data) 247 static void report_resume(struct pci_dev *dev, void *data)
248 { 248 {
249 struct pci_error_handlers *err_handler; 249 struct pci_error_handlers *err_handler;
250 250
251 dev->error_state = pci_channel_io_normal; 251 dev->error_state = pci_channel_io_normal;
252 252
253 if (!dev->driver || 253 if (!dev->driver ||
254 !dev->driver->err_handler || 254 !dev->driver->err_handler ||
255 !dev->driver->err_handler->slot_reset) 255 !dev->driver->err_handler->slot_reset)
256 return; 256 return;
257 257
258 err_handler = dev->driver->err_handler; 258 err_handler = dev->driver->err_handler;
259 err_handler->resume(dev); 259 err_handler->resume(dev);
260 return; 260 return;
261 } 261 }
262 262
263 /** 263 /**
264 * broadcast_error_message - handle message broadcast to downstream drivers 264 * broadcast_error_message - handle message broadcast to downstream drivers
265 * @dev: pointer to from where in a hierarchy message is broadcasted down 265 * @dev: pointer to from where in a hierarchy message is broadcasted down
266 * @state: error state 266 * @state: error state
267 * @error_mesg: message to print 267 * @error_mesg: message to print
268 * @cb: callback to be broadcasted 268 * @cb: callback to be broadcasted
269 * 269 *
270 * Invoked during error recovery process. Once being invoked, the content 270 * Invoked during error recovery process. Once being invoked, the content
271 * of error severity will be broadcasted to all downstream drivers in a 271 * of error severity will be broadcasted to all downstream drivers in a
272 * hierarchy in question. 272 * hierarchy in question.
273 */ 273 */
274 static pci_ers_result_t broadcast_error_message(struct pci_dev *dev, 274 static pci_ers_result_t broadcast_error_message(struct pci_dev *dev,
275 enum pci_channel_state state, 275 enum pci_channel_state state,
276 char *error_mesg, 276 char *error_mesg,
277 void (*cb)(struct pci_dev *, void *)) 277 void (*cb)(struct pci_dev *, void *))
278 { 278 {
279 struct aer_broadcast_data result_data; 279 struct aer_broadcast_data result_data;
280 280
281 dev_printk(KERN_DEBUG, &dev->dev, "broadcast %s message\n", error_mesg); 281 dev_printk(KERN_DEBUG, &dev->dev, "broadcast %s message\n", error_mesg);
282 result_data.state = state; 282 result_data.state = state;
283 if (cb == report_error_detected) 283 if (cb == report_error_detected)
284 result_data.result = PCI_ERS_RESULT_CAN_RECOVER; 284 result_data.result = PCI_ERS_RESULT_CAN_RECOVER;
285 else 285 else
286 result_data.result = PCI_ERS_RESULT_RECOVERED; 286 result_data.result = PCI_ERS_RESULT_RECOVERED;
287 287
288 if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE) { 288 if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE) {
289 /* 289 /*
290 * If the error is reported by a bridge, we think this error 290 * If the error is reported by a bridge, we think this error
291 * is related to the downstream link of the bridge, so we 291 * is related to the downstream link of the bridge, so we
292 * do error recovery on all subordinates of the bridge instead 292 * do error recovery on all subordinates of the bridge instead
293 * of the bridge and clear the error status of the bridge. 293 * of the bridge and clear the error status of the bridge.
294 */ 294 */
295 if (cb == report_error_detected) 295 if (cb == report_error_detected)
296 dev->error_state = state; 296 dev->error_state = state;
297 pci_walk_bus(dev->subordinate, cb, &result_data); 297 pci_walk_bus(dev->subordinate, cb, &result_data);
298 if (cb == report_resume) { 298 if (cb == report_resume) {
299 pci_cleanup_aer_uncorrect_error_status(dev); 299 pci_cleanup_aer_uncorrect_error_status(dev);
300 dev->error_state = pci_channel_io_normal; 300 dev->error_state = pci_channel_io_normal;
301 } 301 }
302 } 302 }
303 else { 303 else {
304 /* 304 /*
305 * If the error is reported by an end point, we think this 305 * If the error is reported by an end point, we think this
306 * error is related to the upstream link of the end point. 306 * error is related to the upstream link of the end point.
307 */ 307 */
308 pci_walk_bus(dev->bus, cb, &result_data); 308 pci_walk_bus(dev->bus, cb, &result_data);
309 } 309 }
310 310
311 return result_data.result; 311 return result_data.result;
312 } 312 }
313 313
314 struct find_aer_service_data { 314 struct find_aer_service_data {
315 struct pcie_port_service_driver *aer_driver; 315 struct pcie_port_service_driver *aer_driver;
316 int is_downstream; 316 int is_downstream;
317 }; 317 };
318 318
319 static int find_aer_service_iter(struct device *device, void *data) 319 static int find_aer_service_iter(struct device *device, void *data)
320 { 320 {
321 struct device_driver *driver; 321 struct device_driver *driver;
322 struct pcie_port_service_driver *service_driver; 322 struct pcie_port_service_driver *service_driver;
323 struct pcie_device *pcie_dev; 323 struct pcie_device *pcie_dev;
324 struct find_aer_service_data *result; 324 struct find_aer_service_data *result;
325 325
326 result = (struct find_aer_service_data *) data; 326 result = (struct find_aer_service_data *) data;
327 327
328 if (device->bus == &pcie_port_bus_type) { 328 if (device->bus == &pcie_port_bus_type) {
329 pcie_dev = to_pcie_device(device); 329 pcie_dev = to_pcie_device(device);
330 if (pcie_dev->id.port_type == PCIE_SW_DOWNSTREAM_PORT) 330 if (pcie_dev->id.port_type == PCIE_SW_DOWNSTREAM_PORT)
331 result->is_downstream = 1; 331 result->is_downstream = 1;
332 332
333 driver = device->driver; 333 driver = device->driver;
334 if (driver) { 334 if (driver) {
335 service_driver = to_service_driver(driver); 335 service_driver = to_service_driver(driver);
336 if (service_driver->id_table->service_type == 336 if (service_driver->id_table->service_type ==
337 PCIE_PORT_SERVICE_AER) { 337 PCIE_PORT_SERVICE_AER) {
338 result->aer_driver = service_driver; 338 result->aer_driver = service_driver;
339 return 1; 339 return 1;
340 } 340 }
341 } 341 }
342 } 342 }
343 343
344 return 0; 344 return 0;
345 } 345 }
346 346
347 static void find_aer_service(struct pci_dev *dev, 347 static void find_aer_service(struct pci_dev *dev,
348 struct find_aer_service_data *data) 348 struct find_aer_service_data *data)
349 { 349 {
350 int retval; 350 int retval;
351 retval = device_for_each_child(&dev->dev, data, find_aer_service_iter); 351 retval = device_for_each_child(&dev->dev, data, find_aer_service_iter);
352 } 352 }
353 353
354 static pci_ers_result_t reset_link(struct pcie_device *aerdev, 354 static pci_ers_result_t reset_link(struct pcie_device *aerdev,
355 struct pci_dev *dev) 355 struct pci_dev *dev)
356 { 356 {
357 struct pci_dev *udev; 357 struct pci_dev *udev;
358 pci_ers_result_t status; 358 pci_ers_result_t status;
359 struct find_aer_service_data data; 359 struct find_aer_service_data data;
360 360
361 if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE) 361 if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE)
362 udev = dev; 362 udev = dev;
363 else 363 else
364 udev= dev->bus->self; 364 udev= dev->bus->self;
365 365
366 data.is_downstream = 0; 366 data.is_downstream = 0;
367 data.aer_driver = NULL; 367 data.aer_driver = NULL;
368 find_aer_service(udev, &data); 368 find_aer_service(udev, &data);
369 369
370 /* 370 /*
371 * Use the aer driver of the error agent firstly. 371 * Use the aer driver of the error agent firstly.
372 * If it hasn't the aer driver, use the root port's 372 * If it hasn't the aer driver, use the root port's
373 */ 373 */
374 if (!data.aer_driver || !data.aer_driver->reset_link) { 374 if (!data.aer_driver || !data.aer_driver->reset_link) {
375 if (data.is_downstream && 375 if (data.is_downstream &&
376 aerdev->device.driver && 376 aerdev->device.driver &&
377 to_service_driver(aerdev->device.driver)->reset_link) { 377 to_service_driver(aerdev->device.driver)->reset_link) {
378 data.aer_driver = 378 data.aer_driver =
379 to_service_driver(aerdev->device.driver); 379 to_service_driver(aerdev->device.driver);
380 } else { 380 } else {
381 dev_printk(KERN_DEBUG, &dev->dev, "no link-reset " 381 dev_printk(KERN_DEBUG, &dev->dev, "no link-reset "
382 "support\n"); 382 "support\n");
383 return PCI_ERS_RESULT_DISCONNECT; 383 return PCI_ERS_RESULT_DISCONNECT;
384 } 384 }
385 } 385 }
386 386
387 status = data.aer_driver->reset_link(udev); 387 status = data.aer_driver->reset_link(udev);
388 if (status != PCI_ERS_RESULT_RECOVERED) { 388 if (status != PCI_ERS_RESULT_RECOVERED) {
389 dev_printk(KERN_DEBUG, &dev->dev, "link reset at upstream " 389 dev_printk(KERN_DEBUG, &dev->dev, "link reset at upstream "
390 "device %s failed\n", pci_name(udev)); 390 "device %s failed\n", pci_name(udev));
391 return PCI_ERS_RESULT_DISCONNECT; 391 return PCI_ERS_RESULT_DISCONNECT;
392 } 392 }
393 393
394 return status; 394 return status;
395 } 395 }
396 396
397 /** 397 /**
398 * do_recovery - handle nonfatal/fatal error recovery process 398 * do_recovery - handle nonfatal/fatal error recovery process
399 * @aerdev: pointer to a pcie_device data structure of root port 399 * @aerdev: pointer to a pcie_device data structure of root port
400 * @dev: pointer to a pci_dev data structure of agent detecting an error 400 * @dev: pointer to a pci_dev data structure of agent detecting an error
401 * @severity: error severity type 401 * @severity: error severity type
402 * 402 *
403 * Invoked when an error is nonfatal/fatal. Once being invoked, broadcast 403 * Invoked when an error is nonfatal/fatal. Once being invoked, broadcast
404 * error detected message to all downstream drivers within a hierarchy in 404 * error detected message to all downstream drivers within a hierarchy in
405 * question and return the returned code. 405 * question and return the returned code.
406 */ 406 */
407 static pci_ers_result_t do_recovery(struct pcie_device *aerdev, 407 static pci_ers_result_t do_recovery(struct pcie_device *aerdev,
408 struct pci_dev *dev, 408 struct pci_dev *dev,
409 int severity) 409 int severity)
410 { 410 {
411 pci_ers_result_t status, result = PCI_ERS_RESULT_RECOVERED; 411 pci_ers_result_t status, result = PCI_ERS_RESULT_RECOVERED;
412 enum pci_channel_state state; 412 enum pci_channel_state state;
413 413
414 if (severity == AER_FATAL) 414 if (severity == AER_FATAL)
415 state = pci_channel_io_frozen; 415 state = pci_channel_io_frozen;
416 else 416 else
417 state = pci_channel_io_normal; 417 state = pci_channel_io_normal;
418 418
419 status = broadcast_error_message(dev, 419 status = broadcast_error_message(dev,
420 state, 420 state,
421 "error_detected", 421 "error_detected",
422 report_error_detected); 422 report_error_detected);
423 423
424 if (severity == AER_FATAL) { 424 if (severity == AER_FATAL) {
425 result = reset_link(aerdev, dev); 425 result = reset_link(aerdev, dev);
426 if (result != PCI_ERS_RESULT_RECOVERED) { 426 if (result != PCI_ERS_RESULT_RECOVERED) {
427 /* TODO: Should panic here? */ 427 /* TODO: Should panic here? */
428 return result; 428 return result;
429 } 429 }
430 } 430 }
431 431
432 if (status == PCI_ERS_RESULT_CAN_RECOVER) 432 if (status == PCI_ERS_RESULT_CAN_RECOVER)
433 status = broadcast_error_message(dev, 433 status = broadcast_error_message(dev,
434 state, 434 state,
435 "mmio_enabled", 435 "mmio_enabled",
436 report_mmio_enabled); 436 report_mmio_enabled);
437 437
438 if (status == PCI_ERS_RESULT_NEED_RESET) { 438 if (status == PCI_ERS_RESULT_NEED_RESET) {
439 /* 439 /*
440 * TODO: Should call platform-specific 440 * TODO: Should call platform-specific
441 * functions to reset slot before calling 441 * functions to reset slot before calling
442 * drivers' slot_reset callbacks? 442 * drivers' slot_reset callbacks?
443 */ 443 */
444 status = broadcast_error_message(dev, 444 status = broadcast_error_message(dev,
445 state, 445 state,
446 "slot_reset", 446 "slot_reset",
447 report_slot_reset); 447 report_slot_reset);
448 } 448 }
449 449
450 if (status == PCI_ERS_RESULT_RECOVERED) 450 if (status == PCI_ERS_RESULT_RECOVERED)
451 broadcast_error_message(dev, 451 broadcast_error_message(dev,
452 state, 452 state,
453 "resume", 453 "resume",
454 report_resume); 454 report_resume);
455 455
456 return status; 456 return status;
457 } 457 }
458 458
459 /** 459 /**
460 * handle_error_source - handle logging error into an event log 460 * handle_error_source - handle logging error into an event log
461 * @aerdev: pointer to pcie_device data structure of the root port 461 * @aerdev: pointer to pcie_device data structure of the root port
462 * @dev: pointer to pci_dev data structure of error source device 462 * @dev: pointer to pci_dev data structure of error source device
463 * @info: comprehensive error information 463 * @info: comprehensive error information
464 * 464 *
465 * Invoked when an error being detected by Root Port. 465 * Invoked when an error being detected by Root Port.
466 */ 466 */
467 static void handle_error_source(struct pcie_device * aerdev, 467 static void handle_error_source(struct pcie_device * aerdev,
468 struct pci_dev *dev, 468 struct pci_dev *dev,
469 struct aer_err_info info) 469 struct aer_err_info info)
470 { 470 {
471 pci_ers_result_t status = 0; 471 pci_ers_result_t status = 0;
472 int pos; 472 int pos;
473 473
474 if (info.severity == AER_CORRECTABLE) { 474 if (info.severity == AER_CORRECTABLE) {
475 /* 475 /*
476 * Correctable error does not need software intevention. 476 * Correctable error does not need software intevention.
477 * No need to go through error recovery process. 477 * No need to go through error recovery process.
478 */ 478 */
479 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); 479 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
480 if (pos) 480 if (pos)
481 pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, 481 pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS,
482 info.status); 482 info.status);
483 } else { 483 } else {
484 status = do_recovery(aerdev, dev, info.severity); 484 status = do_recovery(aerdev, dev, info.severity);
485 if (status == PCI_ERS_RESULT_RECOVERED) { 485 if (status == PCI_ERS_RESULT_RECOVERED) {
486 dev_printk(KERN_DEBUG, &dev->dev, "AER driver " 486 dev_printk(KERN_DEBUG, &dev->dev, "AER driver "
487 "successfully recovered\n"); 487 "successfully recovered\n");
488 } else { 488 } else {
489 /* TODO: Should kernel panic here? */ 489 /* TODO: Should kernel panic here? */
490 dev_printk(KERN_DEBUG, &dev->dev, "AER driver didn't " 490 dev_printk(KERN_DEBUG, &dev->dev, "AER driver didn't "
491 "recover\n"); 491 "recover\n");
492 } 492 }
493 } 493 }
494 } 494 }
495 495
496 /** 496 /**
497 * aer_enable_rootport - enable Root Port's interrupts when receiving messages 497 * aer_enable_rootport - enable Root Port's interrupts when receiving messages
498 * @rpc: pointer to a Root Port data structure 498 * @rpc: pointer to a Root Port data structure
499 * 499 *
500 * Invoked when PCIE bus loads AER service driver. 500 * Invoked when PCIE bus loads AER service driver.
501 */ 501 */
502 void aer_enable_rootport(struct aer_rpc *rpc) 502 void aer_enable_rootport(struct aer_rpc *rpc)
503 { 503 {
504 struct pci_dev *pdev = rpc->rpd->port; 504 struct pci_dev *pdev = rpc->rpd->port;
505 int pos, aer_pos; 505 int pos, aer_pos;
506 u16 reg16; 506 u16 reg16;
507 u32 reg32; 507 u32 reg32;
508 508
509 pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); 509 pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
510 /* Clear PCIE Capability's Device Status */ 510 /* Clear PCIE Capability's Device Status */
511 pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, &reg16); 511 pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, &reg16);
512 pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16); 512 pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16);
513 513
514 /* Disable system error generation in response to error messages */ 514 /* Disable system error generation in response to error messages */
515 pci_read_config_word(pdev, pos + PCI_EXP_RTCTL, &reg16); 515 pci_read_config_word(pdev, pos + PCI_EXP_RTCTL, &reg16);
516 reg16 &= ~(SYSTEM_ERROR_INTR_ON_MESG_MASK); 516 reg16 &= ~(SYSTEM_ERROR_INTR_ON_MESG_MASK);
517 pci_write_config_word(pdev, pos + PCI_EXP_RTCTL, reg16); 517 pci_write_config_word(pdev, pos + PCI_EXP_RTCTL, reg16);
518 518
519 aer_pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); 519 aer_pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
520 /* Clear error status */ 520 /* Clear error status */
521 pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, &reg32); 521 pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, &reg32);
522 pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, reg32); 522 pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, reg32);
523 pci_read_config_dword(pdev, aer_pos + PCI_ERR_COR_STATUS, &reg32); 523 pci_read_config_dword(pdev, aer_pos + PCI_ERR_COR_STATUS, &reg32);
524 pci_write_config_dword(pdev, aer_pos + PCI_ERR_COR_STATUS, reg32); 524 pci_write_config_dword(pdev, aer_pos + PCI_ERR_COR_STATUS, reg32);
525 pci_read_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, &reg32); 525 pci_read_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, &reg32);
526 pci_write_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, reg32); 526 pci_write_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, reg32);
527 527
528 /* Enable Root Port device reporting error itself */ 528 /* Enable Root Port device reporting error itself */
529 pci_read_config_word(pdev, pos+PCI_EXP_DEVCTL, &reg16); 529 pci_read_config_word(pdev, pos+PCI_EXP_DEVCTL, &reg16);
530 reg16 = reg16 | 530 reg16 = reg16 |
531 PCI_EXP_DEVCTL_CERE | 531 PCI_EXP_DEVCTL_CERE |
532 PCI_EXP_DEVCTL_NFERE | 532 PCI_EXP_DEVCTL_NFERE |
533 PCI_EXP_DEVCTL_FERE | 533 PCI_EXP_DEVCTL_FERE |
534 PCI_EXP_DEVCTL_URRE; 534 PCI_EXP_DEVCTL_URRE;
535 pci_write_config_word(pdev, pos+PCI_EXP_DEVCTL, 535 pci_write_config_word(pdev, pos+PCI_EXP_DEVCTL,
536 reg16); 536 reg16);
537 537
538 /* Enable Root Port's interrupt in response to error messages */ 538 /* Enable Root Port's interrupt in response to error messages */
539 pci_write_config_dword(pdev, 539 pci_write_config_dword(pdev,
540 aer_pos + PCI_ERR_ROOT_COMMAND, 540 aer_pos + PCI_ERR_ROOT_COMMAND,
541 ROOT_PORT_INTR_ON_MESG_MASK); 541 ROOT_PORT_INTR_ON_MESG_MASK);
542 } 542 }
543 543
544 /** 544 /**
545 * disable_root_aer - disable Root Port's interrupts when receiving messages 545 * disable_root_aer - disable Root Port's interrupts when receiving messages
546 * @rpc: pointer to a Root Port data structure 546 * @rpc: pointer to a Root Port data structure
547 * 547 *
548 * Invoked when PCIE bus unloads AER service driver. 548 * Invoked when PCIE bus unloads AER service driver.
549 */ 549 */
550 static void disable_root_aer(struct aer_rpc *rpc) 550 static void disable_root_aer(struct aer_rpc *rpc)
551 { 551 {
552 struct pci_dev *pdev = rpc->rpd->port; 552 struct pci_dev *pdev = rpc->rpd->port;
553 u32 reg32; 553 u32 reg32;
554 int pos; 554 int pos;
555 555
556 pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); 556 pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
557 /* Disable Root's interrupt in response to error messages */ 557 /* Disable Root's interrupt in response to error messages */
558 pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, 0); 558 pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, 0);
559 559
560 /* Clear Root's error status reg */ 560 /* Clear Root's error status reg */
561 pci_read_config_dword(pdev, pos + PCI_ERR_ROOT_STATUS, &reg32); 561 pci_read_config_dword(pdev, pos + PCI_ERR_ROOT_STATUS, &reg32);
562 pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_STATUS, reg32); 562 pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_STATUS, reg32);
563 } 563 }
564 564
565 /** 565 /**
566 * get_e_source - retrieve an error source 566 * get_e_source - retrieve an error source
567 * @rpc: pointer to the root port which holds an error 567 * @rpc: pointer to the root port which holds an error
568 * 568 *
569 * Invoked by DPC handler to consume an error. 569 * Invoked by DPC handler to consume an error.
570 */ 570 */
571 static struct aer_err_source* get_e_source(struct aer_rpc *rpc) 571 static struct aer_err_source* get_e_source(struct aer_rpc *rpc)
572 { 572 {
573 struct aer_err_source *e_source; 573 struct aer_err_source *e_source;
574 unsigned long flags; 574 unsigned long flags;
575 575
576 /* Lock access to Root error producer/consumer index */ 576 /* Lock access to Root error producer/consumer index */
577 spin_lock_irqsave(&rpc->e_lock, flags); 577 spin_lock_irqsave(&rpc->e_lock, flags);
578 if (rpc->prod_idx == rpc->cons_idx) { 578 if (rpc->prod_idx == rpc->cons_idx) {
579 spin_unlock_irqrestore(&rpc->e_lock, flags); 579 spin_unlock_irqrestore(&rpc->e_lock, flags);
580 return NULL; 580 return NULL;
581 } 581 }
582 e_source = &rpc->e_sources[rpc->cons_idx]; 582 e_source = &rpc->e_sources[rpc->cons_idx];
583 rpc->cons_idx++; 583 rpc->cons_idx++;
584 if (rpc->cons_idx == AER_ERROR_SOURCES_MAX) 584 if (rpc->cons_idx == AER_ERROR_SOURCES_MAX)
585 rpc->cons_idx = 0; 585 rpc->cons_idx = 0;
586 spin_unlock_irqrestore(&rpc->e_lock, flags); 586 spin_unlock_irqrestore(&rpc->e_lock, flags);
587 587
588 return e_source; 588 return e_source;
589 } 589 }
590 590
591 static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info) 591 static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
592 { 592 {
593 int pos; 593 int pos;
594 594
595 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); 595 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
596 596
597 /* The device might not support AER */ 597 /* The device might not support AER */
598 if (!pos) 598 if (!pos)
599 return AER_SUCCESS; 599 return AER_SUCCESS;
600 600
601 if (info->severity == AER_CORRECTABLE) { 601 if (info->severity == AER_CORRECTABLE) {
602 pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, 602 pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS,
603 &info->status); 603 &info->status);
604 if (!(info->status & ERR_CORRECTABLE_ERROR_MASK)) 604 if (!(info->status & ERR_CORRECTABLE_ERROR_MASK))
605 return AER_UNSUCCESS; 605 return AER_UNSUCCESS;
606 } else if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE || 606 } else if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE ||
607 info->severity == AER_NONFATAL) { 607 info->severity == AER_NONFATAL) {
608 608
609 /* Link is still healthy for IO reads */ 609 /* Link is still healthy for IO reads */
610 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, 610 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS,
611 &info->status); 611 &info->status);
612 if (!(info->status & ERR_UNCORRECTABLE_ERROR_MASK)) 612 if (!(info->status & ERR_UNCORRECTABLE_ERROR_MASK))
613 return AER_UNSUCCESS; 613 return AER_UNSUCCESS;
614 614
615 if (info->status & AER_LOG_TLP_MASKS) { 615 if (info->status & AER_LOG_TLP_MASKS) {
616 info->flags |= AER_TLP_HEADER_VALID_FLAG; 616 info->flags |= AER_TLP_HEADER_VALID_FLAG;
617 pci_read_config_dword(dev, 617 pci_read_config_dword(dev,
618 pos + PCI_ERR_HEADER_LOG, &info->tlp.dw0); 618 pos + PCI_ERR_HEADER_LOG, &info->tlp.dw0);
619 pci_read_config_dword(dev, 619 pci_read_config_dword(dev,
620 pos + PCI_ERR_HEADER_LOG + 4, &info->tlp.dw1); 620 pos + PCI_ERR_HEADER_LOG + 4, &info->tlp.dw1);
621 pci_read_config_dword(dev, 621 pci_read_config_dword(dev,
622 pos + PCI_ERR_HEADER_LOG + 8, &info->tlp.dw2); 622 pos + PCI_ERR_HEADER_LOG + 8, &info->tlp.dw2);
623 pci_read_config_dword(dev, 623 pci_read_config_dword(dev,
624 pos + PCI_ERR_HEADER_LOG + 12, &info->tlp.dw3); 624 pos + PCI_ERR_HEADER_LOG + 12, &info->tlp.dw3);
625 } 625 }
626 } 626 }
627 627
628 return AER_SUCCESS; 628 return AER_SUCCESS;
629 } 629 }
630 630
631 /** 631 /**
632 * aer_isr_one_error - consume an error detected by root port 632 * aer_isr_one_error - consume an error detected by root port
633 * @p_device: pointer to error root port service device 633 * @p_device: pointer to error root port service device
634 * @e_src: pointer to an error source 634 * @e_src: pointer to an error source
635 */ 635 */
636 static void aer_isr_one_error(struct pcie_device *p_device, 636 static void aer_isr_one_error(struct pcie_device *p_device,
637 struct aer_err_source *e_src) 637 struct aer_err_source *e_src)
638 { 638 {
639 struct device *s_device; 639 struct device *s_device;
640 struct aer_err_info e_info = {0, 0, 0,}; 640 struct aer_err_info e_info = {0, 0, 0,};
641 int i; 641 int i;
642 u16 id; 642 u16 id;
643 643
644 /* 644 /*
645 * There is a possibility that both correctable error and 645 * There is a possibility that both correctable error and
646 * uncorrectable error being logged. Report correctable error first. 646 * uncorrectable error being logged. Report correctable error first.
647 */ 647 */
648 for (i = 1; i & ROOT_ERR_STATUS_MASKS ; i <<= 2) { 648 for (i = 1; i & ROOT_ERR_STATUS_MASKS ; i <<= 2) {
649 if (i > 4) 649 if (i > 4)
650 break; 650 break;
651 if (!(e_src->status & i)) 651 if (!(e_src->status & i))
652 continue; 652 continue;
653 653
654 /* Init comprehensive error information */ 654 /* Init comprehensive error information */
655 if (i & PCI_ERR_ROOT_COR_RCV) { 655 if (i & PCI_ERR_ROOT_COR_RCV) {
656 id = ERR_COR_ID(e_src->id); 656 id = ERR_COR_ID(e_src->id);
657 e_info.severity = AER_CORRECTABLE; 657 e_info.severity = AER_CORRECTABLE;
658 } else { 658 } else {
659 id = ERR_UNCOR_ID(e_src->id); 659 id = ERR_UNCOR_ID(e_src->id);
660 e_info.severity = ((e_src->status >> 6) & 1); 660 e_info.severity = ((e_src->status >> 6) & 1);
661 } 661 }
662 if (e_src->status & 662 if (e_src->status &
663 (PCI_ERR_ROOT_MULTI_COR_RCV | 663 (PCI_ERR_ROOT_MULTI_COR_RCV |
664 PCI_ERR_ROOT_MULTI_UNCOR_RCV)) 664 PCI_ERR_ROOT_MULTI_UNCOR_RCV))
665 e_info.flags |= AER_MULTI_ERROR_VALID_FLAG; 665 e_info.flags |= AER_MULTI_ERROR_VALID_FLAG;
666 if (!(s_device = find_source_device(p_device->port, id))) { 666 if (!(s_device = find_source_device(p_device->port, id))) {
667 printk(KERN_DEBUG "%s->can't find device of ID%04x\n", 667 printk(KERN_DEBUG "%s->can't find device of ID%04x\n",
668 __func__, id); 668 __func__, id);
669 continue; 669 continue;
670 } 670 }
671 if (get_device_error_info(to_pci_dev(s_device), &e_info) == 671 if (get_device_error_info(to_pci_dev(s_device), &e_info) ==
672 AER_SUCCESS) { 672 AER_SUCCESS) {
673 aer_print_error(to_pci_dev(s_device), &e_info); 673 aer_print_error(to_pci_dev(s_device), &e_info);
674 handle_error_source(p_device, 674 handle_error_source(p_device,
675 to_pci_dev(s_device), 675 to_pci_dev(s_device),
676 e_info); 676 e_info);
677 } 677 }
678 } 678 }
679 } 679 }
680 680
681 /** 681 /**
682 * aer_isr - consume errors detected by root port 682 * aer_isr - consume errors detected by root port
683 * @work: definition of this work item 683 * @work: definition of this work item
684 * 684 *
685 * Invoked, as DPC, when root port records new detected error 685 * Invoked, as DPC, when root port records new detected error
686 */ 686 */
687 void aer_isr(struct work_struct *work) 687 void aer_isr(struct work_struct *work)
688 { 688 {
689 struct aer_rpc *rpc = container_of(work, struct aer_rpc, dpc_handler); 689 struct aer_rpc *rpc = container_of(work, struct aer_rpc, dpc_handler);
690 struct pcie_device *p_device = rpc->rpd; 690 struct pcie_device *p_device = rpc->rpd;
691 struct aer_err_source *e_src; 691 struct aer_err_source *e_src;
692 692
693 mutex_lock(&rpc->rpc_mutex); 693 mutex_lock(&rpc->rpc_mutex);
694 e_src = get_e_source(rpc); 694 e_src = get_e_source(rpc);
695 while (e_src) { 695 while (e_src) {
696 aer_isr_one_error(p_device, e_src); 696 aer_isr_one_error(p_device, e_src);
697 e_src = get_e_source(rpc); 697 e_src = get_e_source(rpc);
698 } 698 }
699 mutex_unlock(&rpc->rpc_mutex); 699 mutex_unlock(&rpc->rpc_mutex);
700 700
701 wake_up(&rpc->wait_release); 701 wake_up(&rpc->wait_release);
702 } 702 }
703 703
704 /** 704 /**
705 * aer_delete_rootport - disable root port aer and delete service data 705 * aer_delete_rootport - disable root port aer and delete service data
706 * @rpc: pointer to a root port device being deleted 706 * @rpc: pointer to a root port device being deleted
707 * 707 *
708 * Invoked when AER service unloaded on a specific Root Port 708 * Invoked when AER service unloaded on a specific Root Port
709 */ 709 */
710 void aer_delete_rootport(struct aer_rpc *rpc) 710 void aer_delete_rootport(struct aer_rpc *rpc)
711 { 711 {
712 /* Disable root port AER itself */ 712 /* Disable root port AER itself */
713 disable_root_aer(rpc); 713 disable_root_aer(rpc);
714 714
715 kfree(rpc); 715 kfree(rpc);
716 } 716 }
717 717
718 /** 718 /**
719 * aer_init - provide AER initialization 719 * aer_init - provide AER initialization
720 * @dev: pointer to AER pcie device 720 * @dev: pointer to AER pcie device
721 * 721 *
722 * Invoked when AER service driver is loaded. 722 * Invoked when AER service driver is loaded.
723 */ 723 */
724 int aer_init(struct pcie_device *dev) 724 int aer_init(struct pcie_device *dev)
725 { 725 {
726 if (aer_osc_setup(dev) && !forceload) 726 if (aer_osc_setup(dev) && !forceload)
727 return -ENXIO; 727 return -ENXIO;
728 728
729 return AER_SUCCESS; 729 return AER_SUCCESS;
730 } 730 }
731 731
732 EXPORT_SYMBOL_GPL(pci_enable_pcie_error_reporting); 732 EXPORT_SYMBOL_GPL(pci_enable_pcie_error_reporting);
733 EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting); 733 EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting);
734 EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status); 734 EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status);
735 735
736 736
drivers/pci/pcie/portdrv.h
1 /* 1 /*
2 * File: portdrv.h 2 * File: portdrv.h
3 * Purpose: PCI Express Port Bus Driver's Internal Data Structures 3 * Purpose: PCI Express Port Bus Driver's Internal Data Structures
4 * 4 *
5 * Copyright (C) 2004 Intel 5 * Copyright (C) 2004 Intel
6 * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) 6 * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
7 */ 7 */
8 8
9 #ifndef _PORTDRV_H_ 9 #ifndef _PORTDRV_H_
10 #define _PORTDRV_H_ 10 #define _PORTDRV_H_
11 11
12 #include <linux/compiler.h> 12 #include <linux/compiler.h>
13 13
14 #if !defined(PCI_CAP_ID_PME) 14 #if !defined(PCI_CAP_ID_PME)
15 #define PCI_CAP_ID_PME 1 15 #define PCI_CAP_ID_PME 1
16 #endif 16 #endif
17 17
18 #if !defined(PCI_CAP_ID_EXP) 18 #if !defined(PCI_CAP_ID_EXP)
19 #define PCI_CAP_ID_EXP 0x10 19 #define PCI_CAP_ID_EXP 0x10
20 #endif 20 #endif
21 21
22 #define PORT_TYPE_MASK 0xf 22 #define PORT_TYPE_MASK 0xf
23 #define PORT_TO_SLOT_MASK 0x100 23 #define PORT_TO_SLOT_MASK 0x100
24 #define SLOT_HP_CAPABLE_MASK 0x40 24 #define SLOT_HP_CAPABLE_MASK 0x40
25 #define PCIE_CAPABILITIES_REG 0x2 25 #define PCIE_CAPABILITIES_REG 0x2
26 #define PCIE_SLOT_CAPABILITIES_REG 0x14 26 #define PCIE_SLOT_CAPABILITIES_REG 0x14
27 #define PCIE_PORT_DEVICE_MAXSERVICES 4 27 #define PCIE_PORT_DEVICE_MAXSERVICES 4
28 #define PCI_CFG_SPACE_SIZE 256
29 28
30 #define get_descriptor_id(type, service) (((type - 4) << 4) | service) 29 #define get_descriptor_id(type, service) (((type - 4) << 4) | service)
31 30
32 struct pcie_port_device_ext { 31 struct pcie_port_device_ext {
33 int interrupt_mode; /* [0:INTx | 1:MSI | 2:MSI-X] */ 32 int interrupt_mode; /* [0:INTx | 1:MSI | 2:MSI-X] */
34 }; 33 };
35 34
36 extern struct bus_type pcie_port_bus_type; 35 extern struct bus_type pcie_port_bus_type;
37 extern int pcie_port_device_probe(struct pci_dev *dev); 36 extern int pcie_port_device_probe(struct pci_dev *dev);
38 extern int pcie_port_device_register(struct pci_dev *dev); 37 extern int pcie_port_device_register(struct pci_dev *dev);
39 #ifdef CONFIG_PM 38 #ifdef CONFIG_PM
40 extern int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state); 39 extern int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state);
41 extern int pcie_port_device_resume(struct pci_dev *dev); 40 extern int pcie_port_device_resume(struct pci_dev *dev);
42 #endif 41 #endif
43 extern void pcie_port_device_remove(struct pci_dev *dev); 42 extern void pcie_port_device_remove(struct pci_dev *dev);
44 extern int __must_check pcie_port_bus_register(void); 43 extern int __must_check pcie_port_bus_register(void);
45 extern void pcie_port_bus_unregister(void); 44 extern void pcie_port_bus_unregister(void);
46 45
47 #endif /* _PORTDRV_H_ */ 46 #endif /* _PORTDRV_H_ */
48 47
1 /* 1 /*
2 * Copyright (C) 2006 Intel Corp. 2 * Copyright (C) 2006 Intel Corp.
3 * Tom Long Nguyen (tom.l.nguyen@intel.com) 3 * Tom Long Nguyen (tom.l.nguyen@intel.com)
4 * Zhang Yanmin (yanmin.zhang@intel.com) 4 * Zhang Yanmin (yanmin.zhang@intel.com)
5 */ 5 */
6 6
7 #ifndef _AER_H_ 7 #ifndef _AER_H_
8 #define _AER_H_ 8 #define _AER_H_
9 9
10 #if defined(CONFIG_PCIEAER) 10 #if defined(CONFIG_PCIEAER)
11 /* pci-e port driver needs this function to enable aer */ 11 /* pci-e port driver needs this function to enable aer */
12 extern int pci_enable_pcie_error_reporting(struct pci_dev *dev); 12 extern int pci_enable_pcie_error_reporting(struct pci_dev *dev);
13 extern int pci_find_aer_capability(struct pci_dev *dev);
14 extern int pci_disable_pcie_error_reporting(struct pci_dev *dev); 13 extern int pci_disable_pcie_error_reporting(struct pci_dev *dev);
15 extern int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev); 14 extern int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev);
16 #else 15 #else
17 static inline int pci_enable_pcie_error_reporting(struct pci_dev *dev) 16 static inline int pci_enable_pcie_error_reporting(struct pci_dev *dev)
18 { 17 {
19 return -EINVAL; 18 return -EINVAL;
20 } 19 }
21 static inline int pci_disable_pcie_error_reporting(struct pci_dev *dev) 20 static inline int pci_disable_pcie_error_reporting(struct pci_dev *dev)
22 { 21 {
23 return -EINVAL; 22 return -EINVAL;
24 } 23 }
25 static inline int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev) 24 static inline int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev)
26 { 25 {
27 return -EINVAL; 26 return -EINVAL;
28 } 27 }
29 #endif 28 #endif
30 29
31 #endif //_AER_H_ 30 #endif //_AER_H_
32 31
33 32