aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/i7core_edac.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2009-10-14 07:02:40 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-10 10:49:31 -0400
commitde06eeef5809a69ff4daaae2bd63977e5404553d (patch)
tree2dab4c58d8837c35946e8f94d04d266607c4b1a3 /drivers/edac/i7core_edac.c
parentfd3826549db7f73d22b9c9abb80e01effb95c2ba (diff)
i7core_edac: Use a more generic approach for probing PCI devices
Currently, only one PCI set of tables is allowed. This prevents using the driver for other devices like Lynnfield, with have a different set of PCI ID's. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/edac/i7core_edac.c')
-rw-r--r--drivers/edac/i7core_edac.c79
1 files changed, 40 insertions, 39 deletions
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
index bb538dfbdc6..b6fce2e38e3 100644
--- a/drivers/edac/i7core_edac.c
+++ b/drivers/edac/i7core_edac.c
@@ -202,12 +202,14 @@ struct pci_id_descr {
202 int dev; 202 int dev;
203 int func; 203 int func;
204 int dev_id; 204 int dev_id;
205 int optional;
205}; 206};
206 207
207struct i7core_dev { 208struct i7core_dev {
208 struct list_head list; 209 struct list_head list;
209 u8 socket; 210 u8 socket;
210 struct pci_dev **pdev; 211 struct pci_dev **pdev;
212 int n_devs;
211 struct mem_ctl_info *mci; 213 struct mem_ctl_info *mci;
212}; 214};
213 215
@@ -259,11 +261,12 @@ static DEFINE_MUTEX(i7core_edac_lock);
259 .func = (function), \ 261 .func = (function), \
260 .dev_id = (device_id) 262 .dev_id = (device_id)
261 263
262struct pci_id_descr pci_dev_descr[] = { 264struct pci_id_descr pci_dev_descr_i7core[] = {
263 /* Memory controller */ 265 /* Memory controller */
264 { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_I7_MCR) }, 266 { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_I7_MCR) },
265 { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_I7_MC_TAD) }, 267 { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_I7_MC_TAD) },
266 { PCI_DESCR(3, 2, PCI_DEVICE_ID_INTEL_I7_MC_RAS) }, /* if RDIMM */ 268 /* Exists only for RDIMM */
269 { PCI_DESCR(3, 2, PCI_DEVICE_ID_INTEL_I7_MC_RAS), .optional = 1 },
267 { PCI_DESCR(3, 4, PCI_DEVICE_ID_INTEL_I7_MC_TEST) }, 270 { PCI_DESCR(3, 4, PCI_DEVICE_ID_INTEL_I7_MC_TEST) },
268 271
269 /* Channel 0 */ 272 /* Channel 0 */
@@ -294,7 +297,6 @@ struct pci_id_descr pci_dev_descr[] = {
294 { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_I7_NONCORE) }, 297 { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_I7_NONCORE) },
295 298
296}; 299};
297#define N_DEVS ARRAY_SIZE(pci_dev_descr)
298 300
299/* 301/*
300 * pci_device_id table for which devices we are looking for 302 * pci_device_id table for which devices we are looking for
@@ -380,7 +382,7 @@ static struct pci_dev *get_pdev_slot_func(u8 socket, unsigned slot,
380 if (!i7core_dev) 382 if (!i7core_dev)
381 return NULL; 383 return NULL;
382 384
383 for (i = 0; i < N_DEVS; i++) { 385 for (i = 0; i < i7core_dev->n_devs; i++) {
384 if (!i7core_dev->pdev[i]) 386 if (!i7core_dev->pdev[i])
385 continue; 387 continue;
386 388
@@ -1116,7 +1118,7 @@ static void i7core_put_devices(struct i7core_dev *i7core_dev)
1116 int i; 1118 int i;
1117 1119
1118 debugf0(__FILE__ ": %s()\n", __func__); 1120 debugf0(__FILE__ ": %s()\n", __func__);
1119 for (i = 0; i < N_DEVS; i++) { 1121 for (i = 0; i < i7core_dev->n_devs; i++) {
1120 struct pci_dev *pdev = i7core_dev->pdev[i]; 1122 struct pci_dev *pdev = i7core_dev->pdev[i];
1121 if (!pdev) 1123 if (!pdev)
1122 continue; 1124 continue;
@@ -1138,7 +1140,7 @@ static void i7core_put_all_devices(void)
1138 i7core_put_devices(i7core_dev); 1140 i7core_put_devices(i7core_dev);
1139} 1141}
1140 1142
1141static void i7core_xeon_pci_fixup(void) 1143static void i7core_xeon_pci_fixup(int dev_id)
1142{ 1144{
1143 struct pci_dev *pdev = NULL; 1145 struct pci_dev *pdev = NULL;
1144 int i; 1146 int i;
@@ -1147,8 +1149,7 @@ static void i7core_xeon_pci_fixup(void)
1147 * aren't announced by acpi. So, we need to use a legacy scan probing 1149 * aren't announced by acpi. So, we need to use a legacy scan probing
1148 * to detect them 1150 * to detect them
1149 */ 1151 */
1150 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 1152 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, dev_id, NULL);
1151 pci_dev_descr[0].dev_id, NULL);
1152 if (unlikely(!pdev)) { 1153 if (unlikely(!pdev)) {
1153 for (i = 0; i < MAX_SOCKET_BUSES; i++) 1154 for (i = 0; i < MAX_SOCKET_BUSES; i++)
1154 pcibios_scan_specific_bus(255-i); 1155 pcibios_scan_specific_bus(255-i);
@@ -1161,7 +1162,8 @@ static void i7core_xeon_pci_fixup(void)
1161 * 1162 *
1162 * Need to 'get' device 16 func 1 and func 2 1163 * Need to 'get' device 16 func 1 and func 2
1163 */ 1164 */
1164int i7core_get_onedevice(struct pci_dev **prev, int devno) 1165int i7core_get_onedevice(struct pci_dev **prev, int devno,
1166 struct pci_id_descr *dev_descr, unsigned n_devs)
1165{ 1167{
1166 struct i7core_dev *i7core_dev; 1168 struct i7core_dev *i7core_dev;
1167 1169
@@ -1170,14 +1172,14 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno)
1170 u8 socket = 0; 1172 u8 socket = 0;
1171 1173
1172 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 1174 pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
1173 pci_dev_descr[devno].dev_id, *prev); 1175 dev_descr->dev_id, *prev);
1174 1176
1175 /* 1177 /*
1176 * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core regs 1178 * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core regs
1177 * is at addr 8086:2c40, instead of 8086:2c41. So, we need 1179 * is at addr 8086:2c40, instead of 8086:2c41. So, we need
1178 * to probe for the alternate address in case of failure 1180 * to probe for the alternate address in case of failure
1179 */ 1181 */
1180 if (pci_dev_descr[devno].dev_id == PCI_DEVICE_ID_INTEL_I7_NONCORE && !pdev) 1182 if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_I7_NONCORE && !pdev)
1181 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 1183 pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
1182 PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT, *prev); 1184 PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT, *prev);
1183 1185
@@ -1187,19 +1189,13 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno)
1187 return 0; 1189 return 0;
1188 } 1190 }
1189 1191
1190 /* 1192 if (dev_descr->optional)
1191 * Dev 3 function 2 only exists on chips with RDIMMs
1192 * so, it is ok to not found it
1193 */
1194 if ((pci_dev_descr[devno].dev == 3) && (pci_dev_descr[devno].func == 2)) {
1195 *prev = pdev;
1196 return 0; 1193 return 0;
1197 }
1198 1194
1199 i7core_printk(KERN_ERR, 1195 i7core_printk(KERN_ERR,
1200 "Device not found: dev %02x.%d PCI ID %04x:%04x\n", 1196 "Device not found: dev %02x.%d PCI ID %04x:%04x\n",
1201 pci_dev_descr[devno].dev, pci_dev_descr[devno].func, 1197 dev_descr->dev, dev_descr->func,
1202 PCI_VENDOR_ID_INTEL, pci_dev_descr[devno].dev_id); 1198 PCI_VENDOR_ID_INTEL, dev_descr->dev_id);
1203 1199
1204 /* End of list, leave */ 1200 /* End of list, leave */
1205 return -ENODEV; 1201 return -ENODEV;
@@ -1216,11 +1212,12 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno)
1216 i7core_dev = kzalloc(sizeof(*i7core_dev), GFP_KERNEL); 1212 i7core_dev = kzalloc(sizeof(*i7core_dev), GFP_KERNEL);
1217 if (!i7core_dev) 1213 if (!i7core_dev)
1218 return -ENOMEM; 1214 return -ENOMEM;
1219 i7core_dev->pdev = kzalloc(sizeof(*i7core_dev->pdev) * N_DEVS, 1215 i7core_dev->pdev = kzalloc(sizeof(*i7core_dev->pdev) * n_devs,
1220 GFP_KERNEL); 1216 GFP_KERNEL);
1221 if (!i7core_dev->pdev) 1217 if (!i7core_dev->pdev)
1222 return -ENOMEM; 1218 return -ENOMEM;
1223 i7core_dev->socket = socket; 1219 i7core_dev->socket = socket;
1220 i7core_dev->n_devs = n_devs;
1224 list_add_tail(&i7core_dev->list, &i7core_edac_list); 1221 list_add_tail(&i7core_dev->list, &i7core_edac_list);
1225 } 1222 }
1226 1223
@@ -1228,8 +1225,8 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno)
1228 i7core_printk(KERN_ERR, 1225 i7core_printk(KERN_ERR,
1229 "Duplicated device for " 1226 "Duplicated device for "
1230 "dev %02x:%02x.%d PCI ID %04x:%04x\n", 1227 "dev %02x:%02x.%d PCI ID %04x:%04x\n",
1231 bus, pci_dev_descr[devno].dev, pci_dev_descr[devno].func, 1228 bus, dev_descr->dev, dev_descr->func,
1232 PCI_VENDOR_ID_INTEL, pci_dev_descr[devno].dev_id); 1229 PCI_VENDOR_ID_INTEL, dev_descr->dev_id);
1233 pci_dev_put(pdev); 1230 pci_dev_put(pdev);
1234 return -ENODEV; 1231 return -ENODEV;
1235 } 1232 }
@@ -1237,14 +1234,14 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno)
1237 i7core_dev->pdev[devno] = pdev; 1234 i7core_dev->pdev[devno] = pdev;
1238 1235
1239 /* Sanity check */ 1236 /* Sanity check */
1240 if (unlikely(PCI_SLOT(pdev->devfn) != pci_dev_descr[devno].dev || 1237 if (unlikely(PCI_SLOT(pdev->devfn) != dev_descr->dev ||
1241 PCI_FUNC(pdev->devfn) != pci_dev_descr[devno].func)) { 1238 PCI_FUNC(pdev->devfn) != dev_descr->func)) {
1242 i7core_printk(KERN_ERR, 1239 i7core_printk(KERN_ERR,
1243 "Device PCI ID %04x:%04x " 1240 "Device PCI ID %04x:%04x "
1244 "has dev %02x:%02x.%d instead of dev %02x:%02x.%d\n", 1241 "has dev %02x:%02x.%d instead of dev %02x:%02x.%d\n",
1245 PCI_VENDOR_ID_INTEL, pci_dev_descr[devno].dev_id, 1242 PCI_VENDOR_ID_INTEL, dev_descr->dev_id,
1246 bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), 1243 bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
1247 bus, pci_dev_descr[devno].dev, pci_dev_descr[devno].func); 1244 bus, dev_descr->dev, dev_descr->func);
1248 return -ENODEV; 1245 return -ENODEV;
1249 } 1246 }
1250 1247
@@ -1253,30 +1250,32 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno)
1253 i7core_printk(KERN_ERR, 1250 i7core_printk(KERN_ERR,
1254 "Couldn't enable " 1251 "Couldn't enable "
1255 "dev %02x:%02x.%d PCI ID %04x:%04x\n", 1252 "dev %02x:%02x.%d PCI ID %04x:%04x\n",
1256 bus, pci_dev_descr[devno].dev, pci_dev_descr[devno].func, 1253 bus, dev_descr->dev, dev_descr->func,
1257 PCI_VENDOR_ID_INTEL, pci_dev_descr[devno].dev_id); 1254 PCI_VENDOR_ID_INTEL, dev_descr->dev_id);
1258 return -ENODEV; 1255 return -ENODEV;
1259 } 1256 }
1260 1257
1261 debugf0("Detected socket %d dev %02x:%02x.%d PCI ID %04x:%04x\n", 1258 debugf0("Detected socket %d dev %02x:%02x.%d PCI ID %04x:%04x\n",
1262 socket, bus, pci_dev_descr[devno].dev, 1259 socket, bus, dev_descr->dev,
1263 pci_dev_descr[devno].func, 1260 dev_descr->func,
1264 PCI_VENDOR_ID_INTEL, pci_dev_descr[devno].dev_id); 1261 PCI_VENDOR_ID_INTEL, dev_descr->dev_id);
1265 1262
1266 *prev = pdev; 1263 *prev = pdev;
1267 1264
1268 return 0; 1265 return 0;
1269} 1266}
1270 1267
1271static int i7core_get_devices(void) 1268static int i7core_get_devices(struct pci_id_descr dev_descr[], unsigned n_devs)
1272{ 1269{
1273 int i; 1270 int i, rc;
1274 struct pci_dev *pdev = NULL; 1271 struct pci_dev *pdev = NULL;
1275 1272
1276 for (i = 0; i < N_DEVS; i++) { 1273 for (i = 0; i < n_devs; i++) {
1277 pdev = NULL; 1274 pdev = NULL;
1278 do { 1275 do {
1279 if (i7core_get_onedevice(&pdev, i) < 0) { 1276 rc = i7core_get_onedevice(&pdev, i, &dev_descr[i],
1277 n_devs);
1278 if (rc < 0) {
1280 i7core_put_all_devices(); 1279 i7core_put_all_devices();
1281 return -ENODEV; 1280 return -ENODEV;
1282 } 1281 }
@@ -1298,7 +1297,7 @@ static int mci_bind_devs(struct mem_ctl_info *mci,
1298 i7core_dev->mci = mci; 1297 i7core_dev->mci = mci;
1299 1298
1300 pvt->is_registered = 0; 1299 pvt->is_registered = 0;
1301 for (i = 0; i < N_DEVS; i++) { 1300 for (i = 0; i < i7core_dev->n_devs; i++) {
1302 pdev = i7core_dev->pdev[i]; 1301 pdev = i7core_dev->pdev[i];
1303 if (!pdev) 1302 if (!pdev)
1304 continue; 1303 continue;
@@ -1838,7 +1837,9 @@ static int __devinit i7core_probe(struct pci_dev *pdev,
1838 1837
1839 /* get the pci devices we want to reserve for our use */ 1838 /* get the pci devices we want to reserve for our use */
1840 mutex_lock(&i7core_edac_lock); 1839 mutex_lock(&i7core_edac_lock);
1841 rc = i7core_get_devices(); 1840
1841 rc = i7core_get_devices(pci_dev_descr_i7core,
1842 ARRAY_SIZE(pci_dev_descr_i7core));
1842 if (unlikely(rc < 0)) 1843 if (unlikely(rc < 0))
1843 goto fail0; 1844 goto fail0;
1844 1845
@@ -1937,7 +1938,7 @@ static int __init i7core_init(void)
1937 /* Ensure that the OPSTATE is set correctly for POLL or NMI */ 1938 /* Ensure that the OPSTATE is set correctly for POLL or NMI */
1938 opstate_init(); 1939 opstate_init();
1939 1940
1940 i7core_xeon_pci_fixup(); 1941 i7core_xeon_pci_fixup(pci_dev_descr_i7core[0].dev_id);
1941 1942
1942 pci_rc = pci_register_driver(&i7core_driver); 1943 pci_rc = pci_register_driver(&i7core_driver);
1943 1944