lkml.org 
[lkml]   [2009]   [May]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[patch 01/13] Driver Core: add nodename callbacks
From: Kay Sievers <kay.sievers@vrfy.org>

This adds the nodename callback for struct class, struct device_type and
struct device, to allow drivers to send userspace hints on the device
name and subdirectory that should be used for it.

Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Jan Blunck <jblunck@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
drivers/base/core.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++-
include/linux/device.h | 4 +++
2 files changed, 54 insertions(+), 1 deletion(-)
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -161,10 +161,18 @@ static int dev_uevent(struct kset *kset,
struct device *dev = to_dev(kobj);
int retval = 0;

- /* add the major/minor if present */
+ /* add device node properties if present */
if (MAJOR(dev->devt)) {
+ const char *tmp;
+ const char *name;
+
add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt));
add_uevent_var(env, "MINOR=%u", MINOR(dev->devt));
+ name = device_get_nodename(dev, &tmp);
+ if (name) {
+ add_uevent_var(env, "DEVNAME=%s", name);
+ kfree(tmp);
+ }
}

if (dev->type && dev->type->name)
@@ -1125,6 +1133,47 @@ static struct device *next_device(struct
}

/**
+ * device_get_nodename - path of device node file
+ * @dev: device
+ * @tmp: possibly allocated string
+ *
+ * Return the relative path of a possible device node.
+ * Non-default names may need to allocate a memory to compose
+ * a name. This memory is returned in tmp and needs to be
+ * freed by the caller.
+ */
+const char *device_get_nodename(struct device *dev, const char **tmp)
+{
+ char *s;
+
+ *tmp = NULL;
+
+ /* the device type may provide a specific name */
+ if (dev->type && dev->type->nodename)
+ *tmp = dev->type->nodename(dev);
+ if (*tmp)
+ return *tmp;
+
+ /* the class may provide a specific name */
+ if (dev->class && dev->class->nodename)
+ *tmp = dev->class->nodename(dev);
+ if (*tmp)
+ return *tmp;
+
+ /* return name without allocation, tmp == NULL */
+ if (strchr(dev_name(dev), '!') == NULL)
+ return dev_name(dev);
+
+ /* replace '!' in the name with '/' */
+ *tmp = kstrdup(dev_name(dev), GFP_KERNEL);
+ if (!*tmp)
+ return NULL;
+ while ((s = strchr(*tmp, '!')))
+ s[0] = '/';
+ return *tmp;
+}
+
+/**
* device_for_each_child - device child iterator.
* @parent: parent struct device.
* @data: data for the callback.
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -196,6 +196,7 @@ struct class {
struct kobject *dev_kobj;

int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
+ char *(*nodename)(struct device *dev);

void (*class_release)(struct class *class);
void (*dev_release)(struct device *dev);
@@ -291,6 +292,7 @@ struct device_type {
const char *name;
struct attribute_group **groups;
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
+ char *(*nodename)(struct device *dev);
void (*release)(struct device *dev);

int (*suspend)(struct device *dev, pm_message_t state);
@@ -371,6 +373,7 @@ struct device_dma_parameters {

struct device {
struct device *parent;
+ char *(*nodename)(struct device *dev);

struct device_private *p;

@@ -493,6 +496,7 @@ extern struct device *device_find_child(
extern int device_rename(struct device *dev, char *new_name);
extern int device_move(struct device *dev, struct device *new_parent,
enum dpm_order dpm_order);
+extern const char *device_get_nodename(struct device *dev, const char **tmp);

/*
* Root device objects for grouping under /sys/devices



\
 
 \ /
  Last update: 2009-05-09 16:47    [from the cache]
©2003-2011 Jasper Spaans