diff options
author | David Fries <David@Fries.net> | 2014-01-15 23:29:26 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-02-07 18:40:18 -0500 |
commit | d3a8a9dbb903c73a7ec2deae4c9b7d74b6834f4c (patch) | |
tree | 49128d16abf121d8ae8c555a17a1339a09ff7585 /drivers/w1/masters | |
parent | b3be177a19f0f9e4f0deb473cef0e95e1254f2e9 (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.c | 4 | ||||
-rw-r--r-- | drivers/w1/masters/ds2490.c | 8 |
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 | } |
796 | search_out: | ||
797 | mutex_unlock(&master->bus_mutex); | ||
794 | } | 798 | } |
795 | 799 | ||
796 | #if 0 | 800 | #if 0 |