aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/edac_pci_sysfs.c
diff options
context:
space:
mode:
authorDave Jiang <djiang@mvista.com>2007-07-19 04:49:52 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-19 13:04:54 -0400
commit91b99041c1d577ded1da599ddc28cec2e07253cf (patch)
tree21b132d19166dca5c363b98e20741b78df4ad68a /drivers/edac/edac_pci_sysfs.c
parent81d87cb13e367bb804bf44889ae0de7369705d6c (diff)
drivers/edac: updated PCI monitoring
Moving PCI to a per-instance device model This should include the correct sysfs setup as well. Please review. Signed-off-by: Dave Jiang <djiang@mvista.com> Signed-off-by: Douglas Thompson <dougthompson@xmission.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/edac/edac_pci_sysfs.c')
-rw-r--r--drivers/edac/edac_pci_sysfs.c279
1 files changed, 255 insertions, 24 deletions
diff --git a/drivers/edac/edac_pci_sysfs.c b/drivers/edac/edac_pci_sysfs.c
index 9388eaa794be..0b179e0fd112 100644
--- a/drivers/edac/edac_pci_sysfs.c
+++ b/drivers/edac/edac_pci_sysfs.c
@@ -15,13 +15,142 @@
15 15
16 16
17#ifdef CONFIG_PCI 17#ifdef CONFIG_PCI
18static int check_pci_parity = 0; /* default YES check PCI parity */ 18
19static int panic_on_pci_parity; /* default no panic on PCI Parity */ 19#define EDAC_PCI_SYMLINK "device"
20
21static int check_pci_errors = 0; /* default YES check PCI parity */
22static int panic_on_pci_parity = 0; /* default no panic on PCI Parity */
23static int log_pci_errs = 1;
20static atomic_t pci_parity_count = ATOMIC_INIT(0); 24static atomic_t pci_parity_count = ATOMIC_INIT(0);
25static atomic_t pci_nonparity_count = ATOMIC_INIT(0);
21 26
22static struct kobject edac_pci_kobj; /* /sys/devices/system/edac/pci */ 27static struct kobject edac_pci_kobj; /* /sys/devices/system/edac/pci */
23static struct completion edac_pci_kobj_complete; 28static struct completion edac_pci_kobj_complete;
29static atomic_t edac_pci_sysfs_refcount = ATOMIC_INIT(0);
30
31/**************************** EDAC PCI sysfs instance *******************/
32static ssize_t instance_pe_count_show(struct edac_pci_ctl_info *pci, char *data)
33{
34 return sprintf(data,"%u\n", atomic_read(&pci->counters.pe_count));
35}
36
37static ssize_t instance_npe_count_show(struct edac_pci_ctl_info *pci,
38 char *data)
39{
40 return sprintf(data,"%u\n", atomic_read(&pci->counters.npe_count));
41}
42
43#define to_instance(k) container_of(k, struct edac_pci_ctl_info, kobj)
44#define to_instance_attr(a) container_of(a, struct instance_attribute, attr)
45
46/* DEVICE instance kobject release() function */
47static void edac_pci_instance_release(struct kobject *kobj)
48{
49 struct edac_pci_ctl_info *pci;
50
51 debugf1("%s()\n", __func__);
52
53 pci = to_instance(kobj);
54 complete(&pci->kobj_complete);
55}
56
57/* instance specific attribute structure */
58struct instance_attribute {
59 struct attribute attr;
60 ssize_t (*show)(struct edac_pci_ctl_info *, char *);
61 ssize_t (*store)(struct edac_pci_ctl_info *, const char *, size_t);
62};
63
64/* Function to 'show' fields from the edac_pci 'instance' structure */
65static ssize_t edac_pci_instance_show(struct kobject *kobj,
66 struct attribute *attr,
67 char *buffer)
68{
69 struct edac_pci_ctl_info *pci = to_instance(kobj);
70 struct instance_attribute *instance_attr = to_instance_attr(attr);
71
72 if (instance_attr->show)
73 return instance_attr->show(pci, buffer);
74 return -EIO;
75}
76
77
78/* Function to 'store' fields into the edac_pci 'instance' structure */
79static ssize_t edac_pci_instance_store(struct kobject *kobj,
80 struct attribute *attr,
81 const char *buffer, size_t count)
82{
83 struct edac_pci_ctl_info *pci = to_instance(kobj);
84 struct instance_attribute *instance_attr = to_instance_attr(attr);
85
86 if (instance_attr->store)
87 return instance_attr->store(pci, buffer, count);
88 return -EIO;
89}
90
91static struct sysfs_ops pci_instance_ops = {
92 .show = edac_pci_instance_show,
93 .store = edac_pci_instance_store
94};
95
96#define INSTANCE_ATTR(_name, _mode, _show, _store) \
97static struct instance_attribute attr_instance_##_name = { \
98 .attr = {.name = __stringify(_name), .mode = _mode }, \
99 .show = _show, \
100 .store = _store, \
101};
102
103INSTANCE_ATTR(pe_count, S_IRUGO, instance_pe_count_show, NULL);
104INSTANCE_ATTR(npe_count, S_IRUGO, instance_npe_count_show, NULL);
105
106/* pci instance attributes */
107static struct instance_attribute *pci_instance_attr[] = {
108 &attr_instance_pe_count,
109 &attr_instance_npe_count,
110 NULL
111};
24 112
113/* the ktype for pci instance */
114static struct kobj_type ktype_pci_instance = {
115 .release = edac_pci_instance_release,
116 .sysfs_ops = &pci_instance_ops,
117 .default_attrs = (struct attribute **)pci_instance_attr,
118};
119
120static int edac_pci_create_instance_kobj(struct edac_pci_ctl_info *pci, int idx)
121{
122 int err;
123
124 pci->kobj.parent = &edac_pci_kobj;
125 pci->kobj.ktype = &ktype_pci_instance;
126
127 err = kobject_set_name(&pci->kobj, "pci%d", idx);
128 if (err)
129 return err;
130
131 err = kobject_register(&pci->kobj);
132 if (err != 0) {
133 debugf2("%s() failed to register instance pci%d\n",
134 __func__, idx);
135 return err;
136 }
137
138 debugf1("%s() Register instance 'pci%d' kobject\n", __func__, idx);
139
140 return 0;
141}
142
143static void
144edac_pci_delete_instance_kobj(struct edac_pci_ctl_info *pci, int idx)
145{
146 init_completion(&pci->kobj_complete);
147 kobject_unregister(&pci->kobj);
148 wait_for_completion(&pci->kobj_complete);
149}
150
151/***************************** EDAC PCI sysfs root **********************/
152#define to_edacpci(k) container_of(k, struct edac_pci_ctl_info, kobj)
153#define to_edacpci_attr(a) container_of(a, struct edac_pci_attr, attr)
25 154
26static ssize_t edac_pci_int_show(void *ptr, char *buffer) 155static ssize_t edac_pci_int_show(void *ptr, char *buffer)
27{ 156{
@@ -91,25 +220,34 @@ static struct edac_pci_dev_attribute edac_pci_attr_##_name = { \
91}; 220};
92 221
93/* PCI Parity control files */ 222/* PCI Parity control files */
94EDAC_PCI_ATTR(check_pci_parity, S_IRUGO|S_IWUSR, edac_pci_int_show, 223EDAC_PCI_ATTR(check_pci_errors, S_IRUGO|S_IWUSR, edac_pci_int_show,
224 edac_pci_int_store);
225EDAC_PCI_ATTR(log_pci_errs, S_IRUGO|S_IWUSR, edac_pci_int_show,
95 edac_pci_int_store); 226 edac_pci_int_store);
96EDAC_PCI_ATTR(panic_on_pci_parity, S_IRUGO|S_IWUSR, edac_pci_int_show, 227EDAC_PCI_ATTR(panic_on_pci_parity, S_IRUGO|S_IWUSR, edac_pci_int_show,
97 edac_pci_int_store); 228 edac_pci_int_store);
98EDAC_PCI_ATTR(pci_parity_count, S_IRUGO, edac_pci_int_show, NULL); 229EDAC_PCI_ATTR(pci_parity_count, S_IRUGO, edac_pci_int_show, NULL);
230EDAC_PCI_ATTR(pci_nonparity_count, S_IRUGO, edac_pci_int_show, NULL);
99 231
100/* Base Attributes of the memory ECC object */ 232/* Base Attributes of the memory ECC object */
101static struct edac_pci_dev_attribute *edac_pci_attr[] = { 233static struct edac_pci_dev_attribute *edac_pci_attr[] = {
102 &edac_pci_attr_check_pci_parity, 234 &edac_pci_attr_check_pci_errors,
235 &edac_pci_attr_log_pci_errs,
103 &edac_pci_attr_panic_on_pci_parity, 236 &edac_pci_attr_panic_on_pci_parity,
104 &edac_pci_attr_pci_parity_count, 237 &edac_pci_attr_pci_parity_count,
238 &edac_pci_attr_pci_nonparity_count,
105 NULL, 239 NULL,
106}; 240};
107 241
108/* No memory to release */ 242/* No memory to release */
109static void edac_pci_release(struct kobject *kobj) 243static void edac_pci_release(struct kobject *kobj)
110{ 244{
245 struct edac_pci_ctl_info *pci;
246
247 pci = to_edacpci(kobj);
248
111 debugf1("%s()\n", __func__); 249 debugf1("%s()\n", __func__);
112 complete(&edac_pci_kobj_complete); 250 complete(&pci->kobj_complete);
113} 251}
114 252
115static struct kobj_type ktype_edac_pci = { 253static struct kobj_type ktype_edac_pci = {
@@ -124,7 +262,7 @@ static struct kobj_type ktype_edac_pci = {
124 * setup the sysfs for EDAC PCI attributes 262 * setup the sysfs for EDAC PCI attributes
125 * assumes edac_class has already been initialized 263 * assumes edac_class has already been initialized
126 */ 264 */
127int edac_sysfs_pci_setup(void) 265int edac_pci_register_main_kobj(void)
128{ 266{
129 int err; 267 int err;
130 struct sysdev_class *edac_class; 268 struct sysdev_class *edac_class;
@@ -132,32 +270,39 @@ int edac_sysfs_pci_setup(void)
132 debugf1("%s()\n", __func__); 270 debugf1("%s()\n", __func__);
133 271
134 edac_class = edac_get_edac_class(); 272 edac_class = edac_get_edac_class();
273 if (edac_class == NULL) {
274 debugf1("%s() no edac_class\n", __func__);
275 return -ENODEV;
276 }
135 277
136 memset(&edac_pci_kobj, 0, sizeof(edac_pci_kobj));
137 edac_pci_kobj.parent = &edac_class->kset.kobj;
138 edac_pci_kobj.ktype = &ktype_edac_pci; 278 edac_pci_kobj.ktype = &ktype_edac_pci;
279
280 edac_pci_kobj.parent = &edac_class->kset.kobj;
281
139 err = kobject_set_name(&edac_pci_kobj, "pci"); 282 err = kobject_set_name(&edac_pci_kobj, "pci");
283 if(err)
284 return err;
140 285
141 if (!err) { 286 /* Instanstiate the pci object */
142 /* Instanstiate the pci object */ 287 /* FIXME: maybe new sysdev_create_subdir() */
143 /* FIXME: maybe new sysdev_create_subdir() */ 288 err = kobject_register(&edac_pci_kobj);
144 err = kobject_register(&edac_pci_kobj);
145 289
146 if (err) 290 if (err) {
147 debugf1("Failed to register '.../edac/pci'\n"); 291 debugf1("Failed to register '.../edac/pci'\n");
148 else 292 return err;
149 debugf1("Registered '.../edac/pci' kobject\n");
150 } 293 }
151 294
152 return err; 295 debugf1("Registered '.../edac/pci' kobject\n");
296
297 return 0;
153} 298}
154 299
155/* 300/*
156 * edac_sysfs_pci_teardown 301 * edac_pci_unregister_main_kobj()
157 * 302 *
158 * perform the sysfs teardown for the PCI attributes 303 * perform the sysfs teardown for the PCI attributes
159 */ 304 */
160void edac_sysfs_pci_teardown(void) 305void edac_pci_unregister_main_kobj(void)
161{ 306{
162 debugf0("%s()\n", __func__); 307 debugf0("%s()\n", __func__);
163 init_completion(&edac_pci_kobj_complete); 308 init_completion(&edac_pci_kobj_complete);
@@ -165,7 +310,53 @@ void edac_sysfs_pci_teardown(void)
165 wait_for_completion(&edac_pci_kobj_complete); 310 wait_for_completion(&edac_pci_kobj_complete);
166} 311}
167 312
313int edac_pci_create_sysfs(struct edac_pci_ctl_info *pci)
314{
315 int err;
316 struct kobject *edac_kobj = &pci->kobj;
317
318 if (atomic_inc_return(&edac_pci_sysfs_refcount) == 1) {
319 err = edac_pci_register_main_kobj();
320 if (err) {
321 atomic_dec(&edac_pci_sysfs_refcount);
322 return err;
323 }
324 }
325
326 err = edac_pci_create_instance_kobj(pci, pci->pci_idx);
327 if (err) {
328 if (atomic_dec_return(&edac_pci_sysfs_refcount) == 0)
329 edac_pci_unregister_main_kobj();
330 }
168 331
332
333 debugf0("%s() idx=%d\n", __func__, pci->pci_idx);
334
335 err = sysfs_create_link(edac_kobj,
336 &pci->dev->kobj,
337 EDAC_PCI_SYMLINK);
338 if (err) {
339 debugf0("%s() sysfs_create_link() returned err= %d\n",
340 __func__, err);
341 return err;
342 }
343
344 return 0;
345}
346
347void edac_pci_remove_sysfs(struct edac_pci_ctl_info *pci)
348{
349 debugf0("%s()\n", __func__);
350
351 edac_pci_delete_instance_kobj(pci, pci->pci_idx);
352
353 sysfs_remove_link(&pci->kobj, EDAC_PCI_SYMLINK);
354
355 if (atomic_dec_return(&edac_pci_sysfs_refcount) == 0)
356 edac_pci_unregister_main_kobj();
357}
358
359/************************ PCI error handling *************************/
169static u16 get_pci_parity_status(struct pci_dev *dev, int secondary) 360static u16 get_pci_parity_status(struct pci_dev *dev, int secondary)
170{ 361{
171 int where; 362 int where;
@@ -231,10 +422,12 @@ static void edac_pci_dev_parity_test(struct pci_dev *dev)
231 422
232 /* check the status reg for errors */ 423 /* check the status reg for errors */
233 if (status) { 424 if (status) {
234 if (status & (PCI_STATUS_SIG_SYSTEM_ERROR)) 425 if (status & (PCI_STATUS_SIG_SYSTEM_ERROR)) {
235 edac_printk(KERN_CRIT, EDAC_PCI, 426 edac_printk(KERN_CRIT, EDAC_PCI,
236 "Signaled System Error on %s\n", 427 "Signaled System Error on %s\n",
237 pci_name(dev)); 428 pci_name(dev));
429 atomic_inc(&pci_nonparity_count);
430 }
238 431
239 if (status & (PCI_STATUS_PARITY)) { 432 if (status & (PCI_STATUS_PARITY)) {
240 edac_printk(KERN_CRIT, EDAC_PCI, 433 edac_printk(KERN_CRIT, EDAC_PCI,
@@ -267,10 +460,12 @@ static void edac_pci_dev_parity_test(struct pci_dev *dev)
267 460
268 /* check the secondary status reg for errors */ 461 /* check the secondary status reg for errors */
269 if (status) { 462 if (status) {
270 if (status & (PCI_STATUS_SIG_SYSTEM_ERROR)) 463 if (status & (PCI_STATUS_SIG_SYSTEM_ERROR)) {
271 edac_printk(KERN_CRIT, EDAC_PCI, "Bridge " 464 edac_printk(KERN_CRIT, EDAC_PCI, "Bridge "
272 "Signaled System Error on %s\n", 465 "Signaled System Error on %s\n",
273 pci_name(dev)); 466 pci_name(dev));
467 atomic_inc(&pci_nonparity_count);
468 }
274 469
275 if (status & (PCI_STATUS_PARITY)) { 470 if (status & (PCI_STATUS_PARITY)) {
276 edac_printk(KERN_CRIT, EDAC_PCI, "Bridge " 471 edac_printk(KERN_CRIT, EDAC_PCI, "Bridge "
@@ -321,7 +516,7 @@ void edac_pci_do_parity_check(void)
321 516
322 debugf3("%s()\n", __func__); 517 debugf3("%s()\n", __func__);
323 518
324 if (!check_pci_parity) 519 if (!check_pci_errors)
325 return; 520 return;
326 521
327 before_count = atomic_read(&pci_parity_count); 522 before_count = atomic_read(&pci_parity_count);
@@ -348,13 +543,49 @@ void edac_pci_clear_parity_errors(void)
348 */ 543 */
349 edac_pci_dev_parity_iterator(edac_pci_dev_parity_clear); 544 edac_pci_dev_parity_iterator(edac_pci_dev_parity_clear);
350} 545}
546void edac_pci_handle_pe(struct edac_pci_ctl_info *pci, const char *msg)
547{
548
549 /* global PE counter incremented by edac_pci_do_parity_check() */
550 atomic_inc(&pci->counters.pe_count);
551
552 if (log_pci_errs)
553 edac_pci_printk(pci, KERN_WARNING,
554 "Parity Error ctl: %s %d: %s\n",
555 pci->ctl_name, pci->pci_idx, msg);
556
557 /*
558 * poke all PCI devices and see which one is the troublemaker
559 * panic() is called if set
560 */
561 edac_pci_do_parity_check();
562}
563EXPORT_SYMBOL_GPL(edac_pci_handle_pe);
351 564
565void edac_pci_handle_npe(struct edac_pci_ctl_info *pci, const char *msg)
566{
567
568 /* global NPE counter incremented by edac_pci_do_parity_check() */
569 atomic_inc(&pci->counters.npe_count);
570
571 if (log_pci_errs)
572 edac_pci_printk(pci, KERN_WARNING,
573 "Non-Parity Error ctl: %s %d: %s\n",
574 pci->ctl_name, pci->pci_idx, msg);
575
576 /*
577 * poke all PCI devices and see which one is the troublemaker
578 * panic() is called if set
579 */
580 edac_pci_do_parity_check();
581}
582EXPORT_SYMBOL_GPL(edac_pci_handle_npe);
352 583
353/* 584/*
354 * Define the PCI parameter to the module 585 * Define the PCI parameter to the module
355 */ 586 */
356module_param(check_pci_parity, int, 0644); 587module_param(check_pci_errors, int, 0644);
357MODULE_PARM_DESC(check_pci_parity, "Check for PCI bus parity errors: 0=off 1=on"); 588MODULE_PARM_DESC(check_pci_errors, "Check for PCI bus parity errors: 0=off 1=on");
358module_param(panic_on_pci_parity, int, 0644); 589module_param(panic_on_pci_parity, int, 0644);
359MODULE_PARM_DESC(panic_on_pci_parity, "Panic on PCI Bus Parity error: 0=off 1=on"); 590MODULE_PARM_DESC(panic_on_pci_parity, "Panic on PCI Bus Parity error: 0=off 1=on");
360 591