All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christian Gromm <christian.gromm@microchip.com>
To: gregkh@linuxfoundation.org
Cc: driverdev-devel@linuxdriverproject.org,
	Christian Gromm <christian.gromm@microchip.com>
Subject: [PATCH 22/50] staging: most: core: replace struct most_inst_obj
Date: Tue, 21 Nov 2017 15:04:56 +0100	[thread overview]
Message-ID: <1511273124-7840-23-git-send-email-christian.gromm@microchip.com> (raw)
In-Reply-To: <1511273124-7840-1-git-send-email-christian.gromm@microchip.com>

This patch introduces struct interface_private as a replacement for
the struct most_inst_obj. This structure holds private data that is
only needed by the core module and will be accessed by a pointer from
within the most_interface structure. As a result of this replacement
the bus helper functions can be used to search for devices.

Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
---
 drivers/staging/most/core.c | 200 +++++++++++++++++++++-----------------------
 drivers/staging/most/core.h |   2 +
 2 files changed, 99 insertions(+), 103 deletions(-)

diff --git a/drivers/staging/most/core.c b/drivers/staging/most/core.c
index 4caea38..87178a8 100644
--- a/drivers/staging/most/core.c
+++ b/drivers/staging/most/core.c
@@ -62,7 +62,6 @@ struct most_channel {
 	struct mutex nq_mutex; /* nq thread synchronization */
 	int is_starving;
 	struct most_interface *iface;
-	struct most_inst_obj *inst;
 	struct most_channel_config cfg;
 	bool keep_mbo;
 	bool enqueue_halt;
@@ -79,12 +78,11 @@ struct most_channel {
 
 #define to_channel(d) container_of(d, struct most_channel, dev)
 
-struct most_inst_obj {
+struct interface_private {
 	int dev_id;
-	struct most_interface *iface;
-	struct list_head channel_list;
+	char name[STRING_SIZE];
 	struct most_channel *channel[MAX_CHANNELS];
-	struct list_head list;
+	struct list_head channel_list;
 };
 
 static const struct {
@@ -478,9 +476,6 @@ static const struct attribute_group *channel_attr_groups[] = {
 /*		     ___	       ___
  *		     ___I N S T A N C E___
  */
-
-static struct list_head instance_list;
-
 static ssize_t description_show(struct device *dev,
 				struct device_attribute *attr,
 				char *buf)
@@ -551,33 +546,38 @@ static struct most_aim *match_module(char *name)
 	return NULL;
 }
 
-static ssize_t links_show(struct device_driver *drv, char *buf)
+int print_links(struct device *dev, void *data)
 {
-	struct most_channel *c;
-	struct most_inst_obj *i;
 	int offs = 0;
+	char *buf = data;
+	struct most_channel *c;
+	struct most_interface *iface = to_most_interface(dev);
 
-	list_for_each_entry(i, &instance_list, list) {
-		list_for_each_entry(c, &i->channel_list, list) {
-			if (c->pipe0.aim) {
-				offs += snprintf(buf + offs,
-						 PAGE_SIZE - offs,
-						 "%s:%s:%s\n",
-						 c->pipe0.aim->name,
-						 dev_name(&i->iface->dev),
-						 dev_name(&c->dev));
-			}
-			if (c->pipe1.aim) {
-				offs += snprintf(buf + offs,
-						 PAGE_SIZE - offs,
-						 "%s:%s:%s\n",
-						 c->pipe1.aim->name,
-						 dev_name(&i->iface->dev),
-						 dev_name(&c->dev));
-			}
+	list_for_each_entry(c, &iface->p->channel_list, list) {
+		if (c->pipe0.aim) {
+			offs += snprintf(buf + offs,
+					 PAGE_SIZE - offs,
+					 "%s:%s:%s\n",
+					 c->pipe0.aim->name,
+					 dev_name(&iface->dev),
+					 dev_name(&c->dev));
+		}
+		if (c->pipe1.aim) {
+			offs += snprintf(buf + offs,
+					 PAGE_SIZE - offs,
+					 "%s:%s:%s\n",
+					 c->pipe1.aim->name,
+					 dev_name(&iface->dev),
+					 dev_name(&c->dev));
 		}
 	}
-	return offs;
+	return 0;
+}
+
+static ssize_t links_show(struct device_driver *drv, char *buf)
+{
+	bus_for_each_dev(&mc.bus, NULL, buf, print_links);
+	return strlen(buf);
 }
 
 static ssize_t modules_show(struct device_driver *drv, char *buf)
@@ -633,6 +633,13 @@ static int split_string(char *buf, char **a, char **b, char **c, char **d)
 	return 0;
 }
 
+static int match_bus_dev(struct device *dev, void *data)
+{
+	char *mdev_name = data;
+
+	return !strcmp(dev_name(dev), mdev_name);
+}
+
 /**
  * get_channel - get pointer to channel object
  * @mdev: name of the device instance
@@ -642,28 +649,19 @@ static int split_string(char *buf, char **a, char **b, char **c, char **d)
  */
 static struct most_channel *get_channel(char *mdev, char *mdev_ch)
 {
+	struct device *dev = NULL;
+	struct most_interface *iface;
 	struct most_channel *c, *tmp;
-	struct most_inst_obj *i, *i_tmp;
-	int found = 0;
 
-	list_for_each_entry_safe(i, i_tmp, &instance_list, list) {
-		if (!strcmp(dev_name(&i->iface->dev), mdev)) {
-			found++;
-			break;
-		}
-	}
-	if (unlikely(!found))
-		return ERR_PTR(-EIO);
-
-	list_for_each_entry_safe(c, tmp, &i->channel_list, list) {
-		if (!strcmp(dev_name(&c->dev), mdev_ch)) {
-			found++;
-			break;
-		}
+	dev = bus_find_device(&mc.bus, NULL, mdev, match_bus_dev);
+	if (!dev)
+		return NULL;
+	iface = to_most_interface(dev);
+	list_for_each_entry_safe(c, tmp, &iface->p->channel_list, list) {
+		if (!strcmp(dev_name(&c->dev), mdev_ch))
+			return c;
 	}
-	if (unlikely(found < 2))
-		return ERR_PTR(-EIO);
-	return c;
+	return NULL;
 }
 
 static
@@ -741,7 +739,7 @@ static ssize_t add_link_store(struct device_driver *drv,
 	}
 
 	c = get_channel(mdev, mdev_ch);
-	if (IS_ERR(c))
+	if (!c)
 		return -ENODEV;
 
 	ret = link_channel_to_aim(c, aim, aim_param);
@@ -780,7 +778,7 @@ static ssize_t remove_link_store(struct device_driver *drv,
 		return ret;
 	aim = match_module(aim_name);
 	c = get_channel(mdev, mdev_ch);
-	if (IS_ERR(c))
+	if (!c)
 		return -ENODEV;
 
 	if (aim->disconnect_channel(c->iface, c->channel_id))
@@ -1048,8 +1046,7 @@ static void most_write_completion(struct mbo *mbo)
 
 int channel_has_mbo(struct most_interface *iface, int id, struct most_aim *aim)
 {
-	struct most_inst_obj *inst = iface->priv;
-	struct most_channel *c = inst->channel[id];
+	struct most_channel *c = iface->p->channel[id];
 	unsigned long flags;
 	int empty;
 
@@ -1081,11 +1078,10 @@ struct mbo *most_get_mbo(struct most_interface *iface, int id,
 {
 	struct mbo *mbo;
 	struct most_channel *c;
-	struct most_inst_obj *inst = iface->priv;
 	unsigned long flags;
 	int *num_buffers_ptr;
 
-	c = inst->channel[id];
+	c = iface->p->channel[id];
 	if (unlikely(!c))
 		return NULL;
 
@@ -1187,8 +1183,7 @@ int most_start_channel(struct most_interface *iface, int id,
 {
 	int num_buffer;
 	int ret;
-	struct most_inst_obj *inst = iface->priv;
-	struct most_channel *c = inst->channel[id];
+	struct most_channel *c = iface->p->channel[id];
 
 	if (unlikely(!c))
 		return -EINVAL;
@@ -1256,15 +1251,13 @@ EXPORT_SYMBOL_GPL(most_start_channel);
 int most_stop_channel(struct most_interface *iface, int id,
 		      struct most_aim *aim)
 {
-	struct most_inst_obj *inst;
 	struct most_channel *c;
 
 	if (unlikely((!iface) || (id >= iface->num_channels) || (id < 0))) {
 		pr_err("Bad interface or index out of range\n");
 		return -EINVAL;
 	}
-	inst = iface->priv;
-	c = inst->channel[id];
+	c = iface->p->channel[id];
 	if (unlikely(!c))
 		return -EINVAL;
 
@@ -1326,33 +1319,38 @@ int most_register_aim(struct most_aim *aim)
 }
 EXPORT_SYMBOL_GPL(most_register_aim);
 
+static int disconnect_channels(struct device *dev, void *data)
+{
+	struct most_interface *iface;
+	struct most_channel *c, *tmp;
+	struct most_aim *aim = data;
+
+	iface = to_most_interface(dev);
+	list_for_each_entry_safe(c, tmp, &iface->p->channel_list, list) {
+		if (c->pipe0.aim == aim || c->pipe1.aim == aim)
+			aim->disconnect_channel(c->iface, c->channel_id);
+		if (c->pipe0.aim == aim)
+			c->pipe0.aim = NULL;
+		if (c->pipe1.aim == aim)
+			c->pipe1.aim = NULL;
+	}
+	return 0;
+}
+
 /**
  * most_deregister_aim - deregisters an AIM (driver) with the core
  * @aim: AIM to be removed
  */
 int most_deregister_aim(struct most_aim *aim)
 {
-	struct most_channel *c, *tmp;
-	struct most_inst_obj *i, *i_tmp;
-
 	if (!aim) {
 		pr_err("Bad driver\n");
 		return -EINVAL;
 	}
 
-	list_for_each_entry_safe(i, i_tmp, &instance_list, list) {
-		list_for_each_entry_safe(c, tmp, &i->channel_list, list) {
-			if (c->pipe0.aim == aim || c->pipe1.aim == aim)
-				aim->disconnect_channel(
-					c->iface, c->channel_id);
-			if (c->pipe0.aim == aim)
-				c->pipe0.aim = NULL;
-			if (c->pipe1.aim == aim)
-				c->pipe1.aim = NULL;
-		}
-	}
+	bus_for_each_dev(&mc.bus, NULL, aim, disconnect_channels);
 	list_del(&aim->list);
-	pr_info("deregistering application interfacing module %s\n", aim->name);
+	pr_info("deregistering module %s\n", aim->name);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(most_deregister_aim);
@@ -1378,10 +1376,8 @@ int most_register_interface(struct most_interface *iface)
 {
 	unsigned int i;
 	int id;
-	char name[STRING_SIZE];
 	char channel_name[STRING_SIZE];
 	struct most_channel *c;
-	struct most_inst_obj *inst;
 
 	if (!iface || !iface->enqueue || !iface->configure ||
 	    !iface->poison_channel || (iface->num_channels > MAX_CHANNELS)) {
@@ -1395,27 +1391,24 @@ int most_register_interface(struct most_interface *iface)
 		return id;
 	}
 
-	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
-	if (!inst) {
+	iface->p = kzalloc(sizeof(*iface->p), GFP_KERNEL);
+	if (!iface->p) {
 		pr_info("Failed to allocate interface instance\n");
 		ida_simple_remove(&mdev_id, id);
 		return -ENOMEM;
 	}
 
-	iface->priv = inst;
-	INIT_LIST_HEAD(&inst->channel_list);
-	inst->iface = iface;
-	inst->dev_id = id;
-	list_add_tail(&inst->list, &instance_list);
-	snprintf(name, STRING_SIZE, "mdev%d", id);
-	iface->dev.init_name = name;
+	INIT_LIST_HEAD(&iface->p->channel_list);
+	iface->p->dev_id = id;
+	snprintf(iface->p->name, STRING_SIZE, "mdev%d", id);
+	iface->dev.init_name = iface->p->name;
 	iface->dev.bus = &mc.bus;
 	iface->dev.parent = &mc.dev;
 	iface->dev.groups = interface_attr_groups;
 	iface->dev.release = release_interface;
 	if (device_register(&iface->dev)) {
 		pr_err("registering iface->dev failed\n");
-		kfree(inst);
+		kfree(iface->p);
 		ida_simple_remove(&mdev_id, id);
 		return -ENOMEM;
 	}
@@ -1428,7 +1421,6 @@ int most_register_interface(struct most_interface *iface)
 		else
 			snprintf(channel_name, STRING_SIZE, "%s", name_suffix);
 
-		/* this increments the reference count of this instance */
 		c = kzalloc(sizeof(*c), GFP_KERNEL);
 		if (!c)
 			goto free_instance;
@@ -1438,12 +1430,11 @@ int most_register_interface(struct most_interface *iface)
 		c->dev.release = release_channel;
 		if (device_register(&c->dev)) {
 			pr_err("registering c->dev failed\n");
-			goto free_instance;
+			goto free_instance_nodev;
 		}
-		inst->channel[i] = c;
+		iface->p->channel[i] = c;
 		c->is_starving = 0;
 		c->iface = iface;
-		c->inst = inst;
 		c->channel_id = i;
 		c->keep_mbo = false;
 		c->enqueue_halt = false;
@@ -1462,14 +1453,22 @@ int most_register_interface(struct most_interface *iface)
 		atomic_set(&c->mbo_ref, 0);
 		mutex_init(&c->start_mutex);
 		mutex_init(&c->nq_mutex);
-		list_add_tail(&c->list, &inst->channel_list);
+		list_add_tail(&c->list, &iface->p->channel_list);
 	}
 	pr_info("registered new MOST device mdev%d (%s)\n",
 		id, iface->description);
 	return 0;
 
+free_instance_nodev:
+	kfree(c);
+
 free_instance:
-	pr_info("Failed allocate channel(s)\n");
+	while (i > 0) {
+		c = iface->p->channel[--i];
+		device_unregister(&c->dev);
+		kfree(c);
+	}
+	kfree(iface->p);
 	device_unregister(&iface->dev);
 	ida_simple_remove(&mdev_id, id);
 	return -ENOMEM;
@@ -1487,12 +1486,10 @@ void most_deregister_interface(struct most_interface *iface)
 {
 	int i;
 	struct most_channel *c;
-	struct most_inst_obj *inst;
 
 	pr_info("deregistering MOST device %s (%s)\n", dev_name(&iface->dev), iface->description);
-	inst = iface->priv;
 	for (i = 0; i < iface->num_channels; i++) {
-		c = inst->channel[i];
+		c = iface->p->channel[i];
 		if (c->pipe0.aim)
 			c->pipe0.aim->disconnect_channel(c->iface,
 							c->channel_id);
@@ -1506,8 +1503,8 @@ void most_deregister_interface(struct most_interface *iface)
 		kfree(c);
 	}
 
-	ida_simple_remove(&mdev_id, inst->dev_id);
-	kfree(inst);
+	ida_simple_remove(&mdev_id, iface->p->dev_id);
+	kfree(iface->p);
 	device_unregister(&iface->dev);
 }
 EXPORT_SYMBOL_GPL(most_deregister_interface);
@@ -1524,8 +1521,7 @@ EXPORT_SYMBOL_GPL(most_deregister_interface);
  */
 void most_stop_enqueue(struct most_interface *iface, int id)
 {
-	struct most_inst_obj *inst = iface->priv;
-	struct most_channel *c = inst->channel[id];
+	struct most_channel *c = iface->p->channel[id];
 
 	if (!c)
 		return;
@@ -1546,8 +1542,7 @@ EXPORT_SYMBOL_GPL(most_stop_enqueue);
  */
 void most_resume_enqueue(struct most_interface *iface, int id)
 {
-	struct most_inst_obj *inst = iface->priv;
-	struct most_channel *c = inst->channel[id];
+	struct most_channel *c = iface->p->channel[id];
 
 	if (!c)
 		return;
@@ -1570,7 +1565,6 @@ static int __init most_init(void)
 	int err;
 
 	pr_info("init()\n");
-	INIT_LIST_HEAD(&instance_list);
 	INIT_LIST_HEAD(&mc.mod_list);
 	ida_init(&mdev_id);
 
diff --git a/drivers/staging/most/core.h b/drivers/staging/most/core.h
index a4fb75c..fe0ad62 100644
--- a/drivers/staging/most/core.h
+++ b/drivers/staging/most/core.h
@@ -26,6 +26,7 @@
 #include <linux/device.h>
 
 struct module;
+struct interface_private;
 
 /**
  * Interface type
@@ -254,6 +255,7 @@ struct most_interface {
 						   unsigned char link_stat,
 						   unsigned char *mac_addr));
 	void *priv;
+	struct interface_private *p;
 };
 
 #define to_most_interface(d) container_of(d, struct most_interface, dev)
-- 
2.7.4

  parent reply	other threads:[~2017-11-21 14:04 UTC|newest]

Thread overview: 68+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-21 14:04 [PATCH 00/50] staging: most: rework driver architecture and fix defects Christian Gromm
2017-11-21 14:04 ` [PATCH 01/50] staging: most: move core files Christian Gromm
2017-11-21 14:04 ` [PATCH 02/50] staging: most: cdev: rename module Christian Gromm
2017-11-21 14:04 ` [PATCH 03/50] staging: most: i2c: " Christian Gromm
2017-11-21 14:04 ` [PATCH 04/50] staging: most: dim2: " Christian Gromm
2017-11-21 14:04 ` [PATCH 05/50] staging: most: net: " Christian Gromm
2017-11-21 14:04 ` [PATCH 06/50] staging: most: sound: " Christian Gromm
2017-11-21 14:04 ` [PATCH 07/50] staging: most: usb: " Christian Gromm
2017-11-21 14:04 ` [PATCH 08/50] staging: most: video: " Christian Gromm
2017-11-24 15:08   ` Greg KH
2017-11-21 14:04 ` [PATCH 09/50] staging: most: remove proprietary kobjects Christian Gromm
2017-11-24 15:19   ` Greg KH
2017-11-21 14:04 ` [PATCH 10/50] staging: most: core: remove function get_channel_by_iface Christian Gromm
2017-11-22 10:44   ` Frans Klaver
2017-11-21 14:04 ` [PATCH 11/50] staging: most: core: add a match function for the bus Christian Gromm
2017-11-21 14:04 ` [PATCH 12/50] staging: most: core: encapsulate code in function Christian Gromm
2017-11-21 14:04 ` [PATCH 13/50] staging: most: core: rename structure Christian Gromm
2017-11-21 14:04 ` [PATCH 14/50] staging: most: core: rename struct most_c_aim_obj to pipe Christian Gromm
2017-11-21 14:04 ` [PATCH 15/50] staging: most: core: rename struct memeber Christian Gromm
2017-11-21 14:04 ` [PATCH 16/50] staging: most: core: rename members aim* of struct most_channel Christian Gromm
2017-11-21 14:04 ` [PATCH 17/50] staging: most: core: use structure to pack driver specific data Christian Gromm
2017-11-21 14:04 ` [PATCH 18/50] staging: most: core: track aim modules with linked list Christian Gromm
2017-11-21 14:04 ` [PATCH 19/50] staging: most: core: fix sysfs attribute management Christian Gromm
2017-11-21 14:04 ` [PATCH 20/50] staging: most: core: remove struct device Christian Gromm
2017-11-22 13:01   ` PrasannaKumar Muralidharan
2017-11-24 15:10     ` Greg KH
2017-11-24 15:20       ` Greg KH
2017-11-21 14:04 ` [PATCH 21/50] staging: most: core: rename function Christian Gromm
2017-11-21 14:04 ` Christian Gromm [this message]
2017-11-21 14:04 ` [PATCH 23/50] staging: most: core: put channel name in struct most_channel Christian Gromm
2017-11-21 14:04 ` [PATCH 24/50] staging: most: core: remove context pointer Christian Gromm
2017-11-21 14:04 ` [PATCH 25/50] staging: most: usb: remove pointer initialization Christian Gromm
2017-11-21 14:05 ` [PATCH 26/50] staging: most: rename struct most_aim Christian Gromm
2017-11-22 13:01   ` PrasannaKumar Muralidharan
2017-11-21 14:05 ` [PATCH 27/50] staging: most: rename functions to register a driver with most_core Christian Gromm
2017-11-21 14:05 ` [PATCH 28/50] staging: most: core: rename mod_list Christian Gromm
2017-11-21 14:05 ` [PATCH 29/50] staging: most: core: rename aim variables Christian Gromm
2017-11-21 14:05 ` [PATCH 30/50] staging: most: core: rename function link_channel_to_aim Christian Gromm
2017-11-21 14:05 ` [PATCH 31/50] staging: most: net: remove aim designators Christian Gromm
2017-11-21 14:05 ` [PATCH 32/50] staging: most: sound: remove aim designator Christian Gromm
2017-11-21 14:05 ` [PATCH 33/50] staging: most: video: remove aim designators Christian Gromm
2017-11-21 14:05 ` [PATCH 34/50] staging: most: cdev: rename struct aim_channel Christian Gromm
2017-11-21 14:05 ` [PATCH 35/50] staging: most: cdev: rename variable aim_devno Christian Gromm
2017-11-21 14:05 ` [PATCH 36/50] staging: most: cdev: rename class instance aim_class Christian Gromm
2017-11-21 14:05 ` [PATCH 37/50] staging: most: cdev: rename variable cdev_aim Christian Gromm
2017-11-21 14:05 ` [PATCH 38/50] staging: most: fix comment sections Christian Gromm
2017-11-21 14:05 ` [PATCH 39/50] staging: most: core: denote modules as components Christian Gromm
2017-11-21 14:05 ` [PATCH 40/50] staging: most: core: fix formatting Christian Gromm
2017-11-21 14:05 ` [PATCH 41/50] staging: most: usb: clear functional stall on OUT endpoint Christian Gromm
2017-11-22 13:01   ` PrasannaKumar Muralidharan
2017-11-21 14:05 ` [PATCH 42/50] staging: most: core: fix data type Christian Gromm
2017-11-22 13:02   ` PrasannaKumar Muralidharan
2017-11-24 15:09   ` Greg KH
2017-11-21 14:05 ` [PATCH 43/50] staging: most: core: check value returned by match function Christian Gromm
2017-11-21 14:05 ` [PATCH 44/50] staging: most: update driver usage file Christian Gromm
2017-11-21 14:05 ` [PATCH 45/50] staging: most: cdev: replace function prefix Christian Gromm
2017-11-21 14:05 ` [PATCH 46/50] staging: most: cdev: bundle module variables in structure Christian Gromm
2017-11-21 14:05 ` [PATCH 47/50] staging: most: core: remove class generation Christian Gromm
2017-11-22 13:02   ` PrasannaKumar Muralidharan
2017-11-21 14:05 ` [PATCH 48/50] staging: most: core: fix list traversing Christian Gromm
2017-11-21 14:05 ` [PATCH 49/50] staging: most: add ABI documentation Christian Gromm
2017-11-21 14:05 ` [PATCH 50/50] staging: most: usb: fix show/store function names Christian Gromm
2017-11-22 13:00 ` [PATCH 00/50] staging: most: rework driver architecture and fix defects PrasannaKumar Muralidharan
2017-11-24 15:11   ` Greg KH
2017-11-24 15:31 ` Greg KH
2017-11-24 15:46   ` Christian Gromm
2017-11-27 13:38   ` Christian Gromm
2017-11-27 15:07     ` Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1511273124-7840-23-git-send-email-christian.gromm@microchip.com \
    --to=christian.gromm@microchip.com \
    --cc=driverdev-devel@linuxdriverproject.org \
    --cc=gregkh@linuxfoundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.