[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [linux-2.6.18-xen] PCI x86: always use conf1 to access config space below 256 bytes
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1250243673 -3600 # Node ID 829e4ede647c69f016fbd8e16690004e892bb702 # Parent 2846a6cde181beac5880e0bce0c5b210ef36a995 PCI x86: always use conf1 to access config space below 256 bytes Back-ported to 2.6.18.8 by Simon Horman Signed-off-by: Ivan Kokshaysky <ink@xxxxxxxxxxxxxxxxxxxx> Signed-off-by: Matthew Wilcox <willy@xxxxxxxxxxxxxxx> Signed-off-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> Signed-off-by: Simon Horman <horms@xxxxxxxxxxxx> --- arch/i386/pci/mmconfig.c | 59 ++++++--------------------------------------- arch/x86_64/pci/mmconfig.c | 52 ++++++--------------------------------- 2 files changed, 18 insertions(+), 93 deletions(-) diff -r 2846a6cde181 -r 829e4ede647c arch/i386/pci/mmconfig.c --- a/arch/i386/pci/mmconfig.c Fri Aug 14 10:53:56 2009 +0100 +++ b/arch/i386/pci/mmconfig.c Fri Aug 14 10:54:33 2009 +0100 @@ -19,15 +19,10 @@ #define MMCONFIG_APER_MIN (2 * 1024*1024) #define MMCONFIG_APER_MAX (256 * 1024*1024) -/* Assume systems with more busses have correct MCFG */ -#define MAX_CHECK_BUS 16 - #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) /* The base address of the last MMCONFIG device accessed */ static u32 mmcfg_last_accessed_device; - -static DECLARE_BITMAP(fallback_slots, MAX_CHECK_BUS*32); /* * Functions for accessing PCI configuration space with MMCONFIG accesses @@ -36,10 +31,6 @@ static u32 get_base_addr(unsigned int se { int cfg_num = -1; struct acpi_table_mcfg_config *cfg; - - if (seg == 0 && bus < MAX_CHECK_BUS && - test_bit(PCI_SLOT(devfn) + 32*bus, fallback_slots)) - return 0; while (1) { ++cfg_num; @@ -83,13 +74,16 @@ static int pci_mmcfg_read(unsigned int s u32 base; if ((bus > 255) || (devfn > 255) || (reg > 4095)) { - *value = -1; +err: *value = -1; return -EINVAL; } + if (reg < 256) + return pci_conf1_read(seg,bus,devfn,reg,len,value); + base = get_base_addr(seg, bus, devfn); if (!base) - return pci_conf1_read(seg,bus,devfn,reg,len,value); + goto err; spin_lock_irqsave(&pci_config_lock, flags); @@ -121,9 +115,12 @@ static int pci_mmcfg_write(unsigned int if ((bus > 255) || (devfn > 255) || (reg > 4095)) return -EINVAL; + if (reg < 256) + return pci_conf1_write(seg,bus,devfn,reg,len,value); + base = get_base_addr(seg, bus, devfn); if (!base) - return pci_conf1_write(seg,bus,devfn,reg,len,value); + return -EINVAL; spin_lock_irqsave(&pci_config_lock, flags); @@ -151,42 +148,6 @@ static struct pci_raw_ops pci_mmcfg = { .write = pci_mmcfg_write, }; -/* K8 systems have some devices (typically in the builtin northbridge) - that are only accessible using type1 - Normally this can be expressed in the MCFG by not listing them - and assigning suitable _SEGs, but this isn't implemented in some BIOS. - Instead try to discover all devices on bus 0 that are unreachable using MM - and fallback for them. */ -static __init void unreachable_devices(void) -{ - int i, k; - unsigned long flags; - - for (k = 0; k < MAX_CHECK_BUS; k++) { - for (i = 0; i < 32; i++) { - u32 val1; - u32 addr; - - pci_conf1_read(0, k, PCI_DEVFN(i, 0), 0, 4, &val1); - if (val1 == 0xffffffff) - continue; - - /* Locking probably not needed, but safer */ - spin_lock_irqsave(&pci_config_lock, flags); - addr = get_base_addr(0, k, PCI_DEVFN(i, 0)); - if (addr != 0) - pci_exp_set_dev_base(addr, k, PCI_DEVFN(i, 0)); - if (addr == 0 || - readl((u32 __iomem *)mmcfg_virt_addr) != val1) { - set_bit(i + 32*k, fallback_slots); - printk(KERN_NOTICE - "PCI: No mmconfig possible on %x:%x\n", k, i); - } - spin_unlock_irqrestore(&pci_config_lock, flags); - } - } -} - void __init pci_mmcfg_init(void) { if ((pci_probe & PCI_PROBE_MMCONF) == 0) @@ -210,6 +171,4 @@ void __init pci_mmcfg_init(void) printk(KERN_INFO "PCI: Using MMCONFIG\n"); raw_pci_ops = &pci_mmcfg; pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; - - unreachable_devices(); } diff -r 2846a6cde181 -r 829e4ede647c arch/x86_64/pci/mmconfig.c --- a/arch/x86_64/pci/mmconfig.c Fri Aug 14 10:53:56 2009 +0100 +++ b/arch/x86_64/pci/mmconfig.c Fri Aug 14 10:54:33 2009 +0100 @@ -16,12 +16,6 @@ /* aperture is up to 256MB but BIOS may reserve less */ #define MMCONFIG_APER_MIN (2 * 1024*1024) #define MMCONFIG_APER_MAX (256 * 1024*1024) - -/* Verify the first 16 busses. We assume that systems with more busses - get MCFG right. */ -#define MAX_CHECK_BUS 16 - -static DECLARE_BITMAP(fallback_slots, 32*MAX_CHECK_BUS); /* Static virtual mapping of the MMCONFIG aperture */ struct mmcfg_virt { @@ -87,9 +81,6 @@ static char __iomem *pci_dev_base(unsign static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) { char __iomem *addr; - if (seg == 0 && bus < MAX_CHECK_BUS && - test_bit(32*bus + PCI_SLOT(devfn), fallback_slots)) - return NULL; addr = get_virt(seg, bus); if (!addr) return NULL; @@ -103,13 +94,16 @@ static int pci_mmcfg_read(unsigned int s /* Why do we have this when nobody checks it. How about a BUG()!? -AK */ if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) { - *value = -1; +err: *value = -1; return -EINVAL; } + if (reg < 256) + return pci_conf1_read(seg,bus,devfn,reg,len,value); + addr = pci_dev_base(seg, bus, devfn); if (!addr) - return pci_conf1_read(seg,bus,devfn,reg,len,value); + goto err; switch (len) { case 1: @@ -135,9 +129,12 @@ static int pci_mmcfg_write(unsigned int if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) return -EINVAL; + if (reg < 256) + return pci_conf1_write(seg,bus,devfn,reg,len,value); + addr = pci_dev_base(seg, bus, devfn); if (!addr) - return pci_conf1_write(seg,bus,devfn,reg,len,value); + return -EINVAL; switch (len) { case 1: @@ -158,35 +155,6 @@ static struct pci_raw_ops pci_mmcfg = { .read = pci_mmcfg_read, .write = pci_mmcfg_write, }; - -/* K8 systems have some devices (typically in the builtin northbridge) - that are only accessible using type1 - Normally this can be expressed in the MCFG by not listing them - and assigning suitable _SEGs, but this isn't implemented in some BIOS. - Instead try to discover all devices on bus 0 that are unreachable using MM - and fallback for them. */ -static __init void unreachable_devices(void) -{ - int i, k; - /* Use the max bus number from ACPI here? */ - for (k = 0; k < MAX_CHECK_BUS; k++) { - for (i = 0; i < 32; i++) { - u32 val1; - char __iomem *addr; - - pci_conf1_read(0, k, PCI_DEVFN(i,0), 0, 4, &val1); - if (val1 == 0xffffffff) - continue; - addr = pci_dev_base(0, k, PCI_DEVFN(i, 0)); - if (addr == NULL|| readl(addr) != val1) { - set_bit(i + 32*k, fallback_slots); - printk(KERN_NOTICE - "PCI: No mmconfig possible on device %x:%x\n", - k, i); - } - } - } -} void __init pci_mmcfg_init(void) { @@ -226,8 +194,6 @@ void __init pci_mmcfg_init(void) } } - unreachable_devices(); - raw_pci_ops = &pci_mmcfg; pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |