diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-06-22 21:48:31 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-10 10:44:48 -0400 |
commit | eb94fc402f1592dfe847b245d9109c11a99a2ea1 (patch) | |
tree | 75a74e293f40d7c97b756fee51c2721eb5221e42 /drivers/edac | |
parent | 5566cb7c91ba4ff4447278bb27896b4a2bb7d18a (diff) |
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>
Diffstat (limited to 'drivers/edac')
-rw-r--r-- | drivers/edac/i7core_edac.c | 66 |
1 files changed, 50 insertions, 16 deletions
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 772219fa10be..e0a3b217c52b 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c | |||
@@ -309,25 +309,33 @@ static inline int numcol(u32 col) | |||
309 | /**************************************************************************** | 309 | /**************************************************************************** |
310 | Memory check routines | 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 | int i; | 314 | int i; |
316 | u32 status, control; | ||
317 | |||
318 | *channels = 0; | ||
319 | 315 | ||
320 | for (i = 0; i < N_DEVS; i++) { | 316 | for (i = 0; i < N_DEVS; i++) { |
321 | if (!pci_devs[i].pdev) | 317 | if (!pci_devs[i].pdev) |
322 | continue; | 318 | continue; |
323 | 319 | ||
324 | if (PCI_SLOT(pci_devs[i].pdev->devfn) == 3 && | 320 | if (PCI_SLOT(pci_devs[i].pdev->devfn) == slot && |
325 | PCI_FUNC(pci_devs[i].pdev->devfn) == 0) { | 321 | PCI_FUNC(pci_devs[i].pdev->devfn) == func) { |
326 | pdev = pci_devs[i].pdev; | 322 | return pci_devs[i].pdev; |
327 | break; | ||
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 | if (!pdev) { | 339 | if (!pdev) { |
332 | i7core_printk(KERN_ERR, "Couldn't find fn 3.0!!!\n"); | 340 | i7core_printk(KERN_ERR, "Couldn't find fn 3.0!!!\n"); |
333 | return -ENODEV; | 341 | return -ENODEV; |
@@ -338,6 +346,7 @@ static int i7core_get_active_channels(int *channels) | |||
338 | pci_read_config_dword(pdev, MC_CONTROL, &control); | 346 | pci_read_config_dword(pdev, MC_CONTROL, &control); |
339 | 347 | ||
340 | for (i = 0; i < NUM_CHANS; i++) { | 348 | for (i = 0; i < NUM_CHANS; i++) { |
349 | u32 dimm_dod[3]; | ||
341 | /* Check if the channel is active */ | 350 | /* Check if the channel is active */ |
342 | if (!(control & (1 << (8 + i)))) | 351 | if (!(control & (1 << (8 + i)))) |
343 | continue; | 352 | continue; |
@@ -347,7 +356,27 @@ static int i7core_get_active_channels(int *channels) | |||
347 | continue; | 356 | continue; |
348 | } | 357 | } |
349 | 358 | ||
359 | pdev = get_pdev_slot_func(i + 4, 1); | ||
360 | if (!pdev) { | ||
361 | i7core_printk(KERN_ERR, "Couldn't find fn %d.%d!!!\n", | ||
362 | i + 4, 1); | ||
363 | return -ENODEV; | ||
364 | } | ||
365 | /* Devices 4-6 function 1 */ | ||
366 | pci_read_config_dword(pdev, | ||
367 | MC_DOD_CH_DIMM0, &dimm_dod[0]); | ||
368 | pci_read_config_dword(pdev, | ||
369 | MC_DOD_CH_DIMM1, &dimm_dod[1]); | ||
370 | pci_read_config_dword(pdev, | ||
371 | MC_DOD_CH_DIMM2, &dimm_dod[2]); | ||
372 | |||
350 | (*channels)++; | 373 | (*channels)++; |
374 | |||
375 | for (j = 0; j < 3; j++) { | ||
376 | if (!DIMM_PRESENT(dimm_dod[j])) | ||
377 | continue; | ||
378 | (*csrows)++; | ||
379 | } | ||
351 | } | 380 | } |
352 | 381 | ||
353 | debugf0("Number of active channels: %d\n", *channels); | 382 | debugf0("Number of active channels: %d\n", *channels); |
@@ -473,7 +502,11 @@ static int get_dimm_config(struct mem_ctl_info *mci) | |||
473 | RANKOFFSET(dimm_dod[j]), | 502 | RANKOFFSET(dimm_dod[j]), |
474 | banks, ranks, rows, cols); | 503 | banks, ranks, rows, cols); |
475 | 504 | ||
476 | npages = cols * rows; /* FIXME */ | 505 | #if PAGE_SHIFT > 20 |
506 | npages = size >> (PAGE_SHIFT - 20); | ||
507 | #else | ||
508 | npages = size << (20 - PAGE_SHIFT); | ||
509 | #endif | ||
477 | 510 | ||
478 | csr = &mci->csrows[csrow]; | 511 | csr = &mci->csrows[csrow]; |
479 | csr->first_page = last_page + 1; | 512 | csr->first_page = last_page + 1; |
@@ -482,8 +515,12 @@ static int get_dimm_config(struct mem_ctl_info *mci) | |||
482 | csr->nr_pages = npages; | 515 | csr->nr_pages = npages; |
483 | 516 | ||
484 | csr->page_mask = 0; | 517 | csr->page_mask = 0; |
485 | csr->grain = 0; | 518 | csr->grain = 8; |
486 | csr->csrow_idx = csrow; | 519 | csr->csrow_idx = csrow; |
520 | csr->nr_channels = 1; | ||
521 | |||
522 | csr->channels[0].chan_idx = i; | ||
523 | csr->channels[0].ce_count = 0; | ||
487 | 524 | ||
488 | switch (banks) { | 525 | switch (banks) { |
489 | case 4: | 526 | case 4: |
@@ -1179,7 +1216,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, | |||
1179 | { | 1216 | { |
1180 | struct mem_ctl_info *mci; | 1217 | struct mem_ctl_info *mci; |
1181 | struct i7core_pvt *pvt; | 1218 | struct i7core_pvt *pvt; |
1182 | int num_channels = 0; | 1219 | int num_channels; |
1183 | int num_csrows; | 1220 | int num_csrows; |
1184 | int dev_idx = id->driver_data; | 1221 | int dev_idx = id->driver_data; |
1185 | int rc; | 1222 | int rc; |
@@ -1193,13 +1230,10 @@ static int __devinit i7core_probe(struct pci_dev *pdev, | |||
1193 | return rc; | 1230 | return rc; |
1194 | 1231 | ||
1195 | /* Check the number of active and not disabled channels */ | 1232 | /* Check the number of active and not disabled channels */ |
1196 | rc = i7core_get_active_channels(&num_channels); | 1233 | rc = i7core_get_active_channels(&num_channels, &num_csrows); |
1197 | if (unlikely (rc < 0)) | 1234 | if (unlikely (rc < 0)) |
1198 | goto fail0; | 1235 | goto fail0; |
1199 | 1236 | ||
1200 | /* FIXME: we currently don't know the number of csrows */ | ||
1201 | num_csrows = num_channels; | ||
1202 | |||
1203 | /* allocate a new MC control structure */ | 1237 | /* allocate a new MC control structure */ |
1204 | mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, 0); | 1238 | mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, 0); |
1205 | if (unlikely (!mci)) { | 1239 | if (unlikely (!mci)) { |