1/*
2 *	Low-Level PCI Support for PC
3 *
4 *	(c) 1999--2000 Martin Mares <mj@ucw.cz>
5 */
6
7#include <linux/sched.h>
8#include <linux/pci.h>
9#include <linux/ioport.h>
10#include <linux/init.h>
11#include <linux/dmi.h>
12
13#include <asm/acpi.h>
14#include <asm/segment.h>
15#include <asm/io.h>
16#include <asm/smp.h>
17
18#include "pci.h"
19
20unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
21				PCI_PROBE_MMCONF;
22
23static int pci_bf_sort;
24int pci_routeirq;
25int pcibios_last_bus = -1;
26unsigned long pirq_table_addr;
27struct pci_bus *pci_root_bus;
28struct pci_raw_ops *raw_pci_ops;
29
30static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
31{
32	return raw_pci_ops->read(0, bus->number, devfn, where, size, value);
33}
34
35static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
36{
37	return raw_pci_ops->write(0, bus->number, devfn, where, size, value);
38}
39
40struct pci_ops pci_root_ops = {
41	.read = pci_read,
42	.write = pci_write,
43};
44
45/*
46 * legacy, numa, and acpi all want to call pcibios_scan_root
47 * from their initcalls. This flag prevents that.
48 */
49int pcibios_scanned;
50
51/*
52 * This interrupt-safe spinlock protects all accesses to PCI
53 * configuration space.
54 */
55DEFINE_SPINLOCK(pci_config_lock);
56
57/*
58 * Several buggy motherboards address only 16 devices and mirror
59 * them to next 16 IDs. We try to detect this `feature' on all
60 * primary buses (those containing host bridges as they are
61 * expected to be unique) and remove the ghost devices.
62 */
63
64static void __devinit pcibios_fixup_ghosts(struct pci_bus *b)
65{
66	struct list_head *ln, *mn;
67	struct pci_dev *d, *e;
68	int mirror = PCI_DEVFN(16,0);
69	int seen_host_bridge = 0;
70	int i;
71
72	DBG("PCI: Scanning for ghost devices on bus %d\n", b->number);
73	list_for_each(ln, &b->devices) {
74		d = pci_dev_b(ln);
75		if ((d->class >> 8) == PCI_CLASS_BRIDGE_HOST)
76			seen_host_bridge++;
77		for (mn=ln->next; mn != &b->devices; mn=mn->next) {
78			e = pci_dev_b(mn);
79			if (e->devfn != d->devfn + mirror ||
80			    e->vendor != d->vendor ||
81			    e->device != d->device ||
82			    e->class != d->class)
83				continue;
84			for(i=0; i<PCI_NUM_RESOURCES; i++)
85				if (e->resource[i].start != d->resource[i].start ||
86				    e->resource[i].end != d->resource[i].end ||
87				    e->resource[i].flags != d->resource[i].flags)
88					continue;
89			break;
90		}
91		if (mn == &b->devices)
92			return;
93	}
94	if (!seen_host_bridge)
95		return;
96	printk(KERN_WARNING "PCI: Ignoring ghost devices on bus %02x\n", b->number);
97
98	ln = &b->devices;
99	while (ln->next != &b->devices) {
100		d = pci_dev_b(ln->next);
101		if (d->devfn >= mirror) {
102			list_del(&d->global_list);
103			list_del(&d->bus_list);
104			kfree(d);
105		} else
106			ln = ln->next;
107	}
108}
109
110/*
111 *  Called after each bus is probed, but before its children
112 *  are examined.
113 */
114
115void __devinit  pcibios_fixup_bus(struct pci_bus *b)
116{
117	pcibios_fixup_ghosts(b);
118	pci_read_bridge_bases(b);
119}
120
121/*
122 * Only use DMI information to set this if nothing was passed
123 * on the kernel command line (which was parsed earlier).
124 */
125
126static int __devinit set_bf_sort(struct dmi_system_id *d)
127{
128	if (pci_bf_sort == pci_bf_sort_default) {
129		pci_bf_sort = pci_dmi_bf;
130		printk(KERN_INFO "PCI: %s detected, enabling pci=bfsort.\n", d->ident);
131	}
132	return 0;
133}
134
135/*
136 * Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus)
137 */
138#ifdef __i386__
139static int __devinit assign_all_busses(struct dmi_system_id *d)
140{
141	pci_probe |= PCI_ASSIGN_ALL_BUSSES;
142	printk(KERN_INFO "%s detected: enabling PCI bus# renumbering"
143			" (pci=assign-busses)\n", d->ident);
144	return 0;
145}
146#endif
147
148static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = {
149#ifdef __i386__
150/*
151 * Laptops which need pci=assign-busses to see Cardbus cards
152 */
153	{
154		.callback = assign_all_busses,
155		.ident = "Samsung X20 Laptop",
156		.matches = {
157			DMI_MATCH(DMI_SYS_VENDOR, "Samsung Electronics"),
158			DMI_MATCH(DMI_PRODUCT_NAME, "SX20S"),
159		},
160	},
161#endif		/* __i386__ */
162	{
163		.callback = set_bf_sort,
164		.ident = "Dell PowerEdge 1950",
165		.matches = {
166			DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
167			DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1950"),
168		},
169	},
170	{
171		.callback = set_bf_sort,
172		.ident = "Dell PowerEdge 1955",
173		.matches = {
174			DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
175			DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1955"),
176		},
177	},
178	{
179		.callback = set_bf_sort,
180		.ident = "Dell PowerEdge 2900",
181		.matches = {
182			DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
183			DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2900"),
184		},
185	},
186	{
187		.callback = set_bf_sort,
188		.ident = "Dell PowerEdge 2950",
189		.matches = {
190			DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
191			DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2950"),
192		},
193	},
194	{
195		.callback = set_bf_sort,
196		.ident = "Dell PowerEdge R900",
197		.matches = {
198			DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
199			DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R900"),
200		},
201	},
202	{
203		.callback = set_bf_sort,
204		.ident = "HP ProLiant BL20p G3",
205		.matches = {
206			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
207			DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL20p G3"),
208		},
209	},
210	{
211		.callback = set_bf_sort,
212		.ident = "HP ProLiant BL20p G4",
213		.matches = {
214			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
215			DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL20p G4"),
216		},
217	},
218	{
219		.callback = set_bf_sort,
220		.ident = "HP ProLiant BL30p G1",
221		.matches = {
222			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
223			DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL30p G1"),
224		},
225	},
226	{
227		.callback = set_bf_sort,
228		.ident = "HP ProLiant BL25p G1",
229		.matches = {
230			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
231			DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL25p G1"),
232		},
233	},
234	{
235		.callback = set_bf_sort,
236		.ident = "HP ProLiant BL35p G1",
237		.matches = {
238			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
239			DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL35p G1"),
240		},
241	},
242	{
243		.callback = set_bf_sort,
244		.ident = "HP ProLiant BL45p G1",
245		.matches = {
246			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
247			DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL45p G1"),
248		},
249	},
250	{
251		.callback = set_bf_sort,
252		.ident = "HP ProLiant BL45p G2",
253		.matches = {
254			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
255			DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL45p G2"),
256		},
257	},
258	{
259		.callback = set_bf_sort,
260		.ident = "HP ProLiant BL460c G1",
261		.matches = {
262			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
263			DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL460c G1"),
264		},
265	},
266	{
267		.callback = set_bf_sort,
268		.ident = "HP ProLiant BL465c G1",
269		.matches = {
270			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
271			DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL465c G1"),
272		},
273	},
274	{
275		.callback = set_bf_sort,
276		.ident = "HP ProLiant BL480c G1",
277		.matches = {
278			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
279			DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL480c G1"),
280		},
281	},
282	{
283		.callback = set_bf_sort,
284		.ident = "HP ProLiant BL685c G1",
285		.matches = {
286			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
287			DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL685c G1"),
288		},
289	},
290	{}
291};
292
293struct pci_bus * __devinit pcibios_scan_root(int busnum)
294{
295	struct pci_bus *bus = NULL;
296
297	dmi_check_system(pciprobe_dmi_table);
298
299	while ((bus = pci_find_next_bus(bus)) != NULL) {
300		if (bus->number == busnum) {
301			/* Already scanned */
302			return bus;
303		}
304	}
305
306	printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busnum);
307
308	return pci_scan_bus_parented(NULL, busnum, &pci_root_ops, NULL);
309}
310
311extern u8 pci_cache_line_size;
312
313static int __init pcibios_init(void)
314{
315	struct cpuinfo_x86 *c = &boot_cpu_data;
316
317	if (!raw_pci_ops) {
318		printk(KERN_WARNING "PCI: System does not support PCI\n");
319		return 0;
320	}
321
322	/*
323	 * Assume PCI cacheline size of 32 bytes for all x86s except K7/K8
324	 * and P4. It's also good for 386/486s (which actually have 16)
325	 * as quite a few PCI devices do not support smaller values.
326	 */
327	pci_cache_line_size = 32 >> 2;
328	if (c->x86 >= 6 && c->x86_vendor == X86_VENDOR_AMD)
329		pci_cache_line_size = 64 >> 2;	/* K7 & K8 */
330	else if (c->x86 > 6 && c->x86_vendor == X86_VENDOR_INTEL)
331		pci_cache_line_size = 128 >> 2;	/* P4 */
332
333	pcibios_resource_survey();
334
335	if (pci_bf_sort >= pci_force_bf)
336		pci_sort_breadthfirst();
337#ifdef CONFIG_PCI_BIOS
338	if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT))
339		pcibios_sort();
340#endif
341	return 0;
342}
343
344subsys_initcall(pcibios_init);
345
346char * __devinit  pcibios_setup(char *str)
347{
348	if (!strcmp(str, "off")) {
349		pci_probe = 0;
350		return NULL;
351	} else if (!strcmp(str, "bfsort")) {
352		pci_bf_sort = pci_force_bf;
353		return NULL;
354	} else if (!strcmp(str, "nobfsort")) {
355		pci_bf_sort = pci_force_nobf;
356		return NULL;
357	}
358#ifdef CONFIG_PCI_BIOS
359	else if (!strcmp(str, "bios")) {
360		pci_probe = PCI_PROBE_BIOS;
361		return NULL;
362	} else if (!strcmp(str, "nobios")) {
363		pci_probe &= ~PCI_PROBE_BIOS;
364		return NULL;
365	} else if (!strcmp(str, "nosort")) {
366		pci_probe |= PCI_NO_SORT;
367		return NULL;
368	} else if (!strcmp(str, "biosirq")) {
369		pci_probe |= PCI_BIOS_IRQ_SCAN;
370		return NULL;
371	} else if (!strncmp(str, "pirqaddr=", 9)) {
372		pirq_table_addr = simple_strtoul(str+9, NULL, 0);
373		return NULL;
374	}
375#endif
376#ifdef CONFIG_PCI_DIRECT
377	else if (!strcmp(str, "conf1")) {
378		pci_probe = PCI_PROBE_CONF1 | PCI_NO_CHECKS;
379		return NULL;
380	}
381	else if (!strcmp(str, "conf2")) {
382		pci_probe = PCI_PROBE_CONF2 | PCI_NO_CHECKS;
383		return NULL;
384	}
385#endif
386#ifdef CONFIG_PCI_MMCONFIG
387	else if (!strcmp(str, "nommconf")) {
388		pci_probe &= ~PCI_PROBE_MMCONF;
389		return NULL;
390	}
391#endif
392	else if (!strcmp(str, "noacpi")) {
393		acpi_noirq_set();
394		return NULL;
395	}
396	else if (!strcmp(str, "noearly")) {
397		pci_probe |= PCI_PROBE_NOEARLY;
398		return NULL;
399	}
400#ifndef CONFIG_X86_VISWS
401	else if (!strcmp(str, "usepirqmask")) {
402		pci_probe |= PCI_USE_PIRQ_MASK;
403		return NULL;
404	} else if (!strncmp(str, "irqmask=", 8)) {
405		pcibios_irq_mask = simple_strtol(str+8, NULL, 0);
406		return NULL;
407	} else if (!strncmp(str, "lastbus=", 8)) {
408		pcibios_last_bus = simple_strtol(str+8, NULL, 0);
409		return NULL;
410	}
411#endif
412	else if (!strcmp(str, "rom")) {
413		pci_probe |= PCI_ASSIGN_ROMS;
414		return NULL;
415	} else if (!strcmp(str, "assign-busses")) {
416		pci_probe |= PCI_ASSIGN_ALL_BUSSES;
417		return NULL;
418	} else if (!strcmp(str, "routeirq")) {
419		pci_routeirq = 1;
420		return NULL;
421	}
422	return str;
423}
424
425unsigned int pcibios_assign_all_busses(void)
426{
427	return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
428}
429
430int pcibios_enable_device(struct pci_dev *dev, int mask)
431{
432	int err;
433
434	if ((err = pcibios_enable_resources(dev, mask)) < 0)
435		return err;
436
437	if (!dev->msi_enabled)
438		return pcibios_enable_irq(dev);
439	return 0;
440}
441
442void pcibios_disable_device (struct pci_dev *dev)
443{
444	if (!dev->msi_enabled && pcibios_disable_irq)
445		pcibios_disable_irq(dev);
446}
447