aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci-sysfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/pci-sysfs.c')
-rw-r--r--drivers/pci/pci-sysfs.c48
1 files changed, 28 insertions, 20 deletions
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index d5cdccf27a69..d2f1354fd189 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -58,13 +58,14 @@ static ssize_t broken_parity_status_store(struct device *dev,
58 const char *buf, size_t count) 58 const char *buf, size_t count)
59{ 59{
60 struct pci_dev *pdev = to_pci_dev(dev); 60 struct pci_dev *pdev = to_pci_dev(dev);
61 ssize_t consumed = -EINVAL; 61 unsigned long val;
62 62
63 if ((count > 0) && (*buf == '0' || *buf == '1')) { 63 if (strict_strtoul(buf, 0, &val) < 0)
64 pdev->broken_parity_status = *buf == '1' ? 1 : 0; 64 return -EINVAL;
65 consumed = count; 65
66 } 66 pdev->broken_parity_status = !!val;
67 return consumed; 67
68 return count;
68} 69}
69 70
70static ssize_t local_cpus_show(struct device *dev, 71static ssize_t local_cpus_show(struct device *dev,
@@ -133,19 +134,23 @@ static ssize_t is_enabled_store(struct device *dev,
133 struct device_attribute *attr, const char *buf, 134 struct device_attribute *attr, const char *buf,
134 size_t count) 135 size_t count)
135{ 136{
136 ssize_t result = -EINVAL;
137 struct pci_dev *pdev = to_pci_dev(dev); 137 struct pci_dev *pdev = to_pci_dev(dev);
138 unsigned long val;
139 ssize_t result = strict_strtoul(buf, 0, &val);
140
141 if (result < 0)
142 return result;
138 143
139 /* this can crash the machine when done on the "wrong" device */ 144 /* this can crash the machine when done on the "wrong" device */
140 if (!capable(CAP_SYS_ADMIN)) 145 if (!capable(CAP_SYS_ADMIN))
141 return count; 146 return -EPERM;
142 147
143 if (*buf == '0') { 148 if (!val) {
144 if (atomic_read(&pdev->enable_cnt) != 0) 149 if (atomic_read(&pdev->enable_cnt) != 0)
145 pci_disable_device(pdev); 150 pci_disable_device(pdev);
146 else 151 else
147 result = -EIO; 152 result = -EIO;
148 } else if (*buf == '1') 153 } else
149 result = pci_enable_device(pdev); 154 result = pci_enable_device(pdev);
150 155
151 return result < 0 ? result : count; 156 return result < 0 ? result : count;
@@ -185,25 +190,28 @@ msi_bus_store(struct device *dev, struct device_attribute *attr,
185 const char *buf, size_t count) 190 const char *buf, size_t count)
186{ 191{
187 struct pci_dev *pdev = to_pci_dev(dev); 192 struct pci_dev *pdev = to_pci_dev(dev);
193 unsigned long val;
194
195 if (strict_strtoul(buf, 0, &val) < 0)
196 return -EINVAL;
188 197
189 /* bad things may happen if the no_msi flag is changed 198 /* bad things may happen if the no_msi flag is changed
190 * while some drivers are loaded */ 199 * while some drivers are loaded */
191 if (!capable(CAP_SYS_ADMIN)) 200 if (!capable(CAP_SYS_ADMIN))
192 return count; 201 return -EPERM;
193 202
203 /* Maybe pci devices without subordinate busses shouldn't even have this
204 * attribute in the first place? */
194 if (!pdev->subordinate) 205 if (!pdev->subordinate)
195 return count; 206 return count;
196 207
197 if (*buf == '0') { 208 /* Is the flag going to change, or keep the value it already had? */
198 pdev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; 209 if (!(pdev->subordinate->bus_flags & PCI_BUS_FLAGS_NO_MSI) ^
199 dev_warn(&pdev->dev, "forced subordinate bus to not support MSI," 210 !!val) {
200 " bad things could happen.\n"); 211 pdev->subordinate->bus_flags ^= PCI_BUS_FLAGS_NO_MSI;
201 }
202 212
203 if (*buf == '1') { 213 dev_warn(&pdev->dev, "forced subordinate bus to%s support MSI,"
204 pdev->subordinate->bus_flags &= ~PCI_BUS_FLAGS_NO_MSI; 214 " bad things could happen\n", val ? "" : " not");
205 dev_warn(&pdev->dev, "forced subordinate bus to support MSI,"
206 " bad things could happen.\n");
207 } 215 }
208 216
209 return count; 217 return count;