]>
Commit | Line | Data |
---|---|---|
2874c5fd | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
d3afa58c MS |
2 | /* |
3 | * Contains common pci routines for ALL ppc platform | |
4 | * (based on pci_32.c and pci_64.c) | |
5 | * | |
6 | * Port for PPC64 David Engebretsen, IBM Corp. | |
7 | * Contains common pci routines for ppc64 platform, pSeries and iSeries brands. | |
8 | * | |
9 | * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM | |
10 | * Rework, based on alpha PCI code. | |
11 | * | |
12 | * Common pmac/prep/chrp pci routines. -- Cort | |
d3afa58c MS |
13 | */ |
14 | ||
15 | #include <linux/kernel.h> | |
16 | #include <linux/pci.h> | |
17 | #include <linux/string.h> | |
18 | #include <linux/init.h> | |
57c8a661 | 19 | #include <linux/memblock.h> |
d3afa58c | 20 | #include <linux/mm.h> |
3a4f8a0b | 21 | #include <linux/shmem_fs.h> |
d3afa58c MS |
22 | #include <linux/list.h> |
23 | #include <linux/syscalls.h> | |
24 | #include <linux/irq.h> | |
25 | #include <linux/vmalloc.h> | |
5a0e3ad6 | 26 | #include <linux/slab.h> |
f1ca09b2 GL |
27 | #include <linux/of.h> |
28 | #include <linux/of_address.h> | |
5c9f303e | 29 | #include <linux/of_irq.h> |
04bea68b | 30 | #include <linux/of_pci.h> |
66421a64 | 31 | #include <linux/export.h> |
d3afa58c MS |
32 | |
33 | #include <asm/processor.h> | |
6bd55f0b | 34 | #include <linux/io.h> |
d3afa58c MS |
35 | #include <asm/pci-bridge.h> |
36 | #include <asm/byteorder.h> | |
37 | ||
38 | static DEFINE_SPINLOCK(hose_spinlock); | |
39 | LIST_HEAD(hose_list); | |
40 | ||
41 | /* XXX kill that some day ... */ | |
42 | static int global_phb_number; /* Global phb counter */ | |
43 | ||
44 | /* ISA Memory physical address */ | |
45 | resource_size_t isa_mem_base; | |
46 | ||
bf13a6fa | 47 | unsigned long isa_io_base; |
52e9e6e0 FW |
48 | EXPORT_SYMBOL(isa_io_base); |
49 | ||
bf13a6fa BH |
50 | static int pci_bus_count; |
51 | ||
d3afa58c MS |
52 | struct pci_controller *pcibios_alloc_controller(struct device_node *dev) |
53 | { | |
54 | struct pci_controller *phb; | |
55 | ||
56 | phb = zalloc_maybe_bootmem(sizeof(struct pci_controller), GFP_KERNEL); | |
57 | if (!phb) | |
58 | return NULL; | |
59 | spin_lock(&hose_spinlock); | |
60 | phb->global_number = global_phb_number++; | |
61 | list_add_tail(&phb->list_node, &hose_list); | |
62 | spin_unlock(&hose_spinlock); | |
63 | phb->dn = dev; | |
64 | phb->is_dynamic = mem_init_done; | |
65 | return phb; | |
66 | } | |
67 | ||
68 | void pcibios_free_controller(struct pci_controller *phb) | |
69 | { | |
70 | spin_lock(&hose_spinlock); | |
71 | list_del(&phb->list_node); | |
72 | spin_unlock(&hose_spinlock); | |
73 | ||
74 | if (phb->is_dynamic) | |
75 | kfree(phb); | |
76 | } | |
77 | ||
78 | static resource_size_t pcibios_io_size(const struct pci_controller *hose) | |
79 | { | |
28f65c11 | 80 | return resource_size(&hose->io_resource); |
d3afa58c MS |
81 | } |
82 | ||
83 | int pcibios_vaddr_is_ioport(void __iomem *address) | |
84 | { | |
85 | int ret = 0; | |
86 | struct pci_controller *hose; | |
87 | resource_size_t size; | |
88 | ||
89 | spin_lock(&hose_spinlock); | |
90 | list_for_each_entry(hose, &hose_list, list_node) { | |
91 | size = pcibios_io_size(hose); | |
92 | if (address >= hose->io_base_virt && | |
93 | address < (hose->io_base_virt + size)) { | |
94 | ret = 1; | |
95 | break; | |
96 | } | |
97 | } | |
98 | spin_unlock(&hose_spinlock); | |
99 | return ret; | |
100 | } | |
101 | ||
102 | unsigned long pci_address_to_pio(phys_addr_t address) | |
103 | { | |
104 | struct pci_controller *hose; | |
105 | resource_size_t size; | |
106 | unsigned long ret = ~0; | |
107 | ||
108 | spin_lock(&hose_spinlock); | |
109 | list_for_each_entry(hose, &hose_list, list_node) { | |
110 | size = pcibios_io_size(hose); | |
111 | if (address >= hose->io_base_phys && | |
112 | address < (hose->io_base_phys + size)) { | |
113 | unsigned long base = | |
114 | (unsigned long)hose->io_base_virt - _IO_BASE; | |
115 | ret = base + (address - hose->io_base_phys); | |
116 | break; | |
117 | } | |
118 | } | |
119 | spin_unlock(&hose_spinlock); | |
120 | ||
121 | return ret; | |
122 | } | |
123 | EXPORT_SYMBOL_GPL(pci_address_to_pio); | |
124 | ||
d3afa58c MS |
125 | /* This routine is meant to be used early during boot, when the |
126 | * PCI bus numbers have not yet been assigned, and you need to | |
127 | * issue PCI config cycles to an OF device. | |
128 | * It could also be used to "fix" RTAS config cycles if you want | |
129 | * to set pci_assign_all_buses to 1 and still use RTAS for PCI | |
130 | * config cycles. | |
131 | */ | |
132 | struct pci_controller *pci_find_hose_for_OF_device(struct device_node *node) | |
133 | { | |
134 | while (node) { | |
135 | struct pci_controller *hose, *tmp; | |
136 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) | |
137 | if (hose->dn == node) | |
138 | return hose; | |
139 | node = node->parent; | |
140 | } | |
141 | return NULL; | |
142 | } | |
143 | ||
b51d4a3e MS |
144 | void pcibios_set_master(struct pci_dev *dev) |
145 | { | |
146 | /* No special bus mastering setup handling */ | |
147 | } | |
148 | ||
d3afa58c | 149 | /* |
70f6283a | 150 | * Platform support for /proc/bus/pci/X/Y mmap()s. |
d3afa58c MS |
151 | */ |
152 | ||
70f6283a | 153 | int pci_iobar_pfn(struct pci_dev *pdev, int bar, struct vm_area_struct *vma) |
d3afa58c | 154 | { |
70f6283a DW |
155 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); |
156 | resource_size_t ioaddr = pci_resource_start(pdev, bar); | |
d3afa58c | 157 | |
f7eaacc1 | 158 | if (!hose) |
70f6283a | 159 | return -EINVAL; /* should never happen */ |
d3afa58c | 160 | |
70f6283a DW |
161 | /* Convert to an offset within this PCI controller */ |
162 | ioaddr -= (unsigned long)hose->io_base_virt - _IO_BASE; | |
d3afa58c | 163 | |
70f6283a DW |
164 | vma->vm_pgoff += (ioaddr + hose->io_base_phys) >> PAGE_SHIFT; |
165 | return 0; | |
d3afa58c MS |
166 | } |
167 | ||
d3afa58c MS |
168 | /* |
169 | * This one is used by /dev/mem and fbdev who have no clue about the | |
170 | * PCI device, it tries to find the PCI device first and calls the | |
171 | * above routine | |
172 | */ | |
173 | pgprot_t pci_phys_mem_access_prot(struct file *file, | |
174 | unsigned long pfn, | |
175 | unsigned long size, | |
176 | pgprot_t prot) | |
177 | { | |
178 | struct pci_dev *pdev = NULL; | |
179 | struct resource *found = NULL; | |
180 | resource_size_t offset = ((resource_size_t)pfn) << PAGE_SHIFT; | |
181 | int i; | |
182 | ||
183 | if (page_is_ram(pfn)) | |
184 | return prot; | |
185 | ||
186 | prot = pgprot_noncached(prot); | |
187 | for_each_pci_dev(pdev) { | |
188 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | |
189 | struct resource *rp = &pdev->resource[i]; | |
190 | int flags = rp->flags; | |
191 | ||
192 | /* Active and same type? */ | |
193 | if ((flags & IORESOURCE_MEM) == 0) | |
194 | continue; | |
195 | /* In the range of this resource? */ | |
196 | if (offset < (rp->start & PAGE_MASK) || | |
197 | offset > rp->end) | |
198 | continue; | |
199 | found = rp; | |
200 | break; | |
201 | } | |
202 | if (found) | |
203 | break; | |
204 | } | |
205 | if (found) { | |
206 | if (found->flags & IORESOURCE_PREFETCH) | |
207 | prot = pgprot_noncached_wc(prot); | |
208 | pci_dev_put(pdev); | |
209 | } | |
210 | ||
211 | pr_debug("PCI: Non-PCI map for %llx, prot: %lx\n", | |
212 | (unsigned long long)offset, pgprot_val(prot)); | |
213 | ||
214 | return prot; | |
215 | } | |
216 | ||
d3afa58c MS |
217 | /* This provides legacy IO read access on a bus */ |
218 | int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val, size_t size) | |
219 | { | |
220 | unsigned long offset; | |
221 | struct pci_controller *hose = pci_bus_to_host(bus); | |
222 | struct resource *rp = &hose->io_resource; | |
223 | void __iomem *addr; | |
224 | ||
225 | /* Check if port can be supported by that bus. We only check | |
226 | * the ranges of the PHB though, not the bus itself as the rules | |
227 | * for forwarding legacy cycles down bridges are not our problem | |
228 | * here. So if the host bridge supports it, we do it. | |
229 | */ | |
230 | offset = (unsigned long)hose->io_base_virt - _IO_BASE; | |
231 | offset += port; | |
232 | ||
233 | if (!(rp->flags & IORESOURCE_IO)) | |
234 | return -ENXIO; | |
235 | if (offset < rp->start || (offset + size) > rp->end) | |
236 | return -ENXIO; | |
237 | addr = hose->io_base_virt + port; | |
238 | ||
239 | switch (size) { | |
240 | case 1: | |
241 | *((u8 *)val) = in_8(addr); | |
242 | return 1; | |
243 | case 2: | |
244 | if (port & 1) | |
245 | return -EINVAL; | |
246 | *((u16 *)val) = in_le16(addr); | |
247 | return 2; | |
248 | case 4: | |
249 | if (port & 3) | |
250 | return -EINVAL; | |
251 | *((u32 *)val) = in_le32(addr); | |
252 | return 4; | |
253 | } | |
254 | return -EINVAL; | |
255 | } | |
256 | ||
257 | /* This provides legacy IO write access on a bus */ | |
258 | int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val, size_t size) | |
259 | { | |
260 | unsigned long offset; | |
261 | struct pci_controller *hose = pci_bus_to_host(bus); | |
262 | struct resource *rp = &hose->io_resource; | |
263 | void __iomem *addr; | |
264 | ||
265 | /* Check if port can be supported by that bus. We only check | |
266 | * the ranges of the PHB though, not the bus itself as the rules | |
267 | * for forwarding legacy cycles down bridges are not our problem | |
268 | * here. So if the host bridge supports it, we do it. | |
269 | */ | |
270 | offset = (unsigned long)hose->io_base_virt - _IO_BASE; | |
271 | offset += port; | |
272 | ||
273 | if (!(rp->flags & IORESOURCE_IO)) | |
274 | return -ENXIO; | |
275 | if (offset < rp->start || (offset + size) > rp->end) | |
276 | return -ENXIO; | |
277 | addr = hose->io_base_virt + port; | |
278 | ||
279 | /* WARNING: The generic code is idiotic. It gets passed a pointer | |
280 | * to what can be a 1, 2 or 4 byte quantity and always reads that | |
281 | * as a u32, which means that we have to correct the location of | |
282 | * the data read within those 32 bits for size 1 and 2 | |
283 | */ | |
284 | switch (size) { | |
285 | case 1: | |
286 | out_8(addr, val >> 24); | |
287 | return 1; | |
288 | case 2: | |
289 | if (port & 1) | |
290 | return -EINVAL; | |
291 | out_le16(addr, val >> 16); | |
292 | return 2; | |
293 | case 4: | |
294 | if (port & 3) | |
295 | return -EINVAL; | |
296 | out_le32(addr, val); | |
297 | return 4; | |
298 | } | |
299 | return -EINVAL; | |
300 | } | |
301 | ||
302 | /* This provides legacy IO or memory mmap access on a bus */ | |
303 | int pci_mmap_legacy_page_range(struct pci_bus *bus, | |
304 | struct vm_area_struct *vma, | |
305 | enum pci_mmap_state mmap_state) | |
306 | { | |
307 | struct pci_controller *hose = pci_bus_to_host(bus); | |
308 | resource_size_t offset = | |
309 | ((resource_size_t)vma->vm_pgoff) << PAGE_SHIFT; | |
310 | resource_size_t size = vma->vm_end - vma->vm_start; | |
311 | struct resource *rp; | |
312 | ||
313 | pr_debug("pci_mmap_legacy_page_range(%04x:%02x, %s @%llx..%llx)\n", | |
314 | pci_domain_nr(bus), bus->number, | |
315 | mmap_state == pci_mmap_mem ? "MEM" : "IO", | |
316 | (unsigned long long)offset, | |
317 | (unsigned long long)(offset + size - 1)); | |
318 | ||
319 | if (mmap_state == pci_mmap_mem) { | |
320 | /* Hack alert ! | |
321 | * | |
322 | * Because X is lame and can fail starting if it gets an error | |
323 | * trying to mmap legacy_mem (instead of just moving on without | |
324 | * legacy memory access) we fake it here by giving it anonymous | |
325 | * memory, effectively behaving just like /dev/zero | |
326 | */ | |
327 | if ((offset + size) > hose->isa_mem_size) { | |
6bd55f0b MS |
328 | pr_debug("Process %s (pid:%d) mapped non-existing PCI", |
329 | current->comm, current->pid); | |
330 | pr_debug("legacy memory for 0%04x:%02x\n", | |
331 | pci_domain_nr(bus), bus->number); | |
d3afa58c MS |
332 | if (vma->vm_flags & VM_SHARED) |
333 | return shmem_zero_setup(vma); | |
334 | return 0; | |
335 | } | |
336 | offset += hose->isa_mem_phys; | |
337 | } else { | |
6bd55f0b | 338 | unsigned long io_offset = (unsigned long)hose->io_base_virt - |
d3afa58c MS |
339 | _IO_BASE; |
340 | unsigned long roffset = offset + io_offset; | |
341 | rp = &hose->io_resource; | |
342 | if (!(rp->flags & IORESOURCE_IO)) | |
343 | return -ENXIO; | |
344 | if (roffset < rp->start || (roffset + size) > rp->end) | |
345 | return -ENXIO; | |
346 | offset += hose->io_base_phys; | |
347 | } | |
348 | pr_debug(" -> mapping phys %llx\n", (unsigned long long)offset); | |
349 | ||
350 | vma->vm_pgoff = offset >> PAGE_SHIFT; | |
351 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | |
352 | return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, | |
353 | vma->vm_end - vma->vm_start, | |
354 | vma->vm_page_prot); | |
355 | } | |
356 | ||
357 | void pci_resource_to_user(const struct pci_dev *dev, int bar, | |
358 | const struct resource *rsrc, | |
359 | resource_size_t *start, resource_size_t *end) | |
360 | { | |
0ad8f06d | 361 | struct pci_bus_region region; |
d3afa58c | 362 | |
0ad8f06d BH |
363 | if (rsrc->flags & IORESOURCE_IO) { |
364 | pcibios_resource_to_bus(dev->bus, ®ion, | |
365 | (struct resource *) rsrc); | |
366 | *start = region.start; | |
367 | *end = region.end; | |
d3afa58c | 368 | return; |
0ad8f06d | 369 | } |
d3afa58c | 370 | |
0ad8f06d BH |
371 | /* We pass a CPU physical address to userland for MMIO instead of a |
372 | * BAR value because X is lame and expects to be able to use that | |
373 | * to pass to /dev/mem! | |
d3afa58c | 374 | * |
0ad8f06d BH |
375 | * That means we may have 64-bit values where some apps only expect |
376 | * 32 (like X itself since it thinks only Sparc has 64-bit MMIO). | |
d3afa58c | 377 | */ |
0ad8f06d BH |
378 | *start = rsrc->start; |
379 | *end = rsrc->end; | |
d3afa58c MS |
380 | } |
381 | ||
382 | /** | |
383 | * pci_process_bridge_OF_ranges - Parse PCI bridge resources from device tree | |
384 | * @hose: newly allocated pci_controller to be setup | |
385 | * @dev: device node of the host bridge | |
386 | * @primary: set if primary bus (32 bits only, soon to be deprecated) | |
387 | * | |
388 | * This function will parse the "ranges" property of a PCI host bridge device | |
389 | * node and setup the resource mapping of a pci controller based on its | |
390 | * content. | |
391 | * | |
392 | * Life would be boring if it wasn't for a few issues that we have to deal | |
393 | * with here: | |
394 | * | |
395 | * - We can only cope with one IO space range and up to 3 Memory space | |
396 | * ranges. However, some machines (thanks Apple !) tend to split their | |
397 | * space into lots of small contiguous ranges. So we have to coalesce. | |
398 | * | |
399 | * - We can only cope with all memory ranges having the same offset | |
400 | * between CPU addresses and PCI addresses. Unfortunately, some bridges | |
401 | * are setup for a large 1:1 mapping along with a small "window" which | |
402 | * maps PCI address 0 to some arbitrary high address of the CPU space in | |
403 | * order to give access to the ISA memory hole. | |
404 | * The way out of here that I've chosen for now is to always set the | |
405 | * offset based on the first resource found, then override it if we | |
406 | * have a different offset and the previous was set by an ISA hole. | |
407 | * | |
408 | * - Some busses have IO space not starting at 0, which causes trouble with | |
409 | * the way we do our IO resource renumbering. The code somewhat deals with | |
410 | * it for 64 bits but I would expect problems on 32 bits. | |
411 | * | |
412 | * - Some 32 bits platforms such as 4xx can have physical space larger than | |
413 | * 32 bits so we need to use 64 bits values for the parsing | |
414 | */ | |
b881bc46 GKH |
415 | void pci_process_bridge_OF_ranges(struct pci_controller *hose, |
416 | struct device_node *dev, int primary) | |
d3afa58c | 417 | { |
d3afa58c | 418 | int memno = 0, isa_hole = -1; |
d3afa58c MS |
419 | unsigned long long isa_mb = 0; |
420 | struct resource *res; | |
4f7b6de4 AM |
421 | struct of_pci_range range; |
422 | struct of_pci_range_parser parser; | |
d3afa58c | 423 | |
f2b8ae0e RH |
424 | pr_info("PCI host bridge %pOF %s ranges:\n", |
425 | dev, primary ? "(primary)" : ""); | |
d3afa58c | 426 | |
4f7b6de4 AM |
427 | /* Check for ranges property */ |
428 | if (of_pci_range_parser_init(&parser, dev)) | |
d3afa58c MS |
429 | return; |
430 | ||
d3afa58c | 431 | pr_debug("Parsing ranges property...\n"); |
4f7b6de4 | 432 | for_each_of_pci_range(&parser, &range) { |
d3afa58c | 433 | /* Read next ranges element */ |
d3afa58c MS |
434 | |
435 | /* If we failed translation or got a zero-sized region | |
436 | * (some FW try to feed us with non sensical zero sized regions | |
437 | * such as power3 which look like some kind of attempt | |
438 | * at exposing the VGA memory hole) | |
439 | */ | |
4f7b6de4 | 440 | if (range.cpu_addr == OF_BAD_ADDR || range.size == 0) |
d3afa58c MS |
441 | continue; |
442 | ||
d3afa58c MS |
443 | /* Act based on address space type */ |
444 | res = NULL; | |
4f7b6de4 AM |
445 | switch (range.flags & IORESOURCE_TYPE_BITS) { |
446 | case IORESOURCE_IO: | |
6bd55f0b | 447 | pr_info(" IO 0x%016llx..0x%016llx -> 0x%016llx\n", |
4f7b6de4 AM |
448 | range.cpu_addr, range.cpu_addr + range.size - 1, |
449 | range.pci_addr); | |
d3afa58c MS |
450 | |
451 | /* We support only one IO range */ | |
452 | if (hose->pci_io_size) { | |
6bd55f0b | 453 | pr_info(" \\--> Skipped (too many) !\n"); |
d3afa58c MS |
454 | continue; |
455 | } | |
456 | /* On 32 bits, limit I/O space to 16MB */ | |
4f7b6de4 AM |
457 | if (range.size > 0x01000000) |
458 | range.size = 0x01000000; | |
d3afa58c MS |
459 | |
460 | /* 32 bits needs to map IOs here */ | |
4f7b6de4 AM |
461 | hose->io_base_virt = ioremap(range.cpu_addr, |
462 | range.size); | |
d3afa58c MS |
463 | |
464 | /* Expect trouble if pci_addr is not 0 */ | |
465 | if (primary) | |
466 | isa_io_base = | |
467 | (unsigned long)hose->io_base_virt; | |
468 | /* pci_io_size and io_base_phys always represent IO | |
469 | * space starting at 0 so we factor in pci_addr | |
470 | */ | |
4f7b6de4 AM |
471 | hose->pci_io_size = range.pci_addr + range.size; |
472 | hose->io_base_phys = range.cpu_addr - range.pci_addr; | |
d3afa58c MS |
473 | |
474 | /* Build resource */ | |
475 | res = &hose->io_resource; | |
4f7b6de4 AM |
476 | range.cpu_addr = range.pci_addr; |
477 | ||
d3afa58c | 478 | break; |
4f7b6de4 | 479 | case IORESOURCE_MEM: |
6bd55f0b | 480 | pr_info(" MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n", |
4f7b6de4 AM |
481 | range.cpu_addr, range.cpu_addr + range.size - 1, |
482 | range.pci_addr, | |
e252d293 | 483 | (range.flags & IORESOURCE_PREFETCH) ? |
4f7b6de4 | 484 | "Prefetch" : ""); |
d3afa58c MS |
485 | |
486 | /* We support only 3 memory ranges */ | |
487 | if (memno >= 3) { | |
6bd55f0b | 488 | pr_info(" \\--> Skipped (too many) !\n"); |
d3afa58c MS |
489 | continue; |
490 | } | |
491 | /* Handles ISA memory hole space here */ | |
4f7b6de4 AM |
492 | if (range.pci_addr == 0) { |
493 | isa_mb = range.cpu_addr; | |
d3afa58c MS |
494 | isa_hole = memno; |
495 | if (primary || isa_mem_base == 0) | |
4f7b6de4 AM |
496 | isa_mem_base = range.cpu_addr; |
497 | hose->isa_mem_phys = range.cpu_addr; | |
498 | hose->isa_mem_size = range.size; | |
d3afa58c MS |
499 | } |
500 | ||
501 | /* We get the PCI/Mem offset from the first range or | |
502 | * the, current one if the offset came from an ISA | |
503 | * hole. If they don't match, bugger. | |
504 | */ | |
505 | if (memno == 0 || | |
4f7b6de4 | 506 | (isa_hole >= 0 && range.pci_addr != 0 && |
d3afa58c | 507 | hose->pci_mem_offset == isa_mb)) |
4f7b6de4 AM |
508 | hose->pci_mem_offset = range.cpu_addr - |
509 | range.pci_addr; | |
510 | else if (range.pci_addr != 0 && | |
511 | hose->pci_mem_offset != range.cpu_addr - | |
512 | range.pci_addr) { | |
6bd55f0b | 513 | pr_info(" \\--> Skipped (offset mismatch) !\n"); |
d3afa58c MS |
514 | continue; |
515 | } | |
516 | ||
517 | /* Build resource */ | |
518 | res = &hose->mem_resources[memno++]; | |
d3afa58c MS |
519 | break; |
520 | } | |
70dcd942 MS |
521 | if (res != NULL) { |
522 | res->name = dev->full_name; | |
523 | res->flags = range.flags; | |
524 | res->start = range.cpu_addr; | |
525 | res->end = range.cpu_addr + range.size - 1; | |
526 | res->parent = res->child = res->sibling = NULL; | |
527 | } | |
d3afa58c MS |
528 | } |
529 | ||
530 | /* If there's an ISA hole and the pci_mem_offset is -not- matching | |
531 | * the ISA hole offset, then we need to remove the ISA hole from | |
532 | * the resource list for that brige | |
533 | */ | |
534 | if (isa_hole >= 0 && hose->pci_mem_offset != isa_mb) { | |
535 | unsigned int next = isa_hole + 1; | |
6bd55f0b | 536 | pr_info(" Removing ISA hole at 0x%016llx\n", isa_mb); |
d3afa58c MS |
537 | if (next < memno) |
538 | memmove(&hose->mem_resources[isa_hole], | |
539 | &hose->mem_resources[next], | |
540 | sizeof(struct resource) * (memno - next)); | |
541 | hose->mem_resources[--memno].flags = 0; | |
542 | } | |
543 | } | |
544 | ||
9413d968 | 545 | /* Display the domain number in /proc */ |
d3afa58c MS |
546 | int pci_proc_domain(struct pci_bus *bus) |
547 | { | |
9413d968 | 548 | return pci_domain_nr(bus); |
d3afa58c MS |
549 | } |
550 | ||
d3afa58c MS |
551 | /* This header fixup will do the resource fixup for all devices as they are |
552 | * probed, but not for bridge ranges | |
553 | */ | |
b881bc46 | 554 | static void pcibios_fixup_resources(struct pci_dev *dev) |
d3afa58c MS |
555 | { |
556 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | |
557 | int i; | |
558 | ||
559 | if (!hose) { | |
6bd55f0b | 560 | pr_err("No host bridge for PCI dev %s !\n", |
d3afa58c MS |
561 | pci_name(dev)); |
562 | return; | |
563 | } | |
564 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | |
565 | struct resource *res = dev->resource + i; | |
566 | if (!res->flags) | |
567 | continue; | |
e5b36841 | 568 | if (res->start == 0) { |
6bd55f0b | 569 | pr_debug("PCI:%s Resource %d %016llx-%016llx [%x]", |
d3afa58c MS |
570 | pci_name(dev), i, |
571 | (unsigned long long)res->start, | |
572 | (unsigned long long)res->end, | |
573 | (unsigned int)res->flags); | |
6bd55f0b | 574 | pr_debug("is unassigned\n"); |
d3afa58c MS |
575 | res->end -= res->start; |
576 | res->start = 0; | |
577 | res->flags |= IORESOURCE_UNSET; | |
578 | continue; | |
579 | } | |
580 | ||
aa23bdc0 | 581 | pr_debug("PCI:%s Resource %d %016llx-%016llx [%x]\n", |
d3afa58c | 582 | pci_name(dev), i, |
6bd55f0b | 583 | (unsigned long long)res->start, |
d3afa58c MS |
584 | (unsigned long long)res->end, |
585 | (unsigned int)res->flags); | |
d3afa58c MS |
586 | } |
587 | } | |
588 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources); | |
589 | ||
01cf9d52 BKG |
590 | int pcibios_add_device(struct pci_dev *dev) |
591 | { | |
592 | dev->irq = of_irq_parse_and_map_pci(dev, 0, 0); | |
593 | ||
594 | return 0; | |
595 | } | |
596 | EXPORT_SYMBOL(pcibios_add_device); | |
597 | ||
d3afa58c MS |
598 | /* |
599 | * Reparent resource children of pr that conflict with res | |
600 | * under res, and make res replace those children. | |
601 | */ | |
602 | static int __init reparent_resources(struct resource *parent, | |
603 | struct resource *res) | |
604 | { | |
605 | struct resource *p, **pp; | |
606 | struct resource **firstpp = NULL; | |
607 | ||
608 | for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) { | |
609 | if (p->end < res->start) | |
610 | continue; | |
611 | if (res->end < p->start) | |
612 | break; | |
613 | if (p->start < res->start || p->end > res->end) | |
614 | return -1; /* not completely contained */ | |
615 | if (firstpp == NULL) | |
616 | firstpp = pp; | |
617 | } | |
618 | if (firstpp == NULL) | |
619 | return -1; /* didn't find any conflicting entries? */ | |
620 | res->parent = parent; | |
621 | res->child = *firstpp; | |
622 | res->sibling = *pp; | |
623 | *firstpp = res; | |
624 | *pp = NULL; | |
625 | for (p = res->child; p != NULL; p = p->sibling) { | |
626 | p->parent = res; | |
627 | pr_debug("PCI: Reparented %s [%llx..%llx] under %s\n", | |
628 | p->name, | |
629 | (unsigned long long)p->start, | |
630 | (unsigned long long)p->end, res->name); | |
631 | } | |
632 | return 0; | |
633 | } | |
634 | ||
635 | /* | |
636 | * Handle resources of PCI devices. If the world were perfect, we could | |
637 | * just allocate all the resource regions and do nothing more. It isn't. | |
638 | * On the other hand, we cannot just re-allocate all devices, as it would | |
639 | * require us to know lots of host bridge internals. So we attempt to | |
640 | * keep as much of the original configuration as possible, but tweak it | |
641 | * when it's found to be wrong. | |
642 | * | |
643 | * Known BIOS problems we have to work around: | |
644 | * - I/O or memory regions not configured | |
645 | * - regions configured, but not enabled in the command register | |
646 | * - bogus I/O addresses above 64K used | |
647 | * - expansion ROMs left enabled (this may sound harmless, but given | |
648 | * the fact the PCI specs explicitly allow address decoders to be | |
649 | * shared between expansion ROMs and other resource regions, it's | |
650 | * at least dangerous) | |
651 | * | |
652 | * Our solution: | |
653 | * (1) Allocate resources for all buses behind PCI-to-PCI bridges. | |
654 | * This gives us fixed barriers on where we can allocate. | |
655 | * (2) Allocate resources for all enabled devices. If there is | |
656 | * a collision, just mark the resource as unallocated. Also | |
657 | * disable expansion ROMs during this step. | |
658 | * (3) Try to allocate resources for disabled devices. If the | |
659 | * resources were assigned correctly, everything goes well, | |
660 | * if they weren't, they won't disturb allocation of other | |
661 | * resources. | |
662 | * (4) Assign new addresses to resources which were either | |
663 | * not configured at all or misconfigured. If explicitly | |
664 | * requested by the user, configure expansion ROM address | |
665 | * as well. | |
666 | */ | |
667 | ||
f7eaacc1 | 668 | static void pcibios_allocate_bus_resources(struct pci_bus *bus) |
d3afa58c MS |
669 | { |
670 | struct pci_bus *b; | |
671 | int i; | |
672 | struct resource *res, *pr; | |
673 | ||
674 | pr_debug("PCI: Allocating bus resources for %04x:%02x...\n", | |
675 | pci_domain_nr(bus), bus->number); | |
676 | ||
8a66da71 | 677 | pci_bus_for_each_resource(bus, res, i) { |
d3afa58c MS |
678 | if (!res || !res->flags |
679 | || res->start > res->end || res->parent) | |
680 | continue; | |
681 | if (bus->parent == NULL) | |
682 | pr = (res->flags & IORESOURCE_IO) ? | |
683 | &ioport_resource : &iomem_resource; | |
684 | else { | |
685 | /* Don't bother with non-root busses when | |
686 | * re-assigning all resources. We clear the | |
687 | * resource flags as if they were colliding | |
688 | * and as such ensure proper re-allocation | |
689 | * later. | |
690 | */ | |
d3afa58c MS |
691 | pr = pci_find_parent_resource(bus->self, res); |
692 | if (pr == res) { | |
693 | /* this happens when the generic PCI | |
694 | * code (wrongly) decides that this | |
695 | * bridge is transparent -- paulus | |
696 | */ | |
697 | continue; | |
698 | } | |
699 | } | |
700 | ||
6bd55f0b | 701 | pr_debug("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx ", |
d3afa58c MS |
702 | bus->self ? pci_name(bus->self) : "PHB", |
703 | bus->number, i, | |
704 | (unsigned long long)res->start, | |
6bd55f0b MS |
705 | (unsigned long long)res->end); |
706 | pr_debug("[0x%x], parent %p (%s)\n", | |
d3afa58c MS |
707 | (unsigned int)res->flags, |
708 | pr, (pr && pr->name) ? pr->name : "nil"); | |
709 | ||
710 | if (pr && !(pr->flags & IORESOURCE_UNSET)) { | |
576e4385 YL |
711 | struct pci_dev *dev = bus->self; |
712 | ||
d3afa58c MS |
713 | if (request_resource(pr, res) == 0) |
714 | continue; | |
715 | /* | |
716 | * Must be a conflict with an existing entry. | |
717 | * Move that entry (or entries) under the | |
718 | * bridge resource and try again. | |
719 | */ | |
720 | if (reparent_resources(pr, res) == 0) | |
721 | continue; | |
576e4385 YL |
722 | |
723 | if (dev && i < PCI_BRIDGE_RESOURCE_NUM && | |
724 | pci_claim_bridge_resource(dev, | |
725 | i + PCI_BRIDGE_RESOURCES) == 0) | |
726 | continue; | |
727 | ||
d3afa58c | 728 | } |
6bd55f0b MS |
729 | pr_warn("PCI: Cannot allocate resource region "); |
730 | pr_cont("%d of PCI bridge %d, will remap\n", i, bus->number); | |
837c4ef1 | 731 | res->start = res->end = 0; |
d3afa58c MS |
732 | res->flags = 0; |
733 | } | |
734 | ||
735 | list_for_each_entry(b, &bus->children, node) | |
736 | pcibios_allocate_bus_resources(b); | |
737 | } | |
738 | ||
b881bc46 | 739 | static inline void alloc_resource(struct pci_dev *dev, int idx) |
d3afa58c MS |
740 | { |
741 | struct resource *pr, *r = &dev->resource[idx]; | |
742 | ||
743 | pr_debug("PCI: Allocating %s: Resource %d: %016llx..%016llx [%x]\n", | |
744 | pci_name(dev), idx, | |
745 | (unsigned long long)r->start, | |
746 | (unsigned long long)r->end, | |
747 | (unsigned int)r->flags); | |
748 | ||
749 | pr = pci_find_parent_resource(dev, r); | |
750 | if (!pr || (pr->flags & IORESOURCE_UNSET) || | |
751 | request_resource(pr, r) < 0) { | |
6bd55f0b MS |
752 | pr_warn("PCI: Cannot allocate resource region %d ", idx); |
753 | pr_cont("of device %s, will remap\n", pci_name(dev)); | |
d3afa58c MS |
754 | if (pr) |
755 | pr_debug("PCI: parent is %p: %016llx-%016llx [%x]\n", | |
756 | pr, | |
757 | (unsigned long long)pr->start, | |
758 | (unsigned long long)pr->end, | |
759 | (unsigned int)pr->flags); | |
760 | /* We'll assign a new address later */ | |
761 | r->flags |= IORESOURCE_UNSET; | |
762 | r->end -= r->start; | |
763 | r->start = 0; | |
764 | } | |
765 | } | |
766 | ||
767 | static void __init pcibios_allocate_resources(int pass) | |
768 | { | |
769 | struct pci_dev *dev = NULL; | |
770 | int idx, disabled; | |
771 | u16 command; | |
772 | struct resource *r; | |
773 | ||
774 | for_each_pci_dev(dev) { | |
775 | pci_read_config_word(dev, PCI_COMMAND, &command); | |
776 | for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) { | |
777 | r = &dev->resource[idx]; | |
778 | if (r->parent) /* Already allocated */ | |
779 | continue; | |
780 | if (!r->flags || (r->flags & IORESOURCE_UNSET)) | |
781 | continue; /* Not assigned at all */ | |
782 | /* We only allocate ROMs on pass 1 just in case they | |
783 | * have been screwed up by firmware | |
784 | */ | |
785 | if (idx == PCI_ROM_RESOURCE) | |
786 | disabled = 1; | |
787 | if (r->flags & IORESOURCE_IO) | |
788 | disabled = !(command & PCI_COMMAND_IO); | |
789 | else | |
790 | disabled = !(command & PCI_COMMAND_MEMORY); | |
791 | if (pass == disabled) | |
792 | alloc_resource(dev, idx); | |
793 | } | |
794 | if (pass) | |
795 | continue; | |
796 | r = &dev->resource[PCI_ROM_RESOURCE]; | |
797 | if (r->flags) { | |
798 | /* Turn the ROM off, leave the resource region, | |
799 | * but keep it unregistered. | |
800 | */ | |
801 | u32 reg; | |
802 | pci_read_config_dword(dev, dev->rom_base_reg, ®); | |
803 | if (reg & PCI_ROM_ADDRESS_ENABLE) { | |
804 | pr_debug("PCI: Switching off ROM of %s\n", | |
805 | pci_name(dev)); | |
806 | r->flags &= ~IORESOURCE_ROM_ENABLE; | |
807 | pci_write_config_dword(dev, dev->rom_base_reg, | |
808 | reg & ~PCI_ROM_ADDRESS_ENABLE); | |
809 | } | |
810 | } | |
811 | } | |
812 | } | |
813 | ||
814 | static void __init pcibios_reserve_legacy_regions(struct pci_bus *bus) | |
815 | { | |
816 | struct pci_controller *hose = pci_bus_to_host(bus); | |
817 | resource_size_t offset; | |
818 | struct resource *res, *pres; | |
819 | int i; | |
820 | ||
821 | pr_debug("Reserving legacy ranges for domain %04x\n", | |
822 | pci_domain_nr(bus)); | |
823 | ||
824 | /* Check for IO */ | |
825 | if (!(hose->io_resource.flags & IORESOURCE_IO)) | |
826 | goto no_io; | |
827 | offset = (unsigned long)hose->io_base_virt - _IO_BASE; | |
828 | res = kzalloc(sizeof(struct resource), GFP_KERNEL); | |
829 | BUG_ON(res == NULL); | |
830 | res->name = "Legacy IO"; | |
831 | res->flags = IORESOURCE_IO; | |
832 | res->start = offset; | |
833 | res->end = (offset + 0xfff) & 0xfffffffful; | |
834 | pr_debug("Candidate legacy IO: %pR\n", res); | |
835 | if (request_resource(&hose->io_resource, res)) { | |
6bd55f0b | 836 | pr_debug("PCI %04x:%02x Cannot reserve Legacy IO %pR\n", |
d3afa58c MS |
837 | pci_domain_nr(bus), bus->number, res); |
838 | kfree(res); | |
839 | } | |
840 | ||
841 | no_io: | |
842 | /* Check for memory */ | |
843 | offset = hose->pci_mem_offset; | |
844 | pr_debug("hose mem offset: %016llx\n", (unsigned long long)offset); | |
845 | for (i = 0; i < 3; i++) { | |
846 | pres = &hose->mem_resources[i]; | |
847 | if (!(pres->flags & IORESOURCE_MEM)) | |
848 | continue; | |
849 | pr_debug("hose mem res: %pR\n", pres); | |
850 | if ((pres->start - offset) <= 0xa0000 && | |
851 | (pres->end - offset) >= 0xbffff) | |
852 | break; | |
853 | } | |
854 | if (i >= 3) | |
855 | return; | |
856 | res = kzalloc(sizeof(struct resource), GFP_KERNEL); | |
857 | BUG_ON(res == NULL); | |
858 | res->name = "Legacy VGA memory"; | |
859 | res->flags = IORESOURCE_MEM; | |
860 | res->start = 0xa0000 + offset; | |
861 | res->end = 0xbffff + offset; | |
862 | pr_debug("Candidate VGA memory: %pR\n", res); | |
863 | if (request_resource(pres, res)) { | |
6bd55f0b | 864 | pr_debug("PCI %04x:%02x Cannot reserve VGA memory %pR\n", |
d3afa58c MS |
865 | pci_domain_nr(bus), bus->number, res); |
866 | kfree(res); | |
867 | } | |
868 | } | |
869 | ||
870 | void __init pcibios_resource_survey(void) | |
871 | { | |
872 | struct pci_bus *b; | |
873 | ||
874 | /* Allocate and assign resources. If we re-assign everything, then | |
875 | * we skip the allocate phase | |
876 | */ | |
877 | list_for_each_entry(b, &pci_root_buses, node) | |
878 | pcibios_allocate_bus_resources(b); | |
879 | ||
e5b36841 BH |
880 | pcibios_allocate_resources(0); |
881 | pcibios_allocate_resources(1); | |
d3afa58c MS |
882 | |
883 | /* Before we start assigning unassigned resource, we try to reserve | |
884 | * the low IO area and the VGA memory area if they intersect the | |
885 | * bus available resources to avoid allocating things on top of them | |
886 | */ | |
e5b36841 BH |
887 | list_for_each_entry(b, &pci_root_buses, node) |
888 | pcibios_reserve_legacy_regions(b); | |
d3afa58c | 889 | |
e5b36841 BH |
890 | /* Now proceed to assigning things that were left unassigned */ |
891 | pr_debug("PCI: Assigning unassigned resources...\n"); | |
892 | pci_assign_unassigned_resources(); | |
d3afa58c MS |
893 | } |
894 | ||
b881bc46 GKH |
895 | static void pcibios_setup_phb_resources(struct pci_controller *hose, |
896 | struct list_head *resources) | |
d3afa58c | 897 | { |
5420e46d | 898 | unsigned long io_offset; |
d3afa58c MS |
899 | struct resource *res; |
900 | int i; | |
901 | ||
902 | /* Hookup PHB IO resource */ | |
58de74b8 BH |
903 | res = &hose->io_resource; |
904 | ||
905 | /* Fixup IO space offset */ | |
906 | io_offset = (unsigned long)hose->io_base_virt - isa_io_base; | |
907 | res->start = (res->start + io_offset) & 0xffffffffu; | |
908 | res->end = (res->end + io_offset) & 0xffffffffu; | |
d3afa58c MS |
909 | |
910 | if (!res->flags) { | |
6bd55f0b | 911 | pr_warn("PCI: I/O resource not set for host "); |
f2b8ae0e RH |
912 | pr_cont("bridge %pOF (domain %d)\n", |
913 | hose->dn, hose->global_number); | |
d3afa58c MS |
914 | /* Workaround for lack of IO resource only on 32-bit */ |
915 | res->start = (unsigned long)hose->io_base_virt - isa_io_base; | |
916 | res->end = res->start + IO_SPACE_LIMIT; | |
917 | res->flags = IORESOURCE_IO; | |
918 | } | |
f7eaacc1 MS |
919 | pci_add_resource_offset(resources, res, |
920 | (__force resource_size_t)(hose->io_base_virt - _IO_BASE)); | |
d3afa58c MS |
921 | |
922 | pr_debug("PCI: PHB IO resource = %016llx-%016llx [%lx]\n", | |
923 | (unsigned long long)res->start, | |
924 | (unsigned long long)res->end, | |
925 | (unsigned long)res->flags); | |
926 | ||
927 | /* Hookup PHB Memory resources */ | |
928 | for (i = 0; i < 3; ++i) { | |
929 | res = &hose->mem_resources[i]; | |
930 | if (!res->flags) { | |
931 | if (i > 0) | |
932 | continue; | |
6bd55f0b | 933 | pr_err("PCI: Memory resource 0 not set for "); |
f2b8ae0e RH |
934 | pr_cont("host bridge %pOF (domain %d)\n", |
935 | hose->dn, hose->global_number); | |
d3afa58c MS |
936 | |
937 | /* Workaround for lack of MEM resource only on 32-bit */ | |
938 | res->start = hose->pci_mem_offset; | |
939 | res->end = (resource_size_t)-1LL; | |
940 | res->flags = IORESOURCE_MEM; | |
941 | ||
942 | } | |
aa23bdc0 | 943 | pci_add_resource_offset(resources, res, hose->pci_mem_offset); |
d3afa58c MS |
944 | |
945 | pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n", | |
946 | i, (unsigned long long)res->start, | |
947 | (unsigned long long)res->end, | |
948 | (unsigned long)res->flags); | |
949 | } | |
950 | ||
951 | pr_debug("PCI: PHB MEM offset = %016llx\n", | |
952 | (unsigned long long)hose->pci_mem_offset); | |
953 | pr_debug("PCI: PHB IO offset = %08lx\n", | |
954 | (unsigned long)hose->io_base_virt - _IO_BASE); | |
955 | } | |
956 | ||
b881bc46 | 957 | static void pcibios_scan_phb(struct pci_controller *hose) |
bf13a6fa | 958 | { |
58de74b8 | 959 | LIST_HEAD(resources); |
bf13a6fa BH |
960 | struct pci_bus *bus; |
961 | struct device_node *node = hose->dn; | |
bf13a6fa | 962 | |
f2b8ae0e | 963 | pr_debug("PCI: Scanning PHB %pOF\n", node); |
bf13a6fa | 964 | |
58de74b8 BH |
965 | pcibios_setup_phb_resources(hose, &resources); |
966 | ||
4723b984 BH |
967 | bus = pci_scan_root_bus(hose->parent, hose->first_busno, |
968 | hose->ops, hose, &resources); | |
bf13a6fa | 969 | if (bus == NULL) { |
6bd55f0b | 970 | pr_err("Failed to create bus for PCI domain %04x\n", |
bf13a6fa | 971 | hose->global_number); |
58de74b8 | 972 | pci_free_resource_list(&resources); |
bf13a6fa BH |
973 | return; |
974 | } | |
b918c62e | 975 | bus->busn_res.start = hose->first_busno; |
bf13a6fa BH |
976 | hose->bus = bus; |
977 | ||
b918c62e | 978 | hose->last_busno = bus->busn_res.end; |
bf13a6fa BH |
979 | } |
980 | ||
981 | static int __init pcibios_init(void) | |
982 | { | |
983 | struct pci_controller *hose, *tmp; | |
984 | int next_busno = 0; | |
985 | ||
6bd55f0b | 986 | pr_info("PCI: Probing PCI hardware\n"); |
bf13a6fa BH |
987 | |
988 | /* Scan all of the recorded PCI controllers. */ | |
989 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { | |
990 | hose->last_busno = 0xff; | |
991 | pcibios_scan_phb(hose); | |
bf13a6fa BH |
992 | if (next_busno <= hose->last_busno) |
993 | next_busno = hose->last_busno + 1; | |
994 | } | |
995 | pci_bus_count = next_busno; | |
996 | ||
997 | /* Call common code to handle resource allocation */ | |
998 | pcibios_resource_survey(); | |
b97ea289 YW |
999 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { |
1000 | if (hose->bus) | |
1001 | pci_bus_add_devices(hose->bus); | |
1002 | } | |
bf13a6fa BH |
1003 | |
1004 | return 0; | |
1005 | } | |
1006 | ||
1007 | subsys_initcall(pcibios_init); | |
1008 | ||
1009 | static struct pci_controller *pci_bus_to_hose(int bus) | |
1010 | { | |
1011 | struct pci_controller *hose, *tmp; | |
1012 | ||
1013 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) | |
1014 | if (bus >= hose->first_busno && bus <= hose->last_busno) | |
1015 | return hose; | |
1016 | return NULL; | |
1017 | } | |
1018 | ||
1019 | /* Provide information on locations of various I/O regions in physical | |
1020 | * memory. Do this on a per-card basis so that we choose the right | |
1021 | * root bridge. | |
1022 | * Note that the returned IO or memory base is a physical address | |
1023 | */ | |
1024 | ||
1025 | long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) | |
1026 | { | |
1027 | struct pci_controller *hose; | |
1028 | long result = -EOPNOTSUPP; | |
1029 | ||
1030 | hose = pci_bus_to_hose(bus); | |
1031 | if (!hose) | |
1032 | return -ENODEV; | |
1033 | ||
1034 | switch (which) { | |
1035 | case IOBASE_BRIDGE_NUMBER: | |
1036 | return (long)hose->first_busno; | |
1037 | case IOBASE_MEMORY: | |
1038 | return (long)hose->pci_mem_offset; | |
1039 | case IOBASE_IO: | |
1040 | return (long)hose->io_base_phys; | |
1041 | case IOBASE_ISA_IO: | |
1042 | return (long)isa_io_base; | |
1043 | case IOBASE_ISA_MEM: | |
1044 | return (long)isa_mem_base; | |
1045 | } | |
1046 | ||
1047 | return result; | |
1048 | } | |
1049 | ||
d3afa58c MS |
1050 | /* |
1051 | * Null PCI config access functions, for the case when we can't | |
1052 | * find a hose. | |
1053 | */ | |
1054 | #define NULL_PCI_OP(rw, size, type) \ | |
1055 | static int \ | |
1056 | null_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \ | |
1057 | { \ | |
1058 | return PCIBIOS_DEVICE_NOT_FOUND; \ | |
1059 | } | |
1060 | ||
1061 | static int | |
1062 | null_read_config(struct pci_bus *bus, unsigned int devfn, int offset, | |
1063 | int len, u32 *val) | |
1064 | { | |
1065 | return PCIBIOS_DEVICE_NOT_FOUND; | |
1066 | } | |
1067 | ||
1068 | static int | |
1069 | null_write_config(struct pci_bus *bus, unsigned int devfn, int offset, | |
1070 | int len, u32 val) | |
1071 | { | |
1072 | return PCIBIOS_DEVICE_NOT_FOUND; | |
1073 | } | |
1074 | ||
1075 | static struct pci_ops null_pci_ops = { | |
1076 | .read = null_read_config, | |
1077 | .write = null_write_config, | |
1078 | }; | |
1079 | ||
1080 | /* | |
1081 | * These functions are used early on before PCI scanning is done | |
1082 | * and all of the pci_dev and pci_bus structures have been created. | |
1083 | */ | |
1084 | static struct pci_bus * | |
1085 | fake_pci_bus(struct pci_controller *hose, int busnr) | |
1086 | { | |
1087 | static struct pci_bus bus; | |
1088 | ||
1089 | if (!hose) | |
6bd55f0b | 1090 | pr_err("Can't find hose for PCI bus %d!\n", busnr); |
d3afa58c MS |
1091 | |
1092 | bus.number = busnr; | |
1093 | bus.sysdata = hose; | |
1094 | bus.ops = hose ? hose->ops : &null_pci_ops; | |
1095 | return &bus; | |
1096 | } | |
1097 | ||
1098 | #define EARLY_PCI_OP(rw, size, type) \ | |
1099 | int early_##rw##_config_##size(struct pci_controller *hose, int bus, \ | |
1100 | int devfn, int offset, type value) \ | |
1101 | { \ | |
1102 | return pci_bus_##rw##_config_##size(fake_pci_bus(hose, bus), \ | |
1103 | devfn, offset, value); \ | |
1104 | } | |
1105 | ||
1106 | EARLY_PCI_OP(read, byte, u8 *) | |
1107 | EARLY_PCI_OP(read, word, u16 *) | |
1108 | EARLY_PCI_OP(read, dword, u32 *) | |
1109 | EARLY_PCI_OP(write, byte, u8) | |
1110 | EARLY_PCI_OP(write, word, u16) | |
1111 | EARLY_PCI_OP(write, dword, u32) | |
1112 | ||
1113 | int early_find_capability(struct pci_controller *hose, int bus, int devfn, | |
1114 | int cap) | |
1115 | { | |
1116 | return pci_bus_find_capability(fake_pci_bus(hose, bus), devfn, cap); | |
1117 | } |