[PATCH 7/30] W1: be able to manually add and remove slaves

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: David Fries
Date: Wednesday, July 30, 2008 - 7:48 pm

sysfs entries were added to manually add and remove slave devices.
This is useful if the automatic bus searching is disabled, and the
device ids are already known.

Signed-off-by: David Fries <david@fries.net>
Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
---
 drivers/w1/w1.c |  137 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 136 insertions(+), 1 deletions(-)

diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index 32418d4..354c12a 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -56,6 +56,8 @@ module_param_named(slave_ttl, w1_max_slave_ttl, int, 0);
 DEFINE_MUTEX(w1_mlock);
 LIST_HEAD(w1_masters);
 
+static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn);
+
 static int w1_master_match(struct device *dev, struct device_driver *drv)
 {
 	return 1;
@@ -357,7 +359,8 @@ static ssize_t w1_master_attribute_show_slave_count(struct device *dev, struct d
 	return count;
 }
 
-static ssize_t w1_master_attribute_show_slaves(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t w1_master_attribute_show_slaves(struct device *dev,
+	struct device_attribute *attr, char *buf)
 {
 	struct w1_master *md = dev_to_w1_master(dev);
 	int c = PAGE_SIZE;
@@ -382,6 +385,134 @@ static ssize_t w1_master_attribute_show_slaves(struct device *dev, struct device
 	return PAGE_SIZE - c;
 }
 
+static ssize_t w1_master_attribute_show_add(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	int c = PAGE_SIZE;
+	c -= snprintf(buf+PAGE_SIZE - c, c,
+		"write device id xx-xxxxxxxxxxxx to add slave\n");
+	return PAGE_SIZE - c;
+}
+
+static int w1_atoreg_num(struct device *dev, const char *buf, size_t count,
+	struct w1_reg_num *rn)
+{
+	unsigned int family;
+	u64 id;
+	int i;
+	u64 rn64_le;
+	/* The CRC value isn't read from the user because the sysfs directory
+	 * doesn't include it and most messages from the bus search don't
+	 * print it either.  It would be unreasonable for the user to then
+	 * provide it.
+	 */
+	const char *error_msg = "bad slave string format, expecting "
+		"ff-dddddddddddd\n";
+
+	if (buf[2] != '-') {
+		dev_err(dev, "%s", error_msg);
+		return -EINVAL;
+	}
+	i = sscanf(buf, "%02x-%012llx", &family, &id);
+	if (i != 2) {
+		dev_err(dev, "%s", error_msg);
+		return -EINVAL;
+	}
+	rn->family = family;
+	rn->id = id;
+
+	rn64_le = cpu_to_le64(*(u64 *)rn);
+	rn->crc = w1_calc_crc8((u8 *)&rn64_le, 7);
+
+	#if 0
+	dev_info(dev, "With CRC device is %02x.%012llx.%02x.\n",
+		  rn->family, (unsigned long long)rn->id, rn->crc);
+	#endif
+
+	return 0;
+}
+
+/* Searches the slaves in the w1_master and returns a pointer or NULL.
+ * Note: must hold the mutex
+ */
+static struct w1_slave *w1_slave_search_device(struct w1_master *dev,
+	struct w1_reg_num *rn)
+{
+	struct w1_slave *sl;
+	list_for_each_entry(sl, &dev->slist, w1_slave_entry) {
+		if (sl->reg_num.family == rn->family &&
+				sl->reg_num.id == rn->id &&
+				sl->reg_num.crc == rn->crc) {
+			return sl;
+		}
+	}
+	return NULL;
+}
+
+static ssize_t w1_master_attribute_store_add(struct device *dev,
+						struct device_attribute *attr,
+						const char *buf, size_t count)
+{
+	struct w1_master *md = dev_to_w1_master(dev);
+	struct w1_reg_num rn;
+	struct w1_slave *sl;
+	ssize_t result = count;
+
+	if (w1_atoreg_num(dev, buf, count, &rn))
+		return -EINVAL;
+
+	mutex_lock(&md->mutex);
+	sl = w1_slave_search_device(md, &rn);
+	/* It would be nice to do a targeted search one the one-wire bus
+	 * for the new device to see if it is out there or not.  But the
+	 * current search doesn't support that.
+	 */
+	if (sl) {
+		dev_info(dev, "Device %s already exists\n", sl->name);
+		result = -EINVAL;
+	} else {
+		w1_attach_slave_device(md, &rn);
+	}
+	mutex_unlock(&md->mutex);
+
+	return result;
+}
+
+static ssize_t w1_master_attribute_show_remove(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	int c = PAGE_SIZE;
+	c -= snprintf(buf+PAGE_SIZE - c, c,
+		"write device id xx-xxxxxxxxxxxx to remove slave\n");
+	return PAGE_SIZE - c;
+}
+
+static ssize_t w1_master_attribute_store_remove(struct device *dev,
+						struct device_attribute *attr,
+						const char *buf, size_t count)
+{
+	struct w1_master *md = dev_to_w1_master(dev);
+	struct w1_reg_num rn;
+	struct w1_slave *sl;
+	ssize_t result = count;
+
+	if (w1_atoreg_num(dev, buf, count, &rn))
+		return -EINVAL;
+
+	mutex_lock(&md->mutex);
+	sl = w1_slave_search_device(md, &rn);
+	if (sl) {
+		w1_slave_detach(sl);
+	} else {
+		dev_info(dev, "Device %02x-%012llx doesn't exists\n", rn.family,
+			(unsigned long long)rn.id);
+		result = -EINVAL;
+	}
+	mutex_unlock(&md->mutex);
+
+	return result;
+}
+
 #define W1_MASTER_ATTR_RO(_name, _mode)				\
 	struct device_attribute w1_master_attribute_##_name =	\
 		__ATTR(w1_master_##_name, _mode,		\
@@ -402,6 +533,8 @@ static W1_MASTER_ATTR_RO(timeout, S_IRUGO);
 static W1_MASTER_ATTR_RO(pointer, S_IRUGO);
 static W1_MASTER_ATTR_RW(search, S_IRUGO | S_IWUGO);
 static W1_MASTER_ATTR_RW(pullup, S_IRUGO | S_IWUGO);
+static W1_MASTER_ATTR_RW(add, S_IRUGO | S_IWUGO);
+static W1_MASTER_ATTR_RW(remove, S_IRUGO | S_IWUGO);
 
 static struct attribute *w1_master_default_attrs[] = {
 	&w1_master_attribute_name.attr,
@@ -413,6 +546,8 @@ static struct attribute *w1_master_default_attrs[] = {
 	&w1_master_attribute_pointer.attr,
 	&w1_master_attribute_search.attr,
 	&w1_master_attribute_pullup.attr,
+	&w1_master_attribute_add.attr,
+	&w1_master_attribute_remove.attr,
 	NULL
 };
 
-- 
1.4.4.4
--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[PATCH 2/30] W1: abort search early on on exit, David Fries, (Mon Jul 28, 7:12 pm)
[PATCH 3/30] W1: don't delay search start, David Fries, (Mon Jul 28, 7:13 pm)
[PATCH 4/30] W1: w1_process, block or sleep, David Fries, (Mon Jul 28, 7:14 pm)
[PATCH 8/30] W1: recode w1_slave_found logic, David Fries, (Mon Jul 28, 7:18 pm)
[PATCH 9/30] W1: new module parameter search_count, David Fries, (Mon Jul 28, 7:19 pm)
[PATCH 16/30] W1: w1.c s/printk/dev_dbg/, David Fries, (Mon Jul 28, 7:23 pm)
[PATCH 17/30] W1: w1_io.c reset comments and msleep, David Fries, (Mon Jul 28, 7:24 pm)
[PATCH 18/30] W1: ds1wm.c msleep for reset, David Fries, (Mon Jul 28, 7:24 pm)
[PATCH 19/30] W1: ds2490.c correct print message, David Fries, (Mon Jul 28, 7:25 pm)
[PATCH 22/30] W1: ds2490.c disable bit read and write, David Fries, (Mon Jul 28, 7:25 pm)
[PATCH 24/30] W1: ds2490.c ds_dump_status rework, David Fries, (Mon Jul 28, 7:26 pm)
[PATCH 26/30] W1: ds2490.c reset ds2490 in init, David Fries, (Mon Jul 28, 7:27 pm)
[PATCH 27/30] W1: ds2490.c magic number work, David Fries, (Mon Jul 28, 7:28 pm)
[PATCH 30/30] W1: ds2490.c optimize ds_set_pullup, David Fries, (Mon Jul 28, 7:30 pm)
[PATCH 2/30] W1: abort search early on on exit, David Fries, (Wed Jul 30, 7:48 pm)
[PATCH 3/30] W1: don't delay search start, David Fries, (Wed Jul 30, 7:48 pm)
[PATCH 4/30] W1: w1_process, block or sleep, David Fries, (Wed Jul 30, 7:48 pm)
[PATCH 7/30] W1: be able to manually add and remove slaves, David Fries, (Wed Jul 30, 7:48 pm)
[PATCH 8/30] W1: recode w1_slave_found logic, David Fries, (Wed Jul 30, 7:48 pm)
[PATCH 9/30] W1: new module parameter search_count, David Fries, (Wed Jul 30, 7:48 pm)
[PATCH 16/30] W1: w1.c s/printk/dev_dbg/, David Fries, (Wed Jul 30, 7:49 pm)
[PATCH 17/30] W1: w1_io.c reset comments and msleep, David Fries, (Wed Jul 30, 7:49 pm)
[PATCH 18/30] W1: ds1wm.c msleep for reset, David Fries, (Wed Jul 30, 7:49 pm)
[PATCH 19/30] W1: ds2490.c correct print message, David Fries, (Wed Jul 30, 7:49 pm)
[PATCH 22/30] W1: ds2490.c disable bit read and write, David Fries, (Wed Jul 30, 7:50 pm)
[PATCH 24/30] W1: ds2490.c ds_dump_status rework, David Fries, (Wed Jul 30, 7:50 pm)
[PATCH 26/30] W1: ds2490.c reset ds2490 in init, David Fries, (Wed Jul 30, 7:50 pm)
[PATCH 27/30] W1: ds2490.c magic number work, David Fries, (Wed Jul 30, 7:50 pm)
[PATCH 30/30] W1: ds2490.c optimize ds_set_pullup, David Fries, (Wed Jul 30, 7:50 pm)