@@ -637,10 +637,19 @@ static inline int numcol(u32 mtr)
637
637
return 1 << cols ;
638
638
}
639
639
640
- static struct sbridge_dev * get_sbridge_dev (u8 bus )
640
+ static struct sbridge_dev * get_sbridge_dev (u8 bus , int multi_bus )
641
641
{
642
642
struct sbridge_dev * sbridge_dev ;
643
643
644
+ /*
645
+ * If we have devices scattered across several busses that pertain
646
+ * to the same memory controller, we'll lump them all together.
647
+ */
648
+ if (multi_bus ) {
649
+ return list_first_entry_or_null (& sbridge_edac_list ,
650
+ struct sbridge_dev , list );
651
+ }
652
+
644
653
list_for_each_entry (sbridge_dev , & sbridge_edac_list , list ) {
645
654
if (sbridge_dev -> bus == bus )
646
655
return sbridge_dev ;
@@ -1588,7 +1597,8 @@ static void sbridge_put_all_devices(void)
1588
1597
static int sbridge_get_onedevice (struct pci_dev * * prev ,
1589
1598
u8 * num_mc ,
1590
1599
const struct pci_id_table * table ,
1591
- const unsigned devno )
1600
+ const unsigned devno ,
1601
+ const int multi_bus )
1592
1602
{
1593
1603
struct sbridge_dev * sbridge_dev ;
1594
1604
const struct pci_id_descr * dev_descr = & table -> descr [devno ];
@@ -1624,7 +1634,7 @@ static int sbridge_get_onedevice(struct pci_dev **prev,
1624
1634
}
1625
1635
bus = pdev -> bus -> number ;
1626
1636
1627
- sbridge_dev = get_sbridge_dev (bus );
1637
+ sbridge_dev = get_sbridge_dev (bus , multi_bus );
1628
1638
if (!sbridge_dev ) {
1629
1639
sbridge_dev = alloc_sbridge_dev (bus , table );
1630
1640
if (!sbridge_dev ) {
@@ -1673,21 +1683,32 @@ static int sbridge_get_onedevice(struct pci_dev **prev,
1673
1683
* @num_mc: pointer to the memory controllers count, to be incremented in case
1674
1684
* of success.
1675
1685
* @table: model specific table
1686
+ * @allow_dups: allow for multiple devices to exist with the same device id
1687
+ * (as implemented, this isn't expected to work correctly in the
1688
+ * multi-socket case).
1689
+ * @multi_bus: don't assume devices on different buses belong to different
1690
+ * memory controllers.
1676
1691
*
1677
1692
* returns 0 in case of success or error code
1678
1693
*/
1679
- static int sbridge_get_all_devices (u8 * num_mc ,
1680
- const struct pci_id_table * table )
1694
+ static int sbridge_get_all_devices_full (u8 * num_mc ,
1695
+ const struct pci_id_table * table ,
1696
+ int allow_dups ,
1697
+ int multi_bus )
1681
1698
{
1682
1699
int i , rc ;
1683
1700
struct pci_dev * pdev = NULL ;
1684
1701
1685
1702
while (table && table -> descr ) {
1686
1703
for (i = 0 ; i < table -> n_devs ; i ++ ) {
1687
- pdev = NULL ;
1704
+ if (!allow_dups || i == 0 ||
1705
+ table -> descr [i ].dev_id !=
1706
+ table -> descr [i - 1 ].dev_id ) {
1707
+ pdev = NULL ;
1708
+ }
1688
1709
do {
1689
1710
rc = sbridge_get_onedevice (& pdev , num_mc ,
1690
- table , i );
1711
+ table , i , multi_bus );
1691
1712
if (rc < 0 ) {
1692
1713
if (i == 0 ) {
1693
1714
i = table -> n_devs ;
@@ -1696,14 +1717,17 @@ static int sbridge_get_all_devices(u8 *num_mc,
1696
1717
sbridge_put_all_devices ();
1697
1718
return - ENODEV ;
1698
1719
}
1699
- } while (pdev );
1720
+ } while (pdev && ! allow_dups );
1700
1721
}
1701
1722
table ++ ;
1702
1723
}
1703
1724
1704
1725
return 0 ;
1705
1726
}
1706
1727
1728
+ #define sbridge_get_all_devices (num_mc , table ) \
1729
+ sbridge_get_all_devices_full(num_mc, table, 0, 0)
1730
+
1707
1731
static int sbridge_mci_bind_devs (struct mem_ctl_info * mci ,
1708
1732
struct sbridge_dev * sbridge_dev )
1709
1733
{
0 commit comments