W1: clean-up family implementation:
    - get rid of w1_family_ops and template attributes in w1_slave
      structure and have family drivers create necessary attributes
      themselves. There are too many different devices using 1-Wire
      interface and it is impossible to fit them all into single
      attribute model. If interface unification is needed it can be
      done by building cross-bus class hierarchy.
    - rename w1_smem to w1_sernum because devices are called Silicon
      serial numbers, they have address (ID) but don't have memory
      in regular sense.
    - rename w1_therm to w1_thermal.

Signed-off-by: Dmitry Torokhov <[EMAIL PROTECTED]>
---

 drivers/w1/w1_smem.c         |  103 -----------------------
 drivers/w1/w1_therm.c        |  188 -------------------------------------------
 dtor/drivers/w1/Kconfig      |   13 +-
 dtor/drivers/w1/Makefile     |    4 
 dtor/drivers/w1/w1.c         |  148 +++++++++------------------------
 dtor/drivers/w1/w1.h         |    5 -
 dtor/drivers/w1/w1_family.c  |   37 +++++---
 dtor/drivers/w1/w1_family.h  |   23 +----
 dtor/drivers/w1/w1_sernum.c  |   58 +++++++++++++
 dtor/drivers/w1/w1_thermal.c |  173 +++++++++++++++++++++++++++++++++++++++
 10 files changed, 317 insertions(+), 435 deletions(-)

Index: dtor/drivers/w1/w1_therm.c
===================================================================
--- dtor.orig/drivers/w1/w1_therm.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- *     w1_therm.c
- *
- * Copyright (c) 2004 Evgeniy Polyakov <[EMAIL PROTECTED]>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the therms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <asm/types.h>
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-
-#include "w1.h"
-#include "w1_io.h"
-#include "w1_family.h"
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Evgeniy Polyakov <[EMAIL PROTECTED]>");
-MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, temperature 
family.");
-
-static u8 bad_roms[][9] = {
-                               {0xaa, 0x00, 0x4b, 0x46, 0xff, 0xff, 0x0c, 
0x10, 0x87},
-                               {}
-                       };
-
-static ssize_t w1_therm_read_temp(struct device *, char *);
-static ssize_t w1_therm_read_bin(struct kobject *, char *, loff_t, size_t);
-
-static struct w1_family_ops w1_therm_fops = {
-       .rbin = &w1_therm_read_bin,
-       .rval = &w1_therm_read_temp,
-       .rvalname = "temp1_input",
-};
-
-static inline int w1_convert_temp(u8 rom[9])
-{
-       int t, h;
-
-       if (rom[1] == 0)
-               t = ((s32)rom[0] >> 1)*1000;
-       else
-               t = 1000*(-1*(s32)(0x100-rom[0]) >> 1);
-
-       t -= 250;
-       h = 1000*((s32)rom[7] - (s32)rom[6]);
-       h /= (s32)rom[7];
-       t += h;
-
-       return t;
-}
-
-static ssize_t w1_therm_read_temp(struct device *dev, char *buf)
-{
-       struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
-
-       return sprintf(buf, "%d\n", w1_convert_temp(sl->rom));
-}
-
-static int w1_therm_check_rom(u8 rom[9])
-{
-       int i;
-
-       for (i=0; i<sizeof(bad_roms)/9; ++i)
-               if (!memcmp(bad_roms[i], rom, 9))
-                       return 1;
-
-       return 0;
-}
-
-static ssize_t w1_therm_read_bin(struct kobject *kobj, char *buf, loff_t off, 
size_t count)
-{
-       struct w1_slave *sl = container_of(container_of(kobj, struct device, 
kobj),
-                                          struct w1_slave, dev);
-       struct w1_master *dev = sl->master;
-       u8 rom[9], crc, verdict;
-       int i, max_trying = 10;
-
-       if (down_interruptible(&sl->master->mutex))
-               return 0;
-
-       if (off > W1_SLAVE_DATA_SIZE) {
-               count = 0;
-               goto out;
-       }
-       if (off + count > W1_SLAVE_DATA_SIZE) {
-               count = 0;
-               goto out;
-       }
-
-       memset(buf, 0, count);
-       memset(rom, 0, sizeof(rom));
-
-       count = 0;
-       verdict = 0;
-       crc = 0;
-
-       while (max_trying--) {
-               if (!w1_reset_bus (dev)) {
-                       int count = 0;
-                       u8 match[9] = {W1_MATCH_ROM, };
-                       unsigned int tm = 750;
-
-                       memcpy(&match[1], (u64 *) & sl->reg_num, 8);
-
-                       w1_write_block(dev, match, 9);
-
-                       w1_write_8(dev, W1_CONVERT_TEMP);
-
-                       while (tm) {
-                               tm = msleep_interruptible(tm);
-                               if (signal_pending(current))
-                                       flush_signals(current);
-                       }
-
-                       if (!w1_reset_bus (dev)) {
-                               w1_write_block(dev, match, 9);
-
-                               w1_write_8(dev, W1_READ_SCRATCHPAD);
-                               if ((count = w1_read_block(dev, rom, 9)) != 9) {
-                                       dev_warn(&dev->dev, "w1_read_block() 
returned %d instead of 9.\n", count);
-                               }
-
-                               crc = w1_calc_crc8(rom, 8);
-
-                               if (rom[8] == crc && rom[0])
-                                       verdict = 1;
-
-                       }
-               }
-
-               if (!w1_therm_check_rom(rom))
-                       break;
-       }
-
-       for (i = 0; i < 9; ++i)
-               count += sprintf(buf + count, "%02x ", rom[i]);
-       count += sprintf(buf + count, ": crc=%02x %s\n",
-                          crc, (verdict) ? "YES" : "NO");
-       if (verdict)
-               memcpy(sl->rom, rom, sizeof(sl->rom));
-       else
-               dev_warn(&dev->dev, "18S20 doesn't respond to CONVERT_TEMP.\n");
-
-       for (i = 0; i < 9; ++i)
-               count += sprintf(buf + count, "%02x ", sl->rom[i]);
-
-       count += sprintf(buf + count, "t=%d\n", w1_convert_temp(rom));
-out:
-       up(&dev->mutex);
-
-       return count;
-}
-
-static struct w1_family w1_therm_family = {
-       .fid = W1_FAMILY_THERM,
-       .fops = &w1_therm_fops,
-};
-
-static int __init w1_therm_init(void)
-{
-       return w1_register_family(&w1_therm_family);
-}
-
-static void __exit w1_therm_fini(void)
-{
-       w1_unregister_family(&w1_therm_family);
-}
-
-module_init(w1_therm_init);
-module_exit(w1_therm_fini);
Index: dtor/drivers/w1/w1_smem.c
===================================================================
--- dtor.orig/drivers/w1/w1_smem.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- *     w1_smem.c
- *
- * Copyright (c) 2004 Evgeniy Polyakov <[EMAIL PROTECTED]>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the smems of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <asm/types.h>
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <linux/types.h>
-
-#include "w1.h"
-#include "w1_io.h"
-#include "w1_family.h"
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Evgeniy Polyakov <[EMAIL PROTECTED]>");
-MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, 64bit memory 
family.");
-
-static ssize_t w1_smem_read_val(struct device *, char *);
-static ssize_t w1_smem_read_bin(struct kobject *, char *, loff_t, size_t);
-
-static struct w1_family_ops w1_smem_fops = {
-       .rbin = &w1_smem_read_bin,
-       .rval = &w1_smem_read_val,
-       .rvalname = "id",
-};
-
-static ssize_t w1_smem_read_val(struct device *dev, char *buf)
-{
-       struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
-       int i;
-       ssize_t count = 0;
-
-       for (i = 0; i < 9; ++i)
-               count += sprintf(buf + count, "%02x ", ((u8 *)&sl->reg_num)[i]);
-       count += sprintf(buf + count, "\n");
-
-       return count;
-}
-
-static ssize_t w1_smem_read_bin(struct kobject *kobj, char *buf, loff_t off, 
size_t count)
-{
-       struct w1_slave *sl = container_of(container_of(kobj, struct device, 
kobj),
-                                          struct w1_slave, dev);
-       int i;
-
-       if (down_interruptible(&sl->master->mutex))
-               return 0;
-
-       if (off > W1_SLAVE_DATA_SIZE) {
-               count = 0;
-               goto out;
-       }
-       if (off + count > W1_SLAVE_DATA_SIZE) {
-               count = 0;
-               goto out;
-       }
-       for (i = 0; i < 9; ++i)
-               count += sprintf(buf + count, "%02x ", ((u8 *)&sl->reg_num)[i]);
-       count += sprintf(buf + count, "\n");
-
-out:
-       up(&sl->master->mutex);
-
-       return count;
-}
-
-static struct w1_family w1_smem_family = {
-       .fid = W1_FAMILY_SMEM,
-       .fops = &w1_smem_fops,
-};
-
-static int __init w1_smem_init(void)
-{
-       return w1_register_family(&w1_smem_family);
-}
-
-static void __exit w1_smem_fini(void)
-{
-       w1_unregister_family(&w1_smem_family);
-}
-
-module_init(w1_smem_init);
-module_exit(w1_smem_fini);
Index: dtor/drivers/w1/w1.c
===================================================================
--- dtor.orig/drivers/w1/w1.c
+++ dtor/drivers/w1/w1.c
@@ -2,6 +2,7 @@
  *     w1.c
  *
  * Copyright (c) 2004 Evgeniy Polyakov <[EMAIL PROTECTED]>
+ * Copyright (c) 2005 Dmitry Torokhov <[EMAIL PROTECTED]>
  *
  *
  * This program is free software; you can redistribute it and/or modify
@@ -97,30 +98,6 @@ static struct attribute_group w1_slave_d
        .attrs = w1_slave_default_attrs,
 };
 
-static ssize_t w1_default_read_name(struct device *dev, char *buf)
-{
-       return sprintf(buf, "No family registered.\n");
-}
-
-static ssize_t w1_default_read_bin(struct kobject *kobj, char *buf, loff_t off,
-                    size_t count)
-{
-       return sprintf(buf, "No family registered.\n");
-}
-
-static struct device_attribute w1_slave_attribute_val =
-       __ATTR(value, S_IRUGO, w1_default_read_name, NULL);
-
-static struct bin_attribute w1_slave_bin_attribute = {
-       .attr = {
-               .name = "w1_slave",
-               .mode = S_IRUGO,
-               .owner = THIS_MODULE,
-       },
-       .size = W1_SLAVE_DATA_SIZE,
-       .read = &w1_default_read_bin,
-};
-
 static void w1_slave_release(struct device *dev)
 {
        struct w1_slave *slave = to_w1_slave(dev);
@@ -130,79 +107,10 @@ static void w1_slave_release(struct devi
        module_put(THIS_MODULE);
 }
 
-static int __w1_attach_slave_device(struct w1_slave *slave)
-{
-       int err;
-
-       slave->dev.parent = &slave->master->dev;
-       slave->dev.bus = &w1_bus_type;
-       slave->dev.release = &w1_slave_release;
-
-       snprintf(&slave->dev.bus_id[0], sizeof(slave->dev.bus_id),
-                 "%02x-%012llx",
-                 (unsigned int) slave->reg_num.family,
-                 (unsigned long long) slave->reg_num.id);
-
-       dev_dbg(&slave->dev, "%s: registering %s.\n", __func__,
-               &slave->dev.bus_id[0]);
-
-       err = device_register(&slave->dev);
-       if (err < 0) {
-               dev_err(&slave->dev,
-                        "Device registration [%s] failed. err=%d\n",
-                        slave->dev.bus_id, err);
-               return err;
-       }
-
-       __module_get(THIS_MODULE);
-
-       memcpy(&slave->attr_bin, &w1_slave_bin_attribute, 
sizeof(slave->attr_bin));
-       memcpy(&slave->attr_val, &w1_slave_attribute_val, 
sizeof(slave->attr_val));
-
-       slave->attr_bin.read = slave->family->fops->rbin;
-       slave->attr_val.show = slave->family->fops->rval;
-       slave->attr_val.attr.name = slave->family->fops->rvalname;
-
-       err = device_create_file(&slave->dev, &slave->attr_val);
-       if (err < 0) {
-               dev_err(&slave->dev,
-                        "sysfs file creation for [%s] failed. err=%d\n",
-                        slave->dev.bus_id, err);
-               device_unregister(&slave->dev);
-               return err;
-       }
-
-       err = sysfs_create_bin_file(&slave->dev.kobj, &slave->attr_bin);
-       if (err < 0) {
-               dev_err(&slave->dev,
-                        "sysfs file creation for [%s] failed. err=%d\n",
-                        slave->dev.bus_id, err);
-               device_remove_file(&slave->dev, &slave->attr_val);
-               device_unregister(&slave->dev);
-               return err;
-       }
-
-       err = sysfs_create_group(&slave->dev.kobj, &w1_slave_defattr_group);
-       if (err < 0) {
-               dev_err(&slave->dev,
-                        "sysfs group creation for [%s] failed. err=%d\n",
-                        slave->dev.bus_id, err);
-               sysfs_remove_bin_file(&slave->dev.kobj, &slave->attr_bin);
-               device_remove_file(&slave->dev, &slave->attr_val);
-               device_unregister(&slave->dev);
-               return err;
-       }
-
-       list_add_tail(&slave->node, &slave->master->slist);
-
-       return 0;
-}
-
 static int w1_attach_slave_device(struct w1_master *master, struct w1_reg_num 
*rn)
 {
        struct w1_slave *slave;
-       struct w1_family *f;
-       int err;
+       int error;
 
        slave = kcalloc(1, sizeof(struct w1_slave), GFP_KERNEL);
        if (!slave) {
@@ -212,13 +120,16 @@ static int w1_attach_slave_device(struct
                return -ENOMEM;
        }
 
+       init_MUTEX(&slave->mutex);
+       INIT_LIST_HEAD(&slave->node);
        slave->master = master;
        slave->reg_num = *rn;
        set_bit(W1_SLAVE_ACTIVE, &slave->flags);
+       slave->ttl = master->slave_ttl;
 
        spin_lock(&w1_flock);
-       f = w1_family_registered(rn->family);
-       if (!f) {
+       slave->family = w1_family_registered(rn->family);
+       if (!slave->family) {
                spin_unlock(&w1_flock);
                dev_info(&master->dev,
                         "Family %x for %02x.%012llx.%02x is not registered.\n",
@@ -227,21 +138,45 @@ static int w1_attach_slave_device(struct
                kfree(slave);
                return -ENODEV;
        }
-       __w1_family_get(f);
+       __w1_family_get(slave->family);
        spin_unlock(&w1_flock);
 
-       slave->family = f;
+       slave->dev.parent = &slave->master->dev;
+       slave->dev.bus = &w1_bus_type;
+       slave->dev.release = &w1_slave_release;
+
+       snprintf(&slave->dev.bus_id[0], sizeof(slave->dev.bus_id),
+                 "%02x-%012llx",
+                 (unsigned int) slave->reg_num.family,
+                 (unsigned long long) slave->reg_num.id);
+
+       dev_dbg(&slave->dev, "%s: registering %s.\n", __func__,
+               &slave->dev.bus_id[0]);
 
-       err = __w1_attach_slave_device(slave);
-       if (err < 0) {
-               dev_err(&master->dev, "%s: Attaching %s failed.\n", __func__,
-                       slave->dev.bus_id);
+       error = device_register(&slave->dev);
+       if (error < 0) {
+               dev_err(&slave->dev,
+                        "Device registration [%s] failed. err=%d\n",
+                        slave->dev.bus_id, error);
                w1_family_put(slave->family);
                kfree(slave);
-               return err;
+               return error;
        }
 
-       slave->ttl = master->slave_ttl;
+       __module_get(THIS_MODULE);
+
+       error = sysfs_create_group(&slave->dev.kobj, &w1_slave_defattr_group);
+       if (error < 0) {
+               dev_err(&slave->dev,
+                        "sysfs group creation for [%s] failed. err=%d\n",
+                        slave->dev.bus_id, error);
+               device_unregister(&slave->dev);
+               return error;
+       }
+
+       w1_family_join(slave);  /* assume it always succeeds for now */
+
+       list_add_tail(&slave->node, &slave->master->slist);
 
        return 0;
 }
@@ -251,9 +186,8 @@ static void w1_slave_detach(struct w1_sl
        dev_info(&slave->dev, "%s: detaching %s.\n",
                 __func__, slave->dev.bus_id);
 
+       w1_family_leave(slave);
        sysfs_remove_group(&slave->dev.kobj, &w1_slave_defattr_group);
-       sysfs_remove_bin_file(&slave->dev.kobj, &slave->attr_bin);
-       device_remove_file(&slave->dev, &slave->attr_val);
        device_unregister(&slave->dev);
 }
 
@@ -519,10 +453,12 @@ void w1_remove_master_device(struct w1_m
 
        w1_stop_master_device(master);
 
+       down(&master->mutex);
        list_for_each_entry_safe(slave, next, &master->slist, node) {
                list_del(&slave->node);
                w1_slave_detach(slave);
        }
+       up(&master->mutex);
 
        sysfs_remove_group(&master->dev.kobj, &w1_master_defattr_group);
        device_unregister(&master->dev);
Index: dtor/drivers/w1/w1.h
===================================================================
--- dtor.orig/drivers/w1/w1.h
+++ dtor/drivers/w1/w1.h
@@ -47,7 +47,6 @@ struct w1_reg_num
 #include "w1_family.h"
 
 #define W1_MAXNAMELEN          32
-#define W1_SLAVE_DATA_SIZE     128
 
 #define W1_SEARCH              0xF0
 #define W1_CONDITIONAL_SEARCH  0xEC
@@ -71,9 +70,7 @@ struct w1_slave
        struct w1_master        *master;
        struct w1_family        *family;
        struct device           dev;
-
-       struct bin_attribute    attr_bin;
-       struct device_attribute attr_name, attr_val;
+       struct semaphore        mutex;
 };
 #define to_w1_slave(dev)       container_of((dev), struct w1_slave, dev)
 
Index: dtor/drivers/w1/w1_thermal.c
===================================================================
--- /dev/null
+++ dtor/drivers/w1/w1_thermal.c
@@ -0,0 +1,173 @@
+/*
+ *     w1_thermal.c
+ *
+ * Copyright (c) 2004 Evgeniy Polyakov <[EMAIL PROTECTED]>
+ * Copyright (c) 2005 Dmitry Torokhov <[EMAIL PROTECTED]>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the therms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+
+#include "w1.h"
+#include "w1_io.h"
+#include "w1_family.h"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Evgeniy Polyakov <[EMAIL PROTECTED]>");
+MODULE_DESCRIPTION("1-Wire Digital Thermometer");
+
+static ssize_t w1_thermal_show_temp(struct device *, char *);
+
+static struct device_attribute w1_thermal_temperature_attr =
+       __ATTR(temp, S_IRUGO, w1_thermal_show_temp, NULL);
+
+static int w1_thermal_join(struct w1_slave *slave)
+{
+       return device_create_file(&slave->dev, &w1_thermal_temperature_attr);
+}
+
+static void w1_thermal_leave(struct w1_slave *slave)
+{
+       device_remove_file(&slave->dev, &w1_thermal_temperature_attr);
+}
+
+static struct w1_family w1_thermal_family = {
+       .fid            = W1_FAMILY_THERMAL,
+       .join           = w1_thermal_join,
+       .leave          = w1_thermal_leave,
+};
+
+static u8 bad_roms[][9] = {
+       { 0xaa, 0x00, 0x4b, 0x46, 0xff, 0xff, 0x0c, 0x10, 0x87 },
+       { }
+};
+
+static inline int w1_convert_temp(u8 rom[9])
+{
+       int t, h;
+
+       if (rom[1] == 0)
+               t = ((s32)rom[0] >> 1) * 1000;
+       else
+               t = 1000 * (-1 * (s32)(0x100 - rom[0]) >> 1);
+
+       t -= 250;
+       h = 1000 * ((s32)rom[7] - (s32)rom[6]);
+       h /= (s32)rom[7];
+       t += h;
+
+       return t;
+}
+
+static int w1_therm_check_rom(u8 rom[9])
+{
+       int i;
+
+       for (i = 0; i < sizeof(bad_roms) / 9; i++)
+               if (!memcmp(bad_roms[i], rom, 9))
+                       return 1;
+
+       return 0;
+}
+
+static int w1_thermal_read_data(struct w1_slave *slave, u8 data[])
+{
+       struct w1_master *dev = slave->master;
+       u8 match[9] = { W1_MATCH_ROM, };
+       u8 crc;
+       int count;
+       int error;
+
+       memset(data, 0, 9);
+
+       error = w1_reset_bus(dev);
+       if (error)
+               return error;
+
+       memcpy(&match[1], (u64 *)&slave->reg_num, sizeof(u64));
+
+       w1_write_block(dev, match, 9);
+       w1_write_8(dev, W1_CONVERT_TEMP);
+       msleep(750);
+
+       error = w1_reset_bus(dev);
+       if (error)
+               return error;
+
+       w1_write_block(dev, match, 9);
+       w1_write_8(dev, W1_READ_SCRATCHPAD);
+       if ((count = w1_read_block(dev, data, 9)) != 9)
+               dev_warn(&dev->dev, "w1_read_block() returned %d instead of 
9.\n", count);
+
+       crc = w1_calc_crc8(data, 8);
+       if (data[8] != crc || !data[0] || w1_therm_check_rom(data))
+               return -EIO;
+
+       return 0;
+}
+
+static ssize_t w1_thermal_show_temp(struct device *dev, char *buf)
+{
+       struct w1_slave *slave = to_w1_slave(dev);
+       int attempts = 10;
+       u8 data[9];
+       int error;
+       ssize_t count = 0;
+
+       error = down_interruptible(&slave->master->mutex);
+       if (error)
+               return error;
+
+       error = down_interruptible(&slave->mutex);
+       if (error)
+               goto out;
+
+       if (slave->family != &w1_thermal_family) {
+               error = -ENODEV;
+               goto out;
+       }
+
+       do {
+               error = w1_thermal_read_data(slave, data);
+               if (!error)
+                       count = sprintf(buf, "%d\n", w1_convert_temp(data));
+
+       } while (error && attempts-- > 0);
+
+       up(&slave->mutex);
+out:
+       up(&slave->master->mutex);
+       return error ? error : count;
+}
+
+static int __init w1_thermal_init(void)
+{
+       return w1_register_family(&w1_thermal_family);
+}
+
+static void __exit w1_thermal_exit(void)
+{
+       w1_unregister_family(&w1_thermal_family);
+}
+
+module_init(w1_thermal_init);
+module_exit(w1_thermal_exit);
Index: dtor/drivers/w1/Makefile
===================================================================
--- dtor.orig/drivers/w1/Makefile
+++ dtor/drivers/w1/Makefile
@@ -10,8 +10,8 @@ obj-$(CONFIG_W1)      += wire.o
 wire-objs              := w1.o w1_family.o w1_io.o
 
 obj-$(CONFIG_W1_MATROX)                += matrox_w1.o
-obj-$(CONFIG_W1_THERM)         += w1_therm.o
-obj-$(CONFIG_W1_SMEM)          += w1_smem.o
+obj-$(CONFIG_W1_THERMAL)       += w1_thermal.o
+obj-$(CONFIG_W1_SERNUM)                += w1_sernum.o
 
 obj-$(CONFIG_W1_DS9490)                += ds9490r.o
 ds9490r-objs    := dscore.o
Index: dtor/drivers/w1/w1_sernum.c
===================================================================
--- /dev/null
+++ dtor/drivers/w1/w1_sernum.c
@@ -0,0 +1,58 @@
+/*
+ *     w1_sernum.c
+ *
+ * Copyright (c) 2004 Evgeniy Polyakov <[EMAIL PROTECTED]>
+ * Copyright (c) 2005 Dmitry Torokhov <[EMAIL PROTECTED]>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the smems of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/types.h>
+
+#include "w1.h"
+#include "w1_family.h"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Evgeniy Polyakov <[EMAIL PROTECTED]>");
+MODULE_DESCRIPTION("1-Wire Silicon Serial Number Driver");
+
+/*
+ * This is a very dumb device. It just has an unique ID and
+ * sits on the bus doing nothing. So the driver does not do
+ * anything fancy either; access to device's ID is provided
+ * by W1 core.
+ */
+
+static struct w1_family w1_serial_num_family = {
+       .fid            = W1_FAMILY_SERIAL_NUM,
+};
+
+static int __init w1_serial_num_init(void)
+{
+       return w1_register_family(&w1_serial_num_family);
+}
+
+static void __exit w1_serial_num_exit(void)
+{
+       w1_unregister_family(&w1_serial_num_family);
+}
+
+module_init(w1_serial_num_init);
+module_exit(w1_serial_num_exit);
Index: dtor/drivers/w1/Kconfig
===================================================================
--- dtor.orig/drivers/w1/Kconfig
+++ dtor/drivers/w1/Kconfig
@@ -40,18 +40,19 @@ config W1_DS9490_BRIDGE
          This support is also available as a module.  If so, the module
          will be called ds_w1_bridge.ko.
 
-config W1_THERM
-       tristate "Thermal family implementation"
+config W1_THERMAL
+       tristate "Thermal sensor devices"
        depends on W1
        help
-         Say Y here if you want to connect 1-wire thermal sensors to you
+         Say Y here if you want to connect 1-wire thermal sensors to your
          wire.
 
-config W1_SMEM
-       tristate "Simple 64bit memory family implementation"
+config W1_SERNUM
+       tristate "Silicon Serial Number devices"
        depends on W1
        help
          Say Y here if you want to connect 1-wire
-         simple 64bit memory rom(ds2401/ds2411/ds1990*) to you wire.
+         simple addressable devices (Silicon Serial Nnumbers -
+         ds2401/ds2411/ds1990*) to your wire.
 
 endmenu
Index: dtor/drivers/w1/w1_family.c
===================================================================
--- dtor.orig/drivers/w1/w1_family.c
+++ dtor/drivers/w1/w1_family.c
@@ -23,28 +23,18 @@
 #include <linux/list.h>
 #include <linux/delay.h>
 
+#include "w1.h"
 #include "w1_family.h"
 
 DEFINE_SPINLOCK(w1_flock);
 static LIST_HEAD(w1_families);
 
-static int w1_check_family(struct w1_family *f)
-{
-       if (!f->fops->rbin || !f->fops->rval || !f->fops->rvalname)
-               return -EINVAL;
-
-       return 0;
-}
-
 int w1_register_family(struct w1_family *newf)
 {
        struct list_head *ent, *n;
        struct w1_family *f;
        int ret = 0;
 
-       if (w1_check_family(newf))
-               return -EINVAL;
-
        spin_lock(&w1_flock);
        list_for_each_safe(ent, n, &w1_families) {
                f = list_entry(ent, struct w1_family, family_entry);
@@ -115,6 +105,31 @@ struct w1_family * w1_family_registered(
        return (ret) ? f : NULL;
 }
 
+int w1_family_join(struct w1_slave *slave)
+{
+       int retval;
+
+       retval = down_interruptible(&slave->mutex);
+       if (retval)
+               return retval;
+
+       if (slave->family->join)
+               retval = slave->family->join(slave);
+
+       up(&slave->mutex);
+       return retval;
+}
+
+void w1_family_leave(struct w1_slave *slave)
+{
+       down(&slave->mutex);
+
+       if (slave->family->leave)
+               slave->family->leave(slave);
+
+       up(&slave->mutex);
+}
+
 void w1_family_put(struct w1_family *f)
 {
        spin_lock(&w1_flock);
Index: dtor/drivers/w1/w1_family.h
===================================================================
--- dtor.orig/drivers/w1/w1_family.h
+++ dtor/drivers/w1/w1_family.h
@@ -26,28 +26,20 @@
 #include <linux/device.h>
 #include <asm/atomic.h>
 
-#define W1_FAMILY_DEFAULT      0
-#define W1_FAMILY_THERM                0x10
-#define W1_FAMILY_SMEM         0x01
+#define W1_FAMILY_SERIAL_NUM   0x01
+#define W1_FAMILY_THERMAL      0x10
 
-#define MAXNAMELEN             32
-
-struct w1_family_ops
-{
-       ssize_t (* rbin)(struct kobject *, char *, loff_t, size_t);
-       ssize_t (* rval)(struct device *, char *);
-       unsigned char rvalname[MAXNAMELEN];
-};
+struct w1_slave;
 
 struct w1_family
 {
        struct list_head        family_entry;
        u8                      fid;
-
-       struct w1_family_ops    *fops;
-
        atomic_t                refcnt;
        u8                      need_exit;
+
+       int (*join)(struct w1_slave *);
+       void (*leave)(struct w1_slave *);
 };
 
 extern spinlock_t w1_flock;
@@ -57,7 +49,8 @@ void w1_family_put(struct w1_family *);
 void __w1_family_get(struct w1_family *);
 void __w1_family_put(struct w1_family *);
 struct w1_family * w1_family_registered(u8);
+int w1_family_join(struct w1_slave *);
+void w1_family_leave(struct w1_slave *);
 void w1_unregister_family(struct w1_family *);
 int w1_register_family(struct w1_family *);
-
 #endif /* __W1_FAMILY_H */
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to