diff options
| -rw-r--r-- | drivers/edac/i7core_edac.c | 117 | ||||
| -rw-r--r-- | include/linux/pci_ids.h | 16 |
2 files changed, 96 insertions, 37 deletions
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 3e2b5379bc05..8d63b0046480 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c | |||
| @@ -206,6 +206,11 @@ struct pci_id_descr { | |||
| 206 | int optional; | 206 | int optional; |
| 207 | }; | 207 | }; |
| 208 | 208 | ||
| 209 | struct pci_id_table { | ||
| 210 | struct pci_id_descr *descr; | ||
| 211 | int n_devs; | ||
| 212 | }; | ||
| 213 | |||
| 209 | struct i7core_dev { | 214 | struct i7core_dev { |
| 210 | struct list_head list; | 215 | struct list_head list; |
| 211 | u8 socket; | 216 | u8 socket; |
| @@ -262,7 +267,7 @@ static DEFINE_MUTEX(i7core_edac_lock); | |||
| 262 | .func = (function), \ | 267 | .func = (function), \ |
| 263 | .dev_id = (device_id) | 268 | .dev_id = (device_id) |
| 264 | 269 | ||
| 265 | struct pci_id_descr pci_dev_descr_i7core[] = { | 270 | struct pci_id_descr pci_dev_descr_i7core_nehalem[] = { |
| 266 | /* Memory controller */ | 271 | /* Memory controller */ |
| 267 | { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_I7_MCR) }, | 272 | { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_I7_MCR) }, |
| 268 | { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_I7_MC_TAD) }, | 273 | { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_I7_MC_TAD) }, |
| @@ -321,6 +326,44 @@ struct pci_id_descr pci_dev_descr_lynnfield[] = { | |||
| 321 | { PCI_DESCR( 0, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE) }, | 326 | { PCI_DESCR( 0, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE) }, |
| 322 | }; | 327 | }; |
| 323 | 328 | ||
| 329 | struct pci_id_descr pci_dev_descr_i7core_westmere[] = { | ||
| 330 | /* Memory controller */ | ||
| 331 | { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MCR_REV2) }, | ||
| 332 | { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TAD_REV2) }, | ||
| 333 | /* Exists only for RDIMM */ | ||
| 334 | { PCI_DESCR(3, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_RAS_REV2), .optional = 1 }, | ||
| 335 | { PCI_DESCR(3, 4, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TEST_REV2) }, | ||
| 336 | |||
| 337 | /* Channel 0 */ | ||
| 338 | { PCI_DESCR(4, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_CTRL_REV2) }, | ||
| 339 | { PCI_DESCR(4, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_ADDR_REV2) }, | ||
| 340 | { PCI_DESCR(4, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_RANK_REV2) }, | ||
| 341 | { PCI_DESCR(4, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_TC_REV2) }, | ||
| 342 | |||
| 343 | /* Channel 1 */ | ||
| 344 | { PCI_DESCR(5, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_CTRL_REV2) }, | ||
| 345 | { PCI_DESCR(5, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_ADDR_REV2) }, | ||
| 346 | { PCI_DESCR(5, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_RANK_REV2) }, | ||
| 347 | { PCI_DESCR(5, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_TC_REV2) }, | ||
| 348 | |||
| 349 | /* Channel 2 */ | ||
| 350 | { PCI_DESCR(6, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_CTRL_REV2) }, | ||
| 351 | { PCI_DESCR(6, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_ADDR_REV2) }, | ||
| 352 | { PCI_DESCR(6, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_RANK_REV2) }, | ||
| 353 | { PCI_DESCR(6, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_TC_REV2) }, | ||
| 354 | |||
| 355 | /* Generic Non-core registers */ | ||
| 356 | { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_REV2) }, | ||
| 357 | |||
| 358 | }; | ||
| 359 | |||
| 360 | #define PCI_ID_TABLE_ENTRY(A) { A, ARRAY_SIZE(A) } | ||
| 361 | struct pci_id_table pci_dev_table[] = { | ||
| 362 | PCI_ID_TABLE_ENTRY(pci_dev_descr_i7core_nehalem), | ||
| 363 | PCI_ID_TABLE_ENTRY(pci_dev_descr_lynnfield), | ||
| 364 | PCI_ID_TABLE_ENTRY(pci_dev_descr_i7core_westmere), | ||
| 365 | }; | ||
| 366 | |||
| 324 | /* | 367 | /* |
| 325 | * pci_device_id table for which devices we are looking for | 368 | * pci_device_id table for which devices we are looking for |
| 326 | */ | 369 | */ |
| @@ -1170,7 +1213,7 @@ static void i7core_put_all_devices(void) | |||
| 1170 | i7core_put_devices(i7core_dev); | 1213 | i7core_put_devices(i7core_dev); |
| 1171 | } | 1214 | } |
| 1172 | 1215 | ||
| 1173 | static void __init i7core_xeon_pci_fixup(int dev_id) | 1216 | static void __init i7core_xeon_pci_fixup(struct pci_id_table *table) |
| 1174 | { | 1217 | { |
| 1175 | struct pci_dev *pdev = NULL; | 1218 | struct pci_dev *pdev = NULL; |
| 1176 | int i; | 1219 | int i; |
| @@ -1179,10 +1222,13 @@ static void __init i7core_xeon_pci_fixup(int dev_id) | |||
| 1179 | * aren't announced by acpi. So, we need to use a legacy scan probing | 1222 | * aren't announced by acpi. So, we need to use a legacy scan probing |
| 1180 | * to detect them | 1223 | * to detect them |
| 1181 | */ | 1224 | */ |
| 1182 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, dev_id, NULL); | 1225 | while (table && table->descr) { |
| 1183 | if (unlikely(!pdev)) { | 1226 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, table->descr[0].dev_id, NULL); |
| 1184 | for (i = 0; i < MAX_SOCKET_BUSES; i++) | 1227 | if (unlikely(!pdev)) { |
| 1185 | pcibios_scan_specific_bus(255-i); | 1228 | for (i = 0; i < MAX_SOCKET_BUSES; i++) |
| 1229 | pcibios_scan_specific_bus(255-i); | ||
| 1230 | } | ||
| 1231 | table++; | ||
| 1186 | } | 1232 | } |
| 1187 | } | 1233 | } |
| 1188 | 1234 | ||
| @@ -1213,15 +1259,10 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno, | |||
| 1213 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, | 1259 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, |
| 1214 | PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT, *prev); | 1260 | PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT, *prev); |
| 1215 | 1261 | ||
| 1216 | if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE && !pdev) { | 1262 | if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE && !pdev) |
| 1217 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, | 1263 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, |
| 1218 | PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_ALT, | 1264 | PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_ALT, |
| 1219 | *prev); | 1265 | *prev); |
| 1220 | if (!pdev) | ||
| 1221 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, | ||
| 1222 | PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_REV2, | ||
| 1223 | *prev); | ||
| 1224 | } | ||
| 1225 | 1266 | ||
| 1226 | if (!pdev) { | 1267 | if (!pdev) { |
| 1227 | if (*prev) { | 1268 | if (*prev) { |
| @@ -1232,6 +1273,9 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno, | |||
| 1232 | if (dev_descr->optional) | 1273 | if (dev_descr->optional) |
| 1233 | return 0; | 1274 | return 0; |
| 1234 | 1275 | ||
| 1276 | if (devno == 0) | ||
| 1277 | return -ENODEV; | ||
| 1278 | |||
| 1235 | i7core_printk(KERN_ERR, | 1279 | i7core_printk(KERN_ERR, |
| 1236 | "Device not found: dev %02x.%d PCI ID %04x:%04x\n", | 1280 | "Device not found: dev %02x.%d PCI ID %04x:%04x\n", |
| 1237 | dev_descr->dev, dev_descr->func, | 1281 | dev_descr->dev, dev_descr->func, |
| @@ -1307,24 +1351,34 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno, | |||
| 1307 | return 0; | 1351 | return 0; |
| 1308 | } | 1352 | } |
| 1309 | 1353 | ||
| 1310 | static int i7core_get_devices(struct pci_id_descr dev_descr[], unsigned n_devs) | 1354 | static int i7core_get_devices(struct pci_id_table *table) |
| 1311 | { | 1355 | { |
| 1312 | int i, rc; | 1356 | int i, rc; |
| 1313 | struct pci_dev *pdev = NULL; | 1357 | struct pci_dev *pdev = NULL; |
| 1314 | 1358 | struct pci_id_descr *dev_descr; | |
| 1315 | for (i = 0; i < n_devs; i++) { | 1359 | |
| 1316 | pdev = NULL; | 1360 | while (table && table->descr) { |
| 1317 | do { | 1361 | dev_descr = table->descr; |
| 1318 | rc = i7core_get_onedevice(&pdev, i, &dev_descr[i], | 1362 | for (i = 0; i < table->n_devs; i++) { |
| 1319 | n_devs); | 1363 | pdev = NULL; |
| 1320 | if (rc < 0) { | 1364 | do { |
| 1321 | i7core_put_all_devices(); | 1365 | rc = i7core_get_onedevice(&pdev, i, &dev_descr[i], |
| 1322 | return -ENODEV; | 1366 | table->n_devs); |
| 1323 | } | 1367 | if (rc < 0) { |
| 1324 | } while (pdev); | 1368 | if (i == 0) { |
| 1369 | i = table->n_devs; | ||
| 1370 | break; | ||
| 1371 | } | ||
| 1372 | i7core_put_all_devices(); | ||
| 1373 | return -ENODEV; | ||
| 1374 | } | ||
| 1375 | } while (pdev); | ||
| 1376 | } | ||
| 1377 | table++; | ||
| 1325 | } | 1378 | } |
| 1326 | 1379 | ||
| 1327 | return 0; | 1380 | return 0; |
| 1381 | return 0; | ||
| 1328 | } | 1382 | } |
| 1329 | 1383 | ||
| 1330 | static int mci_bind_devs(struct mem_ctl_info *mci, | 1384 | static int mci_bind_devs(struct mem_ctl_info *mci, |
| @@ -1884,18 +1938,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, | |||
| 1884 | /* get the pci devices we want to reserve for our use */ | 1938 | /* get the pci devices we want to reserve for our use */ |
| 1885 | mutex_lock(&i7core_edac_lock); | 1939 | mutex_lock(&i7core_edac_lock); |
| 1886 | 1940 | ||
| 1887 | if (pdev->device == PCI_DEVICE_ID_INTEL_LYNNFIELD_QPI_LINK0) { | 1941 | rc = i7core_get_devices(pci_dev_table); |
| 1888 | printk(KERN_INFO "i7core_edac: detected a " | ||
| 1889 | "Lynnfield processor\n"); | ||
| 1890 | rc = i7core_get_devices(pci_dev_descr_lynnfield, | ||
| 1891 | ARRAY_SIZE(pci_dev_descr_lynnfield)); | ||
| 1892 | } else { | ||
| 1893 | printk(KERN_INFO "i7core_edac: detected a " | ||
| 1894 | "Nehalem/Nehalem-EP processor\n"); | ||
| 1895 | rc = i7core_get_devices(pci_dev_descr_i7core, | ||
| 1896 | ARRAY_SIZE(pci_dev_descr_i7core)); | ||
| 1897 | } | ||
| 1898 | |||
| 1899 | if (unlikely(rc < 0)) | 1942 | if (unlikely(rc < 0)) |
| 1900 | goto fail0; | 1943 | goto fail0; |
| 1901 | 1944 | ||
| @@ -1994,7 +2037,7 @@ static int __init i7core_init(void) | |||
| 1994 | /* Ensure that the OPSTATE is set correctly for POLL or NMI */ | 2037 | /* Ensure that the OPSTATE is set correctly for POLL or NMI */ |
| 1995 | opstate_init(); | 2038 | opstate_init(); |
| 1996 | 2039 | ||
| 1997 | i7core_xeon_pci_fixup(pci_dev_descr_i7core[0].dev_id); | 2040 | i7core_xeon_pci_fixup(pci_dev_table); |
| 1998 | 2041 | ||
| 1999 | pci_rc = pci_register_driver(&i7core_driver); | 2042 | pci_rc = pci_register_driver(&i7core_driver); |
| 2000 | 2043 | ||
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 46d76e985bac..413fab765a5f 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
| @@ -2567,6 +2567,22 @@ | |||
| 2567 | #define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_ADDR 0x2ca9 | 2567 | #define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_ADDR 0x2ca9 |
| 2568 | #define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_RANK 0x2caa | 2568 | #define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_RANK 0x2caa |
| 2569 | #define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_TC 0x2cab | 2569 | #define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_TC 0x2cab |
| 2570 | #define PCI_DEVICE_ID_INTEL_LYNNFIELD_MCR_REV2 0x2d98 | ||
| 2571 | #define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TAD_REV2 0x2d99 | ||
| 2572 | #define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_RAS_REV2 0x2d9a | ||
| 2573 | #define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TEST_REV2 0x2d9c | ||
| 2574 | #define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_CTRL_REV2 0x2da0 | ||
| 2575 | #define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_ADDR_REV2 0x2da1 | ||
| 2576 | #define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_RANK_REV2 0x2da2 | ||
| 2577 | #define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_TC_REV2 0x2da3 | ||
| 2578 | #define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_CTRL_REV2 0x2da8 | ||
| 2579 | #define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_ADDR_REV2 0x2da9 | ||
| 2580 | #define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_RANK_REV2 0x2daa | ||
| 2581 | #define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_TC_REV2 0x2dab | ||
| 2582 | #define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_CTRL_REV2 0x2db0 | ||
| 2583 | #define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_ADDR_REV2 0x2db1 | ||
| 2584 | #define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_RANK_REV2 0x2db2 | ||
| 2585 | #define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_TC_REV2 0x2db3 | ||
| 2570 | #define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340 | 2586 | #define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340 |
| 2571 | #define PCI_DEVICE_ID_INTEL_IOAT_TBG4 0x3429 | 2587 | #define PCI_DEVICE_ID_INTEL_IOAT_TBG4 0x3429 |
| 2572 | #define PCI_DEVICE_ID_INTEL_IOAT_TBG5 0x342a | 2588 | #define PCI_DEVICE_ID_INTEL_IOAT_TBG5 0x342a |
