debugf0("%s()\n", __func__);
- /* remove all csrow kobjects */
- debugf4("%s() unregister this mci kobj\n", __func__);
- for (i = 0; i < mci->nr_csrows; i++) {
- if (mci->csrows[i].nr_pages > 0) {
- debugf0("%s() unreg csrow-%d\n", __func__, i);
- kobject_put(&mci->csrows[i].kobj);
- }
- }
-
- /* remove this mci instance's attribtes */
- if (mci->mc_driver_sysfs_attributes) {
- debugf4("%s() unregister mci private attributes\n", __func__);
- edac_remove_mci_instance_attributes(mci,
- mci->mc_driver_sysfs_attributes,
- &mci->edac_mci_kobj, 0);
+ for (i = 0; i < mci->tot_dimms; i++) {
+ struct dimm_info *dimm = &mci->dimms[i];
+ if (dimm->nr_pages == 0)
+ continue;
+ debugf0("%s(): removing device %s\n", __func__,
+ dev_name(&dimm->dev));
+ put_device(&dimm->dev);
}
- /* remove the symlink */
- debugf4("%s() remove_link\n", __func__);
- sysfs_remove_link(&mci->edac_mci_kobj, EDAC_DEVICE_SYMLINK);
-
- /* unregister this instance's kobject */
- debugf4("%s() remove_mci_instance\n", __func__);
- kobject_put(&mci->edac_mci_kobj);
+ debugf0("%s(): removing device %s\n", __func__,
+ dev_name(&mci->dev));
+ put_device(&mci->dev);
}
-
-
-
/*
- * edac_setup_sysfs_mc_kset(void)
- *
- * Initialize the mc_kset for the 'mc' entry
- * This requires creating the top 'mc' directory with a kset
- * and its controls/attributes.
- *
- * To this 'mc' kset, instance 'mci' will be grouped as children.
- *
- * Return: 0 SUCCESS
- * !0 FAILURE error code
+ * Init/exit code for the module. Basically, creates/removes /sys/class/rc
*/
-int edac_sysfs_setup_mc_kset(void)
+
+int __init edac_mc_sysfs_init(void)
{
++<<<<<<< HEAD
+ int rc;
+ struct sysdev_class *edac_class;
+
+ /* get the /sys/devices/system/edac class reference */
+ edac_class = edac_get_sysfs_class();
+ if (edac_class == NULL) {
+ debugf1("%s() no edac_class\n", __func__);
+ return -EINVAL;
+ }
+
+ /*
+ * FIXME: fake a parent device for the EDAC node
+ *
+ * Unfortunately, I couldn't find any easy way to do it, as sysdev
+ * doesn't use struct device.
+ */
+ mci_parent.type = &mci_attr_type;
+ mci_parent.bus = &mci_bus_type;
+ device_initialize(&mci_parent);
+ dev_set_name(&mci_parent, "edac");
+ memcpy(&mci_parent.kobj, &edac_class->kset.kobj,
+ sizeof(mci_parent.kobj));
+
+ rc = bus_register(&mci_bus_type);
+ if (rc) {
+ printk(KERN_ERR "rc_core: unable to register rc class\n");
+ return rc;
++=======
+ int err = -EINVAL;
+ struct bus_type *edac_subsys;
+
+ debugf1("%s()\n", __func__);
+
+ /* get the /sys/devices/system/edac subsys reference */
+ edac_subsys = edac_get_sysfs_subsys();
+ if (edac_subsys == NULL) {
+ debugf1("%s() no edac_subsys error=%d\n", __func__, err);
+ goto fail_out;
+ }
+
+ /* Init the MC's kobject */
+ mc_kset = kset_create_and_add("mc", NULL, &edac_subsys->dev_root->kobj);
+ if (!mc_kset) {
+ err = -ENOMEM;
+ debugf1("%s() Failed to register '.../edac/mc'\n", __func__);
+ goto fail_kset;
++>>>>>>> dcd6c92267155e70a94b3927bce681ce74b80d1f
}
debugf1("%s() Registered '.../edac/mc' kobject\n", __func__);
return 0;
++<<<<<<< HEAD
++=======
+
+ fail_kset:
+ edac_put_sysfs_subsys();
+
+ fail_out:
+ return err;
++>>>>>>> dcd6c92267155e70a94b3927bce681ce74b80d1f
}
-/*
- * edac_sysfs_teardown_mc_kset
- *
- * deconstruct the mc_ket for memory controllers
- */
-void edac_sysfs_teardown_mc_kset(void)
+void __exit edac_mc_sysfs_exit(void)
{
++<<<<<<< HEAD
+ debugf0("%s() removing mc bus\n", __func__);
+ edac_put_sysfs_class();
++=======
+ kset_unregister(mc_kset);
+ edac_put_sysfs_subsys();
+ }
++>>>>>>> dcd6c92267155e70a94b3927bce681ce74b80d1f
+ bus_unregister(&mci_bus_type);
+}
}
page = (unsigned long) info->eap;
- if (info->xeap & 1)
- page |= 0x100000000ul;
- chan = page & 1;
page >>= 1;
- offst = page & ((1 << PAGE_SHIFT) - 1);
- page >>= PAGE_SHIFT;
+ if (info->xeap & 1)
+ page |= 0x80000000;
+ page >>= (PAGE_SHIFT - 1);
row = edac_mc_find_csrow_by_page(mci, page);
+ if (row == -1) {
+ i82975x_mc_printk(mci, KERN_ERR, "error processing EAP:\n"
+ "\tXEAP=%u\n"
+ "\t EAP=0x%08x\n"
+ "\tPAGE=0x%08x\n",
+ (info->xeap & 1) ? 1 : 0, info->eap, (unsigned int) page);
+ return 0;
+ }
+ chan = (mci->csrows[row].nr_channels == 1) ? 0 : info->eap & 1;
+ offst = info->eap
+ & ((1 << PAGE_SHIFT) -
+ (1 << mci->csrows[row].grain));
+
if (info->errsts & 0x0002)
- edac_mc_handle_ue(mci, page, offst , row, "i82975x UE");
+ edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci,
+ page, offst, 0,
+ row, -1, -1,
+ "i82975x UE", "", NULL);
else
++<<<<<<< HEAD
+ edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci,
+ page, offst, info->derrsyn,
+ row, multi_chan ? chan : 0, -1,
+ "i82975x CE", "", NULL);
++=======
+ edac_mc_handle_ce(mci, page, offst, info->derrsyn, row,
+ chan, "i82975x CE");
++>>>>>>> dcd6c92267155e70a94b3927bce681ce74b80d1f
return 1;
}
csrow->first_page = last_cumul_size;
csrow->last_page = cumul_size - 1;
- csrow->nr_pages = cumul_size - last_cumul_size;
last_cumul_size = cumul_size;
++<<<<<<< HEAD
++=======
+ csrow->grain = 1 << 7; /* 128Byte cache-line resolution */
+ csrow->mtype = MEM_DDR2; /* I82975x supports only DDR2 */
+ csrow->dtype = i82975x_dram_type(mch_window, index);
+ csrow->edac_mode = EDAC_SECDED; /* only supported */
++>>>>>>> dcd6c92267155e70a94b3927bce681ce74b80d1f
}
}