summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-02-13 07:49:18 (GMT)
committerDavid S. Miller <davem@sunset.davemloft.net>2006-03-20 09:12:36 (GMT)
commit059833eb817fec3a5a7f62fba9592749c4cebc73 (patch)
tree5de088b9200956458ca83afe33335d6ea87c63d6 /arch
parent0b522497a176f222ae4cf7e6733a5357352224b2 (diff)
downloadlinux-059833eb817fec3a5a7f62fba9592749c4cebc73.tar.xz
[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>
Diffstat (limited to 'arch')
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c33
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;
}