[PATCH] dvb: dst: protect the read/write commands with a mutex
authorManu Abraham <manu@linuxtv.org>
Wed, 9 Nov 2005 05:35:36 +0000 (21:35 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 9 Nov 2005 15:56:03 +0000 (07:56 -0800)
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>
drivers/media/dvb/bt8xx/dst.c
drivers/media/dvb/bt8xx/dst_ca.c
drivers/media/dvb/bt8xx/dst_common.h

index bc833a55438fedbdaa1d29d3b5a193769e432f63..0c718dca09ca84ffda0d24d0b50f7590ee398552 100644 (file)
@@ -910,6 +910,7 @@ static int dst_get_device_id(struct dst_state *state)
 
 static int dst_probe(struct dst_state *state)
 {
+       sema_init(&state->dst_mutex, 1);
        if ((rdc_8820_reset(state)) < 0) {
                dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed.");
                return -1;
@@ -960,21 +961,23 @@ static int dst_probe(struct dst_state *state)
 int dst_command(struct dst_state *state, u8 *data, u8 len)
 {
        u8 reply;
+
+       down(&state->dst_mutex);
        if ((dst_comm_init(state)) < 0) {
                dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed.");
-               return -1;
+               goto error;
        }
        if (write_dst(state, data, len)) {
                dprintk(verbose, DST_INFO, 1, "Tring to recover.. ");
                if ((dst_error_recovery(state)) < 0) {
                        dprintk(verbose, DST_ERROR, 1, "Recovery Failed.");
-                       return -1;
+                       goto error;
                }
-               return -1;
+               goto error;
        }
        if ((dst_pio_disable(state)) < 0) {
                dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed.");
-               return -1;
+               goto error;
        }
        if (state->type_flags & DST_TYPE_HAS_FW_1)
                udelay(3000);
@@ -982,36 +985,41 @@ int dst_command(struct dst_state *state, u8 *data, u8 len)
                dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
                if ((dst_error_recovery(state)) < 0) {
                        dprintk(verbose, DST_INFO, 1, "Recovery Failed.");
-                       return -1;
+                       goto error;
                }
-               return -1;
+               goto error;
        }
        if (reply != ACK) {
                dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply);
-               return -1;
+               goto error;
        }
        if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
-               return 0;
+               goto error;
        if (state->type_flags & DST_TYPE_HAS_FW_1)
                udelay(3000);
        else
                udelay(2000);
        if (!dst_wait_dst_ready(state, NO_DELAY))
-               return -1;
+               goto error;
        if (read_dst(state, state->rxbuffer, FIXED_COMM)) {
                dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
                if ((dst_error_recovery(state)) < 0) {
                        dprintk(verbose, DST_INFO, 1, "Recovery failed.");
-                       return -1;
+                       goto error;
                }
-               return -1;
+               goto error;
        }
        if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
                dprintk(verbose, DST_INFO, 1, "checksum failure");
-               return -1;
+               goto error;
        }
-
+       up(&state->dst_mutex);
        return 0;
+
+error:
+       up(&state->dst_mutex);
+       return -EIO;
+
 }
 EXPORT_SYMBOL(dst_command);
 
index 38c728945bf1fe16bd6d75e62769f3308ddea21c..e6541aff39968597f67d390ab453e846bcc07d35 100644 (file)
@@ -81,36 +81,41 @@ static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8
 {
        u8 reply;
 
+       down(&state->dst_mutex);
        dst_comm_init(state);
        msleep(65);
 
        if (write_dst(state, data, len)) {
                dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover");
                dst_error_recovery(state);
-               return -1;
+               goto error;
        }
        if ((dst_pio_disable(state)) < 0) {
                dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed.");
-               return -1;
+               goto error;
        }
        if (read_dst(state, &reply, GET_ACK) < 0) {
                dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
                dst_error_recovery(state);
-               return -1;
+               goto error;
        }
        if (read) {
                if (! dst_wait_dst_ready(state, LONG_DELAY)) {
                        dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready");
-                       return -1;
+                       goto error;
                }
                if (read_dst(state, ca_string, 128) < 0) {      /*      Try to make this dynamic        */
                        dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
                        dst_error_recovery(state);
-                       return -1;
+                       goto error;
                }
        }
-
+       up(&state->dst_mutex);
        return 0;
+
+error:
+       up(&state->dst_mutex);
+       return -EIO;
 }
 
 
index 29b5430dbe4f106f5b05ae33cd428ecc66ab90db..81557f38fe3826aa0cfdc44ba0ac96f19de2eac6 100644 (file)
@@ -22,6 +22,7 @@
 #ifndef DST_COMMON_H
 #define DST_COMMON_H
 
+#include <linux/smp_lock.h>
 #include <linux/dvb/frontend.h>
 #include <linux/device.h>
 #include "bt878.h"
@@ -119,6 +120,8 @@ struct dst_state {
        u8 card_info[8];
        u8 vendor[8];
        u8 board_info[8];
+
+       struct semaphore dst_mutex;
 };
 
 struct dst_types {