Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 198810
Collapse All | Expand All

(-)a/arch/x86/pci/mmconfig-shared.c (-35 lines)
Lines 22-63 Link Here
22
#define MMCONFIG_APER_MIN	(2 * 1024*1024)
22
#define MMCONFIG_APER_MIN	(2 * 1024*1024)
23
#define MMCONFIG_APER_MAX	(256 * 1024*1024)
23
#define MMCONFIG_APER_MAX	(256 * 1024*1024)
24
24
25
DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS);
26
27
/* Indicate if the mmcfg resources have been placed into the resource table. */
25
/* Indicate if the mmcfg resources have been placed into the resource table. */
28
static int __initdata pci_mmcfg_resources_inserted;
26
static int __initdata pci_mmcfg_resources_inserted;
29
27
30
/* K8 systems have some devices (typically in the builtin northbridge)
31
   that are only accessible using type1
32
   Normally this can be expressed in the MCFG by not listing them
33
   and assigning suitable _SEGs, but this isn't implemented in some BIOS.
34
   Instead try to discover all devices on bus 0 that are unreachable using MM
35
   and fallback for them. */
36
static void __init unreachable_devices(void)
37
{
38
	int i, bus;
39
	/* Use the max bus number from ACPI here? */
40
	for (bus = 0; bus < PCI_MMCFG_MAX_CHECK_BUS; bus++) {
41
		for (i = 0; i < 32; i++) {
42
			unsigned int devfn = PCI_DEVFN(i, 0);
43
			u32 val1, val2;
44
45
			pci_conf1_read(0, bus, devfn, 0, 4, &val1);
46
			if (val1 == 0xffffffff)
47
				continue;
48
49
			if (pci_mmcfg_arch_reachable(0, bus, devfn)) {
50
				raw_pci_ops->read(0, bus, devfn, 0, 4, &val2);
51
				if (val1 == val2)
52
					continue;
53
			}
54
			set_bit(i + 32 * bus, pci_mmcfg_fallback_slots);
55
			printk(KERN_NOTICE "PCI: No mmconfig possible on device"
56
			       " %02x:%02x\n", bus, i);
57
		}
58
	}
59
}
60
61
static const char __init *pci_mmcfg_e7520(void)
28
static const char __init *pci_mmcfg_e7520(void)
62
{
29
{
63
	u32 win;
30
	u32 win;
Lines 270-277 void __init pci_mmcfg_init(int type) Link Here
270
		return;
237
		return;
271
238
272
	if (pci_mmcfg_arch_init()) {
239
	if (pci_mmcfg_arch_init()) {
273
		if (type == 1)
274
			unreachable_devices();
275
		if (known_bridge)
240
		if (known_bridge)
276
			pci_mmcfg_insert_resources(IORESOURCE_BUSY);
241
			pci_mmcfg_insert_resources(IORESOURCE_BUSY);
277
		pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
242
		pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
(-)a/arch/x86/pci/mmconfig_32.c (-13 / +9 lines)
Lines 30-39 static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) Link Here
30
	struct acpi_mcfg_allocation *cfg;
30
	struct acpi_mcfg_allocation *cfg;
31
	int cfg_num;
31
	int cfg_num;
32
32
33
	if (seg == 0 && bus < PCI_MMCFG_MAX_CHECK_BUS &&
34
	    test_bit(PCI_SLOT(devfn) + 32*bus, pci_mmcfg_fallback_slots))
35
		return 0;
36
37
	for (cfg_num = 0; cfg_num < pci_mmcfg_config_num; cfg_num++) {
33
	for (cfg_num = 0; cfg_num < pci_mmcfg_config_num; cfg_num++) {
38
		cfg = &pci_mmcfg_config[cfg_num];
34
		cfg = &pci_mmcfg_config[cfg_num];
39
		if (cfg->pci_segment == seg &&
35
		if (cfg->pci_segment == seg &&
Lines 68-80 static int pci_mmcfg_read(unsigned int seg, unsigned int bus, Link Here
68
	u32 base;
64
	u32 base;
69
65
70
	if ((bus > 255) || (devfn > 255) || (reg > 4095)) {
66
	if ((bus > 255) || (devfn > 255) || (reg > 4095)) {
71
		*value = -1;
67
err:		*value = -1;
72
		return -EINVAL;
68
		return -EINVAL;
73
	}
69
	}
74
70
71
	if (reg < 256)
72
		return pci_conf1_read(seg,bus,devfn,reg,len,value);
73
75
	base = get_base_addr(seg, bus, devfn);
74
	base = get_base_addr(seg, bus, devfn);
76
	if (!base)
75
	if (!base)
77
		return pci_conf1_read(seg,bus,devfn,reg,len,value);
76
		goto err;
78
77
79
	spin_lock_irqsave(&pci_config_lock, flags);
78
	spin_lock_irqsave(&pci_config_lock, flags);
80
79
Lines 105-113 static int pci_mmcfg_write(unsigned int seg, unsigned int bus, Link Here
105
	if ((bus > 255) || (devfn > 255) || (reg > 4095))
104
	if ((bus > 255) || (devfn > 255) || (reg > 4095))
106
		return -EINVAL;
105
		return -EINVAL;
107
106
107
	if (reg < 256)
108
		return pci_conf1_write(seg,bus,devfn,reg,len,value);
109
108
	base = get_base_addr(seg, bus, devfn);
110
	base = get_base_addr(seg, bus, devfn);
109
	if (!base)
111
	if (!base)
110
		return pci_conf1_write(seg,bus,devfn,reg,len,value);
112
		return -EINVAL;
111
113
112
	spin_lock_irqsave(&pci_config_lock, flags);
114
	spin_lock_irqsave(&pci_config_lock, flags);
113
115
Lines 134-145 static struct pci_raw_ops pci_mmcfg = { Link Here
134
	.write =	pci_mmcfg_write,
136
	.write =	pci_mmcfg_write,
135
};
137
};
136
138
137
int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus,
138
				    unsigned int devfn)
139
{
140
	return get_base_addr(seg, bus, devfn) != 0;
141
}
142
143
int __init pci_mmcfg_arch_init(void)
139
int __init pci_mmcfg_arch_init(void)
144
{
140
{
145
	printk(KERN_INFO "PCI: Using MMCONFIG\n");
141
	printk(KERN_INFO "PCI: Using MMCONFIG\n");
(-)a/arch/x86/pci/mmconfig_64.c (-12 / +10 lines)
Lines 40-48 static char __iomem *get_virt(unsigned int seg, unsigned bus) Link Here
40
static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
40
static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
41
{
41
{
42
	char __iomem *addr;
42
	char __iomem *addr;
43
	if (seg == 0 && bus < PCI_MMCFG_MAX_CHECK_BUS &&
43
44
		test_bit(32*bus + PCI_SLOT(devfn), pci_mmcfg_fallback_slots))
45
		return NULL;
46
	addr = get_virt(seg, bus);
44
	addr = get_virt(seg, bus);
47
	if (!addr)
45
	if (!addr)
48
		return NULL;
46
		return NULL;
Lines 56-68 static int pci_mmcfg_read(unsigned int seg, unsigned int bus, Link Here
56
54
57
	/* Why do we have this when nobody checks it. How about a BUG()!? -AK */
55
	/* Why do we have this when nobody checks it. How about a BUG()!? -AK */
58
	if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) {
56
	if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) {
59
		*value = -1;
57
err:		*value = -1;
60
		return -EINVAL;
58
		return -EINVAL;
61
	}
59
	}
62
60
61
	if (reg < 256)
62
		return pci_conf1_read(seg,bus,devfn,reg,len,value);
63
63
	addr = pci_dev_base(seg, bus, devfn);
64
	addr = pci_dev_base(seg, bus, devfn);
64
	if (!addr)
65
	if (!addr)
65
		return pci_conf1_read(seg,bus,devfn,reg,len,value);
66
		goto err;
66
67
67
	switch (len) {
68
	switch (len) {
68
	case 1:
69
	case 1:
Lines 88-96 static int pci_mmcfg_write(unsigned int seg, unsigned int bus, Link Here
88
	if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
89
	if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
89
		return -EINVAL;
90
		return -EINVAL;
90
91
92
	if (reg < 256)
93
		return pci_conf1_write(seg,bus,devfn,reg,len,value);
94
91
	addr = pci_dev_base(seg, bus, devfn);
95
	addr = pci_dev_base(seg, bus, devfn);
92
	if (!addr)
96
	if (!addr)
93
		return pci_conf1_write(seg,bus,devfn,reg,len,value);
97
		return -EINVAL;
94
98
95
	switch (len) {
99
	switch (len) {
96
	case 1:
100
	case 1:
Lines 126-137 static void __iomem * __init mcfg_ioremap(struct acpi_mcfg_allocation *cfg) Link Here
126
	return addr;
130
	return addr;
127
}
131
}
128
132
129
int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus,
130
				    unsigned int devfn)
131
{
132
	return pci_dev_base(seg, bus, devfn) != NULL;
133
}
134
135
int __init pci_mmcfg_arch_init(void)
133
int __init pci_mmcfg_arch_init(void)
136
{
134
{
137
	int i;
135
	int i;
(-)a/arch/x86/pci/pci.h (-7 lines)
Lines 98-110 extern void pcibios_sort(void); Link Here
98
98
99
/* pci-mmconfig.c */
99
/* pci-mmconfig.c */
100
100
101
/* Verify the first 16 busses. We assume that systems with more busses
102
   get MCFG right. */
103
#define PCI_MMCFG_MAX_CHECK_BUS 16
104
extern DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS);
105
106
extern int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus,
107
					   unsigned int devfn);
108
extern int __init pci_mmcfg_arch_init(void);
101
extern int __init pci_mmcfg_arch_init(void);
109
102
110
/*
103
/*

Return to bug 198810