Re: [PATCH 20/26] pctv452e: don't do DMA on stack
On Fri, 7 Oct 2016 14:24:30 -0300 Mauro Carvalho Chehab wrote: > 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. > > Signed-off-by: Mauro Carvalho Chehab > --- > drivers/media/usb/dvb-usb/pctv452e.c | 110 > ++- 1 file changed, 58 insertions(+), > 52 deletions(-) > > diff --git a/drivers/media/usb/dvb-usb/pctv452e.c > b/drivers/media/usb/dvb-usb/pctv452e.c index > c05de1b088a4..855fe9d34b59 100644 --- > a/drivers/media/usb/dvb-usb/pctv452e.c +++ > b/drivers/media/usb/dvb-usb/pctv452e.c @@ -97,13 +97,14 @@ struct > pctv452e_state { u8 c; /* transaction counter, wraps > around... */ u8 initialized; /* set to 1 if 0x15 has been sent */ > u16 last_rc_key; > + > + unsigned char data[80]; > }; > > static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data, >unsigned int write_len, unsigned int > read_len) { > struct pctv452e_state *state = (struct pctv452e_state > *)d->priv; > - u8 buf[64]; > u8 id; > unsigned int rlen; > int ret; > @@ -114,30 +115,30 @@ static int tt3650_ci_msg(struct dvb_usb_device > *d, u8 cmd, u8 *data, > id = state->c++; > > - buf[0] = SYNC_BYTE_OUT; > - buf[1] = id; > - buf[2] = cmd; > - buf[3] = write_len; > + state->data[0] = SYNC_BYTE_OUT; > + state->data[1] = id; > + state->data[2] = cmd; > + state->data[3] = write_len; > > - memcpy(buf + 4, data, write_len); > + memcpy(state->data + 4, data, write_len); > > rlen = (read_len > 0) ? 64 : 0; > - ret = dvb_usb_generic_rw(d, buf, 4 + write_len, > - buf, rlen, /* delay_ms */ 0); > + ret = dvb_usb_generic_rw(d, state->data, 4 + write_len, > + state->data, rlen, /* delay_ms */ > 0); if (0 != ret) > goto failed; > > ret = -EIO; > - if (SYNC_BYTE_IN != buf[0] || id != buf[1]) > + if (SYNC_BYTE_IN != state->data[0] || id != state->data[1]) > goto failed; > > - memcpy(data, buf + 4, read_len); > + memcpy(data, state->data + 4, read_len); > > return 0; > > failed: > err("CI error %d; %02X %02X %02X -> %*ph.", > - ret, SYNC_BYTE_OUT, id, cmd, 3, buf); > + ret, SYNC_BYTE_OUT, id, cmd, 3, state->data); > > return ret; > } > @@ -405,7 +406,6 @@ static int pctv452e_i2c_msg(struct dvb_usb_device > *d, u8 addr, u8 *rcv_buf, u8 rcv_len) > { > struct pctv452e_state *state = (struct pctv452e_state > *)d->priv; > - u8 buf[64]; > u8 id; > int ret; > > @@ -415,42 +415,40 @@ static int pctv452e_i2c_msg(struct > dvb_usb_device *d, u8 addr, if (snd_len > 64 - 7 || rcv_len > 64 - 7) > goto failed; > > - buf[0] = SYNC_BYTE_OUT; > - buf[1] = id; > - buf[2] = PCTV_CMD_I2C; > - buf[3] = snd_len + 3; > - buf[4] = addr << 1; > - buf[5] = snd_len; > - buf[6] = rcv_len; > + state->data[0] = SYNC_BYTE_OUT; > + state->data[1] = id; > + state->data[2] = PCTV_CMD_I2C; > + state->data[3] = snd_len + 3; > + state->data[4] = addr << 1; > + state->data[5] = snd_len; > + state->data[6] = rcv_len; > > - memcpy(buf + 7, snd_buf, snd_len); > + memcpy(state->data + 7, snd_buf, snd_len); > > - ret = dvb_usb_generic_rw(d, buf, 7 + snd_len, > - buf, /* rcv_len */ 64, > + ret = dvb_usb_generic_rw(d, state->data, 7 + snd_len, > + state->data, /* rcv_len */ 64, > /* delay_ms */ 0); > if (ret < 0) > goto failed; > > /* TT USB protocol error. */ > ret = -EIO; > - if (SYNC_BYTE_IN != buf[0] || id != buf[1]) > + if (SYNC_BYTE_IN != state->data[0] || id != state->data[1]) > goto failed; > > /* I2C device didn't respond as expected. */ > ret = -EREMOTEIO; > - if (buf[5] < snd_len || buf[6] < rcv_len) > + if (state->data[5] < snd_len || state->data[6] < rcv_len) > goto failed; > > - memcpy(rcv_buf, buf + 7, rcv_len); > + memcpy(rcv_buf, state->data + 7, rcv_len); > > return rcv_len; > > failed: > - err("I2C error %d; %02X %02X %02X %02X %02X -> " > - "%02X %02X %02X %02X %02X.", > + err("I2C error %d; %02X %02X %02X %02X %02X -> %*ph", >ret, SYNC_BYTE_OUT, id, addr << 1, snd_len, rcv_len, > - buf[0], buf[1], buf[4], buf[5], buf[6]); > - > + 7, state->data); > return ret; > } > > @@ -499,8 +497,7 @@ static u32 pctv452e_i2c_func(struct i2c_adapter > *adapter) static int pctv452e_power_ctrl(struct dvb_usb_device *d, > int i) { > struct pctv452e_state *state = (struct pctv452e_state > *)d->priv; > - u8 b0[] = { 0xaa, 0, PCTV_CMD_RESET, 1, 0 }; > - u8 rx[PCTV_
[PATCH 20/26] pctv452e: don't do DMA on stack
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. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/pctv452e.c | 110 ++- 1 file changed, 58 insertions(+), 52 deletions(-) diff --git a/drivers/media/usb/dvb-usb/pctv452e.c b/drivers/media/usb/dvb-usb/pctv452e.c index c05de1b088a4..855fe9d34b59 100644 --- a/drivers/media/usb/dvb-usb/pctv452e.c +++ b/drivers/media/usb/dvb-usb/pctv452e.c @@ -97,13 +97,14 @@ struct pctv452e_state { u8 c; /* transaction counter, wraps around... */ u8 initialized; /* set to 1 if 0x15 has been sent */ u16 last_rc_key; + + unsigned char data[80]; }; static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data, unsigned int write_len, unsigned int read_len) { struct pctv452e_state *state = (struct pctv452e_state *)d->priv; - u8 buf[64]; u8 id; unsigned int rlen; int ret; @@ -114,30 +115,30 @@ static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data, id = state->c++; - buf[0] = SYNC_BYTE_OUT; - buf[1] = id; - buf[2] = cmd; - buf[3] = write_len; + state->data[0] = SYNC_BYTE_OUT; + state->data[1] = id; + state->data[2] = cmd; + state->data[3] = write_len; - memcpy(buf + 4, data, write_len); + memcpy(state->data + 4, data, write_len); rlen = (read_len > 0) ? 64 : 0; - ret = dvb_usb_generic_rw(d, buf, 4 + write_len, - buf, rlen, /* delay_ms */ 0); + ret = dvb_usb_generic_rw(d, state->data, 4 + write_len, + state->data, rlen, /* delay_ms */ 0); if (0 != ret) goto failed; ret = -EIO; - if (SYNC_BYTE_IN != buf[0] || id != buf[1]) + if (SYNC_BYTE_IN != state->data[0] || id != state->data[1]) goto failed; - memcpy(data, buf + 4, read_len); + memcpy(data, state->data + 4, read_len); return 0; failed: err("CI error %d; %02X %02X %02X -> %*ph.", -ret, SYNC_BYTE_OUT, id, cmd, 3, buf); +ret, SYNC_BYTE_OUT, id, cmd, 3, state->data); return ret; } @@ -405,7 +406,6 @@ static int pctv452e_i2c_msg(struct dvb_usb_device *d, u8 addr, u8 *rcv_buf, u8 rcv_len) { struct pctv452e_state *state = (struct pctv452e_state *)d->priv; - u8 buf[64]; u8 id; int ret; @@ -415,42 +415,40 @@ static int pctv452e_i2c_msg(struct dvb_usb_device *d, u8 addr, if (snd_len > 64 - 7 || rcv_len > 64 - 7) goto failed; - buf[0] = SYNC_BYTE_OUT; - buf[1] = id; - buf[2] = PCTV_CMD_I2C; - buf[3] = snd_len + 3; - buf[4] = addr << 1; - buf[5] = snd_len; - buf[6] = rcv_len; + state->data[0] = SYNC_BYTE_OUT; + state->data[1] = id; + state->data[2] = PCTV_CMD_I2C; + state->data[3] = snd_len + 3; + state->data[4] = addr << 1; + state->data[5] = snd_len; + state->data[6] = rcv_len; - memcpy(buf + 7, snd_buf, snd_len); + memcpy(state->data + 7, snd_buf, snd_len); - ret = dvb_usb_generic_rw(d, buf, 7 + snd_len, - buf, /* rcv_len */ 64, + ret = dvb_usb_generic_rw(d, state->data, 7 + snd_len, + state->data, /* rcv_len */ 64, /* delay_ms */ 0); if (ret < 0) goto failed; /* TT USB protocol error. */ ret = -EIO; - if (SYNC_BYTE_IN != buf[0] || id != buf[1]) + if (SYNC_BYTE_IN != state->data[0] || id != state->data[1]) goto failed; /* I2C device didn't respond as expected. */ ret = -EREMOTEIO; - if (buf[5] < snd_len || buf[6] < rcv_len) + if (state->data[5] < snd_len || state->data[6] < rcv_len) goto failed; - memcpy(rcv_buf, buf + 7, rcv_len); + memcpy(rcv_buf, state->data + 7, rcv_len); return rcv_len; failed: - err("I2C error %d; %02X %02X %02X %02X %02X -> " -"%02X %02X %02X %02X %02X.", + err("I2C error %d; %02X %02X %02X %02X %02X -> %*ph", ret, SYNC_BYTE_OUT, id, addr << 1, snd_len, rcv_len, -buf[0], buf[1], buf[4], buf[5], buf[6]); - +7, state->data); return ret; } @@ -499,8 +497,7 @@ static u32 pctv452e_i2c_func(struct i2c_adapter *adapter) static int pctv452e_power_ctrl(struct dvb_usb_device *d, int i) { struct pctv452e_state *state = (struct pctv452e_state *)d->priv; - u8 b0[] = { 0xaa, 0, PCTV_CMD_RESET, 1, 0 }; - u8 rx[PCTV_ANSWER_LEN]; + u8 *rx; int ret; info("%s: %d\n", __func__, i); @@ -511,6 +508,10 @@ static i