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