Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1498221d authored by Stephen Hemminger's avatar Stephen Hemminger Committed by David S. Miller
Browse files

[CLASS DEVICE]: add attribute_group creation



Extend the support of attribute groups in class_device's to allow
groups to be created as part of the registration process. This allows
network device's to avoid race between registration and creating
groups.

Note that unlike attributes that are a property of the class object,
the groups are a property of the class_device object. This is done
because there are different types of network devices (wireless for
example).

Signed-off-by: default avatarStephen Hemminger <shemminger@osdl.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5528e568
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -456,6 +456,35 @@ static void class_device_remove_attrs(struct class_device * cd)
	}
}

static int class_device_add_groups(struct class_device * cd)
{
	int i;
	int error = 0;

	if (cd->groups) {
		for (i = 0; cd->groups[i]; i++) {
			error = sysfs_create_group(&cd->kobj, cd->groups[i]);
			if (error) {
				while (--i >= 0)
					sysfs_remove_group(&cd->kobj, cd->groups[i]);
				goto out;
			}
		}
	}
out:
	return error;
}

static void class_device_remove_groups(struct class_device * cd)
{
	int i;
	if (cd->groups) {
		for (i = 0; cd->groups[i]; i++) {
			sysfs_remove_group(&cd->kobj, cd->groups[i]);
		}
	}
}

static ssize_t show_dev(struct class_device *class_dev, char *buf)
{
	return print_dev_t(buf, class_dev->devt);
@@ -559,6 +588,8 @@ int class_device_add(struct class_device *class_dev)
				  class_name);
	}

	class_device_add_groups(class_dev);

	kobject_uevent(&class_dev->kobj, KOBJ_ADD);

	/* notify any interfaces this device is now here */
@@ -672,6 +703,7 @@ void class_device_del(struct class_device *class_dev)
	if (class_dev->devt_attr)
		class_device_remove_file(class_dev, class_dev->devt_attr);
	class_device_remove_attrs(class_dev);
	class_device_remove_groups(class_dev);

	kobject_uevent(&class_dev->kobj, KOBJ_REMOVE);
	kobject_del(&class_dev->kobj);
+2 −0
Original line number Diff line number Diff line
@@ -200,6 +200,7 @@ extern int class_device_create_file(struct class_device *,
 * @node: for internal use by the driver core only.
 * @kobj: for internal use by the driver core only.
 * @devt_attr: for internal use by the driver core only.
 * @groups: optional additional groups to be created
 * @dev: if set, a symlink to the struct device is created in the sysfs
 * directory for this struct class device.
 * @class_data: pointer to whatever you want to store here for this struct
@@ -228,6 +229,7 @@ struct class_device {
	struct device		* dev;		/* not necessary, but nice to have */
	void			* class_data;	/* class-specific data */
	struct class_device	*parent;	/* parent of this child device, if there is one */
	struct attribute_group  ** groups;	/* optional groups */

	void	(*release)(struct class_device *dev);
	int	(*uevent)(struct class_device *dev, char **envp,