Driver core: change add_uevent_var to use a struct
This changes the uevent buffer functions to use a struct instead of a long list of parameters. It does no longer require the caller to do the proper buffer termination and size accounting, which is currently wrong in some places. It fixes a known bug where parts of the uevent environment are overwritten because of wrong index calculations. Many thanks to Mathieu Desnoyers for finding bugs and improving the error handling. Signed-off-by: Kay Sievers <kay.sievers@vrfy.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> Cc: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
8380770c84
commit
7eff2e7a8b
47 changed files with 300 additions and 636 deletions
|
@ -66,8 +66,7 @@ static int tiocx_match(struct device *dev, struct device_driver *drv)
|
|||
|
||||
}
|
||||
|
||||
static int tiocx_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
static int tiocx_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
|
@ -57,26 +57,21 @@ ssize_t of_device_get_modalias(struct of_device *ofdev,
|
|||
return tsize;
|
||||
}
|
||||
|
||||
int of_device_uevent(struct device *dev,
|
||||
char **envp, int num_envp, char *buffer, int buffer_size)
|
||||
int of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct of_device *ofdev;
|
||||
const char *compat;
|
||||
int i = 0, length = 0, seen = 0, cplen, sl;
|
||||
int seen = 0, cplen, sl;
|
||||
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
|
||||
ofdev = to_of_device(dev);
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"OF_NAME=%s", ofdev->node->name))
|
||||
if (add_uevent_var(env, "OF_NAME=%s", ofdev->node->name))
|
||||
return -ENOMEM;
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"OF_TYPE=%s", ofdev->node->type))
|
||||
if (add_uevent_var(env, "OF_TYPE=%s", ofdev->node->type))
|
||||
return -ENOMEM;
|
||||
|
||||
/* Since the compatible field can contain pretty much anything
|
||||
|
@ -85,9 +80,7 @@ int of_device_uevent(struct device *dev,
|
|||
|
||||
compat = of_get_property(ofdev->node, "compatible", &cplen);
|
||||
while (compat && *compat && cplen > 0) {
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"OF_COMPATIBLE_%d=%s", seen, compat))
|
||||
if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat))
|
||||
return -ENOMEM;
|
||||
|
||||
sl = strlen (compat) + 1;
|
||||
|
@ -96,25 +89,17 @@ int of_device_uevent(struct device *dev,
|
|||
seen++;
|
||||
}
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"OF_COMPATIBLE_N=%d", seen))
|
||||
if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen))
|
||||
return -ENOMEM;
|
||||
|
||||
/* modalias is trickier, we add it in 2 steps */
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"MODALIAS="))
|
||||
if (add_uevent_var(env, "MODALIAS="))
|
||||
return -ENOMEM;
|
||||
|
||||
sl = of_device_get_modalias(ofdev, &buffer[length-1],
|
||||
buffer_size-length);
|
||||
if (sl >= (buffer_size-length))
|
||||
sl = of_device_get_modalias(ofdev, &env->buf[env->buflen-1],
|
||||
sizeof(env->buf) - env->buflen);
|
||||
if (sl >= (sizeof(env->buf) - env->buflen))
|
||||
return -ENOMEM;
|
||||
|
||||
length += sl;
|
||||
|
||||
envp[i] = NULL;
|
||||
env->buflen += sl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -317,30 +317,20 @@ static int vio_bus_match(struct device *dev, struct device_driver *drv)
|
|||
return (ids != NULL) && (vio_match_device(ids, vio_dev) != NULL);
|
||||
}
|
||||
|
||||
static int vio_hotplug(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
static int vio_hotplug(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
const struct vio_dev *vio_dev = to_vio_dev(dev);
|
||||
struct device_node *dn;
|
||||
const char *cp;
|
||||
int length;
|
||||
|
||||
if (!num_envp)
|
||||
return -ENOMEM;
|
||||
|
||||
dn = dev->archdata.of_node;
|
||||
if (!dn)
|
||||
return -ENODEV;
|
||||
cp = of_get_property(dn, "compatible", &length);
|
||||
cp = of_get_property(dn, "compatible", NULL);
|
||||
if (!cp)
|
||||
return -ENODEV;
|
||||
|
||||
envp[0] = buffer;
|
||||
length = scnprintf(buffer, buffer_size, "MODALIAS=vio:T%sS%s",
|
||||
vio_dev->type, cp);
|
||||
if ((buffer_size - length) <= 0)
|
||||
return -ENOMEM;
|
||||
envp[1] = NULL;
|
||||
add_uevent_var(env, "MODALIAS=vio:T%sS%s", vio_dev->type, cp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -437,18 +437,13 @@ static void ps3_system_bus_shutdown(struct device *_dev)
|
|||
dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
|
||||
}
|
||||
|
||||
static int ps3_system_bus_uevent(struct device *_dev, char **envp,
|
||||
int num_envp, char *buffer, int buffer_size)
|
||||
static int ps3_system_bus_uevent(struct device *_dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
|
||||
int i = 0, length = 0;
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
|
||||
&length, "MODALIAS=ps3:%d",
|
||||
dev->match_id))
|
||||
if (add_uevent_var(env, "MODALIAS=ps3:%d", dev->match_id))
|
||||
return -ENOMEM;
|
||||
|
||||
envp[i] = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -540,61 +540,42 @@ static int block_uevent_filter(struct kset *kset, struct kobject *kobj)
|
|||
return ((ktype == &ktype_block) || (ktype == &ktype_part));
|
||||
}
|
||||
|
||||
static int block_uevent(struct kset *kset, struct kobject *kobj, char **envp,
|
||||
int num_envp, char *buffer, int buffer_size)
|
||||
static int block_uevent(struct kset *kset, struct kobject *kobj,
|
||||
struct kobj_uevent_env *env)
|
||||
{
|
||||
struct kobj_type *ktype = get_ktype(kobj);
|
||||
struct device *physdev;
|
||||
struct gendisk *disk;
|
||||
struct hd_struct *part;
|
||||
int length = 0;
|
||||
int i = 0;
|
||||
|
||||
if (ktype == &ktype_block) {
|
||||
disk = container_of(kobj, struct gendisk, kobj);
|
||||
add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
|
||||
&length, "MINOR=%u", disk->first_minor);
|
||||
add_uevent_var(env, "MINOR=%u", disk->first_minor);
|
||||
} else if (ktype == &ktype_part) {
|
||||
disk = container_of(kobj->parent, struct gendisk, kobj);
|
||||
part = container_of(kobj, struct hd_struct, kobj);
|
||||
add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
|
||||
&length, "MINOR=%u",
|
||||
add_uevent_var(env, "MINOR=%u",
|
||||
disk->first_minor + part->partno);
|
||||
} else
|
||||
return 0;
|
||||
|
||||
add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
|
||||
"MAJOR=%u", disk->major);
|
||||
add_uevent_var(env, "MAJOR=%u", disk->major);
|
||||
|
||||
/* add physical device, backing this device */
|
||||
physdev = disk->driverfs_dev;
|
||||
if (physdev) {
|
||||
char *path = kobject_get_path(&physdev->kobj, GFP_KERNEL);
|
||||
|
||||
add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
|
||||
&length, "PHYSDEVPATH=%s", path);
|
||||
add_uevent_var(env, "PHYSDEVPATH=%s", path);
|
||||
kfree(path);
|
||||
|
||||
if (physdev->bus)
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PHYSDEVBUS=%s",
|
||||
physdev->bus->name);
|
||||
add_uevent_var(env, "PHYSDEVBUS=%s", physdev->bus->name);
|
||||
|
||||
if (physdev->driver)
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PHYSDEVDRIVER=%s",
|
||||
physdev->driver->name);
|
||||
add_uevent_var(env, physdev->driver->name);
|
||||
}
|
||||
|
||||
/* terminate, set to next free slot, shrink available space */
|
||||
envp[i] = NULL;
|
||||
envp = &envp[i];
|
||||
num_envp -= i;
|
||||
buffer = &buffer[length];
|
||||
buffer_size -= length;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -319,16 +319,18 @@ static int acpi_bus_match(struct device *dev, struct device_driver *drv)
|
|||
return !acpi_match_device_ids(acpi_dev, acpi_drv->ids);
|
||||
}
|
||||
|
||||
static int acpi_device_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct acpi_device *acpi_dev = to_acpi_device(dev);
|
||||
int len;
|
||||
|
||||
strcpy(buffer, "MODALIAS=");
|
||||
if (create_modalias(acpi_dev, buffer + 9, buffer_size - 9) > 0) {
|
||||
envp[0] = buffer;
|
||||
envp[1] = NULL;
|
||||
}
|
||||
if (add_uevent_var(env, "MODALIAS="))
|
||||
return -ENOMEM;
|
||||
len = create_modalias(acpi_dev, &env->buf[env->buflen - 1],
|
||||
sizeof(env->buf) - env->buflen);
|
||||
if (len >= (sizeof(env->buf) - env->buflen))
|
||||
return -ENOMEM;
|
||||
env->buflen += len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,15 +44,12 @@ static int amba_match(struct device *dev, struct device_driver *drv)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG
|
||||
static int amba_uevent(struct device *dev, char **envp, int nr_env, char *buf, int bufsz)
|
||||
static int amba_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct amba_device *pcdev = to_amba_device(dev);
|
||||
int retval = 0, i = 0, len = 0;
|
||||
int retval = 0;
|
||||
|
||||
retval = add_uevent_var(envp, nr_env, &i,
|
||||
buf, bufsz, &len,
|
||||
"AMBA_ID=%08x", pcdev->periphid);
|
||||
envp[i] = NULL;
|
||||
retval = add_uevent_var(env, "AMBA_ID=%08x", pcdev->periphid);
|
||||
return retval;
|
||||
}
|
||||
#else
|
||||
|
|
|
@ -180,8 +180,7 @@ static void class_device_create_release(struct class_device *class_dev)
|
|||
|
||||
/* needed to allow these devices to have parent class devices */
|
||||
static int class_device_create_uevent(struct class_device *class_dev,
|
||||
char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
struct kobj_uevent_env *env)
|
||||
{
|
||||
pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id);
|
||||
return 0;
|
||||
|
@ -403,64 +402,43 @@ static void remove_deprecated_class_device_links(struct class_device *cd)
|
|||
{ }
|
||||
#endif
|
||||
|
||||
static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp,
|
||||
int num_envp, char *buffer, int buffer_size)
|
||||
static int class_uevent(struct kset *kset, struct kobject *kobj,
|
||||
struct kobj_uevent_env *env)
|
||||
{
|
||||
struct class_device *class_dev = to_class_dev(kobj);
|
||||
struct device *dev = class_dev->dev;
|
||||
int i = 0;
|
||||
int length = 0;
|
||||
int retval = 0;
|
||||
|
||||
pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id);
|
||||
|
||||
if (MAJOR(class_dev->devt)) {
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"MAJOR=%u", MAJOR(class_dev->devt));
|
||||
add_uevent_var(env, "MAJOR=%u", MAJOR(class_dev->devt));
|
||||
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"MINOR=%u", MINOR(class_dev->devt));
|
||||
add_uevent_var(env, "MINOR=%u", MINOR(class_dev->devt));
|
||||
}
|
||||
|
||||
if (dev) {
|
||||
const char *path = kobject_get_path(&dev->kobj, GFP_KERNEL);
|
||||
if (path) {
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PHYSDEVPATH=%s", path);
|
||||
add_uevent_var(env, "PHYSDEVPATH=%s", path);
|
||||
kfree(path);
|
||||
}
|
||||
|
||||
if (dev->bus)
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PHYSDEVBUS=%s", dev->bus->name);
|
||||
add_uevent_var(env, "PHYSDEVBUS=%s", dev->bus->name);
|
||||
|
||||
if (dev->driver)
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PHYSDEVDRIVER=%s", dev->driver->name);
|
||||
add_uevent_var(env, "PHYSDEVDRIVER=%s", dev->driver->name);
|
||||
}
|
||||
|
||||
/* terminate, set to next free slot, shrink available space */
|
||||
envp[i] = NULL;
|
||||
envp = &envp[i];
|
||||
num_envp -= i;
|
||||
buffer = &buffer[length];
|
||||
buffer_size -= length;
|
||||
|
||||
if (class_dev->uevent) {
|
||||
/* have the class device specific function add its stuff */
|
||||
retval = class_dev->uevent(class_dev, envp, num_envp,
|
||||
buffer, buffer_size);
|
||||
retval = class_dev->uevent(class_dev, env);
|
||||
if (retval)
|
||||
pr_debug("class_dev->uevent() returned %d\n", retval);
|
||||
} else if (class_dev->class->uevent) {
|
||||
/* have the class specific function add its stuff */
|
||||
retval = class_dev->class->uevent(class_dev, envp, num_envp,
|
||||
buffer, buffer_size);
|
||||
retval = class_dev->class->uevent(class_dev, env);
|
||||
if (retval)
|
||||
pr_debug("class->uevent() returned %d\n", retval);
|
||||
}
|
||||
|
|
|
@ -141,33 +141,23 @@ static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
|
||||
int num_envp, char *buffer, int buffer_size)
|
||||
static int dev_uevent(struct kset *kset, struct kobject *kobj,
|
||||
struct kobj_uevent_env *env)
|
||||
{
|
||||
struct device *dev = to_dev(kobj);
|
||||
int i = 0;
|
||||
int length = 0;
|
||||
int retval = 0;
|
||||
|
||||
/* add the major/minor if present */
|
||||
if (MAJOR(dev->devt)) {
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"MAJOR=%u", MAJOR(dev->devt));
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"MINOR=%u", MINOR(dev->devt));
|
||||
add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt));
|
||||
add_uevent_var(env, "MINOR=%u", MINOR(dev->devt));
|
||||
}
|
||||
|
||||
if (dev->type && dev->type->name)
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"DEVTYPE=%s", dev->type->name);
|
||||
add_uevent_var(env, "DEVTYPE=%s", dev->type->name);
|
||||
|
||||
if (dev->driver)
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"DRIVER=%s", dev->driver->name);
|
||||
add_uevent_var(env, "DRIVER=%s", dev->driver->name);
|
||||
|
||||
#ifdef CONFIG_SYSFS_DEPRECATED
|
||||
if (dev->class) {
|
||||
|
@ -181,59 +171,43 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
|
|||
|
||||
path = kobject_get_path(&parent->kobj, GFP_KERNEL);
|
||||
if (path) {
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PHYSDEVPATH=%s", path);
|
||||
add_uevent_var(env, "PHYSDEVPATH=%s", path);
|
||||
kfree(path);
|
||||
}
|
||||
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PHYSDEVBUS=%s", parent->bus->name);
|
||||
add_uevent_var(env, "PHYSDEVBUS=%s", parent->bus->name);
|
||||
|
||||
if (parent->driver)
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PHYSDEVDRIVER=%s", parent->driver->name);
|
||||
add_uevent_var(env, "PHYSDEVDRIVER=%s",
|
||||
parent->driver->name);
|
||||
}
|
||||
} else if (dev->bus) {
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PHYSDEVBUS=%s", dev->bus->name);
|
||||
add_uevent_var(env, "PHYSDEVBUS=%s", dev->bus->name);
|
||||
|
||||
if (dev->driver)
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PHYSDEVDRIVER=%s", dev->driver->name);
|
||||
add_uevent_var(env, "PHYSDEVDRIVER=%s", dev->driver->name);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* terminate, set to next free slot, shrink available space */
|
||||
envp[i] = NULL;
|
||||
envp = &envp[i];
|
||||
num_envp -= i;
|
||||
buffer = &buffer[length];
|
||||
buffer_size -= length;
|
||||
|
||||
/* have the bus specific function add its stuff */
|
||||
if (dev->bus && dev->bus->uevent) {
|
||||
/* have the bus specific function add its stuff */
|
||||
retval = dev->bus->uevent(dev, envp, num_envp, buffer, buffer_size);
|
||||
retval = dev->bus->uevent(dev, env);
|
||||
if (retval)
|
||||
pr_debug ("%s: bus uevent() returned %d\n",
|
||||
__FUNCTION__, retval);
|
||||
}
|
||||
|
||||
/* have the class specific function add its stuff */
|
||||
if (dev->class && dev->class->dev_uevent) {
|
||||
/* have the class specific function add its stuff */
|
||||
retval = dev->class->dev_uevent(dev, envp, num_envp, buffer, buffer_size);
|
||||
retval = dev->class->dev_uevent(dev, env);
|
||||
if (retval)
|
||||
pr_debug("%s: class uevent() returned %d\n",
|
||||
__FUNCTION__, retval);
|
||||
}
|
||||
|
||||
/* have the device type specific fuction add its stuff */
|
||||
if (dev->type && dev->type->uevent) {
|
||||
/* have the device type specific fuction add its stuff */
|
||||
retval = dev->type->uevent(dev, envp, num_envp, buffer, buffer_size);
|
||||
retval = dev->type->uevent(dev, env);
|
||||
if (retval)
|
||||
pr_debug("%s: dev_type uevent() returned %d\n",
|
||||
__FUNCTION__, retval);
|
||||
|
@ -253,9 +227,7 @@ static ssize_t show_uevent(struct device *dev, struct device_attribute *attr,
|
|||
{
|
||||
struct kobject *top_kobj;
|
||||
struct kset *kset;
|
||||
char *envp[32];
|
||||
char *data = NULL;
|
||||
char *pos;
|
||||
struct kobj_uevent_env *env = NULL;
|
||||
int i;
|
||||
size_t count = 0;
|
||||
int retval;
|
||||
|
@ -278,26 +250,20 @@ static ssize_t show_uevent(struct device *dev, struct device_attribute *attr,
|
|||
if (!kset->uevent_ops->filter(kset, &dev->kobj))
|
||||
goto out;
|
||||
|
||||
data = (char *)get_zeroed_page(GFP_KERNEL);
|
||||
if (!data)
|
||||
env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);
|
||||
if (!env)
|
||||
return -ENOMEM;
|
||||
|
||||
/* let the kset specific function add its keys */
|
||||
pos = data;
|
||||
memset(envp, 0, sizeof(envp));
|
||||
retval = kset->uevent_ops->uevent(kset, &dev->kobj,
|
||||
envp, ARRAY_SIZE(envp),
|
||||
pos, PAGE_SIZE);
|
||||
retval = kset->uevent_ops->uevent(kset, &dev->kobj, env);
|
||||
if (retval)
|
||||
goto out;
|
||||
|
||||
/* copy keys to file */
|
||||
for (i = 0; envp[i]; i++) {
|
||||
pos = &buf[count];
|
||||
count += sprintf(pos, "%s\n", envp[i]);
|
||||
}
|
||||
for (i = 0; i < env->envp_idx; i++)
|
||||
count += sprintf(&buf[count], "%s\n", env->envp[i]);
|
||||
out:
|
||||
free_page((unsigned long)data);
|
||||
kfree(env);
|
||||
return count;
|
||||
}
|
||||
|
||||
|
|
|
@ -88,19 +88,14 @@ static CLASS_ATTR(timeout, 0644, firmware_timeout_show, firmware_timeout_store);
|
|||
|
||||
static void fw_dev_release(struct device *dev);
|
||||
|
||||
static int firmware_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct firmware_priv *fw_priv = dev_get_drvdata(dev);
|
||||
int i = 0, len = 0;
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
|
||||
"FIRMWARE=%s", fw_priv->fw_id))
|
||||
if (add_uevent_var(env, "FIRMWARE=%s", fw_priv->fw_id))
|
||||
return -ENOMEM;
|
||||
if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
|
||||
"TIMEOUT=%i", loading_timeout))
|
||||
if (add_uevent_var(env, "TIMEOUT=%i", loading_timeout))
|
||||
return -ENOMEM;
|
||||
envp[i] = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -34,8 +34,7 @@ static const char *memory_uevent_name(struct kset *kset, struct kobject *kobj)
|
|||
return MEMORY_CLASS_NAME;
|
||||
}
|
||||
|
||||
static int memory_uevent(struct kset *kset, struct kobject *kobj, char **envp,
|
||||
int num_envp, char *buffer, int buffer_size)
|
||||
static int memory_uevent(struct kset *kset, struct kobj_uevent_env *env)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
|
|
|
@ -529,13 +529,11 @@ static struct device_attribute platform_dev_attrs[] = {
|
|||
__ATTR_NULL,
|
||||
};
|
||||
|
||||
static int platform_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
|
||||
envp[0] = buffer;
|
||||
snprintf(buffer, buffer_size, "MODALIAS=platform:%s", pdev->name);
|
||||
add_uevent_var(env, "MODALIAS=platform:%s", pdev->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -128,16 +128,11 @@ static int eisa_bus_match (struct device *dev, struct device_driver *drv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int eisa_bus_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
static int eisa_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct eisa_device *edev = to_eisa_device(dev);
|
||||
int i = 0;
|
||||
int length = 0;
|
||||
|
||||
add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
|
||||
"MODALIAS=" EISA_DEVICE_MODALIAS_FMT, edev->id.sig);
|
||||
envp[i] = NULL;
|
||||
add_uevent_var(env, "MODALIAS=" EISA_DEVICE_MODALIAS_FMT, edev->id.sig);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -130,23 +130,16 @@ static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size)
|
|||
}
|
||||
|
||||
static int
|
||||
fw_unit_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
fw_unit_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct fw_unit *unit = fw_unit(dev);
|
||||
char modalias[64];
|
||||
int length = 0;
|
||||
int i = 0;
|
||||
|
||||
get_modalias(unit, modalias, sizeof(modalias));
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"MODALIAS=%s", modalias))
|
||||
if (add_uevent_var(env, "MODALIAS=%s", modalias))
|
||||
return -ENOMEM;
|
||||
|
||||
envp[i] = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -134,14 +134,17 @@ static struct attribute_group* sys_dmi_attribute_groups[] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
static int dmi_dev_uevent(struct device *dev, char **envp,
|
||||
int num_envp, char *buffer, int buffer_size)
|
||||
static int dmi_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
strcpy(buffer, "MODALIAS=");
|
||||
get_modalias(buffer+9, buffer_size-9);
|
||||
envp[0] = buffer;
|
||||
envp[1] = NULL;
|
||||
ssize_t len;
|
||||
|
||||
if (add_uevent_var(env, "MODALIAS="))
|
||||
return -ENOMEM;
|
||||
len = get_modalias(&env->buf[env->buflen - 1],
|
||||
sizeof(env->buf) - env->buflen);
|
||||
if (len >= (sizeof(env->buf) - env->buflen))
|
||||
return -ENOMEM;
|
||||
env->buflen += len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -67,20 +67,16 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)
|
|||
#ifdef CONFIG_HOTPLUG
|
||||
|
||||
/* uevent helps with hotplug: modprobe -q $(MODALIAS) */
|
||||
static int i2c_device_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
int i = 0, length = 0;
|
||||
|
||||
/* by definition, legacy drivers can't hotplug */
|
||||
if (dev->driver || !client->driver_name)
|
||||
return 0;
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
|
||||
"MODALIAS=%s", client->driver_name))
|
||||
if (add_uevent_var(env, "MODALIAS=%s", client->driver_name))
|
||||
return -ENOMEM;
|
||||
envp[i] = NULL;
|
||||
dev_dbg(dev, "uevent\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1663,20 +1663,13 @@ static struct device_attribute ide_dev_attrs[] = {
|
|||
__ATTR_NULL
|
||||
};
|
||||
|
||||
static int ide_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
static int ide_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
ide_drive_t *drive = to_ide_device(dev);
|
||||
int i = 0;
|
||||
int length = 0;
|
||||
|
||||
add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
|
||||
"MEDIA=%s", media_string(drive));
|
||||
add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
|
||||
"DRIVENAME=%s", drive->name);
|
||||
add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
|
||||
"MODALIAS=ide:m-%s", media_string(drive));
|
||||
envp[i] = NULL;
|
||||
add_uevent_var(env, "MEDIA=%s", media_string(drive));
|
||||
add_uevent_var(env, "DRIVENAME=%s", drive->name);
|
||||
add_uevent_var(env, "MODALIAS=ide:m-%s", media_string(drive));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -153,8 +153,7 @@ struct host_info {
|
|||
};
|
||||
|
||||
static int nodemgr_bus_match(struct device * dev, struct device_driver * drv);
|
||||
static int nodemgr_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size);
|
||||
static int nodemgr_uevent(struct device *dev, struct kobj_uevent_env *env);
|
||||
static void nodemgr_resume_ne(struct node_entry *ne);
|
||||
static void nodemgr_remove_ne(struct node_entry *ne);
|
||||
static struct node_entry *find_entry_by_guid(u64 guid);
|
||||
|
@ -1160,12 +1159,9 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent
|
|||
|
||||
#ifdef CONFIG_HOTPLUG
|
||||
|
||||
static int nodemgr_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
static int nodemgr_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct unit_directory *ud;
|
||||
int i = 0;
|
||||
int length = 0;
|
||||
int retval = 0;
|
||||
/* ieee1394:venNmoNspNverN */
|
||||
char buf[8 + 1 + 3 + 8 + 2 + 8 + 2 + 8 + 3 + 8 + 1];
|
||||
|
@ -1180,9 +1176,7 @@ static int nodemgr_uevent(struct device *dev, char **envp, int num_envp,
|
|||
|
||||
#define PUT_ENVP(fmt,val) \
|
||||
do { \
|
||||
retval = add_uevent_var(envp, num_envp, &i, \
|
||||
buffer, buffer_size, &length, \
|
||||
fmt, val); \
|
||||
retval = add_uevent_var(env, fmt, val); \
|
||||
if (retval) \
|
||||
return retval; \
|
||||
} while (0)
|
||||
|
@ -1201,15 +1195,12 @@ do { \
|
|||
|
||||
#undef PUT_ENVP
|
||||
|
||||
envp[i] = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int nodemgr_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
static int nodemgr_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
|
@ -434,21 +434,18 @@ static void ib_device_release(struct class_device *cdev)
|
|||
kfree(dev);
|
||||
}
|
||||
|
||||
static int ib_device_uevent(struct class_device *cdev, char **envp,
|
||||
int num_envp, char *buf, int size)
|
||||
static int ib_device_uevent(struct class_device *cdev,
|
||||
struct kobj_uevent_env *env)
|
||||
{
|
||||
struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
|
||||
int i = 0, len = 0;
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i, buf, size, &len,
|
||||
"NAME=%s", dev->name))
|
||||
if (add_uevent_var(env, "NAME=%s", dev->name))
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* It would be nice to pass the node GUID with the event...
|
||||
*/
|
||||
|
||||
envp[i] = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -859,87 +859,66 @@ static void input_dev_release(struct device *device)
|
|||
* Input uevent interface - loading event handlers based on
|
||||
* device bitfields.
|
||||
*/
|
||||
static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index,
|
||||
char *buffer, int buffer_size, int *cur_len,
|
||||
static int input_add_uevent_bm_var(struct kobj_uevent_env *env,
|
||||
const char *name, unsigned long *bitmap, int max)
|
||||
{
|
||||
if (*cur_index >= num_envp - 1)
|
||||
int len;
|
||||
|
||||
if (add_uevent_var(env, "%s=", name))
|
||||
return -ENOMEM;
|
||||
|
||||
envp[*cur_index] = buffer + *cur_len;
|
||||
|
||||
*cur_len += snprintf(buffer + *cur_len, max(buffer_size - *cur_len, 0), name);
|
||||
if (*cur_len >= buffer_size)
|
||||
len = input_print_bitmap(&env->buf[env->buflen - 1],
|
||||
sizeof(env->buf) - env->buflen,
|
||||
bitmap, max, 0);
|
||||
if (len >= (sizeof(env->buf) - env->buflen))
|
||||
return -ENOMEM;
|
||||
|
||||
*cur_len += input_print_bitmap(buffer + *cur_len,
|
||||
max(buffer_size - *cur_len, 0),
|
||||
bitmap, max, 0) + 1;
|
||||
if (*cur_len > buffer_size)
|
||||
return -ENOMEM;
|
||||
|
||||
(*cur_index)++;
|
||||
env->buflen += len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int input_add_uevent_modalias_var(char **envp, int num_envp, int *cur_index,
|
||||
char *buffer, int buffer_size, int *cur_len,
|
||||
static int input_add_uevent_modalias_var(struct kobj_uevent_env *env,
|
||||
struct input_dev *dev)
|
||||
{
|
||||
if (*cur_index >= num_envp - 1)
|
||||
int len;
|
||||
|
||||
if (add_uevent_var(env, "MODALIAS="))
|
||||
return -ENOMEM;
|
||||
|
||||
envp[*cur_index] = buffer + *cur_len;
|
||||
|
||||
*cur_len += snprintf(buffer + *cur_len, max(buffer_size - *cur_len, 0),
|
||||
"MODALIAS=");
|
||||
if (*cur_len >= buffer_size)
|
||||
len = input_print_modalias(&env->buf[env->buflen - 1],
|
||||
sizeof(env->buf) - env->buflen,
|
||||
dev, 0);
|
||||
if (len >= (sizeof(env->buf) - env->buflen))
|
||||
return -ENOMEM;
|
||||
|
||||
*cur_len += input_print_modalias(buffer + *cur_len,
|
||||
max(buffer_size - *cur_len, 0),
|
||||
dev, 0) + 1;
|
||||
if (*cur_len > buffer_size)
|
||||
return -ENOMEM;
|
||||
|
||||
(*cur_index)++;
|
||||
env->buflen += len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define INPUT_ADD_HOTPLUG_VAR(fmt, val...) \
|
||||
do { \
|
||||
int err = add_uevent_var(envp, num_envp, &i, \
|
||||
buffer, buffer_size, &len, \
|
||||
fmt, val); \
|
||||
int err = add_uevent_var(env, fmt, val); \
|
||||
if (err) \
|
||||
return err; \
|
||||
} while (0)
|
||||
|
||||
#define INPUT_ADD_HOTPLUG_BM_VAR(name, bm, max) \
|
||||
do { \
|
||||
int err = input_add_uevent_bm_var(envp, num_envp, &i, \
|
||||
buffer, buffer_size, &len, \
|
||||
name, bm, max); \
|
||||
int err = input_add_uevent_bm_var(env, name, bm, max); \
|
||||
if (err) \
|
||||
return err; \
|
||||
} while (0)
|
||||
|
||||
#define INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev) \
|
||||
do { \
|
||||
int err = input_add_uevent_modalias_var(envp, \
|
||||
num_envp, &i, \
|
||||
buffer, buffer_size, &len, \
|
||||
dev); \
|
||||
int err = input_add_uevent_modalias_var(env, dev); \
|
||||
if (err) \
|
||||
return err; \
|
||||
} while (0)
|
||||
|
||||
static int input_dev_uevent(struct device *device, char **envp,
|
||||
int num_envp, char *buffer, int buffer_size)
|
||||
static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct input_dev *dev = to_input_dev(device);
|
||||
int i = 0;
|
||||
int len = 0;
|
||||
|
||||
INPUT_ADD_HOTPLUG_VAR("PRODUCT=%x/%x/%x/%x",
|
||||
dev->id.bustype, dev->id.vendor,
|
||||
|
@ -971,7 +950,6 @@ static int input_dev_uevent(struct device *device, char **envp,
|
|||
|
||||
INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev);
|
||||
|
||||
envp[i] = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -876,18 +876,14 @@ static int serio_bus_match(struct device *dev, struct device_driver *drv)
|
|||
|
||||
#define SERIO_ADD_UEVENT_VAR(fmt, val...) \
|
||||
do { \
|
||||
int err = add_uevent_var(envp, num_envp, &i, \
|
||||
buffer, buffer_size, &len, \
|
||||
fmt, val); \
|
||||
int err = add_uevent_var(env, fmt, val); \
|
||||
if (err) \
|
||||
return err; \
|
||||
} while (0)
|
||||
|
||||
static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
|
||||
static int serio_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct serio *serio;
|
||||
int i = 0;
|
||||
int len = 0;
|
||||
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
|
@ -900,7 +896,6 @@ static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buf
|
|||
SERIO_ADD_UEVENT_VAR("SERIO_EXTRA=%02x", serio->id.extra);
|
||||
SERIO_ADD_UEVENT_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X",
|
||||
serio->id.type, serio->id.proto, serio->id.id, serio->id.extra);
|
||||
envp[i] = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -908,7 +903,7 @@ static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buf
|
|||
|
||||
#else
|
||||
|
||||
static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
|
||||
static int serio_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
|
@ -905,8 +905,8 @@ struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *mp,
|
|||
}
|
||||
|
||||
|
||||
static int pvr2_sysfs_hotplug(struct device *cd,char **envp,
|
||||
int numenvp,char *buf,int size)
|
||||
static int pvr2_sysfs_hotplug(struct device *d,
|
||||
struct kobj_uevent_env *env)
|
||||
{
|
||||
/* Even though we don't do anything here, we still need this function
|
||||
because sysfs will still try to call it. */
|
||||
|
|
|
@ -57,16 +57,11 @@ static int tifm_bus_match(struct device *dev, struct device_driver *drv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tifm_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
static int tifm_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev);
|
||||
int i = 0;
|
||||
int length = 0;
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
|
||||
"TIFM_CARD_TYPE=%s",
|
||||
tifm_media_type_name(sock->type, 1)))
|
||||
if (add_uevent_var(env, "TIFM_CARD_TYPE=%s", tifm_media_type_name(sock->type, 1)))
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -58,12 +58,11 @@ static int mmc_bus_match(struct device *dev, struct device_driver *drv)
|
|||
}
|
||||
|
||||
static int
|
||||
mmc_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf,
|
||||
int buf_size)
|
||||
mmc_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct mmc_card *card = dev_to_mmc_card(dev);
|
||||
const char *type;
|
||||
int i = 0, length = 0;
|
||||
int retval = 0;
|
||||
|
||||
switch (card->type) {
|
||||
case MMC_TYPE_MMC:
|
||||
|
@ -80,20 +79,14 @@ mmc_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf,
|
|||
}
|
||||
|
||||
if (type) {
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buf, buf_size, &length,
|
||||
"MMC_TYPE=%s", type))
|
||||
return -ENOMEM;
|
||||
retval = add_uevent_var(env, "MMC_TYPE=%s", type);
|
||||
if (retval)
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buf, buf_size, &length,
|
||||
"MMC_NAME=%s", mmc_card_name(card)))
|
||||
return -ENOMEM;
|
||||
retval = add_uevent_var(env, "MMC_NAME=%s", mmc_card_name(card));
|
||||
|
||||
envp[i] = NULL;
|
||||
|
||||
return 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int mmc_bus_probe(struct device *dev)
|
||||
|
|
|
@ -3,12 +3,9 @@
|
|||
#include <linux/module.h>
|
||||
#include "pci.h"
|
||||
|
||||
int pci_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
int pci_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct pci_dev *pdev;
|
||||
int i = 0;
|
||||
int length = 0;
|
||||
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
|
@ -17,37 +14,24 @@ int pci_uevent(struct device *dev, char **envp, int num_envp,
|
|||
if (!pdev)
|
||||
return -ENODEV;
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PCI_CLASS=%04X", pdev->class))
|
||||
if (add_uevent_var(env, "PCI_CLASS=%04X", pdev->class))
|
||||
return -ENOMEM;
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PCI_ID=%04X:%04X", pdev->vendor, pdev->device))
|
||||
if (add_uevent_var(env, "PCI_ID=%04X:%04X", pdev->vendor, pdev->device))
|
||||
return -ENOMEM;
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor,
|
||||
if (add_uevent_var(env, "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor,
|
||||
pdev->subsystem_device))
|
||||
return -ENOMEM;
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PCI_SLOT_NAME=%s", pci_name(pdev)))
|
||||
if (add_uevent_var(env, "PCI_SLOT_NAME=%s", pci_name(pdev)))
|
||||
return -ENOMEM;
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x",
|
||||
if (add_uevent_var(env, "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x",
|
||||
pdev->vendor, pdev->device,
|
||||
pdev->subsystem_vendor, pdev->subsystem_device,
|
||||
(u8)(pdev->class >> 16), (u8)(pdev->class >> 8),
|
||||
(u8)(pdev->class)))
|
||||
return -ENOMEM;
|
||||
|
||||
envp[i] = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -532,8 +532,7 @@ void pci_dev_put(struct pci_dev *dev)
|
|||
}
|
||||
|
||||
#ifndef CONFIG_HOTPLUG
|
||||
int pci_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
int pci_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* Functions internal to the PCI core code */
|
||||
|
||||
extern int pci_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size);
|
||||
extern int pci_uevent(struct device *dev, struct kobj_uevent_env *env);
|
||||
extern int pci_create_sysfs_dev_files(struct pci_dev *pdev);
|
||||
extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
|
||||
extern void pci_cleanup_rom(struct pci_dev *dev);
|
||||
|
|
|
@ -907,18 +907,14 @@ int pcmcia_insert_card(struct pcmcia_socket *skt)
|
|||
EXPORT_SYMBOL(pcmcia_insert_card);
|
||||
|
||||
|
||||
static int pcmcia_socket_uevent(struct device *dev, char **envp,
|
||||
int num_envp, char *buffer, int buffer_size)
|
||||
static int pcmcia_socket_uevent(struct device *dev,
|
||||
struct kobj_uevent_env *env)
|
||||
{
|
||||
struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev);
|
||||
int i = 0, length = 0;
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
|
||||
&length, "SOCKET_NO=%u", s->sock))
|
||||
if (add_uevent_var(env, "SOCKET_NO=%u", s->sock))
|
||||
return -ENOMEM;
|
||||
|
||||
envp[i] = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1064,11 +1064,10 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
|
|||
|
||||
#ifdef CONFIG_HOTPLUG
|
||||
|
||||
static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
static int pcmcia_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct pcmcia_device *p_dev;
|
||||
int i, length = 0;
|
||||
int i;
|
||||
u32 hash[4] = { 0, 0, 0, 0};
|
||||
|
||||
if (!dev)
|
||||
|
@ -1083,23 +1082,13 @@ static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp,
|
|||
hash[i] = crc32(0, p_dev->prod_id[i], strlen(p_dev->prod_id[i]));
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"SOCKET_NO=%u",
|
||||
p_dev->socket->sock))
|
||||
if (add_uevent_var(env, "SOCKET_NO=%u", p_dev->socket->sock))
|
||||
return -ENOMEM;
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"DEVICE_NO=%02X",
|
||||
p_dev->device_no))
|
||||
if (add_uevent_var(env, "DEVICE_NO=%02X", p_dev->device_no))
|
||||
return -ENOMEM;
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"MODALIAS=pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X"
|
||||
if (add_uevent_var(env, "MODALIAS=pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X"
|
||||
"pa%08Xpb%08Xpc%08Xpd%08X",
|
||||
p_dev->has_manf_id ? p_dev->manf_id : 0,
|
||||
p_dev->has_card_id ? p_dev->card_id : 0,
|
||||
|
@ -1112,15 +1101,12 @@ static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp,
|
|||
hash[3]))
|
||||
return -ENOMEM;
|
||||
|
||||
envp[i] = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
static int pcmcia_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
|
@ -14,8 +14,7 @@
|
|||
|
||||
extern int power_supply_create_attrs(struct power_supply *psy);
|
||||
extern void power_supply_remove_attrs(struct power_supply *psy);
|
||||
extern int power_supply_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size);
|
||||
extern int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env);
|
||||
|
||||
#else
|
||||
|
||||
|
|
|
@ -195,11 +195,10 @@ static char *kstruprdup(const char *str, gfp_t gfp)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int power_supply_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct power_supply *psy = dev_get_drvdata(dev);
|
||||
int i = 0, length = 0, ret = 0, j;
|
||||
int ret = 0, j;
|
||||
char *prop_buf;
|
||||
char *attrname;
|
||||
|
||||
|
@ -212,8 +211,7 @@ int power_supply_uevent(struct device *dev, char **envp, int num_envp,
|
|||
|
||||
dev_dbg(dev, "POWER_SUPPLY_NAME=%s\n", psy->name);
|
||||
|
||||
ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
|
||||
&length, "POWER_SUPPLY_NAME=%s", psy->name);
|
||||
ret = add_uevent_var(env, "POWER_SUPPLY_NAME=%s", psy->name);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -243,9 +241,7 @@ int power_supply_uevent(struct device *dev, char **envp, int num_envp,
|
|||
|
||||
dev_dbg(dev, "Static prop %s=%s\n", attrname, prop_buf);
|
||||
|
||||
ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
|
||||
&length, "POWER_SUPPLY_%s=%s",
|
||||
attrname, prop_buf);
|
||||
ret = add_uevent_var(env, "POWER_SUPPLY_%s=%s", attrname, prop_buf);
|
||||
kfree(attrname);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
@ -282,14 +278,11 @@ int power_supply_uevent(struct device *dev, char **envp, int num_envp,
|
|||
|
||||
dev_dbg(dev, "prop %s=%s\n", attrname, prop_buf);
|
||||
|
||||
ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
|
||||
&length, "POWER_SUPPLY_%s=%s",
|
||||
attrname, prop_buf);
|
||||
ret = add_uevent_var(env, "POWER_SUPPLY_%s=%s", attrname, prop_buf);
|
||||
kfree(attrname);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
envp[i] = NULL;
|
||||
|
||||
out:
|
||||
free_page((unsigned long)prop_buf);
|
||||
|
|
|
@ -44,8 +44,7 @@ ccwgroup_bus_match (struct device * dev, struct device_driver * drv)
|
|||
return 0;
|
||||
}
|
||||
static int
|
||||
ccwgroup_uevent (struct device *dev, char **envp, int num_envp, char *buffer,
|
||||
int buffer_size)
|
||||
ccwgroup_uevent (struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
|
|
|
@ -78,49 +78,38 @@ static int snprint_alias(char *buf, size_t size,
|
|||
|
||||
/* Set up environment variables for ccw device uevent. Return 0 on success,
|
||||
* non-zero otherwise. */
|
||||
static int ccw_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
static int ccw_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct ccw_device *cdev = to_ccwdev(dev);
|
||||
struct ccw_device_id *id = &(cdev->id);
|
||||
int i = 0;
|
||||
int len = 0;
|
||||
int ret;
|
||||
char modalias_buf[30];
|
||||
|
||||
/* CU_TYPE= */
|
||||
ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
|
||||
"CU_TYPE=%04X", id->cu_type);
|
||||
ret = add_uevent_var(env, "CU_TYPE=%04X", id->cu_type);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* CU_MODEL= */
|
||||
ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
|
||||
"CU_MODEL=%02X", id->cu_model);
|
||||
ret = add_uevent_var(env, "CU_MODEL=%02X", id->cu_model);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* The next two can be zero, that's ok for us */
|
||||
/* DEV_TYPE= */
|
||||
ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
|
||||
"DEV_TYPE=%04X", id->dev_type);
|
||||
ret = add_uevent_var(env, "DEV_TYPE=%04X", id->dev_type);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* DEV_MODEL= */
|
||||
ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
|
||||
"DEV_MODEL=%02X", id->dev_model);
|
||||
ret = add_uevent_var(env, "DEV_MODEL=%02X", id->dev_model);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* MODALIAS= */
|
||||
snprint_alias(modalias_buf, sizeof(modalias_buf), id, "");
|
||||
ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
|
||||
"MODALIAS=%s", modalias_buf);
|
||||
if (ret)
|
||||
return ret;
|
||||
envp[i] = NULL;
|
||||
return 0;
|
||||
ret = add_uevent_var(env, "MODALIAS=%s", modalias_buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct bus_type ccw_bus_type;
|
||||
|
|
|
@ -458,28 +458,22 @@ static int ap_bus_match(struct device *dev, struct device_driver *drv)
|
|||
* uevent function for AP devices. It sets up a single environment
|
||||
* variable DEV_TYPE which contains the hardware device type.
|
||||
*/
|
||||
static int ap_uevent (struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
static int ap_uevent (struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct ap_device *ap_dev = to_ap_dev(dev);
|
||||
int retval = 0, length = 0, i = 0;
|
||||
int retval = 0;
|
||||
|
||||
if (!ap_dev)
|
||||
return -ENODEV;
|
||||
|
||||
/* Set up DEV_TYPE environment variable. */
|
||||
retval = add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"DEV_TYPE=%04X", ap_dev->device_type);
|
||||
retval = add_uevent_var(env, "DEV_TYPE=%04X", ap_dev->device_type);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
/* Add MODALIAS= */
|
||||
retval = add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"MODALIAS=ap:t%02X", ap_dev->device_type);
|
||||
retval = add_uevent_var(env, "MODALIAS=ap:t%02X", ap_dev->device_type);
|
||||
|
||||
envp[i] = NULL;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
@ -277,16 +277,11 @@ static int scsi_bus_match(struct device *dev, struct device_driver *gendrv)
|
|||
return (sdp->inq_periph_qual == SCSI_INQ_PQ_CON)? 1: 0;
|
||||
}
|
||||
|
||||
static int scsi_bus_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
static int scsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct scsi_device *sdev = to_scsi_device(dev);
|
||||
int i = 0;
|
||||
int length = 0;
|
||||
|
||||
add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
|
||||
"MODALIAS=" SCSI_DEVICE_MODALIAS_FMT, sdev->type);
|
||||
envp[i] = NULL;
|
||||
add_uevent_var(env, "MODALIAS=" SCSI_DEVICE_MODALIAS_FMT, sdev->type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -67,14 +67,11 @@ static int spi_match_device(struct device *dev, struct device_driver *drv)
|
|||
return strncmp(spi->modalias, drv->name, BUS_ID_SIZE) == 0;
|
||||
}
|
||||
|
||||
static int spi_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
static int spi_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
const struct spi_device *spi = to_spi_device(dev);
|
||||
|
||||
envp[0] = buffer;
|
||||
snprintf(buffer, buffer_size, "MODALIAS=%s", spi->modalias);
|
||||
envp[1] = NULL;
|
||||
add_uevent_var(env, "MODALIAS=%s", spi->modalias);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -576,12 +576,9 @@ static int usb_device_match(struct device *dev, struct device_driver *drv)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG
|
||||
static int usb_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct usb_device *usb_dev;
|
||||
int i = 0;
|
||||
int length = 0;
|
||||
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
|
@ -610,51 +607,39 @@ static int usb_uevent(struct device *dev, char **envp, int num_envp,
|
|||
* all the device descriptors we don't tell them about. Or
|
||||
* act as usermode drivers.
|
||||
*/
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"DEVICE=/proc/bus/usb/%03d/%03d",
|
||||
if (add_uevent_var(env, "DEVICE=/proc/bus/usb/%03d/%03d",
|
||||
usb_dev->bus->busnum, usb_dev->devnum))
|
||||
return -ENOMEM;
|
||||
#endif
|
||||
|
||||
/* per-device configurations are common */
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PRODUCT=%x/%x/%x",
|
||||
if (add_uevent_var(env, "PRODUCT=%x/%x/%x",
|
||||
le16_to_cpu(usb_dev->descriptor.idVendor),
|
||||
le16_to_cpu(usb_dev->descriptor.idProduct),
|
||||
le16_to_cpu(usb_dev->descriptor.bcdDevice)))
|
||||
return -ENOMEM;
|
||||
|
||||
/* class-based driver binding models */
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"TYPE=%d/%d/%d",
|
||||
if (add_uevent_var(env, "TYPE=%d/%d/%d",
|
||||
usb_dev->descriptor.bDeviceClass,
|
||||
usb_dev->descriptor.bDeviceSubClass,
|
||||
usb_dev->descriptor.bDeviceProtocol))
|
||||
return -ENOMEM;
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"BUSNUM=%03d",
|
||||
if (add_uevent_var(env, "BUSNUM=%03d",
|
||||
usb_dev->bus->busnum))
|
||||
return -ENOMEM;
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"DEVNUM=%03d",
|
||||
if (add_uevent_var(env, "DEVNUM=%03d",
|
||||
usb_dev->devnum))
|
||||
return -ENOMEM;
|
||||
|
||||
envp[i] = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int usb_uevent(struct device *dev, char **envp,
|
||||
int num_envp, char *buffer, int buffer_size)
|
||||
static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
|
@ -1339,14 +1339,11 @@ void usb_release_interface(struct device *dev)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG
|
||||
static int usb_if_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct usb_device *usb_dev;
|
||||
struct usb_interface *intf;
|
||||
struct usb_host_interface *alt;
|
||||
int i = 0;
|
||||
int length = 0;
|
||||
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
|
@ -1359,39 +1356,30 @@ static int usb_if_uevent(struct device *dev, char **envp, int num_envp,
|
|||
alt = intf->cur_altsetting;
|
||||
|
||||
#ifdef CONFIG_USB_DEVICEFS
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"DEVICE=/proc/bus/usb/%03d/%03d",
|
||||
if (add_uevent_var(env, "DEVICE=/proc/bus/usb/%03d/%03d",
|
||||
usb_dev->bus->busnum, usb_dev->devnum))
|
||||
return -ENOMEM;
|
||||
#endif
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PRODUCT=%x/%x/%x",
|
||||
if (add_uevent_var(env, "PRODUCT=%x/%x/%x",
|
||||
le16_to_cpu(usb_dev->descriptor.idVendor),
|
||||
le16_to_cpu(usb_dev->descriptor.idProduct),
|
||||
le16_to_cpu(usb_dev->descriptor.bcdDevice)))
|
||||
return -ENOMEM;
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"TYPE=%d/%d/%d",
|
||||
if (add_uevent_var(env, "TYPE=%d/%d/%d",
|
||||
usb_dev->descriptor.bDeviceClass,
|
||||
usb_dev->descriptor.bDeviceSubClass,
|
||||
usb_dev->descriptor.bDeviceProtocol))
|
||||
return -ENOMEM;
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"INTERFACE=%d/%d/%d",
|
||||
if (add_uevent_var(env, "INTERFACE=%d/%d/%d",
|
||||
alt->desc.bInterfaceClass,
|
||||
alt->desc.bInterfaceSubClass,
|
||||
alt->desc.bInterfaceProtocol))
|
||||
return -ENOMEM;
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
if (add_uevent_var(env,
|
||||
"MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
|
||||
le16_to_cpu(usb_dev->descriptor.idVendor),
|
||||
le16_to_cpu(usb_dev->descriptor.idProduct),
|
||||
|
@ -1404,14 +1392,12 @@ static int usb_if_uevent(struct device *dev, char **envp, int num_envp,
|
|||
alt->desc.bInterfaceProtocol))
|
||||
return -ENOMEM;
|
||||
|
||||
envp[i] = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int usb_if_uevent(struct device *dev, char **envp,
|
||||
int num_envp, char *buffer, int buffer_size)
|
||||
static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
|
@ -197,7 +197,7 @@ static struct w1_family w1_default_family = {
|
|||
.fops = &w1_default_fops,
|
||||
};
|
||||
|
||||
static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size);
|
||||
static int w1_uevent(struct device *dev, struct kobj_uevent_env *env);
|
||||
|
||||
static struct bus_type w1_bus_type = {
|
||||
.name = "w1",
|
||||
|
@ -396,13 +396,12 @@ static void w1_destroy_master_attributes(struct w1_master *master)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG
|
||||
static int w1_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
static int w1_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct w1_master *md = NULL;
|
||||
struct w1_slave *sl = NULL;
|
||||
char *event_owner, *name;
|
||||
int err, cur_index=0, cur_len=0;
|
||||
int err;
|
||||
|
||||
if (dev->driver == &w1_master_driver) {
|
||||
md = container_of(dev, struct w1_master, dev);
|
||||
|
@ -423,23 +422,19 @@ static int w1_uevent(struct device *dev, char **envp, int num_envp,
|
|||
if (dev->driver != &w1_slave_driver || !sl)
|
||||
return 0;
|
||||
|
||||
err = add_uevent_var(envp, num_envp, &cur_index, buffer, buffer_size,
|
||||
&cur_len, "W1_FID=%02X", sl->reg_num.family);
|
||||
err = add_uevent_var(env, "W1_FID=%02X", sl->reg_num.family);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = add_uevent_var(envp, num_envp, &cur_index, buffer, buffer_size,
|
||||
&cur_len, "W1_SLAVE_ID=%024LX",
|
||||
(unsigned long long)sl->reg_num.id);
|
||||
envp[cur_index] = NULL;
|
||||
err = add_uevent_var(env, "W1_SLAVE_ID=%024LX",
|
||||
(unsigned long long)sl->reg_num.id);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
};
|
||||
#else
|
||||
static int w1_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
static int w1_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ struct of_device
|
|||
extern ssize_t of_device_get_modalias(struct of_device *ofdev,
|
||||
char *str, ssize_t len);
|
||||
extern int of_device_uevent(struct device *dev,
|
||||
char **envp, int num_envp, char *buffer, int buffer_size);
|
||||
struct kobj_uevent_env *env);
|
||||
|
||||
/* This is just here during the transition */
|
||||
#include <linux/of_device.h>
|
||||
|
|
|
@ -66,8 +66,7 @@ struct bus_type {
|
|||
struct driver_attribute * drv_attrs;
|
||||
|
||||
int (*match)(struct device * dev, struct device_driver * drv);
|
||||
int (*uevent)(struct device *dev, char **envp,
|
||||
int num_envp, char *buffer, int buffer_size);
|
||||
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
|
||||
int (*probe)(struct device * dev);
|
||||
int (*remove)(struct device * dev);
|
||||
void (*shutdown)(struct device * dev);
|
||||
|
@ -187,10 +186,8 @@ struct class {
|
|||
struct class_device_attribute * class_dev_attrs;
|
||||
struct device_attribute * dev_attrs;
|
||||
|
||||
int (*uevent)(struct class_device *dev, char **envp,
|
||||
int num_envp, char *buffer, int buffer_size);
|
||||
int (*dev_uevent)(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size);
|
||||
int (*uevent)(struct class_device *dev, struct kobj_uevent_env *env);
|
||||
int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
|
||||
|
||||
void (*release)(struct class_device *dev);
|
||||
void (*class_release)(struct class *class);
|
||||
|
@ -266,8 +263,7 @@ struct class_device {
|
|||
struct attribute_group ** groups; /* optional groups */
|
||||
|
||||
void (*release)(struct class_device *dev);
|
||||
int (*uevent)(struct class_device *dev, char **envp,
|
||||
int num_envp, char *buffer, int buffer_size);
|
||||
int (*uevent)(struct class_device *dev, struct kobj_uevent_env *env);
|
||||
char class_id[BUS_ID_SIZE]; /* unique to this class */
|
||||
};
|
||||
|
||||
|
@ -335,8 +331,7 @@ extern void class_device_destroy(struct class *cls, dev_t devt);
|
|||
struct device_type {
|
||||
const char *name;
|
||||
struct attribute_group **groups;
|
||||
int (*uevent)(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size);
|
||||
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
|
||||
void (*release)(struct device *dev);
|
||||
int (*suspend)(struct device * dev, pm_message_t state);
|
||||
int (*resume)(struct device * dev);
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
#define KOBJ_NAME_LEN 20
|
||||
#define UEVENT_HELPER_PATH_LEN 256
|
||||
#define UEVENT_NUM_ENVP 32 /* number of env pointers */
|
||||
#define UEVENT_BUFFER_SIZE 2048 /* buffer for the variables */
|
||||
|
||||
/* path to the userspace helper executed on an event */
|
||||
extern char uevent_helper[];
|
||||
|
@ -111,11 +113,18 @@ struct kobj_type {
|
|||
struct attribute ** default_attrs;
|
||||
};
|
||||
|
||||
struct kobj_uevent_env {
|
||||
char *envp[UEVENT_NUM_ENVP];
|
||||
int envp_idx;
|
||||
char buf[UEVENT_BUFFER_SIZE];
|
||||
int buflen;
|
||||
};
|
||||
|
||||
struct kset_uevent_ops {
|
||||
int (*filter)(struct kset *kset, struct kobject *kobj);
|
||||
const char *(*name)(struct kset *kset, struct kobject *kobj);
|
||||
int (*uevent)(struct kset *kset, struct kobject *kobj, char **envp,
|
||||
int num_envp, char *buffer, int buffer_size);
|
||||
int (*uevent)(struct kset *kset, struct kobject *kobj,
|
||||
struct kobj_uevent_env *env);
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -275,10 +284,8 @@ int kobject_uevent(struct kobject *kobj, enum kobject_action action);
|
|||
int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
|
||||
char *envp[]);
|
||||
|
||||
int add_uevent_var(char **envp, int num_envp, int *cur_index,
|
||||
char *buffer, int buffer_size, int *cur_len,
|
||||
const char *format, ...)
|
||||
__attribute__((format (printf, 7, 8)));
|
||||
int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...)
|
||||
__attribute__((format (printf, 2, 3)));
|
||||
#else
|
||||
static inline int kobject_uevent(struct kobject *kobj, enum kobject_action action)
|
||||
{ return 0; }
|
||||
|
@ -287,9 +294,7 @@ static inline int kobject_uevent_env(struct kobject *kobj,
|
|||
char *envp[])
|
||||
{ return 0; }
|
||||
|
||||
static inline int add_uevent_var(char **envp, int num_envp, int *cur_index,
|
||||
char *buffer, int buffer_size, int *cur_len,
|
||||
const char *format, ...)
|
||||
static inline int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...)
|
||||
{ return 0; }
|
||||
#endif
|
||||
|
||||
|
|
|
@ -22,8 +22,6 @@
|
|||
#include <linux/kobject.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
#define BUFFER_SIZE 2048 /* buffer for the variables */
|
||||
#define NUM_ENVP 32 /* number of env pointers */
|
||||
|
||||
/* the strings here must match the enum in include/linux/kobject.h */
|
||||
const char *kobject_actions[] = {
|
||||
|
@ -54,31 +52,21 @@ static struct sock *uevent_sock;
|
|||
* corresponding error when it fails.
|
||||
*/
|
||||
int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
|
||||
char *envp_ext[])
|
||||
char *envp_ext[])
|
||||
{
|
||||
char **envp;
|
||||
char *buffer;
|
||||
char *scratch;
|
||||
const char *action_string;
|
||||
struct kobj_uevent_env *env;
|
||||
const char *action_string = kobject_actions[action];
|
||||
const char *devpath = NULL;
|
||||
const char *subsystem;
|
||||
struct kobject *top_kobj;
|
||||
struct kset *kset;
|
||||
struct kset_uevent_ops *uevent_ops;
|
||||
u64 seq;
|
||||
char *seq_buff;
|
||||
int i = 0;
|
||||
int retval = 0;
|
||||
int j;
|
||||
|
||||
pr_debug("%s\n", __FUNCTION__);
|
||||
|
||||
action_string = kobject_actions[action];
|
||||
if (!action_string) {
|
||||
pr_debug("kobject attempted to send uevent without action_string!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* search the kset we belong to */
|
||||
top_kobj = kobj;
|
||||
while (!top_kobj->kset && top_kobj->parent) {
|
||||
|
@ -92,7 +80,7 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
|
|||
kset = top_kobj->kset;
|
||||
uevent_ops = kset->uevent_ops;
|
||||
|
||||
/* skip the event, if the filter returns zero. */
|
||||
/* skip the event, if the filter returns zero. */
|
||||
if (uevent_ops && uevent_ops->filter)
|
||||
if (!uevent_ops->filter(kset, kobj)) {
|
||||
pr_debug("kobject filter function caused the event to drop!\n");
|
||||
|
@ -109,18 +97,11 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* environment index */
|
||||
envp = kzalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL);
|
||||
if (!envp)
|
||||
/* environment buffer */
|
||||
env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);
|
||||
if (!env)
|
||||
return -ENOMEM;
|
||||
|
||||
/* environment values */
|
||||
buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
|
||||
if (!buffer) {
|
||||
retval = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* complete object path */
|
||||
devpath = kobject_get_path(kobj, GFP_KERNEL);
|
||||
if (!devpath) {
|
||||
|
@ -128,29 +109,29 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
|
|||
goto exit;
|
||||
}
|
||||
|
||||
/* event environemnt for helper process only */
|
||||
envp[i++] = "HOME=/";
|
||||
envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
|
||||
|
||||
/* default keys */
|
||||
scratch = buffer;
|
||||
envp [i++] = scratch;
|
||||
scratch += sprintf(scratch, "ACTION=%s", action_string) + 1;
|
||||
envp [i++] = scratch;
|
||||
scratch += sprintf (scratch, "DEVPATH=%s", devpath) + 1;
|
||||
envp [i++] = scratch;
|
||||
scratch += sprintf(scratch, "SUBSYSTEM=%s", subsystem) + 1;
|
||||
for (j = 0; envp_ext && envp_ext[j]; j++)
|
||||
envp[i++] = envp_ext[j];
|
||||
/* just reserve the space, overwrite it after kset call has returned */
|
||||
envp[i++] = seq_buff = scratch;
|
||||
scratch += strlen("SEQNUM=18446744073709551616") + 1;
|
||||
retval = add_uevent_var(env, "ACTION=%s", action_string);
|
||||
if (retval)
|
||||
goto exit;
|
||||
retval = add_uevent_var(env, "DEVPATH=%s", devpath);
|
||||
if (retval)
|
||||
goto exit;
|
||||
retval = add_uevent_var(env, "SUBSYSTEM=%s", subsystem);
|
||||
if (retval)
|
||||
goto exit;
|
||||
|
||||
/* keys passed in from the caller */
|
||||
if (envp_ext) {
|
||||
for (i = 0; envp_ext[i]; i++) {
|
||||
retval = add_uevent_var(env, envp_ext[i]);
|
||||
if (retval)
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* let the kset specific function add its stuff */
|
||||
if (uevent_ops && uevent_ops->uevent) {
|
||||
retval = uevent_ops->uevent(kset, kobj,
|
||||
&envp[i], NUM_ENVP - i, scratch,
|
||||
BUFFER_SIZE - (scratch - buffer));
|
||||
retval = uevent_ops->uevent(kset, kobj, env);
|
||||
if (retval) {
|
||||
pr_debug ("%s - uevent() returned %d\n",
|
||||
__FUNCTION__, retval);
|
||||
|
@ -158,11 +139,13 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
|
|||
}
|
||||
}
|
||||
|
||||
/* we will send an event, request a new sequence number */
|
||||
/* we will send an event, so request a new sequence number */
|
||||
spin_lock(&sequence_lock);
|
||||
seq = ++uevent_seqnum;
|
||||
spin_unlock(&sequence_lock);
|
||||
sprintf(seq_buff, "SEQNUM=%llu", (unsigned long long)seq);
|
||||
retval = add_uevent_var(env, "SEQNUM=%llu", (unsigned long long)seq);
|
||||
if (retval)
|
||||
goto exit;
|
||||
|
||||
#if defined(CONFIG_NET)
|
||||
/* send netlink message */
|
||||
|
@ -172,17 +155,19 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
|
|||
|
||||
/* allocate message with the maximum possible size */
|
||||
len = strlen(action_string) + strlen(devpath) + 2;
|
||||
skb = alloc_skb(len + BUFFER_SIZE, GFP_KERNEL);
|
||||
skb = alloc_skb(len + env->buflen, GFP_KERNEL);
|
||||
if (skb) {
|
||||
char *scratch;
|
||||
|
||||
/* add header */
|
||||
scratch = skb_put(skb, len);
|
||||
sprintf(scratch, "%s@%s", action_string, devpath);
|
||||
|
||||
/* copy keys to our continuous event payload buffer */
|
||||
for (i = 2; envp[i]; i++) {
|
||||
len = strlen(envp[i]) + 1;
|
||||
for (i = 0; i < env->envp_idx; i++) {
|
||||
len = strlen(env->envp[i]) + 1;
|
||||
scratch = skb_put(skb, len);
|
||||
strcpy(scratch, envp[i]);
|
||||
strcpy(scratch, env->envp[i]);
|
||||
}
|
||||
|
||||
NETLINK_CB(skb).dst_group = 1;
|
||||
|
@ -198,13 +183,19 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
|
|||
argv [0] = uevent_helper;
|
||||
argv [1] = (char *)subsystem;
|
||||
argv [2] = NULL;
|
||||
call_usermodehelper (argv[0], argv, envp, UMH_WAIT_EXEC);
|
||||
retval = add_uevent_var(env, "HOME=/");
|
||||
if (retval)
|
||||
goto exit;
|
||||
retval = add_uevent_var(env, "PATH=/sbin:/bin:/usr/sbin:/usr/bin");
|
||||
if (retval)
|
||||
goto exit;
|
||||
|
||||
call_usermodehelper (argv[0], argv, env->envp, UMH_WAIT_EXEC);
|
||||
}
|
||||
|
||||
exit:
|
||||
kfree(devpath);
|
||||
kfree(buffer);
|
||||
kfree(envp);
|
||||
kfree(env);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -227,52 +218,38 @@ int kobject_uevent(struct kobject *kobj, enum kobject_action action)
|
|||
EXPORT_SYMBOL_GPL(kobject_uevent);
|
||||
|
||||
/**
|
||||
* add_uevent_var - helper for creating event variables
|
||||
* @envp: Pointer to table of environment variables, as passed into
|
||||
* uevent() method.
|
||||
* @num_envp: Number of environment variable slots available, as
|
||||
* passed into uevent() method.
|
||||
* @cur_index: Pointer to current index into @envp. It should be
|
||||
* initialized to 0 before the first call to add_uevent_var(),
|
||||
* and will be incremented on success.
|
||||
* @buffer: Pointer to buffer for environment variables, as passed
|
||||
* into uevent() method.
|
||||
* @buffer_size: Length of @buffer, as passed into uevent() method.
|
||||
* @cur_len: Pointer to current length of space used in @buffer.
|
||||
* Should be initialized to 0 before the first call to
|
||||
* add_uevent_var(), and will be incremented on success.
|
||||
* @format: Format for creating environment variable (of the form
|
||||
* "XXX=%x") for snprintf().
|
||||
* add_uevent_var - add key value string to the environment buffer
|
||||
* @env: environment buffer structure
|
||||
* @format: printf format for the key=value pair
|
||||
*
|
||||
* Returns 0 if environment variable was added successfully or -ENOMEM
|
||||
* if no space was available.
|
||||
*/
|
||||
int add_uevent_var(char **envp, int num_envp, int *cur_index,
|
||||
char *buffer, int buffer_size, int *cur_len,
|
||||
const char *format, ...)
|
||||
int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
int len;
|
||||
|
||||
/*
|
||||
* We check against num_envp - 1 to make sure there is at
|
||||
* least one slot left after we return, since kobject_uevent()
|
||||
* needs to set the last slot to NULL.
|
||||
*/
|
||||
if (*cur_index >= num_envp - 1)
|
||||
if (env->envp_idx >= ARRAY_SIZE(env->envp)) {
|
||||
printk(KERN_ERR "add_uevent_var: too many keys\n");
|
||||
WARN_ON(1);
|
||||
return -ENOMEM;
|
||||
|
||||
envp[*cur_index] = buffer + *cur_len;
|
||||
}
|
||||
|
||||
va_start(args, format);
|
||||
*cur_len += vsnprintf(envp[*cur_index],
|
||||
max(buffer_size - *cur_len, 0),
|
||||
format, args) + 1;
|
||||
len = vsnprintf(&env->buf[env->buflen],
|
||||
sizeof(env->buf) - env->buflen,
|
||||
format, args);
|
||||
va_end(args);
|
||||
|
||||
if (*cur_len > buffer_size)
|
||||
if (len >= (sizeof(env->buf) - env->buflen)) {
|
||||
printk(KERN_ERR "add_uevent_var: buffer size too small\n");
|
||||
WARN_ON(1);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
(*cur_index)++;
|
||||
env->envp[env->envp_idx++] = &env->buf[env->buflen];
|
||||
env->buflen += len + 1;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(add_uevent_var);
|
||||
|
|
|
@ -105,10 +105,9 @@ static struct class_device_attribute *atm_attrs[] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
static int atm_uevent(struct class_device *cdev, char **envp, int num_envp, char *buf, int size)
|
||||
static int atm_uevent(struct class_device *cdev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct atm_dev *adev;
|
||||
int i = 0, len = 0;
|
||||
|
||||
if (!cdev)
|
||||
return -ENODEV;
|
||||
|
@ -117,11 +116,9 @@ static int atm_uevent(struct class_device *cdev, char **envp, int num_envp, char
|
|||
if (!adev)
|
||||
return -ENODEV;
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i, buf, size, &len,
|
||||
"NAME=%s%d", adev->type, adev->number))
|
||||
if (add_uevent_var(env, "NAME=%s%d", adev->type, adev->number))
|
||||
return -ENOMEM;
|
||||
|
||||
envp[i] = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -396,28 +396,22 @@ static struct attribute_group wireless_group = {
|
|||
#endif /* CONFIG_SYSFS */
|
||||
|
||||
#ifdef CONFIG_HOTPLUG
|
||||
static int netdev_uevent(struct device *d, char **envp,
|
||||
int num_envp, char *buf, int size)
|
||||
static int netdev_uevent(struct device *d, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct net_device *dev = to_net_dev(d);
|
||||
int retval, len = 0, i = 0;
|
||||
int retval;
|
||||
|
||||
/* pass interface to uevent. */
|
||||
retval = add_uevent_var(envp, num_envp, &i,
|
||||
buf, size, &len,
|
||||
"INTERFACE=%s", dev->name);
|
||||
retval = add_uevent_var(env, "INTERFACE=%s", dev->name);
|
||||
if (retval)
|
||||
goto exit;
|
||||
|
||||
/* pass ifindex to uevent.
|
||||
* ifindex is useful as it won't change (interface name may change)
|
||||
* and is what RtNetlink uses natively. */
|
||||
retval = add_uevent_var(envp, num_envp, &i,
|
||||
buf, size, &len,
|
||||
"IFINDEX=%d", dev->ifindex);
|
||||
retval = add_uevent_var(env, "IFINDEX=%d", dev->ifindex);
|
||||
|
||||
exit:
|
||||
envp[i] = NULL;
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -53,8 +53,7 @@ static void wiphy_dev_release(struct device *dev)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG
|
||||
static int wiphy_uevent(struct device *dev, char **envp,
|
||||
int num_envp, char *buf, int size)
|
||||
static int wiphy_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
/* TODO, we probably need stuff here */
|
||||
return 0;
|
||||
|
|
|
@ -56,13 +56,12 @@ static int soundbus_probe(struct device *dev)
|
|||
}
|
||||
|
||||
|
||||
static int soundbus_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
static int soundbus_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct soundbus_dev * soundbus_dev;
|
||||
struct of_device * of;
|
||||
const char *compat;
|
||||
int retval = 0, i = 0, length = 0;
|
||||
int retval = 0;
|
||||
int cplen, seen = 0;
|
||||
|
||||
if (!dev)
|
||||
|
@ -75,15 +74,11 @@ static int soundbus_uevent(struct device *dev, char **envp, int num_envp,
|
|||
of = &soundbus_dev->ofdev;
|
||||
|
||||
/* stuff we want to pass to /sbin/hotplug */
|
||||
retval = add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"OF_NAME=%s", of->node->name);
|
||||
retval = add_uevent_var(env, "OF_NAME=%s", of->node->name);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
retval = add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"OF_TYPE=%s", of->node->type);
|
||||
retval = add_uevent_var(env, "OF_TYPE=%s", of->node->type);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
|
@ -93,27 +88,19 @@ static int soundbus_uevent(struct device *dev, char **envp, int num_envp,
|
|||
|
||||
compat = of_get_property(of->node, "compatible", &cplen);
|
||||
while (compat && cplen > 0) {
|
||||
int tmp = length;
|
||||
retval = add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"OF_COMPATIBLE_%d=%s", seen, compat);
|
||||
int tmp = env->buflen;
|
||||
retval = add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat);
|
||||
if (retval)
|
||||
return retval;
|
||||
compat += length - tmp;
|
||||
cplen -= length - tmp;
|
||||
compat += env->buflen - tmp;
|
||||
cplen -= env->buflen - tmp;
|
||||
seen += 1;
|
||||
}
|
||||
|
||||
retval = add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"OF_COMPATIBLE_N=%d", seen);
|
||||
retval = add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen);
|
||||
if (retval)
|
||||
return retval;
|
||||
retval = add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"MODALIAS=%s", soundbus_dev->modalias);
|
||||
|
||||
envp[i] = NULL;
|
||||
retval = add_uevent_var(env, "MODALIAS=%s", soundbus_dev->modalias);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue