diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-09-25 12:42:25 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-10 10:49:30 -0400 |
commit | b968759ee7102f86fec5f3349f7a8ab4556884a3 (patch) | |
tree | dcea622a061de20fee0e64b8224e323a1fa5b4b1 /drivers/edac/edac_mc_sysfs.c | |
parent | 35be95446734cbb10b088a6b38269ac4a8ac3a86 (diff) |
edac: Create an unique instance for each kobj
Current code only works when there's just one memory
controller, since we need one kobj for each instance.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/edac/edac_mc_sysfs.c')
-rw-r--r-- | drivers/edac/edac_mc_sysfs.c | 75 |
1 files changed, 49 insertions, 26 deletions
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index f689d7d6ab46..c200c2fd43ea 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c | |||
@@ -730,7 +730,7 @@ void edac_mc_unregister_sysfs_main_kobj(struct mem_ctl_info *mci) | |||
730 | 730 | ||
731 | #define EDAC_DEVICE_SYMLINK "device" | 731 | #define EDAC_DEVICE_SYMLINK "device" |
732 | 732 | ||
733 | #define grp_to_mci(k) (container_of(k, struct mcidev_sysfs_group, kobj)->mci) | 733 | #define grp_to_mci(k) (container_of(k, struct mcidev_sysfs_group_kobj, kobj)->mci) |
734 | 734 | ||
735 | /* MCI show/store functions for top most object */ | 735 | /* MCI show/store functions for top most object */ |
736 | static ssize_t inst_grp_show(struct kobject *kobj, struct attribute *attr, | 736 | static ssize_t inst_grp_show(struct kobject *kobj, struct attribute *attr, |
@@ -764,12 +764,12 @@ static ssize_t inst_grp_store(struct kobject *kobj, struct attribute *attr, | |||
764 | /* No memory to release for this kobj */ | 764 | /* No memory to release for this kobj */ |
765 | static void edac_inst_grp_release(struct kobject *kobj) | 765 | static void edac_inst_grp_release(struct kobject *kobj) |
766 | { | 766 | { |
767 | struct mcidev_sysfs_group *grp; | 767 | struct mcidev_sysfs_group_kobj *grp; |
768 | struct mem_ctl_info *mci; | 768 | struct mem_ctl_info *mci; |
769 | 769 | ||
770 | debugf1("%s()\n", __func__); | 770 | debugf1("%s()\n", __func__); |
771 | 771 | ||
772 | grp = container_of(kobj, struct mcidev_sysfs_group, kobj); | 772 | grp = container_of(kobj, struct mcidev_sysfs_group_kobj, kobj); |
773 | mci = grp->mci; | 773 | mci = grp->mci; |
774 | 774 | ||
775 | kobject_put(&mci->edac_mci_kobj); | 775 | kobject_put(&mci->edac_mci_kobj); |
@@ -804,22 +804,30 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci, | |||
804 | 804 | ||
805 | while (sysfs_attrib) { | 805 | while (sysfs_attrib) { |
806 | if (sysfs_attrib->grp) { | 806 | if (sysfs_attrib->grp) { |
807 | struct kobject *newkobj = &sysfs_attrib->grp->kobj; | 807 | struct mcidev_sysfs_group_kobj *grp_kobj; |
808 | |||
809 | grp_kobj = kzalloc(sizeof(*grp_kobj), GFP_KERNEL); | ||
810 | if (!grp_kobj) | ||
811 | return -ENOMEM; | ||
812 | |||
813 | list_add_tail(&grp_kobj->list, &mci->grp_kobj_list); | ||
814 | |||
815 | grp_kobj->grp = sysfs_attrib->grp; | ||
816 | grp_kobj->mci = mci; | ||
808 | 817 | ||
809 | debugf0("%s() grp %s, mci %p\n", __func__, | 818 | debugf0("%s() grp %s, mci %p\n", __func__, |
810 | sysfs_attrib->grp->name, mci); | 819 | sysfs_attrib->grp->name, mci); |
811 | 820 | ||
812 | sysfs_attrib->grp->mci = mci; | 821 | err = kobject_init_and_add(&grp_kobj->kobj, |
813 | 822 | &ktype_inst_grp, | |
814 | err = kobject_init_and_add(newkobj, &ktype_inst_grp, | ||
815 | &mci->edac_mci_kobj, | 823 | &mci->edac_mci_kobj, |
816 | sysfs_attrib->grp->name); | 824 | sysfs_attrib->grp->name); |
817 | if (err) | 825 | if (err) |
818 | return err; | 826 | return err; |
819 | 827 | ||
820 | err = edac_create_mci_instance_attributes(mci, | 828 | err = edac_create_mci_instance_attributes(mci, |
821 | sysfs_attrib->grp->mcidev_attr, | 829 | grp_kobj->grp->mcidev_attr, |
822 | newkobj); | 830 | &grp_kobj->kobj); |
823 | 831 | ||
824 | if (err) | 832 | if (err) |
825 | return err; | 833 | return err; |
@@ -845,25 +853,27 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci, | |||
845 | * remove MC driver specific attributes at the topmost level | 853 | * remove MC driver specific attributes at the topmost level |
846 | * directory of this mci instance. | 854 | * directory of this mci instance. |
847 | */ | 855 | */ |
848 | static void edac_remove_mci_instance_attributes( | 856 | static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci, |
849 | struct mcidev_sysfs_attribute *sysfs_attrib, | 857 | struct mcidev_sysfs_attribute *sysfs_attrib, |
850 | struct kobject *kobj) | 858 | struct kobject *kobj, int count) |
851 | { | 859 | { |
860 | struct mcidev_sysfs_group_kobj *grp_kobj, *tmp; | ||
861 | |||
852 | debugf1("%s()\n", __func__); | 862 | debugf1("%s()\n", __func__); |
853 | 863 | ||
854 | /* loop if there are attributes and until we hit a NULL entry */ | 864 | /* |
865 | * loop if there are attributes and until we hit a NULL entry | ||
866 | * Remove first all the atributes | ||
867 | */ | ||
855 | while (sysfs_attrib) { | 868 | while (sysfs_attrib) { |
856 | if (sysfs_attrib->grp) { | 869 | if (sysfs_attrib->grp) { |
857 | struct kobject *newkobj = &sysfs_attrib->grp->kobj; | 870 | list_for_each_entry(grp_kobj, &mci->grp_kobj_list, |
858 | 871 | list) | |
859 | debugf0("%s() grp %s\n", __func__, | 872 | if (grp_kobj->grp == sysfs_attrib->grp) |
860 | sysfs_attrib->grp->name); | 873 | edac_remove_mci_instance_attributes(mci, |
861 | 874 | grp_kobj->grp->mcidev_attr, | |
862 | edac_remove_mci_instance_attributes( | 875 | &grp_kobj->kobj, count + 1); |
863 | sysfs_attrib->grp->mcidev_attr, newkobj); | 876 | } else if (sysfs_attrib->attr.name) { |
864 | |||
865 | kobject_put(newkobj); | ||
866 | } else if (sysfs_attrib->attr.name) { | ||
867 | debugf0("%s() file %s\n", __func__, | 877 | debugf0("%s() file %s\n", __func__, |
868 | sysfs_attrib->attr.name); | 878 | sysfs_attrib->attr.name); |
869 | sysfs_remove_file(kobj, &sysfs_attrib->attr); | 879 | sysfs_remove_file(kobj, &sysfs_attrib->attr); |
@@ -871,6 +881,16 @@ static void edac_remove_mci_instance_attributes( | |||
871 | break; | 881 | break; |
872 | sysfs_attrib++; | 882 | sysfs_attrib++; |
873 | } | 883 | } |
884 | |||
885 | /* | ||
886 | * Now that all attributes got removed, it is save to remove all groups | ||
887 | */ | ||
888 | if (!count) | ||
889 | list_for_each_entry_safe(grp_kobj, tmp, &mci->grp_kobj_list, | ||
890 | list) { | ||
891 | debugf0("%s() grp %s\n", __func__, grp_kobj->grp->name); | ||
892 | kobject_put(&grp_kobj->kobj); | ||
893 | } | ||
874 | } | 894 | } |
875 | 895 | ||
876 | 896 | ||
@@ -891,6 +911,8 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) | |||
891 | 911 | ||
892 | debugf0("%s() idx=%d\n", __func__, mci->mc_idx); | 912 | debugf0("%s() idx=%d\n", __func__, mci->mc_idx); |
893 | 913 | ||
914 | INIT_LIST_HEAD(&mci->grp_kobj_list); | ||
915 | |||
894 | /* create a symlink for the device */ | 916 | /* create a symlink for the device */ |
895 | err = sysfs_create_link(kobj_mci, &mci->dev->kobj, | 917 | err = sysfs_create_link(kobj_mci, &mci->dev->kobj, |
896 | EDAC_DEVICE_SYMLINK); | 918 | EDAC_DEVICE_SYMLINK); |
@@ -940,8 +962,8 @@ fail1: | |||
940 | } | 962 | } |
941 | 963 | ||
942 | /* remove the mci instance's attributes, if any */ | 964 | /* remove the mci instance's attributes, if any */ |
943 | edac_remove_mci_instance_attributes( | 965 | edac_remove_mci_instance_attributes(mci, |
944 | mci->mc_driver_sysfs_attributes, &mci->edac_mci_kobj); | 966 | mci->mc_driver_sysfs_attributes, &mci->edac_mci_kobj, 0); |
945 | 967 | ||
946 | /* remove the symlink */ | 968 | /* remove the symlink */ |
947 | sysfs_remove_link(kobj_mci, EDAC_DEVICE_SYMLINK); | 969 | sysfs_remove_link(kobj_mci, EDAC_DEVICE_SYMLINK); |
@@ -975,8 +997,9 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) | |||
975 | debugf0("%s() remove_mci_instance\n", __func__); | 997 | debugf0("%s() remove_mci_instance\n", __func__); |
976 | 998 | ||
977 | /* remove this mci instance's attribtes */ | 999 | /* remove this mci instance's attribtes */ |
978 | edac_remove_mci_instance_attributes(mci->mc_driver_sysfs_attributes, | 1000 | edac_remove_mci_instance_attributes(mci, |
979 | &mci->edac_mci_kobj); | 1001 | mci->mc_driver_sysfs_attributes, |
1002 | &mci->edac_mci_kobj, 0); | ||
980 | debugf0("%s() unregister this mci kobj\n", __func__); | 1003 | debugf0("%s() unregister this mci kobj\n", __func__); |
981 | 1004 | ||
982 | /* unregister this instance's kobject */ | 1005 | /* unregister this instance's kobject */ |