aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2009-04-30 09:23:42 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-06-16 00:30:25 -0400
commit6fcf53acccf85b4b0d0260e66c692a341760f464 (patch)
tree445f725558bde27492095f8d05cc645315f8c1c1 /drivers
parentacc0e90fbccbc6e4d48184cba0983ea044e131af (diff)
Driver Core: add nodename callbacks
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/base/core.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 4d59975c24a8..7ecb1938e590 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -162,10 +162,18 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,
162 struct device *dev = to_dev(kobj); 162 struct device *dev = to_dev(kobj);
163 int retval = 0; 163 int retval = 0;
164 164
165 /* add the major/minor if present */ 165 /* add device node properties if present */
166 if (MAJOR(dev->devt)) { 166 if (MAJOR(dev->devt)) {
167 const char *tmp;
168 const char *name;
169
167 add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt)); 170 add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt));
168 add_uevent_var(env, "MINOR=%u", MINOR(dev->devt)); 171 add_uevent_var(env, "MINOR=%u", MINOR(dev->devt));
172 name = device_get_nodename(dev, &tmp);
173 if (name) {
174 add_uevent_var(env, "DEVNAME=%s", name);
175 kfree(tmp);
176 }
169 } 177 }
170 178
171 if (dev->type && dev->type->name) 179 if (dev->type && dev->type->name)
@@ -1129,6 +1137,47 @@ static struct device *next_device(struct klist_iter *i)
1129} 1137}
1130 1138
1131/** 1139/**
1140 * device_get_nodename - path of device node file
1141 * @dev: device
1142 * @tmp: possibly allocated string
1143 *
1144 * Return the relative path of a possible device node.
1145 * Non-default names may need to allocate a memory to compose
1146 * a name. This memory is returned in tmp and needs to be
1147 * freed by the caller.
1148 */
1149const char *device_get_nodename(struct device *dev, const char **tmp)
1150{
1151 char *s;
1152
1153 *tmp = NULL;
1154
1155 /* the device type may provide a specific name */
1156 if (dev->type && dev->type->nodename)
1157 *tmp = dev->type->nodename(dev);
1158 if (*tmp)
1159 return *tmp;
1160
1161 /* the class may provide a specific name */
1162 if (dev->class && dev->class->nodename)
1163 *tmp = dev->class->nodename(dev);
1164 if (*tmp)
1165 return *tmp;
1166
1167 /* return name without allocation, tmp == NULL */
1168 if (strchr(dev_name(dev), '!') == NULL)
1169 return dev_name(dev);
1170
1171 /* replace '!' in the name with '/' */
1172 *tmp = kstrdup(dev_name(dev), GFP_KERNEL);
1173 if (!*tmp)
1174 return NULL;
1175 while ((s = strchr(*tmp, '!')))
1176 s[0] = '/';
1177 return *tmp;
1178}
1179
1180/**
1132 * device_for_each_child - device child iterator. 1181 * device_for_each_child - device child iterator.
1133 * @parent: parent struct device. 1182 * @parent: parent struct device.
1134 * @data: data for the callback. 1183 * @data: data for the callback.