diff options
Diffstat (limited to 'arch/i386/pci/mmconfig.c')
-rw-r--r-- | arch/i386/pci/mmconfig.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index dfbf80cff834..cc787a7c030c 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c | |||
@@ -30,10 +30,8 @@ static u32 get_base_addr(unsigned int seg, int bus) | |||
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 | /* something bad is going on, no cfg table is found. */ | 33 | /* Not found - fallback to type 1 */ |
34 | /* so we fall back to the old way we used to do this */ | 34 | return 0; |
35 | /* and just rely on the first entry to be correct. */ | ||
36 | return pci_mmcfg_config[0].base_address; | ||
37 | } | 35 | } |
38 | cfg = &pci_mmcfg_config[cfg_num]; | 36 | cfg = &pci_mmcfg_config[cfg_num]; |
39 | if (cfg->pci_segment_group_number != seg) | 37 | if (cfg->pci_segment_group_number != seg) |
@@ -44,9 +42,9 @@ static u32 get_base_addr(unsigned int seg, int bus) | |||
44 | } | 42 | } |
45 | } | 43 | } |
46 | 44 | ||
47 | static inline void pci_exp_set_dev_base(unsigned int seg, int bus, int devfn) | 45 | static inline void pci_exp_set_dev_base(unsigned int base, int bus, int devfn) |
48 | { | 46 | { |
49 | u32 dev_base = get_base_addr(seg, bus) | (bus << 20) | (devfn << 12); | 47 | u32 dev_base = base | (bus << 20) | (devfn << 12); |
50 | if (dev_base != mmcfg_last_accessed_device) { | 48 | if (dev_base != mmcfg_last_accessed_device) { |
51 | mmcfg_last_accessed_device = dev_base; | 49 | mmcfg_last_accessed_device = dev_base; |
52 | set_fixmap_nocache(FIX_PCIE_MCFG, dev_base); | 50 | set_fixmap_nocache(FIX_PCIE_MCFG, dev_base); |
@@ -57,13 +55,18 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, | |||
57 | unsigned int devfn, int reg, int len, u32 *value) | 55 | unsigned int devfn, int reg, int len, u32 *value) |
58 | { | 56 | { |
59 | unsigned long flags; | 57 | unsigned long flags; |
58 | u32 base; | ||
60 | 59 | ||
61 | if (!value || (bus > 255) || (devfn > 255) || (reg > 4095)) | 60 | if (!value || (bus > 255) || (devfn > 255) || (reg > 4095)) |
62 | return -EINVAL; | 61 | return -EINVAL; |
63 | 62 | ||
63 | base = get_base_addr(seg, bus); | ||
64 | if (!base) | ||
65 | return pci_conf1_read(seg,bus,devfn,reg,len,value); | ||
66 | |||
64 | spin_lock_irqsave(&pci_config_lock, flags); | 67 | spin_lock_irqsave(&pci_config_lock, flags); |
65 | 68 | ||
66 | pci_exp_set_dev_base(seg, bus, devfn); | 69 | pci_exp_set_dev_base(base, bus, devfn); |
67 | 70 | ||
68 | switch (len) { | 71 | switch (len) { |
69 | case 1: | 72 | case 1: |
@@ -86,13 +89,18 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, | |||
86 | unsigned int devfn, int reg, int len, u32 value) | 89 | unsigned int devfn, int reg, int len, u32 value) |
87 | { | 90 | { |
88 | unsigned long flags; | 91 | unsigned long flags; |
92 | u32 base; | ||
89 | 93 | ||
90 | if ((bus > 255) || (devfn > 255) || (reg > 4095)) | 94 | if ((bus > 255) || (devfn > 255) || (reg > 4095)) |
91 | return -EINVAL; | 95 | return -EINVAL; |
92 | 96 | ||
97 | base = get_base_addr(seg, bus); | ||
98 | if (!base) | ||
99 | return pci_conf1_write(seg,bus,devfn,reg,len,value); | ||
100 | |||
93 | spin_lock_irqsave(&pci_config_lock, flags); | 101 | spin_lock_irqsave(&pci_config_lock, flags); |
94 | 102 | ||
95 | pci_exp_set_dev_base(seg, bus, devfn); | 103 | pci_exp_set_dev_base(base, bus, devfn); |
96 | 104 | ||
97 | switch (len) { | 105 | switch (len) { |
98 | case 1: | 106 | case 1: |