diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-02-12 23:49:18 -0800 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-03-20 01:12:36 -0800 |
commit | 059833eb817fec3a5a7f62fba9592749c4cebc73 (patch) | |
tree | 5de088b9200956458ca83afe33335d6ea87c63d6 | |
parent | 0b522497a176f222ae4cf7e6733a5357352224b2 (diff) | |
download | op-kernel-dev-059833eb817fec3a5a7f62fba9592749c4cebc73.zip op-kernel-dev-059833eb817fec3a5a7f62fba9592749c4cebc73.tar.gz |
[SPARC64]: Range check bus number in SUN4V PCI controller driver.
It has to be somewhere in the range from pbm->pci_first_busno to
pbm->pci_last_busno, inclusive.
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | arch/sparc64/kernel/pci_sun4v.c | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 7055616..dc79b74 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -514,19 +514,31 @@ struct pci_iommu_ops pci_sun4v_iommu_ops = { /* SUN4V PCI configuration space accessors. */ +static inline int pci_sun4v_out_of_range(struct pci_pbm_info *pbm, unsigned int bus) +{ + if (bus < pbm->pci_first_busno || + bus > pbm->pci_last_busno) + return 1; + return 0; +} + static int pci_sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, int where, int size, u32 *value) { struct pci_pbm_info *pbm = bus_dev->sysdata; - unsigned long devhandle = pbm->devhandle; + u32 devhandle = pbm->devhandle; unsigned int bus = bus_dev->number; unsigned int device = PCI_SLOT(devfn); unsigned int func = PCI_FUNC(devfn); unsigned long ret; - ret = pci_sun4v_config_get(devhandle, - HV_PCI_DEVICE_BUILD(bus, device, func), - where, size); + if (pci_sun4v_out_of_range(pbm, bus)) { + ret = ~0UL; + } else { + ret = pci_sun4v_config_get(devhandle, + HV_PCI_DEVICE_BUILD(bus, device, func), + where, size); + } switch (size) { case 1: *value = ret & 0xff; @@ -547,16 +559,19 @@ static int pci_sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, int where, int size, u32 value) { struct pci_pbm_info *pbm = bus_dev->sysdata; - unsigned long devhandle = pbm->devhandle; + u32 devhandle = pbm->devhandle; unsigned int bus = bus_dev->number; unsigned int device = PCI_SLOT(devfn); unsigned int func = PCI_FUNC(devfn); unsigned long ret; - ret = pci_sun4v_config_put(devhandle, - HV_PCI_DEVICE_BUILD(bus, device, func), - where, size, value); - + if (pci_sun4v_out_of_range(pbm, bus)) { + /* Do nothing. */ + } else { + ret = pci_sun4v_config_put(devhandle, + HV_PCI_DEVICE_BUILD(bus, device, func), + where, size, value); + } return PCIBIOS_SUCCESSFUL; } |