All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/14] staging: most: switch to configfs
@ 2019-03-21 13:26 Christian Gromm
  2019-03-21 13:26 ` [PATCH 01/14] staging: most: add new file configfs.c Christian Gromm
                   ` (13 more replies)
  0 siblings, 14 replies; 20+ messages in thread
From: Christian Gromm @ 2019-03-21 13:26 UTC (permalink / raw)
  To: gregkh; +Cc: Christian Gromm, driverdev-devel

This patch set makes the driver provide its configuration interface via
configfs. The configuration interface is being switched to simplify the
process of setting up the driver and to introduce the new feature of
speculative configuration.

Christian Gromm (14):
  staging: most: add new file configfs.c
  staging: most: change signature of function probe_channel
  staging: most: core: add configfs interface functions
  staging: most: sound: introduce new sound adapter management
  staging: most: enable configfs support
  staging: most: core: make sysfs attributes read-only
  staging: most: core: use device description as name
  staging: most: usb: remove prefix from description tag
  staging: most: core: remove attribute add_link
  staging: most: allow speculative configuration
  staging: most: configfs: make create attributes write-only
  staging: most: configfs: add code for link removal
  staging: most: configfs: rename config attributes
  staging: most: Documentation: update driver documentation

 .../most/Documentation/ABI/configfs-most.txt       | 204 ++++++
 .../staging/most/Documentation/driver_usage.txt    | 131 ++--
 drivers/staging/most/Makefile                      |   1 +
 drivers/staging/most/cdev/cdev.c                   |   8 +-
 drivers/staging/most/configfs.c                    | 709 +++++++++++++++++++++
 drivers/staging/most/core.c                        | 306 ++++-----
 drivers/staging/most/core.h                        |  21 +-
 drivers/staging/most/net/net.c                     |   3 +-
 drivers/staging/most/sound/sound.c                 |  59 +-
 drivers/staging/most/usb/usb.c                     |   2 +-
 drivers/staging/most/video/video.c                 |   3 +-
 11 files changed, 1199 insertions(+), 248 deletions(-)
 create mode 100644 drivers/staging/most/Documentation/ABI/configfs-most.txt
 create mode 100644 drivers/staging/most/configfs.c

-- 
2.7.4

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 01/14] staging: most: add new file configfs.c
  2019-03-21 13:26 [PATCH 00/14] staging: most: switch to configfs Christian Gromm
@ 2019-03-21 13:26 ` Christian Gromm
  2019-03-22 10:44   ` Dan Carpenter
  2019-03-22 10:46   ` Dan Carpenter
  2019-03-21 13:26 ` [PATCH 02/14] staging: most: change signature of function probe_channel Christian Gromm
                   ` (12 subsequent siblings)
  13 siblings, 2 replies; 20+ messages in thread
From: Christian Gromm @ 2019-03-21 13:26 UTC (permalink / raw)
  To: gregkh; +Cc: Christian Gromm, driverdev-devel

This patch adds the file configfs.c to the driver directory. The file
registers the necessary subsystems with configfs in order to move the
driver configuration from sysfs to configfs.

Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
---
 drivers/staging/most/configfs.c | 659 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 659 insertions(+)
 create mode 100644 drivers/staging/most/configfs.c

diff --git a/drivers/staging/most/configfs.c b/drivers/staging/most/configfs.c
new file mode 100644
index 0000000..cefce69
--- /dev/null
+++ b/drivers/staging/most/configfs.c
@@ -0,0 +1,659 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * configfs.c - Implementation of configfs interface to the driver stack
+ *
+ * Copyright (C) 2013-2015 Microchip Technology Germany II GmbH & Co. KG
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/configfs.h>
+#include <most/core.h>
+
+#define MAX_LEN 30
+
+struct mdev_link {
+	struct config_item item;
+	int create;
+	u16 num_buffers;
+	u16 buffer_size;
+	u16 subbuffer_size;
+	u16 packets_per_xact;
+	u16 dbr_size;
+	char datatype[MAX_LEN];
+	char direction[MAX_LEN];
+	char name[MAX_LEN];
+	char mdev[MAX_LEN];
+	char channel[MAX_LEN];
+	char comp[MAX_LEN];
+	char param[MAX_LEN];
+};
+
+int set_cfg_buffer_size(struct mdev_link *link)
+{
+	if (!link->buffer_size)
+		return -ENODATA;
+	return most_set_cfg_buffer_size(link->mdev, link->channel,
+					link->buffer_size);
+}
+
+int set_cfg_subbuffer_size(struct mdev_link *link)
+{
+	if (!link->subbuffer_size)
+		return -ENODATA;
+	return most_set_cfg_subbuffer_size(link->mdev, link->channel,
+					   link->subbuffer_size);
+}
+
+int set_cfg_dbr_size(struct mdev_link *link)
+{
+	if (!link->dbr_size)
+		return -ENODATA;
+	return most_set_cfg_dbr_size(link->mdev, link->channel,
+				     link->dbr_size);
+}
+
+int set_cfg_num_buffers(struct mdev_link *link)
+{
+	if (!link->num_buffers)
+		return -ENODATA;
+	return most_set_cfg_num_buffers(link->mdev, link->channel,
+					link->num_buffers);
+}
+
+int set_cfg_packets_xact(struct mdev_link *link)
+{
+	if (!link->packets_per_xact)
+		return -ENODATA;
+	return most_set_cfg_packets_xact(link->mdev, link->channel,
+					 link->packets_per_xact);
+}
+
+int set_cfg_direction(struct mdev_link *link)
+{
+	if (!strlen(link->direction))
+		return -ENODATA;
+	return most_set_cfg_direction(link->mdev, link->channel,
+				      link->direction);
+}
+
+int set_cfg_datatype(struct mdev_link *link)
+{
+	if (!strlen(link->datatype))
+		return -ENODATA;
+	return most_set_cfg_datatype(link->mdev, link->channel,
+				     link->datatype);
+}
+
+static int (*set_config_val[])(struct mdev_link *link) = {
+	set_cfg_buffer_size,
+	set_cfg_subbuffer_size,
+	set_cfg_dbr_size,
+	set_cfg_num_buffers,
+	set_cfg_packets_xact,
+	set_cfg_direction,
+	set_cfg_datatype,
+};
+
+static inline struct mdev_link *to_mdev_link(struct config_item *item)
+{
+	return item ? container_of(item, struct mdev_link, item) : NULL;
+}
+
+static ssize_t mdev_link_create_show(struct config_item *item, char *page)
+{
+	return sprintf(page, "%d\n", to_mdev_link(item)->create);
+}
+
+static ssize_t mdev_link_create_store(struct config_item *item,
+				      const char *page, size_t count)
+{
+	struct mdev_link *mdev_link = to_mdev_link(item);
+	u16 tmp;
+	int ret;
+	int i;
+	char *p = (char *)page;
+
+	ret = kstrtou16(p, 0, &tmp);
+	if (ret)
+		return ret;
+	if (tmp > 1)
+		return -ERANGE;
+
+	for (i = 0; i < ARRAY_SIZE(set_config_val); i++) {
+		ret = set_config_val[i](mdev_link);
+		if (ret < 0) {
+			pr_err("Config failed\n");
+			return ret;
+		}
+	}
+
+	if (!mdev_link->mdev || !mdev_link->channel || !mdev_link->comp) {
+		pr_err("Config parameters incomplete\n");
+		return -EIO;
+	}
+	if (tmp)
+		ret = most_add_link(mdev_link->mdev, mdev_link->channel,
+				    mdev_link->comp, mdev_link->name,
+				    mdev_link->param);
+	else
+		ret = most_remove_link(mdev_link->mdev, mdev_link->channel,
+				       mdev_link->comp);
+	if (ret)
+		return ret;
+	mdev_link->create = tmp;
+	return count;
+}
+
+static ssize_t mdev_link_direction_show(struct config_item *item, char *page)
+{
+	return sprintf(page, "%s\n", to_mdev_link(item)->direction);
+}
+
+static ssize_t mdev_link_direction_store(struct config_item *item,
+					 const char *page, size_t count)
+{
+	struct mdev_link *mdev_link = to_mdev_link(item);
+	char *buf = (char *)page;
+
+	if (strcmp(buf, "dir_rx\n") && strcmp(buf, "rx\n") &&
+	    strcmp(buf, "dir_tx\n") && strcmp(buf, "tx\n"))
+		return -EINVAL;
+	strcpy(mdev_link->direction, buf);
+	return count;
+}
+
+static ssize_t mdev_link_datatype_show(struct config_item *item, char *page)
+{
+	return sprintf(page, "%s\n", to_mdev_link(item)->datatype);
+}
+
+static ssize_t mdev_link_datatype_store(struct config_item *item,
+					const char *page, size_t count)
+{
+	struct mdev_link *mdev_link = to_mdev_link(item);
+	char *buf = (char *)page;
+
+	if (strcmp(buf, "control\n") && strcmp(buf, "async\n") &&
+	    strcmp(buf, "sync\n") && strcmp(buf, "isoc\n") &&
+	    strcmp(buf, "isoc_avp\n"))
+		return -EINVAL;
+	strcpy(mdev_link->datatype, buf);
+	return count;
+}
+
+static ssize_t mdev_link_mdev_show(struct config_item *item, char *page)
+{
+	return sprintf(page, "%s\n", to_mdev_link(item)->mdev);
+}
+
+static ssize_t mdev_link_mdev_store(struct config_item *item,
+				    const char *page, size_t count)
+{
+	struct mdev_link *mdev_link = to_mdev_link(item);
+	char *p = (char *)page;
+
+	strcpy(mdev_link->mdev, p);
+	return count;
+}
+
+static ssize_t mdev_link_channel_show(struct config_item *item, char *page)
+{
+	return sprintf(page, "%s\n", to_mdev_link(item)->channel);
+}
+
+static ssize_t mdev_link_channel_store(struct config_item *item,
+				       const char *page, size_t count)
+{
+	struct mdev_link *mdev_link = to_mdev_link(item);
+	char *p = (char *)page;
+
+	strcpy(mdev_link->channel, p);
+	return count;
+}
+
+static ssize_t mdev_link_comp_show(struct config_item *item, char *page)
+{
+	return sprintf(page, "%s\n", to_mdev_link(item)->comp);
+}
+
+static ssize_t mdev_link_comp_store(struct config_item *item,
+				    const char *page, size_t count)
+{
+	struct mdev_link *mdev_link = to_mdev_link(item);
+	char *p = (char *)page;
+
+	strcpy(mdev_link->comp, p);
+
+	return count;
+}
+
+static ssize_t mdev_link_param_show(struct config_item *item, char *page)
+{
+	return sprintf(page, "%s\n", to_mdev_link(item)->param);
+}
+
+static ssize_t mdev_link_param_store(struct config_item *item,
+				     const char *page, size_t count)
+{
+	struct mdev_link *mdev_link = to_mdev_link(item);
+	char *p = (char *)page;
+
+	strcpy(mdev_link->param, p);
+
+	return count;
+}
+
+static ssize_t mdev_link_num_buffers_show(struct config_item *item, char *page)
+{
+	return sprintf(page, "%d\n", to_mdev_link(item)->num_buffers);
+}
+
+static ssize_t mdev_link_num_buffers_store(struct config_item *item,
+					   const char *page, size_t count)
+{
+	struct mdev_link *mdev_link = to_mdev_link(item);
+	char *p = (char *)page;
+	int ret;
+
+	ret = kstrtou16(p, 0, &mdev_link->num_buffers);
+	if (ret)
+		return ret;
+	return count;
+}
+
+static ssize_t mdev_link_buffer_size_show(struct config_item *item, char *page)
+{
+	return sprintf(page, "%d\n", to_mdev_link(item)->buffer_size);
+}
+
+static ssize_t mdev_link_buffer_size_store(struct config_item *item,
+					   const char *page, size_t count)
+{
+	struct mdev_link *mdev_link = to_mdev_link(item);
+	char *p = (char *)page;
+	int ret;
+
+	ret = kstrtou16(p, 0, &mdev_link->buffer_size);
+	if (ret)
+		return ret;
+	return count;
+}
+
+static ssize_t mdev_link_subbuffer_size_show(struct config_item *item,
+					     char *page)
+{
+	return sprintf(page, "%d\n", to_mdev_link(item)->subbuffer_size);
+}
+
+static ssize_t mdev_link_subbuffer_size_store(struct config_item *item,
+					      const char *page, size_t count)
+{
+	struct mdev_link *mdev_link = to_mdev_link(item);
+	char *p = (char *)page;
+	int ret;
+
+	ret = kstrtou16(p, 0, &mdev_link->subbuffer_size);
+	if (ret)
+		return ret;
+	return count;
+}
+
+static ssize_t mdev_link_packets_per_xact_show(struct config_item *item,
+					       char *page)
+{
+	return sprintf(page, "%d\n", to_mdev_link(item)->packets_per_xact);
+}
+
+static ssize_t mdev_link_packets_per_xact_store(struct config_item *item,
+						const char *page, size_t count)
+{
+	struct mdev_link *mdev_link = to_mdev_link(item);
+	char *p = (char *)page;
+	int ret;
+
+	ret = kstrtou16(p, 0, &mdev_link->packets_per_xact);
+	if (ret)
+		return ret;
+	return count;
+}
+
+static ssize_t mdev_link_dbr_size_show(struct config_item *item, char *page)
+{
+	return sprintf(page, "%d\n", to_mdev_link(item)->dbr_size);
+}
+
+static ssize_t mdev_link_dbr_size_store(struct config_item *item,
+					const char *page, size_t count)
+{
+	struct mdev_link *mdev_link = to_mdev_link(item);
+	char *p = (char *)page;
+	int ret;
+
+	ret = kstrtou16(p, 0, &mdev_link->dbr_size);
+	if (ret)
+		return ret;
+	return count;
+}
+
+CONFIGFS_ATTR(mdev_link_, create);
+CONFIGFS_ATTR(mdev_link_, mdev);
+CONFIGFS_ATTR(mdev_link_, channel);
+CONFIGFS_ATTR(mdev_link_, comp);
+CONFIGFS_ATTR(mdev_link_, param);
+CONFIGFS_ATTR(mdev_link_, num_buffers);
+CONFIGFS_ATTR(mdev_link_, buffer_size);
+CONFIGFS_ATTR(mdev_link_, subbuffer_size);
+CONFIGFS_ATTR(mdev_link_, packets_per_xact);
+CONFIGFS_ATTR(mdev_link_, datatype);
+CONFIGFS_ATTR(mdev_link_, direction);
+CONFIGFS_ATTR(mdev_link_, dbr_size);
+
+static struct configfs_attribute *mdev_link_attrs[] = {
+	&mdev_link_attr_create,
+	&mdev_link_attr_mdev,
+	&mdev_link_attr_channel,
+	&mdev_link_attr_comp,
+	&mdev_link_attr_param,
+	&mdev_link_attr_num_buffers,
+	&mdev_link_attr_buffer_size,
+	&mdev_link_attr_subbuffer_size,
+	&mdev_link_attr_packets_per_xact,
+	&mdev_link_attr_datatype,
+	&mdev_link_attr_direction,
+	&mdev_link_attr_dbr_size,
+	NULL,
+};
+
+static void mdev_link_release(struct config_item *item)
+{
+	kfree(to_mdev_link(item));
+}
+
+static struct configfs_item_operations mdev_link_item_ops = {
+	.release		= mdev_link_release,
+};
+
+static const struct config_item_type mdev_link_type = {
+	.ct_item_ops	= &mdev_link_item_ops,
+	.ct_attrs	= mdev_link_attrs,
+	.ct_owner	= THIS_MODULE,
+};
+
+struct most_common {
+	struct config_group group;
+};
+
+static inline struct most_common *to_most_common(struct config_item *item)
+{
+	return item ? container_of(to_config_group(item),
+				   struct most_common, group) : NULL;
+}
+
+static struct config_item *most_common_make_item(struct config_group *group,
+						 const char *name)
+{
+	struct mdev_link *mdev_link;
+
+	mdev_link = kzalloc(sizeof(*mdev_link), GFP_KERNEL);
+	if (!mdev_link)
+		return ERR_PTR(-ENOMEM);
+
+	config_item_init_type_name(&mdev_link->item, name,
+				   &mdev_link_type);
+
+	if (!strcmp(group->cg_item.ci_namebuf, "most_cdev"))
+		strcpy(mdev_link->comp, "cdev");
+	else if (!strcmp(group->cg_item.ci_namebuf, "most_net"))
+		strcpy(mdev_link->comp, "net");
+	else if (!strcmp(group->cg_item.ci_namebuf, "most_video"))
+		strcpy(mdev_link->comp, "video");
+	strcpy(mdev_link->name, name);
+	return &mdev_link->item;
+}
+
+static void most_common_release(struct config_item *item)
+{
+	kfree(to_most_common(item));
+}
+
+static struct configfs_item_operations most_common_item_ops = {
+	.release	= most_common_release,
+};
+
+static struct configfs_group_operations most_common_group_ops = {
+	.make_item	= most_common_make_item,
+};
+
+static const struct config_item_type most_common_type = {
+	.ct_item_ops	= &most_common_item_ops,
+	.ct_group_ops	= &most_common_group_ops,
+	.ct_owner	= THIS_MODULE,
+};
+
+static struct configfs_subsystem most_cdev_subsys = {
+	.su_group = {
+		.cg_item = {
+			.ci_namebuf = "most_cdev",
+			.ci_type = &most_common_type,
+		},
+	},
+};
+
+static struct configfs_subsystem most_net_subsys = {
+	.su_group = {
+		.cg_item = {
+			.ci_namebuf = "most_net",
+			.ci_type = &most_common_type,
+		},
+	},
+};
+
+static struct configfs_subsystem most_video_subsys = {
+	.su_group = {
+		.cg_item = {
+			.ci_namebuf = "most_video",
+			.ci_type = &most_common_type,
+		},
+	},
+};
+
+struct most_snd_grp {
+	struct config_group group;
+	int create;
+	struct list_head list;
+};
+
+static inline struct most_snd_grp *to_most_snd_grp(struct config_item *item)
+{
+	return item ? container_of(to_config_group(item),
+				   struct most_snd_grp, group) : NULL;
+}
+
+static struct config_item *most_snd_grp_make_item(struct config_group *group,
+						  const char *name)
+{
+	struct mdev_link *mdev_link;
+
+	mdev_link = kzalloc(sizeof(*mdev_link), GFP_KERNEL);
+	if (!mdev_link)
+		return ERR_PTR(-ENOMEM);
+
+	config_item_init_type_name(&mdev_link->item, name, &mdev_link_type);
+	mdev_link->create = 0;
+	strcpy(mdev_link->name, name);
+	strcpy(mdev_link->comp, "sound");
+	return &mdev_link->item;
+}
+
+static ssize_t most_snd_grp_create_show(struct config_item *item, char *page)
+{
+	return sprintf(page, "%d\n", to_most_snd_grp(item)->create);
+}
+
+static ssize_t most_snd_grp_create_store(struct config_item *item,
+					 const char *page, size_t count)
+{
+	struct most_snd_grp *snd_grp = to_most_snd_grp(item);
+	int ret = 0;
+	u16 tmp;
+	char *p = (char *)page;
+
+	ret = kstrtou16(p, 0, &tmp);
+	if (ret)
+		return ret;
+	if (tmp > 1)
+		return -ERANGE;
+	if (tmp) {
+		ret = most_cfg_complete("sound");
+		if (ret)
+			return ret;
+	}
+	snd_grp->create = tmp;
+	return count;
+}
+
+CONFIGFS_ATTR(most_snd_grp_, create);
+
+static struct configfs_attribute *most_snd_grp_attrs[] = {
+	&most_snd_grp_attr_create,
+	NULL,
+};
+
+static void most_snd_grp_release(struct config_item *item)
+{
+	struct most_snd_grp *group = to_most_snd_grp(item);
+
+	list_del(&group->list);
+	kfree(group);
+}
+
+static struct configfs_item_operations most_snd_grp_item_ops = {
+	.release	= most_snd_grp_release,
+};
+
+static struct configfs_group_operations most_snd_grp_group_ops = {
+	.make_item	= most_snd_grp_make_item,
+};
+
+static const struct config_item_type most_snd_grp_type = {
+	.ct_item_ops	= &most_snd_grp_item_ops,
+	.ct_group_ops	= &most_snd_grp_group_ops,
+	.ct_attrs	= most_snd_grp_attrs,
+	.ct_owner	= THIS_MODULE,
+};
+
+struct most_sound {
+	struct configfs_subsystem subsys;
+	struct list_head soundcard_list;
+};
+
+static inline struct most_sound *to_most_sound(struct config_item *item)
+{
+	return item ? container_of(to_configfs_subsystem(to_config_group(item)),
+				   struct most_sound, subsys) : NULL;
+}
+
+static struct config_group *most_sound_make_group(struct config_group *group,
+						  const char *name)
+{
+	struct most_snd_grp *most;
+	struct most_sound *ms = container_of(to_configfs_subsystem(group),
+					     struct most_sound, subsys);
+
+	list_for_each_entry(most, &ms->soundcard_list, list) {
+		if (!most->create) {
+			pr_info("adapter configuration still in progress.\n");
+			return ERR_PTR(-EPROTO);
+		}
+	}
+	most = kzalloc(sizeof(*most), GFP_KERNEL);
+	if (!most)
+		return ERR_PTR(-ENOMEM);
+
+	config_group_init_type_name(&most->group, name, &most_snd_grp_type);
+	list_add_tail(&most->list, &ms->soundcard_list);
+	return &most->group;
+}
+
+static struct configfs_group_operations most_sound_group_ops = {
+	.make_group	= most_sound_make_group,
+};
+
+static const struct config_item_type most_sound_type = {
+	.ct_group_ops	= &most_sound_group_ops,
+	.ct_owner	= THIS_MODULE,
+};
+
+static struct most_sound most_sound_subsys = {
+	.subsys = {
+		.su_group = {
+			.cg_item = {
+				.ci_namebuf = "most_sound",
+				.ci_type = &most_sound_type,
+			},
+		},
+	},
+};
+
+int most_register_configfs_subsys(struct core_component *c)
+{
+	int ret;
+
+	if (!strcmp(c->name, "cdev"))
+		ret = configfs_register_subsystem(&most_cdev_subsys);
+	else if (!strcmp(c->name, "net"))
+		ret = configfs_register_subsystem(&most_net_subsys);
+	else if (!strcmp(c->name, "video"))
+		ret = configfs_register_subsystem(&most_video_subsys);
+	else if (!strcmp(c->name, "sound"))
+		ret = configfs_register_subsystem(&most_sound_subsys.subsys);
+	else
+		return -ENODEV;
+
+	if (ret) {
+		pr_err("Error %d while registering subsystem %s\n",
+		       ret,
+		       most_sound_subsys.subsys.su_group.cg_item.ci_namebuf);
+	}
+	return ret;
+}
+EXPORT_SYMBOL_GPL(most_register_configfs_subsys);
+
+void most_deregister_configfs_subsys(struct core_component *c)
+{
+	if (!strcmp(c->name, "cdev"))
+		configfs_unregister_subsystem(&most_cdev_subsys);
+	else if (!strcmp(c->name, "net"))
+		configfs_unregister_subsystem(&most_net_subsys);
+	else if (!strcmp(c->name, "video"))
+		configfs_unregister_subsystem(&most_video_subsys);
+	else if (!strcmp(c->name, "sound"))
+		configfs_unregister_subsystem(&most_sound_subsys.subsys);
+}
+EXPORT_SYMBOL_GPL(most_deregister_configfs_subsys);
+
+int __init configfs_init(void)
+{
+	config_group_init(&most_cdev_subsys.su_group);
+	mutex_init(&most_cdev_subsys.su_mutex);
+
+	config_group_init(&most_net_subsys.su_group);
+	mutex_init(&most_net_subsys.su_mutex);
+
+	config_group_init(&most_video_subsys.su_group);
+	mutex_init(&most_video_subsys.su_mutex);
+
+	config_group_init(&most_sound_subsys.subsys.su_group);
+	mutex_init(&most_sound_subsys.subsys.su_mutex);
+
+	INIT_LIST_HEAD(&most_sound_subsys.soundcard_list);
+
+	return 0;
+}
+
+void __exit configfs_exit(void)
+{
+}
-- 
2.7.4

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 02/14] staging: most: change signature of function probe_channel
  2019-03-21 13:26 [PATCH 00/14] staging: most: switch to configfs Christian Gromm
  2019-03-21 13:26 ` [PATCH 01/14] staging: most: add new file configfs.c Christian Gromm
@ 2019-03-21 13:26 ` Christian Gromm
  2019-03-21 13:26 ` [PATCH 03/14] staging: most: core: add configfs interface functions Christian Gromm
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 20+ messages in thread
From: Christian Gromm @ 2019-03-21 13:26 UTC (permalink / raw)
  To: gregkh; +Cc: Christian Gromm, driverdev-devel

This patch adds the param argument to the function parameter of
the call-back probe_channel. This parameter is needed to configure
the channels of an attached device.

Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
---
 drivers/staging/most/cdev/cdev.c   | 2 +-
 drivers/staging/most/core.c        | 6 ++++--
 drivers/staging/most/core.h        | 3 ++-
 drivers/staging/most/net/net.c     | 3 ++-
 drivers/staging/most/sound/sound.c | 3 +--
 drivers/staging/most/video/video.c | 3 ++-
 6 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/most/cdev/cdev.c b/drivers/staging/most/cdev/cdev.c
index f2b347c..97408ec 100644
--- a/drivers/staging/most/cdev/cdev.c
+++ b/drivers/staging/most/cdev/cdev.c
@@ -425,7 +425,7 @@ static int comp_tx_completion(struct most_interface *iface, int channel_id)
  * Returns 0 on success or error code otherwise.
  */
 static int comp_probe(struct most_interface *iface, int channel_id,
-		      struct most_channel_config *cfg, char *name)
+		      struct most_channel_config *cfg, char *name, char *args)
 {
 	struct comp_channel *c;
 	unsigned long cl_flags;
diff --git a/drivers/staging/most/core.c b/drivers/staging/most/core.c
index 18936cd..fb19b63 100644
--- a/drivers/staging/most/core.c
+++ b/drivers/staging/most/core.c
@@ -701,6 +701,7 @@ static struct most_channel *get_channel(char *mdev, char *mdev_ch)
 static
 inline int link_channel_to_component(struct most_channel *c,
 				     struct core_component *comp,
+				     char *name,
 				     char *comp_param)
 {
 	int ret;
@@ -714,7 +715,8 @@ inline int link_channel_to_component(struct most_channel *c,
 		return -ENOSPC;
 
 	*comp_ptr = comp;
-	ret = comp->probe_channel(c->iface, c->channel_id, &c->cfg, comp_param);
+	ret = comp->probe_channel(c->iface, c->channel_id, &c->cfg, name,
+				  comp_param);
 	if (ret) {
 		*comp_ptr = NULL;
 		return ret;
@@ -775,7 +777,7 @@ static ssize_t add_link_store(struct device_driver *drv,
 	if (!c)
 		return -ENODEV;
 
-	ret = link_channel_to_component(c, comp, comp_param);
+	ret = link_channel_to_component(c, comp, "name", comp_param);
 	if (ret)
 		return ret;
 	return len;
diff --git a/drivers/staging/most/core.h b/drivers/staging/most/core.h
index 64cc02f..025dd1d 100644
--- a/drivers/staging/most/core.h
+++ b/drivers/staging/most/core.h
@@ -266,7 +266,8 @@ struct core_component {
 	struct list_head list;
 	const char *name;
 	int (*probe_channel)(struct most_interface *iface, int channel_idx,
-			     struct most_channel_config *cfg, char *name);
+			     struct most_channel_config *cfg, char *name,
+			     char *param);
 	int (*disconnect_channel)(struct most_interface *iface,
 				  int channel_idx);
 	int (*rx_completion)(struct mbo *mbo);
diff --git a/drivers/staging/most/net/net.c b/drivers/staging/most/net/net.c
index e20584b..c8a64e2 100644
--- a/drivers/staging/most/net/net.c
+++ b/drivers/staging/most/net/net.c
@@ -293,7 +293,8 @@ static struct net_dev_context *get_net_dev_hold(struct most_interface *iface)
 }
 
 static int comp_probe_channel(struct most_interface *iface, int channel_idx,
-			      struct most_channel_config *ccfg, char *name)
+			      struct most_channel_config *ccfg, char *name,
+			      char *args)
 {
 	struct net_dev_context *nd;
 	struct net_dev_channel *ch;
diff --git a/drivers/staging/most/sound/sound.c b/drivers/staging/most/sound/sound.c
index 79ab3a7..02fcd32 100644
--- a/drivers/staging/most/sound/sound.c
+++ b/drivers/staging/most/sound/sound.c
@@ -579,7 +579,7 @@ static void release_adapter(struct sound_adapter *adpt)
  */
 static int audio_probe_channel(struct most_interface *iface, int channel_id,
 			       struct most_channel_config *cfg,
-			       char *arg_list)
+			       char *device_name, char *arg_list)
 {
 	struct channel *channel;
 	struct sound_adapter *adpt;
@@ -588,7 +588,6 @@ static int audio_probe_channel(struct most_interface *iface, int channel_id,
 	int capture_count = 0;
 	int ret;
 	int direction;
-	char *device_name;
 	u16 ch_num;
 	u8 create = 0;
 	char *sample_res;
diff --git a/drivers/staging/most/video/video.c b/drivers/staging/most/video/video.c
index ad7e28a..adca250 100644
--- a/drivers/staging/most/video/video.c
+++ b/drivers/staging/most/video/video.c
@@ -453,7 +453,8 @@ static void comp_v4l2_dev_release(struct v4l2_device *v4l2_dev)
 }
 
 static int comp_probe_channel(struct most_interface *iface, int channel_idx,
-			      struct most_channel_config *ccfg, char *name)
+			      struct most_channel_config *ccfg, char *name,
+			      char *args)
 {
 	int ret;
 	struct most_video_dev *mdev = get_comp_dev(iface, channel_idx);
-- 
2.7.4

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 03/14] staging: most: core: add configfs interface functions
  2019-03-21 13:26 [PATCH 00/14] staging: most: switch to configfs Christian Gromm
  2019-03-21 13:26 ` [PATCH 01/14] staging: most: add new file configfs.c Christian Gromm
  2019-03-21 13:26 ` [PATCH 02/14] staging: most: change signature of function probe_channel Christian Gromm
@ 2019-03-21 13:26 ` Christian Gromm
  2019-03-21 13:26 ` [PATCH 04/14] staging: most: sound: introduce new sound adapter management Christian Gromm
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 20+ messages in thread
From: Christian Gromm @ 2019-03-21 13:26 UTC (permalink / raw)
  To: gregkh; +Cc: Christian Gromm, driverdev-devel

This patch adds the core's interface to configfs file.

Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
---
 drivers/staging/most/core.c | 142 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/staging/most/core.h |  17 +++++-
 2 files changed, 158 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/most/core.c b/drivers/staging/most/core.c
index fb19b63..d5cf58f 100644
--- a/drivers/staging/most/core.c
+++ b/drivers/staging/most/core.c
@@ -783,6 +783,127 @@ static ssize_t add_link_store(struct device_driver *drv,
 	return len;
 }
 
+int most_set_cfg_buffer_size(char *mdev, char *mdev_ch, u16 val)
+{
+	struct most_channel *c = get_channel(mdev, mdev_ch);
+
+	if (!c)
+		return -ENODEV;
+	c->cfg.buffer_size = val;
+	return 0;
+}
+
+int most_set_cfg_subbuffer_size(char *mdev, char *mdev_ch, u16 val)
+{
+	struct most_channel *c = get_channel(mdev, mdev_ch);
+
+	if (!c)
+		return -ENODEV;
+	c->cfg.subbuffer_size = val;
+	return 0;
+}
+
+int most_set_cfg_dbr_size(char *mdev, char *mdev_ch, u16 val)
+{
+	struct most_channel *c = get_channel(mdev, mdev_ch);
+
+	if (!c)
+		return -ENODEV;
+	c->cfg.dbr_size = val;
+	return 0;
+}
+
+int most_set_cfg_num_buffers(char *mdev, char *mdev_ch, u16 val)
+{
+	struct most_channel *c = get_channel(mdev, mdev_ch);
+
+	if (!c)
+		return -ENODEV;
+	c->cfg.num_buffers = val;
+	return 0;
+}
+
+int most_set_cfg_datatype(char *mdev, char *mdev_ch, char *buf)
+{
+	int i;
+	struct most_channel *c = get_channel(mdev, mdev_ch);
+
+	if (!c)
+		return -ENODEV;
+	for (i = 0; i < ARRAY_SIZE(ch_data_type); i++) {
+		if (!strcmp(buf, ch_data_type[i].name)) {
+			c->cfg.data_type = ch_data_type[i].most_ch_data_type;
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(ch_data_type))
+		pr_info("WARN: invalid attribute settings\n");
+	return 0;
+}
+
+int most_set_cfg_direction(char *mdev, char *mdev_ch, char *buf)
+{
+	struct most_channel *c = get_channel(mdev, mdev_ch);
+
+	if (!c)
+		return -ENODEV;
+	if (!strcmp(buf, "dir_rx\n")) {
+		c->cfg.direction = MOST_CH_RX;
+	} else if (!strcmp(buf, "rx\n")) {
+		c->cfg.direction = MOST_CH_RX;
+	} else if (!strcmp(buf, "dir_tx\n")) {
+		c->cfg.direction = MOST_CH_TX;
+	} else if (!strcmp(buf, "tx\n")) {
+		c->cfg.direction = MOST_CH_TX;
+	} else {
+		pr_info("Invalid direction\n");
+		return -ENODATA;
+	}
+	return 0;
+}
+
+int most_set_cfg_packets_xact(char *mdev, char *mdev_ch, u16 val)
+{
+	struct most_channel *c = get_channel(mdev, mdev_ch);
+
+	if (!c)
+		return -ENODEV;
+	c->cfg.packets_per_xact = val;
+	return 0;
+}
+
+int most_cfg_complete(char *comp_name)
+{
+	struct core_component *comp;
+
+	comp = match_component(comp_name);
+	if (!comp)
+		return -ENODEV;
+
+	return comp->cfg_complete();
+}
+
+int most_add_link(char *mdev, char *mdev_ch, char *comp_name, char *link_name,
+		  char *comp_param)
+{
+	struct most_channel *c;
+	struct core_component *comp;
+	char buf[STRING_SIZE];
+
+	comp = match_component(comp_name);
+	if (!comp)
+		return -ENODEV;
+	if (!comp_param || *comp_param == 0) {
+		snprintf(buf, sizeof(buf), "%s-%s", mdev, mdev_ch);
+		comp_param = buf;
+	}
+	c = get_channel(mdev, mdev_ch);
+	if (!c)
+		return -ENODEV;
+
+	return link_channel_to_component(c, comp, link_name, comp_param);
+}
 /**
  * remove_link_store - store function for remove_link attribute
  * @drv: device driver
@@ -825,6 +946,27 @@ static ssize_t remove_link_store(struct device_driver *drv,
 	return len;
 }
 
+int most_remove_link(char *mdev, char *mdev_ch, char *comp_name)
+{
+	struct most_channel *c;
+	struct core_component *comp;
+
+	comp = match_component(comp_name);
+	if (!comp)
+		return -ENODEV;
+	c = get_channel(mdev, mdev_ch);
+	if (!c)
+		return -ENODEV;
+
+	if (comp->disconnect_channel(c->iface, c->channel_id))
+		return -EIO;
+	if (c->pipe0.comp == comp)
+		c->pipe0.comp = NULL;
+	if (c->pipe1.comp == comp)
+		c->pipe1.comp = NULL;
+	return 0;
+}
+
 #define DRV_ATTR(_name)  (&driver_attr_##_name.attr)
 
 static DRIVER_ATTR_RO(links);
diff --git a/drivers/staging/most/core.h b/drivers/staging/most/core.h
index 025dd1d..f875159 100644
--- a/drivers/staging/most/core.h
+++ b/drivers/staging/most/core.h
@@ -272,6 +272,7 @@ struct core_component {
 				  int channel_idx);
 	int (*rx_completion)(struct mbo *mbo);
 	int (*tx_completion)(struct most_interface *iface, int channel_idx);
+	int (*cfg_complete)(void);
 };
 
 /**
@@ -319,5 +320,19 @@ int most_start_channel(struct most_interface *iface, int channel_idx,
 		       struct core_component *comp);
 int most_stop_channel(struct most_interface *iface, int channel_idx,
 		      struct core_component *comp);
-
+int __init configfs_init(void);
+void __exit configfs_exit(void);
+int most_register_configfs_subsys(struct core_component *comp);
+void most_deregister_configfs_subsys(struct core_component *comp);
+int most_add_link(char *mdev, char *mdev_ch, char *comp_name, char *link_name,
+		  char *comp_param);
+int most_remove_link(char *mdev, char *mdev_ch, char *comp_name);
+int most_set_cfg_buffer_size(char *mdev, char *mdev_ch, u16 val);
+int most_set_cfg_subbuffer_size(char *mdev, char *mdev_ch, u16 val);
+int most_set_cfg_dbr_size(char *mdev, char *mdev_ch, u16 val);
+int most_set_cfg_num_buffers(char *mdev, char *mdev_ch, u16 val);
+int most_set_cfg_datatype(char *mdev, char *mdev_ch, char *buf);
+int most_set_cfg_direction(char *mdev, char *mdev_ch, char *buf);
+int most_set_cfg_packets_xact(char *mdev, char *mdev_ch, u16 val);
+int most_cfg_complete(char *comp_name);
 #endif /* MOST_CORE_H_ */
-- 
2.7.4

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 04/14] staging: most: sound: introduce new sound adapter management
  2019-03-21 13:26 [PATCH 00/14] staging: most: switch to configfs Christian Gromm
                   ` (2 preceding siblings ...)
  2019-03-21 13:26 ` [PATCH 03/14] staging: most: core: add configfs interface functions Christian Gromm
@ 2019-03-21 13:26 ` Christian Gromm
  2019-03-21 13:26 ` [PATCH 05/14] staging: most: enable configfs support Christian Gromm
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 20+ messages in thread
From: Christian Gromm @ 2019-03-21 13:26 UTC (permalink / raw)
  To: gregkh; +Cc: Christian Gromm, driverdev-devel

This patch adapts the sound card management to the configfs changes.

Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
---
 drivers/staging/most/sound/sound.c | 41 +++++++++++++++++++++-----------------
 1 file changed, 23 insertions(+), 18 deletions(-)

diff --git a/drivers/staging/most/sound/sound.c b/drivers/staging/most/sound/sound.c
index 02fcd32..049ec44 100644
--- a/drivers/staging/most/sound/sound.c
+++ b/drivers/staging/most/sound/sound.c
@@ -471,17 +471,11 @@ static const struct snd_pcm_ops pcm_ops = {
 	.page       = snd_pcm_lib_get_vmalloc_page,
 };
 
-static int split_arg_list(char *buf, char **device_name, u16 *ch_num,
-			  char **sample_res, u8 *create)
+static int split_arg_list(char *buf, u16 *ch_num, char **sample_res)
 {
 	char *num;
 	int ret;
 
-	*device_name = strsep(&buf, ".");
-	if (!*device_name) {
-		pr_err("Missing sound card name\n");
-		return -EIO;
-	}
 	num = strsep(&buf, "x");
 	if (!num)
 		goto err;
@@ -492,8 +486,6 @@ static int split_arg_list(char *buf, char **device_name, u16 *ch_num,
 	if (!*sample_res)
 		goto err;
 
-	if (buf && !strcmp(buf, "create"))
-		*create = 1;
 	return 0;
 
 err:
@@ -589,7 +581,6 @@ static int audio_probe_channel(struct most_interface *iface, int channel_id,
 	int ret;
 	int direction;
 	u16 ch_num;
-	u8 create = 0;
 	char *sample_res;
 
 	if (!iface)
@@ -600,8 +591,7 @@ static int audio_probe_channel(struct most_interface *iface, int channel_id,
 		return -EINVAL;
 	}
 
-	ret = split_arg_list(arg_list, &device_name, &ch_num, &sample_res,
-			     &create);
+	ret = split_arg_list(arg_list, &ch_num, &sample_res);
 	if (ret < 0)
 		return ret;
 
@@ -672,12 +662,6 @@ static int audio_probe_channel(struct most_interface *iface, int channel_id,
 	strscpy(pcm->name, device_name, sizeof(pcm->name));
 	snd_pcm_set_ops(pcm, direction, &pcm_ops);
 
-	if (create) {
-		ret = snd_card_register(adpt->card);
-		if (ret < 0)
-			goto err_free_adpt;
-		adpt->registered = true;
-	}
 	return 0;
 
 err_free_adpt:
@@ -685,6 +669,26 @@ static int audio_probe_channel(struct most_interface *iface, int channel_id,
 	return ret;
 }
 
+static int audio_create_sound_card(void)
+{
+	int ret;
+	struct sound_adapter *adpt;
+
+	list_for_each_entry(adpt, &adpt_list, list) {
+		if (!adpt->registered)
+			goto adpt_alloc;
+	}
+	return -ENODEV;
+adpt_alloc:
+	ret = snd_card_register(adpt->card);
+	if (ret < 0) {
+		release_adapter(adpt);
+		return ret;
+	}
+	adpt->registered = true;
+	return ret;
+}
+
 /**
  * audio_disconnect_channel - function to disconnect a channel
  * @iface: pointer to interface instance
@@ -781,6 +785,7 @@ static struct core_component comp = {
 	.disconnect_channel = audio_disconnect_channel,
 	.rx_completion = audio_rx_completion,
 	.tx_completion = audio_tx_completion,
+	.cfg_complete = audio_create_sound_card,
 };
 
 static int __init audio_init(void)
-- 
2.7.4

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 05/14] staging: most: enable configfs support
  2019-03-21 13:26 [PATCH 00/14] staging: most: switch to configfs Christian Gromm
                   ` (3 preceding siblings ...)
  2019-03-21 13:26 ` [PATCH 04/14] staging: most: sound: introduce new sound adapter management Christian Gromm
@ 2019-03-21 13:26 ` Christian Gromm
  2019-03-22 11:59   ` [RFC PATCH] staging: most: set_cfg_buffer_size() can be static kbuild test robot
                     ` (2 more replies)
  2019-03-21 13:26 ` [PATCH 06/14] staging: most: core: make sysfs attributes read-only Christian Gromm
                   ` (8 subsequent siblings)
  13 siblings, 3 replies; 20+ messages in thread
From: Christian Gromm @ 2019-03-21 13:26 UTC (permalink / raw)
  To: gregkh; +Cc: Christian Gromm, driverdev-devel

This patch enables the configfs functionality of the driver by
registering the configfs subsystems and compiling the configfs
part of the sources.

Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
---
 drivers/staging/most/Makefile      |  1 +
 drivers/staging/most/cdev/cdev.c   |  6 ++++++
 drivers/staging/most/core.c        |  3 ++-
 drivers/staging/most/sound/sound.c | 11 ++++++++++-
 4 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/most/Makefile b/drivers/staging/most/Makefile
index c7662f6..85ea5a4 100644
--- a/drivers/staging/most/Makefile
+++ b/drivers/staging/most/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_MOST) += most_core.o
 most_core-y := core.o
+most_core-y += configfs.o
 ccflags-y += -I $(srctree)/drivers/staging/
 
 obj-$(CONFIG_MOST_CDEV)	+= cdev/
diff --git a/drivers/staging/most/cdev/cdev.c b/drivers/staging/most/cdev/cdev.c
index 97408ec..d98977c 100644
--- a/drivers/staging/most/cdev/cdev.c
+++ b/drivers/staging/most/cdev/cdev.c
@@ -527,8 +527,13 @@ static int __init mod_init(void)
 	err = most_register_component(&comp.cc);
 	if (err)
 		goto free_cdev;
+	err = most_register_configfs_subsys(&comp.cc);
+	if (err)
+		goto deregister_comp;
 	return 0;
 
+deregister_comp:
+	most_deregister_component(&comp.cc);
 free_cdev:
 	unregister_chrdev_region(comp.devno, CHRDEV_REGION_SIZE);
 dest_ida:
@@ -543,6 +548,7 @@ static void __exit mod_exit(void)
 
 	pr_info("exit module\n");
 
+	most_deregister_configfs_subsys(&comp.cc);
 	most_deregister_component(&comp.cc);
 
 	list_for_each_entry_safe(c, tmp, &channel_list, list) {
diff --git a/drivers/staging/most/core.c b/drivers/staging/most/core.c
index d5cf58f..b366517 100644
--- a/drivers/staging/most/core.c
+++ b/drivers/staging/most/core.c
@@ -1765,7 +1765,7 @@ static int __init most_init(void)
 		err = -ENOMEM;
 		goto err_unregister_driver;
 	}
-
+	configfs_init();
 	return 0;
 
 err_unregister_driver:
@@ -1778,6 +1778,7 @@ static int __init most_init(void)
 static void __exit most_exit(void)
 {
 	pr_info("exit core module\n");
+	configfs_exit();
 	device_unregister(&mc.dev);
 	driver_unregister(&mc.drv);
 	bus_unregister(&mc.bus);
diff --git a/drivers/staging/most/sound/sound.c b/drivers/staging/most/sound/sound.c
index 049ec44..fd089e6 100644
--- a/drivers/staging/most/sound/sound.c
+++ b/drivers/staging/most/sound/sound.c
@@ -790,16 +790,25 @@ static struct core_component comp = {
 
 static int __init audio_init(void)
 {
+	int ret;
+
 	pr_info("init()\n");
 
 	INIT_LIST_HEAD(&adpt_list);
 
-	return most_register_component(&comp);
+	ret = most_register_component(&comp);
+	if (ret)
+		pr_err("Failed to register %s\n", comp.name);
+	ret = most_register_configfs_subsys(&comp);
+	if (ret)
+		pr_err("Failed to register %s configfs subsys\n", comp.name);
+	return ret;
 }
 
 static void __exit audio_exit(void)
 {
 	pr_info("exit()\n");
+	most_deregister_configfs_subsys(&comp);
 	most_deregister_component(&comp);
 }
 
-- 
2.7.4

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 06/14] staging: most: core: make sysfs attributes read-only
  2019-03-21 13:26 [PATCH 00/14] staging: most: switch to configfs Christian Gromm
                   ` (4 preceding siblings ...)
  2019-03-21 13:26 ` [PATCH 05/14] staging: most: enable configfs support Christian Gromm
@ 2019-03-21 13:26 ` Christian Gromm
  2019-03-21 13:26 ` [PATCH 07/14] staging: most: core: use device description as name Christian Gromm
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 20+ messages in thread
From: Christian Gromm @ 2019-03-21 13:26 UTC (permalink / raw)
  To: gregkh; +Cc: Christian Gromm, driverdev-devel

This patch changes the access flags of the channel attributes to
read-only. This is needed, because configuration is done via configfs.

Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
---
 drivers/staging/most/core.c | 122 +++-----------------------------------------
 1 file changed, 7 insertions(+), 115 deletions(-)

diff --git a/drivers/staging/most/core.c b/drivers/staging/most/core.c
index b366517..006f044 100644
--- a/drivers/staging/most/core.c
+++ b/drivers/staging/most/core.c
@@ -272,19 +272,6 @@ static ssize_t set_number_of_buffers_show(struct device *dev,
 	return snprintf(buf, PAGE_SIZE, "%d\n", c->cfg.num_buffers);
 }
 
-static ssize_t set_number_of_buffers_store(struct device *dev,
-					   struct device_attribute *attr,
-					   const char *buf,
-					   size_t count)
-{
-	struct most_channel *c = to_channel(dev);
-	int ret = kstrtou16(buf, 0, &c->cfg.num_buffers);
-
-	if (ret)
-		return ret;
-	return count;
-}
-
 static ssize_t set_buffer_size_show(struct device *dev,
 				    struct device_attribute *attr,
 				    char *buf)
@@ -294,19 +281,6 @@ static ssize_t set_buffer_size_show(struct device *dev,
 	return snprintf(buf, PAGE_SIZE, "%d\n", c->cfg.buffer_size);
 }
 
-static ssize_t set_buffer_size_store(struct device *dev,
-				     struct device_attribute *attr,
-				     const char *buf,
-				     size_t count)
-{
-	struct most_channel *c = to_channel(dev);
-	int ret = kstrtou16(buf, 0, &c->cfg.buffer_size);
-
-	if (ret)
-		return ret;
-	return count;
-}
-
 static ssize_t set_direction_show(struct device *dev,
 				  struct device_attribute *attr,
 				  char *buf)
@@ -320,28 +294,6 @@ static ssize_t set_direction_show(struct device *dev,
 	return snprintf(buf, PAGE_SIZE, "unconfigured\n");
 }
 
-static ssize_t set_direction_store(struct device *dev,
-				   struct device_attribute *attr,
-				   const char *buf,
-				   size_t count)
-{
-	struct most_channel *c = to_channel(dev);
-
-	if (!strcmp(buf, "dir_rx\n")) {
-		c->cfg.direction = MOST_CH_RX;
-	} else if (!strcmp(buf, "rx\n")) {
-		c->cfg.direction = MOST_CH_RX;
-	} else if (!strcmp(buf, "dir_tx\n")) {
-		c->cfg.direction = MOST_CH_TX;
-	} else if (!strcmp(buf, "tx\n")) {
-		c->cfg.direction = MOST_CH_TX;
-	} else {
-		pr_info("WARN: invalid attribute settings\n");
-		return -EINVAL;
-	}
-	return count;
-}
-
 static ssize_t set_datatype_show(struct device *dev,
 				 struct device_attribute *attr,
 				 char *buf)
@@ -356,28 +308,6 @@ static ssize_t set_datatype_show(struct device *dev,
 	return snprintf(buf, PAGE_SIZE, "unconfigured\n");
 }
 
-static ssize_t set_datatype_store(struct device *dev,
-				  struct device_attribute *attr,
-				  const char *buf,
-				  size_t count)
-{
-	int i;
-	struct most_channel *c = to_channel(dev);
-
-	for (i = 0; i < ARRAY_SIZE(ch_data_type); i++) {
-		if (!strcmp(buf, ch_data_type[i].name)) {
-			c->cfg.data_type = ch_data_type[i].most_ch_data_type;
-			break;
-		}
-	}
-
-	if (i == ARRAY_SIZE(ch_data_type)) {
-		pr_info("WARN: invalid attribute settings\n");
-		return -EINVAL;
-	}
-	return count;
-}
-
 static ssize_t set_subbuffer_size_show(struct device *dev,
 				       struct device_attribute *attr,
 				       char *buf)
@@ -387,19 +317,6 @@ static ssize_t set_subbuffer_size_show(struct device *dev,
 	return snprintf(buf, PAGE_SIZE, "%d\n", c->cfg.subbuffer_size);
 }
 
-static ssize_t set_subbuffer_size_store(struct device *dev,
-					struct device_attribute *attr,
-					const char *buf,
-					size_t count)
-{
-	struct most_channel *c = to_channel(dev);
-	int ret = kstrtou16(buf, 0, &c->cfg.subbuffer_size);
-
-	if (ret)
-		return ret;
-	return count;
-}
-
 static ssize_t set_packets_per_xact_show(struct device *dev,
 					 struct device_attribute *attr,
 					 char *buf)
@@ -409,19 +326,6 @@ static ssize_t set_packets_per_xact_show(struct device *dev,
 	return snprintf(buf, PAGE_SIZE, "%d\n", c->cfg.packets_per_xact);
 }
 
-static ssize_t set_packets_per_xact_store(struct device *dev,
-					  struct device_attribute *attr,
-					  const char *buf,
-					  size_t count)
-{
-	struct most_channel *c = to_channel(dev);
-	int ret = kstrtou16(buf, 0, &c->cfg.packets_per_xact);
-
-	if (ret)
-		return ret;
-	return count;
-}
-
 static ssize_t set_dbr_size_show(struct device *dev,
 				 struct device_attribute *attr, char *buf)
 {
@@ -430,18 +334,6 @@ static ssize_t set_dbr_size_show(struct device *dev,
 	return snprintf(buf, PAGE_SIZE, "%d\n", c->cfg.dbr_size);
 }
 
-static ssize_t set_dbr_size_store(struct device *dev,
-				  struct device_attribute *attr,
-				  const char *buf, size_t count)
-{
-	struct most_channel *c = to_channel(dev);
-	int ret = kstrtou16(buf, 0, &c->cfg.dbr_size);
-
-	if (ret)
-		return ret;
-	return count;
-}
-
 #define to_dev_attr(a) container_of(a, struct device_attribute, attr)
 static umode_t channel_attr_is_visible(struct kobject *kobj,
 				       struct attribute *attr, int index)
@@ -469,13 +361,13 @@ static DEVICE_ATTR_RO(number_of_stream_buffers);
 static DEVICE_ATTR_RO(size_of_stream_buffer);
 static DEVICE_ATTR_RO(size_of_packet_buffer);
 static DEVICE_ATTR_RO(channel_starving);
-static DEVICE_ATTR_RW(set_buffer_size);
-static DEVICE_ATTR_RW(set_number_of_buffers);
-static DEVICE_ATTR_RW(set_direction);
-static DEVICE_ATTR_RW(set_datatype);
-static DEVICE_ATTR_RW(set_subbuffer_size);
-static DEVICE_ATTR_RW(set_packets_per_xact);
-static DEVICE_ATTR_RW(set_dbr_size);
+static DEVICE_ATTR_RO(set_buffer_size);
+static DEVICE_ATTR_RO(set_number_of_buffers);
+static DEVICE_ATTR_RO(set_direction);
+static DEVICE_ATTR_RO(set_datatype);
+static DEVICE_ATTR_RO(set_subbuffer_size);
+static DEVICE_ATTR_RO(set_packets_per_xact);
+static DEVICE_ATTR_RO(set_dbr_size);
 
 static struct attribute *channel_attrs[] = {
 	DEV_ATTR(available_directions),
-- 
2.7.4

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 07/14] staging: most: core: use device description as name
  2019-03-21 13:26 [PATCH 00/14] staging: most: switch to configfs Christian Gromm
                   ` (5 preceding siblings ...)
  2019-03-21 13:26 ` [PATCH 06/14] staging: most: core: make sysfs attributes read-only Christian Gromm
@ 2019-03-21 13:26 ` Christian Gromm
  2019-03-21 13:26 ` [PATCH 08/14] staging: most: usb: remove prefix from description tag Christian Gromm
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 20+ messages in thread
From: Christian Gromm @ 2019-03-21 13:26 UTC (permalink / raw)
  To: gregkh; +Cc: Christian Gromm, driverdev-devel

This patch uses the device description to clearly identity a device
attached to the bus. It is needed as the currently useed mdevX
notation is not sufficiant in case more than one network
interface controller is being used at the same time.

Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
---
 drivers/staging/most/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/most/core.c b/drivers/staging/most/core.c
index 006f044..c4423b5 100644
--- a/drivers/staging/most/core.c
+++ b/drivers/staging/most/core.c
@@ -1467,7 +1467,7 @@ int most_register_interface(struct most_interface *iface)
 
 	INIT_LIST_HEAD(&iface->p->channel_list);
 	iface->p->dev_id = id;
-	snprintf(iface->p->name, STRING_SIZE, "mdev%d", id);
+	strcpy(iface->p->name, iface->description);
 	iface->dev.init_name = iface->p->name;
 	iface->dev.bus = &mc.bus;
 	iface->dev.parent = &mc.dev;
-- 
2.7.4

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 08/14] staging: most: usb: remove prefix from description tag
  2019-03-21 13:26 [PATCH 00/14] staging: most: switch to configfs Christian Gromm
                   ` (6 preceding siblings ...)
  2019-03-21 13:26 ` [PATCH 07/14] staging: most: core: use device description as name Christian Gromm
@ 2019-03-21 13:26 ` Christian Gromm
  2019-03-21 13:26 ` [PATCH 09/14] staging: most: core: remove attribute add_link Christian Gromm
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 20+ messages in thread
From: Christian Gromm @ 2019-03-21 13:26 UTC (permalink / raw)
  To: gregkh; +Cc: Christian Gromm, driverdev-devel

This patch cuts off the usb_device prefix of the description string.
It is not needed, as the interface type is already available with the
interface attribute of a channel.

Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
---
 drivers/staging/most/usb/usb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/most/usb/usb.c b/drivers/staging/most/usb/usb.c
index c0293d8..360cb5b 100644
--- a/drivers/staging/most/usb/usb.c
+++ b/drivers/staging/most/usb/usb.c
@@ -1072,7 +1072,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
 	mdev->iface.num_channels = num_endpoints;
 
 	snprintf(mdev->description, sizeof(mdev->description),
-		 "usb_device %d-%s:%d.%d",
+		 "%d-%s:%d.%d",
 		 usb_dev->bus->busnum,
 		 usb_dev->devpath,
 		 usb_dev->config->desc.bConfigurationValue,
-- 
2.7.4

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 09/14] staging: most: core: remove attribute add_link
  2019-03-21 13:26 [PATCH 00/14] staging: most: switch to configfs Christian Gromm
                   ` (7 preceding siblings ...)
  2019-03-21 13:26 ` [PATCH 08/14] staging: most: usb: remove prefix from description tag Christian Gromm
@ 2019-03-21 13:26 ` Christian Gromm
  2019-03-21 13:26 ` [PATCH 10/14] staging: most: allow speculative configuration Christian Gromm
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 20+ messages in thread
From: Christian Gromm @ 2019-03-21 13:26 UTC (permalink / raw)
  To: gregkh; +Cc: Christian Gromm, driverdev-devel

This patch removes the driver attribute add_link. It is not needed, because
the link management is now done via configfs.

Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
---
 drivers/staging/most/core.c | 61 ---------------------------------------------
 1 file changed, 61 deletions(-)

diff --git a/drivers/staging/most/core.c b/drivers/staging/most/core.c
index c4423b5..31291bc 100644
--- a/drivers/staging/most/core.c
+++ b/drivers/staging/most/core.c
@@ -616,65 +616,6 @@ inline int link_channel_to_component(struct most_channel *c,
 	return 0;
 }
 
-/**
- * add_link_store - store function for add_link attribute
- * @drv: device driver
- * @buf: buffer
- * @len: buffer length
- *
- * This parses the string given by buf and splits it into
- * four substrings. Note: last substring is optional. In case a cdev
- * component is loaded the optional 4th substring will make up the name of
- * device node in the /dev directory. If omitted, the device node will
- * inherit the channel's name within sysfs.
- *
- * Searches for (device, channel) pair and probes the component
- *
- * Example:
- * (1) echo "mdev0:ch6:cdev:my_rxchannel" >add_link
- * (2) echo "mdev1:ep81:cdev" >add_link
- *
- * (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_driver *drv,
-			      const char *buf,
-			      size_t len)
-{
-	struct most_channel *c;
-	struct core_component *comp;
-	char buffer[STRING_SIZE];
-	char *mdev;
-	char *mdev_ch;
-	char *comp_name;
-	char *comp_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, &comp_name, &comp_param);
-	if (ret)
-		return ret;
-	comp = match_component(comp_name);
-	if (!comp)
-		return -ENODEV;
-	if (!comp_param || *comp_param == 0) {
-		snprintf(devnod_buf, sizeof(devnod_buf), "%s-%s", mdev,
-			 mdev_ch);
-		comp_param = devnod_buf;
-	}
-
-	c = get_channel(mdev, mdev_ch);
-	if (!c)
-		return -ENODEV;
-
-	ret = link_channel_to_component(c, comp, "name", comp_param);
-	if (ret)
-		return ret;
-	return len;
-}
-
 int most_set_cfg_buffer_size(char *mdev, char *mdev_ch, u16 val)
 {
 	struct most_channel *c = get_channel(mdev, mdev_ch);
@@ -863,13 +804,11 @@ int most_remove_link(char *mdev, char *mdev_ch, char *comp_name)
 
 static DRIVER_ATTR_RO(links);
 static DRIVER_ATTR_RO(components);
-static DRIVER_ATTR_WO(add_link);
 static DRIVER_ATTR_WO(remove_link);
 
 static struct attribute *mc_attrs[] = {
 	DRV_ATTR(links),
 	DRV_ATTR(components),
-	DRV_ATTR(add_link),
 	DRV_ATTR(remove_link),
 	NULL,
 };
-- 
2.7.4

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 10/14] staging: most: allow speculative configuration
  2019-03-21 13:26 [PATCH 00/14] staging: most: switch to configfs Christian Gromm
                   ` (8 preceding siblings ...)
  2019-03-21 13:26 ` [PATCH 09/14] staging: most: core: remove attribute add_link Christian Gromm
@ 2019-03-21 13:26 ` Christian Gromm
  2019-03-21 13:26 ` [PATCH 11/14] staging: most: configfs: make create attributes write-only Christian Gromm
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 20+ messages in thread
From: Christian Gromm @ 2019-03-21 13:26 UTC (permalink / raw)
  To: gregkh; +Cc: Christian Gromm, driverdev-devel

This patch makes the driver accept a link confiiguration eventhough no
device is attached to the bus. Instead the configuration is being applied
as soon as a device is being registered with the core.

Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
---
 drivers/staging/most/configfs.c    | 63 +++++++++++++++++++++++++++-----------
 drivers/staging/most/core.c        | 16 +++-------
 drivers/staging/most/core.h        |  1 +
 drivers/staging/most/sound/sound.c |  6 ++--
 4 files changed, 54 insertions(+), 32 deletions(-)

diff --git a/drivers/staging/most/configfs.c b/drivers/staging/most/configfs.c
index cefce69..84a4bd3 100644
--- a/drivers/staging/most/configfs.c
+++ b/drivers/staging/most/configfs.c
@@ -16,6 +16,7 @@
 
 struct mdev_link {
 	struct config_item item;
+	struct list_head list;
 	int create;
 	u16 num_buffers;
 	u16 buffer_size;
@@ -31,6 +32,8 @@ struct mdev_link {
 	char param[MAX_LEN];
 };
 
+struct list_head mdev_link_list;
+
 int set_cfg_buffer_size(struct mdev_link *link)
 {
 	if (!link->buffer_size)
@@ -107,13 +110,30 @@ static ssize_t mdev_link_create_show(struct config_item *item, char *page)
 	return sprintf(page, "%d\n", to_mdev_link(item)->create);
 }
 
+static int set_config_and_add_link(struct mdev_link *mdev_link)
+{
+	int i;
+	int ret;
+
+	for (i = 0; i < ARRAY_SIZE(set_config_val); i++) {
+		ret = set_config_val[i](mdev_link);
+		if (ret == -ENODATA) {
+			pr_err("Config failed\n");
+			return ret;
+		}
+	}
+
+	return most_add_link(mdev_link->mdev, mdev_link->channel,
+			     mdev_link->comp, mdev_link->name,
+			     mdev_link->param);
+}
+
 static ssize_t mdev_link_create_store(struct config_item *item,
 				      const char *page, size_t count)
 {
 	struct mdev_link *mdev_link = to_mdev_link(item);
 	u16 tmp;
 	int ret;
-	int i;
 	char *p = (char *)page;
 
 	ret = kstrtou16(p, 0, &tmp);
@@ -121,28 +141,18 @@ static ssize_t mdev_link_create_store(struct config_item *item,
 		return ret;
 	if (tmp > 1)
 		return -ERANGE;
-
-	for (i = 0; i < ARRAY_SIZE(set_config_val); i++) {
-		ret = set_config_val[i](mdev_link);
-		if (ret < 0) {
-			pr_err("Config failed\n");
-			return ret;
-		}
-	}
+	if (!tmp)
+		return most_remove_link(mdev_link->mdev, mdev_link->channel,
+					mdev_link->comp);
 
 	if (!mdev_link->mdev || !mdev_link->channel || !mdev_link->comp) {
 		pr_err("Config parameters incomplete\n");
-		return -EIO;
+		return -ENODATA;
 	}
-	if (tmp)
-		ret = most_add_link(mdev_link->mdev, mdev_link->channel,
-				    mdev_link->comp, mdev_link->name,
-				    mdev_link->param);
-	else
-		ret = most_remove_link(mdev_link->mdev, mdev_link->channel,
-				       mdev_link->comp);
-	if (ret)
+	ret = set_config_and_add_link(mdev_link);
+	if (ret && ret != -ENODEV)
 		return ret;
+	list_add_tail(&mdev_link->list, &mdev_link_list);
 	mdev_link->create = tmp;
 	return count;
 }
@@ -622,6 +632,22 @@ int most_register_configfs_subsys(struct core_component *c)
 }
 EXPORT_SYMBOL_GPL(most_register_configfs_subsys);
 
+void most_interface_register_notify(const char *mdev)
+{
+	bool register_snd_card = false;
+	struct mdev_link *mdev_link;
+
+	list_for_each_entry(mdev_link, &mdev_link_list, list) {
+		if (!strcmp(mdev_link->mdev, mdev)) {
+			set_config_and_add_link(mdev_link);
+			if (!strcmp(mdev_link->comp, "sound"))
+				register_snd_card = true;
+		}
+	}
+	if (register_snd_card)
+		most_cfg_complete("sound");
+}
+
 void most_deregister_configfs_subsys(struct core_component *c)
 {
 	if (!strcmp(c->name, "cdev"))
@@ -650,6 +676,7 @@ int __init configfs_init(void)
 	mutex_init(&most_sound_subsys.subsys.su_mutex);
 
 	INIT_LIST_HEAD(&most_sound_subsys.soundcard_list);
+	INIT_LIST_HEAD(&mdev_link_list);
 
 	return 0;
 }
diff --git a/drivers/staging/most/core.c b/drivers/staging/most/core.c
index 31291bc..765a74c0 100644
--- a/drivers/staging/most/core.c
+++ b/drivers/staging/most/core.c
@@ -720,19 +720,10 @@ int most_cfg_complete(char *comp_name)
 int most_add_link(char *mdev, char *mdev_ch, char *comp_name, char *link_name,
 		  char *comp_param)
 {
-	struct most_channel *c;
-	struct core_component *comp;
-	char buf[STRING_SIZE];
+	struct most_channel *c = get_channel(mdev, mdev_ch);
+	struct core_component *comp = match_component(comp_name);
 
-	comp = match_component(comp_name);
-	if (!comp)
-		return -ENODEV;
-	if (!comp_param || *comp_param == 0) {
-		snprintf(buf, sizeof(buf), "%s-%s", mdev, mdev_ch);
-		comp_param = buf;
-	}
-	c = get_channel(mdev, mdev_ch);
-	if (!c)
+	if (!c || !comp)
 		return -ENODEV;
 
 	return link_channel_to_component(c, comp, link_name, comp_param);
@@ -1462,6 +1453,7 @@ int most_register_interface(struct most_interface *iface)
 	}
 	pr_info("registered new device mdev%d (%s)\n",
 		id, iface->description);
+	most_interface_register_notify(iface->description);
 	return 0;
 
 err_free_most_channel:
diff --git a/drivers/staging/most/core.h b/drivers/staging/most/core.h
index f875159..22a0a29 100644
--- a/drivers/staging/most/core.h
+++ b/drivers/staging/most/core.h
@@ -335,4 +335,5 @@ int most_set_cfg_datatype(char *mdev, char *mdev_ch, char *buf);
 int most_set_cfg_direction(char *mdev, char *mdev_ch, char *buf);
 int most_set_cfg_packets_xact(char *mdev, char *mdev_ch, u16 val);
 int most_cfg_complete(char *comp_name);
+void most_interface_register_notify(const char *mdev_name);
 #endif /* MOST_CORE_H_ */
diff --git a/drivers/staging/most/sound/sound.c b/drivers/staging/most/sound/sound.c
index fd089e6..44c9146 100644
--- a/drivers/staging/most/sound/sound.c
+++ b/drivers/staging/most/sound/sound.c
@@ -20,6 +20,7 @@
 #include <most/core.h>
 
 #define DRIVER_NAME "sound"
+#define STRING_SIZE	80
 
 static struct core_component comp;
 
@@ -582,6 +583,7 @@ static int audio_probe_channel(struct most_interface *iface, int channel_id,
 	int direction;
 	u16 ch_num;
 	char *sample_res;
+	char arg_list_cpy[STRING_SIZE];
 
 	if (!iface)
 		return -EINVAL;
@@ -590,8 +592,8 @@ static int audio_probe_channel(struct most_interface *iface, int channel_id,
 		pr_err("Incompatible channel type\n");
 		return -EINVAL;
 	}
-
-	ret = split_arg_list(arg_list, &ch_num, &sample_res);
+	strlcpy(arg_list_cpy, arg_list, STRING_SIZE);
+	ret = split_arg_list(arg_list_cpy, &ch_num, &sample_res);
 	if (ret < 0)
 		return ret;
 
-- 
2.7.4

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 11/14] staging: most: configfs: make create attributes write-only
  2019-03-21 13:26 [PATCH 00/14] staging: most: switch to configfs Christian Gromm
                   ` (9 preceding siblings ...)
  2019-03-21 13:26 ` [PATCH 10/14] staging: most: allow speculative configuration Christian Gromm
@ 2019-03-21 13:26 ` Christian Gromm
  2019-03-21 13:26 ` [PATCH 12/14] staging: most: configfs: add code for link removal Christian Gromm
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 20+ messages in thread
From: Christian Gromm @ 2019-03-21 13:26 UTC (permalink / raw)
  To: gregkh; +Cc: Christian Gromm, driverdev-devel

Reading the create attribute that triggers the creation of a link to
a certain channel is not necessary. Hence, it is being removed.

Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
---
 drivers/staging/most/configfs.c | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/most/configfs.c b/drivers/staging/most/configfs.c
index 84a4bd3..1e1d7d0 100644
--- a/drivers/staging/most/configfs.c
+++ b/drivers/staging/most/configfs.c
@@ -105,11 +105,6 @@ static inline struct mdev_link *to_mdev_link(struct config_item *item)
 	return item ? container_of(item, struct mdev_link, item) : NULL;
 }
 
-static ssize_t mdev_link_create_show(struct config_item *item, char *page)
-{
-	return sprintf(page, "%d\n", to_mdev_link(item)->create);
-}
-
 static int set_config_and_add_link(struct mdev_link *mdev_link)
 {
 	int i;
@@ -348,7 +343,7 @@ static ssize_t mdev_link_dbr_size_store(struct config_item *item,
 	return count;
 }
 
-CONFIGFS_ATTR(mdev_link_, create);
+CONFIGFS_ATTR_WO(mdev_link_, create);
 CONFIGFS_ATTR(mdev_link_, mdev);
 CONFIGFS_ATTR(mdev_link_, channel);
 CONFIGFS_ATTR(mdev_link_, comp);
@@ -498,11 +493,6 @@ static struct config_item *most_snd_grp_make_item(struct config_group *group,
 	return &mdev_link->item;
 }
 
-static ssize_t most_snd_grp_create_show(struct config_item *item, char *page)
-{
-	return sprintf(page, "%d\n", to_most_snd_grp(item)->create);
-}
-
 static ssize_t most_snd_grp_create_store(struct config_item *item,
 					 const char *page, size_t count)
 {
@@ -525,7 +515,7 @@ static ssize_t most_snd_grp_create_store(struct config_item *item,
 	return count;
 }
 
-CONFIGFS_ATTR(most_snd_grp_, create);
+CONFIGFS_ATTR_WO(most_snd_grp_, create);
 
 static struct configfs_attribute *most_snd_grp_attrs[] = {
 	&most_snd_grp_attr_create,
-- 
2.7.4

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 12/14] staging: most: configfs: add code for link removal
  2019-03-21 13:26 [PATCH 00/14] staging: most: switch to configfs Christian Gromm
                   ` (10 preceding siblings ...)
  2019-03-21 13:26 ` [PATCH 11/14] staging: most: configfs: make create attributes write-only Christian Gromm
@ 2019-03-21 13:26 ` Christian Gromm
  2019-03-21 13:26 ` [PATCH 13/14] staging: most: configfs: rename config attributes Christian Gromm
  2019-03-21 13:26 ` [PATCH 14/14] staging: most: Documentation: update driver documentation Christian Gromm
  13 siblings, 0 replies; 20+ messages in thread
From: Christian Gromm @ 2019-03-21 13:26 UTC (permalink / raw)
  To: gregkh; +Cc: driverdev-devel, Christian Gromm

This patch adds code that cleans up established links whenever the destroy
attribute is set or if the config_item (directory) is being removed.

Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
---
 drivers/staging/most/configfs.c | 41 +++++++++++++++++++++++++++++++++++++----
 1 file changed, 37 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/most/configfs.c b/drivers/staging/most/configfs.c
index 1e1d7d0..cb0256a 100644
--- a/drivers/staging/most/configfs.c
+++ b/drivers/staging/most/configfs.c
@@ -18,6 +18,7 @@ struct mdev_link {
 	struct config_item item;
 	struct list_head list;
 	int create;
+	int destroy;
 	u16 num_buffers;
 	u16 buffer_size;
 	u16 subbuffer_size;
@@ -134,11 +135,8 @@ static ssize_t mdev_link_create_store(struct config_item *item,
 	ret = kstrtou16(p, 0, &tmp);
 	if (ret)
 		return ret;
-	if (tmp > 1)
+	if (tmp != 1)
 		return -ERANGE;
-	if (!tmp)
-		return most_remove_link(mdev_link->mdev, mdev_link->channel,
-					mdev_link->comp);
 
 	if (!mdev_link->mdev || !mdev_link->channel || !mdev_link->comp) {
 		pr_err("Config parameters incomplete\n");
@@ -152,6 +150,29 @@ static ssize_t mdev_link_create_store(struct config_item *item,
 	return count;
 }
 
+static ssize_t mdev_link_destroy_store(struct config_item *item,
+				       const char *page, size_t count)
+{
+	struct mdev_link *mdev_link = to_mdev_link(item);
+	u16 tmp;
+	int ret;
+	char *p = (char *)page;
+
+	ret = kstrtou16(p, 0, &tmp);
+	if (ret)
+		return ret;
+	if (tmp != 1)
+		return -ERANGE;
+	mdev_link->destroy = tmp;
+	ret = most_remove_link(mdev_link->mdev, mdev_link->channel,
+			       mdev_link->comp);
+	if (ret)
+		return ret;
+	if (!list_empty(&mdev_link_list))
+		list_del(&mdev_link->list);
+	return count;
+}
+
 static ssize_t mdev_link_direction_show(struct config_item *item, char *page)
 {
 	return sprintf(page, "%s\n", to_mdev_link(item)->direction);
@@ -344,6 +365,7 @@ static ssize_t mdev_link_dbr_size_store(struct config_item *item,
 }
 
 CONFIGFS_ATTR_WO(mdev_link_, create);
+CONFIGFS_ATTR_WO(mdev_link_, destroy);
 CONFIGFS_ATTR(mdev_link_, mdev);
 CONFIGFS_ATTR(mdev_link_, channel);
 CONFIGFS_ATTR(mdev_link_, comp);
@@ -358,6 +380,7 @@ CONFIGFS_ATTR(mdev_link_, dbr_size);
 
 static struct configfs_attribute *mdev_link_attrs[] = {
 	&mdev_link_attr_create,
+	&mdev_link_attr_destroy,
 	&mdev_link_attr_mdev,
 	&mdev_link_attr_channel,
 	&mdev_link_attr_comp,
@@ -374,6 +397,16 @@ static struct configfs_attribute *mdev_link_attrs[] = {
 
 static void mdev_link_release(struct config_item *item)
 {
+	struct mdev_link *mdev_link = to_mdev_link(item);
+	int ret;
+
+	if (!list_empty(&mdev_link_list)) {
+		ret = most_remove_link(mdev_link->mdev, mdev_link->channel,
+				       mdev_link->comp);
+		if (ret && (ret != -ENODEV))
+			pr_err("Removing link failed.\n");
+		list_del(&mdev_link->list);
+	}
 	kfree(to_mdev_link(item));
 }
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 13/14] staging: most: configfs: rename config attributes
  2019-03-21 13:26 [PATCH 00/14] staging: most: switch to configfs Christian Gromm
                   ` (11 preceding siblings ...)
  2019-03-21 13:26 ` [PATCH 12/14] staging: most: configfs: add code for link removal Christian Gromm
@ 2019-03-21 13:26 ` Christian Gromm
  2019-03-21 13:26 ` [PATCH 14/14] staging: most: Documentation: update driver documentation Christian Gromm
  13 siblings, 0 replies; 20+ messages in thread
From: Christian Gromm @ 2019-03-21 13:26 UTC (permalink / raw)
  To: gregkh; +Cc: Christian Gromm, driverdev-devel

This patch introduces attribute names that are more self explaining.

Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
---
 drivers/staging/most/configfs.c | 98 ++++++++++++++++++++---------------------
 1 file changed, 49 insertions(+), 49 deletions(-)

diff --git a/drivers/staging/most/configfs.c b/drivers/staging/most/configfs.c
index cb0256a..8d6aaf9 100644
--- a/drivers/staging/most/configfs.c
+++ b/drivers/staging/most/configfs.c
@@ -17,8 +17,8 @@
 struct mdev_link {
 	struct config_item item;
 	struct list_head list;
-	int create;
-	int destroy;
+	int create_link;
+	int destroy_link;
 	u16 num_buffers;
 	u16 buffer_size;
 	u16 subbuffer_size;
@@ -27,10 +27,10 @@ struct mdev_link {
 	char datatype[MAX_LEN];
 	char direction[MAX_LEN];
 	char name[MAX_LEN];
-	char mdev[MAX_LEN];
+	char device[MAX_LEN];
 	char channel[MAX_LEN];
 	char comp[MAX_LEN];
-	char param[MAX_LEN];
+	char comp_params[MAX_LEN];
 };
 
 struct list_head mdev_link_list;
@@ -39,7 +39,7 @@ int set_cfg_buffer_size(struct mdev_link *link)
 {
 	if (!link->buffer_size)
 		return -ENODATA;
-	return most_set_cfg_buffer_size(link->mdev, link->channel,
+	return most_set_cfg_buffer_size(link->device, link->channel,
 					link->buffer_size);
 }
 
@@ -47,7 +47,7 @@ int set_cfg_subbuffer_size(struct mdev_link *link)
 {
 	if (!link->subbuffer_size)
 		return -ENODATA;
-	return most_set_cfg_subbuffer_size(link->mdev, link->channel,
+	return most_set_cfg_subbuffer_size(link->device, link->channel,
 					   link->subbuffer_size);
 }
 
@@ -55,7 +55,7 @@ int set_cfg_dbr_size(struct mdev_link *link)
 {
 	if (!link->dbr_size)
 		return -ENODATA;
-	return most_set_cfg_dbr_size(link->mdev, link->channel,
+	return most_set_cfg_dbr_size(link->device, link->channel,
 				     link->dbr_size);
 }
 
@@ -63,7 +63,7 @@ int set_cfg_num_buffers(struct mdev_link *link)
 {
 	if (!link->num_buffers)
 		return -ENODATA;
-	return most_set_cfg_num_buffers(link->mdev, link->channel,
+	return most_set_cfg_num_buffers(link->device, link->channel,
 					link->num_buffers);
 }
 
@@ -71,7 +71,7 @@ int set_cfg_packets_xact(struct mdev_link *link)
 {
 	if (!link->packets_per_xact)
 		return -ENODATA;
-	return most_set_cfg_packets_xact(link->mdev, link->channel,
+	return most_set_cfg_packets_xact(link->device, link->channel,
 					 link->packets_per_xact);
 }
 
@@ -79,7 +79,7 @@ int set_cfg_direction(struct mdev_link *link)
 {
 	if (!strlen(link->direction))
 		return -ENODATA;
-	return most_set_cfg_direction(link->mdev, link->channel,
+	return most_set_cfg_direction(link->device, link->channel,
 				      link->direction);
 }
 
@@ -87,7 +87,7 @@ int set_cfg_datatype(struct mdev_link *link)
 {
 	if (!strlen(link->datatype))
 		return -ENODATA;
-	return most_set_cfg_datatype(link->mdev, link->channel,
+	return most_set_cfg_datatype(link->device, link->channel,
 				     link->datatype);
 }
 
@@ -119,13 +119,13 @@ static int set_config_and_add_link(struct mdev_link *mdev_link)
 		}
 	}
 
-	return most_add_link(mdev_link->mdev, mdev_link->channel,
+	return most_add_link(mdev_link->device, mdev_link->channel,
 			     mdev_link->comp, mdev_link->name,
-			     mdev_link->param);
+			     mdev_link->comp_params);
 }
 
-static ssize_t mdev_link_create_store(struct config_item *item,
-				      const char *page, size_t count)
+static ssize_t mdev_link_create_link_store(struct config_item *item,
+					   const char *page, size_t count)
 {
 	struct mdev_link *mdev_link = to_mdev_link(item);
 	u16 tmp;
@@ -138,7 +138,7 @@ static ssize_t mdev_link_create_store(struct config_item *item,
 	if (tmp != 1)
 		return -ERANGE;
 
-	if (!mdev_link->mdev || !mdev_link->channel || !mdev_link->comp) {
+	if (!mdev_link->device || !mdev_link->channel || !mdev_link->comp) {
 		pr_err("Config parameters incomplete\n");
 		return -ENODATA;
 	}
@@ -146,12 +146,12 @@ static ssize_t mdev_link_create_store(struct config_item *item,
 	if (ret && ret != -ENODEV)
 		return ret;
 	list_add_tail(&mdev_link->list, &mdev_link_list);
-	mdev_link->create = tmp;
+	mdev_link->create_link = tmp;
 	return count;
 }
 
-static ssize_t mdev_link_destroy_store(struct config_item *item,
-				       const char *page, size_t count)
+static ssize_t mdev_link_destroy_link_store(struct config_item *item,
+					    const char *page, size_t count)
 {
 	struct mdev_link *mdev_link = to_mdev_link(item);
 	u16 tmp;
@@ -163,8 +163,8 @@ static ssize_t mdev_link_destroy_store(struct config_item *item,
 		return ret;
 	if (tmp != 1)
 		return -ERANGE;
-	mdev_link->destroy = tmp;
-	ret = most_remove_link(mdev_link->mdev, mdev_link->channel,
+	mdev_link->destroy_link = tmp;
+	ret = most_remove_link(mdev_link->device, mdev_link->channel,
 			       mdev_link->comp);
 	if (ret)
 		return ret;
@@ -210,18 +210,18 @@ static ssize_t mdev_link_datatype_store(struct config_item *item,
 	return count;
 }
 
-static ssize_t mdev_link_mdev_show(struct config_item *item, char *page)
+static ssize_t mdev_link_device_show(struct config_item *item, char *page)
 {
-	return sprintf(page, "%s\n", to_mdev_link(item)->mdev);
+	return sprintf(page, "%s\n", to_mdev_link(item)->device);
 }
 
-static ssize_t mdev_link_mdev_store(struct config_item *item,
-				    const char *page, size_t count)
+static ssize_t mdev_link_device_store(struct config_item *item,
+				      const char *page, size_t count)
 {
 	struct mdev_link *mdev_link = to_mdev_link(item);
 	char *p = (char *)page;
 
-	strcpy(mdev_link->mdev, p);
+	strcpy(mdev_link->device, p);
 	return count;
 }
 
@@ -256,18 +256,18 @@ static ssize_t mdev_link_comp_store(struct config_item *item,
 	return count;
 }
 
-static ssize_t mdev_link_param_show(struct config_item *item, char *page)
+static ssize_t mdev_link_comp_params_show(struct config_item *item, char *page)
 {
-	return sprintf(page, "%s\n", to_mdev_link(item)->param);
+	return sprintf(page, "%s\n", to_mdev_link(item)->comp_params);
 }
 
-static ssize_t mdev_link_param_store(struct config_item *item,
-				     const char *page, size_t count)
+static ssize_t mdev_link_comp_params_store(struct config_item *item,
+					   const char *page, size_t count)
 {
 	struct mdev_link *mdev_link = to_mdev_link(item);
 	char *p = (char *)page;
 
-	strcpy(mdev_link->param, p);
+	strcpy(mdev_link->comp_params, p);
 
 	return count;
 }
@@ -364,12 +364,12 @@ static ssize_t mdev_link_dbr_size_store(struct config_item *item,
 	return count;
 }
 
-CONFIGFS_ATTR_WO(mdev_link_, create);
-CONFIGFS_ATTR_WO(mdev_link_, destroy);
-CONFIGFS_ATTR(mdev_link_, mdev);
+CONFIGFS_ATTR_WO(mdev_link_, create_link);
+CONFIGFS_ATTR_WO(mdev_link_, destroy_link);
+CONFIGFS_ATTR(mdev_link_, device);
 CONFIGFS_ATTR(mdev_link_, channel);
 CONFIGFS_ATTR(mdev_link_, comp);
-CONFIGFS_ATTR(mdev_link_, param);
+CONFIGFS_ATTR(mdev_link_, comp_params);
 CONFIGFS_ATTR(mdev_link_, num_buffers);
 CONFIGFS_ATTR(mdev_link_, buffer_size);
 CONFIGFS_ATTR(mdev_link_, subbuffer_size);
@@ -379,12 +379,12 @@ CONFIGFS_ATTR(mdev_link_, direction);
 CONFIGFS_ATTR(mdev_link_, dbr_size);
 
 static struct configfs_attribute *mdev_link_attrs[] = {
-	&mdev_link_attr_create,
-	&mdev_link_attr_destroy,
-	&mdev_link_attr_mdev,
+	&mdev_link_attr_create_link,
+	&mdev_link_attr_destroy_link,
+	&mdev_link_attr_device,
 	&mdev_link_attr_channel,
 	&mdev_link_attr_comp,
-	&mdev_link_attr_param,
+	&mdev_link_attr_comp_params,
 	&mdev_link_attr_num_buffers,
 	&mdev_link_attr_buffer_size,
 	&mdev_link_attr_subbuffer_size,
@@ -401,7 +401,7 @@ static void mdev_link_release(struct config_item *item)
 	int ret;
 
 	if (!list_empty(&mdev_link_list)) {
-		ret = most_remove_link(mdev_link->mdev, mdev_link->channel,
+		ret = most_remove_link(mdev_link->device, mdev_link->channel,
 				       mdev_link->comp);
 		if (ret && (ret != -ENODEV))
 			pr_err("Removing link failed.\n");
@@ -500,7 +500,7 @@ static struct configfs_subsystem most_video_subsys = {
 
 struct most_snd_grp {
 	struct config_group group;
-	int create;
+	int create_card;
 	struct list_head list;
 };
 
@@ -520,14 +520,14 @@ static struct config_item *most_snd_grp_make_item(struct config_group *group,
 		return ERR_PTR(-ENOMEM);
 
 	config_item_init_type_name(&mdev_link->item, name, &mdev_link_type);
-	mdev_link->create = 0;
+	mdev_link->create_link = 0;
 	strcpy(mdev_link->name, name);
 	strcpy(mdev_link->comp, "sound");
 	return &mdev_link->item;
 }
 
-static ssize_t most_snd_grp_create_store(struct config_item *item,
-					 const char *page, size_t count)
+static ssize_t most_snd_grp_create_card_store(struct config_item *item,
+					      const char *page, size_t count)
 {
 	struct most_snd_grp *snd_grp = to_most_snd_grp(item);
 	int ret = 0;
@@ -544,14 +544,14 @@ static ssize_t most_snd_grp_create_store(struct config_item *item,
 		if (ret)
 			return ret;
 	}
-	snd_grp->create = tmp;
+	snd_grp->create_card = tmp;
 	return count;
 }
 
-CONFIGFS_ATTR_WO(most_snd_grp_, create);
+CONFIGFS_ATTR_WO(most_snd_grp_, create_card);
 
 static struct configfs_attribute *most_snd_grp_attrs[] = {
-	&most_snd_grp_attr_create,
+	&most_snd_grp_attr_create_card,
 	NULL,
 };
 
@@ -597,7 +597,7 @@ static struct config_group *most_sound_make_group(struct config_group *group,
 					     struct most_sound, subsys);
 
 	list_for_each_entry(most, &ms->soundcard_list, list) {
-		if (!most->create) {
+		if (!most->create_card) {
 			pr_info("adapter configuration still in progress.\n");
 			return ERR_PTR(-EPROTO);
 		}
@@ -661,7 +661,7 @@ void most_interface_register_notify(const char *mdev)
 	struct mdev_link *mdev_link;
 
 	list_for_each_entry(mdev_link, &mdev_link_list, list) {
-		if (!strcmp(mdev_link->mdev, mdev)) {
+		if (!strcmp(mdev_link->device, mdev)) {
 			set_config_and_add_link(mdev_link);
 			if (!strcmp(mdev_link->comp, "sound"))
 				register_snd_card = true;
-- 
2.7.4

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 14/14] staging: most: Documentation: update driver documentation
  2019-03-21 13:26 [PATCH 00/14] staging: most: switch to configfs Christian Gromm
                   ` (12 preceding siblings ...)
  2019-03-21 13:26 ` [PATCH 13/14] staging: most: configfs: rename config attributes Christian Gromm
@ 2019-03-21 13:26 ` Christian Gromm
  13 siblings, 0 replies; 20+ messages in thread
From: Christian Gromm @ 2019-03-21 13:26 UTC (permalink / raw)
  To: gregkh; +Cc: Christian Gromm, driverdev-devel

This patch updates the driver documentation files to reflect the
latest changes regarding configfs.

Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
---
 .../most/Documentation/ABI/configfs-most.txt       | 204 +++++++++++++++++++++
 .../staging/most/Documentation/driver_usage.txt    | 131 +++++++------
 2 files changed, 284 insertions(+), 51 deletions(-)
 create mode 100644 drivers/staging/most/Documentation/ABI/configfs-most.txt

diff --git a/drivers/staging/most/Documentation/ABI/configfs-most.txt b/drivers/staging/most/Documentation/ABI/configfs-most.txt
new file mode 100644
index 0000000..f5669f4
--- /dev/null
+++ b/drivers/staging/most/Documentation/ABI/configfs-most.txt
@@ -0,0 +1,204 @@
+What: 		/sys/kernel/config/most_<component>
+Date: 		March 8, 2019
+KernelVersion:  5.0.0
+Description: 	Interface is used to configure and connect device channels
+		to component drivers.
+
+		Attributes are visible only when configfs is mounted. To mount
+		configfs in /sys/kernel/config directory use:
+		# mount -t configfs none /sys/kernel/config/
+
+
+What: 		/sys/kernel/config/most_cdev/<link>
+Date: 		March 8, 2019
+KernelVersion:  5.0.0
+Description:
+		The attributes:
+
+		buffer_size	configure the buffer size for this channel
+
+		subbuffer_size	configure the sub-buffer size for this channel
+				(needed for synchronous and isochrnous data)
+
+
+		num_buffers	configure number of buffers used for this
+				channel
+
+		datatype	configure type of data that will travel over
+				this channel
+
+		direction	configure whether this link will be an input
+				or output
+
+		dbr_size	configure DBR data buffer size (this is used
+				for MediaLB communiction only)
+
+		packets_per_xact
+				configure the number of packets that will be
+				collected from the network before being
+				transmitted via USB (this is used for USB
+				communiction only)
+
+		device		name of the device the link is to be attached to
+
+		channel		name of the channel the link is to be attached to
+
+		comp_params	pass parameters needed by some components
+
+		create_link	write '1' to this attribute to trigger the
+				creation of the link. In case of speculative
+				configuration, the creation is post-poned until
+				a physical device is being attached to the bus.
+
+		destroy_link	write '1' to this attribute to destroy an
+				active link
+
+What: 		/sys/kernel/config/most_video/<link>
+Date: 		March 8, 2019
+KernelVersion:  5.0.0
+Description:
+		The attributes:
+
+		buffer_size	configure the buffer size for this channel
+
+		subbuffer_size	configure the sub-buffer size for this channel
+				(needed for synchronous and isochrnous data)
+
+
+		num_buffers	configure number of buffers used for this
+				channel
+
+		datatype	configure type of data that will travel over
+				this channel
+
+		direction	configure whether this link will be an input
+				or output
+
+		dbr_size	configure DBR data buffer size (this is used
+				for MediaLB communiction only)
+
+		packets_per_xact
+				configure the number of packets that will be
+				collected from the network before being
+				transmitted via USB (this is used for USB
+				communiction only)
+
+		device		name of the device the link is to be attached to
+
+		channel		name of the channel the link is to be attached to
+
+		comp_params	pass parameters needed by some components
+
+		create_link	write '1' to this attribute to trigger the
+				creation of the link. In case of speculative
+				configuration, the creation is post-poned until
+				a physical device is being attached to the bus.
+
+		destroy_link	write '1' to this attribute to destroy an
+				active link
+
+What: 		/sys/kernel/config/most_net/<link>
+Date: 		March 8, 2019
+KernelVersion:  5.0.0
+Description:
+		The attributes:
+
+		buffer_size	configure the buffer size for this channel
+
+		subbuffer_size	configure the sub-buffer size for this channel
+				(needed for synchronous and isochrnous data)
+
+
+		num_buffers	configure number of buffers used for this
+				channel
+
+		datatype	configure type of data that will travel over
+				this channel
+
+		direction	configure whether this link will be an input
+				or output
+
+		dbr_size	configure DBR data buffer size (this is used
+				for MediaLB communiction only)
+
+		packets_per_xact
+				configure the number of packets that will be
+				collected from the network before being
+				transmitted via USB (this is used for USB
+				communiction only)
+
+		device		name of the device the link is to be attached to
+
+		channel		name of the channel the link is to be attached to
+
+		comp_params	pass parameters needed by some components
+
+		create_link	write '1' to this attribute to trigger the
+				creation of the link. In case of speculative
+				configuration, the creation is post-poned until
+				a physical device is being attached to the bus.
+
+		destroy_link	write '1' to this attribute to destroy an
+				active link
+
+What: 		/sys/kernel/config/most_sound/<card>
+Date: 		March 8, 2019
+KernelVersion:  5.0.0
+Description:
+		The attributes:
+
+		create_card	write '1' to this attribute to trigger the
+                                registration of the sound card with the ALSA
+				subsystem.
+
+What: 		/sys/kernel/config/most_sound/<card>/<link>
+Date: 		March 8, 2019
+KernelVersion:  5.0.0
+Description:
+		The attributes:
+
+		buffer_size	configure the buffer size for this channel
+
+		subbuffer_size	configure the sub-buffer size for this channel
+				(needed for synchronous and isochrnous data)
+
+
+		num_buffers	configure number of buffers used for this
+				channel
+
+		datatype	configure type of data that will travel over
+				this channel
+
+		direction	configure whether this link will be an input
+				or output
+
+		dbr_size	configure DBR data buffer size (this is used
+				for MediaLB communiction only)
+
+		packets_per_xact
+				configure the number of packets that will be
+				collected from the network before being
+				transmitted via USB (this is used for USB
+				communiction only)
+
+		device		name of the device the link is to be attached to
+
+		channel		name of the channel the link is to be attached to
+
+		comp_params	pass parameters needed by some components
+
+		create_link	write '1' to this attribute to trigger the
+				creation of the link. In case of speculative
+				configuration, the creation is post-poned until
+				a physical device is being attached to the bus.
+
+		destroy_link	write '1' to this attribute to destroy an
+				active link
+
+What: 		/sys/kernel/config/rdma_cm/<hca>/ports/<port-num>/default_roce_tos
+Date: 		March 8, 2019
+KernelVersion:  5.0.0
+Description: 	RDMA-CM QPs from HCA <hca> at port <port-num>
+		will be created with this TOS as default.
+		This can be overridden by using the rdma_set_option API.
+		The possible RoCE TOS values are 0-255.
diff --git a/drivers/staging/most/Documentation/driver_usage.txt b/drivers/staging/most/Documentation/driver_usage.txt
index da7a8f4..56d7919 100644
--- a/drivers/staging/most/Documentation/driver_usage.txt
+++ b/drivers/staging/most/Documentation/driver_usage.txt
@@ -115,36 +115,75 @@ following components are available
 
 		Section 2 Usage of the MOST Driver
 
-		Section 2.1 Configuration
-
-See ABI/sysfs-bus-most.txt
-
-
-		Section 2.2 Routing Channels
-
-To connect a configured channel to a certain core component and make it
-accessible for user space applications, the driver attribute 'add_link' is
-used. The configuration string passed to it has the following format:
-
-	"device_name:channel_name:component_name:link_name[.param]"
-
-It is the concatenation of up to four substrings separated by a colon. The
-substrings contain the names of the MOST interface, the channel, the
-component driver and a custom name with which the link is going to be
-referenced with. Since some components need additional information, the
-link name can be extended with a component-specific parameter (separated by
-a dot). In case the character device component is loaded, the handle would
-also appear as a device node in the /dev directory.
-
-Cdev component example:
-        $ echo "mdev0:ep_81:cdev:my_rx_channel" >$(DRV_DIR)/add_link
-
-
-Sound component example:
-
-The sound component needs additional parameters to determine the audio
-resolution that is going to be used and to trigger the registration of a
-sound card with ALSA. The following audio formats are available:
+		Section 2.1 Configuration and Data Link
+
+The driver is to be configured via configfs. Each loaded component kernel
+object (see section 1.3) registers a subsystem with configfs, which is used to
+configure and establish communiction pathways (links) to attached devices on
+the bus. To do so, the user has to descend into the component's configuration
+directory and create a new directory (child config itmes). The name of this
+directory will be used as a reference for the link and it will contain the
+following attributes:
+
+	- buffer_size
+	  configure the buffer size for this channel
+	- subbuffer_size
+	  configure the sub-buffer size for this channel (needed for
+	  synchronous and isochrnous data)
+	- num_buffers
+	  configure number of buffers used for this channel
+	- datatype
+	  configure type of data that will travel over this channel
+	- direction
+	  configure whether this link will be an input or output
+	- dbr_size
+	  configure DBR data buffer size (this is used for MediaLB communiction
+	  only)
+	- packets_per_xact
+	  configure the number of packets that will be collected from the
+	  network before being transmitted via USB (this is used for USB
+	  communiction only)
+	- device
+	  name of the device the link is to be attached to
+	- channel
+	  name of the channel the link is to be attached to
+	- comp_params
+	  pass parameters needed by some components
+	- create_link
+	  write '1' to this attribute to trigger the creation of the link. In
+	  case of speculative configuration, the creation is post-poned until
+	  a physical device is being attached to the bus.
+	- destroy_link
+	  write '1' to this attribute to destroy an already established link
+
+
+See ABI/sysfs-bus-most.txt and ABI/configfs-most.txt
+
+
+		Section 2.2 Configure a Sound Card
+
+Setting up synchronous channels to be mapped as an ALSA sound adapter is a two
+step process. Firstly, a directory (child config group) has to be created
+inside the most_sound's configuration directory. This adapter dir will
+represent the sound adapter. The name of the directory is for user reference
+only and has no further influence, as all sound adapters will be given a static
+name in ALSA. The sound adapter will have the following attribute:
+
+	- create_card
+	  write '1' to this attribute to trigger the registration of the card
+	  with the ALSA subsystem.
+	  In case of speculative configuration, the creation is post-poned
+	  until a physical device is being attached to the bus.
+
+Secondly, links will have to be created inside the adapter dir as described in
+section 2.1. These links will become the PCM devices of the sound card. The
+name of a PCM device will be inherited from the directory name. When all
+channels have been configured and created, the sound card itself can be created
+by writing '1' to the create_card attribute.
+
+The sound component needs an additional parameter to determine the audio
+resolution that is going to be used.
+The following audio formats are available:
 
 	- "1x8" (Mono)
 	- "2x16" (16-bit stereo)
@@ -152,18 +191,8 @@ sound card with ALSA. The following audio formats are available:
 	- "2x32" (32-bit stereo)
 	- "6x16" (16-bit surround 5.1)
 
-To make the sound module create a sound card and register it with ALSA the
-string "create" needs to be attached to the module parameter section of the
-configuration string. To create a sound card with with two playback devices
-(linked to channel ep01 and ep02) and one capture device (linked to channel
-ep83) the following is written to the add_link file:
-
-        $ echo "mdev0:ep01:sound:most51_playback.6x16" >$(DRV_DIR)/add_link
-        $ echo "mdev0:ep02:sound:most_playback.2x16" >$(DRV_DIR)/add_link
-        $ echo "mdev0:ep83:sound:most_capture.2x16.create" >$(DRV_DIR)/add_link
-
-The link names (most51_playback, most_playback and most_capture) will
-become the names of the PCM devices of the sound card.
+The resolution string has to be written to the link directory's comp_params
+attribute.
 
 		Section 2.3 USB Padding
 
@@ -174,13 +203,13 @@ hardware, which is for performance optimization purposes of the USB
 transmission.
 
 When transmitting synchronous data the allocated channel width needs to be
-written to 'set_subbuffer_size'. Additionally, the number of MOST frames
-that should travel to the host within one USB transaction need to be
-written to 'packets_per_xact'.
+written to 'subbuffer_size'. Additionally, the number of MOST frames that
+should travel to the host within one USB transaction need to be written to
+'packets_per_xact'.
 
 The driver, then, calculates the synchronous threshold as follows:
 
-	frame_size = set_subbuffer_size * packets_per_xact
+	frame_size = subbuffer_size * packets_per_xact
 
 In case 'packets_per_xact' is set to 0xFF the maximum number of packets,
 allocated within one MOST frame, is calculated that fit into _one_ 512 byte
@@ -192,15 +221,15 @@ This frame_size is the number of synchronous data within an USB
 transaction, which renders MTU_USB - frame_size bytes for padding.
 
 When transmitting isochronous AVP data the desired packet size needs to be
-written to 'set_subbuffer_size' and hardware will always expect two
-isochronous packets within one USB transaction. This renders
+written to 'subbuffer_size' and hardware will always expect two isochronous
+packets within one USB transaction. This renders
 
-	MTU_USB - (2 * set_subbuffer_size)
+	MTU_USB - (2 * subbuffer_size)
 
 bytes for padding.
 
-Note that at least (2 * set_subbuffer_size) bytes for isochronous data or
-(set_subbuffer_size * packts_per_xact) bytes for synchronous data need to
+Note that at least (2 * subbuffer_size) bytes for isochronous data or
+(subbuffer_size * packts_per_xact) bytes for synchronous data need to
 be put in the transmission buffer and passed to the driver.
 
 Since adapter drivers are allowed to change a chosen configuration to best
-- 
2.7.4

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH 01/14] staging: most: add new file configfs.c
  2019-03-21 13:26 ` [PATCH 01/14] staging: most: add new file configfs.c Christian Gromm
@ 2019-03-22 10:44   ` Dan Carpenter
  2019-03-22 10:46   ` Dan Carpenter
  1 sibling, 0 replies; 20+ messages in thread
From: Dan Carpenter @ 2019-03-22 10:44 UTC (permalink / raw)
  To: Christian Gromm; +Cc: gregkh, driverdev-devel

On Thu, Mar 21, 2019 at 02:26:02PM +0100, Christian Gromm wrote:
> This patch adds the file configfs.c to the driver directory. The file
> registers the necessary subsystems with configfs in order to move the
> driver configuration from sysfs to configfs.
> 
> Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
> ---
>  drivers/staging/most/configfs.c | 659 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 659 insertions(+)
>  create mode 100644 drivers/staging/most/configfs.c
> 
> diff --git a/drivers/staging/most/configfs.c b/drivers/staging/most/configfs.c
> new file mode 100644
> index 0000000..cefce69
> --- /dev/null
> +++ b/drivers/staging/most/configfs.c
> @@ -0,0 +1,659 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * configfs.c - Implementation of configfs interface to the driver stack
> + *
> + * Copyright (C) 2013-2015 Microchip Technology Germany II GmbH & Co. KG
> + */
> +
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +#include <linux/init.h>
> +#include <linux/configfs.h>
> +#include <most/core.h>
> +
> +#define MAX_LEN 30
> +
> +struct mdev_link {
> +	struct config_item item;
> +	int create;
> +	u16 num_buffers;
> +	u16 buffer_size;
> +	u16 subbuffer_size;
> +	u16 packets_per_xact;
> +	u16 dbr_size;
> +	char datatype[MAX_LEN];
> +	char direction[MAX_LEN];
> +	char name[MAX_LEN];
> +	char mdev[MAX_LEN];
> +	char channel[MAX_LEN];
> +	char comp[MAX_LEN];
> +	char param[MAX_LEN];
> +};
> +
> +int set_cfg_buffer_size(struct mdev_link *link)
   ^^^^^^^^^^^^^^^^^^^^^^^
Please run Sparse over your code.  This should be static.

> +{
> +	if (!link->buffer_size)
> +		return -ENODATA;
> +	return most_set_cfg_buffer_size(link->mdev, link->channel,
> +					link->buffer_size);
> +}
> +
> +int set_cfg_subbuffer_size(struct mdev_link *link)
> +{
> +	if (!link->subbuffer_size)
> +		return -ENODATA;
> +	return most_set_cfg_subbuffer_size(link->mdev, link->channel,
> +					   link->subbuffer_size);
> +}
> +
> +int set_cfg_dbr_size(struct mdev_link *link)
> +{
> +	if (!link->dbr_size)
> +		return -ENODATA;
> +	return most_set_cfg_dbr_size(link->mdev, link->channel,
> +				     link->dbr_size);
> +}
> +
> +int set_cfg_num_buffers(struct mdev_link *link)
> +{
> +	if (!link->num_buffers)
> +		return -ENODATA;
> +	return most_set_cfg_num_buffers(link->mdev, link->channel,
> +					link->num_buffers);
> +}
> +
> +int set_cfg_packets_xact(struct mdev_link *link)
> +{
> +	if (!link->packets_per_xact)
> +		return -ENODATA;
> +	return most_set_cfg_packets_xact(link->mdev, link->channel,
> +					 link->packets_per_xact);
> +}
> +
> +int set_cfg_direction(struct mdev_link *link)
> +{
> +	if (!strlen(link->direction))
> +		return -ENODATA;
> +	return most_set_cfg_direction(link->mdev, link->channel,
> +				      link->direction);
> +}
> +
> +int set_cfg_datatype(struct mdev_link *link)
> +{
> +	if (!strlen(link->datatype))
> +		return -ENODATA;
> +	return most_set_cfg_datatype(link->mdev, link->channel,
> +				     link->datatype);
> +}
> +
> +static int (*set_config_val[])(struct mdev_link *link) = {
> +	set_cfg_buffer_size,
> +	set_cfg_subbuffer_size,
> +	set_cfg_dbr_size,
> +	set_cfg_num_buffers,
> +	set_cfg_packets_xact,
> +	set_cfg_direction,
> +	set_cfg_datatype,
> +};
> +
> +static inline struct mdev_link *to_mdev_link(struct config_item *item)
          ^^^^^^
No need to mark this as inline.  The compiler is smart enough to do it
automatically.

> +{
> +	return item ? container_of(item, struct mdev_link, item) : NULL;

None of the callers check the return...  Just do:

	return container_of(item, struct mdev_link, item);


> +}
> +
> +static ssize_t mdev_link_create_show(struct config_item *item, char *page)
> +{
> +	return sprintf(page, "%d\n", to_mdev_link(item)->create);
> +}
> +
> +static ssize_t mdev_link_create_store(struct config_item *item,
> +				      const char *page, size_t count)
> +{
> +	struct mdev_link *mdev_link = to_mdev_link(item);
> +	u16 tmp;
> +	int ret;
> +	int i;
> +	char *p = (char *)page;
> +
> +	ret = kstrtou16(p, 0, &tmp);
> +	if (ret)
> +		return ret;
> +	if (tmp > 1)
> +		return -ERANGE;
> +
> +	for (i = 0; i < ARRAY_SIZE(set_config_val); i++) {
> +		ret = set_config_val[i](mdev_link);
> +		if (ret < 0) {
> +			pr_err("Config failed\n");

This error message is not very useful.

> +			return ret;
> +		}
> +	}
> +
> +	if (!mdev_link->mdev || !mdev_link->channel || !mdev_link->comp) {
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
These are arrays, not pointers.  Remove.  We checked already.

> +		pr_err("Config parameters incomplete\n");
> +		return -EIO;
> +	}
> +	if (tmp)
> +		ret = most_add_link(mdev_link->mdev, mdev_link->channel,
> +				    mdev_link->comp, mdev_link->name,
> +				    mdev_link->param);
> +	else
> +		ret = most_remove_link(mdev_link->mdev, mdev_link->channel,
> +				       mdev_link->comp);
> +	if (ret)
> +		return ret;
> +	mdev_link->create = tmp;
> +	return count;
> +}
> +
> +static ssize_t mdev_link_direction_show(struct config_item *item, char *page)
> +{
> +	return sprintf(page, "%s\n", to_mdev_link(item)->direction);

Can you use snprintf()?  It's slightly tricky for static analysis tools
to verify that ->direction is NUL terminated properly.

> +}
> +
> +static ssize_t mdev_link_direction_store(struct config_item *item,
> +					 const char *page, size_t count)
> +{
> +	struct mdev_link *mdev_link = to_mdev_link(item);
> +	char *buf = (char *)page;
        ^^^^^^^^^^^^^^^^^^^^^^^^
No need for the "buf" variable.  Just rename page, or use page as-is.

> +
> +	if (strcmp(buf, "dir_rx\n") && strcmp(buf, "rx\n") &&
> +	    strcmp(buf, "dir_tx\n") && strcmp(buf, "tx\n"))
> +		return -EINVAL;


> +	strcpy(mdev_link->direction, buf);
> +	return count;
> +}
> +
> +static ssize_t mdev_link_datatype_show(struct config_item *item, char *page)
> +{
> +	return sprintf(page, "%s\n", to_mdev_link(item)->datatype);

%s goes to snprintf(), please.

> +}
> +
> +static ssize_t mdev_link_datatype_store(struct config_item *item,
> +					const char *page, size_t count)
> +{
> +	struct mdev_link *mdev_link = to_mdev_link(item);
> +	char *buf = (char *)page;
> +
> +	if (strcmp(buf, "control\n") && strcmp(buf, "async\n") &&
> +	    strcmp(buf, "sync\n") && strcmp(buf, "isoc\n") &&
> +	    strcmp(buf, "isoc_avp\n"))
> +		return -EINVAL;
> +	strcpy(mdev_link->datatype, buf);
> +	return count;
> +}
> +
> +static ssize_t mdev_link_mdev_show(struct config_item *item, char *page)
> +{
> +	return sprintf(page, "%s\n", to_mdev_link(item)->mdev);
> +}
> +
> +static ssize_t mdev_link_mdev_store(struct config_item *item,
> +				    const char *page, size_t count)
> +{
> +	struct mdev_link *mdev_link = to_mdev_link(item);
> +	char *p = (char *)page;
> +
> +	strcpy(mdev_link->mdev, p);
        ^^^^^^^^^^^^^^^^^^^^^^^^^^
Buffer overflow.  PAGE_SIZE of text can't fit in 30 chars.

> +	return count;
> +}
> +
> +static ssize_t mdev_link_channel_show(struct config_item *item, char *page)
> +{
> +	return sprintf(page, "%s\n", to_mdev_link(item)->channel);
> +}
> +
> +static ssize_t mdev_link_channel_store(struct config_item *item,
> +				       const char *page, size_t count)
> +{
> +	struct mdev_link *mdev_link = to_mdev_link(item);
> +	char *p = (char *)page;
> +
> +	strcpy(mdev_link->channel, p);
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Buffer overflow.

> +	return count;
> +}
> +
> +static ssize_t mdev_link_comp_show(struct config_item *item, char *page)
> +{
> +	return sprintf(page, "%s\n", to_mdev_link(item)->comp);
> +}
> +
> +static ssize_t mdev_link_comp_store(struct config_item *item,
> +				    const char *page, size_t count)
> +{
> +	struct mdev_link *mdev_link = to_mdev_link(item);
> +	char *p = (char *)page;
> +
> +	strcpy(mdev_link->comp, p);
        ^^^^^^^^^^^^^^^^^^^^^^^^^^
Buffer overflow.

> +
> +	return count;
> +}
> +
> +static ssize_t mdev_link_param_show(struct config_item *item, char *page)
> +{
> +	return sprintf(page, "%s\n", to_mdev_link(item)->param);
               ^^^^^^^        ^^

> +}
> +
> +static ssize_t mdev_link_param_store(struct config_item *item,
> +				     const char *page, size_t count)
> +{
> +	struct mdev_link *mdev_link = to_mdev_link(item);
> +	char *p = (char *)page;
> +
> +	strcpy(mdev_link->param, p);
        ^^^^^^^^^^^^^^^^^^^^^^^^^^

> +
> +	return count;
> +}
> +
> +static ssize_t mdev_link_num_buffers_show(struct config_item *item, char *page)
> +{
> +	return sprintf(page, "%d\n", to_mdev_link(item)->num_buffers);
> +}
> +
> +static ssize_t mdev_link_num_buffers_store(struct config_item *item,
> +					   const char *page, size_t count)
> +{
> +	struct mdev_link *mdev_link = to_mdev_link(item);
> +	char *p = (char *)page;
        ^^^^^^^

No need.

> +	int ret;
> +
> +	ret = kstrtou16(p, 0, &mdev_link->num_buffers);
> +	if (ret)
> +		return ret;
> +	return count;
> +}
> +
> +static ssize_t mdev_link_buffer_size_show(struct config_item *item, char *page)
> +{
> +	return sprintf(page, "%d\n", to_mdev_link(item)->buffer_size);
> +}
> +
> +static ssize_t mdev_link_buffer_size_store(struct config_item *item,
> +					   const char *page, size_t count)
> +{
> +	struct mdev_link *mdev_link = to_mdev_link(item);
> +	char *p = (char *)page;
> +	int ret;
> +
> +	ret = kstrtou16(p, 0, &mdev_link->buffer_size);
> +	if (ret)
> +		return ret;
> +	return count;
> +}
> +
> +static ssize_t mdev_link_subbuffer_size_show(struct config_item *item,
> +					     char *page)
> +{
> +	return sprintf(page, "%d\n", to_mdev_link(item)->subbuffer_size);
> +}
> +
> +static ssize_t mdev_link_subbuffer_size_store(struct config_item *item,
> +					      const char *page, size_t count)
> +{
> +	struct mdev_link *mdev_link = to_mdev_link(item);
> +	char *p = (char *)page;
> +	int ret;
> +
> +	ret = kstrtou16(p, 0, &mdev_link->subbuffer_size);
> +	if (ret)
> +		return ret;
> +	return count;
> +}
> +
> +static ssize_t mdev_link_packets_per_xact_show(struct config_item *item,
> +					       char *page)
> +{
> +	return sprintf(page, "%d\n", to_mdev_link(item)->packets_per_xact);
> +}
> +
> +static ssize_t mdev_link_packets_per_xact_store(struct config_item *item,
> +						const char *page, size_t count)
> +{
> +	struct mdev_link *mdev_link = to_mdev_link(item);
> +	char *p = (char *)page;
> +	int ret;
> +
> +	ret = kstrtou16(p, 0, &mdev_link->packets_per_xact);
> +	if (ret)
> +		return ret;
> +	return count;
> +}
> +
> +static ssize_t mdev_link_dbr_size_show(struct config_item *item, char *page)
> +{
> +	return sprintf(page, "%d\n", to_mdev_link(item)->dbr_size);
> +}
> +
> +static ssize_t mdev_link_dbr_size_store(struct config_item *item,
> +					const char *page, size_t count)
> +{
> +	struct mdev_link *mdev_link = to_mdev_link(item);
> +	char *p = (char *)page;
> +	int ret;
> +
> +	ret = kstrtou16(p, 0, &mdev_link->dbr_size);
> +	if (ret)
> +		return ret;
> +	return count;
> +}
> +
> +CONFIGFS_ATTR(mdev_link_, create);
> +CONFIGFS_ATTR(mdev_link_, mdev);
> +CONFIGFS_ATTR(mdev_link_, channel);
> +CONFIGFS_ATTR(mdev_link_, comp);
> +CONFIGFS_ATTR(mdev_link_, param);
> +CONFIGFS_ATTR(mdev_link_, num_buffers);
> +CONFIGFS_ATTR(mdev_link_, buffer_size);
> +CONFIGFS_ATTR(mdev_link_, subbuffer_size);
> +CONFIGFS_ATTR(mdev_link_, packets_per_xact);
> +CONFIGFS_ATTR(mdev_link_, datatype);
> +CONFIGFS_ATTR(mdev_link_, direction);
> +CONFIGFS_ATTR(mdev_link_, dbr_size);
> +
> +static struct configfs_attribute *mdev_link_attrs[] = {
> +	&mdev_link_attr_create,
> +	&mdev_link_attr_mdev,
> +	&mdev_link_attr_channel,
> +	&mdev_link_attr_comp,
> +	&mdev_link_attr_param,
> +	&mdev_link_attr_num_buffers,
> +	&mdev_link_attr_buffer_size,
> +	&mdev_link_attr_subbuffer_size,
> +	&mdev_link_attr_packets_per_xact,
> +	&mdev_link_attr_datatype,
> +	&mdev_link_attr_direction,
> +	&mdev_link_attr_dbr_size,
> +	NULL,
> +};
> +
> +static void mdev_link_release(struct config_item *item)
> +{
> +	kfree(to_mdev_link(item));
> +}
> +
> +static struct configfs_item_operations mdev_link_item_ops = {
> +	.release		= mdev_link_release,
> +};
> +
> +static const struct config_item_type mdev_link_type = {
> +	.ct_item_ops	= &mdev_link_item_ops,
> +	.ct_attrs	= mdev_link_attrs,
> +	.ct_owner	= THIS_MODULE,
> +};
> +
> +struct most_common {
> +	struct config_group group;
> +};
> +
> +static inline struct most_common *to_most_common(struct config_item *item)
> +{
> +	return item ? container_of(to_config_group(item),
> +				   struct most_common, group) : NULL;

The caller does check for NULLs, but I don't know if checking is really
required here.  I suspect not.

> +}
> +
> +static struct config_item *most_common_make_item(struct config_group *group,
> +						 const char *name)
> +{
> +	struct mdev_link *mdev_link;
> +
> +	mdev_link = kzalloc(sizeof(*mdev_link), GFP_KERNEL);
> +	if (!mdev_link)
> +		return ERR_PTR(-ENOMEM);
> +
> +	config_item_init_type_name(&mdev_link->item, name,
> +				   &mdev_link_type);
> +
> +	if (!strcmp(group->cg_item.ci_namebuf, "most_cdev"))
> +		strcpy(mdev_link->comp, "cdev");
> +	else if (!strcmp(group->cg_item.ci_namebuf, "most_net"))
> +		strcpy(mdev_link->comp, "net");
> +	else if (!strcmp(group->cg_item.ci_namebuf, "most_video"))
> +		strcpy(mdev_link->comp, "video");
> +	strcpy(mdev_link->name, name);
> +	return &mdev_link->item;
> +}
> +
> +static void most_common_release(struct config_item *item)
> +{
> +	kfree(to_most_common(item));
> +}
> +
> +static struct configfs_item_operations most_common_item_ops = {
> +	.release	= most_common_release,
> +};
> +
> +static struct configfs_group_operations most_common_group_ops = {
> +	.make_item	= most_common_make_item,
> +};
> +
> +static const struct config_item_type most_common_type = {
> +	.ct_item_ops	= &most_common_item_ops,
> +	.ct_group_ops	= &most_common_group_ops,
> +	.ct_owner	= THIS_MODULE,
> +};
> +
> +static struct configfs_subsystem most_cdev_subsys = {
> +	.su_group = {
> +		.cg_item = {
> +			.ci_namebuf = "most_cdev",
> +			.ci_type = &most_common_type,
> +		},
> +	},
> +};
> +
> +static struct configfs_subsystem most_net_subsys = {
> +	.su_group = {
> +		.cg_item = {
> +			.ci_namebuf = "most_net",
> +			.ci_type = &most_common_type,
> +		},
> +	},
> +};
> +
> +static struct configfs_subsystem most_video_subsys = {
> +	.su_group = {
> +		.cg_item = {
> +			.ci_namebuf = "most_video",
> +			.ci_type = &most_common_type,
> +		},
> +	},
> +};
> +
> +struct most_snd_grp {
> +	struct config_group group;
> +	int create;
> +	struct list_head list;
> +};
> +
> +static inline struct most_snd_grp *to_most_snd_grp(struct config_item *item)
> +{
> +	return item ? container_of(to_config_group(item),
> +				   struct most_snd_grp, group) : NULL;

The callers don't check for NULL returns.

> +}
> +
> +static struct config_item *most_snd_grp_make_item(struct config_group *group,
> +						  const char *name)
> +{
> +	struct mdev_link *mdev_link;
> +
> +	mdev_link = kzalloc(sizeof(*mdev_link), GFP_KERNEL);
> +	if (!mdev_link)
> +		return ERR_PTR(-ENOMEM);
> +
> +	config_item_init_type_name(&mdev_link->item, name, &mdev_link_type);
> +	mdev_link->create = 0;
> +	strcpy(mdev_link->name, name);
> +	strcpy(mdev_link->comp, "sound");
> +	return &mdev_link->item;
> +}
> +
> +static ssize_t most_snd_grp_create_show(struct config_item *item, char *page)
> +{
> +	return sprintf(page, "%d\n", to_most_snd_grp(item)->create);
> +}
> +
> +static ssize_t most_snd_grp_create_store(struct config_item *item,
> +					 const char *page, size_t count)
> +{
> +	struct most_snd_grp *snd_grp = to_most_snd_grp(item);
> +	int ret = 0;
               ^^^^
No need to initialize.

> +	u16 tmp;
> +	char *p = (char *)page;
        ^^^^^^^
No need.

> +
> +	ret = kstrtou16(p, 0, &tmp);

I would be tempting to recomend kstrtobool() which allows "Yes/no" and
on/off inputs as well.

> +	if (ret)
> +		return ret;
> +	if (tmp > 1)
> +		return -ERANGE;
> +	if (tmp) {
> +		ret = most_cfg_complete("sound");
> +		if (ret)
> +			return ret;
> +	}
> +	snd_grp->create = tmp;
> +	return count;
> +}
> +
> +CONFIGFS_ATTR(most_snd_grp_, create);
> +
> +static struct configfs_attribute *most_snd_grp_attrs[] = {
> +	&most_snd_grp_attr_create,
> +	NULL,
> +};
> +
> +static void most_snd_grp_release(struct config_item *item)
> +{
> +	struct most_snd_grp *group = to_most_snd_grp(item);
> +
> +	list_del(&group->list);
> +	kfree(group);
> +}
> +
> +static struct configfs_item_operations most_snd_grp_item_ops = {
> +	.release	= most_snd_grp_release,
> +};
> +
> +static struct configfs_group_operations most_snd_grp_group_ops = {
> +	.make_item	= most_snd_grp_make_item,
> +};
> +
> +static const struct config_item_type most_snd_grp_type = {
> +	.ct_item_ops	= &most_snd_grp_item_ops,
> +	.ct_group_ops	= &most_snd_grp_group_ops,
> +	.ct_attrs	= most_snd_grp_attrs,
> +	.ct_owner	= THIS_MODULE,
> +};
> +
> +struct most_sound {
> +	struct configfs_subsystem subsys;
> +	struct list_head soundcard_list;
> +};
> +
> +static inline struct most_sound *to_most_sound(struct config_item *item)

I can't find any callers.  Weird that the compiler doesn't complain.

> +{
> +	return item ? container_of(to_configfs_subsystem(to_config_group(item)),
> +				   struct most_sound, subsys) : NULL;
> +}
> +
> +static struct config_group *most_sound_make_group(struct config_group *group,
> +						  const char *name)
> +{
> +	struct most_snd_grp *most;
> +	struct most_sound *ms = container_of(to_configfs_subsystem(group),
> +					     struct most_sound, subsys);
> +
> +	list_for_each_entry(most, &ms->soundcard_list, list) {
> +		if (!most->create) {
> +			pr_info("adapter configuration still in progress.\n");

This error message is slightly off.  The adapter could be disabled.

> +			return ERR_PTR(-EPROTO);
> +		}
> +	}
> +	most = kzalloc(sizeof(*most), GFP_KERNEL);
> +	if (!most)
> +		return ERR_PTR(-ENOMEM);
> +
> +	config_group_init_type_name(&most->group, name, &most_snd_grp_type);
> +	list_add_tail(&most->list, &ms->soundcard_list);
> +	return &most->group;
> +}
> +
> +static struct configfs_group_operations most_sound_group_ops = {
> +	.make_group	= most_sound_make_group,
> +};
> +
> +static const struct config_item_type most_sound_type = {
> +	.ct_group_ops	= &most_sound_group_ops,
> +	.ct_owner	= THIS_MODULE,
> +};
> +
> +static struct most_sound most_sound_subsys = {
> +	.subsys = {
> +		.su_group = {
> +			.cg_item = {
> +				.ci_namebuf = "most_sound",
> +				.ci_type = &most_sound_type,
> +			},
> +		},
> +	},
> +};
> +
> +int most_register_configfs_subsys(struct core_component *c)
> +{
> +	int ret;
> +
> +	if (!strcmp(c->name, "cdev"))
> +		ret = configfs_register_subsystem(&most_cdev_subsys);
> +	else if (!strcmp(c->name, "net"))
> +		ret = configfs_register_subsystem(&most_net_subsys);
> +	else if (!strcmp(c->name, "video"))
> +		ret = configfs_register_subsystem(&most_video_subsys);
> +	else if (!strcmp(c->name, "sound"))
> +		ret = configfs_register_subsystem(&most_sound_subsys.subsys);
> +	else
> +		return -ENODEV;
> +
> +	if (ret) {
> +		pr_err("Error %d while registering subsystem %s\n",
> +		       ret,
> +		       most_sound_subsys.subsys.su_group.cg_item.ci_namebuf);
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Could you use "c->name" instead?

> +	}
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(most_register_configfs_subsys);
> +
> +void most_deregister_configfs_subsys(struct core_component *c)
> +{
> +	if (!strcmp(c->name, "cdev"))
> +		configfs_unregister_subsystem(&most_cdev_subsys);
> +	else if (!strcmp(c->name, "net"))
> +		configfs_unregister_subsystem(&most_net_subsys);
> +	else if (!strcmp(c->name, "video"))
> +		configfs_unregister_subsystem(&most_video_subsys);
> +	else if (!strcmp(c->name, "sound"))
> +		configfs_unregister_subsystem(&most_sound_subsys.subsys);
> +}
> +EXPORT_SYMBOL_GPL(most_deregister_configfs_subsys);
> +
> +int __init configfs_init(void)
> +{
> +	config_group_init(&most_cdev_subsys.su_group);
> +	mutex_init(&most_cdev_subsys.su_mutex);
> +
> +	config_group_init(&most_net_subsys.su_group);
> +	mutex_init(&most_net_subsys.su_mutex);
> +
> +	config_group_init(&most_video_subsys.su_group);
> +	mutex_init(&most_video_subsys.su_mutex);
> +
> +	config_group_init(&most_sound_subsys.subsys.su_group);
> +	mutex_init(&most_sound_subsys.subsys.su_mutex);
> +
> +	INIT_LIST_HEAD(&most_sound_subsys.soundcard_list);
> +
> +	return 0;
> +}
> +
> +void __exit configfs_exit(void)
> +{
> +}

You shouldn't need empty functions...

regards,
dan carpenter
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 01/14] staging: most: add new file configfs.c
  2019-03-21 13:26 ` [PATCH 01/14] staging: most: add new file configfs.c Christian Gromm
  2019-03-22 10:44   ` Dan Carpenter
@ 2019-03-22 10:46   ` Dan Carpenter
  1 sibling, 0 replies; 20+ messages in thread
From: Dan Carpenter @ 2019-03-22 10:46 UTC (permalink / raw)
  To: Christian Gromm; +Cc: gregkh, driverdev-devel

On Thu, Mar 21, 2019 at 02:26:02PM +0100, Christian Gromm wrote:
> +static ssize_t mdev_link_direction_store(struct config_item *item,
> +					 const char *page, size_t count)
> +{
> +	struct mdev_link *mdev_link = to_mdev_link(item);
> +	char *buf = (char *)page;
> +
> +	if (strcmp(buf, "dir_rx\n") && strcmp(buf, "rx\n") &&
> +	    strcmp(buf, "dir_tx\n") && strcmp(buf, "tx\n"))

Please use sysfs_streq() here instead of strcmp().  It's ugly to
require that the input has a \n char.  Same for everything.

regards,
dan carpenter

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [RFC PATCH] staging: most: set_cfg_buffer_size() can be static
  2019-03-21 13:26 ` [PATCH 05/14] staging: most: enable configfs support Christian Gromm
@ 2019-03-22 11:59   ` kbuild test robot
  2019-03-22 11:59   ` [PATCH 05/14] staging: most: enable configfs support kbuild test robot
  2019-03-23 21:43   ` kbuild test robot
  2 siblings, 0 replies; 20+ messages in thread
From: kbuild test robot @ 2019-03-22 11:59 UTC (permalink / raw)
  To: Christian Gromm; +Cc: gregkh, driverdev-devel, kbuild-all


Fixes: 7c85575b16e9 ("staging: most: enable configfs support")
Signed-off-by: kbuild test robot <lkp@intel.com>
---
 configfs.c |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/most/configfs.c b/drivers/staging/most/configfs.c
index cefce69..36d40d7 100644
--- a/drivers/staging/most/configfs.c
+++ b/drivers/staging/most/configfs.c
@@ -31,7 +31,7 @@ struct mdev_link {
 	char param[MAX_LEN];
 };
 
-int set_cfg_buffer_size(struct mdev_link *link)
+static int set_cfg_buffer_size(struct mdev_link *link)
 {
 	if (!link->buffer_size)
 		return -ENODATA;
@@ -39,7 +39,7 @@ int set_cfg_buffer_size(struct mdev_link *link)
 					link->buffer_size);
 }
 
-int set_cfg_subbuffer_size(struct mdev_link *link)
+static int set_cfg_subbuffer_size(struct mdev_link *link)
 {
 	if (!link->subbuffer_size)
 		return -ENODATA;
@@ -47,7 +47,7 @@ int set_cfg_subbuffer_size(struct mdev_link *link)
 					   link->subbuffer_size);
 }
 
-int set_cfg_dbr_size(struct mdev_link *link)
+static int set_cfg_dbr_size(struct mdev_link *link)
 {
 	if (!link->dbr_size)
 		return -ENODATA;
@@ -55,7 +55,7 @@ int set_cfg_dbr_size(struct mdev_link *link)
 				     link->dbr_size);
 }
 
-int set_cfg_num_buffers(struct mdev_link *link)
+static int set_cfg_num_buffers(struct mdev_link *link)
 {
 	if (!link->num_buffers)
 		return -ENODATA;
@@ -63,7 +63,7 @@ int set_cfg_num_buffers(struct mdev_link *link)
 					link->num_buffers);
 }
 
-int set_cfg_packets_xact(struct mdev_link *link)
+static int set_cfg_packets_xact(struct mdev_link *link)
 {
 	if (!link->packets_per_xact)
 		return -ENODATA;
@@ -71,7 +71,7 @@ int set_cfg_packets_xact(struct mdev_link *link)
 					 link->packets_per_xact);
 }
 
-int set_cfg_direction(struct mdev_link *link)
+static int set_cfg_direction(struct mdev_link *link)
 {
 	if (!strlen(link->direction))
 		return -ENODATA;
@@ -79,7 +79,7 @@ int set_cfg_direction(struct mdev_link *link)
 				      link->direction);
 }
 
-int set_cfg_datatype(struct mdev_link *link)
+static int set_cfg_datatype(struct mdev_link *link)
 {
 	if (!strlen(link->datatype))
 		return -ENODATA;
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH 05/14] staging: most: enable configfs support
  2019-03-21 13:26 ` [PATCH 05/14] staging: most: enable configfs support Christian Gromm
  2019-03-22 11:59   ` [RFC PATCH] staging: most: set_cfg_buffer_size() can be static kbuild test robot
@ 2019-03-22 11:59   ` kbuild test robot
  2019-03-23 21:43   ` kbuild test robot
  2 siblings, 0 replies; 20+ messages in thread
From: kbuild test robot @ 2019-03-22 11:59 UTC (permalink / raw)
  To: Christian Gromm; +Cc: gregkh, driverdev-devel, kbuild-all

Hi Christian,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on staging/staging-testing]
[also build test WARNING on v5.1-rc1 next-20190321]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Christian-Gromm/staging-most-switch-to-configfs/20190322-075523
reproduce:
        # apt-get install sparse
        make ARCH=x86_64 allmodconfig
        make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'


sparse warnings: (new ones prefixed by >>)

>> drivers/staging/most/configfs.c:34:5: sparse: symbol 'set_cfg_buffer_size' was not declared. Should it be static?
>> drivers/staging/most/configfs.c:42:5: sparse: symbol 'set_cfg_subbuffer_size' was not declared. Should it be static?
>> drivers/staging/most/configfs.c:50:5: sparse: symbol 'set_cfg_dbr_size' was not declared. Should it be static?
>> drivers/staging/most/configfs.c:58:5: sparse: symbol 'set_cfg_num_buffers' was not declared. Should it be static?
>> drivers/staging/most/configfs.c:66:5: sparse: symbol 'set_cfg_packets_xact' was not declared. Should it be static?
>> drivers/staging/most/configfs.c:74:5: sparse: symbol 'set_cfg_direction' was not declared. Should it be static?
>> drivers/staging/most/configfs.c:82:5: sparse: symbol 'set_cfg_datatype' was not declared. Should it be static?

Please review and possibly fold the followup patch.

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 05/14] staging: most: enable configfs support
  2019-03-21 13:26 ` [PATCH 05/14] staging: most: enable configfs support Christian Gromm
  2019-03-22 11:59   ` [RFC PATCH] staging: most: set_cfg_buffer_size() can be static kbuild test robot
  2019-03-22 11:59   ` [PATCH 05/14] staging: most: enable configfs support kbuild test robot
@ 2019-03-23 21:43   ` kbuild test robot
  2 siblings, 0 replies; 20+ messages in thread
From: kbuild test robot @ 2019-03-23 21:43 UTC (permalink / raw)
  To: Christian Gromm; +Cc: gregkh, driverdev-devel, kbuild-all

[-- Attachment #1: Type: text/plain, Size: 20458 bytes --]

Hi Christian,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on staging/staging-testing]
[also build test ERROR on v5.1-rc1 next-20190322]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Christian-Gromm/staging-most-switch-to-configfs/20190322-075523
config: x86_64-randconfig-i1-03180048 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/staging/most/configfs.o: In function `most_snd_grp_make_item':
>> drivers/staging/most/configfs.c:484: undefined reference to `config_item_init_type_name'
   drivers/staging/most/configfs.o: In function `most_common_make_item':
   drivers/staging/most/configfs.c:404: undefined reference to `config_item_init_type_name'
   drivers/staging/most/configfs.o: In function `most_sound_make_group':
>> drivers/staging/most/configfs.c:576: undefined reference to `config_group_init_type_name'
   drivers/staging/most/configfs.o: In function `most_register_configfs_subsys':
>> drivers/staging/most/configfs.c:606: undefined reference to `configfs_register_subsystem'
   drivers/staging/most/configfs.c:608: undefined reference to `configfs_register_subsystem'
   drivers/staging/most/configfs.c:610: undefined reference to `configfs_register_subsystem'
   drivers/staging/most/configfs.c:612: undefined reference to `configfs_register_subsystem'
   drivers/staging/most/configfs.o: In function `most_deregister_configfs_subsys':
>> drivers/staging/most/configfs.c:628: undefined reference to `configfs_unregister_subsystem'
   drivers/staging/most/configfs.c:630: undefined reference to `configfs_unregister_subsystem'
   drivers/staging/most/configfs.c:632: undefined reference to `configfs_unregister_subsystem'
   drivers/staging/most/configfs.c:634: undefined reference to `configfs_unregister_subsystem'
   drivers/staging/most/configfs.o: In function `configfs_init':
>> drivers/staging/most/configfs.c:640: undefined reference to `config_group_init'
   drivers/staging/most/configfs.c:643: undefined reference to `config_group_init'
   drivers/staging/most/configfs.c:646: undefined reference to `config_group_init'
   drivers/staging/most/configfs.c:649: undefined reference to `config_group_init'

vim +484 drivers/staging/most/configfs.c

590f3182 Christian Gromm 2019-03-21  394  
590f3182 Christian Gromm 2019-03-21  395  static struct config_item *most_common_make_item(struct config_group *group,
590f3182 Christian Gromm 2019-03-21  396  						 const char *name)
590f3182 Christian Gromm 2019-03-21  397  {
590f3182 Christian Gromm 2019-03-21  398  	struct mdev_link *mdev_link;
590f3182 Christian Gromm 2019-03-21  399  
590f3182 Christian Gromm 2019-03-21  400  	mdev_link = kzalloc(sizeof(*mdev_link), GFP_KERNEL);
590f3182 Christian Gromm 2019-03-21  401  	if (!mdev_link)
590f3182 Christian Gromm 2019-03-21  402  		return ERR_PTR(-ENOMEM);
590f3182 Christian Gromm 2019-03-21  403  
590f3182 Christian Gromm 2019-03-21 @404  	config_item_init_type_name(&mdev_link->item, name,
590f3182 Christian Gromm 2019-03-21  405  				   &mdev_link_type);
590f3182 Christian Gromm 2019-03-21  406  
590f3182 Christian Gromm 2019-03-21  407  	if (!strcmp(group->cg_item.ci_namebuf, "most_cdev"))
590f3182 Christian Gromm 2019-03-21  408  		strcpy(mdev_link->comp, "cdev");
590f3182 Christian Gromm 2019-03-21  409  	else if (!strcmp(group->cg_item.ci_namebuf, "most_net"))
590f3182 Christian Gromm 2019-03-21  410  		strcpy(mdev_link->comp, "net");
590f3182 Christian Gromm 2019-03-21  411  	else if (!strcmp(group->cg_item.ci_namebuf, "most_video"))
590f3182 Christian Gromm 2019-03-21  412  		strcpy(mdev_link->comp, "video");
590f3182 Christian Gromm 2019-03-21  413  	strcpy(mdev_link->name, name);
590f3182 Christian Gromm 2019-03-21  414  	return &mdev_link->item;
590f3182 Christian Gromm 2019-03-21  415  }
590f3182 Christian Gromm 2019-03-21  416  
590f3182 Christian Gromm 2019-03-21  417  static void most_common_release(struct config_item *item)
590f3182 Christian Gromm 2019-03-21  418  {
590f3182 Christian Gromm 2019-03-21  419  	kfree(to_most_common(item));
590f3182 Christian Gromm 2019-03-21  420  }
590f3182 Christian Gromm 2019-03-21  421  
590f3182 Christian Gromm 2019-03-21  422  static struct configfs_item_operations most_common_item_ops = {
590f3182 Christian Gromm 2019-03-21  423  	.release	= most_common_release,
590f3182 Christian Gromm 2019-03-21  424  };
590f3182 Christian Gromm 2019-03-21  425  
590f3182 Christian Gromm 2019-03-21  426  static struct configfs_group_operations most_common_group_ops = {
590f3182 Christian Gromm 2019-03-21  427  	.make_item	= most_common_make_item,
590f3182 Christian Gromm 2019-03-21  428  };
590f3182 Christian Gromm 2019-03-21  429  
590f3182 Christian Gromm 2019-03-21  430  static const struct config_item_type most_common_type = {
590f3182 Christian Gromm 2019-03-21  431  	.ct_item_ops	= &most_common_item_ops,
590f3182 Christian Gromm 2019-03-21  432  	.ct_group_ops	= &most_common_group_ops,
590f3182 Christian Gromm 2019-03-21  433  	.ct_owner	= THIS_MODULE,
590f3182 Christian Gromm 2019-03-21  434  };
590f3182 Christian Gromm 2019-03-21  435  
590f3182 Christian Gromm 2019-03-21  436  static struct configfs_subsystem most_cdev_subsys = {
590f3182 Christian Gromm 2019-03-21  437  	.su_group = {
590f3182 Christian Gromm 2019-03-21  438  		.cg_item = {
590f3182 Christian Gromm 2019-03-21  439  			.ci_namebuf = "most_cdev",
590f3182 Christian Gromm 2019-03-21  440  			.ci_type = &most_common_type,
590f3182 Christian Gromm 2019-03-21  441  		},
590f3182 Christian Gromm 2019-03-21  442  	},
590f3182 Christian Gromm 2019-03-21  443  };
590f3182 Christian Gromm 2019-03-21  444  
590f3182 Christian Gromm 2019-03-21  445  static struct configfs_subsystem most_net_subsys = {
590f3182 Christian Gromm 2019-03-21  446  	.su_group = {
590f3182 Christian Gromm 2019-03-21  447  		.cg_item = {
590f3182 Christian Gromm 2019-03-21  448  			.ci_namebuf = "most_net",
590f3182 Christian Gromm 2019-03-21  449  			.ci_type = &most_common_type,
590f3182 Christian Gromm 2019-03-21  450  		},
590f3182 Christian Gromm 2019-03-21  451  	},
590f3182 Christian Gromm 2019-03-21  452  };
590f3182 Christian Gromm 2019-03-21  453  
590f3182 Christian Gromm 2019-03-21  454  static struct configfs_subsystem most_video_subsys = {
590f3182 Christian Gromm 2019-03-21  455  	.su_group = {
590f3182 Christian Gromm 2019-03-21  456  		.cg_item = {
590f3182 Christian Gromm 2019-03-21  457  			.ci_namebuf = "most_video",
590f3182 Christian Gromm 2019-03-21  458  			.ci_type = &most_common_type,
590f3182 Christian Gromm 2019-03-21  459  		},
590f3182 Christian Gromm 2019-03-21  460  	},
590f3182 Christian Gromm 2019-03-21  461  };
590f3182 Christian Gromm 2019-03-21  462  
590f3182 Christian Gromm 2019-03-21  463  struct most_snd_grp {
590f3182 Christian Gromm 2019-03-21  464  	struct config_group group;
590f3182 Christian Gromm 2019-03-21  465  	int create;
590f3182 Christian Gromm 2019-03-21  466  	struct list_head list;
590f3182 Christian Gromm 2019-03-21  467  };
590f3182 Christian Gromm 2019-03-21  468  
590f3182 Christian Gromm 2019-03-21  469  static inline struct most_snd_grp *to_most_snd_grp(struct config_item *item)
590f3182 Christian Gromm 2019-03-21  470  {
590f3182 Christian Gromm 2019-03-21  471  	return item ? container_of(to_config_group(item),
590f3182 Christian Gromm 2019-03-21  472  				   struct most_snd_grp, group) : NULL;
590f3182 Christian Gromm 2019-03-21  473  }
590f3182 Christian Gromm 2019-03-21  474  
590f3182 Christian Gromm 2019-03-21  475  static struct config_item *most_snd_grp_make_item(struct config_group *group,
590f3182 Christian Gromm 2019-03-21  476  						  const char *name)
590f3182 Christian Gromm 2019-03-21  477  {
590f3182 Christian Gromm 2019-03-21  478  	struct mdev_link *mdev_link;
590f3182 Christian Gromm 2019-03-21  479  
590f3182 Christian Gromm 2019-03-21  480  	mdev_link = kzalloc(sizeof(*mdev_link), GFP_KERNEL);
590f3182 Christian Gromm 2019-03-21  481  	if (!mdev_link)
590f3182 Christian Gromm 2019-03-21  482  		return ERR_PTR(-ENOMEM);
590f3182 Christian Gromm 2019-03-21  483  
590f3182 Christian Gromm 2019-03-21 @484  	config_item_init_type_name(&mdev_link->item, name, &mdev_link_type);
590f3182 Christian Gromm 2019-03-21  485  	mdev_link->create = 0;
590f3182 Christian Gromm 2019-03-21  486  	strcpy(mdev_link->name, name);
590f3182 Christian Gromm 2019-03-21  487  	strcpy(mdev_link->comp, "sound");
590f3182 Christian Gromm 2019-03-21  488  	return &mdev_link->item;
590f3182 Christian Gromm 2019-03-21  489  }
590f3182 Christian Gromm 2019-03-21  490  
590f3182 Christian Gromm 2019-03-21  491  static ssize_t most_snd_grp_create_show(struct config_item *item, char *page)
590f3182 Christian Gromm 2019-03-21  492  {
590f3182 Christian Gromm 2019-03-21  493  	return sprintf(page, "%d\n", to_most_snd_grp(item)->create);
590f3182 Christian Gromm 2019-03-21  494  }
590f3182 Christian Gromm 2019-03-21  495  
590f3182 Christian Gromm 2019-03-21  496  static ssize_t most_snd_grp_create_store(struct config_item *item,
590f3182 Christian Gromm 2019-03-21  497  					 const char *page, size_t count)
590f3182 Christian Gromm 2019-03-21  498  {
590f3182 Christian Gromm 2019-03-21  499  	struct most_snd_grp *snd_grp = to_most_snd_grp(item);
590f3182 Christian Gromm 2019-03-21  500  	int ret = 0;
590f3182 Christian Gromm 2019-03-21  501  	u16 tmp;
590f3182 Christian Gromm 2019-03-21  502  	char *p = (char *)page;
590f3182 Christian Gromm 2019-03-21  503  
590f3182 Christian Gromm 2019-03-21  504  	ret = kstrtou16(p, 0, &tmp);
590f3182 Christian Gromm 2019-03-21  505  	if (ret)
590f3182 Christian Gromm 2019-03-21  506  		return ret;
590f3182 Christian Gromm 2019-03-21  507  	if (tmp > 1)
590f3182 Christian Gromm 2019-03-21  508  		return -ERANGE;
590f3182 Christian Gromm 2019-03-21  509  	if (tmp) {
590f3182 Christian Gromm 2019-03-21  510  		ret = most_cfg_complete("sound");
590f3182 Christian Gromm 2019-03-21  511  		if (ret)
590f3182 Christian Gromm 2019-03-21  512  			return ret;
590f3182 Christian Gromm 2019-03-21  513  	}
590f3182 Christian Gromm 2019-03-21  514  	snd_grp->create = tmp;
590f3182 Christian Gromm 2019-03-21  515  	return count;
590f3182 Christian Gromm 2019-03-21  516  }
590f3182 Christian Gromm 2019-03-21  517  
590f3182 Christian Gromm 2019-03-21  518  CONFIGFS_ATTR(most_snd_grp_, create);
590f3182 Christian Gromm 2019-03-21  519  
590f3182 Christian Gromm 2019-03-21  520  static struct configfs_attribute *most_snd_grp_attrs[] = {
590f3182 Christian Gromm 2019-03-21  521  	&most_snd_grp_attr_create,
590f3182 Christian Gromm 2019-03-21  522  	NULL,
590f3182 Christian Gromm 2019-03-21  523  };
590f3182 Christian Gromm 2019-03-21  524  
590f3182 Christian Gromm 2019-03-21  525  static void most_snd_grp_release(struct config_item *item)
590f3182 Christian Gromm 2019-03-21  526  {
590f3182 Christian Gromm 2019-03-21  527  	struct most_snd_grp *group = to_most_snd_grp(item);
590f3182 Christian Gromm 2019-03-21  528  
590f3182 Christian Gromm 2019-03-21  529  	list_del(&group->list);
590f3182 Christian Gromm 2019-03-21  530  	kfree(group);
590f3182 Christian Gromm 2019-03-21  531  }
590f3182 Christian Gromm 2019-03-21  532  
590f3182 Christian Gromm 2019-03-21  533  static struct configfs_item_operations most_snd_grp_item_ops = {
590f3182 Christian Gromm 2019-03-21  534  	.release	= most_snd_grp_release,
590f3182 Christian Gromm 2019-03-21  535  };
590f3182 Christian Gromm 2019-03-21  536  
590f3182 Christian Gromm 2019-03-21  537  static struct configfs_group_operations most_snd_grp_group_ops = {
590f3182 Christian Gromm 2019-03-21  538  	.make_item	= most_snd_grp_make_item,
590f3182 Christian Gromm 2019-03-21  539  };
590f3182 Christian Gromm 2019-03-21  540  
590f3182 Christian Gromm 2019-03-21  541  static const struct config_item_type most_snd_grp_type = {
590f3182 Christian Gromm 2019-03-21  542  	.ct_item_ops	= &most_snd_grp_item_ops,
590f3182 Christian Gromm 2019-03-21  543  	.ct_group_ops	= &most_snd_grp_group_ops,
590f3182 Christian Gromm 2019-03-21  544  	.ct_attrs	= most_snd_grp_attrs,
590f3182 Christian Gromm 2019-03-21  545  	.ct_owner	= THIS_MODULE,
590f3182 Christian Gromm 2019-03-21  546  };
590f3182 Christian Gromm 2019-03-21  547  
590f3182 Christian Gromm 2019-03-21  548  struct most_sound {
590f3182 Christian Gromm 2019-03-21  549  	struct configfs_subsystem subsys;
590f3182 Christian Gromm 2019-03-21  550  	struct list_head soundcard_list;
590f3182 Christian Gromm 2019-03-21  551  };
590f3182 Christian Gromm 2019-03-21  552  
590f3182 Christian Gromm 2019-03-21  553  static inline struct most_sound *to_most_sound(struct config_item *item)
590f3182 Christian Gromm 2019-03-21  554  {
590f3182 Christian Gromm 2019-03-21  555  	return item ? container_of(to_configfs_subsystem(to_config_group(item)),
590f3182 Christian Gromm 2019-03-21  556  				   struct most_sound, subsys) : NULL;
590f3182 Christian Gromm 2019-03-21  557  }
590f3182 Christian Gromm 2019-03-21  558  
590f3182 Christian Gromm 2019-03-21  559  static struct config_group *most_sound_make_group(struct config_group *group,
590f3182 Christian Gromm 2019-03-21  560  						  const char *name)
590f3182 Christian Gromm 2019-03-21  561  {
590f3182 Christian Gromm 2019-03-21  562  	struct most_snd_grp *most;
590f3182 Christian Gromm 2019-03-21  563  	struct most_sound *ms = container_of(to_configfs_subsystem(group),
590f3182 Christian Gromm 2019-03-21  564  					     struct most_sound, subsys);
590f3182 Christian Gromm 2019-03-21  565  
590f3182 Christian Gromm 2019-03-21  566  	list_for_each_entry(most, &ms->soundcard_list, list) {
590f3182 Christian Gromm 2019-03-21  567  		if (!most->create) {
590f3182 Christian Gromm 2019-03-21  568  			pr_info("adapter configuration still in progress.\n");
590f3182 Christian Gromm 2019-03-21  569  			return ERR_PTR(-EPROTO);
590f3182 Christian Gromm 2019-03-21  570  		}
590f3182 Christian Gromm 2019-03-21  571  	}
590f3182 Christian Gromm 2019-03-21  572  	most = kzalloc(sizeof(*most), GFP_KERNEL);
590f3182 Christian Gromm 2019-03-21  573  	if (!most)
590f3182 Christian Gromm 2019-03-21  574  		return ERR_PTR(-ENOMEM);
590f3182 Christian Gromm 2019-03-21  575  
590f3182 Christian Gromm 2019-03-21 @576  	config_group_init_type_name(&most->group, name, &most_snd_grp_type);
590f3182 Christian Gromm 2019-03-21  577  	list_add_tail(&most->list, &ms->soundcard_list);
590f3182 Christian Gromm 2019-03-21  578  	return &most->group;
590f3182 Christian Gromm 2019-03-21  579  }
590f3182 Christian Gromm 2019-03-21  580  
590f3182 Christian Gromm 2019-03-21  581  static struct configfs_group_operations most_sound_group_ops = {
590f3182 Christian Gromm 2019-03-21  582  	.make_group	= most_sound_make_group,
590f3182 Christian Gromm 2019-03-21  583  };
590f3182 Christian Gromm 2019-03-21  584  
590f3182 Christian Gromm 2019-03-21  585  static const struct config_item_type most_sound_type = {
590f3182 Christian Gromm 2019-03-21  586  	.ct_group_ops	= &most_sound_group_ops,
590f3182 Christian Gromm 2019-03-21  587  	.ct_owner	= THIS_MODULE,
590f3182 Christian Gromm 2019-03-21  588  };
590f3182 Christian Gromm 2019-03-21  589  
590f3182 Christian Gromm 2019-03-21  590  static struct most_sound most_sound_subsys = {
590f3182 Christian Gromm 2019-03-21  591  	.subsys = {
590f3182 Christian Gromm 2019-03-21  592  		.su_group = {
590f3182 Christian Gromm 2019-03-21  593  			.cg_item = {
590f3182 Christian Gromm 2019-03-21  594  				.ci_namebuf = "most_sound",
590f3182 Christian Gromm 2019-03-21  595  				.ci_type = &most_sound_type,
590f3182 Christian Gromm 2019-03-21  596  			},
590f3182 Christian Gromm 2019-03-21  597  		},
590f3182 Christian Gromm 2019-03-21  598  	},
590f3182 Christian Gromm 2019-03-21  599  };
590f3182 Christian Gromm 2019-03-21  600  
590f3182 Christian Gromm 2019-03-21  601  int most_register_configfs_subsys(struct core_component *c)
590f3182 Christian Gromm 2019-03-21  602  {
590f3182 Christian Gromm 2019-03-21  603  	int ret;
590f3182 Christian Gromm 2019-03-21  604  
590f3182 Christian Gromm 2019-03-21  605  	if (!strcmp(c->name, "cdev"))
590f3182 Christian Gromm 2019-03-21 @606  		ret = configfs_register_subsystem(&most_cdev_subsys);
590f3182 Christian Gromm 2019-03-21  607  	else if (!strcmp(c->name, "net"))
590f3182 Christian Gromm 2019-03-21 @608  		ret = configfs_register_subsystem(&most_net_subsys);
590f3182 Christian Gromm 2019-03-21  609  	else if (!strcmp(c->name, "video"))
590f3182 Christian Gromm 2019-03-21  610  		ret = configfs_register_subsystem(&most_video_subsys);
590f3182 Christian Gromm 2019-03-21  611  	else if (!strcmp(c->name, "sound"))
590f3182 Christian Gromm 2019-03-21  612  		ret = configfs_register_subsystem(&most_sound_subsys.subsys);
590f3182 Christian Gromm 2019-03-21  613  	else
590f3182 Christian Gromm 2019-03-21  614  		return -ENODEV;
590f3182 Christian Gromm 2019-03-21  615  
590f3182 Christian Gromm 2019-03-21  616  	if (ret) {
590f3182 Christian Gromm 2019-03-21  617  		pr_err("Error %d while registering subsystem %s\n",
590f3182 Christian Gromm 2019-03-21  618  		       ret,
590f3182 Christian Gromm 2019-03-21  619  		       most_sound_subsys.subsys.su_group.cg_item.ci_namebuf);
590f3182 Christian Gromm 2019-03-21  620  	}
590f3182 Christian Gromm 2019-03-21  621  	return ret;
590f3182 Christian Gromm 2019-03-21  622  }
590f3182 Christian Gromm 2019-03-21  623  EXPORT_SYMBOL_GPL(most_register_configfs_subsys);
590f3182 Christian Gromm 2019-03-21  624  
590f3182 Christian Gromm 2019-03-21  625  void most_deregister_configfs_subsys(struct core_component *c)
590f3182 Christian Gromm 2019-03-21  626  {
590f3182 Christian Gromm 2019-03-21  627  	if (!strcmp(c->name, "cdev"))
590f3182 Christian Gromm 2019-03-21 @628  		configfs_unregister_subsystem(&most_cdev_subsys);
590f3182 Christian Gromm 2019-03-21  629  	else if (!strcmp(c->name, "net"))
590f3182 Christian Gromm 2019-03-21  630  		configfs_unregister_subsystem(&most_net_subsys);
590f3182 Christian Gromm 2019-03-21  631  	else if (!strcmp(c->name, "video"))
590f3182 Christian Gromm 2019-03-21  632  		configfs_unregister_subsystem(&most_video_subsys);
590f3182 Christian Gromm 2019-03-21  633  	else if (!strcmp(c->name, "sound"))
590f3182 Christian Gromm 2019-03-21  634  		configfs_unregister_subsystem(&most_sound_subsys.subsys);
590f3182 Christian Gromm 2019-03-21  635  }
590f3182 Christian Gromm 2019-03-21  636  EXPORT_SYMBOL_GPL(most_deregister_configfs_subsys);
590f3182 Christian Gromm 2019-03-21  637  
590f3182 Christian Gromm 2019-03-21  638  int __init configfs_init(void)
590f3182 Christian Gromm 2019-03-21  639  {
590f3182 Christian Gromm 2019-03-21 @640  	config_group_init(&most_cdev_subsys.su_group);
590f3182 Christian Gromm 2019-03-21  641  	mutex_init(&most_cdev_subsys.su_mutex);
590f3182 Christian Gromm 2019-03-21  642  
590f3182 Christian Gromm 2019-03-21  643  	config_group_init(&most_net_subsys.su_group);
590f3182 Christian Gromm 2019-03-21  644  	mutex_init(&most_net_subsys.su_mutex);
590f3182 Christian Gromm 2019-03-21  645  
590f3182 Christian Gromm 2019-03-21  646  	config_group_init(&most_video_subsys.su_group);
590f3182 Christian Gromm 2019-03-21  647  	mutex_init(&most_video_subsys.su_mutex);
590f3182 Christian Gromm 2019-03-21  648  
590f3182 Christian Gromm 2019-03-21  649  	config_group_init(&most_sound_subsys.subsys.su_group);
590f3182 Christian Gromm 2019-03-21  650  	mutex_init(&most_sound_subsys.subsys.su_mutex);
590f3182 Christian Gromm 2019-03-21  651  
590f3182 Christian Gromm 2019-03-21  652  	INIT_LIST_HEAD(&most_sound_subsys.soundcard_list);
590f3182 Christian Gromm 2019-03-21  653  
590f3182 Christian Gromm 2019-03-21  654  	return 0;
590f3182 Christian Gromm 2019-03-21  655  }
590f3182 Christian Gromm 2019-03-21  656  

:::::: The code at line 484 was first introduced by commit
:::::: 590f31828d2a264c02bc4eeebb6722c906aa0444 staging: most: add new file configfs.c

:::::: TO: Christian Gromm <christian.gromm@microchip.com>
:::::: CC: 0day robot <lkp@intel.com>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 23929 bytes --]

[-- Attachment #3: Type: text/plain, Size: 169 bytes --]

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2019-03-23 21:44 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-21 13:26 [PATCH 00/14] staging: most: switch to configfs Christian Gromm
2019-03-21 13:26 ` [PATCH 01/14] staging: most: add new file configfs.c Christian Gromm
2019-03-22 10:44   ` Dan Carpenter
2019-03-22 10:46   ` Dan Carpenter
2019-03-21 13:26 ` [PATCH 02/14] staging: most: change signature of function probe_channel Christian Gromm
2019-03-21 13:26 ` [PATCH 03/14] staging: most: core: add configfs interface functions Christian Gromm
2019-03-21 13:26 ` [PATCH 04/14] staging: most: sound: introduce new sound adapter management Christian Gromm
2019-03-21 13:26 ` [PATCH 05/14] staging: most: enable configfs support Christian Gromm
2019-03-22 11:59   ` [RFC PATCH] staging: most: set_cfg_buffer_size() can be static kbuild test robot
2019-03-22 11:59   ` [PATCH 05/14] staging: most: enable configfs support kbuild test robot
2019-03-23 21:43   ` kbuild test robot
2019-03-21 13:26 ` [PATCH 06/14] staging: most: core: make sysfs attributes read-only Christian Gromm
2019-03-21 13:26 ` [PATCH 07/14] staging: most: core: use device description as name Christian Gromm
2019-03-21 13:26 ` [PATCH 08/14] staging: most: usb: remove prefix from description tag Christian Gromm
2019-03-21 13:26 ` [PATCH 09/14] staging: most: core: remove attribute add_link Christian Gromm
2019-03-21 13:26 ` [PATCH 10/14] staging: most: allow speculative configuration Christian Gromm
2019-03-21 13:26 ` [PATCH 11/14] staging: most: configfs: make create attributes write-only Christian Gromm
2019-03-21 13:26 ` [PATCH 12/14] staging: most: configfs: add code for link removal Christian Gromm
2019-03-21 13:26 ` [PATCH 13/14] staging: most: configfs: rename config attributes Christian Gromm
2019-03-21 13:26 ` [PATCH 14/14] staging: most: Documentation: update driver documentation Christian Gromm

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.