diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/sparc64/kernel/pci_common.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/sparc64/kernel/pci_common.c')
-rw-r--r-- | arch/sparc64/kernel/pci_common.c | 1040 |
1 files changed, 1040 insertions, 0 deletions
diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c new file mode 100644 index 000000000000..58310aacea28 --- /dev/null +++ b/arch/sparc64/kernel/pci_common.c | |||
@@ -0,0 +1,1040 @@ | |||
1 | /* $Id: pci_common.c,v 1.29 2002/02/01 00:56:03 davem Exp $ | ||
2 | * pci_common.c: PCI controller common support. | ||
3 | * | ||
4 | * Copyright (C) 1999 David S. Miller (davem@redhat.com) | ||
5 | */ | ||
6 | |||
7 | #include <linux/string.h> | ||
8 | #include <linux/slab.h> | ||
9 | #include <linux/init.h> | ||
10 | |||
11 | #include <asm/pbm.h> | ||
12 | |||
13 | /* Fix self device of BUS and hook it into BUS->self. | ||
14 | * The pci_scan_bus does not do this for the host bridge. | ||
15 | */ | ||
16 | void __init pci_fixup_host_bridge_self(struct pci_bus *pbus) | ||
17 | { | ||
18 | struct pci_dev *pdev; | ||
19 | |||
20 | list_for_each_entry(pdev, &pbus->devices, bus_list) { | ||
21 | if (pdev->class >> 8 == PCI_CLASS_BRIDGE_HOST) { | ||
22 | pbus->self = pdev; | ||
23 | return; | ||
24 | } | ||
25 | } | ||
26 | |||
27 | prom_printf("PCI: Critical error, cannot find host bridge PDEV.\n"); | ||
28 | prom_halt(); | ||
29 | } | ||
30 | |||
31 | /* Find the OBP PROM device tree node for a PCI device. | ||
32 | * Return zero if not found. | ||
33 | */ | ||
34 | static int __init find_device_prom_node(struct pci_pbm_info *pbm, | ||
35 | struct pci_dev *pdev, | ||
36 | int bus_prom_node, | ||
37 | struct linux_prom_pci_registers *pregs, | ||
38 | int *nregs) | ||
39 | { | ||
40 | int node; | ||
41 | |||
42 | /* | ||
43 | * Return the PBM's PROM node in case we are it's PCI device, | ||
44 | * as the PBM's reg property is different to standard PCI reg | ||
45 | * properties. We would delete this device entry otherwise, | ||
46 | * which confuses XFree86's device probing... | ||
47 | */ | ||
48 | if ((pdev->bus->number == pbm->pci_bus->number) && (pdev->devfn == 0) && | ||
49 | (pdev->vendor == PCI_VENDOR_ID_SUN) && | ||
50 | (pdev->device == PCI_DEVICE_ID_SUN_PBM || | ||
51 | pdev->device == PCI_DEVICE_ID_SUN_SCHIZO || | ||
52 | pdev->device == PCI_DEVICE_ID_SUN_TOMATILLO || | ||
53 | pdev->device == PCI_DEVICE_ID_SUN_SABRE || | ||
54 | pdev->device == PCI_DEVICE_ID_SUN_HUMMINGBIRD)) { | ||
55 | *nregs = 0; | ||
56 | return bus_prom_node; | ||
57 | } | ||
58 | |||
59 | node = prom_getchild(bus_prom_node); | ||
60 | while (node != 0) { | ||
61 | int err = prom_getproperty(node, "reg", | ||
62 | (char *)pregs, | ||
63 | sizeof(*pregs) * PROMREG_MAX); | ||
64 | if (err == 0 || err == -1) | ||
65 | goto do_next_sibling; | ||
66 | if (((pregs[0].phys_hi >> 8) & 0xff) == pdev->devfn) { | ||
67 | *nregs = err / sizeof(*pregs); | ||
68 | return node; | ||
69 | } | ||
70 | |||
71 | do_next_sibling: | ||
72 | node = prom_getsibling(node); | ||
73 | } | ||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | /* Older versions of OBP on PCI systems encode 64-bit MEM | ||
78 | * space assignments incorrectly, this fixes them up. We also | ||
79 | * take the opportunity here to hide other kinds of bogus | ||
80 | * assignments. | ||
81 | */ | ||
82 | static void __init fixup_obp_assignments(struct pci_dev *pdev, | ||
83 | struct pcidev_cookie *pcp) | ||
84 | { | ||
85 | int i; | ||
86 | |||
87 | if (pdev->vendor == PCI_VENDOR_ID_AL && | ||
88 | (pdev->device == PCI_DEVICE_ID_AL_M7101 || | ||
89 | pdev->device == PCI_DEVICE_ID_AL_M1533)) { | ||
90 | int i; | ||
91 | |||
92 | /* Zap all of the normal resources, they are | ||
93 | * meaningless and generate bogus resource collision | ||
94 | * messages. This is OpenBoot's ill-fated attempt to | ||
95 | * represent the implicit resources that these devices | ||
96 | * have. | ||
97 | */ | ||
98 | pcp->num_prom_assignments = 0; | ||
99 | for (i = 0; i < 6; i++) { | ||
100 | pdev->resource[i].start = | ||
101 | pdev->resource[i].end = | ||
102 | pdev->resource[i].flags = 0; | ||
103 | } | ||
104 | pdev->resource[PCI_ROM_RESOURCE].start = | ||
105 | pdev->resource[PCI_ROM_RESOURCE].end = | ||
106 | pdev->resource[PCI_ROM_RESOURCE].flags = 0; | ||
107 | return; | ||
108 | } | ||
109 | |||
110 | for (i = 0; i < pcp->num_prom_assignments; i++) { | ||
111 | struct linux_prom_pci_registers *ap; | ||
112 | int space; | ||
113 | |||
114 | ap = &pcp->prom_assignments[i]; | ||
115 | space = ap->phys_hi >> 24; | ||
116 | if ((space & 0x3) == 2 && | ||
117 | (space & 0x4) != 0) { | ||
118 | ap->phys_hi &= ~(0x7 << 24); | ||
119 | ap->phys_hi |= 0x3 << 24; | ||
120 | } | ||
121 | } | ||
122 | } | ||
123 | |||
124 | /* Fill in the PCI device cookie sysdata for the given | ||
125 | * PCI device. This cookie is the means by which one | ||
126 | * can get to OBP and PCI controller specific information | ||
127 | * for a PCI device. | ||
128 | */ | ||
129 | static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm, | ||
130 | struct pci_dev *pdev, | ||
131 | int bus_prom_node) | ||
132 | { | ||
133 | struct linux_prom_pci_registers pregs[PROMREG_MAX]; | ||
134 | struct pcidev_cookie *pcp; | ||
135 | int device_prom_node, nregs, err; | ||
136 | |||
137 | device_prom_node = find_device_prom_node(pbm, pdev, bus_prom_node, | ||
138 | pregs, &nregs); | ||
139 | if (device_prom_node == 0) { | ||
140 | /* If it is not in the OBP device tree then | ||
141 | * there must be a damn good reason for it. | ||
142 | * | ||
143 | * So what we do is delete the device from the | ||
144 | * PCI device tree completely. This scenario | ||
145 | * is seen, for example, on CP1500 for the | ||
146 | * second EBUS/HappyMeal pair if the external | ||
147 | * connector for it is not present. | ||
148 | */ | ||
149 | pci_remove_bus_device(pdev); | ||
150 | return; | ||
151 | } | ||
152 | |||
153 | pcp = kmalloc(sizeof(*pcp), GFP_ATOMIC); | ||
154 | if (pcp == NULL) { | ||
155 | prom_printf("PCI_COOKIE: Fatal malloc error, aborting...\n"); | ||
156 | prom_halt(); | ||
157 | } | ||
158 | pcp->pbm = pbm; | ||
159 | pcp->prom_node = device_prom_node; | ||
160 | memcpy(pcp->prom_regs, pregs, sizeof(pcp->prom_regs)); | ||
161 | pcp->num_prom_regs = nregs; | ||
162 | err = prom_getproperty(device_prom_node, "name", | ||
163 | pcp->prom_name, sizeof(pcp->prom_name)); | ||
164 | if (err > 0) | ||
165 | pcp->prom_name[err] = 0; | ||
166 | else | ||
167 | pcp->prom_name[0] = 0; | ||
168 | |||
169 | err = prom_getproperty(device_prom_node, | ||
170 | "assigned-addresses", | ||
171 | (char *)pcp->prom_assignments, | ||
172 | sizeof(pcp->prom_assignments)); | ||
173 | if (err == 0 || err == -1) | ||
174 | pcp->num_prom_assignments = 0; | ||
175 | else | ||
176 | pcp->num_prom_assignments = | ||
177 | (err / sizeof(pcp->prom_assignments[0])); | ||
178 | |||
179 | if (strcmp(pcp->prom_name, "ebus") == 0) { | ||
180 | struct linux_prom_ebus_ranges erng[PROM_PCIRNG_MAX]; | ||
181 | int iter; | ||
182 | |||
183 | /* EBUS is special... */ | ||
184 | err = prom_getproperty(device_prom_node, "ranges", | ||
185 | (char *)&erng[0], sizeof(erng)); | ||
186 | if (err == 0 || err == -1) { | ||
187 | prom_printf("EBUS: Fatal error, no range property\n"); | ||
188 | prom_halt(); | ||
189 | } | ||
190 | err = (err / sizeof(erng[0])); | ||
191 | for(iter = 0; iter < err; iter++) { | ||
192 | struct linux_prom_ebus_ranges *ep = &erng[iter]; | ||
193 | struct linux_prom_pci_registers *ap; | ||
194 | |||
195 | ap = &pcp->prom_assignments[iter]; | ||
196 | |||
197 | ap->phys_hi = ep->parent_phys_hi; | ||
198 | ap->phys_mid = ep->parent_phys_mid; | ||
199 | ap->phys_lo = ep->parent_phys_lo; | ||
200 | ap->size_hi = 0; | ||
201 | ap->size_lo = ep->size; | ||
202 | } | ||
203 | pcp->num_prom_assignments = err; | ||
204 | } | ||
205 | |||
206 | fixup_obp_assignments(pdev, pcp); | ||
207 | |||
208 | pdev->sysdata = pcp; | ||
209 | } | ||
210 | |||
211 | void __init pci_fill_in_pbm_cookies(struct pci_bus *pbus, | ||
212 | struct pci_pbm_info *pbm, | ||
213 | int prom_node) | ||
214 | { | ||
215 | struct pci_dev *pdev, *pdev_next; | ||
216 | struct pci_bus *this_pbus, *pbus_next; | ||
217 | |||
218 | /* This must be _safe because the cookie fillin | ||
219 | routine can delete devices from the tree. */ | ||
220 | list_for_each_entry_safe(pdev, pdev_next, &pbus->devices, bus_list) | ||
221 | pdev_cookie_fillin(pbm, pdev, prom_node); | ||
222 | |||
223 | list_for_each_entry_safe(this_pbus, pbus_next, &pbus->children, node) { | ||
224 | struct pcidev_cookie *pcp = this_pbus->self->sysdata; | ||
225 | |||
226 | pci_fill_in_pbm_cookies(this_pbus, pbm, pcp->prom_node); | ||
227 | } | ||
228 | } | ||
229 | |||
230 | static void __init bad_assignment(struct pci_dev *pdev, | ||
231 | struct linux_prom_pci_registers *ap, | ||
232 | struct resource *res, | ||
233 | int do_prom_halt) | ||
234 | { | ||
235 | prom_printf("PCI: Bogus PROM assignment. BUS[%02x] DEVFN[%x]\n", | ||
236 | pdev->bus->number, pdev->devfn); | ||
237 | if (ap) | ||
238 | prom_printf("PCI: phys[%08x:%08x:%08x] size[%08x:%08x]\n", | ||
239 | ap->phys_hi, ap->phys_mid, ap->phys_lo, | ||
240 | ap->size_hi, ap->size_lo); | ||
241 | if (res) | ||
242 | prom_printf("PCI: RES[%016lx-->%016lx:(%lx)]\n", | ||
243 | res->start, res->end, res->flags); | ||
244 | prom_printf("Please email this information to davem@redhat.com\n"); | ||
245 | if (do_prom_halt) | ||
246 | prom_halt(); | ||
247 | } | ||
248 | |||
249 | static struct resource * | ||
250 | __init get_root_resource(struct linux_prom_pci_registers *ap, | ||
251 | struct pci_pbm_info *pbm) | ||
252 | { | ||
253 | int space = (ap->phys_hi >> 24) & 3; | ||
254 | |||
255 | switch (space) { | ||
256 | case 0: | ||
257 | /* Configuration space, silently ignore it. */ | ||
258 | return NULL; | ||
259 | |||
260 | case 1: | ||
261 | /* 16-bit IO space */ | ||
262 | return &pbm->io_space; | ||
263 | |||
264 | case 2: | ||
265 | /* 32-bit MEM space */ | ||
266 | return &pbm->mem_space; | ||
267 | |||
268 | case 3: | ||
269 | /* 64-bit MEM space, these are allocated out of | ||
270 | * the 32-bit mem_space range for the PBM, ie. | ||
271 | * we just zero out the upper 32-bits. | ||
272 | */ | ||
273 | return &pbm->mem_space; | ||
274 | |||
275 | default: | ||
276 | printk("PCI: What is resource space %x? " | ||
277 | "Tell davem@redhat.com about it!\n", space); | ||
278 | return NULL; | ||
279 | }; | ||
280 | } | ||
281 | |||
282 | static struct resource * | ||
283 | __init get_device_resource(struct linux_prom_pci_registers *ap, | ||
284 | struct pci_dev *pdev) | ||
285 | { | ||
286 | struct resource *res; | ||
287 | int breg = (ap->phys_hi & 0xff); | ||
288 | |||
289 | switch (breg) { | ||
290 | case PCI_ROM_ADDRESS: | ||
291 | /* Unfortunately I have seen several cases where | ||
292 | * buggy FCODE uses a space value of '1' (I/O space) | ||
293 | * in the register property for the ROM address | ||
294 | * so disable this sanity check for now. | ||
295 | */ | ||
296 | #if 0 | ||
297 | { | ||
298 | int space = (ap->phys_hi >> 24) & 3; | ||
299 | |||
300 | /* It had better be MEM space. */ | ||
301 | if (space != 2) | ||
302 | bad_assignment(pdev, ap, NULL, 0); | ||
303 | } | ||
304 | #endif | ||
305 | res = &pdev->resource[PCI_ROM_RESOURCE]; | ||
306 | break; | ||
307 | |||
308 | case PCI_BASE_ADDRESS_0: | ||
309 | case PCI_BASE_ADDRESS_1: | ||
310 | case PCI_BASE_ADDRESS_2: | ||
311 | case PCI_BASE_ADDRESS_3: | ||
312 | case PCI_BASE_ADDRESS_4: | ||
313 | case PCI_BASE_ADDRESS_5: | ||
314 | res = &pdev->resource[(breg - PCI_BASE_ADDRESS_0) / 4]; | ||
315 | break; | ||
316 | |||
317 | default: | ||
318 | bad_assignment(pdev, ap, NULL, 0); | ||
319 | res = NULL; | ||
320 | break; | ||
321 | }; | ||
322 | |||
323 | return res; | ||
324 | } | ||
325 | |||
326 | static int __init pdev_resource_collisions_expected(struct pci_dev *pdev) | ||
327 | { | ||
328 | if (pdev->vendor != PCI_VENDOR_ID_SUN) | ||
329 | return 0; | ||
330 | |||
331 | if (pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS || | ||
332 | pdev->device == PCI_DEVICE_ID_SUN_RIO_1394 || | ||
333 | pdev->device == PCI_DEVICE_ID_SUN_RIO_USB) | ||
334 | return 1; | ||
335 | |||
336 | return 0; | ||
337 | } | ||
338 | |||
339 | static void __init pdev_record_assignments(struct pci_pbm_info *pbm, | ||
340 | struct pci_dev *pdev) | ||
341 | { | ||
342 | struct pcidev_cookie *pcp = pdev->sysdata; | ||
343 | int i; | ||
344 | |||
345 | for (i = 0; i < pcp->num_prom_assignments; i++) { | ||
346 | struct linux_prom_pci_registers *ap; | ||
347 | struct resource *root, *res; | ||
348 | |||
349 | /* The format of this property is specified in | ||
350 | * the PCI Bus Binding to IEEE1275-1994. | ||
351 | */ | ||
352 | ap = &pcp->prom_assignments[i]; | ||
353 | root = get_root_resource(ap, pbm); | ||
354 | res = get_device_resource(ap, pdev); | ||
355 | if (root == NULL || res == NULL || | ||
356 | res->flags == 0) | ||
357 | continue; | ||
358 | |||
359 | /* Ok we know which resource this PROM assignment is | ||
360 | * for, sanity check it. | ||
361 | */ | ||
362 | if ((res->start & 0xffffffffUL) != ap->phys_lo) | ||
363 | bad_assignment(pdev, ap, res, 1); | ||
364 | |||
365 | /* If it is a 64-bit MEM space assignment, verify that | ||
366 | * the resource is too and that the upper 32-bits match. | ||
367 | */ | ||
368 | if (((ap->phys_hi >> 24) & 3) == 3) { | ||
369 | if (((res->flags & IORESOURCE_MEM) == 0) || | ||
370 | ((res->flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK) | ||
371 | != PCI_BASE_ADDRESS_MEM_TYPE_64)) | ||
372 | bad_assignment(pdev, ap, res, 1); | ||
373 | if ((res->start >> 32) != ap->phys_mid) | ||
374 | bad_assignment(pdev, ap, res, 1); | ||
375 | |||
376 | /* PBM cannot generate cpu initiated PIOs | ||
377 | * to the full 64-bit space. Therefore the | ||
378 | * upper 32-bits better be zero. If it is | ||
379 | * not, just skip it and we will assign it | ||
380 | * properly ourselves. | ||
381 | */ | ||
382 | if ((res->start >> 32) != 0UL) { | ||
383 | printk(KERN_ERR "PCI: OBP assigns out of range MEM address " | ||
384 | "%016lx for region %ld on device %s\n", | ||
385 | res->start, (res - &pdev->resource[0]), pci_name(pdev)); | ||
386 | continue; | ||
387 | } | ||
388 | } | ||
389 | |||
390 | /* Adjust the resource into the physical address space | ||
391 | * of this PBM. | ||
392 | */ | ||
393 | pbm->parent->resource_adjust(pdev, res, root); | ||
394 | |||
395 | if (request_resource(root, res) < 0) { | ||
396 | /* OK, there is some conflict. But this is fine | ||
397 | * since we'll reassign it in the fixup pass. | ||
398 | * | ||
399 | * We notify the user that OBP made an error if it | ||
400 | * is a case we don't expect. | ||
401 | */ | ||
402 | if (!pdev_resource_collisions_expected(pdev)) { | ||
403 | printk(KERN_ERR "PCI: Address space collision on region %ld " | ||
404 | "[%016lx:%016lx] of device %s\n", | ||
405 | (res - &pdev->resource[0]), | ||
406 | res->start, res->end, | ||
407 | pci_name(pdev)); | ||
408 | } | ||
409 | } | ||
410 | } | ||
411 | } | ||
412 | |||
413 | void __init pci_record_assignments(struct pci_pbm_info *pbm, | ||
414 | struct pci_bus *pbus) | ||
415 | { | ||
416 | struct pci_dev *dev; | ||
417 | struct pci_bus *bus; | ||
418 | |||
419 | list_for_each_entry(dev, &pbus->devices, bus_list) | ||
420 | pdev_record_assignments(pbm, dev); | ||
421 | |||
422 | list_for_each_entry(bus, &pbus->children, node) | ||
423 | pci_record_assignments(pbm, bus); | ||
424 | } | ||
425 | |||
426 | /* Return non-zero if PDEV has implicit I/O resources even | ||
427 | * though it may not have an I/O base address register | ||
428 | * active. | ||
429 | */ | ||
430 | static int __init has_implicit_io(struct pci_dev *pdev) | ||
431 | { | ||
432 | int class = pdev->class >> 8; | ||
433 | |||
434 | if (class == PCI_CLASS_NOT_DEFINED || | ||
435 | class == PCI_CLASS_NOT_DEFINED_VGA || | ||
436 | class == PCI_CLASS_STORAGE_IDE || | ||
437 | (pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) | ||
438 | return 1; | ||
439 | |||
440 | return 0; | ||
441 | } | ||
442 | |||
443 | static void __init pdev_assign_unassigned(struct pci_pbm_info *pbm, | ||
444 | struct pci_dev *pdev) | ||
445 | { | ||
446 | u32 reg; | ||
447 | u16 cmd; | ||
448 | int i, io_seen, mem_seen; | ||
449 | |||
450 | io_seen = mem_seen = 0; | ||
451 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | ||
452 | struct resource *root, *res; | ||
453 | unsigned long size, min, max, align; | ||
454 | |||
455 | res = &pdev->resource[i]; | ||
456 | |||
457 | if (res->flags & IORESOURCE_IO) | ||
458 | io_seen++; | ||
459 | else if (res->flags & IORESOURCE_MEM) | ||
460 | mem_seen++; | ||
461 | |||
462 | /* If it is already assigned or the resource does | ||
463 | * not exist, there is nothing to do. | ||
464 | */ | ||
465 | if (res->parent != NULL || res->flags == 0UL) | ||
466 | continue; | ||
467 | |||
468 | /* Determine the root we allocate from. */ | ||
469 | if (res->flags & IORESOURCE_IO) { | ||
470 | root = &pbm->io_space; | ||
471 | min = root->start + 0x400UL; | ||
472 | max = root->end; | ||
473 | } else { | ||
474 | root = &pbm->mem_space; | ||
475 | min = root->start; | ||
476 | max = min + 0x80000000UL; | ||
477 | } | ||
478 | |||
479 | size = res->end - res->start; | ||
480 | align = size + 1; | ||
481 | if (allocate_resource(root, res, size + 1, min, max, align, NULL, NULL) < 0) { | ||
482 | /* uh oh */ | ||
483 | prom_printf("PCI: Failed to allocate resource %d for %s\n", | ||
484 | i, pci_name(pdev)); | ||
485 | prom_halt(); | ||
486 | } | ||
487 | |||
488 | /* Update PCI config space. */ | ||
489 | pbm->parent->base_address_update(pdev, i); | ||
490 | } | ||
491 | |||
492 | /* Special case, disable the ROM. Several devices | ||
493 | * act funny (ie. do not respond to memory space writes) | ||
494 | * when it is left enabled. A good example are Qlogic,ISP | ||
495 | * adapters. | ||
496 | */ | ||
497 | pci_read_config_dword(pdev, PCI_ROM_ADDRESS, ®); | ||
498 | reg &= ~PCI_ROM_ADDRESS_ENABLE; | ||
499 | pci_write_config_dword(pdev, PCI_ROM_ADDRESS, reg); | ||
500 | |||
501 | /* If we saw I/O or MEM resources, enable appropriate | ||
502 | * bits in PCI command register. | ||
503 | */ | ||
504 | if (io_seen || mem_seen) { | ||
505 | pci_read_config_word(pdev, PCI_COMMAND, &cmd); | ||
506 | if (io_seen || has_implicit_io(pdev)) | ||
507 | cmd |= PCI_COMMAND_IO; | ||
508 | if (mem_seen) | ||
509 | cmd |= PCI_COMMAND_MEMORY; | ||
510 | pci_write_config_word(pdev, PCI_COMMAND, cmd); | ||
511 | } | ||
512 | |||
513 | /* If this is a PCI bridge or an IDE controller, | ||
514 | * enable bus mastering. In the former case also | ||
515 | * set the cache line size correctly. | ||
516 | */ | ||
517 | if (((pdev->class >> 8) == PCI_CLASS_BRIDGE_PCI) || | ||
518 | (((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) && | ||
519 | ((pdev->class & 0x80) != 0))) { | ||
520 | pci_read_config_word(pdev, PCI_COMMAND, &cmd); | ||
521 | cmd |= PCI_COMMAND_MASTER; | ||
522 | pci_write_config_word(pdev, PCI_COMMAND, cmd); | ||
523 | |||
524 | if ((pdev->class >> 8) == PCI_CLASS_BRIDGE_PCI) | ||
525 | pci_write_config_byte(pdev, | ||
526 | PCI_CACHE_LINE_SIZE, | ||
527 | (64 / sizeof(u32))); | ||
528 | } | ||
529 | } | ||
530 | |||
531 | void __init pci_assign_unassigned(struct pci_pbm_info *pbm, | ||
532 | struct pci_bus *pbus) | ||
533 | { | ||
534 | struct pci_dev *dev; | ||
535 | struct pci_bus *bus; | ||
536 | |||
537 | list_for_each_entry(dev, &pbus->devices, bus_list) | ||
538 | pdev_assign_unassigned(pbm, dev); | ||
539 | |||
540 | list_for_each_entry(bus, &pbus->children, node) | ||
541 | pci_assign_unassigned(pbm, bus); | ||
542 | } | ||
543 | |||
544 | static int __init pci_intmap_match(struct pci_dev *pdev, unsigned int *interrupt) | ||
545 | { | ||
546 | struct linux_prom_pci_intmap bridge_local_intmap[PROM_PCIIMAP_MAX], *intmap; | ||
547 | struct linux_prom_pci_intmask bridge_local_intmask, *intmask; | ||
548 | struct pcidev_cookie *dev_pcp = pdev->sysdata; | ||
549 | struct pci_pbm_info *pbm = dev_pcp->pbm; | ||
550 | struct linux_prom_pci_registers *pregs = dev_pcp->prom_regs; | ||
551 | unsigned int hi, mid, lo, irq; | ||
552 | int i, num_intmap, map_slot; | ||
553 | |||
554 | intmap = &pbm->pbm_intmap[0]; | ||
555 | intmask = &pbm->pbm_intmask; | ||
556 | num_intmap = pbm->num_pbm_intmap; | ||
557 | map_slot = 0; | ||
558 | |||
559 | /* If we are underneath a PCI bridge, use PROM register | ||
560 | * property of the parent bridge which is closest to | ||
561 | * the PBM. | ||
562 | * | ||
563 | * However if that parent bridge has interrupt map/mask | ||
564 | * properties of its own we use the PROM register property | ||
565 | * of the next child device on the path to PDEV. | ||
566 | * | ||
567 | * In detail the two cases are (note that the 'X' below is the | ||
568 | * 'next child on the path to PDEV' mentioned above): | ||
569 | * | ||
570 | * 1) PBM --> PCI bus lacking int{map,mask} --> X ... PDEV | ||
571 | * | ||
572 | * Here we use regs of 'PCI bus' device. | ||
573 | * | ||
574 | * 2) PBM --> PCI bus with int{map,mask} --> X ... PDEV | ||
575 | * | ||
576 | * Here we use regs of 'X'. Note that X can be PDEV. | ||
577 | */ | ||
578 | if (pdev->bus->number != pbm->pci_first_busno) { | ||
579 | struct pcidev_cookie *bus_pcp, *regs_pcp; | ||
580 | struct pci_dev *bus_dev, *regs_dev; | ||
581 | int plen; | ||
582 | |||
583 | bus_dev = pdev->bus->self; | ||
584 | regs_dev = pdev; | ||
585 | |||
586 | while (bus_dev->bus && | ||
587 | bus_dev->bus->number != pbm->pci_first_busno) { | ||
588 | regs_dev = bus_dev; | ||
589 | bus_dev = bus_dev->bus->self; | ||
590 | } | ||
591 | |||
592 | regs_pcp = regs_dev->sysdata; | ||
593 | pregs = regs_pcp->prom_regs; | ||
594 | |||
595 | bus_pcp = bus_dev->sysdata; | ||
596 | |||
597 | /* But if the PCI bridge has it's own interrupt map | ||
598 | * and mask properties, use that and the regs of the | ||
599 | * PCI entity at the next level down on the path to the | ||
600 | * device. | ||
601 | */ | ||
602 | plen = prom_getproperty(bus_pcp->prom_node, "interrupt-map", | ||
603 | (char *) &bridge_local_intmap[0], | ||
604 | sizeof(bridge_local_intmap)); | ||
605 | if (plen != -1) { | ||
606 | intmap = &bridge_local_intmap[0]; | ||
607 | num_intmap = plen / sizeof(struct linux_prom_pci_intmap); | ||
608 | plen = prom_getproperty(bus_pcp->prom_node, | ||
609 | "interrupt-map-mask", | ||
610 | (char *) &bridge_local_intmask, | ||
611 | sizeof(bridge_local_intmask)); | ||
612 | if (plen == -1) { | ||
613 | printk("pci_intmap_match: Warning! Bridge has intmap " | ||
614 | "but no intmask.\n"); | ||
615 | printk("pci_intmap_match: Trying to recover.\n"); | ||
616 | return 0; | ||
617 | } | ||
618 | |||
619 | if (pdev->bus->self != bus_dev) | ||
620 | map_slot = 1; | ||
621 | } else { | ||
622 | pregs = bus_pcp->prom_regs; | ||
623 | map_slot = 1; | ||
624 | } | ||
625 | } | ||
626 | |||
627 | if (map_slot) { | ||
628 | *interrupt = ((*interrupt | ||
629 | - 1 | ||
630 | + PCI_SLOT(pdev->devfn)) & 0x3) + 1; | ||
631 | } | ||
632 | |||
633 | hi = pregs->phys_hi & intmask->phys_hi; | ||
634 | mid = pregs->phys_mid & intmask->phys_mid; | ||
635 | lo = pregs->phys_lo & intmask->phys_lo; | ||
636 | irq = *interrupt & intmask->interrupt; | ||
637 | |||
638 | for (i = 0; i < num_intmap; i++) { | ||
639 | if (intmap[i].phys_hi == hi && | ||
640 | intmap[i].phys_mid == mid && | ||
641 | intmap[i].phys_lo == lo && | ||
642 | intmap[i].interrupt == irq) { | ||
643 | *interrupt = intmap[i].cinterrupt; | ||
644 | printk("PCI-IRQ: Routing bus[%2x] slot[%2x] map[%d] to INO[%02x]\n", | ||
645 | pdev->bus->number, PCI_SLOT(pdev->devfn), | ||
646 | map_slot, *interrupt); | ||
647 | return 1; | ||
648 | } | ||
649 | } | ||
650 | |||
651 | /* We will run this code even if pbm->num_pbm_intmap is zero, just so | ||
652 | * we can apply the slot mapping to the PROM interrupt property value. | ||
653 | * So do not spit out these warnings in that case. | ||
654 | */ | ||
655 | if (num_intmap != 0) { | ||
656 | /* Print it both to OBP console and kernel one so that if bootup | ||
657 | * hangs here the user has the information to report. | ||
658 | */ | ||
659 | prom_printf("pci_intmap_match: bus %02x, devfn %02x: ", | ||
660 | pdev->bus->number, pdev->devfn); | ||
661 | prom_printf("IRQ [%08x.%08x.%08x.%08x] not found in interrupt-map\n", | ||
662 | pregs->phys_hi, pregs->phys_mid, pregs->phys_lo, *interrupt); | ||
663 | prom_printf("Please email this information to davem@redhat.com\n"); | ||
664 | |||
665 | printk("pci_intmap_match: bus %02x, devfn %02x: ", | ||
666 | pdev->bus->number, pdev->devfn); | ||
667 | printk("IRQ [%08x.%08x.%08x.%08x] not found in interrupt-map\n", | ||
668 | pregs->phys_hi, pregs->phys_mid, pregs->phys_lo, *interrupt); | ||
669 | printk("Please email this information to davem@redhat.com\n"); | ||
670 | } | ||
671 | |||
672 | return 0; | ||
673 | } | ||
674 | |||
675 | static void __init pdev_fixup_irq(struct pci_dev *pdev) | ||
676 | { | ||
677 | struct pcidev_cookie *pcp = pdev->sysdata; | ||
678 | struct pci_pbm_info *pbm = pcp->pbm; | ||
679 | struct pci_controller_info *p = pbm->parent; | ||
680 | unsigned int portid = pbm->portid; | ||
681 | unsigned int prom_irq; | ||
682 | int prom_node = pcp->prom_node; | ||
683 | int err; | ||
684 | |||
685 | /* If this is an empty EBUS device, sometimes OBP fails to | ||
686 | * give it a valid fully specified interrupts property. | ||
687 | * The EBUS hooked up to SunHME on PCI I/O boards of | ||
688 | * Ex000 systems is one such case. | ||
689 | * | ||
690 | * The interrupt is not important so just ignore it. | ||
691 | */ | ||
692 | if (pdev->vendor == PCI_VENDOR_ID_SUN && | ||
693 | pdev->device == PCI_DEVICE_ID_SUN_EBUS && | ||
694 | !prom_getchild(prom_node)) { | ||
695 | pdev->irq = 0; | ||
696 | return; | ||
697 | } | ||
698 | |||
699 | err = prom_getproperty(prom_node, "interrupts", | ||
700 | (char *)&prom_irq, sizeof(prom_irq)); | ||
701 | if (err == 0 || err == -1) { | ||
702 | pdev->irq = 0; | ||
703 | return; | ||
704 | } | ||
705 | |||
706 | /* Fully specified already? */ | ||
707 | if (((prom_irq & PCI_IRQ_IGN) >> 6) == portid) { | ||
708 | pdev->irq = p->irq_build(pbm, pdev, prom_irq); | ||
709 | goto have_irq; | ||
710 | } | ||
711 | |||
712 | /* An onboard device? (bit 5 set) */ | ||
713 | if ((prom_irq & PCI_IRQ_INO) & 0x20) { | ||
714 | pdev->irq = p->irq_build(pbm, pdev, (portid << 6 | prom_irq)); | ||
715 | goto have_irq; | ||
716 | } | ||
717 | |||
718 | /* Can we find a matching entry in the interrupt-map? */ | ||
719 | if (pci_intmap_match(pdev, &prom_irq)) { | ||
720 | pdev->irq = p->irq_build(pbm, pdev, (portid << 6) | prom_irq); | ||
721 | goto have_irq; | ||
722 | } | ||
723 | |||
724 | /* Ok, we have to do it the hard way. */ | ||
725 | { | ||
726 | unsigned int bus, slot, line; | ||
727 | |||
728 | bus = (pbm == &pbm->parent->pbm_B) ? (1 << 4) : 0; | ||
729 | |||
730 | /* If we have a legal interrupt property, use it as | ||
731 | * the IRQ line. | ||
732 | */ | ||
733 | if (prom_irq > 0 && prom_irq < 5) { | ||
734 | line = ((prom_irq - 1) & 3); | ||
735 | } else { | ||
736 | u8 pci_irq_line; | ||
737 | |||
738 | /* Else just directly consult PCI config space. */ | ||
739 | pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pci_irq_line); | ||
740 | line = ((pci_irq_line - 1) & 3); | ||
741 | } | ||
742 | |||
743 | /* Now figure out the slot. | ||
744 | * | ||
745 | * Basically, device number zero on the top-level bus is | ||
746 | * always the PCI host controller. Slot 0 is then device 1. | ||
747 | * PBM A supports two external slots (0 and 1), and PBM B | ||
748 | * supports 4 external slots (0, 1, 2, and 3). On-board PCI | ||
749 | * devices are wired to device numbers outside of these | ||
750 | * ranges. -DaveM | ||
751 | */ | ||
752 | if (pdev->bus->number == pbm->pci_first_busno) { | ||
753 | slot = PCI_SLOT(pdev->devfn) - pbm->pci_first_slot; | ||
754 | } else { | ||
755 | struct pci_dev *bus_dev; | ||
756 | |||
757 | /* Underneath a bridge, use slot number of parent | ||
758 | * bridge which is closest to the PBM. | ||
759 | */ | ||
760 | bus_dev = pdev->bus->self; | ||
761 | while (bus_dev->bus && | ||
762 | bus_dev->bus->number != pbm->pci_first_busno) | ||
763 | bus_dev = bus_dev->bus->self; | ||
764 | |||
765 | slot = PCI_SLOT(bus_dev->devfn) - pbm->pci_first_slot; | ||
766 | } | ||
767 | slot = slot << 2; | ||
768 | |||
769 | pdev->irq = p->irq_build(pbm, pdev, | ||
770 | ((portid << 6) & PCI_IRQ_IGN) | | ||
771 | (bus | slot | line)); | ||
772 | } | ||
773 | |||
774 | have_irq: | ||
775 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, | ||
776 | pdev->irq & PCI_IRQ_INO); | ||
777 | } | ||
778 | |||
779 | void __init pci_fixup_irq(struct pci_pbm_info *pbm, | ||
780 | struct pci_bus *pbus) | ||
781 | { | ||
782 | struct pci_dev *dev; | ||
783 | struct pci_bus *bus; | ||
784 | |||
785 | list_for_each_entry(dev, &pbus->devices, bus_list) | ||
786 | pdev_fixup_irq(dev); | ||
787 | |||
788 | list_for_each_entry(bus, &pbus->children, node) | ||
789 | pci_fixup_irq(pbm, bus); | ||
790 | } | ||
791 | |||
792 | static void pdev_setup_busmastering(struct pci_dev *pdev, int is_66mhz) | ||
793 | { | ||
794 | u16 cmd; | ||
795 | u8 hdr_type, min_gnt, ltimer; | ||
796 | |||
797 | pci_read_config_word(pdev, PCI_COMMAND, &cmd); | ||
798 | cmd |= PCI_COMMAND_MASTER; | ||
799 | pci_write_config_word(pdev, PCI_COMMAND, cmd); | ||
800 | |||
801 | /* Read it back, if the mastering bit did not | ||
802 | * get set, the device does not support bus | ||
803 | * mastering so we have nothing to do here. | ||
804 | */ | ||
805 | pci_read_config_word(pdev, PCI_COMMAND, &cmd); | ||
806 | if ((cmd & PCI_COMMAND_MASTER) == 0) | ||
807 | return; | ||
808 | |||
809 | /* Set correct cache line size, 64-byte on all | ||
810 | * Sparc64 PCI systems. Note that the value is | ||
811 | * measured in 32-bit words. | ||
812 | */ | ||
813 | pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, | ||
814 | 64 / sizeof(u32)); | ||
815 | |||
816 | pci_read_config_byte(pdev, PCI_HEADER_TYPE, &hdr_type); | ||
817 | hdr_type &= ~0x80; | ||
818 | if (hdr_type != PCI_HEADER_TYPE_NORMAL) | ||
819 | return; | ||
820 | |||
821 | /* If the latency timer is already programmed with a non-zero | ||
822 | * value, assume whoever set it (OBP or whoever) knows what | ||
823 | * they are doing. | ||
824 | */ | ||
825 | pci_read_config_byte(pdev, PCI_LATENCY_TIMER, <imer); | ||
826 | if (ltimer != 0) | ||
827 | return; | ||
828 | |||
829 | /* XXX Since I'm tipping off the min grant value to | ||
830 | * XXX choose a suitable latency timer value, I also | ||
831 | * XXX considered making use of the max latency value | ||
832 | * XXX as well. Unfortunately I've seen too many bogusly | ||
833 | * XXX low settings for it to the point where it lacks | ||
834 | * XXX any usefulness. In one case, an ethernet card | ||
835 | * XXX claimed a min grant of 10 and a max latency of 5. | ||
836 | * XXX Now, if I had two such cards on the same bus I | ||
837 | * XXX could not set the desired burst period (calculated | ||
838 | * XXX from min grant) without violating the max latency | ||
839 | * XXX bound. Duh... | ||
840 | * XXX | ||
841 | * XXX I blame dumb PC bios implementors for stuff like | ||
842 | * XXX this, most of them don't even try to do something | ||
843 | * XXX sensible with latency timer values and just set some | ||
844 | * XXX default value (usually 32) into every device. | ||
845 | */ | ||
846 | |||
847 | pci_read_config_byte(pdev, PCI_MIN_GNT, &min_gnt); | ||
848 | |||
849 | if (min_gnt == 0) { | ||
850 | /* If no min_gnt setting then use a default | ||
851 | * value. | ||
852 | */ | ||
853 | if (is_66mhz) | ||
854 | ltimer = 16; | ||
855 | else | ||
856 | ltimer = 32; | ||
857 | } else { | ||
858 | int shift_factor; | ||
859 | |||
860 | if (is_66mhz) | ||
861 | shift_factor = 2; | ||
862 | else | ||
863 | shift_factor = 3; | ||
864 | |||
865 | /* Use a default value when the min_gnt value | ||
866 | * is erroneously high. | ||
867 | */ | ||
868 | if (((unsigned int) min_gnt << shift_factor) > 512 || | ||
869 | ((min_gnt << shift_factor) & 0xff) == 0) { | ||
870 | ltimer = 8 << shift_factor; | ||
871 | } else { | ||
872 | ltimer = min_gnt << shift_factor; | ||
873 | } | ||
874 | } | ||
875 | |||
876 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, ltimer); | ||
877 | } | ||
878 | |||
879 | void pci_determine_66mhz_disposition(struct pci_pbm_info *pbm, | ||
880 | struct pci_bus *pbus) | ||
881 | { | ||
882 | struct pci_dev *pdev; | ||
883 | int all_are_66mhz; | ||
884 | u16 status; | ||
885 | |||
886 | if (pbm->is_66mhz_capable == 0) { | ||
887 | all_are_66mhz = 0; | ||
888 | goto out; | ||
889 | } | ||
890 | |||
891 | all_are_66mhz = 1; | ||
892 | list_for_each_entry(pdev, &pbus->devices, bus_list) { | ||
893 | pci_read_config_word(pdev, PCI_STATUS, &status); | ||
894 | if (!(status & PCI_STATUS_66MHZ)) { | ||
895 | all_are_66mhz = 0; | ||
896 | break; | ||
897 | } | ||
898 | } | ||
899 | out: | ||
900 | pbm->all_devs_66mhz = all_are_66mhz; | ||
901 | |||
902 | printk("PCI%d(PBM%c): Bus running at %dMHz\n", | ||
903 | pbm->parent->index, | ||
904 | (pbm == &pbm->parent->pbm_A) ? 'A' : 'B', | ||
905 | (all_are_66mhz ? 66 : 33)); | ||
906 | } | ||
907 | |||
908 | void pci_setup_busmastering(struct pci_pbm_info *pbm, | ||
909 | struct pci_bus *pbus) | ||
910 | { | ||
911 | struct pci_dev *dev; | ||
912 | struct pci_bus *bus; | ||
913 | int is_66mhz; | ||
914 | |||
915 | is_66mhz = pbm->is_66mhz_capable && pbm->all_devs_66mhz; | ||
916 | |||
917 | list_for_each_entry(dev, &pbus->devices, bus_list) | ||
918 | pdev_setup_busmastering(dev, is_66mhz); | ||
919 | |||
920 | list_for_each_entry(bus, &pbus->children, node) | ||
921 | pci_setup_busmastering(pbm, bus); | ||
922 | } | ||
923 | |||
924 | void pci_register_legacy_regions(struct resource *io_res, | ||
925 | struct resource *mem_res) | ||
926 | { | ||
927 | struct resource *p; | ||
928 | |||
929 | /* VGA Video RAM. */ | ||
930 | p = kmalloc(sizeof(*p), GFP_KERNEL); | ||
931 | if (!p) | ||
932 | return; | ||
933 | |||
934 | memset(p, 0, sizeof(*p)); | ||
935 | p->name = "Video RAM area"; | ||
936 | p->start = mem_res->start + 0xa0000UL; | ||
937 | p->end = p->start + 0x1ffffUL; | ||
938 | p->flags = IORESOURCE_BUSY; | ||
939 | request_resource(mem_res, p); | ||
940 | |||
941 | p = kmalloc(sizeof(*p), GFP_KERNEL); | ||
942 | if (!p) | ||
943 | return; | ||
944 | |||
945 | memset(p, 0, sizeof(*p)); | ||
946 | p->name = "System ROM"; | ||
947 | p->start = mem_res->start + 0xf0000UL; | ||
948 | p->end = p->start + 0xffffUL; | ||
949 | p->flags = IORESOURCE_BUSY; | ||
950 | request_resource(mem_res, p); | ||
951 | |||
952 | p = kmalloc(sizeof(*p), GFP_KERNEL); | ||
953 | if (!p) | ||
954 | return; | ||
955 | |||
956 | memset(p, 0, sizeof(*p)); | ||
957 | p->name = "Video ROM"; | ||
958 | p->start = mem_res->start + 0xc0000UL; | ||
959 | p->end = p->start + 0x7fffUL; | ||
960 | p->flags = IORESOURCE_BUSY; | ||
961 | request_resource(mem_res, p); | ||
962 | } | ||
963 | |||
964 | /* Generic helper routines for PCI error reporting. */ | ||
965 | void pci_scan_for_target_abort(struct pci_controller_info *p, | ||
966 | struct pci_pbm_info *pbm, | ||
967 | struct pci_bus *pbus) | ||
968 | { | ||
969 | struct pci_dev *pdev; | ||
970 | struct pci_bus *bus; | ||
971 | |||
972 | list_for_each_entry(pdev, &pbus->devices, bus_list) { | ||
973 | u16 status, error_bits; | ||
974 | |||
975 | pci_read_config_word(pdev, PCI_STATUS, &status); | ||
976 | error_bits = | ||
977 | (status & (PCI_STATUS_SIG_TARGET_ABORT | | ||
978 | PCI_STATUS_REC_TARGET_ABORT)); | ||
979 | if (error_bits) { | ||
980 | pci_write_config_word(pdev, PCI_STATUS, error_bits); | ||
981 | printk("PCI%d(PBM%c): Device [%s] saw Target Abort [%016x]\n", | ||
982 | p->index, ((pbm == &p->pbm_A) ? 'A' : 'B'), | ||
983 | pci_name(pdev), status); | ||
984 | } | ||
985 | } | ||
986 | |||
987 | list_for_each_entry(bus, &pbus->children, node) | ||
988 | pci_scan_for_target_abort(p, pbm, bus); | ||
989 | } | ||
990 | |||
991 | void pci_scan_for_master_abort(struct pci_controller_info *p, | ||
992 | struct pci_pbm_info *pbm, | ||
993 | struct pci_bus *pbus) | ||
994 | { | ||
995 | struct pci_dev *pdev; | ||
996 | struct pci_bus *bus; | ||
997 | |||
998 | list_for_each_entry(pdev, &pbus->devices, bus_list) { | ||
999 | u16 status, error_bits; | ||
1000 | |||
1001 | pci_read_config_word(pdev, PCI_STATUS, &status); | ||
1002 | error_bits = | ||
1003 | (status & (PCI_STATUS_REC_MASTER_ABORT)); | ||
1004 | if (error_bits) { | ||
1005 | pci_write_config_word(pdev, PCI_STATUS, error_bits); | ||
1006 | printk("PCI%d(PBM%c): Device [%s] received Master Abort [%016x]\n", | ||
1007 | p->index, ((pbm == &p->pbm_A) ? 'A' : 'B'), | ||
1008 | pci_name(pdev), status); | ||
1009 | } | ||
1010 | } | ||
1011 | |||
1012 | list_for_each_entry(bus, &pbus->children, node) | ||
1013 | pci_scan_for_master_abort(p, pbm, bus); | ||
1014 | } | ||
1015 | |||
1016 | void pci_scan_for_parity_error(struct pci_controller_info *p, | ||
1017 | struct pci_pbm_info *pbm, | ||
1018 | struct pci_bus *pbus) | ||
1019 | { | ||
1020 | struct pci_dev *pdev; | ||
1021 | struct pci_bus *bus; | ||
1022 | |||
1023 | list_for_each_entry(pdev, &pbus->devices, bus_list) { | ||
1024 | u16 status, error_bits; | ||
1025 | |||
1026 | pci_read_config_word(pdev, PCI_STATUS, &status); | ||
1027 | error_bits = | ||
1028 | (status & (PCI_STATUS_PARITY | | ||
1029 | PCI_STATUS_DETECTED_PARITY)); | ||
1030 | if (error_bits) { | ||
1031 | pci_write_config_word(pdev, PCI_STATUS, error_bits); | ||
1032 | printk("PCI%d(PBM%c): Device [%s] saw Parity Error [%016x]\n", | ||
1033 | p->index, ((pbm == &p->pbm_A) ? 'A' : 'B'), | ||
1034 | pci_name(pdev), status); | ||
1035 | } | ||
1036 | } | ||
1037 | |||
1038 | list_for_each_entry(bus, &pbus->children, node) | ||
1039 | pci_scan_for_parity_error(p, pbm, bus); | ||
1040 | } | ||