aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/w1/w1_int.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/w1/w1_int.c')
-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 @@
29#include "w1_netlink.h" 29#include "w1_netlink.h"
30#include "w1_int.h" 30#include "w1_int.h"
31 31
32static u32 w1_ids = 1;
33static int w1_search_count = -1; /* Default is continual scan */ 32static int w1_search_count = -1; /* Default is continual scan */
34module_param_named(search_count, w1_search_count, int, 0); 33module_param_named(search_count, w1_search_count, int, 0);
35 34
@@ -102,9 +101,10 @@ static void w1_free_dev(struct w1_master *dev)
102 101
103int w1_add_master_device(struct w1_bus_master *master) 102int w1_add_master_device(struct w1_bus_master *master)
104{ 103{
105 struct w1_master *dev; 104 struct w1_master *dev, *entry;
106 int retval = 0; 105 int retval = 0;
107 struct w1_netlink_msg msg; 106 struct w1_netlink_msg msg;
107 int id, found;
108 108
109 /* validate minimum functionality */ 109 /* validate minimum functionality */
110 if (!(master->touch_bit && master->reset_bus) && 110 if (!(master->touch_bit && master->reset_bus) &&
@@ -126,13 +126,33 @@ int w1_add_master_device(struct w1_bus_master *master)
126 master->set_pullup = NULL; 126 master->set_pullup = NULL;
127 } 127 }
128 128
129 dev = w1_alloc_dev(w1_ids++, w1_max_slave_count, w1_max_slave_ttl, &w1_master_driver, &w1_master_device); 129 /* Lock until the device is added (or not) to w1_masters. */
130 if (!dev) 130 mutex_lock(&w1_mlock);
131 /* Search for the first available id (starting at 1). */
132 id = 0;
133 do {
134 ++id;
135 found = 0;
136 list_for_each_entry(entry, &w1_masters, w1_master_entry) {
137 if (entry->id == id) {
138 found = 1;
139 break;
140 }
141 }
142 } while (found);
143
144 dev = w1_alloc_dev(id, w1_max_slave_count, w1_max_slave_ttl,
145 &w1_master_driver, &w1_master_device);
146 if (!dev) {
147 mutex_unlock(&w1_mlock);
131 return -ENOMEM; 148 return -ENOMEM;
149 }
132 150
133 retval = w1_create_master_attributes(dev); 151 retval = w1_create_master_attributes(dev);
134 if (retval) 152 if (retval) {
153 mutex_unlock(&w1_mlock);
135 goto err_out_free_dev; 154 goto err_out_free_dev;
155 }
136 156
137 memcpy(dev->bus_master, master, sizeof(struct w1_bus_master)); 157 memcpy(dev->bus_master, master, sizeof(struct w1_bus_master));
138 158
@@ -144,10 +164,10 @@ int w1_add_master_device(struct w1_bus_master *master)
144 dev_err(&dev->dev, 164 dev_err(&dev->dev,
145 "Failed to create new kernel thread. err=%d\n", 165 "Failed to create new kernel thread. err=%d\n",
146 retval); 166 retval);
167 mutex_unlock(&w1_mlock);
147 goto err_out_rm_attr; 168 goto err_out_rm_attr;
148 } 169 }
149 170
150 mutex_lock(&w1_mlock);
151 list_add(&dev->w1_master_entry, &w1_masters); 171 list_add(&dev->w1_master_entry, &w1_masters);
152 mutex_unlock(&w1_mlock); 172 mutex_unlock(&w1_mlock);
153 173