Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

i7core_edac: fill csrows edac sysfs info

csrows is still fake, since we can't identify its representation with
Nehalem registers.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

+50 -16
+50 -16
drivers/edac/i7core_edac.c
··· 309 309 /**************************************************************************** 310 310 Memory check routines 311 311 ****************************************************************************/ 312 - static int i7core_get_active_channels(int *channels) 312 + static struct pci_dev *get_pdev_slot_func(int slot, int func) 313 313 { 314 - struct pci_dev *pdev = NULL; 315 314 int i; 316 - u32 status, control; 317 - 318 - *channels = 0; 319 315 320 316 for (i = 0; i < N_DEVS; i++) { 321 317 if (!pci_devs[i].pdev) 322 318 continue; 323 319 324 - if (PCI_SLOT(pci_devs[i].pdev->devfn) == 3 && 325 - PCI_FUNC(pci_devs[i].pdev->devfn) == 0) { 326 - pdev = pci_devs[i].pdev; 327 - break; 320 + if (PCI_SLOT(pci_devs[i].pdev->devfn) == slot && 321 + PCI_FUNC(pci_devs[i].pdev->devfn) == func) { 322 + return pci_devs[i].pdev; 328 323 } 329 324 } 330 325 326 + return NULL; 327 + } 328 + 329 + static int i7core_get_active_channels(int *channels, int *csrows) 330 + { 331 + struct pci_dev *pdev = NULL; 332 + int i, j; 333 + u32 status, control; 334 + 335 + *channels = 0; 336 + *csrows = 0; 337 + 338 + pdev = get_pdev_slot_func(3, 0); 331 339 if (!pdev) { 332 340 i7core_printk(KERN_ERR, "Couldn't find fn 3.0!!!\n"); 333 341 return -ENODEV; ··· 346 338 pci_read_config_dword(pdev, MC_CONTROL, &control); 347 339 348 340 for (i = 0; i < NUM_CHANS; i++) { 341 + u32 dimm_dod[3]; 349 342 /* Check if the channel is active */ 350 343 if (!(control & (1 << (8 + i)))) 351 344 continue; ··· 356 347 continue; 357 348 } 358 349 350 + pdev = get_pdev_slot_func(i + 4, 1); 351 + if (!pdev) { 352 + i7core_printk(KERN_ERR, "Couldn't find fn %d.%d!!!\n", 353 + i + 4, 1); 354 + return -ENODEV; 355 + } 356 + /* Devices 4-6 function 1 */ 357 + pci_read_config_dword(pdev, 358 + MC_DOD_CH_DIMM0, &dimm_dod[0]); 359 + pci_read_config_dword(pdev, 360 + MC_DOD_CH_DIMM1, &dimm_dod[1]); 361 + pci_read_config_dword(pdev, 362 + MC_DOD_CH_DIMM2, &dimm_dod[2]); 363 + 359 364 (*channels)++; 365 + 366 + for (j = 0; j < 3; j++) { 367 + if (!DIMM_PRESENT(dimm_dod[j])) 368 + continue; 369 + (*csrows)++; 370 + } 360 371 } 361 372 362 373 debugf0("Number of active channels: %d\n", *channels); ··· 502 473 RANKOFFSET(dimm_dod[j]), 503 474 banks, ranks, rows, cols); 504 475 505 - npages = cols * rows; /* FIXME */ 476 + #if PAGE_SHIFT > 20 477 + npages = size >> (PAGE_SHIFT - 20); 478 + #else 479 + npages = size << (20 - PAGE_SHIFT); 480 + #endif 506 481 507 482 csr = &mci->csrows[csrow]; 508 483 csr->first_page = last_page + 1; ··· 515 482 csr->nr_pages = npages; 516 483 517 484 csr->page_mask = 0; 518 - csr->grain = 0; 485 + csr->grain = 8; 519 486 csr->csrow_idx = csrow; 487 + csr->nr_channels = 1; 488 + 489 + csr->channels[0].chan_idx = i; 490 + csr->channels[0].ce_count = 0; 520 491 521 492 switch (banks) { 522 493 case 4: ··· 1216 1179 { 1217 1180 struct mem_ctl_info *mci; 1218 1181 struct i7core_pvt *pvt; 1219 - int num_channels = 0; 1182 + int num_channels; 1220 1183 int num_csrows; 1221 1184 int dev_idx = id->driver_data; 1222 1185 int rc; ··· 1230 1193 return rc; 1231 1194 1232 1195 /* Check the number of active and not disabled channels */ 1233 - rc = i7core_get_active_channels(&num_channels); 1196 + rc = i7core_get_active_channels(&num_channels, &num_csrows); 1234 1197 if (unlikely (rc < 0)) 1235 1198 goto fail0; 1236 - 1237 - /* FIXME: we currently don't know the number of csrows */ 1238 - num_csrows = num_channels; 1239 1199 1240 1200 /* allocate a new MC control structure */ 1241 1201 mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, 0);