summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <greg@kroah.com>2005-01-16 20:12:22 -0800
committerGreg Kroah-Hartman <greg@kroah.com>2005-01-16 20:12:22 -0800
commit089f0b0e952e194acc9d7217a4f46254524cd8fe (patch)
tree22d5641448e9739cc76320c2e573461dfc51608c /drivers
parentbd24a6bdaf51aa627d7e0cf39509c2af1aae122f (diff)
parent6cbce905acdde7ec6b355acaee7f690677cd947a (diff)
Merge kroah.com:/home/greg/linux/BK/bleed-2.6
into kroah.com:/home/greg/linux/BK/w1-2.6
Diffstat (limited to 'drivers')
-rw-r--r--drivers/w1/w1.c105
-rw-r--r--drivers/w1/w1.h5
-rw-r--r--drivers/w1/w1_io.c10
-rw-r--r--drivers/w1/w1_io.h1
4 files changed, 85 insertions, 36 deletions
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index c4e96e4854ab..d4ded1595cac 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -467,17 +467,75 @@ static void w1_slave_detach(struct w1_slave *sl)
w1_netlink_send(sl->master, &msg);
}
-static void w1_search(struct w1_master *dev)
+static struct w1_master *w1_search_master(unsigned long data)
{
- u64 last, rn, tmp;
- int i, count = 0, slave_count;
- int last_family_desc, last_zero, last_device;
- int search_bit, id_bit, comp_bit, desc_bit;
- struct list_head *ent;
+ struct w1_master *dev;
+ int found = 0;
+
+ spin_lock_irq(&w1_mlock);
+ list_for_each_entry(dev, &w1_masters, w1_master_entry) {
+ if (dev->bus_master->data == data) {
+ found = 1;
+ atomic_inc(&dev->refcnt);
+ break;
+ }
+ }
+ spin_unlock_irq(&w1_mlock);
+
+ return (found)?dev:NULL;
+}
+
+void w1_slave_found(unsigned long data, u64 rn)
+{
+ int slave_count;
struct w1_slave *sl;
+ struct list_head *ent;
+ struct w1_reg_num *tmp;
int family_found = 0;
+ struct w1_master *dev;
+
+ dev = w1_search_master(data);
+ if (!dev) {
+ printk(KERN_ERR "Failed to find w1 master device for data %08lx, it is impossible.\n",
+ data);
+ return;
+ }
+
+ tmp = (struct w1_reg_num *) &rn;
+
+ slave_count = 0;
+ list_for_each(ent, &dev->slist) {
+
+ sl = list_entry(ent, struct w1_slave, w1_slave_entry);
- dev->attempts++;
+ if (sl->reg_num.family == tmp->family &&
+ sl->reg_num.id == tmp->id &&
+ sl->reg_num.crc == tmp->crc) {
+ set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);
+ break;
+ }
+ else if (sl->reg_num.family == tmp->family) {
+ family_found = 1;
+ break;
+ }
+
+ slave_count++;
+ }
+
+ if (slave_count == dev->slave_count &&
+ rn && ((rn >> 56) & 0xff) == w1_calc_crc8((u8 *)&rn, 7)) {
+ w1_attach_slave_device(dev, (struct w1_reg_num *) &rn);
+ }
+
+ atomic_dec(&dev->refcnt);
+}
+
+void w1_search(struct w1_master *dev)
+{
+ u64 last, rn, tmp;
+ int i, count = 0;
+ int last_family_desc, last_zero, last_device;
+ int search_bit, id_bit, comp_bit, desc_bit;
search_bit = id_bit = comp_bit = 0;
rn = tmp = last = 0;
@@ -555,33 +613,8 @@ static void w1_search(struct w1_master *dev)
last_device = 1;
desc_bit = last_zero;
-
- slave_count = 0;
- list_for_each(ent, &dev->slist) {
- struct w1_reg_num *tmp;
-
- tmp = (struct w1_reg_num *) &rn;
-
- sl = list_entry(ent, struct w1_slave, w1_slave_entry);
-
- if (sl->reg_num.family == tmp->family &&
- sl->reg_num.id == tmp->id &&
- sl->reg_num.crc == tmp->crc) {
- set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);
- break;
- }
- else if (sl->reg_num.family == tmp->family) {
- family_found = 1;
- break;
- }
-
- slave_count++;
- }
-
- if (slave_count == dev->slave_count &&
- rn && ((rn >> 56) & 0xff) == w1_calc_crc8((u8 *)&rn, 7)) {
- w1_attach_slave_device(dev, (struct w1_reg_num *) &rn);
- }
+
+ w1_slave_found(dev->bus_master->data, rn);
}
}
@@ -721,8 +754,8 @@ int w1_process(void *data)
clear_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);
}
- w1_search(dev);
-
+ w1_search_devices(dev, w1_slave_found);
+
list_for_each_safe(ent, n, &dev->slist) {
sl = list_entry(ent, struct w1_slave, w1_slave_entry);
diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h
index b84ecb15c018..0abbcfdffed8 100644
--- a/drivers/w1/w1.h
+++ b/drivers/w1/w1.h
@@ -74,6 +74,8 @@ struct w1_slave
struct device_attribute attr_name, attr_val;
};
+typedef void (* w1_slave_found_callback)(unsigned long, u64);
+
struct w1_bus_master
{
unsigned long data;
@@ -90,6 +92,8 @@ struct w1_bus_master
u8 (*touch_bit)(unsigned long, u8);
u8 (*reset_bus)(unsigned long);
+
+ void (*search)(unsigned long, w1_slave_found_callback);
};
struct w1_master
@@ -127,6 +131,7 @@ struct w1_master
int w1_create_master_attributes(struct w1_master *);
void w1_destroy_master_attributes(struct w1_master *);
+void w1_search(struct w1_master *dev);
#endif /* __KERNEL__ */
diff --git a/drivers/w1/w1_io.c b/drivers/w1/w1_io.c
index 765f065a5a77..02796b5a39f6 100644
--- a/drivers/w1/w1_io.c
+++ b/drivers/w1/w1_io.c
@@ -174,6 +174,15 @@ u8 w1_calc_crc8(u8 * data, int len)
return crc;
}
+void w1_search_devices(struct w1_master *dev, w1_slave_found_callback cb)
+{
+ dev->attempts++;
+ if (dev->bus_master->search)
+ dev->bus_master->search(dev->bus_master->data, cb);
+ else
+ w1_search(dev);
+}
+
EXPORT_SYMBOL(w1_write_bit);
EXPORT_SYMBOL(w1_write_8);
EXPORT_SYMBOL(w1_read_bit);
@@ -183,3 +192,4 @@ EXPORT_SYMBOL(w1_calc_crc8);
EXPORT_SYMBOL(w1_delay);
EXPORT_SYMBOL(w1_read_block);
EXPORT_SYMBOL(w1_write_block);
+EXPORT_SYMBOL(w1_search_devices);
diff --git a/drivers/w1/w1_io.h b/drivers/w1/w1_io.h
index f63c2108bcba..6c573005a712 100644
--- a/drivers/w1/w1_io.h
+++ b/drivers/w1/w1_io.h
@@ -34,5 +34,6 @@ int w1_reset_bus(struct w1_master *);
u8 w1_calc_crc8(u8 *, int);
void w1_write_block(struct w1_master *, u8 *, int);
u8 w1_read_block(struct w1_master *, u8 *, int);
+void w1_search_devices(struct w1_master *dev, w1_slave_found_callback cb);
#endif /* __W1_IO_H */