[PATCH 19/50] staging: most: core: fix sysfs attribute management

Christian Gromm christian.gromm at microchip.com
Tue Nov 21 14:04:53 UTC 2017


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: Christian Gromm <christian.gromm at microchip.com>
---
 drivers/staging/most/core.c | 109 +++++++++++++++++++++++++++++---------------
 1 file changed, 73 insertions(+), 36 deletions(-)

diff --git a/drivers/staging/most/core.c b/drivers/staging/most/core.c
index b9b9739..7014f6a 100644
--- a/drivers/staging/most/core.c
+++ b/drivers/staging/most/core.c
@@ -540,28 +540,57 @@ static const struct attribute_group *interface_attr_groups[] = {
 /*		     ___     ___
  *		     ___A I M___
  */
-static ssize_t links_show(struct device *dev, struct device_attribute *attr,
-			  char *buf)
+static struct most_aim *match_module(char *name)
+{
+	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_inst_obj *i;
-	struct most_aim *aim = to_most_aim(dev);
 	int offs = 0;
 
 	list_for_each_entry(i, &instance_list, list) {
 		list_for_each_entry(c, &i->channel_list, list) {
-			if (c->pipe0.aim == aim || c->pipe1.aim == aim) {
-				offs += snprintf(buf + offs, PAGE_SIZE - offs,
-						 "%s:%s\n",
+			if (c->pipe0.aim) {
+				offs += snprintf(buf + offs,
+						 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(&c->dev));
 			}
 		}
 	}
-
 	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
  * splits it into two mandatory and one optional substrings.
@@ -584,7 +613,7 @@ static ssize_t links_show(struct device *dev, struct device_attribute *attr,
  * Input: "mdev1:ep81"
  * 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, ":");
 	if (!*a)
@@ -594,8 +623,12 @@ static int split_string(char *buf, char **a, char **b, char **c)
 	if (!*b)
 		return -EIO;
 
-	if (c)
-		*c = strsep(&buf, ":\n");
+	*c = strsep(&buf, ":\n");
+	if (!*c)
+		return -EIO;
+
+	if (d)
+		*d = strsep(&buf, ":\n");
 
 	return 0;
 }
@@ -680,38 +713,38 @@ inline int link_channel_to_aim(struct most_channel *c, struct most_aim *aim,
  * (1) would create the device node /dev/my_rxchannel
  * (2) would create the device node /dev/mdev1-ep81
  */
-static ssize_t add_link_store(struct device *dev,
-			      struct device_attribute *attr,
+static ssize_t add_link_store(struct device_driver *drv,
 			      const char *buf,
 			      size_t len)
 {
 	struct most_channel *c;
-	struct most_aim *aim = to_most_aim(dev);
+	struct most_aim *aim;
 	char buffer[STRING_SIZE];
 	char *mdev;
 	char *mdev_ch;
-	char *mdev_devnod;
+	char *aim_name;
+	char *aim_param;
 	char devnod_buf[STRING_SIZE];
 	int ret;
 	size_t max_len = min_t(size_t, len + 1, STRING_SIZE);
 
 	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)
 		return ret;
-
-	if (!mdev_devnod || *mdev_devnod == 0) {
+	aim = match_module(aim_name);
+	if (!aim_param || *aim_param == 0) {
 		snprintf(devnod_buf, sizeof(devnod_buf), "%s-%s", mdev,
 			 mdev_ch);
-		mdev_devnod = devnod_buf;
+		aim_param = devnod_buf;
 	}
 
 	c = get_channel_by_name(mdev, mdev_ch);
 	if (IS_ERR(c))
 		return -ENODEV;
 
-	ret = link_channel_to_aim(c, aim, mdev_devnod);
+	ret = link_channel_to_aim(c, aim, aim_param);
 	if (ret)
 		return ret;
 
@@ -728,24 +761,24 @@ static ssize_t add_link_store(struct device *dev,
  * Example:
  * echo "mdev0:ep81" >remove_link
  */
-static ssize_t remove_link_store(struct device *dev,
-				 struct device_attribute *attr,
+static ssize_t remove_link_store(struct device_driver *drv,
 				 const char *buf,
 				 size_t len)
 {
 	struct most_channel *c;
-	struct most_aim *aim = to_most_aim(dev);
+	struct most_aim *aim;
 	char buffer[STRING_SIZE];
 	char *mdev;
 	char *mdev_ch;
+	char *aim_name;
 	int ret;
 	size_t max_len = min_t(size_t, len + 1, STRING_SIZE);
 
 	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)
 		return ret;
-
+	aim = match_module(aim_name);
 	c = get_channel_by_name(mdev, mdev_ch);
 	if (IS_ERR(c))
 		return -ENODEV;
@@ -759,23 +792,27 @@ static ssize_t remove_link_store(struct device *dev,
 	return len;
 }
 
-static DEVICE_ATTR_RO(links);
-static DEVICE_ATTR_WO(add_link);
-static DEVICE_ATTR_WO(remove_link);
+#define DRV_ATTR(_name)  (&driver_attr_##_name.attr)
+
+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[] = {
-	DEV_ATTR(links),
-	DEV_ATTR(add_link),
-	DEV_ATTR(remove_link),
+static struct attribute *module_attrs[] = {
+	DRV_ATTR(links),
+	DRV_ATTR(modules),
+	DRV_ATTR(add_link),
+	DRV_ATTR(remove_link),
 	NULL,
 };
 
-static struct attribute_group aim_attr_group = {
-	.attrs = aim_attrs,
+static struct attribute_group module_attr_group = {
+	.attrs = module_attrs,
 };
 
-static const struct attribute_group *aim_attr_groups[] = {
-	&aim_attr_group,
+static const struct attribute_group *module_attr_groups[] = {
+	&module_attr_group,
 	NULL,
 };
 
@@ -1293,7 +1330,6 @@ int most_register_aim(struct most_aim *aim)
 	aim->dev.init_name = aim->name;
 	aim->dev.bus = &mc.bus;
 	aim->dev.parent = &mc.dev;
-	aim->dev.groups = aim_attr_groups;
 	aim->dev.release = release_aim;
 	ret = device_register(&aim->dev);
 	if (ret) {
@@ -1559,6 +1595,7 @@ static int __init most_init(void)
 	mc.bus.match = most_match,
 	mc.drv.name = "most_core",
 	mc.drv.bus = &mc.bus,
+	mc.drv.groups = module_attr_groups;
 
 	err = bus_register(&mc.bus);
 	if (err) {
-- 
2.7.4



More information about the devel mailing list