aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorAndrew Patterson <andrew.patterson@hp.com>2009-10-12 15:14:05 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-11-04 16:06:37 -0500
commitcc5d153a0ca794e3781ef34c76f32ad3e991b13d (patch)
tree61feef82ec34c5f6489abe6db95fae8d03a43d0b /drivers/pci
parent3c299dc22635e500214707aa28be119ff2b3901c (diff)
PCI: add support for PCI domains to aer_inject
Add support for PCI domains (segments) to aer_inject. Acked-by: Huang Ying <ying.huang@intel.com> Signed-off-by: Andrew Patterson <andrew.patterson@hp.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/pcie/aer/aer_inject.c46
1 files changed, 34 insertions, 12 deletions
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c
index 62d15f652bb6..ac0b5e7bb3f5 100644
--- a/drivers/pci/pcie/aer/aer_inject.c
+++ b/drivers/pci/pcie/aer/aer_inject.c
@@ -23,6 +23,7 @@
23#include <linux/pci.h> 23#include <linux/pci.h>
24#include <linux/fs.h> 24#include <linux/fs.h>
25#include <linux/uaccess.h> 25#include <linux/uaccess.h>
26#include <linux/stddef.h>
26#include "aerdrv.h" 27#include "aerdrv.h"
27 28
28struct aer_error_inj { 29struct aer_error_inj {
@@ -35,10 +36,12 @@ struct aer_error_inj {
35 u32 header_log1; 36 u32 header_log1;
36 u32 header_log2; 37 u32 header_log2;
37 u32 header_log3; 38 u32 header_log3;
39 u16 domain;
38}; 40};
39 41
40struct aer_error { 42struct aer_error {
41 struct list_head list; 43 struct list_head list;
44 u16 domain;
42 unsigned int bus; 45 unsigned int bus;
43 unsigned int devfn; 46 unsigned int devfn;
44 int pos_cap_err; 47 int pos_cap_err;
@@ -66,22 +69,27 @@ static LIST_HEAD(pci_bus_ops_list);
66/* Protect einjected and pci_bus_ops_list */ 69/* Protect einjected and pci_bus_ops_list */
67static DEFINE_SPINLOCK(inject_lock); 70static DEFINE_SPINLOCK(inject_lock);
68 71
69static void aer_error_init(struct aer_error *err, unsigned int bus, 72static void aer_error_init(struct aer_error *err, u16 domain,
70 unsigned int devfn, int pos_cap_err) 73 unsigned int bus, unsigned int devfn,
74 int pos_cap_err)
71{ 75{
72 INIT_LIST_HEAD(&err->list); 76 INIT_LIST_HEAD(&err->list);
77 err->domain = domain;
73 err->bus = bus; 78 err->bus = bus;
74 err->devfn = devfn; 79 err->devfn = devfn;
75 err->pos_cap_err = pos_cap_err; 80 err->pos_cap_err = pos_cap_err;
76} 81}
77 82
78/* inject_lock must be held before calling */ 83/* inject_lock must be held before calling */
79static struct aer_error *__find_aer_error(unsigned int bus, unsigned int devfn) 84static struct aer_error *__find_aer_error(u16 domain, unsigned int bus,
85 unsigned int devfn)
80{ 86{
81 struct aer_error *err; 87 struct aer_error *err;
82 88
83 list_for_each_entry(err, &einjected, list) { 89 list_for_each_entry(err, &einjected, list) {
84 if (bus == err->bus && devfn == err->devfn) 90 if (domain == err->domain &&
91 bus == err->bus &&
92 devfn == err->devfn)
85 return err; 93 return err;
86 } 94 }
87 return NULL; 95 return NULL;
@@ -90,7 +98,10 @@ static struct aer_error *__find_aer_error(unsigned int bus, unsigned int devfn)
90/* inject_lock must be held before calling */ 98/* inject_lock must be held before calling */
91static struct aer_error *__find_aer_error_by_dev(struct pci_dev *dev) 99static struct aer_error *__find_aer_error_by_dev(struct pci_dev *dev)
92{ 100{
93 return __find_aer_error(dev->bus->number, dev->devfn); 101 int domain = pci_domain_nr(dev->bus);
102 if (domain < 0)
103 return NULL;
104 return __find_aer_error((u16)domain, dev->bus->number, dev->devfn);
94} 105}
95 106
96/* inject_lock must be held before calling */ 107/* inject_lock must be held before calling */
@@ -172,11 +183,15 @@ static int pci_read_aer(struct pci_bus *bus, unsigned int devfn, int where,
172 struct aer_error *err; 183 struct aer_error *err;
173 unsigned long flags; 184 unsigned long flags;
174 struct pci_ops *ops; 185 struct pci_ops *ops;
186 int domain;
175 187
176 spin_lock_irqsave(&inject_lock, flags); 188 spin_lock_irqsave(&inject_lock, flags);
177 if (size != sizeof(u32)) 189 if (size != sizeof(u32))
178 goto out; 190 goto out;
179 err = __find_aer_error(bus->number, devfn); 191 domain = pci_domain_nr(bus);
192 if (domain < 0)
193 goto out;
194 err = __find_aer_error((u16)domain, bus->number, devfn);
180 if (!err) 195 if (!err)
181 goto out; 196 goto out;
182 197
@@ -200,11 +215,15 @@ int pci_write_aer(struct pci_bus *bus, unsigned int devfn, int where, int size,
200 unsigned long flags; 215 unsigned long flags;
201 int rw1cs; 216 int rw1cs;
202 struct pci_ops *ops; 217 struct pci_ops *ops;
218 int domain;
203 219
204 spin_lock_irqsave(&inject_lock, flags); 220 spin_lock_irqsave(&inject_lock, flags);
205 if (size != sizeof(u32)) 221 if (size != sizeof(u32))
206 goto out; 222 goto out;
207 err = __find_aer_error(bus->number, devfn); 223 domain = pci_domain_nr(bus);
224 if (domain < 0)
225 goto out;
226 err = __find_aer_error((u16)domain, bus->number, devfn);
208 if (!err) 227 if (!err)
209 goto out; 228 goto out;
210 229
@@ -305,7 +324,7 @@ static int aer_inject(struct aer_error_inj *einj)
305 u32 sever; 324 u32 sever;
306 int ret = 0; 325 int ret = 0;
307 326
308 dev = pci_get_bus_and_slot(einj->bus, devfn); 327 dev = pci_get_domain_bus_and_slot((int)einj->domain, einj->bus, devfn);
309 if (!dev) 328 if (!dev)
310 return -EINVAL; 329 return -EINVAL;
311 rpdev = pcie_find_root_port(dev); 330 rpdev = pcie_find_root_port(dev);
@@ -344,7 +363,8 @@ static int aer_inject(struct aer_error_inj *einj)
344 if (!err) { 363 if (!err) {
345 err = err_alloc; 364 err = err_alloc;
346 err_alloc = NULL; 365 err_alloc = NULL;
347 aer_error_init(err, einj->bus, devfn, pos_cap_err); 366 aer_error_init(err, einj->domain, einj->bus, devfn,
367 pos_cap_err);
348 list_add(&err->list, &einjected); 368 list_add(&err->list, &einjected);
349 } 369 }
350 err->uncor_status |= einj->uncor_status; 370 err->uncor_status |= einj->uncor_status;
@@ -358,7 +378,8 @@ static int aer_inject(struct aer_error_inj *einj)
358 if (!rperr) { 378 if (!rperr) {
359 rperr = rperr_alloc; 379 rperr = rperr_alloc;
360 rperr_alloc = NULL; 380 rperr_alloc = NULL;
361 aer_error_init(rperr, rpdev->bus->number, rpdev->devfn, 381 aer_error_init(rperr, pci_domain_nr(rpdev->bus),
382 rpdev->bus->number, rpdev->devfn,
362 rp_pos_cap_err); 383 rp_pos_cap_err);
363 list_add(&rperr->list, &einjected); 384 list_add(&rperr->list, &einjected);
364 } 385 }
@@ -411,10 +432,11 @@ static ssize_t aer_inject_write(struct file *filp, const char __user *ubuf,
411 432
412 if (!capable(CAP_SYS_ADMIN)) 433 if (!capable(CAP_SYS_ADMIN))
413 return -EPERM; 434 return -EPERM;
414 435 if (usize < offsetof(struct aer_error_inj, domain) ||
415 if (usize != sizeof(struct aer_error_inj)) 436 usize > sizeof(einj))
416 return -EINVAL; 437 return -EINVAL;
417 438
439 memset(&einj, 0, sizeof(einj));
418 if (copy_from_user(&einj, ubuf, usize)) 440 if (copy_from_user(&einj, ubuf, usize))
419 return -EFAULT; 441 return -EFAULT;
420 442