aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/w1/masters
diff options
context:
space:
mode:
authorDavid Fries <David@Fries.net>2014-01-15 23:29:26 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-02-07 18:40:18 -0500
commitd3a8a9dbb903c73a7ec2deae4c9b7d74b6834f4c (patch)
tree49128d16abf121d8ae8c555a17a1339a09ff7585 /drivers/w1/masters
parentb3be177a19f0f9e4f0deb473cef0e95e1254f2e9 (diff)
w1: hold bus_mutex in netlink and search
The bus_mutex needs to be taken to serialize access to a specific bus. netlink wasn't updated when bus_mutex was added and was calling without that lock held, and not all of the masters were holding the bus_mutex in a search. This was causing the ds2490 hardware to stop responding when both netlink and /sys slaves were executing bus commands at the same time. Signed-off-by: David Fries <David@Fries.net> Acked-by: Evgeniy Polyakov <zbr@ioremap.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/w1/masters')
-rw-r--r--drivers/w1/masters/ds1wm.c4
-rw-r--r--drivers/w1/masters/ds2490.c8
2 files changed, 9 insertions, 3 deletions
diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c
index 02df3b1381d2..b077b8b42758 100644
--- a/drivers/w1/masters/ds1wm.c
+++ b/drivers/w1/masters/ds1wm.c
@@ -326,13 +326,14 @@ static void ds1wm_search(void *data, struct w1_master *master_dev,
326 unsigned slaves_found = 0; 326 unsigned slaves_found = 0;
327 unsigned int pass = 0; 327 unsigned int pass = 0;
328 328
329 mutex_lock(&master_dev->bus_mutex);
329 dev_dbg(&ds1wm_data->pdev->dev, "search begin\n"); 330 dev_dbg(&ds1wm_data->pdev->dev, "search begin\n");
330 while (true) { 331 while (true) {
331 ++pass; 332 ++pass;
332 if (pass > 100) { 333 if (pass > 100) {
333 dev_dbg(&ds1wm_data->pdev->dev, 334 dev_dbg(&ds1wm_data->pdev->dev,
334 "too many attempts (100), search aborted\n"); 335 "too many attempts (100), search aborted\n");
335 return; 336 break;
336 } 337 }
337 338
338 mutex_lock(&master_dev->bus_mutex); 339 mutex_lock(&master_dev->bus_mutex);
@@ -439,6 +440,7 @@ static void ds1wm_search(void *data, struct w1_master *master_dev,
439 dev_dbg(&ds1wm_data->pdev->dev, 440 dev_dbg(&ds1wm_data->pdev->dev,
440 "pass: %d total: %d search done ms d bit pos: %d\n", pass, 441 "pass: %d total: %d search done ms d bit pos: %d\n", pass,
441 slaves_found, ms_discrep_bit); 442 slaves_found, ms_discrep_bit);
443 mutex_unlock(&master_dev->bus_mutex);
442} 444}
443 445
444/* --------------------------------------------------------------------- */ 446/* --------------------------------------------------------------------- */
diff --git a/drivers/w1/masters/ds2490.c b/drivers/w1/masters/ds2490.c
index db0bf3229bb6..7404ad3062b7 100644
--- a/drivers/w1/masters/ds2490.c
+++ b/drivers/w1/masters/ds2490.c
@@ -727,9 +727,11 @@ static void ds9490r_search(void *data, struct w1_master *master,
727 */ 727 */
728 u64 buf[2*64/8]; 728 u64 buf[2*64/8];
729 729
730 mutex_lock(&master->bus_mutex);
731
730 /* address to start searching at */ 732 /* address to start searching at */
731 if (ds_send_data(dev, (u8 *)&master->search_id, 8) < 0) 733 if (ds_send_data(dev, (u8 *)&master->search_id, 8) < 0)
732 return; 734 goto search_out;
733 master->search_id = 0; 735 master->search_id = 0;
734 736
735 value = COMM_SEARCH_ACCESS | COMM_IM | COMM_RST | COMM_SM | COMM_F | 737 value = COMM_SEARCH_ACCESS | COMM_IM | COMM_RST | COMM_SM | COMM_F |
@@ -739,7 +741,7 @@ static void ds9490r_search(void *data, struct w1_master *master,
739 search_limit = 0; 741 search_limit = 0;
740 index = search_type | (search_limit << 8); 742 index = search_type | (search_limit << 8);
741 if (ds_send_control(dev, value, index) < 0) 743 if (ds_send_control(dev, value, index) < 0)
742 return; 744 goto search_out;
743 745
744 do { 746 do {
745 schedule_timeout(jtime); 747 schedule_timeout(jtime);
@@ -791,6 +793,8 @@ static void ds9490r_search(void *data, struct w1_master *master,
791 master->max_slave_count); 793 master->max_slave_count);
792 set_bit(W1_WARN_MAX_COUNT, &master->flags); 794 set_bit(W1_WARN_MAX_COUNT, &master->flags);
793 } 795 }
796search_out:
797 mutex_unlock(&master->bus_mutex);
794} 798}
795 799
796#if 0 800#if 0