diff options
author | Greg Thelen <gthelen@google.com> | 2011-04-17 19:20:32 +0400 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2011-05-11 02:43:36 +0400 |
commit | 34e3207205ef492451cc5c53694d4772a9728b9f (patch) | |
tree | 342c517ddb92fd18ea823f9f194447b96846c441 /drivers/pci/access.c | |
parent | d97ecd819137118b4686a753415f93215a6edacf (diff) | |
download | linux-34e3207205ef492451cc5c53694d4772a9728b9f.tar.xz |
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>
Diffstat (limited to 'drivers/pci/access.c')
-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) __remove_wait_queue(&pci_ucfg_wait, &wait); } +/* Returns 0 on success, negative values indicate error. */ #define PCI_USER_READ_CONFIG(size,type) \ int pci_user_read_config_##size \ (struct pci_dev *dev, int pos, type *val) \ { \ int ret = 0; \ u32 data = -1; \ - if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ + if (PCI_##size##_BAD) \ + return -EINVAL; \ raw_spin_lock_irq(&pci_lock); \ if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \ ret = dev->bus->ops->read(dev->bus, dev->devfn, \ pos, sizeof(type), &data); \ raw_spin_unlock_irq(&pci_lock); \ *val = (type)data; \ + if (ret > 0) \ + ret = -EINVAL; \ return ret; \ } +/* Returns 0 on success, negative values indicate error. */ #define PCI_USER_WRITE_CONFIG(size,type) \ int pci_user_write_config_##size \ (struct pci_dev *dev, int pos, type val) \ { \ int ret = -EIO; \ - if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ + if (PCI_##size##_BAD) \ + return -EINVAL; \ raw_spin_lock_irq(&pci_lock); \ if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \ ret = dev->bus->ops->write(dev->bus, dev->devfn, \ pos, sizeof(type), val); \ raw_spin_unlock_irq(&pci_lock); \ + if (ret > 0) \ + ret = -EINVAL; \ return ret; \ } @@ -197,6 +205,8 @@ struct pci_vpd_pci22 { * This code has to spin since there is no other notification from the PCI * hardware. Since the VPD is often implemented by serial attachment to an * EEPROM, it may take many milliseconds to complete. + * + * Returns 0 on success, negative values indicate error. */ static int pci_vpd_pci22_wait(struct pci_dev *dev) { @@ -212,7 +222,7 @@ static int pci_vpd_pci22_wait(struct pci_dev *dev) for (;;) { ret = pci_user_read_config_word(dev, vpd->cap + PCI_VPD_ADDR, &status); - if (ret) + if (ret < 0) return ret; if ((status & PCI_VPD_ADDR_F) == vpd->flag) { |