diff options
| author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-10-14 07:02:40 -0400 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-10 10:49:31 -0400 |
| commit | de06eeef5809a69ff4daaae2bd63977e5404553d (patch) | |
| tree | 2dab4c58d8837c35946e8f94d04d266607c4b1a3 | |
| parent | fd3826549db7f73d22b9c9abb80e01effb95c2ba (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>
| -rw-r--r-- | drivers/edac/i7core_edac.c | 79 |
1 files changed, 40 insertions, 39 deletions
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index bb538dfbdc6c..b6fce2e38e3d 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 | ||
| 207 | struct i7core_dev { | 208 | struct 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 | ||
| 262 | struct pci_id_descr pci_dev_descr[] = { | 264 | struct 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 | ||
| 1141 | static void i7core_xeon_pci_fixup(void) | 1143 | static 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 | */ |
| 1164 | int i7core_get_onedevice(struct pci_dev **prev, int devno) | 1165 | int 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 | ||
| 1271 | static int i7core_get_devices(void) | 1268 | static 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 | ||
