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

Commit bdafb7e8 authored by Christian Gromm's avatar Christian Gromm Committed by Greg Kroah-Hartman
Browse files

staging: most: core: fix sysfs attribute management



This patch creates a new attribute group to manage the attributes
of a registered aim module in sysfs and changes the show and store
functions accordingly.

Signed-off-by: default avatarChristian Gromm <christian.gromm@microchip.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a6404e6e
Loading
Loading
Loading
Loading
+73 −36
Original line number Original line Diff line number Diff line
@@ -534,28 +534,57 @@ static const struct attribute_group *interface_attr_groups[] = {
/*		     ___     ___
/*		     ___     ___
 *		     ___A I M___
 *		     ___A I M___
 */
 */
static ssize_t links_show(struct device *dev, struct device_attribute *attr,
static struct most_aim *match_module(char *name)
			  char *buf)
{
	struct most_aim *aim;

	list_for_each_entry(aim, &mc.mod_list, list) {
		if (!strcmp(aim->name, name))
			return aim;
	}
	return NULL;
}

static ssize_t links_show(struct device_driver *drv, char *buf)
{
{
	struct most_channel *c;
	struct most_channel *c;
	struct most_inst_obj *i;
	struct most_inst_obj *i;
	struct most_aim *aim = to_most_aim(dev);
	int offs = 0;
	int offs = 0;


	list_for_each_entry(i, &instance_list, list) {
	list_for_each_entry(i, &instance_list, list) {
		list_for_each_entry(c, &i->channel_list, list) {
		list_for_each_entry(c, &i->channel_list, list) {
			if (c->pipe0.aim == aim || c->pipe1.aim == aim) {
			if (c->pipe0.aim) {
				offs += snprintf(buf + offs, PAGE_SIZE - offs,
				offs += snprintf(buf + offs,
						 "%s:%s\n",
						 PAGE_SIZE - offs,
						 "%s:%s:%s\n",
						 c->pipe0.aim->name,
						 dev_name(&i->iface->dev),
						 dev_name(&c->dev));
			}
			if (c->pipe1.aim) {
				offs += snprintf(buf + offs,
						 PAGE_SIZE - offs,
						 "%s:%s:%s\n",
						 c->pipe1.aim->name,
						 dev_name(&i->iface->dev),
						 dev_name(&i->iface->dev),
						 dev_name(&c->dev));
						 dev_name(&c->dev));
			}
			}
		}
		}
	}
	}

	return offs;
	return offs;
}
}


static ssize_t modules_show(struct device_driver *drv, char *buf)
{
	struct most_aim *aim;
	int offs = 0;

	list_for_each_entry(aim, &mc.mod_list, list) {
		offs += snprintf(buf + offs, PAGE_SIZE - offs, "%s\n",
				 aim->name);
	}
	return offs;
}
/**
/**
 * split_string - parses and changes string in the buffer buf and
 * split_string - parses and changes string in the buffer buf and
 * splits it into two mandatory and one optional substrings.
 * splits it into two mandatory and one optional substrings.
@@ -578,7 +607,7 @@ static ssize_t links_show(struct device *dev, struct device_attribute *attr,
 * Input: "mdev1:ep81"
 * Input: "mdev1:ep81"
 * Output: *a -> "mdev1", *b -> "ep81", *c == NULL
 * Output: *a -> "mdev1", *b -> "ep81", *c == NULL
 */
 */
static int split_string(char *buf, char **a, char **b, char **c)
static int split_string(char *buf, char **a, char **b, char **c, char **d)
{
{
	*a = strsep(&buf, ":");
	*a = strsep(&buf, ":");
	if (!*a)
	if (!*a)
@@ -588,8 +617,12 @@ static int split_string(char *buf, char **a, char **b, char **c)
	if (!*b)
	if (!*b)
		return -EIO;
		return -EIO;


	if (c)
	*c = strsep(&buf, ":\n");
	*c = strsep(&buf, ":\n");
	if (!*c)
		return -EIO;

	if (d)
		*d = strsep(&buf, ":\n");


	return 0;
	return 0;
}
}
@@ -674,38 +707,38 @@ inline int link_channel_to_aim(struct most_channel *c, struct most_aim *aim,
 * (1) would create the device node /dev/my_rxchannel
 * (1) would create the device node /dev/my_rxchannel
 * (2) would create the device node /dev/mdev1-ep81
 * (2) would create the device node /dev/mdev1-ep81
 */
 */
static ssize_t add_link_store(struct device *dev,
static ssize_t add_link_store(struct device_driver *drv,
			      struct device_attribute *attr,
			      const char *buf,
			      const char *buf,
			      size_t len)
			      size_t len)
{
{
	struct most_channel *c;
	struct most_channel *c;
	struct most_aim *aim = to_most_aim(dev);
	struct most_aim *aim;
	char buffer[STRING_SIZE];
	char buffer[STRING_SIZE];
	char *mdev;
	char *mdev;
	char *mdev_ch;
	char *mdev_ch;
	char *mdev_devnod;
	char *aim_name;
	char *aim_param;
	char devnod_buf[STRING_SIZE];
	char devnod_buf[STRING_SIZE];
	int ret;
	int ret;
	size_t max_len = min_t(size_t, len + 1, STRING_SIZE);
	size_t max_len = min_t(size_t, len + 1, STRING_SIZE);


	strlcpy(buffer, buf, max_len);
	strlcpy(buffer, buf, max_len);


	ret = split_string(buffer, &mdev, &mdev_ch, &mdev_devnod);
	ret = split_string(buffer, &mdev, &mdev_ch, &aim_name, &aim_param);
	if (ret)
	if (ret)
		return ret;
		return ret;

	aim = match_module(aim_name);
	if (!mdev_devnod || *mdev_devnod == 0) {
	if (!aim_param || *aim_param == 0) {
		snprintf(devnod_buf, sizeof(devnod_buf), "%s-%s", mdev,
		snprintf(devnod_buf, sizeof(devnod_buf), "%s-%s", mdev,
			 mdev_ch);
			 mdev_ch);
		mdev_devnod = devnod_buf;
		aim_param = devnod_buf;
	}
	}


	c = get_channel_by_name(mdev, mdev_ch);
	c = get_channel_by_name(mdev, mdev_ch);
	if (IS_ERR(c))
	if (IS_ERR(c))
		return -ENODEV;
		return -ENODEV;


	ret = link_channel_to_aim(c, aim, mdev_devnod);
	ret = link_channel_to_aim(c, aim, aim_param);
	if (ret)
	if (ret)
		return ret;
		return ret;


@@ -722,24 +755,24 @@ static ssize_t add_link_store(struct device *dev,
 * Example:
 * Example:
 * echo "mdev0:ep81" >remove_link
 * echo "mdev0:ep81" >remove_link
 */
 */
static ssize_t remove_link_store(struct device *dev,
static ssize_t remove_link_store(struct device_driver *drv,
				 struct device_attribute *attr,
				 const char *buf,
				 const char *buf,
				 size_t len)
				 size_t len)
{
{
	struct most_channel *c;
	struct most_channel *c;
	struct most_aim *aim = to_most_aim(dev);
	struct most_aim *aim;
	char buffer[STRING_SIZE];
	char buffer[STRING_SIZE];
	char *mdev;
	char *mdev;
	char *mdev_ch;
	char *mdev_ch;
	char *aim_name;
	int ret;
	int ret;
	size_t max_len = min_t(size_t, len + 1, STRING_SIZE);
	size_t max_len = min_t(size_t, len + 1, STRING_SIZE);


	strlcpy(buffer, buf, max_len);
	strlcpy(buffer, buf, max_len);
	ret = split_string(buffer, &mdev, &mdev_ch, NULL);
	ret = split_string(buffer, &mdev, &mdev_ch, &aim_name, NULL);
	if (ret)
	if (ret)
		return ret;
		return ret;

	aim = match_module(aim_name);
	c = get_channel_by_name(mdev, mdev_ch);
	c = get_channel_by_name(mdev, mdev_ch);
	if (IS_ERR(c))
	if (IS_ERR(c))
		return -ENODEV;
		return -ENODEV;
@@ -753,23 +786,27 @@ static ssize_t remove_link_store(struct device *dev,
	return len;
	return len;
}
}


static DEVICE_ATTR_RO(links);
#define DRV_ATTR(_name)  (&driver_attr_##_name.attr)
static DEVICE_ATTR_WO(add_link);

static DEVICE_ATTR_WO(remove_link);
static DRIVER_ATTR_RO(links);
static DRIVER_ATTR_RO(modules);
static DRIVER_ATTR_WO(add_link);
static DRIVER_ATTR_WO(remove_link);


static struct attribute *aim_attrs[] = {
static struct attribute *module_attrs[] = {
	DEV_ATTR(links),
	DRV_ATTR(links),
	DEV_ATTR(add_link),
	DRV_ATTR(modules),
	DEV_ATTR(remove_link),
	DRV_ATTR(add_link),
	DRV_ATTR(remove_link),
	NULL,
	NULL,
};
};


static struct attribute_group aim_attr_group = {
static struct attribute_group module_attr_group = {
	.attrs = aim_attrs,
	.attrs = module_attrs,
};
};


static const struct attribute_group *aim_attr_groups[] = {
static const struct attribute_group *module_attr_groups[] = {
	&aim_attr_group,
	&module_attr_group,
	NULL,
	NULL,
};
};


@@ -1287,7 +1324,6 @@ int most_register_aim(struct most_aim *aim)
	aim->dev.init_name = aim->name;
	aim->dev.init_name = aim->name;
	aim->dev.bus = &mc.bus;
	aim->dev.bus = &mc.bus;
	aim->dev.parent = &mc.dev;
	aim->dev.parent = &mc.dev;
	aim->dev.groups = aim_attr_groups;
	aim->dev.release = release_aim;
	aim->dev.release = release_aim;
	ret = device_register(&aim->dev);
	ret = device_register(&aim->dev);
	if (ret) {
	if (ret) {
@@ -1553,6 +1589,7 @@ static int __init most_init(void)
	mc.bus.match = most_match,
	mc.bus.match = most_match,
	mc.drv.name = "most_core",
	mc.drv.name = "most_core",
	mc.drv.bus = &mc.bus,
	mc.drv.bus = &mc.bus,
	mc.drv.groups = module_attr_groups;


	err = bus_register(&mc.bus);
	err = bus_register(&mc.bus);
	if (err) {
	if (err) {