aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/i7core_edac.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2009-07-18 09:43:08 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-10 10:44:53 -0400
commitc77720b9544d8825ff5b9546d0ee038cfa4d4eb2 (patch)
tree001c9d4e741821e920bbc6eba4a3f9a8e738ddc6 /drivers/edac/i7core_edac.c
parenta639539fa28531924c6b5e0f3963cc63d060947d (diff)
i7core: fix get_devices routine for Xeon55xx
i7core_get_devices() were preparet to get just the first found device of each type. Due to that, on Xeon 55xx, only socket 1 were retrived. Rework i7core_get_devices() to clean it and to properly support Xeon 55xx. While here, fix a small typo. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/edac/i7core_edac.c')
-rw-r--r--drivers/edac/i7core_edac.c186
1 files changed, 108 insertions, 78 deletions
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
index 9f39d3d5502..79636b58ec5 100644
--- a/drivers/edac/i7core_edac.c
+++ b/drivers/edac/i7core_edac.c
@@ -410,7 +410,7 @@ static int i7core_get_active_channels(u8 socket, unsigned *channels,
410 } 410 }
411 } 411 }
412 412
413 debugf0("Number of active channels on socked %d: %d\n", 413 debugf0("Number of active channels on socket %d: %d\n",
414 socket, *channels); 414 socket, *channels);
415 415
416 return 0; 416 return 0;
@@ -1126,107 +1126,137 @@ static void i7core_put_devices(void)
1126 * 1126 *
1127 * Need to 'get' device 16 func 1 and func 2 1127 * Need to 'get' device 16 func 1 and func 2
1128 */ 1128 */
1129static int i7core_get_devices(void) 1129int i7core_get_onedevice(struct pci_dev **prev, int devno)
1130{ 1130{
1131 int rc, i;
1132 struct pci_dev *pdev = NULL; 1131 struct pci_dev *pdev = NULL;
1133 u8 bus = 0; 1132 u8 bus = 0;
1134 u8 socket = 0; 1133 u8 socket = 0;
1135 1134
1136 for (i = 0; i < N_DEVS; i++) { 1135 pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
1136 pci_devs[devno].dev_id, *prev);
1137
1138 /*
1139 * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core pci buses
1140 * aren't announced by acpi. So, we need to use a legacy scan probing
1141 * to detect them
1142 */
1143 if (unlikely(!pdev && !devno && !prev)) {
1144 pcibios_scan_specific_bus(254);
1145 pcibios_scan_specific_bus(255);
1146
1137 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 1147 pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
1138 pci_devs[i].dev_id, NULL); 1148 pci_devs[devno].dev_id, *prev);
1149 }
1139 1150
1140 if (!pdev && !i) { 1151 /*
1141 pcibios_scan_specific_bus(254); 1152 * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core regs
1142 pcibios_scan_specific_bus(255); 1153 * is at addr 8086:2c40, instead of 8086:2c41. So, we need
1154 * to probe for the alternate address in case of failure
1155 */
1156 if (pci_devs[devno].dev_id == PCI_DEVICE_ID_INTEL_I7_NOCORE && !pdev)
1157 pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
1158 PCI_DEVICE_ID_INTEL_I7_NOCORE_ALT, *prev);
1143 1159
1144 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 1160 if (!pdev) {
1145 pci_devs[i].dev_id, NULL); 1161 if (*prev) {
1162 *prev = pdev;
1163 return 0;
1146 } 1164 }
1147 1165
1148 /* 1166 /*
1149 * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core regs 1167 * Dev 3 function 2 only exists on chips with RDIMMs
1150 * is at addr 8086:2c40, instead of 8086:2c41. So, we need 1168 * so, it is ok to not found it
1151 * to probe for the alternate address in case of failure
1152 */ 1169 */
1153 if (pci_devs[i].dev_id == PCI_DEVICE_ID_INTEL_I7_NOCORE 1170 if ((pci_devs[devno].dev == 3) && (pci_devs[devno].func == 2)) {
1154 && !pdev) 1171 *prev = pdev;
1155 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 1172 return 0;
1156 PCI_DEVICE_ID_INTEL_I7_NOCORE_ALT, NULL); 1173 }
1157 1174
1158 if (likely(pdev)) { 1175 i7core_printk(KERN_ERR,
1159 bus = pdev->bus->number; 1176 "Device not found: dev %02x.%d PCI ID %04x:%04x\n",
1177 pci_devs[devno].dev, pci_devs[devno].func,
1178 PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id);
1160 1179
1161 if (bus == 0x3f) 1180 /* End of list, leave */
1162 socket = 0; 1181 return -ENODEV;
1163 else 1182 }
1164 socket = 255 - bus; 1183 bus = pdev->bus->number;
1165 1184
1166 if (socket >= NUM_SOCKETS) { 1185 if (bus == 0x3f)
1167 i7core_printk(KERN_ERR, 1186 socket = 0;
1168 "Found unexpected socket for " 1187 else
1169 "dev %02x:%02x.%d PCI ID %04x:%04x\n", 1188 socket = 255 - bus;
1170 bus, pci_devs[i].dev, pci_devs[i].func, 1189
1171 PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id); 1190 if (socket >= NUM_SOCKETS) {
1191 i7core_printk(KERN_ERR,
1192 "Unexpected socket for "
1193 "dev %02x:%02x.%d PCI ID %04x:%04x\n",
1194 bus, pci_devs[devno].dev, pci_devs[devno].func,
1195 PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id);
1196 pci_dev_put(pdev);
1197 return -ENODEV;
1198 }
1172 1199
1173 rc = -ENODEV; 1200 if (pci_devs[devno].pdev[socket]) {
1174 goto error; 1201 i7core_printk(KERN_ERR,
1175 } 1202 "Duplicated device for "
1203 "dev %02x:%02x.%d PCI ID %04x:%04x\n",
1204 bus, pci_devs[devno].dev, pci_devs[devno].func,
1205 PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id);
1206 pci_dev_put(pdev);
1207 return -ENODEV;
1208 }
1176 1209
1177 pci_devs[i].pdev[socket] = pdev; 1210 pci_devs[devno].pdev[socket] = pdev;
1178 } else { 1211
1179 i7core_printk(KERN_ERR, 1212 /* Sanity check */
1180 "Device not found: " 1213 if (unlikely(PCI_SLOT(pdev->devfn) != pci_devs[devno].dev ||
1181 "dev %02x:%02x.%d PCI ID %04x:%04x\n", 1214 PCI_FUNC(pdev->devfn) != pci_devs[devno].func)) {
1182 bus, pci_devs[i].dev, pci_devs[i].func, 1215 i7core_printk(KERN_ERR,
1183 PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id); 1216 "Device PCI ID %04x:%04x "
1217 "has dev %02x:%02x.%d instead of dev %02x:%02x.%d\n",
1218 PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id,
1219 bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
1220 bus, pci_devs[devno].dev, pci_devs[devno].func);
1221 return -ENODEV;
1222 }
1184 1223
1185 /* Dev 3 function 2 only exists on chips with RDIMMs */ 1224 /* Be sure that the device is enabled */
1186 if ((pci_devs[i].dev == 3) && (pci_devs[i].func == 2)) 1225 if (unlikely(pci_enable_device(pdev) < 0)) {
1187 continue; 1226 i7core_printk(KERN_ERR,
1227 "Couldn't enable "
1228 "dev %02x:%02x.%d PCI ID %04x:%04x\n",
1229 bus, pci_devs[devno].dev, pci_devs[devno].func,
1230 PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id);
1231 return -ENODEV;
1232 }
1188 1233
1189 /* End of list, leave */ 1234 i7core_printk(KERN_INFO,
1190 rc = -ENODEV; 1235 "Registered socket %d "
1191 goto error; 1236 "dev %02x:%02x.%d PCI ID %04x:%04x\n",
1192 } 1237 socket, bus, pci_devs[devno].dev, pci_devs[devno].func,
1238 PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id);
1193 1239
1194 /* Sanity check */ 1240 *prev = pdev;
1195 if (unlikely(PCI_SLOT(pdev->devfn) != pci_devs[i].dev ||
1196 PCI_FUNC(pdev->devfn) != pci_devs[i].func)) {
1197 i7core_printk(KERN_ERR,
1198 "Device PCI ID %04x:%04x "
1199 "has fn %d.%d instead of fn %d.%d\n",
1200 PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id,
1201 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
1202 pci_devs[i].dev, pci_devs[i].func);
1203 rc = -EINVAL;
1204 goto error;
1205 }
1206 1241
1207 /* Be sure that the device is enabled */ 1242 return 0;
1208 rc = pci_enable_device(pdev); 1243}
1209 if (unlikely(rc < 0)) {
1210 i7core_printk(KERN_ERR,
1211 "Couldn't enable PCI ID %04x:%04x "
1212 "fn %d.%d\n",
1213 PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id,
1214 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
1215 goto error;
1216 }
1217 1244
1218 i7core_printk(KERN_INFO, 1245static int i7core_get_devices(void)
1219 "Registered socket %d " 1246{
1220 "dev %02x:%02x.%d PCI ID %04x:%04x\n", 1247 int i;
1221 socket, bus, pci_devs[i].dev, pci_devs[i].func, 1248 struct pci_dev *pdev = NULL;
1222 PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id);
1223 }
1224 1249
1250 for (i = 0; i < N_DEVS; i++) {
1251 pdev = NULL;
1252 do {
1253 if (i7core_get_onedevice(&pdev, i) < 0) {
1254 i7core_put_devices();
1255 return -ENODEV;
1256 }
1257 } while (pdev);
1258 }
1225 return 0; 1259 return 0;
1226
1227error:
1228 i7core_put_devices();
1229 return -EINVAL;
1230} 1260}
1231 1261
1232static int mci_bind_devs(struct mem_ctl_info *mci) 1262static int mci_bind_devs(struct mem_ctl_info *mci)