diff options
-rw-r--r-- | drivers/pci/hotplug/rpadlpar_sysfs.c | 112 |
1 files changed, 43 insertions, 69 deletions
diff --git a/drivers/pci/hotplug/rpadlpar_sysfs.c b/drivers/pci/hotplug/rpadlpar_sysfs.c index 5c3ddb60a002..9cde367915b6 100644 --- a/drivers/pci/hotplug/rpadlpar_sysfs.c +++ b/drivers/pci/hotplug/rpadlpar_sysfs.c | |||
@@ -23,44 +23,13 @@ | |||
23 | 23 | ||
24 | #define MAX_DRC_NAME_LEN 64 | 24 | #define MAX_DRC_NAME_LEN 64 |
25 | 25 | ||
26 | /* Store return code of dlpar operation in attribute struct */ | ||
27 | struct dlpar_io_attr { | ||
28 | int rc; | ||
29 | struct attribute attr; | ||
30 | ssize_t (*store)(struct dlpar_io_attr *dlpar_attr, const char *buf, | ||
31 | size_t nbytes); | ||
32 | }; | ||
33 | 26 | ||
34 | /* Common show callback for all attrs, display the return code | 27 | static ssize_t add_slot_store(struct kobject *kobj, struct kobj_attribute *attr, |
35 | * of the dlpar op */ | 28 | const char *buf, size_t nbytes) |
36 | static ssize_t | ||
37 | dlpar_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) | ||
38 | { | ||
39 | struct dlpar_io_attr *dlpar_attr = container_of(attr, | ||
40 | struct dlpar_io_attr, attr); | ||
41 | return sprintf(buf, "%d\n", dlpar_attr->rc); | ||
42 | } | ||
43 | |||
44 | static ssize_t | ||
45 | dlpar_attr_store(struct kobject * kobj, struct attribute * attr, | ||
46 | const char *buf, size_t nbytes) | ||
47 | { | ||
48 | struct dlpar_io_attr *dlpar_attr = container_of(attr, | ||
49 | struct dlpar_io_attr, attr); | ||
50 | return dlpar_attr->store ? | ||
51 | dlpar_attr->store(dlpar_attr, buf, nbytes) : -EIO; | ||
52 | } | ||
53 | |||
54 | static struct sysfs_ops dlpar_attr_sysfs_ops = { | ||
55 | .show = dlpar_attr_show, | ||
56 | .store = dlpar_attr_store, | ||
57 | }; | ||
58 | |||
59 | static ssize_t add_slot_store(struct dlpar_io_attr *dlpar_attr, | ||
60 | const char *buf, size_t nbytes) | ||
61 | { | 29 | { |
62 | char drc_name[MAX_DRC_NAME_LEN]; | 30 | char drc_name[MAX_DRC_NAME_LEN]; |
63 | char *end; | 31 | char *end; |
32 | int rc; | ||
64 | 33 | ||
65 | if (nbytes >= MAX_DRC_NAME_LEN) | 34 | if (nbytes >= MAX_DRC_NAME_LEN) |
66 | return 0; | 35 | return 0; |
@@ -72,15 +41,25 @@ static ssize_t add_slot_store(struct dlpar_io_attr *dlpar_attr, | |||
72 | end = &drc_name[nbytes]; | 41 | end = &drc_name[nbytes]; |
73 | *end = '\0'; | 42 | *end = '\0'; |
74 | 43 | ||
75 | dlpar_attr->rc = dlpar_add_slot(drc_name); | 44 | rc = dlpar_add_slot(drc_name); |
45 | if (rc) | ||
46 | return rc; | ||
76 | 47 | ||
77 | return nbytes; | 48 | return nbytes; |
78 | } | 49 | } |
79 | 50 | ||
80 | static ssize_t remove_slot_store(struct dlpar_io_attr *dlpar_attr, | 51 | static ssize_t add_slot_show(struct kobject *kobj, |
81 | const char *buf, size_t nbytes) | 52 | struct kobj_attribute *attr, char *buf) |
53 | { | ||
54 | return sprintf(buf, "0\n"); | ||
55 | } | ||
56 | |||
57 | static ssize_t remove_slot_store(struct kobject *kobj, | ||
58 | struct kobj_attribute *attr, | ||
59 | const char *buf, size_t nbytes) | ||
82 | { | 60 | { |
83 | char drc_name[MAX_DRC_NAME_LEN]; | 61 | char drc_name[MAX_DRC_NAME_LEN]; |
62 | int rc; | ||
84 | char *end; | 63 | char *end; |
85 | 64 | ||
86 | if (nbytes >= MAX_DRC_NAME_LEN) | 65 | if (nbytes >= MAX_DRC_NAME_LEN) |
@@ -93,22 +72,24 @@ static ssize_t remove_slot_store(struct dlpar_io_attr *dlpar_attr, | |||
93 | end = &drc_name[nbytes]; | 72 | end = &drc_name[nbytes]; |
94 | *end = '\0'; | 73 | *end = '\0'; |
95 | 74 | ||
96 | dlpar_attr->rc = dlpar_remove_slot(drc_name); | 75 | rc = dlpar_remove_slot(drc_name); |
76 | if (rc) | ||
77 | return rc; | ||
97 | 78 | ||
98 | return nbytes; | 79 | return nbytes; |
99 | } | 80 | } |
100 | 81 | ||
101 | static struct dlpar_io_attr add_slot_attr = { | 82 | static ssize_t remove_slot_show(struct kobject *kobj, |
102 | .rc = 0, | 83 | struct kobj_attribute *attr, char *buf) |
103 | .attr = { .name = ADD_SLOT_ATTR_NAME, .mode = 0644, }, | 84 | { |
104 | .store = add_slot_store, | 85 | return sprintf(buf, "0\n"); |
105 | }; | 86 | } |
106 | 87 | ||
107 | static struct dlpar_io_attr remove_slot_attr = { | 88 | static struct kobj_attribute add_slot_attr = |
108 | .rc = 0, | 89 | __ATTR(ADD_SLOT_ATTR_NAME, 0644, add_slot_show, add_slot_store); |
109 | .attr = { .name = REMOVE_SLOT_ATTR_NAME, .mode = 0644}, | 90 | |
110 | .store = remove_slot_store, | 91 | static struct kobj_attribute remove_slot_attr = |
111 | }; | 92 | __ATTR(REMOVE_SLOT_ATTR_NAME, 0644, remove_slot_show, remove_slot_store); |
112 | 93 | ||
113 | static struct attribute *default_attrs[] = { | 94 | static struct attribute *default_attrs[] = { |
114 | &add_slot_attr.attr, | 95 | &add_slot_attr.attr, |
@@ -116,36 +97,29 @@ static struct attribute *default_attrs[] = { | |||
116 | NULL, | 97 | NULL, |
117 | }; | 98 | }; |
118 | 99 | ||
119 | static void dlpar_io_release(struct kobject *kobj) | 100 | static struct attribute_group dlpar_attr_group = { |
120 | { | 101 | .attrs = default_attrs, |
121 | /* noop */ | ||
122 | return; | ||
123 | } | ||
124 | |||
125 | struct kobj_type ktype_dlpar_io = { | ||
126 | .release = dlpar_io_release, | ||
127 | .sysfs_ops = &dlpar_attr_sysfs_ops, | ||
128 | .default_attrs = default_attrs, | ||
129 | }; | 102 | }; |
130 | 103 | ||
131 | struct kset dlpar_io_kset = { | 104 | static struct kobject *dlpar_kobj; |
132 | .kobj = {.ktype = &ktype_dlpar_io, | ||
133 | .parent = &pci_hotplug_slots_kset->kobj}, | ||
134 | }; | ||
135 | 105 | ||
136 | int dlpar_sysfs_init(void) | 106 | int dlpar_sysfs_init(void) |
137 | { | 107 | { |
138 | kobject_set_name(&dlpar_io_kset.kobj, DLPAR_KOBJ_NAME); | 108 | int error; |
139 | if (kset_register(&dlpar_io_kset)) { | 109 | |
140 | printk(KERN_ERR "rpadlpar_io: cannot register kset for %s\n", | 110 | dlpar_kobj = kobject_create_and_add(DLPAR_KOBJ_NAME, |
141 | kobject_name(&dlpar_io_kset.kobj)); | 111 | &pci_hotplug_slots_kset->kobj); |
112 | if (!dlpar_kobj) | ||
142 | return -EINVAL; | 113 | return -EINVAL; |
143 | } | ||
144 | 114 | ||
145 | return 0; | 115 | error = sysfs_create_group(dlpar_kobj, &dlpar_attr_group); |
116 | if (error) | ||
117 | kobject_unregister(dlpar_kobj); | ||
118 | return error; | ||
146 | } | 119 | } |
147 | 120 | ||
148 | void dlpar_sysfs_exit(void) | 121 | void dlpar_sysfs_exit(void) |
149 | { | 122 | { |
150 | kset_unregister(&dlpar_io_kset); | 123 | sysfs_remove_group(dlpar_kobj, &dlpar_attr_group); |
124 | kobject_unregister(dlpar_kobj); | ||
151 | } | 125 | } |