diff options
-rw-r--r-- | arch/powerpc/kernel/eeh_sysfs.c | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/eeh_sysfs.c b/arch/powerpc/kernel/eeh_sysfs.c index e2595ba4b720..eb15be4d8849 100644 --- a/arch/powerpc/kernel/eeh_sysfs.c +++ b/arch/powerpc/kernel/eeh_sysfs.c | |||
@@ -54,6 +54,62 @@ EEH_SHOW_ATTR(eeh_mode, mode, "0x%x"); | |||
54 | EEH_SHOW_ATTR(eeh_config_addr, config_addr, "0x%x"); | 54 | EEH_SHOW_ATTR(eeh_config_addr, config_addr, "0x%x"); |
55 | EEH_SHOW_ATTR(eeh_pe_config_addr, pe_config_addr, "0x%x"); | 55 | EEH_SHOW_ATTR(eeh_pe_config_addr, pe_config_addr, "0x%x"); |
56 | 56 | ||
57 | static ssize_t eeh_pe_state_show(struct device *dev, | ||
58 | struct device_attribute *attr, char *buf) | ||
59 | { | ||
60 | struct pci_dev *pdev = to_pci_dev(dev); | ||
61 | struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev); | ||
62 | int state; | ||
63 | |||
64 | if (!edev || !edev->pe) | ||
65 | return -ENODEV; | ||
66 | |||
67 | state = eeh_ops->get_state(edev->pe, NULL); | ||
68 | return sprintf(buf, "%08x %08x\n", | ||
69 | state, edev->pe->state); | ||
70 | } | ||
71 | |||
72 | static ssize_t eeh_pe_state_store(struct device *dev, | ||
73 | struct device_attribute *attr, | ||
74 | const char *buf, size_t count) | ||
75 | { | ||
76 | struct pci_dev *pdev = to_pci_dev(dev); | ||
77 | struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev); | ||
78 | int ret; | ||
79 | |||
80 | if (!edev || !edev->pe) | ||
81 | return -ENODEV; | ||
82 | |||
83 | /* Nothing to do if it's not frozen */ | ||
84 | if (!(edev->pe->state & EEH_PE_ISOLATED)) | ||
85 | return count; | ||
86 | |||
87 | /* Enable MMIO */ | ||
88 | ret = eeh_pci_enable(edev->pe, EEH_OPT_THAW_MMIO); | ||
89 | if (ret) { | ||
90 | pr_warn("%s: Failure %d enabling MMIO for PHB#%d-PE#%d\n", | ||
91 | __func__, ret, edev->pe->phb->global_number, | ||
92 | edev->pe->addr); | ||
93 | return -EIO; | ||
94 | } | ||
95 | |||
96 | /* Enable DMA */ | ||
97 | ret = eeh_pci_enable(edev->pe, EEH_OPT_THAW_DMA); | ||
98 | if (ret) { | ||
99 | pr_warn("%s: Failure %d enabling DMA for PHB#%d-PE#%d\n", | ||
100 | __func__, ret, edev->pe->phb->global_number, | ||
101 | edev->pe->addr); | ||
102 | return -EIO; | ||
103 | } | ||
104 | |||
105 | /* Clear software state */ | ||
106 | eeh_pe_state_clear(edev->pe, EEH_PE_ISOLATED); | ||
107 | |||
108 | return count; | ||
109 | } | ||
110 | |||
111 | static DEVICE_ATTR_RW(eeh_pe_state); | ||
112 | |||
57 | void eeh_sysfs_add_device(struct pci_dev *pdev) | 113 | void eeh_sysfs_add_device(struct pci_dev *pdev) |
58 | { | 114 | { |
59 | struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev); | 115 | struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev); |
@@ -68,9 +124,10 @@ void eeh_sysfs_add_device(struct pci_dev *pdev) | |||
68 | rc += device_create_file(&pdev->dev, &dev_attr_eeh_mode); | 124 | rc += device_create_file(&pdev->dev, &dev_attr_eeh_mode); |
69 | rc += device_create_file(&pdev->dev, &dev_attr_eeh_config_addr); | 125 | rc += device_create_file(&pdev->dev, &dev_attr_eeh_config_addr); |
70 | rc += device_create_file(&pdev->dev, &dev_attr_eeh_pe_config_addr); | 126 | rc += device_create_file(&pdev->dev, &dev_attr_eeh_pe_config_addr); |
127 | rc += device_create_file(&pdev->dev, &dev_attr_eeh_pe_state); | ||
71 | 128 | ||
72 | if (rc) | 129 | if (rc) |
73 | printk(KERN_WARNING "EEH: Unable to create sysfs entries\n"); | 130 | pr_warn("EEH: Unable to create sysfs entries\n"); |
74 | else if (edev) | 131 | else if (edev) |
75 | edev->mode |= EEH_DEV_SYSFS; | 132 | edev->mode |= EEH_DEV_SYSFS; |
76 | } | 133 | } |
@@ -92,6 +149,7 @@ void eeh_sysfs_remove_device(struct pci_dev *pdev) | |||
92 | device_remove_file(&pdev->dev, &dev_attr_eeh_mode); | 149 | device_remove_file(&pdev->dev, &dev_attr_eeh_mode); |
93 | device_remove_file(&pdev->dev, &dev_attr_eeh_config_addr); | 150 | device_remove_file(&pdev->dev, &dev_attr_eeh_config_addr); |
94 | device_remove_file(&pdev->dev, &dev_attr_eeh_pe_config_addr); | 151 | device_remove_file(&pdev->dev, &dev_attr_eeh_pe_config_addr); |
152 | device_remove_file(&pdev->dev, &dev_attr_eeh_pe_state); | ||
95 | 153 | ||
96 | if (edev) | 154 | if (edev) |
97 | edev->mode &= ~EEH_DEV_SYSFS; | 155 | edev->mode &= ~EEH_DEV_SYSFS; |