1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88#include <linux/types.h>
89#include <linux/kernel.h>
90#include <linux/pci.h>
91#include <linux/init.h>
92#include <linux/ioport.h>
93#include <linux/errno.h>
94
95#include "pci-i386.h"
96
97void
98pcibios_update_resource(struct pci_dev *dev, struct resource *root,
99 struct resource *res, int resource)
100{
101 u32 new, check;
102 int reg;
103
104 new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
105 if (resource < 6) {
106 reg = PCI_BASE_ADDRESS_0 + 4*resource;
107 } else if (resource == PCI_ROM_RESOURCE) {
108 res->flags |= PCI_ROM_ADDRESS_ENABLE;
109 new |= PCI_ROM_ADDRESS_ENABLE;
110 reg = dev->rom_base_reg;
111 } else {
112
113 return;
114 }
115
116 pci_write_config_dword(dev, reg, new);
117 pci_read_config_dword(dev, reg, &check);
118 if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
119 printk(KERN_ERR "PCI: Error while updating region "
120 "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
121 new, check);
122 }
123}
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138void
139pcibios_align_resource(void *data, struct resource *res,
140 unsigned long size, unsigned long align)
141{
142 if (res->flags & IORESOURCE_IO) {
143 unsigned long start = res->start;
144
145 if (start & 0x300) {
146 start = (start + 0x3ff) & ~0x3ff;
147 res->start = start;
148 }
149 }
150}
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
187{
188 struct list_head *ln;
189 struct pci_bus *bus;
190 struct pci_dev *dev;
191 int idx;
192 struct resource *r, *pr;
193
194
195 for (ln=bus_list->next; ln != bus_list; ln=ln->next) {
196 bus = pci_bus_b(ln);
197 if ((dev = bus->self)) {
198 for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
199 r = &dev->resource[idx];
200 if (!r->start)
201 continue;
202 pr = pci_find_parent_resource(dev, r);
203 if (!pr || request_resource(pr, r) < 0)
204 printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, dev->slot_name);
205 }
206 }
207 pcibios_allocate_bus_resources(&bus->children);
208 }
209}
210
211static void __init pcibios_allocate_resources(int pass)
212{
213 struct pci_dev *dev;
214 int idx, disabled;
215 u16 command;
216 struct resource *r, *pr;
217
218 pci_for_each_dev(dev) {
219 pci_read_config_word(dev, PCI_COMMAND, &command);
220 for(idx = 0; idx < 6; idx++) {
221 r = &dev->resource[idx];
222 if (r->parent)
223 continue;
224 if (!r->start)
225 continue;
226 if (r->flags & IORESOURCE_IO)
227 disabled = !(command & PCI_COMMAND_IO);
228 else
229 disabled = !(command & PCI_COMMAND_MEMORY);
230 if (pass == disabled) {
231 DBG("PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n",
232 r->start, r->end, r->flags, disabled, pass);
233 pr = pci_find_parent_resource(dev, r);
234 if (!pr || request_resource(pr, r) < 0) {
235 printk(KERN_ERR "PCI: Cannot allocate resource region %d of device %s\n", idx, dev->slot_name);
236
237 r->end -= r->start;
238 r->start = 0;
239 }
240 }
241 }
242 if (!pass) {
243 r = &dev->resource[PCI_ROM_RESOURCE];
244 if (r->flags & PCI_ROM_ADDRESS_ENABLE) {
245
246 u32 reg;
247 DBG("PCI: Switching off ROM of %s\n", dev->slot_name);
248 r->flags &= ~PCI_ROM_ADDRESS_ENABLE;
249 pci_read_config_dword(dev, dev->rom_base_reg, ®);
250 pci_write_config_dword(dev, dev->rom_base_reg, reg & ~PCI_ROM_ADDRESS_ENABLE);
251 }
252 }
253 }
254}
255
256static void __init pcibios_assign_resources(void)
257{
258 struct pci_dev *dev;
259 int idx;
260 struct resource *r;
261
262 pci_for_each_dev(dev) {
263 int class = dev->class >> 8;
264
265
266 if (!class || class == PCI_CLASS_BRIDGE_HOST)
267 continue;
268
269 for(idx=0; idx<6; idx++) {
270 r = &dev->resource[idx];
271
272
273
274
275 if ((class == PCI_CLASS_STORAGE_IDE && idx < 4) ||
276 (class == PCI_CLASS_DISPLAY_VGA && (r->flags & IORESOURCE_IO)))
277 continue;
278
279
280
281
282
283
284 if (!r->start && r->end)
285 pci_assign_resource(dev, idx);
286 }
287
288 if (pci_probe & PCI_ASSIGN_ROMS) {
289 r = &dev->resource[PCI_ROM_RESOURCE];
290 r->end -= r->start;
291 r->start = 0;
292 if (r->end)
293 pci_assign_resource(dev, PCI_ROM_RESOURCE);
294 }
295 }
296}
297
298void __init pcibios_resource_survey(void)
299{
300 DBG("PCI: Allocating resources\n");
301 pcibios_allocate_bus_resources(&pci_root_buses);
302 pcibios_allocate_resources(0);
303 pcibios_allocate_resources(1);
304 pcibios_assign_resources();
305}
306
307int pcibios_enable_resources(struct pci_dev *dev, int mask)
308{
309 u16 cmd, old_cmd;
310 int idx;
311 struct resource *r;
312
313 pci_read_config_word(dev, PCI_COMMAND, &cmd);
314 old_cmd = cmd;
315 for(idx=0; idx<6; idx++) {
316
317 if (!(mask & (1<<idx)))
318 continue;
319
320 r = &dev->resource[idx];
321 if (!r->start && r->end) {
322 printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name);
323 return -EINVAL;
324 }
325 if (r->flags & IORESOURCE_IO)
326 cmd |= PCI_COMMAND_IO;
327 if (r->flags & IORESOURCE_MEM)
328 cmd |= PCI_COMMAND_MEMORY;
329 }
330 if (dev->resource[PCI_ROM_RESOURCE].start)
331 cmd |= PCI_COMMAND_MEMORY;
332 if (cmd != old_cmd) {
333 printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd);
334 pci_write_config_word(dev, PCI_COMMAND, cmd);
335 }
336 return 0;
337}
338
339
340
341
342
343unsigned int pcibios_max_latency = 255;
344
345void pcibios_set_master(struct pci_dev *dev)
346{
347 u8 lat;
348 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
349 if (lat < 16)
350 lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
351 else if (lat > pcibios_max_latency)
352 lat = pcibios_max_latency;
353 else
354 return;
355 printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat);
356 pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
357}
358
359int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
360 enum pci_mmap_state mmap_state, int write_combine)
361{
362 unsigned long prot;
363
364
365
366
367 if (mmap_state == pci_mmap_io)
368 return -EINVAL;
369
370
371
372
373 vma->vm_flags |= (VM_SHM | VM_LOCKED | VM_IO);
374
375 prot = pgprot_val(vma->vm_page_prot);
376 if (boot_cpu_data.x86 > 3)
377 prot |= _PAGE_PCD | _PAGE_PWT;
378 vma->vm_page_prot = __pgprot(prot);
379
380
381
382
383 if (remap_page_range(vma->vm_start, vma->vm_pgoff << PAGE_SHIFT,
384 vma->vm_end - vma->vm_start,
385 vma->vm_page_prot))
386 return -EAGAIN;
387
388 return 0;
389}
390