diff options
author | Manu Abraham <manu@linuxtv.org> | 2005-11-09 00:35:36 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-09 10:56:03 -0500 |
commit | d28d57629ffcd30e11a6085e15ee1327fea60b60 (patch) | |
tree | c3286f3f4a2eeec76cff805b5d06a455bab9e8eb | |
parent | 2cbeddc976645262dbe036d6ec0825f96af70da3 (diff) |
[PATCH] dvb: dst: protect the read/write commands with a mutex
We need to protect the read/write commands with a mutex.
Bug reported by Henrik Sjoberg <henke@epact.se>
Signed-off-by: Manu Abraham <manu@linuxtv.org>
Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
Cc: Johannes Stezenbach <js@linuxtv.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | drivers/media/dvb/bt8xx/dst.c | 34 | ||||
-rw-r--r-- | drivers/media/dvb/bt8xx/dst_ca.c | 17 | ||||
-rw-r--r-- | drivers/media/dvb/bt8xx/dst_common.h | 3 |
3 files changed, 35 insertions, 19 deletions
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index bc833a55438f..0c718dca09ca 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c | |||
@@ -910,6 +910,7 @@ static int dst_get_device_id(struct dst_state *state) | |||
910 | 910 | ||
911 | static int dst_probe(struct dst_state *state) | 911 | static int dst_probe(struct dst_state *state) |
912 | { | 912 | { |
913 | sema_init(&state->dst_mutex, 1); | ||
913 | if ((rdc_8820_reset(state)) < 0) { | 914 | if ((rdc_8820_reset(state)) < 0) { |
914 | dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); | 915 | dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); |
915 | return -1; | 916 | return -1; |
@@ -960,21 +961,23 @@ static int dst_probe(struct dst_state *state) | |||
960 | int dst_command(struct dst_state *state, u8 *data, u8 len) | 961 | int dst_command(struct dst_state *state, u8 *data, u8 len) |
961 | { | 962 | { |
962 | u8 reply; | 963 | u8 reply; |
964 | |||
965 | down(&state->dst_mutex); | ||
963 | if ((dst_comm_init(state)) < 0) { | 966 | if ((dst_comm_init(state)) < 0) { |
964 | dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed."); | 967 | dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed."); |
965 | return -1; | 968 | goto error; |
966 | } | 969 | } |
967 | if (write_dst(state, data, len)) { | 970 | if (write_dst(state, data, len)) { |
968 | dprintk(verbose, DST_INFO, 1, "Tring to recover.. "); | 971 | dprintk(verbose, DST_INFO, 1, "Tring to recover.. "); |
969 | if ((dst_error_recovery(state)) < 0) { | 972 | if ((dst_error_recovery(state)) < 0) { |
970 | dprintk(verbose, DST_ERROR, 1, "Recovery Failed."); | 973 | dprintk(verbose, DST_ERROR, 1, "Recovery Failed."); |
971 | return -1; | 974 | goto error; |
972 | } | 975 | } |
973 | return -1; | 976 | goto error; |
974 | } | 977 | } |
975 | if ((dst_pio_disable(state)) < 0) { | 978 | if ((dst_pio_disable(state)) < 0) { |
976 | dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed."); | 979 | dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed."); |
977 | return -1; | 980 | goto error; |
978 | } | 981 | } |
979 | if (state->type_flags & DST_TYPE_HAS_FW_1) | 982 | if (state->type_flags & DST_TYPE_HAS_FW_1) |
980 | udelay(3000); | 983 | udelay(3000); |
@@ -982,36 +985,41 @@ int dst_command(struct dst_state *state, u8 *data, u8 len) | |||
982 | dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); | 985 | dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); |
983 | if ((dst_error_recovery(state)) < 0) { | 986 | if ((dst_error_recovery(state)) < 0) { |
984 | dprintk(verbose, DST_INFO, 1, "Recovery Failed."); | 987 | dprintk(verbose, DST_INFO, 1, "Recovery Failed."); |
985 | return -1; | 988 | goto error; |
986 | } | 989 | } |
987 | return -1; | 990 | goto error; |
988 | } | 991 | } |
989 | if (reply != ACK) { | 992 | if (reply != ACK) { |
990 | dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply); | 993 | dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply); |
991 | return -1; | 994 | goto error; |
992 | } | 995 | } |
993 | if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3)) | 996 | if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3)) |
994 | return 0; | 997 | goto error; |
995 | if (state->type_flags & DST_TYPE_HAS_FW_1) | 998 | if (state->type_flags & DST_TYPE_HAS_FW_1) |
996 | udelay(3000); | 999 | udelay(3000); |
997 | else | 1000 | else |
998 | udelay(2000); | 1001 | udelay(2000); |
999 | if (!dst_wait_dst_ready(state, NO_DELAY)) | 1002 | if (!dst_wait_dst_ready(state, NO_DELAY)) |
1000 | return -1; | 1003 | goto error; |
1001 | if (read_dst(state, state->rxbuffer, FIXED_COMM)) { | 1004 | if (read_dst(state, state->rxbuffer, FIXED_COMM)) { |
1002 | dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); | 1005 | dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); |
1003 | if ((dst_error_recovery(state)) < 0) { | 1006 | if ((dst_error_recovery(state)) < 0) { |
1004 | dprintk(verbose, DST_INFO, 1, "Recovery failed."); | 1007 | dprintk(verbose, DST_INFO, 1, "Recovery failed."); |
1005 | return -1; | 1008 | goto error; |
1006 | } | 1009 | } |
1007 | return -1; | 1010 | goto error; |
1008 | } | 1011 | } |
1009 | if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { | 1012 | if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { |
1010 | dprintk(verbose, DST_INFO, 1, "checksum failure"); | 1013 | dprintk(verbose, DST_INFO, 1, "checksum failure"); |
1011 | return -1; | 1014 | goto error; |
1012 | } | 1015 | } |
1013 | 1016 | up(&state->dst_mutex); | |
1014 | return 0; | 1017 | return 0; |
1018 | |||
1019 | error: | ||
1020 | up(&state->dst_mutex); | ||
1021 | return -EIO; | ||
1022 | |||
1015 | } | 1023 | } |
1016 | EXPORT_SYMBOL(dst_command); | 1024 | EXPORT_SYMBOL(dst_command); |
1017 | 1025 | ||
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c index 38c728945bf1..e6541aff3996 100644 --- a/drivers/media/dvb/bt8xx/dst_ca.c +++ b/drivers/media/dvb/bt8xx/dst_ca.c | |||
@@ -81,36 +81,41 @@ static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 | |||
81 | { | 81 | { |
82 | u8 reply; | 82 | u8 reply; |
83 | 83 | ||
84 | down(&state->dst_mutex); | ||
84 | dst_comm_init(state); | 85 | dst_comm_init(state); |
85 | msleep(65); | 86 | msleep(65); |
86 | 87 | ||
87 | if (write_dst(state, data, len)) { | 88 | if (write_dst(state, data, len)) { |
88 | dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover"); | 89 | dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover"); |
89 | dst_error_recovery(state); | 90 | dst_error_recovery(state); |
90 | return -1; | 91 | goto error; |
91 | } | 92 | } |
92 | if ((dst_pio_disable(state)) < 0) { | 93 | if ((dst_pio_disable(state)) < 0) { |
93 | dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed."); | 94 | dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed."); |
94 | return -1; | 95 | goto error; |
95 | } | 96 | } |
96 | if (read_dst(state, &reply, GET_ACK) < 0) { | 97 | if (read_dst(state, &reply, GET_ACK) < 0) { |
97 | dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); | 98 | dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); |
98 | dst_error_recovery(state); | 99 | dst_error_recovery(state); |
99 | return -1; | 100 | goto error; |
100 | } | 101 | } |
101 | if (read) { | 102 | if (read) { |
102 | if (! dst_wait_dst_ready(state, LONG_DELAY)) { | 103 | if (! dst_wait_dst_ready(state, LONG_DELAY)) { |
103 | dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready"); | 104 | dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready"); |
104 | return -1; | 105 | goto error; |
105 | } | 106 | } |
106 | if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */ | 107 | if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */ |
107 | dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); | 108 | dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); |
108 | dst_error_recovery(state); | 109 | dst_error_recovery(state); |
109 | return -1; | 110 | goto error; |
110 | } | 111 | } |
111 | } | 112 | } |
112 | 113 | up(&state->dst_mutex); | |
113 | return 0; | 114 | return 0; |
115 | |||
116 | error: | ||
117 | up(&state->dst_mutex); | ||
118 | return -EIO; | ||
114 | } | 119 | } |
115 | 120 | ||
116 | 121 | ||
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h index 29b5430dbe4f..81557f38fe38 100644 --- a/drivers/media/dvb/bt8xx/dst_common.h +++ b/drivers/media/dvb/bt8xx/dst_common.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #ifndef DST_COMMON_H | 22 | #ifndef DST_COMMON_H |
23 | #define DST_COMMON_H | 23 | #define DST_COMMON_H |
24 | 24 | ||
25 | #include <linux/smp_lock.h> | ||
25 | #include <linux/dvb/frontend.h> | 26 | #include <linux/dvb/frontend.h> |
26 | #include <linux/device.h> | 27 | #include <linux/device.h> |
27 | #include "bt878.h" | 28 | #include "bt878.h" |
@@ -119,6 +120,8 @@ struct dst_state { | |||
119 | u8 card_info[8]; | 120 | u8 card_info[8]; |
120 | u8 vendor[8]; | 121 | u8 vendor[8]; |
121 | u8 board_info[8]; | 122 | u8 board_info[8]; |
123 | |||
124 | struct semaphore dst_mutex; | ||
122 | }; | 125 | }; |
123 | 126 | ||
124 | struct dst_types { | 127 | struct dst_types { |