The code in ghes_edac_register() switches back and forth between standard and fake controller creation. Do one thing only and separate the code path that creates the fake MC.
Note: For better review the code is not yet carved out in separate functions. Signed-off-by: Robert Richter <rrich...@marvell.com> --- drivers/edac/ghes_edac.c | 73 +++++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 27 deletions(-) diff --git a/drivers/edac/ghes_edac.c b/drivers/edac/ghes_edac.c index 8329af037fbe..47b99e0fea6d 100644 --- a/drivers/edac/ghes_edac.c +++ b/drivers/edac/ghes_edac.c @@ -536,7 +536,6 @@ int ghes_edac_register(struct ghes *ghes, struct device *dev) struct dimm_fill dimm_fill; int rc = 0, num_dimm = 0; struct mem_ctl_info *mci; - bool fake = false; int idx; if (IS_ENABLED(CONFIG_X86)) { @@ -560,24 +559,44 @@ int ghes_edac_register(struct ghes *ghes, struct device *dev) /* Get the number of DIMMs */ dmi_walk(ghes_edac_count_dimms, &num_dimm); - /* Check if we've got a bogus BIOS */ - if (num_dimm == 0) { - fake = true; - num_dimm = 1; - } + if (!num_dimm) { + /* + * Bogus BIOS: Ignore DMI topology and use a single MC + * with only one DIMM for the whole address range to + * catch all errros. + */ + struct dimm_info *dimm; - mci = ghes_mc_create(dev, 0, num_dimm); - if (!mci) { - pr_info("Can't allocate memory for EDAC data\n"); - rc = -ENOMEM; - goto unlock; - } + mci = ghes_mc_create(dev, 0, 1); + if (!mci) { + rc = -ENOMEM; + goto unlock; + } + + dimm = edac_get_dimm_by_index(mci, 0); + + dimm->nr_pages = 1; + dimm->grain = 128; + dimm->mtype = MEM_UNKNOWN; + dimm->dtype = DEV_UNKNOWN; + dimm->edac_mode = EDAC_SECDED; + + snprintf(dimm->label, sizeof(dimm->label), "unknown memory"); + + rc = ghes_mc_add(mci); + if (rc) { + ghes_mc_destroy(mci); + goto unlock; + } - if (fake) { pr_info("This system has a very crappy BIOS: It doesn't even list the DIMMS.\n"); pr_info("Its SMBIOS info is wrong. It is doubtful that the error report would\n"); pr_info("work on such system. Use this driver with caution\n"); - } else if (idx < 0) { + + goto out; + } + + if (idx < 0) { pr_info("This EDAC driver relies on BIOS to enumerate memory and get error reports.\n"); pr_info("Unfortunately, not all BIOSes reflect the memory layout correctly.\n"); pr_info("So, the end result of using this driver varies from vendor to vendor.\n"); @@ -586,31 +605,31 @@ int ghes_edac_register(struct ghes *ghes, struct device *dev) pr_info("This system has %d DIMM sockets.\n", num_dimm); } - if (!fake) { - dimm_fill.index = 0; - dimm_fill.mci = mci; - dmi_walk(ghes_edac_dmidecode, &dimm_fill); - } else { - struct dimm_info *dimm = edac_get_dimm_by_index(mci, 0); - - dimm->nr_pages = 1; - dimm->grain = 128; - dimm->mtype = MEM_UNKNOWN; - dimm->dtype = DEV_UNKNOWN; - dimm->edac_mode = EDAC_SECDED; + mci = ghes_mc_create(dev, 0, num_dimm); + if (!mci) { + rc = -ENOMEM; + goto unlock; } + dimm_fill.index = 0; + dimm_fill.mci = mci; + + dmi_walk(ghes_edac_dmidecode, &dimm_fill); + rc = ghes_mc_add(mci); if (rc < 0) { - pr_info("Can't register at EDAC core\n"); ghes_mc_destroy(mci); goto unlock; } +out: /* only set on success */ refcount_set(&ghes_refcount, 1); unlock: + if (rc < 0) + pr_info("Can't register at EDAC core\n"); + mutex_unlock(&ghes_reg_mutex); return rc; -- 2.20.1