diff options
Diffstat (limited to 'arch/i386/pci/mmconfig.c')
-rw-r--r-- | arch/i386/pci/mmconfig.c | 52 |
1 files changed, 30 insertions, 22 deletions
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index ee815c7d3e4c..2002c741a383 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c | |||
@@ -17,12 +17,15 @@ | |||
17 | 17 | ||
18 | #define MMCONFIG_APER_SIZE (256*1024*1024) | 18 | #define MMCONFIG_APER_SIZE (256*1024*1024) |
19 | 19 | ||
20 | /* Assume systems with more busses have correct MCFG */ | ||
21 | #define MAX_CHECK_BUS 16 | ||
22 | |||
20 | #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) | 23 | #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) |
21 | 24 | ||
22 | /* The base address of the last MMCONFIG device accessed */ | 25 | /* The base address of the last MMCONFIG device accessed */ |
23 | static u32 mmcfg_last_accessed_device; | 26 | static u32 mmcfg_last_accessed_device; |
24 | 27 | ||
25 | static DECLARE_BITMAP(fallback_slots, 32); | 28 | static DECLARE_BITMAP(fallback_slots, MAX_CHECK_BUS*32); |
26 | 29 | ||
27 | /* | 30 | /* |
28 | * Functions for accessing PCI configuration space with MMCONFIG accesses | 31 | * Functions for accessing PCI configuration space with MMCONFIG accesses |
@@ -32,8 +35,8 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) | |||
32 | int cfg_num = -1; | 35 | int cfg_num = -1; |
33 | struct acpi_table_mcfg_config *cfg; | 36 | struct acpi_table_mcfg_config *cfg; |
34 | 37 | ||
35 | if (seg == 0 && bus == 0 && | 38 | if (seg == 0 && bus < MAX_CHECK_BUS && |
36 | test_bit(PCI_SLOT(devfn), fallback_slots)) | 39 | test_bit(PCI_SLOT(devfn) + 32*bus, fallback_slots)) |
37 | return 0; | 40 | return 0; |
38 | 41 | ||
39 | while (1) { | 42 | while (1) { |
@@ -149,29 +152,34 @@ static struct pci_raw_ops pci_mmcfg = { | |||
149 | Normally this can be expressed in the MCFG by not listing them | 152 | Normally this can be expressed in the MCFG by not listing them |
150 | and assigning suitable _SEGs, but this isn't implemented in some BIOS. | 153 | and assigning suitable _SEGs, but this isn't implemented in some BIOS. |
151 | Instead try to discover all devices on bus 0 that are unreachable using MM | 154 | Instead try to discover all devices on bus 0 that are unreachable using MM |
152 | and fallback for them. | 155 | and fallback for them. */ |
153 | We only do this for bus 0/seg 0 */ | ||
154 | static __init void unreachable_devices(void) | 156 | static __init void unreachable_devices(void) |
155 | { | 157 | { |
156 | int i; | 158 | int i, k; |
157 | unsigned long flags; | 159 | unsigned long flags; |
158 | 160 | ||
159 | for (i = 0; i < 32; i++) { | 161 | for (k = 0; k < MAX_CHECK_BUS; k++) { |
160 | u32 val1; | 162 | for (i = 0; i < 32; i++) { |
161 | u32 addr; | 163 | u32 val1; |
162 | 164 | u32 addr; | |
163 | pci_conf1_read(0, 0, PCI_DEVFN(i, 0), 0, 4, &val1); | 165 | |
164 | if (val1 == 0xffffffff) | 166 | pci_conf1_read(0, k, PCI_DEVFN(i, 0), 0, 4, &val1); |
165 | continue; | 167 | if (val1 == 0xffffffff) |
166 | 168 | continue; | |
167 | /* Locking probably not needed, but safer */ | 169 | |
168 | spin_lock_irqsave(&pci_config_lock, flags); | 170 | /* Locking probably not needed, but safer */ |
169 | addr = get_base_addr(0, 0, PCI_DEVFN(i, 0)); | 171 | spin_lock_irqsave(&pci_config_lock, flags); |
170 | if (addr != 0) | 172 | addr = get_base_addr(0, k, PCI_DEVFN(i, 0)); |
171 | pci_exp_set_dev_base(addr, 0, PCI_DEVFN(i, 0)); | 173 | if (addr != 0) |
172 | if (addr == 0 || readl((u32 __iomem *)mmcfg_virt_addr) != val1) | 174 | pci_exp_set_dev_base(addr, k, PCI_DEVFN(i, 0)); |
173 | set_bit(i, fallback_slots); | 175 | if (addr == 0 || |
174 | spin_unlock_irqrestore(&pci_config_lock, flags); | 176 | readl((u32 __iomem *)mmcfg_virt_addr) != val1) { |
177 | set_bit(i, fallback_slots); | ||
178 | printk(KERN_NOTICE | ||
179 | "PCI: No mmconfig possible on %x:%x\n", k, i); | ||
180 | } | ||
181 | spin_unlock_irqrestore(&pci_config_lock, flags); | ||
182 | } | ||
175 | } | 183 | } |
176 | } | 184 | } |
177 | 185 | ||