aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/pci_64.c68
-rw-r--r--arch/powerpc/kernel/rtas_pci.c68
-rw-r--r--arch/powerpc/platforms/iseries/pci.c3
-rw-r--r--arch/powerpc/platforms/maple/pci.c16
-rw-r--r--arch/powerpc/platforms/powermac/pci.c62
-rw-r--r--include/asm-powerpc/ppc-pci.h1
-rw-r--r--include/asm-ppc64/pci-bridge.h14
7 files changed, 114 insertions, 118 deletions
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index d7de3ec0bf83..5a5b24685081 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -187,7 +187,7 @@ static DEFINE_SPINLOCK(hose_spinlock);
187/* 187/*
188 * pci_controller(phb) initialized common variables. 188 * pci_controller(phb) initialized common variables.
189 */ 189 */
190void __devinit pci_setup_pci_controller(struct pci_controller *hose) 190static void __devinit pci_setup_pci_controller(struct pci_controller *hose)
191{ 191{
192 memset(hose, 0, sizeof(struct pci_controller)); 192 memset(hose, 0, sizeof(struct pci_controller));
193 193
@@ -197,6 +197,65 @@ void __devinit pci_setup_pci_controller(struct pci_controller *hose)
197 spin_unlock(&hose_spinlock); 197 spin_unlock(&hose_spinlock);
198} 198}
199 199
200static void add_linux_pci_domain(struct device_node *dev,
201 struct pci_controller *phb)
202{
203 struct property *of_prop;
204 unsigned int size;
205
206 of_prop = (struct property *)
207 get_property(dev, "linux,pci-domain", &size);
208 if (of_prop != NULL)
209 return;
210 WARN_ON(of_prop && size < sizeof(int));
211 if (of_prop && size < sizeof(int))
212 of_prop = NULL;
213 size = sizeof(struct property) + sizeof(int);
214 if (of_prop == NULL) {
215 if (mem_init_done)
216 of_prop = kmalloc(size, GFP_KERNEL);
217 else
218 of_prop = alloc_bootmem(size);
219 }
220 memset(of_prop, 0, sizeof(struct property));
221 of_prop->name = "linux,pci-domain";
222 of_prop->length = sizeof(int);
223 of_prop->value = (unsigned char *)&of_prop[1];
224 *((int *)of_prop->value) = phb->global_number;
225 prom_add_property(dev, of_prop);
226}
227
228struct pci_controller * pcibios_alloc_controller(struct device_node *dev)
229{
230 struct pci_controller *phb;
231
232 if (mem_init_done)
233 phb = kmalloc(sizeof(struct pci_controller), GFP_KERNEL);
234 else
235 phb = alloc_bootmem(sizeof (struct pci_controller));
236 if (phb == NULL)
237 return NULL;
238 pci_setup_pci_controller(phb);
239 phb->arch_data = dev;
240 phb->is_dynamic = mem_init_done;
241 if (dev)
242 add_linux_pci_domain(dev, phb);
243 return phb;
244}
245
246void pcibios_free_controller(struct pci_controller *phb)
247{
248 if (phb->arch_data) {
249 struct device_node *np = phb->arch_data;
250 int *domain = (int *)get_property(np,
251 "linux,pci-domain", NULL);
252 if (domain)
253 *domain = -1;
254 }
255 if (phb->is_dynamic)
256 kfree(phb);
257}
258
200static void __init pcibios_claim_one_bus(struct pci_bus *b) 259static void __init pcibios_claim_one_bus(struct pci_bus *b)
201{ 260{
202 struct pci_dev *dev; 261 struct pci_dev *dev;
@@ -907,9 +966,10 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
907 * (size depending on dev->n_addr_cells) 966 * (size depending on dev->n_addr_cells)
908 * cells 4+5 or 5+6: the size of the range 967 * cells 4+5 or 5+6: the size of the range
909 */ 968 */
910 rlen = 0;
911 hose->io_base_phys = 0;
912 ranges = (unsigned int *) get_property(dev, "ranges", &rlen); 969 ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
970 if (ranges == NULL)
971 return;
972 hose->io_base_phys = 0;
913 while ((rlen -= np * sizeof(unsigned int)) >= 0) { 973 while ((rlen -= np * sizeof(unsigned int)) >= 0) {
914 res = NULL; 974 res = NULL;
915 pci_space = ranges[0]; 975 pci_space = ranges[0];
@@ -1107,6 +1167,8 @@ int remap_bus_range(struct pci_bus *bus)
1107 1167
1108 if (get_bus_io_range(bus, &start_phys, &start_virt, &size)) 1168 if (get_bus_io_range(bus, &start_phys, &start_virt, &size))
1109 return 1; 1169 return 1;
1170 if (start_phys == 0)
1171 return 1;
1110 printk("mapping IO %lx -> %lx, size: %lx\n", start_phys, start_virt, size); 1172 printk("mapping IO %lx -> %lx, size: %lx\n", start_phys, start_virt, size);
1111 if (__ioremap_explicit(start_phys, start_virt, size, 1173 if (__ioremap_explicit(start_phys, start_virt, size,
1112 _PAGE_NO_CACHE | _PAGE_GUARDED)) 1174 _PAGE_NO_CACHE | _PAGE_GUARDED))
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index 0e5a8e116653..60dec2401c26 100644
--- a/arch/powerpc/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -304,75 +304,18 @@ static int __devinit setup_phb(struct device_node *dev,
304 struct pci_controller *phb, 304 struct pci_controller *phb,
305 unsigned int addr_size_words) 305 unsigned int addr_size_words)
306{ 306{
307 pci_setup_pci_controller(phb);
308
309 if (is_python(dev)) 307 if (is_python(dev))
310 python_countermeasures(dev, addr_size_words); 308 python_countermeasures(dev, addr_size_words);
311 309
312 if (phb_set_bus_ranges(dev, phb)) 310 if (phb_set_bus_ranges(dev, phb))
313 return 1; 311 return 1;
314 312
315 phb->arch_data = dev;
316 phb->ops = &rtas_pci_ops; 313 phb->ops = &rtas_pci_ops;
317 phb->buid = get_phb_buid(dev); 314 phb->buid = get_phb_buid(dev);
318 315
319 return 0; 316 return 0;
320} 317}
321 318
322static void __devinit add_linux_pci_domain(struct device_node *dev,
323 struct pci_controller *phb,
324 struct property *of_prop)
325{
326 memset(of_prop, 0, sizeof(struct property));
327 of_prop->name = "linux,pci-domain";
328 of_prop->length = sizeof(phb->global_number);
329 of_prop->value = (unsigned char *)&of_prop[1];
330 memcpy(of_prop->value, &phb->global_number, sizeof(phb->global_number));
331 prom_add_property(dev, of_prop);
332}
333
334static struct pci_controller * __init alloc_phb(struct device_node *dev,
335 unsigned int addr_size_words)
336{
337 struct pci_controller *phb;
338 struct property *of_prop;
339
340 phb = alloc_bootmem(sizeof(struct pci_controller));
341 if (phb == NULL)
342 return NULL;
343
344 of_prop = alloc_bootmem(sizeof(struct property) +
345 sizeof(phb->global_number));
346 if (!of_prop)
347 return NULL;
348
349 if (setup_phb(dev, phb, addr_size_words))
350 return NULL;
351
352 add_linux_pci_domain(dev, phb, of_prop);
353
354 return phb;
355}
356
357static struct pci_controller * __devinit alloc_phb_dynamic(struct device_node *dev, unsigned int addr_size_words)
358{
359 struct pci_controller *phb;
360
361 phb = (struct pci_controller *)kmalloc(sizeof(struct pci_controller),
362 GFP_KERNEL);
363 if (phb == NULL)
364 return NULL;
365
366 if (setup_phb(dev, phb, addr_size_words))
367 return NULL;
368
369 phb->is_dynamic = 1;
370
371 /* TODO: linux,pci-domain? */
372
373 return phb;
374}
375
376unsigned long __init find_and_init_phbs(void) 319unsigned long __init find_and_init_phbs(void)
377{ 320{
378 struct device_node *node; 321 struct device_node *node;
@@ -397,10 +340,10 @@ unsigned long __init find_and_init_phbs(void)
397 if (node->type == NULL || strcmp(node->type, "pci") != 0) 340 if (node->type == NULL || strcmp(node->type, "pci") != 0)
398 continue; 341 continue;
399 342
400 phb = alloc_phb(node, root_size_cells); 343 phb = pcibios_alloc_controller(node);
401 if (!phb) 344 if (!phb)
402 continue; 345 continue;
403 346 setup_phb(node, phb, root_size_cells);
404 pci_process_bridge_OF_ranges(phb, node, 0); 347 pci_process_bridge_OF_ranges(phb, node, 0);
405 pci_setup_phb_io(phb, index == 0); 348 pci_setup_phb_io(phb, index == 0);
406#ifdef CONFIG_PPC_PSERIES 349#ifdef CONFIG_PPC_PSERIES
@@ -446,10 +389,10 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
446 root_size_cells = prom_n_size_cells(root); 389 root_size_cells = prom_n_size_cells(root);
447 390
448 primary = list_empty(&hose_list); 391 primary = list_empty(&hose_list);
449 phb = alloc_phb_dynamic(dn, root_size_cells); 392 phb = pcibios_alloc_controller(dn);
450 if (!phb) 393 if (!phb)
451 return NULL; 394 return NULL;
452 395 setup_phb(dn, phb, root_size_cells);
453 pci_process_bridge_OF_ranges(phb, dn, primary); 396 pci_process_bridge_OF_ranges(phb, dn, primary);
454 397
455 pci_setup_phb_io_dynamic(phb, primary); 398 pci_setup_phb_io_dynamic(phb, primary);
@@ -505,8 +448,7 @@ int pcibios_remove_root_bus(struct pci_controller *phb)
505 } 448 }
506 449
507 list_del(&phb->list_node); 450 list_del(&phb->list_node);
508 if (phb->is_dynamic) 451 pcibios_free_controller(phb);
509 kfree(phb);
510 452
511 return 0; 453 return 0;
512} 454}
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index 4b75131773a6..dafc518fbb83 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -244,10 +244,9 @@ unsigned long __init find_and_init_phbs(void)
244 if (ret == 0) { 244 if (ret == 0) {
245 printk("bus %d appears to exist\n", bus); 245 printk("bus %d appears to exist\n", bus);
246 246
247 phb = (struct pci_controller *)kmalloc(sizeof(struct pci_controller), GFP_KERNEL); 247 phb = pcibios_alloc_controller(NULL);
248 if (phb == NULL) 248 if (phb == NULL)
249 return -ENOMEM; 249 return -ENOMEM;
250 pci_setup_pci_controller(phb);
251 250
252 phb->pci_mem_offset = phb->local_number = bus; 251 phb->pci_mem_offset = phb->local_number = bus;
253 phb->first_busno = bus; 252 phb->first_busno = bus;
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c
index 895aeb3f75d0..f40451da037c 100644
--- a/arch/powerpc/platforms/maple/pci.c
+++ b/arch/powerpc/platforms/maple/pci.c
@@ -326,26 +326,12 @@ static int __init add_bridge(struct device_node *dev)
326 dev->full_name); 326 dev->full_name);
327 } 327 }
328 328
329 hose = alloc_bootmem(sizeof(struct pci_controller)); 329 hose = pcibios_alloc_controller(dev);
330 if (hose == NULL) 330 if (hose == NULL)
331 return -ENOMEM; 331 return -ENOMEM;
332 pci_setup_pci_controller(hose);
333
334 hose->arch_data = dev;
335 hose->first_busno = bus_range ? bus_range[0] : 0; 332 hose->first_busno = bus_range ? bus_range[0] : 0;
336 hose->last_busno = bus_range ? bus_range[1] : 0xff; 333 hose->last_busno = bus_range ? bus_range[1] : 0xff;
337 334
338 of_prop = alloc_bootmem(sizeof(struct property) +
339 sizeof(hose->global_number));
340 if (of_prop) {
341 memset(of_prop, 0, sizeof(struct property));
342 of_prop->name = "linux,pci-domain";
343 of_prop->length = sizeof(hose->global_number);
344 of_prop->value = (unsigned char *)&of_prop[1];
345 memcpy(of_prop->value, &hose->global_number, sizeof(hose->global_number));
346 prom_add_property(dev, of_prop);
347 }
348
349 disp_name = NULL; 335 disp_name = NULL;
350 if (device_is_compatible(dev, "u3-agp")) { 336 if (device_is_compatible(dev, "u3-agp")) {
351 setup_u3_agp(hose); 337 setup_u3_agp(hose);
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index dfd41b9781a9..443be526cde7 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -640,15 +640,16 @@ static void __init setup_u3_ht(struct pci_controller* hose)
640 * the reg address cell, we shall fix that by killing struct 640 * the reg address cell, we shall fix that by killing struct
641 * reg_property and using some accessor functions instead 641 * reg_property and using some accessor functions instead
642 */ 642 */
643 hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000, 0x02000000); 643 hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000,
644 0x02000000);
644 645
645 /* 646 /*
646 * /ht node doesn't expose a "ranges" property, so we "remove" regions that 647 * /ht node doesn't expose a "ranges" property, so we "remove"
647 * have been allocated to AGP. So far, this version of the code doesn't assign 648 * regions that have been allocated to AGP. So far, this version of
648 * any of the 0xfxxxxxxx "fine" memory regions to /ht. 649 * the code doesn't assign any of the 0xfxxxxxxx "fine" memory regions
649 * We need to fix that sooner or later by either parsing all child "ranges" 650 * to /ht. We need to fix that sooner or later by either parsing all
650 * properties or figuring out the U3 address space decoding logic and 651 * child "ranges" properties or figuring out the U3 address space
651 * then read its configuration register (if any). 652 * decoding logic and then read its configuration register (if any).
652 */ 653 */
653 hose->io_base_phys = 0xf4000000; 654 hose->io_base_phys = 0xf4000000;
654 hose->pci_io_size = 0x00400000; 655 hose->pci_io_size = 0x00400000;
@@ -671,10 +672,10 @@ static void __init setup_u3_ht(struct pci_controller* hose)
671 return; 672 return;
672 } 673 }
673 674
674 /* We "remove" the AGP resources from the resources allocated to HT, that 675 /* We "remove" the AGP resources from the resources allocated to HT,
675 * is we create "holes". However, that code does assumptions that so far 676 * that is we create "holes". However, that code does assumptions
676 * happen to be true (cross fingers...), typically that resources in the 677 * that so far happen to be true (cross fingers...), typically that
677 * AGP node are properly ordered 678 * resources in the AGP node are properly ordered
678 */ 679 */
679 cur = 0; 680 cur = 0;
680 for (i=0; i<3; i++) { 681 for (i=0; i<3; i++) {
@@ -684,23 +685,30 @@ static void __init setup_u3_ht(struct pci_controller* hose)
684 /* We don't care about "fine" resources */ 685 /* We don't care about "fine" resources */
685 if (res->start >= 0xf0000000) 686 if (res->start >= 0xf0000000)
686 continue; 687 continue;
687 /* Check if it's just a matter of "shrinking" us in one direction */ 688 /* Check if it's just a matter of "shrinking" us in one
689 * direction
690 */
688 if (hose->mem_resources[cur].start == res->start) { 691 if (hose->mem_resources[cur].start == res->start) {
689 DBG("U3/HT: shrink start of %d, %08lx -> %08lx\n", 692 DBG("U3/HT: shrink start of %d, %08lx -> %08lx\n",
690 cur, hose->mem_resources[cur].start, res->end + 1); 693 cur, hose->mem_resources[cur].start,
694 res->end + 1);
691 hose->mem_resources[cur].start = res->end + 1; 695 hose->mem_resources[cur].start = res->end + 1;
692 continue; 696 continue;
693 } 697 }
694 if (hose->mem_resources[cur].end == res->end) { 698 if (hose->mem_resources[cur].end == res->end) {
695 DBG("U3/HT: shrink end of %d, %08lx -> %08lx\n", 699 DBG("U3/HT: shrink end of %d, %08lx -> %08lx\n",
696 cur, hose->mem_resources[cur].end, res->start - 1); 700 cur, hose->mem_resources[cur].end,
701 res->start - 1);
697 hose->mem_resources[cur].end = res->start - 1; 702 hose->mem_resources[cur].end = res->start - 1;
698 continue; 703 continue;
699 } 704 }
700 /* No, it's not the case, we need a hole */ 705 /* No, it's not the case, we need a hole */
701 if (cur == 2) { 706 if (cur == 2) {
702 /* not enough resources for a hole, we drop part of the range */ 707 /* not enough resources for a hole, we drop part
703 printk(KERN_WARNING "Running out of resources for /ht host !\n"); 708 * of the range
709 */
710 printk(KERN_WARNING "Running out of resources"
711 " for /ht host !\n");
704 hose->mem_resources[cur].end = res->start - 1; 712 hose->mem_resources[cur].end = res->start - 1;
705 continue; 713 continue;
706 } 714 }
@@ -714,17 +722,6 @@ static void __init setup_u3_ht(struct pci_controller* hose)
714 hose->mem_resources[cur-1].end = res->start - 1; 722 hose->mem_resources[cur-1].end = res->start - 1;
715 } 723 }
716} 724}
717
718/* XXX this needs to be converged between ppc32 and ppc64... */
719static struct pci_controller * __init pcibios_alloc_controller(void)
720{
721 struct pci_controller *hose;
722
723 hose = alloc_bootmem(sizeof(struct pci_controller));
724 if (hose)
725 pci_setup_pci_controller(hose);
726 return hose;
727}
728#endif 725#endif
729 726
730/* 727/*
@@ -756,11 +753,16 @@ static int __init add_bridge(struct device_node *dev)
756#endif 753#endif
757 bus_range = (int *) get_property(dev, "bus-range", &len); 754 bus_range = (int *) get_property(dev, "bus-range", &len);
758 if (bus_range == NULL || len < 2 * sizeof(int)) { 755 if (bus_range == NULL || len < 2 * sizeof(int)) {
759 printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n", 756 printk(KERN_WARNING "Can't get bus-range for %s, assume"
760 dev->full_name); 757 " bus 0\n", dev->full_name);
761 } 758 }
762 759
760 /* XXX Different prototypes, to be merged */
761#ifdef CONFIG_PPC64
762 hose = pcibios_alloc_controller(dev);
763#else
763 hose = pcibios_alloc_controller(); 764 hose = pcibios_alloc_controller();
765#endif
764 if (!hose) 766 if (!hose)
765 return -ENOMEM; 767 return -ENOMEM;
766 hose->arch_data = dev; 768 hose->arch_data = dev;
@@ -768,7 +770,7 @@ static int __init add_bridge(struct device_node *dev)
768 hose->last_busno = bus_range ? bus_range[1] : 0xff; 770 hose->last_busno = bus_range ? bus_range[1] : 0xff;
769 771
770 disp_name = NULL; 772 disp_name = NULL;
771#ifdef CONFIG_POWER4 773#ifdef CONFIG_PPC64
772 if (device_is_compatible(dev, "u3-agp")) { 774 if (device_is_compatible(dev, "u3-agp")) {
773 setup_u3_agp(hose); 775 setup_u3_agp(hose);
774 disp_name = "U3-AGP"; 776 disp_name = "U3-AGP";
diff --git a/include/asm-powerpc/ppc-pci.h b/include/asm-powerpc/ppc-pci.h
index 9896fade98a7..2e36e5a7f4f3 100644
--- a/include/asm-powerpc/ppc-pci.h
+++ b/include/asm-powerpc/ppc-pci.h
@@ -14,7 +14,6 @@
14 14
15extern unsigned long isa_io_base; 15extern unsigned long isa_io_base;
16 16
17extern void pci_setup_pci_controller(struct pci_controller *hose);
18extern void pci_setup_phb_io(struct pci_controller *hose, int primary); 17extern void pci_setup_phb_io(struct pci_controller *hose, int primary);
19extern void pci_setup_phb_io_dynamic(struct pci_controller *hose, int primary); 18extern void pci_setup_phb_io_dynamic(struct pci_controller *hose, int primary);
20 19
diff --git a/include/asm-ppc64/pci-bridge.h b/include/asm-ppc64/pci-bridge.h
index efbdaece0cf0..cf04327a597a 100644
--- a/include/asm-ppc64/pci-bridge.h
+++ b/include/asm-ppc64/pci-bridge.h
@@ -61,12 +61,14 @@ struct pci_dn {
61 int busno; /* for pci devices */ 61 int busno; /* for pci devices */
62 int bussubno; /* for pci devices */ 62 int bussubno; /* for pci devices */
63 int devfn; /* for pci devices */ 63 int devfn; /* for pci devices */
64
65#ifdef CONFIG_PPC_PSERIES
64 int eeh_mode; /* See eeh.h for possible EEH_MODEs */ 66 int eeh_mode; /* See eeh.h for possible EEH_MODEs */
65 int eeh_config_addr; 67 int eeh_config_addr;
66 int eeh_check_count; /* # times driver ignored error */ 68 int eeh_check_count; /* # times driver ignored error */
67 int eeh_freeze_count; /* # times this device froze up. */ 69 int eeh_freeze_count; /* # times this device froze up. */
68 int eeh_is_bridge; /* device is pci-to-pci bridge */ 70 int eeh_is_bridge; /* device is pci-to-pci bridge */
69 71#endif
70 int pci_ext_config_space; /* for pci devices */ 72 int pci_ext_config_space; /* for pci devices */
71 struct pci_controller *phb; /* for pci devices */ 73 struct pci_controller *phb; /* for pci devices */
72 struct iommu_table *iommu_table; /* for phb's or bridges */ 74 struct iommu_table *iommu_table; /* for phb's or bridges */
@@ -74,9 +76,9 @@ struct pci_dn {
74 struct device_node *node; /* back-pointer to the device_node */ 76 struct device_node *node; /* back-pointer to the device_node */
75#ifdef CONFIG_PPC_ISERIES 77#ifdef CONFIG_PPC_ISERIES
76 struct list_head Device_List; 78 struct list_head Device_List;
77 int Irq; /* Assigned IRQ */ 79 int Irq; /* Assigned IRQ */
78 int Flags; /* Possible flags(disable/bist)*/ 80 int Flags; /* Possible flags(disable/bist)*/
79 u8 LogicalSlot; /* Hv Slot Index for Tces */ 81 u8 LogicalSlot; /* Hv Slot Index for Tces */
80#endif 82#endif
81 u32 config_space[16]; /* saved PCI config space */ 83 u32 config_space[16]; /* saved PCI config space */
82}; 84};
@@ -136,6 +138,10 @@ static inline struct pci_controller *pci_bus_to_host(struct pci_bus *bus)
136 return PCI_DN(busdn)->phb; 138 return PCI_DN(busdn)->phb;
137} 139}
138 140
141extern struct pci_controller *
142pcibios_alloc_controller(struct device_node *dev);
143extern void pcibios_free_controller(struct pci_controller *phb);
144
139/* Return values for ppc_md.pci_probe_mode function */ 145/* Return values for ppc_md.pci_probe_mode function */
140#define PCI_PROBE_NONE -1 /* Don't look at this bus at all */ 146#define PCI_PROBE_NONE -1 /* Don't look at this bus at all */
141#define PCI_PROBE_NORMAL 0 /* Do normal PCI probing */ 147#define PCI_PROBE_NORMAL 0 /* Do normal PCI probing */