Skip to content

Commit

Permalink
[media] cinergyT2-fe: don't do DMA on stack
Browse files Browse the repository at this point in the history
The USB control messages require DMA to work. We cannot pass
a stack-allocated buffer, as it is not warranted that the
stack would be into a DMA enabled area.

Reviewed-by: Patrick Boettcher <patrick.boettcher@posteo.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
  • Loading branch information
Mauro Carvalho Chehab committed Oct 14, 2016
1 parent c2730ee commit 0d43c0f
Showing 1 changed file with 33 additions and 23 deletions.
56 changes: 33 additions & 23 deletions drivers/media/usb/dvb-usb/cinergyT2-fe.c
Original file line number Diff line number Diff line change
@@ -139,35 +139,42 @@ static uint16_t compute_tps(struct dtv_frontend_properties *op)
struct cinergyt2_fe_state {
struct dvb_frontend fe;
struct dvb_usb_device *d;

unsigned char data[64];
struct mutex data_mutex;

struct dvbt_get_status_msg status;
};

static int cinergyt2_fe_read_status(struct dvb_frontend *fe,
enum fe_status *status)
{
struct cinergyt2_fe_state *state = fe->demodulator_priv;
struct dvbt_get_status_msg result;
u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
int ret;

ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&result,
sizeof(result), 0);
mutex_lock(&state->data_mutex);
state->data[0] = CINERGYT2_EP1_GET_TUNER_STATUS;

ret = dvb_usb_generic_rw(state->d, state->data, 1,
state->data, sizeof(state->status), 0);
if (!ret)
memcpy(&state->status, state->data, sizeof(state->status));
mutex_unlock(&state->data_mutex);

if (ret < 0)
return ret;

state->status = result;

*status = 0;

if (0xffff - le16_to_cpu(result.gain) > 30)
if (0xffff - le16_to_cpu(state->status.gain) > 30)
*status |= FE_HAS_SIGNAL;
if (result.lock_bits & (1 << 6))
if (state->status.lock_bits & (1 << 6))
*status |= FE_HAS_LOCK;
if (result.lock_bits & (1 << 5))
if (state->status.lock_bits & (1 << 5))
*status |= FE_HAS_SYNC;
if (result.lock_bits & (1 << 4))
if (state->status.lock_bits & (1 << 4))
*status |= FE_HAS_CARRIER;
if (result.lock_bits & (1 << 1))
if (state->status.lock_bits & (1 << 1))
*status |= FE_HAS_VITERBI;

if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
@@ -232,34 +239,36 @@ static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe)
{
struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
struct cinergyt2_fe_state *state = fe->demodulator_priv;
struct dvbt_set_parameters_msg param;
char result[2];
struct dvbt_set_parameters_msg *param;
int err;

param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
param.tps = cpu_to_le16(compute_tps(fep));
param.freq = cpu_to_le32(fep->frequency / 1000);
param.flags = 0;
mutex_lock(&state->data_mutex);

param = (void *)state->data;
param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
param->tps = cpu_to_le16(compute_tps(fep));
param->freq = cpu_to_le32(fep->frequency / 1000);
param->flags = 0;

switch (fep->bandwidth_hz) {
default:
case 8000000:
param.bandwidth = 8;
param->bandwidth = 8;
break;
case 7000000:
param.bandwidth = 7;
param->bandwidth = 7;
break;
case 6000000:
param.bandwidth = 6;
param->bandwidth = 6;
break;
}

err = dvb_usb_generic_rw(state->d,
(char *)&param, sizeof(param),
result, sizeof(result), 0);
err = dvb_usb_generic_rw(state->d, state->data, sizeof(*param),
state->data, 2, 0);
if (err < 0)
err("cinergyt2_fe_set_frontend() Failed! err=%d\n", err);

mutex_unlock(&state->data_mutex);
return (err < 0) ? err : 0;
}

@@ -281,6 +290,7 @@ struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d)
s->d = d;
memcpy(&s->fe.ops, &cinergyt2_fe_ops, sizeof(struct dvb_frontend_ops));
s->fe.demodulator_priv = s;
mutex_init(&s->data_mutex);
return &s->fe;
}

0 comments on commit 0d43c0f

Please sign in to comment.