Commit b6ce068a authored by Matthew Wilcox's avatar Matthew Wilcox Committed by Linus Torvalds

Change pci_raw_ops to pci_raw_read/write

We want to allow different implementations of pci_raw_ops for standard
and extended config space on x86.  Rather than clutter generic code with
knowledge of this, we make pci_raw_ops private to x86 and use it to
implement the new raw interface -- raw_pci_read() and raw_pci_write().
Signed-off-by: default avatarMatthew Wilcox <willy@linux.intel.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent a0ca9909
...@@ -43,8 +43,7 @@ ...@@ -43,8 +43,7 @@
#define PCI_SAL_EXT_ADDRESS(seg, bus, devfn, reg) \ #define PCI_SAL_EXT_ADDRESS(seg, bus, devfn, reg) \
(((u64) seg << 28) | (bus << 20) | (devfn << 12) | (reg)) (((u64) seg << 28) | (bus << 20) | (devfn << 12) | (reg))
static int int raw_pci_read(unsigned int seg, unsigned int bus, unsigned int devfn,
pci_sal_read (unsigned int seg, unsigned int bus, unsigned int devfn,
int reg, int len, u32 *value) int reg, int len, u32 *value)
{ {
u64 addr, data = 0; u64 addr, data = 0;
...@@ -68,8 +67,7 @@ pci_sal_read (unsigned int seg, unsigned int bus, unsigned int devfn, ...@@ -68,8 +67,7 @@ pci_sal_read (unsigned int seg, unsigned int bus, unsigned int devfn,
return 0; return 0;
} }
static int int raw_pci_write(unsigned int seg, unsigned int bus, unsigned int devfn,
pci_sal_write (unsigned int seg, unsigned int bus, unsigned int devfn,
int reg, int len, u32 value) int reg, int len, u32 value)
{ {
u64 addr; u64 addr;
...@@ -91,24 +89,17 @@ pci_sal_write (unsigned int seg, unsigned int bus, unsigned int devfn, ...@@ -91,24 +89,17 @@ pci_sal_write (unsigned int seg, unsigned int bus, unsigned int devfn,
return 0; return 0;
} }
static struct pci_raw_ops pci_sal_ops = { static int pci_read(struct pci_bus *bus, unsigned int devfn, int where,
.read = pci_sal_read, int size, u32 *value)
.write = pci_sal_write
};
struct pci_raw_ops *raw_pci_ops = &pci_sal_ops;
static int
pci_read (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
{ {
return raw_pci_ops->read(pci_domain_nr(bus), bus->number, return raw_pci_read(pci_domain_nr(bus), bus->number,
devfn, where, size, value); devfn, where, size, value);
} }
static int static int pci_write(struct pci_bus *bus, unsigned int devfn, int where,
pci_write (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) int size, u32 value)
{ {
return raw_pci_ops->write(pci_domain_nr(bus), bus->number, return raw_pci_write(pci_domain_nr(bus), bus->number,
devfn, where, size, value); devfn, where, size, value);
} }
......
...@@ -752,13 +752,13 @@ tioce_kern_init(struct tioce_common *tioce_common) ...@@ -752,13 +752,13 @@ tioce_kern_init(struct tioce_common *tioce_common)
* Determine the secondary bus number of the port2 logical PPB. * Determine the secondary bus number of the port2 logical PPB.
* This is used to decide whether a given pci device resides on * This is used to decide whether a given pci device resides on
* port1 or port2. Note: We don't have enough plumbing set up * port1 or port2. Note: We don't have enough plumbing set up
* here to use pci_read_config_xxx() so use the raw_pci_ops vector. * here to use pci_read_config_xxx() so use raw_pci_read().
*/ */
seg = tioce_common->ce_pcibus.bs_persist_segment; seg = tioce_common->ce_pcibus.bs_persist_segment;
bus = tioce_common->ce_pcibus.bs_persist_busnum; bus = tioce_common->ce_pcibus.bs_persist_busnum;
raw_pci_ops->read(seg, bus, PCI_DEVFN(2, 0), PCI_SECONDARY_BUS, 1,&tmp); raw_pci_read(seg, bus, PCI_DEVFN(2, 0), PCI_SECONDARY_BUS, 1,&tmp);
tioce_kern->ce_port1_secondary = (u8) tmp; tioce_kern->ce_port1_secondary = (u8) tmp;
/* /*
...@@ -799,11 +799,11 @@ tioce_kern_init(struct tioce_common *tioce_common) ...@@ -799,11 +799,11 @@ tioce_kern_init(struct tioce_common *tioce_common)
/* mem base/limit */ /* mem base/limit */
raw_pci_ops->read(seg, bus, PCI_DEVFN(dev, 0), raw_pci_read(seg, bus, PCI_DEVFN(dev, 0),
PCI_MEMORY_BASE, 2, &tmp); PCI_MEMORY_BASE, 2, &tmp);
base = (u64)tmp << 16; base = (u64)tmp << 16;
raw_pci_ops->read(seg, bus, PCI_DEVFN(dev, 0), raw_pci_read(seg, bus, PCI_DEVFN(dev, 0),
PCI_MEMORY_LIMIT, 2, &tmp); PCI_MEMORY_LIMIT, 2, &tmp);
limit = (u64)tmp << 16; limit = (u64)tmp << 16;
limit |= 0xfffffUL; limit |= 0xfffffUL;
...@@ -817,21 +817,21 @@ tioce_kern_init(struct tioce_common *tioce_common) ...@@ -817,21 +817,21 @@ tioce_kern_init(struct tioce_common *tioce_common)
* attributes. * attributes.
*/ */
raw_pci_ops->read(seg, bus, PCI_DEVFN(dev, 0), raw_pci_read(seg, bus, PCI_DEVFN(dev, 0),
PCI_PREF_MEMORY_BASE, 2, &tmp); PCI_PREF_MEMORY_BASE, 2, &tmp);
base = ((u64)tmp & PCI_PREF_RANGE_MASK) << 16; base = ((u64)tmp & PCI_PREF_RANGE_MASK) << 16;
raw_pci_ops->read(seg, bus, PCI_DEVFN(dev, 0), raw_pci_read(seg, bus, PCI_DEVFN(dev, 0),
PCI_PREF_BASE_UPPER32, 4, &tmp); PCI_PREF_BASE_UPPER32, 4, &tmp);
base |= (u64)tmp << 32; base |= (u64)tmp << 32;
raw_pci_ops->read(seg, bus, PCI_DEVFN(dev, 0), raw_pci_read(seg, bus, PCI_DEVFN(dev, 0),
PCI_PREF_MEMORY_LIMIT, 2, &tmp); PCI_PREF_MEMORY_LIMIT, 2, &tmp);
limit = ((u64)tmp & PCI_PREF_RANGE_MASK) << 16; limit = ((u64)tmp & PCI_PREF_RANGE_MASK) << 16;
limit |= 0xfffffUL; limit |= 0xfffffUL;
raw_pci_ops->read(seg, bus, PCI_DEVFN(dev, 0), raw_pci_read(seg, bus, PCI_DEVFN(dev, 0),
PCI_PREF_LIMIT_UPPER32, 4, &tmp); PCI_PREF_LIMIT_UPPER32, 4, &tmp);
limit |= (u64)tmp << 32; limit |= (u64)tmp << 32;
......
...@@ -27,7 +27,7 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) ...@@ -27,7 +27,7 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev)
pci_write_config_byte(dev, 0xf4, config|0x2); pci_write_config_byte(dev, 0xf4, config|0x2);
/* read xTPR register */ /* read xTPR register */
raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word); raw_pci_read(0, 0, 0x40, 0x4c, 2, &word);
if (!(word & (1 << 13))) { if (!(word & (1 << 13))) {
dev_info(&dev->dev, "Intel E7520/7320/7525 detected; " dev_info(&dev->dev, "Intel E7520/7320/7525 detected; "
......
...@@ -26,16 +26,37 @@ int pcibios_last_bus = -1; ...@@ -26,16 +26,37 @@ int pcibios_last_bus = -1;
unsigned long pirq_table_addr; unsigned long pirq_table_addr;
struct pci_bus *pci_root_bus; struct pci_bus *pci_root_bus;
struct pci_raw_ops *raw_pci_ops; struct pci_raw_ops *raw_pci_ops;
struct pci_raw_ops *raw_pci_ext_ops;
int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn,
int reg, int len, u32 *val)
{
if (reg < 256 && raw_pci_ops)
return raw_pci_ops->read(domain, bus, devfn, reg, len, val);
if (raw_pci_ext_ops)
return raw_pci_ext_ops->read(domain, bus, devfn, reg, len, val);
return -EINVAL;
}
int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn,
int reg, int len, u32 val)
{
if (reg < 256 && raw_pci_ops)
return raw_pci_ops->write(domain, bus, devfn, reg, len, val);
if (raw_pci_ext_ops)
return raw_pci_ext_ops->write(domain, bus, devfn, reg, len, val);
return -EINVAL;
}
static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
{ {
return raw_pci_ops->read(pci_domain_nr(bus), bus->number, return raw_pci_read(pci_domain_nr(bus), bus->number,
devfn, where, size, value); devfn, where, size, value);
} }
static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
{ {
return raw_pci_ops->write(pci_domain_nr(bus), bus->number, return raw_pci_write(pci_domain_nr(bus), bus->number,
devfn, where, size, value); devfn, where, size, value);
} }
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#define PCI_CONF1_ADDRESS(bus, devfn, reg) \ #define PCI_CONF1_ADDRESS(bus, devfn, reg) \
(0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3)) (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3))
int pci_conf1_read(unsigned int seg, unsigned int bus, static int pci_conf1_read(unsigned int seg, unsigned int bus,
unsigned int devfn, int reg, int len, u32 *value) unsigned int devfn, int reg, int len, u32 *value)
{ {
unsigned long flags; unsigned long flags;
...@@ -45,7 +45,7 @@ int pci_conf1_read(unsigned int seg, unsigned int bus, ...@@ -45,7 +45,7 @@ int pci_conf1_read(unsigned int seg, unsigned int bus,
return 0; return 0;
} }
int pci_conf1_write(unsigned int seg, unsigned int bus, static int pci_conf1_write(unsigned int seg, unsigned int bus,
unsigned int devfn, int reg, int len, u32 value) unsigned int devfn, int reg, int len, u32 value)
{ {
unsigned long flags; unsigned long flags;
......
...@@ -215,7 +215,8 @@ static int quirk_aspm_offset[MAX_PCIEROOT << 3]; ...@@ -215,7 +215,8 @@ static int quirk_aspm_offset[MAX_PCIEROOT << 3];
static int quirk_pcie_aspm_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) static int quirk_pcie_aspm_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
{ {
return raw_pci_ops->read(0, bus->number, devfn, where, size, value); return raw_pci_read(pci_domain_nr(bus), bus->number,
devfn, where, size, value);
} }
/* /*
...@@ -231,7 +232,8 @@ static int quirk_pcie_aspm_write(struct pci_bus *bus, unsigned int devfn, int wh ...@@ -231,7 +232,8 @@ static int quirk_pcie_aspm_write(struct pci_bus *bus, unsigned int devfn, int wh
if ((offset) && (where == offset)) if ((offset) && (where == offset))
value = value & 0xfffffffc; value = value & 0xfffffffc;
return raw_pci_ops->write(0, bus->number, devfn, where, size, value); return raw_pci_write(pci_domain_nr(bus), bus->number,
devfn, where, size, value);
} }
static struct pci_ops quirk_pcie_aspm_ops = { static struct pci_ops quirk_pcie_aspm_ops = {
......
...@@ -22,7 +22,7 @@ static void __devinit pcibios_fixup_peer_bridges(void) ...@@ -22,7 +22,7 @@ static void __devinit pcibios_fixup_peer_bridges(void)
if (pci_find_bus(0, n)) if (pci_find_bus(0, n))
continue; continue;
for (devfn = 0; devfn < 256; devfn += 8) { for (devfn = 0; devfn < 256; devfn += 8) {
if (!raw_pci_ops->read(0, n, devfn, PCI_VENDOR_ID, 2, &l) && if (!raw_pci_read(0, n, devfn, PCI_VENDOR_ID, 2, &l) &&
l != 0x0000 && l != 0xffff) { l != 0x0000 && l != 0xffff) {
DBG("Found device at %02x:%02x [%04x]\n", n, devfn, l); DBG("Found device at %02x:%02x [%04x]\n", n, devfn, l);
printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n); printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n);
......
...@@ -28,7 +28,7 @@ static int __initdata pci_mmcfg_resources_inserted; ...@@ -28,7 +28,7 @@ static int __initdata pci_mmcfg_resources_inserted;
static const char __init *pci_mmcfg_e7520(void) static const char __init *pci_mmcfg_e7520(void)
{ {
u32 win; u32 win;
pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0xce, 2, &win); pci_direct_conf1.read(0, 0, PCI_DEVFN(0,0), 0xce, 2, &win);
win = win & 0xf000; win = win & 0xf000;
if(win == 0x0000 || win == 0xf000) if(win == 0x0000 || win == 0xf000)
...@@ -53,7 +53,7 @@ static const char __init *pci_mmcfg_intel_945(void) ...@@ -53,7 +53,7 @@ static const char __init *pci_mmcfg_intel_945(void)
pci_mmcfg_config_num = 1; pci_mmcfg_config_num = 1;
pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0x48, 4, &pciexbar); pci_direct_conf1.read(0, 0, PCI_DEVFN(0,0), 0x48, 4, &pciexbar);
/* Enable bit */ /* Enable bit */
if (!(pciexbar & 1)) if (!(pciexbar & 1))
...@@ -118,7 +118,7 @@ static int __init pci_mmcfg_check_hostbridge(void) ...@@ -118,7 +118,7 @@ static int __init pci_mmcfg_check_hostbridge(void)
int i; int i;
const char *name; const char *name;
pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0, 4, &l); pci_direct_conf1.read(0, 0, PCI_DEVFN(0,0), 0, 4, &l);
vendor = l & 0xffff; vendor = l & 0xffff;
device = (l >> 16) & 0xffff; device = (l >> 16) & 0xffff;
......
...@@ -68,9 +68,6 @@ err: *value = -1; ...@@ -68,9 +68,6 @@ err: *value = -1;
return -EINVAL; return -EINVAL;
} }
if (reg < 256)
return pci_conf1_read(seg,bus,devfn,reg,len,value);
base = get_base_addr(seg, bus, devfn); base = get_base_addr(seg, bus, devfn);
if (!base) if (!base)
goto err; goto err;
...@@ -104,9 +101,6 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, ...@@ -104,9 +101,6 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
if ((bus > 255) || (devfn > 255) || (reg > 4095)) if ((bus > 255) || (devfn > 255) || (reg > 4095))
return -EINVAL; return -EINVAL;
if (reg < 256)
return pci_conf1_write(seg,bus,devfn,reg,len,value);
base = get_base_addr(seg, bus, devfn); base = get_base_addr(seg, bus, devfn);
if (!base) if (!base)
return -EINVAL; return -EINVAL;
...@@ -138,7 +132,7 @@ static struct pci_raw_ops pci_mmcfg = { ...@@ -138,7 +132,7 @@ static struct pci_raw_ops pci_mmcfg = {
int __init pci_mmcfg_arch_init(void) int __init pci_mmcfg_arch_init(void)
{ {
printk(KERN_INFO "PCI: Using MMCONFIG\n"); printk(KERN_INFO "PCI: Using MMCONFIG for extended config space\n");
raw_pci_ops = &pci_mmcfg; raw_pci_ext_ops = &pci_mmcfg;
return 1; return 1;
} }
...@@ -58,9 +58,6 @@ err: *value = -1; ...@@ -58,9 +58,6 @@ err: *value = -1;
return -EINVAL; return -EINVAL;
} }
if (reg < 256)
return pci_conf1_read(seg,bus,devfn,reg,len,value);
addr = pci_dev_base(seg, bus, devfn); addr = pci_dev_base(seg, bus, devfn);
if (!addr) if (!addr)
goto err; goto err;
...@@ -89,9 +86,6 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, ...@@ -89,9 +86,6 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
return -EINVAL; return -EINVAL;
if (reg < 256)
return pci_conf1_write(seg,bus,devfn,reg,len,value);
addr = pci_dev_base(seg, bus, devfn); addr = pci_dev_base(seg, bus, devfn);
if (!addr) if (!addr)
return -EINVAL; return -EINVAL;
...@@ -150,6 +144,6 @@ int __init pci_mmcfg_arch_init(void) ...@@ -150,6 +144,6 @@ int __init pci_mmcfg_arch_init(void)
return 0; return 0;
} }
} }
raw_pci_ops = &pci_mmcfg; raw_pci_ext_ops = &pci_mmcfg;
return 1; return 1;
} }
...@@ -85,10 +85,17 @@ extern spinlock_t pci_config_lock; ...@@ -85,10 +85,17 @@ extern spinlock_t pci_config_lock;
extern int (*pcibios_enable_irq)(struct pci_dev *dev); extern int (*pcibios_enable_irq)(struct pci_dev *dev);
extern void (*pcibios_disable_irq)(struct pci_dev *dev); extern void (*pcibios_disable_irq)(struct pci_dev *dev);
extern int pci_conf1_write(unsigned int seg, unsigned int bus, struct pci_raw_ops {
unsigned int devfn, int reg, int len, u32 value); int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn,
extern int pci_conf1_read(unsigned int seg, unsigned int bus, int reg, int len, u32 *val);
unsigned int devfn, int reg, int len, u32 *value); int (*write)(unsigned int domain, unsigned int bus, unsigned int devfn,
int reg, int len, u32 val);
};
extern struct pci_raw_ops *raw_pci_ops;
extern struct pci_raw_ops *raw_pci_ext_ops;
extern struct pci_raw_ops pci_direct_conf1;
extern int pci_direct_probe(void); extern int pci_direct_probe(void);
extern void pci_direct_init(int type); extern void pci_direct_init(int type);
......
...@@ -13,9 +13,6 @@ ...@@ -13,9 +13,6 @@
#include "pci.h" #include "pci.h"
extern struct pci_raw_ops pci_direct_conf1;
static int pci_visws_enable_irq(struct pci_dev *dev) { return 0; } static int pci_visws_enable_irq(struct pci_dev *dev) { return 0; }
static void pci_visws_disable_irq(struct pci_dev *dev) { } static void pci_visws_disable_irq(struct pci_dev *dev) { }
......
...@@ -200,15 +200,6 @@ acpi_status __init acpi_os_initialize(void) ...@@ -200,15 +200,6 @@ acpi_status __init acpi_os_initialize(void)
acpi_status acpi_os_initialize1(void) acpi_status acpi_os_initialize1(void)
{ {
/*
* Initialize PCI configuration space access, as we'll need to access
* it while walking the namespace (bus 0 and root bridges w/ _BBNs).
*/
if (!raw_pci_ops) {
printk(KERN_ERR PREFIX
"Access to PCI configuration space unavailable\n");
return AE_NULL_ENTRY;
}
kacpid_wq = create_singlethread_workqueue("kacpid"); kacpid_wq = create_singlethread_workqueue("kacpid");
kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify"); kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify");
BUG_ON(!kacpid_wq); BUG_ON(!kacpid_wq);
...@@ -653,11 +644,9 @@ acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, ...@@ -653,11 +644,9 @@ acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
return AE_ERROR; return AE_ERROR;
} }
BUG_ON(!raw_pci_ops); result = raw_pci_read(pci_id->segment, pci_id->bus,
PCI_DEVFN(pci_id->device, pci_id->function),
result = raw_pci_ops->read(pci_id->segment, pci_id->bus, reg, size, value);
PCI_DEVFN(pci_id->device, pci_id->function),
reg, size, value);
return (result ? AE_ERROR : AE_OK); return (result ? AE_ERROR : AE_OK);
} }
...@@ -682,11 +671,9 @@ acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, ...@@ -682,11 +671,9 @@ acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
return AE_ERROR; return AE_ERROR;
} }
BUG_ON(!raw_pci_ops); result = raw_pci_write(pci_id->segment, pci_id->bus,
PCI_DEVFN(pci_id->device, pci_id->function),
result = raw_pci_ops->write(pci_id->segment, pci_id->bus, reg, size, value);
PCI_DEVFN(pci_id->device, pci_id->function),
reg, size, value);
return (result ? AE_ERROR : AE_OK); return (result ? AE_ERROR : AE_OK);
} }
......
...@@ -301,14 +301,14 @@ struct pci_ops { ...@@ -301,14 +301,14 @@ struct pci_ops {
int (*write)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val); int (*write)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val);
}; };
struct pci_raw_ops { /*
int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn, * ACPI needs to be able to access PCI config space before we've done a
int reg, int len, u32 *val); * PCI bus scan and created pci_bus structures.
int (*write)(unsigned int domain, unsigned int bus, unsigned int devfn, */
int reg, int len, u32 val); extern int raw_pci_read(unsigned int domain, unsigned int bus,
}; unsigned int devfn, int reg, int len, u32 *val);
extern int raw_pci_write(unsigned int domain, unsigned int bus,
extern struct pci_raw_ops *raw_pci_ops; unsigned int devfn, int reg, int len, u32 val);
struct pci_bus_region { struct pci_bus_region {
resource_size_t start; resource_size_t start;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment