diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-09-04 23:52:11 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-10 10:44:58 -0400 |
commit | 66607706cee7b6901aa0509198f075859c93ec6a (patch) | |
tree | b55e025bd7149ed9d00f38e596dc94e1f3909b95 /drivers/edac | |
parent | a55456f3446d19853af54b64b3840312f46b6ea5 (diff) |
Dynamically allocate memory for PCI devices
Instead of using a static table assuming always 2 CPU sockets, allocate
space dynamically for Nehalem PCI devs.
This patch is part of a series of patches that changes i7core_edac to
allow more than 2 sockets and to properly report one memory controller
per socket.
Diffstat (limited to 'drivers/edac')
-rw-r--r-- | drivers/edac/i7core_edac.c | 175 |
1 files changed, 114 insertions, 61 deletions
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index af222ffcfdfc..7bcb5993b501 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c | |||
@@ -192,10 +192,9 @@ struct i7core_channel { | |||
192 | }; | 192 | }; |
193 | 193 | ||
194 | struct pci_id_descr { | 194 | struct pci_id_descr { |
195 | int dev; | 195 | int dev; |
196 | int func; | 196 | int func; |
197 | int dev_id; | 197 | int dev_id; |
198 | struct pci_dev *pdev[NUM_SOCKETS]; | ||
199 | }; | 198 | }; |
200 | 199 | ||
201 | struct i7core_pvt { | 200 | struct i7core_pvt { |
@@ -229,6 +228,17 @@ struct i7core_pvt { | |||
229 | spinlock_t mce_lock; | 228 | spinlock_t mce_lock; |
230 | }; | 229 | }; |
231 | 230 | ||
231 | struct i7core_dev { | ||
232 | struct list_head list; | ||
233 | |||
234 | int socket; | ||
235 | struct pci_dev **pdev; | ||
236 | }; | ||
237 | |||
238 | /* Static vars */ | ||
239 | static LIST_HEAD(i7core_edac_list); | ||
240 | static DEFINE_MUTEX(i7core_edac_lock); | ||
241 | |||
232 | /* Device name and register DID (Device ID) */ | 242 | /* Device name and register DID (Device ID) */ |
233 | struct i7core_dev_info { | 243 | struct i7core_dev_info { |
234 | const char *ctl_name; /* name for this device */ | 244 | const char *ctl_name; /* name for this device */ |
@@ -240,7 +250,7 @@ struct i7core_dev_info { | |||
240 | .func = (function), \ | 250 | .func = (function), \ |
241 | .dev_id = (device_id) | 251 | .dev_id = (device_id) |
242 | 252 | ||
243 | struct pci_id_descr pci_devs[] = { | 253 | struct pci_id_descr pci_dev_descr[] = { |
244 | /* Memory controller */ | 254 | /* Memory controller */ |
245 | { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_I7_MCR) }, | 255 | { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_I7_MCR) }, |
246 | { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_I7_MC_TAD) }, | 256 | { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_I7_MC_TAD) }, |
@@ -275,11 +285,10 @@ struct pci_id_descr pci_devs[] = { | |||
275 | { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_I7_NOCORE) }, | 285 | { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_I7_NOCORE) }, |
276 | 286 | ||
277 | }; | 287 | }; |
278 | #define N_DEVS ARRAY_SIZE(pci_devs) | 288 | #define N_DEVS ARRAY_SIZE(pci_dev_descr) |
279 | 289 | ||
280 | /* | 290 | /* |
281 | * pci_device_id table for which devices we are looking for | 291 | * pci_device_id table for which devices we are looking for |
282 | * This should match the first device at pci_devs table | ||
283 | */ | 292 | */ |
284 | static const struct pci_device_id i7core_pci_tbl[] __devinitdata = { | 293 | static const struct pci_device_id i7core_pci_tbl[] __devinitdata = { |
285 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_X58_HUB_MGMT)}, | 294 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_X58_HUB_MGMT)}, |
@@ -288,7 +297,7 @@ static const struct pci_device_id i7core_pci_tbl[] __devinitdata = { | |||
288 | 297 | ||
289 | 298 | ||
290 | /* Table of devices attributes supported by this driver */ | 299 | /* Table of devices attributes supported by this driver */ |
291 | static const struct i7core_dev_info i7core_devs[] = { | 300 | static const struct i7core_dev_info i7core_probe_devs[] = { |
292 | { | 301 | { |
293 | .ctl_name = "i7 Core", | 302 | .ctl_name = "i7 Core", |
294 | .fsb_mapping_errors = PCI_DEVICE_ID_INTEL_I7_MCR, | 303 | .fsb_mapping_errors = PCI_DEVICE_ID_INTEL_I7_MCR, |
@@ -347,21 +356,37 @@ static inline int numcol(u32 col) | |||
347 | return cols[col & 0x3]; | 356 | return cols[col & 0x3]; |
348 | } | 357 | } |
349 | 358 | ||
359 | static struct i7core_dev *get_i7core_dev(int socket) | ||
360 | { | ||
361 | struct i7core_dev *i7core_dev; | ||
362 | |||
363 | list_for_each_entry(i7core_dev, &i7core_edac_list, list) { | ||
364 | if (i7core_dev->socket == socket) | ||
365 | return i7core_dev; | ||
366 | } | ||
367 | |||
368 | return NULL; | ||
369 | } | ||
370 | |||
350 | /**************************************************************************** | 371 | /**************************************************************************** |
351 | Memory check routines | 372 | Memory check routines |
352 | ****************************************************************************/ | 373 | ****************************************************************************/ |
353 | static struct pci_dev *get_pdev_slot_func(u8 socket, unsigned slot, | 374 | static struct pci_dev *get_pdev_slot_func(u8 socket, unsigned slot, |
354 | unsigned func) | 375 | unsigned func) |
355 | { | 376 | { |
377 | struct i7core_dev *i7core_dev = get_i7core_dev(socket); | ||
356 | int i; | 378 | int i; |
357 | 379 | ||
380 | if (!i7core_dev) | ||
381 | return NULL; | ||
382 | |||
358 | for (i = 0; i < N_DEVS; i++) { | 383 | for (i = 0; i < N_DEVS; i++) { |
359 | if (!pci_devs[i].pdev[socket]) | 384 | if (!i7core_dev->pdev[i]) |
360 | continue; | 385 | continue; |
361 | 386 | ||
362 | if (PCI_SLOT(pci_devs[i].pdev[socket]->devfn) == slot && | 387 | if (PCI_SLOT(i7core_dev->pdev[i]->devfn) == slot && |
363 | PCI_FUNC(pci_devs[i].pdev[socket]->devfn) == func) { | 388 | PCI_FUNC(i7core_dev->pdev[i]->devfn) == func) { |
364 | return pci_devs[i].pdev[socket]; | 389 | return i7core_dev->pdev[i]; |
365 | } | 390 | } |
366 | } | 391 | } |
367 | 392 | ||
@@ -1153,9 +1178,18 @@ static void i7core_put_devices(void) | |||
1153 | { | 1178 | { |
1154 | int i, j; | 1179 | int i, j; |
1155 | 1180 | ||
1156 | for (i = 0; i < NUM_SOCKETS; i++) | 1181 | for (i = 0; i < NUM_SOCKETS; i++) { |
1182 | struct i7core_dev *i7core_dev = get_i7core_dev(i); | ||
1183 | if (!i7core_dev) | ||
1184 | continue; | ||
1185 | |||
1157 | for (j = 0; j < N_DEVS; j++) | 1186 | for (j = 0; j < N_DEVS; j++) |
1158 | pci_dev_put(pci_devs[j].pdev[i]); | 1187 | pci_dev_put(i7core_dev->pdev[j]); |
1188 | |||
1189 | list_del(&i7core_dev->list); | ||
1190 | kfree(i7core_dev->pdev); | ||
1191 | kfree(i7core_dev); | ||
1192 | } | ||
1159 | } | 1193 | } |
1160 | 1194 | ||
1161 | static void i7core_xeon_pci_fixup(void) | 1195 | static void i7core_xeon_pci_fixup(void) |
@@ -1168,7 +1202,7 @@ static void i7core_xeon_pci_fixup(void) | |||
1168 | * to detect them | 1202 | * to detect them |
1169 | */ | 1203 | */ |
1170 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, | 1204 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, |
1171 | pci_devs[0].dev_id, NULL); | 1205 | pci_dev_descr[0].dev_id, NULL); |
1172 | if (unlikely(!pdev)) { | 1206 | if (unlikely(!pdev)) { |
1173 | for (i = 0; i < NUM_SOCKETS; i ++) | 1207 | for (i = 0; i < NUM_SOCKETS; i ++) |
1174 | pcibios_scan_specific_bus(255-i); | 1208 | pcibios_scan_specific_bus(255-i); |
@@ -1183,19 +1217,21 @@ static void i7core_xeon_pci_fixup(void) | |||
1183 | */ | 1217 | */ |
1184 | int i7core_get_onedevice(struct pci_dev **prev, int devno) | 1218 | int i7core_get_onedevice(struct pci_dev **prev, int devno) |
1185 | { | 1219 | { |
1220 | struct i7core_dev *i7core_dev; | ||
1221 | |||
1186 | struct pci_dev *pdev = NULL; | 1222 | struct pci_dev *pdev = NULL; |
1187 | u8 bus = 0; | 1223 | u8 bus = 0; |
1188 | u8 socket = 0; | 1224 | u8 socket = 0; |
1189 | 1225 | ||
1190 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, | 1226 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, |
1191 | pci_devs[devno].dev_id, *prev); | 1227 | pci_dev_descr[devno].dev_id, *prev); |
1192 | 1228 | ||
1193 | /* | 1229 | /* |
1194 | * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core regs | 1230 | * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core regs |
1195 | * is at addr 8086:2c40, instead of 8086:2c41. So, we need | 1231 | * is at addr 8086:2c40, instead of 8086:2c41. So, we need |
1196 | * to probe for the alternate address in case of failure | 1232 | * to probe for the alternate address in case of failure |
1197 | */ | 1233 | */ |
1198 | if (pci_devs[devno].dev_id == PCI_DEVICE_ID_INTEL_I7_NOCORE && !pdev) | 1234 | if (pci_dev_descr[devno].dev_id == PCI_DEVICE_ID_INTEL_I7_NOCORE && !pdev) |
1199 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, | 1235 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, |
1200 | PCI_DEVICE_ID_INTEL_I7_NOCORE_ALT, *prev); | 1236 | PCI_DEVICE_ID_INTEL_I7_NOCORE_ALT, *prev); |
1201 | 1237 | ||
@@ -1209,15 +1245,15 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno) | |||
1209 | * Dev 3 function 2 only exists on chips with RDIMMs | 1245 | * Dev 3 function 2 only exists on chips with RDIMMs |
1210 | * so, it is ok to not found it | 1246 | * so, it is ok to not found it |
1211 | */ | 1247 | */ |
1212 | if ((pci_devs[devno].dev == 3) && (pci_devs[devno].func == 2)) { | 1248 | if ((pci_dev_descr[devno].dev == 3) && (pci_dev_descr[devno].func == 2)) { |
1213 | *prev = pdev; | 1249 | *prev = pdev; |
1214 | return 0; | 1250 | return 0; |
1215 | } | 1251 | } |
1216 | 1252 | ||
1217 | i7core_printk(KERN_ERR, | 1253 | i7core_printk(KERN_ERR, |
1218 | "Device not found: dev %02x.%d PCI ID %04x:%04x\n", | 1254 | "Device not found: dev %02x.%d PCI ID %04x:%04x\n", |
1219 | pci_devs[devno].dev, pci_devs[devno].func, | 1255 | pci_dev_descr[devno].dev, pci_dev_descr[devno].func, |
1220 | PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id); | 1256 | PCI_VENDOR_ID_INTEL, pci_dev_descr[devno].dev_id); |
1221 | 1257 | ||
1222 | /* End of list, leave */ | 1258 | /* End of list, leave */ |
1223 | return -ENODEV; | 1259 | return -ENODEV; |
@@ -1229,37 +1265,40 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno) | |||
1229 | else | 1265 | else |
1230 | socket = 255 - bus; | 1266 | socket = 255 - bus; |
1231 | 1267 | ||
1232 | if (socket >= NUM_SOCKETS) { | 1268 | i7core_dev = get_i7core_dev(socket); |
1233 | i7core_printk(KERN_ERR, | 1269 | if (!i7core_dev) { |
1234 | "Unexpected socket for " | 1270 | i7core_dev = kzalloc(sizeof(*i7core_dev), GFP_KERNEL); |
1235 | "dev %02x:%02x.%d PCI ID %04x:%04x\n", | 1271 | if (!i7core_dev) |
1236 | bus, pci_devs[devno].dev, pci_devs[devno].func, | 1272 | return -ENOMEM; |
1237 | PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id); | 1273 | i7core_dev->pdev = kzalloc(sizeof(*i7core_dev->pdev) * N_DEVS, |
1238 | pci_dev_put(pdev); | 1274 | GFP_KERNEL); |
1239 | return -ENODEV; | 1275 | if (!i7core_dev->pdev) |
1276 | return -ENOMEM; | ||
1277 | i7core_dev->socket = socket; | ||
1278 | list_add_tail(&i7core_dev->list, &i7core_edac_list); | ||
1240 | } | 1279 | } |
1241 | 1280 | ||
1242 | if (pci_devs[devno].pdev[socket]) { | 1281 | if (i7core_dev->pdev[devno]) { |
1243 | i7core_printk(KERN_ERR, | 1282 | i7core_printk(KERN_ERR, |
1244 | "Duplicated device for " | 1283 | "Duplicated device for " |
1245 | "dev %02x:%02x.%d PCI ID %04x:%04x\n", | 1284 | "dev %02x:%02x.%d PCI ID %04x:%04x\n", |
1246 | bus, pci_devs[devno].dev, pci_devs[devno].func, | 1285 | bus, pci_dev_descr[devno].dev, pci_dev_descr[devno].func, |
1247 | PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id); | 1286 | PCI_VENDOR_ID_INTEL, pci_dev_descr[devno].dev_id); |
1248 | pci_dev_put(pdev); | 1287 | pci_dev_put(pdev); |
1249 | return -ENODEV; | 1288 | return -ENODEV; |
1250 | } | 1289 | } |
1251 | 1290 | ||
1252 | pci_devs[devno].pdev[socket] = pdev; | 1291 | i7core_dev->pdev[devno] = pdev; |
1253 | 1292 | ||
1254 | /* Sanity check */ | 1293 | /* Sanity check */ |
1255 | if (unlikely(PCI_SLOT(pdev->devfn) != pci_devs[devno].dev || | 1294 | if (unlikely(PCI_SLOT(pdev->devfn) != pci_dev_descr[devno].dev || |
1256 | PCI_FUNC(pdev->devfn) != pci_devs[devno].func)) { | 1295 | PCI_FUNC(pdev->devfn) != pci_dev_descr[devno].func)) { |
1257 | i7core_printk(KERN_ERR, | 1296 | i7core_printk(KERN_ERR, |
1258 | "Device PCI ID %04x:%04x " | 1297 | "Device PCI ID %04x:%04x " |
1259 | "has dev %02x:%02x.%d instead of dev %02x:%02x.%d\n", | 1298 | "has dev %02x:%02x.%d instead of dev %02x:%02x.%d\n", |
1260 | PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id, | 1299 | PCI_VENDOR_ID_INTEL, pci_dev_descr[devno].dev_id, |
1261 | bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), | 1300 | bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), |
1262 | bus, pci_devs[devno].dev, pci_devs[devno].func); | 1301 | bus, pci_dev_descr[devno].dev, pci_dev_descr[devno].func); |
1263 | return -ENODEV; | 1302 | return -ENODEV; |
1264 | } | 1303 | } |
1265 | 1304 | ||
@@ -1268,27 +1307,29 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno) | |||
1268 | i7core_printk(KERN_ERR, | 1307 | i7core_printk(KERN_ERR, |
1269 | "Couldn't enable " | 1308 | "Couldn't enable " |
1270 | "dev %02x:%02x.%d PCI ID %04x:%04x\n", | 1309 | "dev %02x:%02x.%d PCI ID %04x:%04x\n", |
1271 | bus, pci_devs[devno].dev, pci_devs[devno].func, | 1310 | bus, pci_dev_descr[devno].dev, pci_dev_descr[devno].func, |
1272 | PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id); | 1311 | PCI_VENDOR_ID_INTEL, pci_dev_descr[devno].dev_id); |
1273 | return -ENODEV; | 1312 | return -ENODEV; |
1274 | } | 1313 | } |
1275 | 1314 | ||
1276 | i7core_printk(KERN_INFO, | 1315 | i7core_printk(KERN_INFO, |
1277 | "Registered socket %d " | 1316 | "Registered socket %d " |
1278 | "dev %02x:%02x.%d PCI ID %04x:%04x\n", | 1317 | "dev %02x:%02x.%d PCI ID %04x:%04x\n", |
1279 | socket, bus, pci_devs[devno].dev, pci_devs[devno].func, | 1318 | socket, bus, pci_dev_descr[devno].dev, pci_dev_descr[devno].func, |
1280 | PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id); | 1319 | PCI_VENDOR_ID_INTEL, pci_dev_descr[devno].dev_id); |
1281 | 1320 | ||
1282 | *prev = pdev; | 1321 | *prev = pdev; |
1283 | 1322 | ||
1284 | return 0; | 1323 | return 0; |
1285 | } | 1324 | } |
1286 | 1325 | ||
1287 | static int i7core_get_devices(void) | 1326 | static int i7core_get_devices(u8 *sockets) |
1288 | { | 1327 | { |
1289 | int i; | 1328 | int i; |
1290 | struct pci_dev *pdev = NULL; | 1329 | struct pci_dev *pdev = NULL; |
1330 | struct i7core_dev *i7core_dev = NULL; | ||
1291 | 1331 | ||
1332 | *sockets = 0; | ||
1292 | for (i = 0; i < N_DEVS; i++) { | 1333 | for (i = 0; i < N_DEVS; i++) { |
1293 | pdev = NULL; | 1334 | pdev = NULL; |
1294 | do { | 1335 | do { |
@@ -1298,6 +1339,12 @@ static int i7core_get_devices(void) | |||
1298 | } | 1339 | } |
1299 | } while (pdev); | 1340 | } while (pdev); |
1300 | } | 1341 | } |
1342 | |||
1343 | list_for_each_entry(i7core_dev, &i7core_edac_list, list) { | ||
1344 | if (i7core_dev->socket + 1 > *sockets) | ||
1345 | *sockets = i7core_dev->socket + 1; | ||
1346 | } | ||
1347 | |||
1301 | return 0; | 1348 | return 0; |
1302 | } | 1349 | } |
1303 | 1350 | ||
@@ -1307,11 +1354,15 @@ static int mci_bind_devs(struct mem_ctl_info *mci) | |||
1307 | struct pci_dev *pdev; | 1354 | struct pci_dev *pdev; |
1308 | int i, j, func, slot; | 1355 | int i, j, func, slot; |
1309 | 1356 | ||
1310 | |||
1311 | for (i = 0; i < pvt->sockets; i++) { | 1357 | for (i = 0; i < pvt->sockets; i++) { |
1358 | struct i7core_dev *i7core_dev = get_i7core_dev(i); | ||
1359 | |||
1360 | if (!i7core_dev) | ||
1361 | continue; | ||
1362 | |||
1312 | pvt->is_registered[i] = 0; | 1363 | pvt->is_registered[i] = 0; |
1313 | for (j = 0; j < N_DEVS; j++) { | 1364 | for (j = 0; j < N_DEVS; j++) { |
1314 | pdev = pci_devs[j].pdev[i]; | 1365 | pdev = i7core_dev->pdev[j]; |
1315 | if (!pdev) | 1366 | if (!pdev) |
1316 | continue; | 1367 | continue; |
1317 | 1368 | ||
@@ -1723,20 +1774,17 @@ static int __devinit i7core_probe(struct pci_dev *pdev, | |||
1723 | int rc, i; | 1774 | int rc, i; |
1724 | u8 sockets; | 1775 | u8 sockets; |
1725 | 1776 | ||
1726 | if (unlikely(dev_idx >= ARRAY_SIZE(i7core_devs))) | 1777 | /* |
1778 | * FIXME: All memory controllers are allocated at the first pass. | ||
1779 | */ | ||
1780 | if (unlikely(dev_idx >= 1)) | ||
1727 | return -EINVAL; | 1781 | return -EINVAL; |
1728 | 1782 | ||
1729 | /* get the pci devices we want to reserve for our use */ | 1783 | /* get the pci devices we want to reserve for our use */ |
1730 | rc = i7core_get_devices(); | 1784 | mutex_lock(&i7core_edac_lock); |
1785 | rc = i7core_get_devices(&sockets); | ||
1731 | if (unlikely(rc < 0)) | 1786 | if (unlikely(rc < 0)) |
1732 | return rc; | 1787 | goto fail0; |
1733 | |||
1734 | sockets = 1; | ||
1735 | for (i = NUM_SOCKETS - 1; i > 0; i--) | ||
1736 | if (pci_devs[0].pdev[i]) { | ||
1737 | sockets = i + 1; | ||
1738 | break; | ||
1739 | } | ||
1740 | 1788 | ||
1741 | for (i = 0; i < sockets; i++) { | 1789 | for (i = 0; i < sockets; i++) { |
1742 | int channels; | 1790 | int channels; |
@@ -1745,7 +1793,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, | |||
1745 | /* Check the number of active and not disabled channels */ | 1793 | /* Check the number of active and not disabled channels */ |
1746 | rc = i7core_get_active_channels(i, &channels, &csrows); | 1794 | rc = i7core_get_active_channels(i, &channels, &csrows); |
1747 | if (unlikely(rc < 0)) | 1795 | if (unlikely(rc < 0)) |
1748 | goto fail0; | 1796 | goto fail1; |
1749 | 1797 | ||
1750 | num_channels += channels; | 1798 | num_channels += channels; |
1751 | num_csrows += csrows; | 1799 | num_csrows += csrows; |
@@ -1755,7 +1803,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, | |||
1755 | mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, 0); | 1803 | mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, 0); |
1756 | if (unlikely(!mci)) { | 1804 | if (unlikely(!mci)) { |
1757 | rc = -ENOMEM; | 1805 | rc = -ENOMEM; |
1758 | goto fail0; | 1806 | goto fail1; |
1759 | } | 1807 | } |
1760 | 1808 | ||
1761 | debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci); | 1809 | debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci); |
@@ -1776,7 +1824,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, | |||
1776 | mci->edac_cap = EDAC_FLAG_NONE; | 1824 | mci->edac_cap = EDAC_FLAG_NONE; |
1777 | mci->mod_name = "i7core_edac.c"; | 1825 | mci->mod_name = "i7core_edac.c"; |
1778 | mci->mod_ver = I7CORE_REVISION; | 1826 | mci->mod_ver = I7CORE_REVISION; |
1779 | mci->ctl_name = i7core_devs[dev_idx].ctl_name; | 1827 | mci->ctl_name = i7core_probe_devs[dev_idx].ctl_name; |
1780 | mci->dev_name = pci_name(pdev); | 1828 | mci->dev_name = pci_name(pdev); |
1781 | mci->ctl_page_to_phys = NULL; | 1829 | mci->ctl_page_to_phys = NULL; |
1782 | mci->mc_driver_sysfs_attributes = i7core_inj_attrs; | 1830 | mci->mc_driver_sysfs_attributes = i7core_inj_attrs; |
@@ -1786,7 +1834,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, | |||
1786 | /* Store pci devices at mci for faster access */ | 1834 | /* Store pci devices at mci for faster access */ |
1787 | rc = mci_bind_devs(mci); | 1835 | rc = mci_bind_devs(mci); |
1788 | if (unlikely(rc < 0)) | 1836 | if (unlikely(rc < 0)) |
1789 | goto fail1; | 1837 | goto fail2; |
1790 | 1838 | ||
1791 | /* Get dimm basic config */ | 1839 | /* Get dimm basic config */ |
1792 | for (i = 0; i < sockets; i++) | 1840 | for (i = 0; i < sockets; i++) |
@@ -1801,7 +1849,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, | |||
1801 | */ | 1849 | */ |
1802 | 1850 | ||
1803 | rc = -EINVAL; | 1851 | rc = -EINVAL; |
1804 | goto fail1; | 1852 | goto fail2; |
1805 | } | 1853 | } |
1806 | 1854 | ||
1807 | /* allocating generic PCI control info */ | 1855 | /* allocating generic PCI control info */ |
@@ -1832,18 +1880,21 @@ static int __devinit i7core_probe(struct pci_dev *pdev, | |||
1832 | if (unlikely(rc < 0)) { | 1880 | if (unlikely(rc < 0)) { |
1833 | debugf0("MC: " __FILE__ | 1881 | debugf0("MC: " __FILE__ |
1834 | ": %s(): failed edac_mce_register()\n", __func__); | 1882 | ": %s(): failed edac_mce_register()\n", __func__); |
1835 | goto fail1; | 1883 | goto fail2; |
1836 | } | 1884 | } |
1837 | 1885 | ||
1838 | i7core_printk(KERN_INFO, "Driver loaded.\n"); | 1886 | i7core_printk(KERN_INFO, "Driver loaded.\n"); |
1839 | 1887 | ||
1888 | mutex_unlock(&i7core_edac_lock); | ||
1840 | return 0; | 1889 | return 0; |
1841 | 1890 | ||
1842 | fail1: | 1891 | fail2: |
1843 | edac_mc_free(mci); | 1892 | edac_mc_free(mci); |
1844 | 1893 | ||
1845 | fail0: | 1894 | fail1: |
1846 | i7core_put_devices(); | 1895 | i7core_put_devices(); |
1896 | fail0: | ||
1897 | mutex_unlock(&i7core_edac_lock); | ||
1847 | return rc; | 1898 | return rc; |
1848 | } | 1899 | } |
1849 | 1900 | ||
@@ -1871,7 +1922,9 @@ static void __devexit i7core_remove(struct pci_dev *pdev) | |||
1871 | edac_mce_unregister(&pvt->edac_mce); | 1922 | edac_mce_unregister(&pvt->edac_mce); |
1872 | 1923 | ||
1873 | /* retrieve references to resources, and free those resources */ | 1924 | /* retrieve references to resources, and free those resources */ |
1925 | mutex_lock(&i7core_edac_lock); | ||
1874 | i7core_put_devices(); | 1926 | i7core_put_devices(); |
1927 | mutex_unlock(&i7core_edac_lock); | ||
1875 | 1928 | ||
1876 | edac_mc_free(mci); | 1929 | edac_mc_free(mci); |
1877 | } | 1930 | } |