@@ -432,6 +432,11 @@ static void of_scan_pci_bridge(struct pci_pbm_info *pbm,
432
432
node -> full_name );
433
433
return ;
434
434
}
435
+
436
+ if (ofpci_verbose )
437
+ printk (" Bridge bus range [%u --> %u]\n" ,
438
+ busrange [0 ], busrange [1 ]);
439
+
435
440
ranges = of_get_property (node , "ranges" , & len );
436
441
simba = 0 ;
437
442
if (ranges == NULL ) {
@@ -451,6 +456,10 @@ static void of_scan_pci_bridge(struct pci_pbm_info *pbm,
451
456
pci_bus_insert_busn_res (bus , busrange [0 ], busrange [1 ]);
452
457
bus -> bridge_ctl = 0 ;
453
458
459
+ if (ofpci_verbose )
460
+ printk (" Bridge ranges[%p] simba[%d]\n" ,
461
+ ranges , simba );
462
+
454
463
/* parse ranges property, or cook one up by hand for Simba */
455
464
/* PCI #address-cells == 3 and #size-cells == 2 always */
456
465
res = & dev -> resource [PCI_BRIDGE_RESOURCES ];
@@ -468,10 +477,29 @@ static void of_scan_pci_bridge(struct pci_pbm_info *pbm,
468
477
}
469
478
i = 1 ;
470
479
for (; len >= 32 ; len -= 32 , ranges += 8 ) {
480
+ u64 start ;
481
+
482
+ if (ofpci_verbose )
483
+ printk (" RAW Range[%08x:%08x:%08x:%08x:%08x:%08x:"
484
+ "%08x:%08x]\n" ,
485
+ ranges [0 ], ranges [1 ], ranges [2 ], ranges [3 ],
486
+ ranges [4 ], ranges [5 ], ranges [6 ], ranges [7 ]);
487
+
471
488
flags = pci_parse_of_flags (ranges [0 ]);
472
489
size = GET_64BIT (ranges , 6 );
473
490
if (flags == 0 || size == 0 )
474
491
continue ;
492
+
493
+ /* On PCI-Express systems, PCI bridges that have no devices downstream
494
+ * have a bogus size value where the first 32-bit cell is 0xffffffff.
495
+ * This results in a bogus range where start + size overflows.
496
+ *
497
+ * Just skip these otherwise the kernel will complain when the resource
498
+ * tries to be claimed.
499
+ */
500
+ if (size >> 32 == 0xffffffff )
501
+ continue ;
502
+
475
503
if (flags & IORESOURCE_IO ) {
476
504
res = bus -> resource [0 ];
477
505
if (res -> flags ) {
@@ -490,8 +518,13 @@ static void of_scan_pci_bridge(struct pci_pbm_info *pbm,
490
518
}
491
519
492
520
res -> flags = flags ;
493
- region .start = GET_64BIT (ranges , 1 );
521
+ region .start = start = GET_64BIT (ranges , 1 );
494
522
region .end = region .start + size - 1 ;
523
+
524
+ if (ofpci_verbose )
525
+ printk (" Using flags[%08x] start[%016llx] size[%016llx]\n" ,
526
+ flags , start , size );
527
+
495
528
pcibios_bus_to_resource (dev -> bus , res , & region );
496
529
}
497
530
after_ranges :
@@ -584,6 +617,36 @@ static void pci_bus_register_of_sysfs(struct pci_bus *bus)
584
617
pci_bus_register_of_sysfs (child_bus );
585
618
}
586
619
620
+ static void pci_claim_bus_resources (struct pci_bus * bus )
621
+ {
622
+ struct pci_bus * child_bus ;
623
+ struct pci_dev * dev ;
624
+
625
+ list_for_each_entry (dev , & bus -> devices , bus_list ) {
626
+ int i ;
627
+
628
+ for (i = 0 ; i < PCI_NUM_RESOURCES ; i ++ ) {
629
+ struct resource * r = & dev -> resource [i ];
630
+
631
+ if (r -> parent || !r -> start || !r -> flags )
632
+ continue ;
633
+
634
+ if (ofpci_verbose )
635
+ printk ("PCI: Claiming %s: "
636
+ "Resource %d: %016llx..%016llx [%x]\n" ,
637
+ pci_name (dev ), i ,
638
+ (unsigned long long )r -> start ,
639
+ (unsigned long long )r -> end ,
640
+ (unsigned int )r -> flags );
641
+
642
+ pci_claim_resource (dev , i );
643
+ }
644
+ }
645
+
646
+ list_for_each_entry (child_bus , & bus -> children , node )
647
+ pci_claim_bus_resources (child_bus );
648
+ }
649
+
587
650
struct pci_bus * pci_scan_one_pbm (struct pci_pbm_info * pbm ,
588
651
struct device * parent )
589
652
{
@@ -614,6 +677,8 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
614
677
pci_bus_add_devices (bus );
615
678
pci_bus_register_of_sysfs (bus );
616
679
680
+ pci_claim_bus_resources (bus );
681
+
617
682
return bus ;
618
683
}
619
684
0 commit comments