Skip to content

Commit

Permalink
[PATCH] PCI: handle bogus MCFG entries
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Andi Kleen authored and Greg Kroah-Hartman committed Feb 1, 2006
1 parent 877be3f commit 3103039
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 7 deletions.
15 changes: 13 additions & 2 deletions arch/i386/pci/mmconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn)
while (1) {
++cfg_num;
if (cfg_num >= pci_mmcfg_config_num) {
/* Not found - fallback to type 1 */
return 0;
break;
}
cfg = &pci_mmcfg_config[cfg_num];
if (cfg->pci_segment_group_number != seg)
Expand All @@ -46,6 +45,18 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn)
(cfg->end_bus_number >= bus))
return cfg->base_address;
}

/* Handle more broken MCFG tables on Asus etc.
They only contain a single entry for bus 0-0. Assume
this applies to all busses. */
cfg = &pci_mmcfg_config[0];
if (pci_mmcfg_config_num == 1 &&
cfg->pci_segment_group_number == 0 &&
(cfg->start_bus_number | cfg->end_bus_number) == 0)
return cfg->base_address;

/* Fall back to type 0 */
return 0;
}

static inline void pci_exp_set_dev_base(unsigned int base, int bus, int devfn)
Expand Down
19 changes: 14 additions & 5 deletions arch/x86_64/pci/mmconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,27 @@ static char __iomem *get_virt(unsigned int seg, unsigned bus)

while (1) {
++cfg_num;
if (cfg_num >= pci_mmcfg_config_num) {
/* Not found - fall back to type 1. This happens
e.g. on the internal devices of a K8 northbridge. */
return NULL;
}
if (cfg_num >= pci_mmcfg_config_num)
break;
cfg = pci_mmcfg_virt[cfg_num].cfg;
if (cfg->pci_segment_group_number != seg)
continue;
if ((cfg->start_bus_number <= bus) &&
(cfg->end_bus_number >= bus))
return pci_mmcfg_virt[cfg_num].virt;
}

/* Handle more broken MCFG tables on Asus etc.
They only contain a single entry for bus 0-0. Assume
this applies to all busses. */
cfg = &pci_mmcfg_config[0];
if (pci_mmcfg_config_num == 1 &&
cfg->pci_segment_group_number == 0 &&
(cfg->start_bus_number | cfg->end_bus_number) == 0)
return cfg->base_address;

/* Fall back to type 0 */
return 0;
}

static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
Expand Down

0 comments on commit 3103039

Please sign in to comment.