diff options
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/core.c | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index c34a4d8842e1..72c6ee57471b 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -246,6 +246,53 @@ static struct kset_uevent_ops device_uevent_ops = { | |||
246 | .uevent = dev_uevent, | 246 | .uevent = dev_uevent, |
247 | }; | 247 | }; |
248 | 248 | ||
249 | static ssize_t show_uevent(struct device *dev, struct device_attribute *attr, | ||
250 | char *buf) | ||
251 | { | ||
252 | struct kobject *top_kobj; | ||
253 | struct kset *kset; | ||
254 | char *envp[32]; | ||
255 | char data[PAGE_SIZE]; | ||
256 | char *pos; | ||
257 | int i; | ||
258 | size_t count = 0; | ||
259 | int retval; | ||
260 | |||
261 | /* search the kset, the device belongs to */ | ||
262 | top_kobj = &dev->kobj; | ||
263 | if (!top_kobj->kset && top_kobj->parent) { | ||
264 | do { | ||
265 | top_kobj = top_kobj->parent; | ||
266 | } while (!top_kobj->kset && top_kobj->parent); | ||
267 | } | ||
268 | if (!top_kobj->kset) | ||
269 | goto out; | ||
270 | kset = top_kobj->kset; | ||
271 | if (!kset->uevent_ops || !kset->uevent_ops->uevent) | ||
272 | goto out; | ||
273 | |||
274 | /* respect filter */ | ||
275 | if (kset->uevent_ops && kset->uevent_ops->filter) | ||
276 | if (!kset->uevent_ops->filter(kset, &dev->kobj)) | ||
277 | goto out; | ||
278 | |||
279 | /* let the kset specific function add its keys */ | ||
280 | pos = data; | ||
281 | retval = kset->uevent_ops->uevent(kset, &dev->kobj, | ||
282 | envp, ARRAY_SIZE(envp), | ||
283 | pos, PAGE_SIZE); | ||
284 | if (retval) | ||
285 | goto out; | ||
286 | |||
287 | /* copy keys to file */ | ||
288 | for (i = 0; envp[i]; i++) { | ||
289 | pos = &buf[count]; | ||
290 | count += sprintf(pos, "%s\n", envp[i]); | ||
291 | } | ||
292 | out: | ||
293 | return count; | ||
294 | } | ||
295 | |||
249 | static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, | 296 | static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, |
250 | const char *buf, size_t count) | 297 | const char *buf, size_t count) |
251 | { | 298 | { |
@@ -621,10 +668,11 @@ int device_add(struct device *dev) | |||
621 | BUS_NOTIFY_ADD_DEVICE, dev); | 668 | BUS_NOTIFY_ADD_DEVICE, dev); |
622 | 669 | ||
623 | dev->uevent_attr.attr.name = "uevent"; | 670 | dev->uevent_attr.attr.name = "uevent"; |
624 | dev->uevent_attr.attr.mode = S_IWUSR; | 671 | dev->uevent_attr.attr.mode = S_IRUGO | S_IWUSR; |
625 | if (dev->driver) | 672 | if (dev->driver) |
626 | dev->uevent_attr.attr.owner = dev->driver->owner; | 673 | dev->uevent_attr.attr.owner = dev->driver->owner; |
627 | dev->uevent_attr.store = store_uevent; | 674 | dev->uevent_attr.store = store_uevent; |
675 | dev->uevent_attr.show = show_uevent; | ||
628 | error = device_create_file(dev, &dev->uevent_attr); | 676 | error = device_create_file(dev, &dev->uevent_attr); |
629 | if (error) | 677 | if (error) |
630 | goto attrError; | 678 | goto attrError; |