diff options
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) |