diff options
Diffstat (limited to 'drivers/edac')
-rw-r--r-- | drivers/edac/i7core_edac.c | 186 |
1 files changed, 108 insertions, 78 deletions
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 9f39d3d5502e..79636b58ec52 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 | */ |
1129 | static int i7core_get_devices(void) | 1129 | int 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, | 1245 | static 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 | |||
1227 | error: | ||
1228 | i7core_put_devices(); | ||
1229 | return -EINVAL; | ||
1230 | } | 1260 | } |
1231 | 1261 | ||
1232 | static int mci_bind_devs(struct mem_ctl_info *mci) | 1262 | static int mci_bind_devs(struct mem_ctl_info *mci) |