diff options
author | Andi Kleen <ak@suse.de> | 2006-01-26 20:03:50 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-01-31 21:00:13 -0500 |
commit | 3103039cc2a8dc6ababc29afac5c3cadbfa69af9 (patch) | |
tree | f89e6a1ca25281fbf78f6438c0463d06251ae3a3 /arch | |
parent | 877be3f0304de16a77f11b2b47f1291b800d5479 (diff) |
[PATCH] PCI: handle bogus MCFG entries
Handle more bogus MCFG entries
Some Asus P4 boards seem to have broken MCFG tables with
only a single entry for busses 0-0. Special case these
and assume they mean all busses can be accessed.
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/i386/pci/mmconfig.c | 15 | ||||
-rw-r--r-- | arch/x86_64/pci/mmconfig.c | 19 |
2 files changed, 27 insertions, 7 deletions
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index 4bb4d4b0f73a..0ee8a983708c 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c | |||
@@ -36,8 +36,7 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) | |||
36 | while (1) { | 36 | while (1) { |
37 | ++cfg_num; | 37 | ++cfg_num; |
38 | if (cfg_num >= pci_mmcfg_config_num) { | 38 | if (cfg_num >= pci_mmcfg_config_num) { |
39 | /* Not found - fallback to type 1 */ | 39 | break; |
40 | return 0; | ||
41 | } | 40 | } |
42 | cfg = &pci_mmcfg_config[cfg_num]; | 41 | cfg = &pci_mmcfg_config[cfg_num]; |
43 | if (cfg->pci_segment_group_number != seg) | 42 | if (cfg->pci_segment_group_number != seg) |
@@ -46,6 +45,18 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) | |||
46 | (cfg->end_bus_number >= bus)) | 45 | (cfg->end_bus_number >= bus)) |
47 | return cfg->base_address; | 46 | return cfg->base_address; |
48 | } | 47 | } |
48 | |||
49 | /* Handle more broken MCFG tables on Asus etc. | ||
50 | They only contain a single entry for bus 0-0. Assume | ||
51 | this applies to all busses. */ | ||
52 | cfg = &pci_mmcfg_config[0]; | ||
53 | if (pci_mmcfg_config_num == 1 && | ||
54 | cfg->pci_segment_group_number == 0 && | ||
55 | (cfg->start_bus_number | cfg->end_bus_number) == 0) | ||
56 | return cfg->base_address; | ||
57 | |||
58 | /* Fall back to type 0 */ | ||
59 | return 0; | ||
49 | } | 60 | } |
50 | 61 | ||
51 | static inline void pci_exp_set_dev_base(unsigned int base, int bus, int devfn) | 62 | static inline void pci_exp_set_dev_base(unsigned int base, int bus, int devfn) |
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index f16c0d57c552..00d4ddbf980c 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c | |||
@@ -29,11 +29,8 @@ static char __iomem *get_virt(unsigned int seg, unsigned bus) | |||
29 | 29 | ||
30 | while (1) { | 30 | while (1) { |
31 | ++cfg_num; | 31 | ++cfg_num; |
32 | if (cfg_num >= pci_mmcfg_config_num) { | 32 | if (cfg_num >= pci_mmcfg_config_num) |
33 | /* Not found - fall back to type 1. This happens | 33 | break; |
34 | e.g. on the internal devices of a K8 northbridge. */ | ||
35 | return NULL; | ||
36 | } | ||
37 | cfg = pci_mmcfg_virt[cfg_num].cfg; | 34 | cfg = pci_mmcfg_virt[cfg_num].cfg; |
38 | if (cfg->pci_segment_group_number != seg) | 35 | if (cfg->pci_segment_group_number != seg) |
39 | continue; | 36 | continue; |
@@ -41,6 +38,18 @@ static char __iomem *get_virt(unsigned int seg, unsigned bus) | |||
41 | (cfg->end_bus_number >= bus)) | 38 | (cfg->end_bus_number >= bus)) |
42 | return pci_mmcfg_virt[cfg_num].virt; | 39 | return pci_mmcfg_virt[cfg_num].virt; |
43 | } | 40 | } |
41 | |||
42 | /* Handle more broken MCFG tables on Asus etc. | ||
43 | They only contain a single entry for bus 0-0. Assume | ||
44 | this applies to all busses. */ | ||
45 | cfg = &pci_mmcfg_config[0]; | ||
46 | if (pci_mmcfg_config_num == 1 && | ||
47 | cfg->pci_segment_group_number == 0 && | ||
48 | (cfg->start_bus_number | cfg->end_bus_number) == 0) | ||
49 | return cfg->base_address; | ||
50 | |||
51 | /* Fall back to type 0 */ | ||
52 | return 0; | ||
44 | } | 53 | } |
45 | 54 | ||
46 | static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) | 55 | static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) |