diff options
author | Greg Thelen <gthelen@google.com> | 2011-04-17 11:20:32 -0400 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2011-05-10 18:43:36 -0400 |
commit | 34e3207205ef492451cc5c53694d4772a9728b9f (patch) | |
tree | 342c517ddb92fd18ea823f9f194447b96846c441 | |
parent | d97ecd819137118b4686a753415f93215a6edacf (diff) |
PCI: handle positive error codes
Callers expect pci_user_{read,write}_config_*() to indicate errors by
returning negative values. Prior to this change, the indicated routines
could return positive error codes (e.g. PCIBIOS_BAD_REGISTER_NUMBER)
which callers would mistakenly interpret as success.
This change converts any non-zero return from the mentioned routines
into unambiguous negative value return codes.
Signed-off-by: Greg Thelen <gthelen@google.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
-rw-r--r-- | drivers/pci/access.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/drivers/pci/access.c b/drivers/pci/access.c index 0c1f20f570a4..fdaa42aac7c6 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c | |||
@@ -143,33 +143,41 @@ static noinline void pci_wait_ucfg(struct pci_dev *dev) | |||
143 | __remove_wait_queue(&pci_ucfg_wait, &wait); | 143 | __remove_wait_queue(&pci_ucfg_wait, &wait); |
144 | } | 144 | } |
145 | 145 | ||
146 | /* Returns 0 on success, negative values indicate error. */ | ||
146 | #define PCI_USER_READ_CONFIG(size,type) \ | 147 | #define PCI_USER_READ_CONFIG(size,type) \ |
147 | int pci_user_read_config_##size \ | 148 | int pci_user_read_config_##size \ |
148 | (struct pci_dev *dev, int pos, type *val) \ | 149 | (struct pci_dev *dev, int pos, type *val) \ |
149 | { \ | 150 | { \ |
150 | int ret = 0; \ | 151 | int ret = 0; \ |
151 | u32 data = -1; \ | 152 | u32 data = -1; \ |
152 | if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ | 153 | if (PCI_##size##_BAD) \ |
154 | return -EINVAL; \ | ||
153 | raw_spin_lock_irq(&pci_lock); \ | 155 | raw_spin_lock_irq(&pci_lock); \ |
154 | if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \ | 156 | if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \ |
155 | ret = dev->bus->ops->read(dev->bus, dev->devfn, \ | 157 | ret = dev->bus->ops->read(dev->bus, dev->devfn, \ |
156 | pos, sizeof(type), &data); \ | 158 | pos, sizeof(type), &data); \ |
157 | raw_spin_unlock_irq(&pci_lock); \ | 159 | raw_spin_unlock_irq(&pci_lock); \ |
158 | *val = (type)data; \ | 160 | *val = (type)data; \ |
161 | if (ret > 0) \ | ||
162 | ret = -EINVAL; \ | ||
159 | return ret; \ | 163 | return ret; \ |
160 | } | 164 | } |
161 | 165 | ||
166 | /* Returns 0 on success, negative values indicate error. */ | ||
162 | #define PCI_USER_WRITE_CONFIG(size,type) \ | 167 | #define PCI_USER_WRITE_CONFIG(size,type) \ |
163 | int pci_user_write_config_##size \ | 168 | int pci_user_write_config_##size \ |
164 | (struct pci_dev *dev, int pos, type val) \ | 169 | (struct pci_dev *dev, int pos, type val) \ |
165 | { \ | 170 | { \ |
166 | int ret = -EIO; \ | 171 | int ret = -EIO; \ |
167 | if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ | 172 | if (PCI_##size##_BAD) \ |
173 | return -EINVAL; \ | ||
168 | raw_spin_lock_irq(&pci_lock); \ | 174 | raw_spin_lock_irq(&pci_lock); \ |
169 | if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \ | 175 | if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \ |
170 | ret = dev->bus->ops->write(dev->bus, dev->devfn, \ | 176 | ret = dev->bus->ops->write(dev->bus, dev->devfn, \ |
171 | pos, sizeof(type), val); \ | 177 | pos, sizeof(type), val); \ |
172 | raw_spin_unlock_irq(&pci_lock); \ | 178 | raw_spin_unlock_irq(&pci_lock); \ |
179 | if (ret > 0) \ | ||
180 | ret = -EINVAL; \ | ||
173 | return ret; \ | 181 | return ret; \ |
174 | } | 182 | } |
175 | 183 | ||
@@ -197,6 +205,8 @@ struct pci_vpd_pci22 { | |||
197 | * This code has to spin since there is no other notification from the PCI | 205 | * This code has to spin since there is no other notification from the PCI |
198 | * hardware. Since the VPD is often implemented by serial attachment to an | 206 | * hardware. Since the VPD is often implemented by serial attachment to an |
199 | * EEPROM, it may take many milliseconds to complete. | 207 | * EEPROM, it may take many milliseconds to complete. |
208 | * | ||
209 | * Returns 0 on success, negative values indicate error. | ||
200 | */ | 210 | */ |
201 | static int pci_vpd_pci22_wait(struct pci_dev *dev) | 211 | static int pci_vpd_pci22_wait(struct pci_dev *dev) |
202 | { | 212 | { |
@@ -212,7 +222,7 @@ static int pci_vpd_pci22_wait(struct pci_dev *dev) | |||
212 | for (;;) { | 222 | for (;;) { |
213 | ret = pci_user_read_config_word(dev, vpd->cap + PCI_VPD_ADDR, | 223 | ret = pci_user_read_config_word(dev, vpd->cap + PCI_VPD_ADDR, |
214 | &status); | 224 | &status); |
215 | if (ret) | 225 | if (ret < 0) |
216 | return ret; | 226 | return ret; |
217 | 227 | ||
218 | if ((status & PCI_VPD_ADDR_F) == vpd->flag) { | 228 | if ((status & PCI_VPD_ADDR_F) == vpd->flag) { |