Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
587 | giacomo | 1 | /* |
2 | * Low-Level PCI Support for PC |
||
3 | * |
||
4 | * (c) 1999--2000 Martin Mares <mj@ucw.cz> |
||
5 | */ |
||
6 | |||
7 | #include <linuxcomp.h> |
||
8 | |||
9 | #include <linux/sched.h> |
||
10 | #include <linux/pci.h> |
||
11 | #include <linux/ioport.h> |
||
12 | #include <linux/init.h> |
||
13 | |||
14 | #include <asm/segment.h> |
||
15 | #include <asm/io.h> |
||
16 | #include <asm/smp.h> |
||
17 | |||
18 | #include "pci2.h" |
||
19 | |||
20 | #ifdef CONFIG_PCI_BIOS |
||
21 | extern void pcibios_sort(void); |
||
22 | #endif |
||
23 | |||
24 | unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2; |
||
25 | |||
26 | int pcibios_last_bus = -1; |
||
27 | struct pci_bus *pci_root_bus = NULL; |
||
28 | struct pci_raw_ops *raw_pci_ops; |
||
29 | |||
30 | static 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 | |||
35 | static 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 | |||
40 | struct 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 | */ |
||
49 | int pcibios_scanned; |
||
50 | |||
51 | /* |
||
52 | * This interrupt-safe spinlock protects all accesses to PCI |
||
53 | * configuration space. |
||
54 | */ |
||
55 | spinlock_t pci_config_lock = SPIN_LOCK_UNLOCKED; |
||
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 | |||
64 | static 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 | for (ln=b->devices.next; ln != &b->devices; ln=ln->next) { |
||
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 | |||
115 | void __devinit pcibios_fixup_bus(struct pci_bus *b) |
||
116 | { |
||
117 | pcibios_fixup_ghosts(b); |
||
118 | pci_read_bridge_bases(b); |
||
119 | } |
||
120 | |||
121 | |||
122 | struct pci_bus * __devinit pcibios_scan_root(int busnum) |
||
123 | { |
||
124 | struct pci_bus *bus = NULL; |
||
125 | |||
126 | while ((bus = pci_find_next_bus(bus)) != NULL) { |
||
127 | if (bus->number == busnum) { |
||
128 | /* Already scanned */ |
||
129 | return bus; |
||
130 | } |
||
131 | } |
||
132 | |||
133 | printk("PCI: Probing PCI hardware (bus %02x)\n", busnum); |
||
134 | |||
135 | return pci_scan_bus(busnum, &pci_root_ops, NULL); |
||
136 | } |
||
137 | |||
138 | extern u8 pci_cache_line_size; |
||
139 | |||
140 | int __init pcibios_init(void) |
||
141 | { |
||
142 | |||
143 | if (!raw_pci_ops) { |
||
144 | printk("PCI: System does not support PCI\n"); |
||
145 | return 0; |
||
146 | } |
||
147 | |||
148 | /* |
||
149 | * Assume PCI cacheline size of 32 bytes for all x86s except K7/K8 |
||
150 | * and P4. It's also good for 386/486s (which actually have 16) |
||
151 | * as quite a few PCI devices do not support smaller values. |
||
152 | */ |
||
153 | pci_cache_line_size = 32 >> 2; |
||
154 | |||
155 | pcibios_resource_survey(); |
||
156 | |||
157 | #ifdef CONFIG_PCI_BIOS |
||
158 | if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT)) |
||
159 | pcibios_sort(); |
||
160 | #endif |
||
161 | return 0; |
||
162 | } |
||
163 | |||
164 | subsys_initcall(pcibios_init); |
||
165 | |||
166 | char * __devinit pcibios_setup(char *str) |
||
167 | { |
||
168 | if (!strcmp(str, "off")) { |
||
169 | pci_probe = 0; |
||
170 | return NULL; |
||
171 | } |
||
172 | #ifdef CONFIG_PCI_BIOS |
||
173 | else if (!strcmp(str, "bios")) { |
||
174 | pci_probe = PCI_PROBE_BIOS; |
||
175 | return NULL; |
||
176 | } else if (!strcmp(str, "nobios")) { |
||
177 | pci_probe &= ~PCI_PROBE_BIOS; |
||
178 | return NULL; |
||
179 | } else if (!strcmp(str, "nosort")) { |
||
180 | pci_probe |= PCI_NO_SORT; |
||
181 | return NULL; |
||
182 | } else if (!strcmp(str, "biosirq")) { |
||
183 | pci_probe |= PCI_BIOS_IRQ_SCAN; |
||
184 | return NULL; |
||
185 | } |
||
186 | #endif |
||
187 | #ifdef CONFIG_PCI_DIRECT |
||
188 | else if (!strcmp(str, "conf1")) { |
||
189 | pci_probe = PCI_PROBE_CONF1 | PCI_NO_CHECKS; |
||
190 | return NULL; |
||
191 | } |
||
192 | else if (!strcmp(str, "conf2")) { |
||
193 | pci_probe = PCI_PROBE_CONF2 | PCI_NO_CHECKS; |
||
194 | return NULL; |
||
195 | } |
||
196 | #endif |
||
197 | #ifdef CONFIG_ACPI_PCI |
||
198 | else if (!strcmp(str, "noacpi")) { |
||
199 | pci_probe |= PCI_NO_ACPI_ROUTING; |
||
200 | return NULL; |
||
201 | } |
||
202 | #endif |
||
203 | #ifndef CONFIG_X86_VISWS |
||
204 | else if (!strcmp(str, "usepirqmask")) { |
||
205 | pci_probe |= PCI_USE_PIRQ_MASK; |
||
206 | return NULL; |
||
207 | } else if (!strncmp(str, "irqmask=", 8)) { |
||
208 | pcibios_irq_mask = simple_strtol(str+8, NULL, 0); |
||
209 | return NULL; |
||
210 | } else if (!strncmp(str, "lastbus=", 8)) { |
||
211 | pcibios_last_bus = simple_strtol(str+8, NULL, 0); |
||
212 | return NULL; |
||
213 | } |
||
214 | #endif |
||
215 | else if (!strcmp(str, "rom")) { |
||
216 | pci_probe |= PCI_ASSIGN_ROMS; |
||
217 | return NULL; |
||
218 | } else if (!strcmp(str, "assign-busses")) { |
||
219 | pci_probe |= PCI_ASSIGN_ALL_BUSSES; |
||
220 | return NULL; |
||
221 | } |
||
222 | return str; |
||
223 | } |
||
224 | |||
225 | unsigned int pcibios_assign_all_busses(void) |
||
226 | { |
||
227 | return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0; |
||
228 | } |
||
229 | |||
230 | int pcibios_enable_device(struct pci_dev *dev, int mask) |
||
231 | { |
||
232 | int err; |
||
233 | |||
234 | if ((err = pcibios_enable_resources(dev, mask)) < 0) |
||
235 | return err; |
||
236 | |||
237 | return pcibios_enable_irq(dev); |
||
238 | } |