Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

PCI x86: always use conf1 to access config space below 256 bytes

Thanks to Loic Prylli <loic@myri.com>, who originally proposed
this idea.

Always using legacy configuration mechanism for the legacy config space
and extended mechanism (mmconf) for the extended config space is
a simple and very logical approach. It's supposed to resolve all
known mmconf problems. It still allows per-device quirks (tweaking
dev->cfg_size). It also allows to get rid of mmconf fallback code.

Signed-off-by: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Ivan Kokshaysky and committed by
Linus Torvalds
a0ca9909 7cf712db

+19 -67
-35
arch/x86/pci/mmconfig-shared.c
··· 22 22 #define MMCONFIG_APER_MIN (2 * 1024*1024) 23 23 #define MMCONFIG_APER_MAX (256 * 1024*1024) 24 24 25 - DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS); 26 - 27 25 /* Indicate if the mmcfg resources have been placed into the resource table. */ 28 26 static int __initdata pci_mmcfg_resources_inserted; 29 - 30 - /* K8 systems have some devices (typically in the builtin northbridge) 31 - that are only accessible using type1 32 - Normally this can be expressed in the MCFG by not listing them 33 - and assigning suitable _SEGs, but this isn't implemented in some BIOS. 34 - Instead try to discover all devices on bus 0 that are unreachable using MM 35 - and fallback for them. */ 36 - static void __init unreachable_devices(void) 37 - { 38 - int i, bus; 39 - /* Use the max bus number from ACPI here? */ 40 - for (bus = 0; bus < PCI_MMCFG_MAX_CHECK_BUS; bus++) { 41 - for (i = 0; i < 32; i++) { 42 - unsigned int devfn = PCI_DEVFN(i, 0); 43 - u32 val1, val2; 44 - 45 - pci_conf1_read(0, bus, devfn, 0, 4, &val1); 46 - if (val1 == 0xffffffff) 47 - continue; 48 - 49 - if (pci_mmcfg_arch_reachable(0, bus, devfn)) { 50 - raw_pci_ops->read(0, bus, devfn, 0, 4, &val2); 51 - if (val1 == val2) 52 - continue; 53 - } 54 - set_bit(i + 32 * bus, pci_mmcfg_fallback_slots); 55 - printk(KERN_NOTICE "PCI: No mmconfig possible on device" 56 - " %02x:%02x\n", bus, i); 57 - } 58 - } 59 - } 60 27 61 28 static const char __init *pci_mmcfg_e7520(void) 62 29 { ··· 237 270 return; 238 271 239 272 if (pci_mmcfg_arch_init()) { 240 - if (type == 1) 241 - unreachable_devices(); 242 273 if (known_bridge) 243 274 pci_mmcfg_insert_resources(IORESOURCE_BUSY); 244 275 pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
+9 -13
arch/x86/pci/mmconfig_32.c
··· 30 30 struct acpi_mcfg_allocation *cfg; 31 31 int cfg_num; 32 32 33 - if (seg == 0 && bus < PCI_MMCFG_MAX_CHECK_BUS && 34 - test_bit(PCI_SLOT(devfn) + 32*bus, pci_mmcfg_fallback_slots)) 35 - return 0; 36 - 37 33 for (cfg_num = 0; cfg_num < pci_mmcfg_config_num; cfg_num++) { 38 34 cfg = &pci_mmcfg_config[cfg_num]; 39 35 if (cfg->pci_segment == seg && ··· 64 68 u32 base; 65 69 66 70 if ((bus > 255) || (devfn > 255) || (reg > 4095)) { 67 - *value = -1; 71 + err: *value = -1; 68 72 return -EINVAL; 69 73 } 70 74 75 + if (reg < 256) 76 + return pci_conf1_read(seg,bus,devfn,reg,len,value); 77 + 71 78 base = get_base_addr(seg, bus, devfn); 72 79 if (!base) 73 - return pci_conf1_read(seg,bus,devfn,reg,len,value); 80 + goto err; 74 81 75 82 spin_lock_irqsave(&pci_config_lock, flags); 76 83 ··· 104 105 if ((bus > 255) || (devfn > 255) || (reg > 4095)) 105 106 return -EINVAL; 106 107 108 + if (reg < 256) 109 + return pci_conf1_write(seg,bus,devfn,reg,len,value); 110 + 107 111 base = get_base_addr(seg, bus, devfn); 108 112 if (!base) 109 - return pci_conf1_write(seg,bus,devfn,reg,len,value); 113 + return -EINVAL; 110 114 111 115 spin_lock_irqsave(&pci_config_lock, flags); 112 116 ··· 135 133 .read = pci_mmcfg_read, 136 134 .write = pci_mmcfg_write, 137 135 }; 138 - 139 - int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus, 140 - unsigned int devfn) 141 - { 142 - return get_base_addr(seg, bus, devfn) != 0; 143 - } 144 136 145 137 int __init pci_mmcfg_arch_init(void) 146 138 {
+10 -12
arch/x86/pci/mmconfig_64.c
··· 40 40 static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) 41 41 { 42 42 char __iomem *addr; 43 - if (seg == 0 && bus < PCI_MMCFG_MAX_CHECK_BUS && 44 - test_bit(32*bus + PCI_SLOT(devfn), pci_mmcfg_fallback_slots)) 45 - return NULL; 43 + 46 44 addr = get_virt(seg, bus); 47 45 if (!addr) 48 46 return NULL; ··· 54 56 55 57 /* Why do we have this when nobody checks it. How about a BUG()!? -AK */ 56 58 if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) { 57 - *value = -1; 59 + err: *value = -1; 58 60 return -EINVAL; 59 61 } 60 62 63 + if (reg < 256) 64 + return pci_conf1_read(seg,bus,devfn,reg,len,value); 65 + 61 66 addr = pci_dev_base(seg, bus, devfn); 62 67 if (!addr) 63 - return pci_conf1_read(seg,bus,devfn,reg,len,value); 68 + goto err; 64 69 65 70 switch (len) { 66 71 case 1: ··· 89 88 if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) 90 89 return -EINVAL; 91 90 91 + if (reg < 256) 92 + return pci_conf1_write(seg,bus,devfn,reg,len,value); 93 + 92 94 addr = pci_dev_base(seg, bus, devfn); 93 95 if (!addr) 94 - return pci_conf1_write(seg,bus,devfn,reg,len,value); 96 + return -EINVAL; 95 97 96 98 switch (len) { 97 99 case 1: ··· 128 124 cfg->address, cfg->address + size - 1); 129 125 } 130 126 return addr; 131 - } 132 - 133 - int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus, 134 - unsigned int devfn) 135 - { 136 - return pci_dev_base(seg, bus, devfn) != NULL; 137 127 } 138 128 139 129 int __init pci_mmcfg_arch_init(void)
-7
arch/x86/pci/pci.h
··· 98 98 99 99 /* pci-mmconfig.c */ 100 100 101 - /* Verify the first 16 busses. We assume that systems with more busses 102 - get MCFG right. */ 103 - #define PCI_MMCFG_MAX_CHECK_BUS 16 104 - extern DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS); 105 - 106 - extern int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus, 107 - unsigned int devfn); 108 101 extern int __init pci_mmcfg_arch_init(void); 109 102 110 103 /*