diff options
-rw-r--r-- | drivers/base/core.c | 23 | ||||
-rw-r--r-- | include/linux/kobject.h | 25 | ||||
-rw-r--r-- | lib/kobject_uevent.c | 30 |
3 files changed, 47 insertions, 31 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index 0455aa78fa13..91a0367d583e 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -24,6 +24,8 @@ | |||
24 | #include "base.h" | 24 | #include "base.h" |
25 | #include "power/power.h" | 25 | #include "power/power.h" |
26 | 26 | ||
27 | extern const char *kobject_actions[]; | ||
28 | |||
27 | int (*platform_notify)(struct device * dev) = NULL; | 29 | int (*platform_notify)(struct device * dev) = NULL; |
28 | int (*platform_notify_remove)(struct device * dev) = NULL; | 30 | int (*platform_notify_remove)(struct device * dev) = NULL; |
29 | 31 | ||
@@ -303,10 +305,25 @@ out: | |||
303 | static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, | 305 | static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, |
304 | const char *buf, size_t count) | 306 | const char *buf, size_t count) |
305 | { | 307 | { |
306 | if (memcmp(buf, "add", 3) != 0) | 308 | size_t len = count; |
307 | dev_err(dev, "uevent: unsupported action-string; this will " | 309 | enum kobject_action action; |
308 | "be ignored in a future kernel version"); | 310 | |
311 | if (len && buf[len-1] == '\n') | ||
312 | len--; | ||
313 | |||
314 | for (action = 0; action < KOBJ_MAX; action++) { | ||
315 | if (strncmp(kobject_actions[action], buf, len) != 0) | ||
316 | continue; | ||
317 | if (kobject_actions[action][len] != '\0') | ||
318 | continue; | ||
319 | kobject_uevent(&dev->kobj, action); | ||
320 | goto out; | ||
321 | } | ||
322 | |||
323 | dev_err(dev, "uevent: unsupported action-string; this will " | ||
324 | "be ignored in a future kernel version\n"); | ||
309 | kobject_uevent(&dev->kobj, KOBJ_ADD); | 325 | kobject_uevent(&dev->kobj, KOBJ_ADD); |
326 | out: | ||
310 | return count; | 327 | return count; |
311 | } | 328 | } |
312 | 329 | ||
diff --git a/include/linux/kobject.h b/include/linux/kobject.h index 06cbf41d32d2..aa2fe22b1baa 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h | |||
@@ -36,15 +36,24 @@ extern char uevent_helper[]; | |||
36 | /* counter to tag the uevent, read only except for the kobject core */ | 36 | /* counter to tag the uevent, read only except for the kobject core */ |
37 | extern u64 uevent_seqnum; | 37 | extern u64 uevent_seqnum; |
38 | 38 | ||
39 | /* the actions here must match the proper string in lib/kobject_uevent.c */ | 39 | /* |
40 | typedef int __bitwise kobject_action_t; | 40 | * The actions here must match the index to the string array |
41 | * in lib/kobject_uevent.c | ||
42 | * | ||
43 | * Do not add new actions here without checking with the driver-core | ||
44 | * maintainers. Action strings are not meant to express subsystem | ||
45 | * or device specific properties. In most cases you want to send a | ||
46 | * kobject_uevent_env(kobj, KOBJ_CHANGE, env) with additional event | ||
47 | * specific variables added to the event environment. | ||
48 | */ | ||
41 | enum kobject_action { | 49 | enum kobject_action { |
42 | KOBJ_ADD = (__force kobject_action_t) 0x01, /* exclusive to core */ | 50 | KOBJ_ADD, |
43 | KOBJ_REMOVE = (__force kobject_action_t) 0x02, /* exclusive to core */ | 51 | KOBJ_REMOVE, |
44 | KOBJ_CHANGE = (__force kobject_action_t) 0x03, /* device state change */ | 52 | KOBJ_CHANGE, |
45 | KOBJ_OFFLINE = (__force kobject_action_t) 0x04, /* device offline */ | 53 | KOBJ_MOVE, |
46 | KOBJ_ONLINE = (__force kobject_action_t) 0x05, /* device online */ | 54 | KOBJ_ONLINE, |
47 | KOBJ_MOVE = (__force kobject_action_t) 0x06, /* device move */ | 55 | KOBJ_OFFLINE, |
56 | KOBJ_MAX | ||
48 | }; | 57 | }; |
49 | 58 | ||
50 | struct kobject { | 59 | struct kobject { |
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index bd5ecbbafab1..6a80c784a8fb 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c | |||
@@ -33,25 +33,15 @@ static DEFINE_SPINLOCK(sequence_lock); | |||
33 | static struct sock *uevent_sock; | 33 | static struct sock *uevent_sock; |
34 | #endif | 34 | #endif |
35 | 35 | ||
36 | static char *action_to_string(enum kobject_action action) | 36 | /* the strings here must match the enum in include/linux/kobject.h */ |
37 | { | 37 | const char *kobject_actions[] = { |
38 | switch (action) { | 38 | "add", |
39 | case KOBJ_ADD: | 39 | "remove", |
40 | return "add"; | 40 | "change", |
41 | case KOBJ_REMOVE: | 41 | "move", |
42 | return "remove"; | 42 | "online", |
43 | case KOBJ_CHANGE: | 43 | "offline", |
44 | return "change"; | 44 | }; |
45 | case KOBJ_OFFLINE: | ||
46 | return "offline"; | ||
47 | case KOBJ_ONLINE: | ||
48 | return "online"; | ||
49 | case KOBJ_MOVE: | ||
50 | return "move"; | ||
51 | default: | ||
52 | return NULL; | ||
53 | } | ||
54 | } | ||
55 | 45 | ||
56 | /** | 46 | /** |
57 | * kobject_uevent_env - send an uevent with environmental data | 47 | * kobject_uevent_env - send an uevent with environmental data |
@@ -83,7 +73,7 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, | |||
83 | 73 | ||
84 | pr_debug("%s\n", __FUNCTION__); | 74 | pr_debug("%s\n", __FUNCTION__); |
85 | 75 | ||
86 | action_string = action_to_string(action); | 76 | action_string = kobject_actions[action]; |
87 | if (!action_string) { | 77 | if (!action_string) { |
88 | pr_debug("kobject attempted to send uevent without action_string!\n"); | 78 | pr_debug("kobject attempted to send uevent without action_string!\n"); |
89 | return -EINVAL; | 79 | return -EINVAL; |