aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/pci/mmconfig.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/pci/mmconfig.c')
-rw-r--r--arch/i386/pci/mmconfig.c24
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
47static inline void pci_exp_set_dev_base(unsigned int seg, int bus, int devfn) 45static 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: