static void __exit edac_exit_mce_inject(void) { int i; for (i = 0; i < ARRAY_SIZE(sysfs_attrs); i++) sysfs_remove_file(mce_kobj, &sysfs_attrs[i]->attr); kobject_del(mce_kobj); edac_put_sysfs_class(); }
/* * edac_pci_main_kobj_teardown() * * if no longer linked (needed) remove the top level EDAC PCI * kobject with its controls and attributes */ static void edac_pci_main_kobj_teardown(void) { debugf0("%s()\n", __func__); /* Decrement the count and only if no more controller instances * are connected perform the unregisteration of the top level * main kobj */ if (atomic_dec_return(&edac_pci_sysfs_refcount) == 0) { debugf0("%s() called kobject_put on main kobj\n", __func__); kobject_put(edac_pci_top_main_kobj); } edac_put_sysfs_class(); }
/* * edac_device_unregister_sysfs_main_kobj: * the '..../edac/<name>' kobject */ void edac_device_unregister_sysfs_main_kobj(struct edac_device_ctl_info *dev) { debugf0("%s()\n", __func__); debugf4("%s() name of kobject is: %s\n", __func__, kobject_name(&dev->kobj)); /* * Unregister the edac device's kobject and * allow for reference count to reach 0 at which point * the callback will be called to: * a) module_put() this module * b) 'kfree' the memory */ kobject_put(&dev->kobj); edac_put_sysfs_class(); }
static int __init edac_init_mce_inject(void) { struct sysdev_class *edac_class = NULL; int i, err = 0; edac_class = edac_get_sysfs_class(); if (!edac_class) return -EINVAL; mce_kobj = kobject_create_and_add("mce", &edac_class->kset.kobj); if (!mce_kobj) { printk(KERN_ERR "Error creating a mce kset.\n"); err = -ENOMEM; goto err_mce_kobj; } for (i = 0; i < ARRAY_SIZE(sysfs_attrs); i++) { err = sysfs_create_file(mce_kobj, &sysfs_attrs[i]->attr); if (err) { printk(KERN_ERR "Error creating %s in sysfs.\n", sysfs_attrs[i]->attr.name); goto err_sysfs_create; } } return 0; err_sysfs_create: while (--i >= 0) sysfs_remove_file(mce_kobj, &sysfs_attrs[i]->attr); kobject_del(mce_kobj); err_mce_kobj: edac_put_sysfs_class(); return err; }
/** * edac_pci_main_kobj_setup() * * setup the sysfs for EDAC PCI attributes * assumes edac_class has already been initialized */ static int edac_pci_main_kobj_setup(void) { int err; struct sysdev_class *edac_class; debugf0("%s()\n", __func__); /* check and count if we have already created the main kobject */ if (atomic_inc_return(&edac_pci_sysfs_refcount) != 1) return 0; /* First time, so create the main kobject and its * controls and attributes */ edac_class = edac_get_sysfs_class(); if (edac_class == NULL) { debugf1("%s() no edac_class\n", __func__); err = -ENODEV; goto decrement_count_fail; } /* Bump the reference count on this module to ensure the * modules isn't unloaded until we deconstruct the top * level main kobj for EDAC PCI */ if (!try_module_get(THIS_MODULE)) { debugf1("%s() try_module_get() failed\n", __func__); err = -ENODEV; goto mod_get_fail; } edac_pci_top_main_kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL); if (!edac_pci_top_main_kobj) { debugf1("Failed to allocate\n"); err = -ENOMEM; goto kzalloc_fail; } /* Instanstiate the pci object */ err = kobject_init_and_add(edac_pci_top_main_kobj, &ktype_edac_pci_main_kobj, &edac_class->kset.kobj, "pci"); if (err) { debugf1("Failed to register '.../edac/pci'\n"); goto kobject_init_and_add_fail; } /* At this point, to 'release' the top level kobject * for EDAC PCI, then edac_pci_main_kobj_teardown() * must be used, for resources to be cleaned up properly */ kobject_uevent(edac_pci_top_main_kobj, KOBJ_ADD); debugf1("Registered '.../edac/pci' kobject\n"); return 0; /* Error unwind statck */ kobject_init_and_add_fail: kfree(edac_pci_top_main_kobj); kzalloc_fail: module_put(THIS_MODULE); mod_get_fail: edac_put_sysfs_class(); decrement_count_fail: /* if are on this error exit, nothing to tear down */ atomic_dec(&edac_pci_sysfs_refcount); return err; }
/* * edac_device_register_sysfs_main_kobj * * perform the high level setup for the new edac_device instance * * Return: 0 SUCCESS * !0 FAILURE */ int edac_device_register_sysfs_main_kobj(struct edac_device_ctl_info *edac_dev) { struct sysdev_class *edac_class; int err; debugf1("%s()\n", __func__); /* get the /sys/devices/system/edac reference */ edac_class = edac_get_sysfs_class(); if (edac_class == NULL) { debugf1("%s() no edac_class error\n", __func__); err = -ENODEV; goto err_out; } /* Point to the 'edac_class' this instance 'reports' to */ edac_dev->edac_class = edac_class; /* Init the devices's kobject */ memset(&edac_dev->kobj, 0, sizeof(struct kobject)); /* Record which module 'owns' this control structure * and bump the ref count of the module */ edac_dev->owner = THIS_MODULE; if (!try_module_get(edac_dev->owner)) { err = -ENODEV; goto err_mod_get; } /* register */ err = kobject_init_and_add(&edac_dev->kobj, &ktype_device_ctrl, &edac_class->kset.kobj, "%s", edac_dev->name); if (err) { debugf1("%s()Failed to register '.../edac/%s'\n", __func__, edac_dev->name); goto err_kobj_reg; } kobject_uevent(&edac_dev->kobj, KOBJ_ADD); /* At this point, to 'free' the control struct, * edac_device_unregister_sysfs_main_kobj() must be used */ debugf4("%s() Registered '.../edac/%s' kobject\n", __func__, edac_dev->name); return 0; /* Error exit stack */ err_kobj_reg: module_put(edac_dev->owner); err_mod_get: edac_put_sysfs_class(); err_out: return err; }