summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Fries <david@fries.net>2008-10-16 09:04:53 +0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-16 22:21:50 +0400
commitaf00a2d5a047455b35d1e7dc4c7d9993c2bcfb93 (patch)
tree2ad744edff4aa6b4f63c39b9285b578f407fff74
parente0d29c7699de723432da268748aefe9624fc8529 (diff)
downloadlinux-af00a2d5a047455b35d1e7dc4c7d9993c2bcfb93.tar.xz
W1: w1_int.c use first available master number
Follow the example of other devices (like the joystick device). Pick the first available id for each detected device. Currently for USB devices, suspending and resuming would cause the number to increment. Signed-off-by: David Fries <david@fries.net> Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/w1/w1_int.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c
index 3fd6e6651fbe..a3a54567bfba 100644
--- a/drivers/w1/w1_int.c
+++ b/drivers/w1/w1_int.c
@@ -29,7 +29,6 @@
#include "w1_netlink.h"
#include "w1_int.h"
-static u32 w1_ids = 1;
static int w1_search_count = -1; /* Default is continual scan */
module_param_named(search_count, w1_search_count, int, 0);
@@ -102,9 +101,10 @@ static void w1_free_dev(struct w1_master *dev)
int w1_add_master_device(struct w1_bus_master *master)
{
- struct w1_master *dev;
+ struct w1_master *dev, *entry;
int retval = 0;
struct w1_netlink_msg msg;
+ int id, found;
/* validate minimum functionality */
if (!(master->touch_bit && master->reset_bus) &&
@@ -126,13 +126,33 @@ int w1_add_master_device(struct w1_bus_master *master)
master->set_pullup = NULL;
}
- dev = w1_alloc_dev(w1_ids++, w1_max_slave_count, w1_max_slave_ttl, &w1_master_driver, &w1_master_device);
- if (!dev)
+ /* Lock until the device is added (or not) to w1_masters. */
+ mutex_lock(&w1_mlock);
+ /* Search for the first available id (starting at 1). */
+ id = 0;
+ do {
+ ++id;
+ found = 0;
+ list_for_each_entry(entry, &w1_masters, w1_master_entry) {
+ if (entry->id == id) {
+ found = 1;
+ break;
+ }
+ }
+ } while (found);
+
+ dev = w1_alloc_dev(id, w1_max_slave_count, w1_max_slave_ttl,
+ &w1_master_driver, &w1_master_device);
+ if (!dev) {
+ mutex_unlock(&w1_mlock);
return -ENOMEM;
+ }
retval = w1_create_master_attributes(dev);
- if (retval)
+ if (retval) {
+ mutex_unlock(&w1_mlock);
goto err_out_free_dev;
+ }
memcpy(dev->bus_master, master, sizeof(struct w1_bus_master));
@@ -144,10 +164,10 @@ int w1_add_master_device(struct w1_bus_master *master)
dev_err(&dev->dev,
"Failed to create new kernel thread. err=%d\n",
retval);
+ mutex_unlock(&w1_mlock);
goto err_out_rm_attr;
}
- mutex_lock(&w1_mlock);
list_add(&dev->w1_master_entry, &w1_masters);
mutex_unlock(&w1_mlock);