1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include <linux/pci.h>
26#include <linux/stat.h>
27#include <asm/ppc-pci.h>
28#include <asm/pci-bridge.h>
29
30
31
32
33
34
35
36
37
38
39#define EEH_SHOW_ATTR(_name,_memb,_format) \
40static ssize_t eeh_show_##_name(struct device *dev, \
41 struct device_attribute *attr, char *buf) \
42{ \
43 struct pci_dev *pdev = to_pci_dev(dev); \
44 struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev); \
45 \
46 if (!edev) \
47 return 0; \
48 \
49 return sprintf(buf, _format "\n", edev->_memb); \
50} \
51static DEVICE_ATTR(_name, S_IRUGO, eeh_show_##_name, NULL);
52
53EEH_SHOW_ATTR(eeh_mode, mode, "0x%x");
54EEH_SHOW_ATTR(eeh_config_addr, config_addr, "0x%x");
55EEH_SHOW_ATTR(eeh_pe_config_addr, pe_config_addr, "0x%x");
56
57void eeh_sysfs_add_device(struct pci_dev *pdev)
58{
59 struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev);
60 int rc=0;
61
62 if (edev && (edev->mode & EEH_DEV_SYSFS))
63 return;
64
65 rc += device_create_file(&pdev->dev, &dev_attr_eeh_mode);
66 rc += device_create_file(&pdev->dev, &dev_attr_eeh_config_addr);
67 rc += device_create_file(&pdev->dev, &dev_attr_eeh_pe_config_addr);
68
69 if (rc)
70 printk(KERN_WARNING "EEH: Unable to create sysfs entries\n");
71 else if (edev)
72 edev->mode |= EEH_DEV_SYSFS;
73}
74
75void eeh_sysfs_remove_device(struct pci_dev *pdev)
76{
77 struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev);
78
79
80
81
82
83 if (!pdev->dev.kobj.sd) {
84 if (edev)
85 edev->mode &= ~EEH_DEV_SYSFS;
86 return;
87 }
88
89 device_remove_file(&pdev->dev, &dev_attr_eeh_mode);
90 device_remove_file(&pdev->dev, &dev_attr_eeh_config_addr);
91 device_remove_file(&pdev->dev, &dev_attr_eeh_pe_config_addr);
92
93 if (edev)
94 edev->mode &= ~EEH_DEV_SYSFS;
95}
96