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 /drivers/media/dvb/bt8xx/dst.c | |
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>
Diffstat (limited to 'drivers/media/dvb/bt8xx/dst.c')
-rw-r--r-- | drivers/media/dvb/bt8xx/dst.c | 34 |
1 files changed, 21 insertions, 13 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 | ||