Commit d28d5762 authored by Manu Abraham's avatar Manu Abraham Committed by Linus Torvalds

[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: default avatarManu Abraham <manu@linuxtv.org>
Signed-off-by: default avatarMichael Krufky <mkrufky@linuxtv.org>
Cc: Johannes Stezenbach <js@linuxtv.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 2cbeddc9
...@@ -910,6 +910,7 @@ static int dst_get_device_id(struct dst_state *state) ...@@ -910,6 +910,7 @@ static int dst_get_device_id(struct dst_state *state)
static int dst_probe(struct dst_state *state) static int dst_probe(struct dst_state *state)
{ {
sema_init(&state->dst_mutex, 1);
if ((rdc_8820_reset(state)) < 0) { if ((rdc_8820_reset(state)) < 0) {
dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed.");
return -1; return -1;
...@@ -960,21 +961,23 @@ static int dst_probe(struct dst_state *state) ...@@ -960,21 +961,23 @@ static int dst_probe(struct dst_state *state)
int dst_command(struct dst_state *state, u8 *data, u8 len) int dst_command(struct dst_state *state, u8 *data, u8 len)
{ {
u8 reply; u8 reply;
down(&state->dst_mutex);
if ((dst_comm_init(state)) < 0) { if ((dst_comm_init(state)) < 0) {
dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed."); dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed.");
return -1; goto error;
} }
if (write_dst(state, data, len)) { if (write_dst(state, data, len)) {
dprintk(verbose, DST_INFO, 1, "Tring to recover.. "); dprintk(verbose, DST_INFO, 1, "Tring to recover.. ");
if ((dst_error_recovery(state)) < 0) { if ((dst_error_recovery(state)) < 0) {
dprintk(verbose, DST_ERROR, 1, "Recovery Failed."); dprintk(verbose, DST_ERROR, 1, "Recovery Failed.");
return -1; goto error;
} }
return -1; goto error;
} }
if ((dst_pio_disable(state)) < 0) { if ((dst_pio_disable(state)) < 0) {
dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed."); dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed.");
return -1; goto error;
} }
if (state->type_flags & DST_TYPE_HAS_FW_1) if (state->type_flags & DST_TYPE_HAS_FW_1)
udelay(3000); udelay(3000);
...@@ -982,36 +985,41 @@ int dst_command(struct dst_state *state, u8 *data, u8 len) ...@@ -982,36 +985,41 @@ int dst_command(struct dst_state *state, u8 *data, u8 len)
dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
if ((dst_error_recovery(state)) < 0) { if ((dst_error_recovery(state)) < 0) {
dprintk(verbose, DST_INFO, 1, "Recovery Failed."); dprintk(verbose, DST_INFO, 1, "Recovery Failed.");
return -1; goto error;
} }
return -1; goto error;
} }
if (reply != ACK) { if (reply != ACK) {
dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply); 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)) 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) if (state->type_flags & DST_TYPE_HAS_FW_1)
udelay(3000); udelay(3000);
else else
udelay(2000); udelay(2000);
if (!dst_wait_dst_ready(state, NO_DELAY)) if (!dst_wait_dst_ready(state, NO_DELAY))
return -1; goto error;
if (read_dst(state, state->rxbuffer, FIXED_COMM)) { if (read_dst(state, state->rxbuffer, FIXED_COMM)) {
dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
if ((dst_error_recovery(state)) < 0) { if ((dst_error_recovery(state)) < 0) {
dprintk(verbose, DST_INFO, 1, "Recovery failed."); 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)) { if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
dprintk(verbose, DST_INFO, 1, "checksum failure"); dprintk(verbose, DST_INFO, 1, "checksum failure");
return -1; goto error;
} }
up(&state->dst_mutex);
return 0; return 0;
error:
up(&state->dst_mutex);
return -EIO;
} }
EXPORT_SYMBOL(dst_command); EXPORT_SYMBOL(dst_command);
......
...@@ -81,36 +81,41 @@ static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 ...@@ -81,36 +81,41 @@ static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8
{ {
u8 reply; u8 reply;
down(&state->dst_mutex);
dst_comm_init(state); dst_comm_init(state);
msleep(65); msleep(65);
if (write_dst(state, data, len)) { if (write_dst(state, data, len)) {
dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover"); dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover");
dst_error_recovery(state); dst_error_recovery(state);
return -1; goto error;
} }
if ((dst_pio_disable(state)) < 0) { if ((dst_pio_disable(state)) < 0) {
dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed."); dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed.");
return -1; goto error;
} }
if (read_dst(state, &reply, GET_ACK) < 0) { if (read_dst(state, &reply, GET_ACK) < 0) {
dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
dst_error_recovery(state); dst_error_recovery(state);
return -1; goto error;
} }
if (read) { if (read) {
if (! dst_wait_dst_ready(state, LONG_DELAY)) { if (! dst_wait_dst_ready(state, LONG_DELAY)) {
dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready"); 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 */ 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"); dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
dst_error_recovery(state); dst_error_recovery(state);
return -1; goto error;
} }
} }
up(&state->dst_mutex);
return 0; return 0;
error:
up(&state->dst_mutex);
return -EIO;
} }
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#ifndef DST_COMMON_H #ifndef DST_COMMON_H
#define DST_COMMON_H #define DST_COMMON_H
#include <linux/smp_lock.h>
#include <linux/dvb/frontend.h> #include <linux/dvb/frontend.h>
#include <linux/device.h> #include <linux/device.h>
#include "bt878.h" #include "bt878.h"
...@@ -119,6 +120,8 @@ struct dst_state { ...@@ -119,6 +120,8 @@ struct dst_state {
u8 card_info[8]; u8 card_info[8];
u8 vendor[8]; u8 vendor[8];
u8 board_info[8]; u8 board_info[8];
struct semaphore dst_mutex;
}; };
struct dst_types { struct dst_types {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment