Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1497395 > unrolled thread

[PATCH 00/26] Don't use stack for DMA transers on dvb-usb drivers

Started byMauro Carvalho Chehab <mchehab@s-opensource.com>
First post2016-10-07 19:30 +0200
Last post2016-10-07 19:40 +0200
Articles 20 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH 00/26] Don't use stack for DMA transers on dvb-usb drivers Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-07 19:30 +0200
    [PATCH 21/26] pctv452e: don't call BUG_ON() on non-fatal error Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-07 19:30 +0200
      [PATCH v2 21/26] pctv452e: don't call BUG_ON() on non-fatal error Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-08 12:20 +0200
    [PATCH 26/26] digitv: handle error code on RC query Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-07 19:30 +0200
    [PATCH 06/26] cxusb: don't do DMA on stack Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-07 19:30 +0200
      Re: [PATCH 06/26] cxusb: don't do DMA on stack Patrick Boettcher <patrick.boettcher@posteo.de> - 2016-10-10 08:40 +0200
    [PATCH 01/26] af9005: don't do DMA on stack Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-07 19:30 +0200
    [PATCH 11/26] digitv: don't do DMA on stack Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-07 19:30 +0200
      Re: [PATCH 11/26] digitv: don't do DMA on stack Patrick Boettcher <patrick.boettcher@posteo.de> - 2016-10-10 08:40 +0200
    [PATCH 02/26] cinergyT2-core: don't do DMA on stack Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-07 19:30 +0200
      Re: [PATCH 02/26] cinergyT2-core: don't do DMA on stack Patrick Boettcher <patrick.boettcher@posteo.de> - 2016-10-10 08:40 +0200
    [PATCH 15/26] dtt200u: handle USB control message errors Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-07 19:30 +0200
    [PATCH 14/26] dtt200u: don't do DMA on stack Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-07 19:30 +0200
      Re: [PATCH 14/26] dtt200u: don't do DMA on stack Patrick Boettcher <patrick.boettcher@posteo.de> - 2016-10-10 08:40 +0200
    [PATCH 04/26] cinergyT2-fe: cache stats at cinergyt2_fe_read_status() Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-07 19:30 +0200
    [PATCH 18/26] gp8psk: don't go past the buffer size Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-07 19:30 +0200
    [PATCH 07/26] dib0700: be sure that dib0700_ctrl_rd() users can do DMA Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-07 19:40 +0200
      Re: [PATCH 07/26] dib0700: be sure that dib0700_ctrl_rd() users can  do DMA Patrick Boettcher <patrick.boettcher@posteo.de> - 2016-10-10 08:40 +0200
    [PATCH 17/26] gp8psk: don't do DMA on stack Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-07 19:40 +0200
    [PATCH 23/26] dvb-usb: warn if return value for USB read/write routines is not checked Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-07 19:40 +0200

#1497395 — [PATCH 00/26] Don't use stack for DMA transers on dvb-usb drivers

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-07 19:30 +0200
Subject[PATCH 00/26] Don't use stack for DMA transers on dvb-usb drivers
Message-ID<spH85-3EG-5@gated-at.bofh.it>
Sending URB control messages from stack was never supported. Yet, on x86,
the stack was usually at a memory region that allows DMA transfer.

So, several drivers got it wrong. On Kernel 4.9, if VMAP_STACK=y, none of
those drivers will work, as the stack won't be on a DMA-able area anymore.

So, fix the dvb-usb drivers that requre it.

Please notice that, while all those patches compile, I don't have devices
using those drivers to test. So, I really appreciate if people with devices
using those drivers could test and report if they don't break anything.

Thanks!
Mauro

Mauro Carvalho Chehab (26):
  af9005: don't do DMA on stack
  cinergyT2-core: don't do DMA on stack
  cinergyT2-core:: handle error code on RC query
  cinergyT2-fe: cache stats at cinergyt2_fe_read_status()
  cinergyT2-fe: don't do DMA on stack
  cxusb: don't do DMA on stack
  dib0700: be sure that dib0700_ctrl_rd() users can do DMA
  dib0700_core: don't use stack on I2C reads
  dibusb: don't do DMA on stack
  dibusb: handle error code on RC query
  digitv: don't do DMA on stack
  dtt200u-fe: don't do DMA on stack
  dtt200u-fe: handle errors on USB control messages
  dtt200u: don't do DMA on stack
  dtt200u: handle USB control message errors
  dtv5100: : don't do DMA on stack
  gp8psk: don't do DMA on stack
  gp8psk: don't go past the buffer size
  nova-t-usb2: don't do DMA on stack
  pctv452e: don't do DMA on stack
  pctv452e: don't call BUG_ON() on non-fatal error
  technisat-usb2: use DMA buffers for I2C transfers
  dvb-usb: warn if return value for USB read/write routines is not
    checked
  nova-t-usb2: handle error code on RC query
  dw2102: return error if su3000_power_ctrl() fails
  digitv: handle error code on RC query

 drivers/media/usb/dvb-usb/af9005.c          | 211 +++++++++++++++-------------
 drivers/media/usb/dvb-usb/cinergyT2-core.c  |  52 ++++---
 drivers/media/usb/dvb-usb/cinergyT2-fe.c    |  91 ++++--------
 drivers/media/usb/dvb-usb/cxusb.c           |  20 +--
 drivers/media/usb/dvb-usb/cxusb.h           |   5 +
 drivers/media/usb/dvb-usb/dib0700_core.c    |  31 +++-
 drivers/media/usb/dvb-usb/dib0700_devices.c |  25 ++--
 drivers/media/usb/dvb-usb/dibusb-common.c   | 112 +++++++++++----
 drivers/media/usb/dvb-usb/dibusb.h          |   5 +
 drivers/media/usb/dvb-usb/digitv.c          |  26 ++--
 drivers/media/usb/dvb-usb/digitv.h          |   3 +
 drivers/media/usb/dvb-usb/dtt200u-fe.c      |  90 ++++++++----
 drivers/media/usb/dvb-usb/dtt200u.c         |  80 +++++++----
 drivers/media/usb/dvb-usb/dtv5100.c         |  10 +-
 drivers/media/usb/dvb-usb/dvb-usb.h         |   6 +-
 drivers/media/usb/dvb-usb/dw2102.c          |   2 +-
 drivers/media/usb/dvb-usb/gp8psk.c          |  25 +++-
 drivers/media/usb/dvb-usb/nova-t-usb2.c     |  25 +++-
 drivers/media/usb/dvb-usb/pctv452e.c        | 118 ++++++++--------
 drivers/media/usb/dvb-usb/technisat-usb2.c  |  16 ++-
 20 files changed, 577 insertions(+), 376 deletions(-)

-- 
2.7.4

[toc] | [next] | [standalone]


#1497396 — [PATCH 21/26] pctv452e: don't call BUG_ON() on non-fatal error

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-07 19:30 +0200
Subject[PATCH 21/26] pctv452e: don't call BUG_ON() on non-fatal error
Message-ID<spH85-3EG-31@gated-at.bofh.it>
In reply to#1497395
There are some conditions on this driver that are tested with
BUG_ON() with are not serious enough to hang a machine.

So, just return an error if this happens.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
 drivers/media/usb/dvb-usb/pctv452e.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/media/usb/dvb-usb/pctv452e.c b/drivers/media/usb/dvb-usb/pctv452e.c
index 855fe9d34b59..14bd927c50d8 100644
--- a/drivers/media/usb/dvb-usb/pctv452e.c
+++ b/drivers/media/usb/dvb-usb/pctv452e.c
@@ -109,9 +109,11 @@ static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data,
 	unsigned int rlen;
 	int ret;
 
-	BUG_ON(NULL == data && 0 != (write_len | read_len));
-	BUG_ON(write_len > 64 - 4);
-	BUG_ON(read_len > 64 - 4);
+	if (NULL == data && 0 != (write_len | read_len) ||
+	    write_len > 64 - 4) || (read_len > 64 - 4)) {
+		ret = -EIO;
+		goto failed;
+	};
 
 	id = state->c++;
 
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1497698 — [PATCH v2 21/26] pctv452e: don't call BUG_ON() on non-fatal error

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-08 12:20 +0200
Subject[PATCH v2 21/26] pctv452e: don't call BUG_ON() on non-fatal error
Message-ID<spWTv-5OG-9@gated-at.bofh.it>
In reply to#1497396
There are some conditions on this driver that are tested with
BUG_ON() with are not serious enough to hang a machine.

So, just return an error if this happens.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---

v2: simplify the logic and use its own error message.


 drivers/media/usb/dvb-usb/pctv452e.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/media/usb/dvb-usb/pctv452e.c b/drivers/media/usb/dvb-usb/pctv452e.c
index 855fe9d34b59..f70202e6e3eb 100644
--- a/drivers/media/usb/dvb-usb/pctv452e.c
+++ b/drivers/media/usb/dvb-usb/pctv452e.c
@@ -109,9 +109,10 @@ static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data,
 	unsigned int rlen;
 	int ret;
 
-	BUG_ON(NULL == data && 0 != (write_len | read_len));
-	BUG_ON(write_len > 64 - 4);
-	BUG_ON(read_len > 64 - 4);
+	if (!data || (write_len > 64 - 4) || (read_len > 64 - 4)) {
+		err("%s: transfer data invalid", __func__);
+		return -EIO;
+	};
 
 	id = state->c++;
 
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1497397 — [PATCH 26/26] digitv: handle error code on RC query

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-07 19:30 +0200
Subject[PATCH 26/26] digitv: handle error code on RC query
Message-ID<spH86-3EG-37@gated-at.bofh.it>
In reply to#1497395
There's no sense on decoding and generating a RC key code if
there was an error on the URB control message.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
 drivers/media/usb/dvb-usb/digitv.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/media/usb/dvb-usb/digitv.c b/drivers/media/usb/dvb-usb/digitv.c
index 09f8c28bd4db..4284f6984dc1 100644
--- a/drivers/media/usb/dvb-usb/digitv.c
+++ b/drivers/media/usb/dvb-usb/digitv.c
@@ -29,7 +29,9 @@ static int digitv_ctrl_msg(struct dvb_usb_device *d,
 		u8 cmd, u8 vv, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
 {
 	struct digitv_state *st = d->priv;
-	int wo = (rbuf == NULL || rlen == 0); /* write-only */
+	int ret, wo;
+
+	wo = (rbuf == NULL || rlen == 0); /* write-only */
 
 	memset(st->sndbuf, 0, 7);
 	memset(st->rcvbuf, 0, 7);
@@ -40,12 +42,12 @@ static int digitv_ctrl_msg(struct dvb_usb_device *d,
 
 	if (wo) {
 		memcpy(&st->sndbuf[3], wbuf, wlen);
-		dvb_usb_generic_write(d, st->sndbuf, 7);
+		ret = dvb_usb_generic_write(d, st->sndbuf, 7);
 	} else {
-		dvb_usb_generic_rw(d, st->sndbuf, 7, st->rcvbuf, 7, 10);
+		ret = dvb_usb_generic_rw(d, st->sndbuf, 7, st->rcvbuf, 7, 10);
 		memcpy(rbuf, &st->rcvbuf[3], rlen);
 	}
-	return 0;
+	return ret;
 }
 
 /* I2C */
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1497398 — [PATCH 06/26] cxusb: don't do DMA on stack

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-07 19:30 +0200
Subject[PATCH 06/26] cxusb: don't do DMA on stack
Message-ID<spH86-3EG-47@gated-at.bofh.it>
In reply to#1497395
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 <mchehab@s-opensource.com>
---
 drivers/media/usb/dvb-usb/cxusb.c | 20 +++++++-------------
 drivers/media/usb/dvb-usb/cxusb.h |  5 +++++
 2 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c
index 907ac01ae297..f3615349de52 100644
--- a/drivers/media/usb/dvb-usb/cxusb.c
+++ b/drivers/media/usb/dvb-usb/cxusb.c
@@ -45,9 +45,6 @@
 #include "si2168.h"
 #include "si2157.h"
 
-/* Max transfer size done by I2C transfer functions */
-#define MAX_XFER_SIZE  80
-
 /* debug */
 static int dvb_usb_cxusb_debug;
 module_param_named(debug, dvb_usb_cxusb_debug, int, 0644);
@@ -61,23 +58,20 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 static int cxusb_ctrl_msg(struct dvb_usb_device *d,
 			  u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
 {
+	struct cxusb_state *st = d->priv;
 	int wo = (rbuf == NULL || rlen == 0); /* write-only */
-	u8 sndbuf[MAX_XFER_SIZE];
 
-	if (1 + wlen > sizeof(sndbuf)) {
-		warn("i2c wr: len=%d is too big!\n",
-		     wlen);
+	if (1 + wlen > MAX_XFER_SIZE) {
+		warn("i2c wr: len=%d is too big!\n", wlen);
 		return -EOPNOTSUPP;
 	}
 
-	memset(sndbuf, 0, 1+wlen);
-
-	sndbuf[0] = cmd;
-	memcpy(&sndbuf[1], wbuf, wlen);
+	st->data[0] = cmd;
+	memcpy(&st->data[1], wbuf, wlen);
 	if (wo)
-		return dvb_usb_generic_write(d, sndbuf, 1+wlen);
+		return dvb_usb_generic_write(d, st->data, 1 + wlen);
 	else
-		return dvb_usb_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen, 0);
+		return dvb_usb_generic_rw(d, st->data, 1 + wlen, rbuf, rlen, 0);
 }
 
 /* GPIO */
diff --git a/drivers/media/usb/dvb-usb/cxusb.h b/drivers/media/usb/dvb-usb/cxusb.h
index 527ff7905e15..18acda19527a 100644
--- a/drivers/media/usb/dvb-usb/cxusb.h
+++ b/drivers/media/usb/dvb-usb/cxusb.h
@@ -28,10 +28,15 @@
 #define CMD_ANALOG        0x50
 #define CMD_DIGITAL       0x51
 
+/* Max transfer size done by I2C transfer functions */
+#define MAX_XFER_SIZE  80
+
 struct cxusb_state {
 	u8 gpio_write_state[3];
 	struct i2c_client *i2c_client_demod;
 	struct i2c_client *i2c_client_tuner;
+
+	unsigned char data[MAX_XFER_SIZE];
 };
 
 #endif
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1498125 — Re: [PATCH 06/26] cxusb: don't do DMA on stack

FromPatrick Boettcher <patrick.boettcher@posteo.de>
Date2016-10-10 08:40 +0200
SubjectRe: [PATCH 06/26] cxusb: don't do DMA on stack
Message-ID<sqCpH-6ic-11@gated-at.bofh.it>
In reply to#1497398
On Fri,  7 Oct 2016 14:24:16 -0300
Mauro Carvalho Chehab <mchehab@s-opensource.com> 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 <mchehab@s-opensource.com>
> ---
>  drivers/media/usb/dvb-usb/cxusb.c | 20 +++++++-------------
>  drivers/media/usb/dvb-usb/cxusb.h |  5 +++++
>  2 files changed, 12 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/media/usb/dvb-usb/cxusb.c
> b/drivers/media/usb/dvb-usb/cxusb.c index 907ac01ae297..f3615349de52
> 100644 --- a/drivers/media/usb/dvb-usb/cxusb.c
> +++ b/drivers/media/usb/dvb-usb/cxusb.c
> @@ -45,9 +45,6 @@
>  #include "si2168.h"
>  #include "si2157.h"
>  
> -/* Max transfer size done by I2C transfer functions */
> -#define MAX_XFER_SIZE  80
> -
>  /* debug */
>  static int dvb_usb_cxusb_debug;
>  module_param_named(debug, dvb_usb_cxusb_debug, int, 0644);
> @@ -61,23 +58,20 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
>  static int cxusb_ctrl_msg(struct dvb_usb_device *d,
>  			  u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int
> rlen) {
> +	struct cxusb_state *st = d->priv;
>  	int wo = (rbuf == NULL || rlen == 0); /* write-only */
> -	u8 sndbuf[MAX_XFER_SIZE];
>  
> -	if (1 + wlen > sizeof(sndbuf)) {
> -		warn("i2c wr: len=%d is too big!\n",
> -		     wlen);
> +	if (1 + wlen > MAX_XFER_SIZE) {
> +		warn("i2c wr: len=%d is too big!\n", wlen);
>  		return -EOPNOTSUPP;
>  	}
>  
> -	memset(sndbuf, 0, 1+wlen);
> -
> -	sndbuf[0] = cmd;
> -	memcpy(&sndbuf[1], wbuf, wlen);
> +	st->data[0] = cmd;
> +	memcpy(&st->data[1], wbuf, wlen);
>  	if (wo)
> -		return dvb_usb_generic_write(d, sndbuf, 1+wlen);
> +		return dvb_usb_generic_write(d, st->data, 1 + wlen);
>  	else
> -		return dvb_usb_generic_rw(d, sndbuf, 1+wlen, rbuf,
> rlen, 0);
> +		return dvb_usb_generic_rw(d, st->data, 1 + wlen,
> rbuf, rlen, 0); }
>  
>  /* GPIO */
> diff --git a/drivers/media/usb/dvb-usb/cxusb.h
> b/drivers/media/usb/dvb-usb/cxusb.h index 527ff7905e15..18acda19527a
> 100644 --- a/drivers/media/usb/dvb-usb/cxusb.h
> +++ b/drivers/media/usb/dvb-usb/cxusb.h
> @@ -28,10 +28,15 @@
>  #define CMD_ANALOG        0x50
>  #define CMD_DIGITAL       0x51
>  
> +/* Max transfer size done by I2C transfer functions */
> +#define MAX_XFER_SIZE  80
> +
>  struct cxusb_state {
>  	u8 gpio_write_state[3];
>  	struct i2c_client *i2c_client_demod;
>  	struct i2c_client *i2c_client_tuner;
> +
> +	unsigned char data[MAX_XFER_SIZE];
>  };
>  
>  #endif

Reviewed-By: Patrick Boettcher <patrick.boettcher@posteo.de>

[toc] | [prev] | [next] | [standalone]


#1497399 — [PATCH 01/26] af9005: don't do DMA on stack

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-07 19:30 +0200
Subject[PATCH 01/26] af9005: don't do DMA on stack
Message-ID<spH86-3EG-53@gated-at.bofh.it>
In reply to#1497395
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 <mchehab@s-opensource.com>
---
 drivers/media/usb/dvb-usb/af9005.c | 211 +++++++++++++++++++------------------
 1 file changed, 111 insertions(+), 100 deletions(-)

diff --git a/drivers/media/usb/dvb-usb/af9005.c b/drivers/media/usb/dvb-usb/af9005.c
index efa782ed6e2d..cc5815de1cfb 100644
--- a/drivers/media/usb/dvb-usb/af9005.c
+++ b/drivers/media/usb/dvb-usb/af9005.c
@@ -52,17 +52,15 @@ u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
 struct af9005_device_state {
 	u8 sequence;
 	int led_state;
+	unsigned char data[256];
 };
 
 static int af9005_generic_read_write(struct dvb_usb_device *d, u16 reg,
 			      int readwrite, int type, u8 * values, int len)
 {
 	struct af9005_device_state *st = d->priv;
-	u8 obuf[16] = { 0 };
-	u8 ibuf[17] = { 0 };
-	u8 command;
-	int i;
-	int ret;
+	u8 command, seq;
+	int i, ret;
 
 	if (len < 1) {
 		err("generic read/write, less than 1 byte. Makes no sense.");
@@ -73,16 +71,16 @@ static int af9005_generic_read_write(struct dvb_usb_device *d, u16 reg,
 		return -EINVAL;
 	}
 
-	obuf[0] = 14;		/* rest of buffer length low */
-	obuf[1] = 0;		/* rest of buffer length high */
+	st->data[0] = 14;		/* rest of buffer length low */
+	st->data[1] = 0;		/* rest of buffer length high */
 
-	obuf[2] = AF9005_REGISTER_RW;	/* register operation */
-	obuf[3] = 12;		/* rest of buffer length */
+	st->data[2] = AF9005_REGISTER_RW;	/* register operation */
+	st->data[3] = 12;		/* rest of buffer length */
 
-	obuf[4] = st->sequence++;	/* sequence number */
+	st->data[4] = seq = st->sequence++;	/* sequence number */
 
-	obuf[5] = (u8) (reg >> 8);	/* register address */
-	obuf[6] = (u8) (reg & 0xff);
+	st->data[5] = (u8) (reg >> 8);	/* register address */
+	st->data[6] = (u8) (reg & 0xff);
 
 	if (type == AF9005_OFDM_REG) {
 		command = AF9005_CMD_OFDM_REG;
@@ -96,49 +94,43 @@ static int af9005_generic_read_write(struct dvb_usb_device *d, u16 reg,
 	command |= readwrite;
 	if (readwrite == AF9005_CMD_WRITE)
 		for (i = 0; i < len; i++)
-			obuf[8 + i] = values[i];
+			st->data[8 + i] = values[i];
 	else if (type == AF9005_TUNER_REG)
 		/* read command for tuner, the first byte contains the i2c address */
-		obuf[8] = values[0];
-	obuf[7] = command;
+		st->data[8] = values[0];
+	st->data[7] = command;
 
-	ret = dvb_usb_generic_rw(d, obuf, 16, ibuf, 17, 0);
+	ret = dvb_usb_generic_rw(d, st->data, 16, st->data, 17, 0);
 	if (ret)
 		return ret;
 
 	/* sanity check */
-	if (ibuf[2] != AF9005_REGISTER_RW_ACK) {
+	if (st->data[2] != AF9005_REGISTER_RW_ACK) {
 		err("generic read/write, wrong reply code.");
 		return -EIO;
 	}
-	if (ibuf[3] != 0x0d) {
+	if (st->data[3] != 0x0d) {
 		err("generic read/write, wrong length in reply.");
 		return -EIO;
 	}
-	if (ibuf[4] != obuf[4]) {
+	if (st->data[4] != seq) {
 		err("generic read/write, wrong sequence in reply.");
 		return -EIO;
 	}
 	/*
-	   Windows driver doesn't check these fields, in fact sometimes
-	   the register in the reply is different that what has been sent
-
-	   if (ibuf[5] != obuf[5] || ibuf[6] != obuf[6]) {
-	   err("generic read/write, wrong register in reply.");
-	   return -EIO;
-	   }
-	   if (ibuf[7] != command) {
-	   err("generic read/write wrong command in reply.");
-	   return -EIO;
-	   }
+	 * In thesis, both input and output buffers should have
+	 * identical values for st->data[5] to st->data[8].
+	 * However, windows driver doesn't check these fields, in fact
+	 * sometimes the register in the reply is different that what
+	 * has been sent
 	 */
-	if (ibuf[16] != 0x01) {
+	if (st->data[16] != 0x01) {
 		err("generic read/write wrong status code in reply.");
 		return -EIO;
 	}
 	if (readwrite == AF9005_CMD_READ)
 		for (i = 0; i < len; i++)
-			values[i] = ibuf[8 + i];
+			values[i] = st->data[8 + i];
 
 	return 0;
 
@@ -464,8 +456,7 @@ int af9005_send_command(struct dvb_usb_device *d, u8 command, u8 * wbuf,
 	struct af9005_device_state *st = d->priv;
 
 	int ret, i, packet_len;
-	u8 buf[64];
-	u8 ibuf[64];
+	u8 seq;
 
 	if (wlen < 0) {
 		err("send command, wlen less than 0 bytes. Makes no sense.");
@@ -480,37 +471,37 @@ int af9005_send_command(struct dvb_usb_device *d, u8 command, u8 * wbuf,
 		return -EINVAL;
 	}
 	packet_len = wlen + 5;
-	buf[0] = (u8) (packet_len & 0xff);
-	buf[1] = (u8) ((packet_len & 0xff00) >> 8);
+	st->data[0] = (u8) (packet_len & 0xff);
+	st->data[1] = (u8) ((packet_len & 0xff00) >> 8);
 
-	buf[2] = 0x26;		/* packet type */
-	buf[3] = wlen + 3;
-	buf[4] = st->sequence++;
-	buf[5] = command;
-	buf[6] = wlen;
+	st->data[2] = 0x26;		/* packet type */
+	st->data[3] = wlen + 3;
+	st->data[4] = seq = st->sequence++;
+	st->data[5] = command;
+	st->data[6] = wlen;
 	for (i = 0; i < wlen; i++)
-		buf[7 + i] = wbuf[i];
-	ret = dvb_usb_generic_rw(d, buf, wlen + 7, ibuf, rlen + 7, 0);
+		st->data[7 + i] = wbuf[i];
+	ret = dvb_usb_generic_rw(d, st->data, wlen + 7, st->data, rlen + 7, 0);
 	if (ret)
 		return ret;
-	if (ibuf[2] != 0x27) {
+	if (st->data[2] != 0x27) {
 		err("send command, wrong reply code.");
 		return -EIO;
 	}
-	if (ibuf[4] != buf[4]) {
+	if (st->data[4] != seq) {
 		err("send command, wrong sequence in reply.");
 		return -EIO;
 	}
-	if (ibuf[5] != 0x01) {
+	if (st->data[5] != 0x01) {
 		err("send command, wrong status code in reply.");
 		return -EIO;
 	}
-	if (ibuf[6] != rlen) {
+	if (st->data[6] != rlen) {
 		err("send command, invalid data length in reply.");
 		return -EIO;
 	}
 	for (i = 0; i < rlen; i++)
-		rbuf[i] = ibuf[i + 7];
+		rbuf[i] = st->data[i + 7];
 	return 0;
 }
 
@@ -518,56 +509,56 @@ int af9005_read_eeprom(struct dvb_usb_device *d, u8 address, u8 * values,
 		       int len)
 {
 	struct af9005_device_state *st = d->priv;
-	u8 obuf[16], ibuf[14];
+	u8 seq;
 	int ret, i;
 
-	memset(obuf, 0, sizeof(obuf));
-	memset(ibuf, 0, sizeof(ibuf));
+	memset(st->data, 0, sizeof(st->data));
 
-	obuf[0] = 14;		/* length of rest of packet low */
-	obuf[1] = 0;		/* length of rest of packer high */
+	st->data[0] = 14;		/* length of rest of packet low */
+	st->data[1] = 0;		/* length of rest of packer high */
 
-	obuf[2] = 0x2a;		/* read/write eeprom */
+	st->data[2] = 0x2a;		/* read/write eeprom */
 
-	obuf[3] = 12;		/* size */
+	st->data[3] = 12;		/* size */
 
-	obuf[4] = st->sequence++;
+	st->data[4] = seq = st->sequence++;
 
-	obuf[5] = 0;		/* read */
+	st->data[5] = 0;		/* read */
 
-	obuf[6] = len;
-	obuf[7] = address;
-	ret = dvb_usb_generic_rw(d, obuf, 16, ibuf, 14, 0);
+	st->data[6] = len;
+	st->data[7] = address;
+	ret = dvb_usb_generic_rw(d, st->data, 16, st->data, 14, 0);
 	if (ret)
 		return ret;
-	if (ibuf[2] != 0x2b) {
+	if (st->data[2] != 0x2b) {
 		err("Read eeprom, invalid reply code");
 		return -EIO;
 	}
-	if (ibuf[3] != 10) {
+	if (st->data[3] != 10) {
 		err("Read eeprom, invalid reply length");
 		return -EIO;
 	}
-	if (ibuf[4] != obuf[4]) {
+	if (st->data[4] != seq) {
 		err("Read eeprom, wrong sequence in reply ");
 		return -EIO;
 	}
-	if (ibuf[5] != 1) {
+	if (st->data[5] != 1) {
 		err("Read eeprom, wrong status in reply ");
 		return -EIO;
 	}
 	for (i = 0; i < len; i++) {
-		values[i] = ibuf[6 + i];
+		values[i] = st->data[6 + i];
 	}
 	return 0;
 }
 
-static int af9005_boot_packet(struct usb_device *udev, int type, u8 * reply)
+static int af9005_boot_packet(struct usb_device *udev, int type, u8 *reply,
+			      u8 *buf, int size)
 {
-	u8 buf[FW_BULKOUT_SIZE + 2];
 	u16 checksum;
 	int act_len, i, ret;
-	memset(buf, 0, sizeof(buf));
+
+	memset(buf, 0, size);
 	buf[0] = (u8) (FW_BULKOUT_SIZE & 0xff);
 	buf[1] = (u8) ((FW_BULKOUT_SIZE >> 8) & 0xff);
 	switch (type) {
@@ -720,15 +711,21 @@ static int af9005_download_firmware(struct usb_device *udev, const struct firmwa
 {
 	int i, packets, ret, act_len;
 
-	u8 buf[FW_BULKOUT_SIZE + 2];
+	u8 *buf;
 	u8 reply;
 
-	ret = af9005_boot_packet(udev, FW_CONFIG, &reply);
+	buf = kmalloc(FW_BULKOUT_SIZE + 2, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	ret = af9005_boot_packet(udev, FW_CONFIG, &reply, buf,
+				 FW_BULKOUT_SIZE + 2);
 	if (ret)
-		return ret;
+		goto err;
 	if (reply != 0x01) {
 		err("before downloading firmware, FW_CONFIG expected 0x01, received 0x%x", reply);
-		return -EIO;
+		ret = -EIO;
+		goto err;
 	}
 	packets = fw->size / FW_BULKOUT_SIZE;
 	buf[0] = (u8) (FW_BULKOUT_SIZE & 0xff);
@@ -743,28 +740,35 @@ static int af9005_download_firmware(struct usb_device *udev, const struct firmwa
 				   buf, FW_BULKOUT_SIZE + 2, &act_len, 1000);
 		if (ret) {
 			err("firmware download failed at packet %d with code %d", i, ret);
-			return ret;
+			goto err;
 		}
 	}
-	ret = af9005_boot_packet(udev, FW_CONFIRM, &reply);
+	ret = af9005_boot_packet(udev, FW_CONFIRM, &reply,
+				 buf, FW_BULKOUT_SIZE + 2);
 	if (ret)
-		return ret;
+		goto err;
 	if (reply != (u8) (packets & 0xff)) {
 		err("after downloading firmware, FW_CONFIRM expected 0x%x, received 0x%x", packets & 0xff, reply);
-		return -EIO;
+		ret = -EIO;
+		goto err;
 	}
-	ret = af9005_boot_packet(udev, FW_BOOT, &reply);
+	ret = af9005_boot_packet(udev, FW_BOOT, &reply, buf,
+				 FW_BULKOUT_SIZE + 2);
 	if (ret)
-		return ret;
-	ret = af9005_boot_packet(udev, FW_CONFIG, &reply);
+		goto err;
+	ret = af9005_boot_packet(udev, FW_CONFIG, &reply, buf,
+				 FW_BULKOUT_SIZE + 2);
 	if (ret)
-		return ret;
+		goto err;
 	if (reply != 0x02) {
 		err("after downloading firmware, FW_CONFIG expected 0x02, received 0x%x", reply);
-		return -EIO;
+		ret = -EIO;
+		goto err;
 	}
 
-	return 0;
+err:
+	kfree(buf);
+	return ret;
 
 }
 
@@ -823,9 +827,7 @@ static int af9005_rc_query(struct dvb_usb_device *d, u32 * event, int *state)
 {
 	struct af9005_device_state *st = d->priv;
 	int ret, len;
-
-	u8 obuf[5];
-	u8 ibuf[256];
+	u8 seq;
 
 	*state = REMOTE_NO_KEY_PRESSED;
 	if (rc_decode == NULL) {
@@ -833,33 +835,33 @@ static int af9005_rc_query(struct dvb_usb_device *d, u32 * event, int *state)
 		return 0;
 	}
 	/* deb_info("rc_query\n"); */
-	obuf[0] = 3;		/* rest of packet length low */
-	obuf[1] = 0;		/* rest of packet lentgh high */
-	obuf[2] = 0x40;		/* read remote */
-	obuf[3] = 1;		/* rest of packet length */
-	obuf[4] = st->sequence++;	/* sequence number */
-	ret = dvb_usb_generic_rw(d, obuf, 5, ibuf, 256, 0);
+	st->data[0] = 3;		/* rest of packet length low */
+	st->data[1] = 0;		/* rest of packet lentgh high */
+	st->data[2] = 0x40;		/* read remote */
+	st->data[3] = 1;		/* rest of packet length */
+	st->data[4] = seq = st->sequence++;	/* sequence number */
+	ret = dvb_usb_generic_rw(d, st->data, 5, st->data, 256, 0);
 	if (ret) {
 		err("rc query failed");
 		return ret;
 	}
-	if (ibuf[2] != 0x41) {
+	if (st->data[2] != 0x41) {
 		err("rc query bad header.");
 		return -EIO;
 	}
-	if (ibuf[4] != obuf[4]) {
+	if (st->data[4] != seq) {
 		err("rc query bad sequence.");
 		return -EIO;
 	}
-	len = ibuf[5];
+	len = st->data[5];
 	if (len > 246) {
 		err("rc query invalid length");
 		return -EIO;
 	}
 	if (len > 0) {
 		deb_rc("rc data (%d) ", len);
-		debug_dump((ibuf + 6), len, deb_rc);
-		ret = rc_decode(d, &ibuf[6], len, event, state);
+		debug_dump((st->data + 6), len, deb_rc);
+		ret = rc_decode(d, &st->data[6], len, event, state);
 		if (ret) {
 			err("rc_decode failed");
 			return ret;
@@ -953,10 +955,16 @@ static int af9005_identify_state(struct usb_device *udev,
 				 int *cold)
 {
 	int ret;
-	u8 reply;
-	ret = af9005_boot_packet(udev, FW_CONFIG, &reply);
+	u8 reply, *buf;
+
+	buf = kmalloc(FW_BULKOUT_SIZE + 2, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	ret = af9005_boot_packet(udev, FW_CONFIG, &reply,
+				 buf, FW_BULKOUT_SIZE + 2);
 	if (ret)
-		return ret;
+		goto err;
 	deb_info("result of FW_CONFIG in identify state %d\n", reply);
 	if (reply == 0x01)
 		*cold = 1;
@@ -965,7 +973,10 @@ static int af9005_identify_state(struct usb_device *udev,
 	else
 		return -EIO;
 	deb_info("Identify state cold = %d\n", *cold);
-	return 0;
+
+err:
+	kfree(buf);
+	return ret;
 }
 
 static struct dvb_usb_device_properties af9005_properties;
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1497400 — [PATCH 11/26] digitv: don't do DMA on stack

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-07 19:30 +0200
Subject[PATCH 11/26] digitv: don't do DMA on stack
Message-ID<spH86-3EG-39@gated-at.bofh.it>
In reply to#1497395
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 <mchehab@s-opensource.com>
---
 drivers/media/usb/dvb-usb/digitv.c | 20 +++++++++++---------
 drivers/media/usb/dvb-usb/digitv.h |  3 +++
 2 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/media/usb/dvb-usb/digitv.c b/drivers/media/usb/dvb-usb/digitv.c
index 63134335c994..09f8c28bd4db 100644
--- a/drivers/media/usb/dvb-usb/digitv.c
+++ b/drivers/media/usb/dvb-usb/digitv.c
@@ -28,20 +28,22 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 static int digitv_ctrl_msg(struct dvb_usb_device *d,
 		u8 cmd, u8 vv, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
 {
+	struct digitv_state *st = d->priv;
 	int wo = (rbuf == NULL || rlen == 0); /* write-only */
-	u8 sndbuf[7],rcvbuf[7];
-	memset(sndbuf,0,7); memset(rcvbuf,0,7);
 
-	sndbuf[0] = cmd;
-	sndbuf[1] = vv;
-	sndbuf[2] = wo ? wlen : rlen;
+	memset(st->sndbuf, 0, 7);
+	memset(st->rcvbuf, 0, 7);
+
+	st->sndbuf[0] = cmd;
+	st->sndbuf[1] = vv;
+	st->sndbuf[2] = wo ? wlen : rlen;
 
 	if (wo) {
-		memcpy(&sndbuf[3],wbuf,wlen);
-		dvb_usb_generic_write(d,sndbuf,7);
+		memcpy(&st->sndbuf[3], wbuf, wlen);
+		dvb_usb_generic_write(d, st->sndbuf, 7);
 	} else {
-		dvb_usb_generic_rw(d,sndbuf,7,rcvbuf,7,10);
-		memcpy(rbuf,&rcvbuf[3],rlen);
+		dvb_usb_generic_rw(d, st->sndbuf, 7, st->rcvbuf, 7, 10);
+		memcpy(rbuf, &st->rcvbuf[3], rlen);
 	}
 	return 0;
 }
diff --git a/drivers/media/usb/dvb-usb/digitv.h b/drivers/media/usb/dvb-usb/digitv.h
index 908c09f4966b..cf104689bdff 100644
--- a/drivers/media/usb/dvb-usb/digitv.h
+++ b/drivers/media/usb/dvb-usb/digitv.h
@@ -6,6 +6,9 @@
 
 struct digitv_state {
     int is_nxt6000;
+
+    unsigned char sndbuf[7];
+    unsigned char rcvbuf[7];
 };
 
 /* protocol (from usblogging and the SDK:
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1498127 — Re: [PATCH 11/26] digitv: don't do DMA on stack

FromPatrick Boettcher <patrick.boettcher@posteo.de>
Date2016-10-10 08:40 +0200
SubjectRe: [PATCH 11/26] digitv: don't do DMA on stack
Message-ID<sqCpH-6ic-7@gated-at.bofh.it>
In reply to#1497400
On Fri,  7 Oct 2016 14:24:21 -0300
Mauro Carvalho Chehab <mchehab@s-opensource.com> 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 <mchehab@s-opensource.com>
> ---
>  drivers/media/usb/dvb-usb/digitv.c | 20 +++++++++++---------
>  drivers/media/usb/dvb-usb/digitv.h |  3 +++
>  2 files changed, 14 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/media/usb/dvb-usb/digitv.c
> b/drivers/media/usb/dvb-usb/digitv.c index 63134335c994..09f8c28bd4db
> 100644 --- a/drivers/media/usb/dvb-usb/digitv.c
> +++ b/drivers/media/usb/dvb-usb/digitv.c
> @@ -28,20 +28,22 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
>  static int digitv_ctrl_msg(struct dvb_usb_device *d,
>  		u8 cmd, u8 vv, u8 *wbuf, int wlen, u8 *rbuf, int
> rlen) {
> +	struct digitv_state *st = d->priv;
>  	int wo = (rbuf == NULL || rlen == 0); /* write-only */
> -	u8 sndbuf[7],rcvbuf[7];
> -	memset(sndbuf,0,7); memset(rcvbuf,0,7);
>  
> -	sndbuf[0] = cmd;
> -	sndbuf[1] = vv;
> -	sndbuf[2] = wo ? wlen : rlen;
> +	memset(st->sndbuf, 0, 7);
> +	memset(st->rcvbuf, 0, 7);
> +
> +	st->sndbuf[0] = cmd;
> +	st->sndbuf[1] = vv;
> +	st->sndbuf[2] = wo ? wlen : rlen;
>  
>  	if (wo) {
> -		memcpy(&sndbuf[3],wbuf,wlen);
> -		dvb_usb_generic_write(d,sndbuf,7);
> +		memcpy(&st->sndbuf[3], wbuf, wlen);
> +		dvb_usb_generic_write(d, st->sndbuf, 7);
>  	} else {
> -		dvb_usb_generic_rw(d,sndbuf,7,rcvbuf,7,10);
> -		memcpy(rbuf,&rcvbuf[3],rlen);
> +		dvb_usb_generic_rw(d, st->sndbuf, 7, st->rcvbuf, 7,
> 10);
> +		memcpy(rbuf, &st->rcvbuf[3], rlen);
>  	}
>  	return 0;
>  }
> diff --git a/drivers/media/usb/dvb-usb/digitv.h
> b/drivers/media/usb/dvb-usb/digitv.h index 908c09f4966b..cf104689bdff
> 100644 --- a/drivers/media/usb/dvb-usb/digitv.h
> +++ b/drivers/media/usb/dvb-usb/digitv.h
> @@ -6,6 +6,9 @@
>  
>  struct digitv_state {
>      int is_nxt6000;
> +
> +    unsigned char sndbuf[7];
> +    unsigned char rcvbuf[7];
>  };
>  
>  /* protocol (from usblogging and the SDK:

Reviewed-By: Patrick Boettcher <patrick.boettcher@posteo.de>

[toc] | [prev] | [next] | [standalone]


#1497401 — [PATCH 02/26] cinergyT2-core: don't do DMA on stack

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-07 19:30 +0200
Subject[PATCH 02/26] cinergyT2-core: don't do DMA on stack
Message-ID<spH86-3EG-41@gated-at.bofh.it>
In reply to#1497395
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 <mchehab@s-opensource.com>
---
 drivers/media/usb/dvb-usb/cinergyT2-core.c | 45 ++++++++++++++++++------------
 1 file changed, 27 insertions(+), 18 deletions(-)

diff --git a/drivers/media/usb/dvb-usb/cinergyT2-core.c b/drivers/media/usb/dvb-usb/cinergyT2-core.c
index 9fd1527494eb..91640c927776 100644
--- a/drivers/media/usb/dvb-usb/cinergyT2-core.c
+++ b/drivers/media/usb/dvb-usb/cinergyT2-core.c
@@ -41,6 +41,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 struct cinergyt2_state {
 	u8 rc_counter;
+	unsigned char data[64];
 };
 
 /* We are missing a release hook with usb_device data */
@@ -50,29 +51,36 @@ static struct dvb_usb_device_properties cinergyt2_properties;
 
 static int cinergyt2_streaming_ctrl(struct dvb_usb_adapter *adap, int enable)
 {
-	char buf[] = { CINERGYT2_EP1_CONTROL_STREAM_TRANSFER, enable ? 1 : 0 };
-	char result[64];
-	return dvb_usb_generic_rw(adap->dev, buf, sizeof(buf), result,
-				sizeof(result), 0);
+	struct dvb_usb_device *d = adap->dev;
+	struct cinergyt2_state *st = d->priv;
+
+	st->data[0] = CINERGYT2_EP1_CONTROL_STREAM_TRANSFER;
+	st->data[1] = enable ? 1 : 0;
+
+	return dvb_usb_generic_rw(d, st->data, 2, st->data, 64, 0);
 }
 
 static int cinergyt2_power_ctrl(struct dvb_usb_device *d, int enable)
 {
-	char buf[] = { CINERGYT2_EP1_SLEEP_MODE, enable ? 0 : 1 };
-	char state[3];
-	return dvb_usb_generic_rw(d, buf, sizeof(buf), state, sizeof(state), 0);
+	struct cinergyt2_state *st = d->priv;
+
+	st->data[0] = CINERGYT2_EP1_SLEEP_MODE;
+	st->data[1] = enable ? 0 : 1;
+
+	return dvb_usb_generic_rw(d, st->data, 2, st->data, 3, 0);
 }
 
 static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap)
 {
-	char query[] = { CINERGYT2_EP1_GET_FIRMWARE_VERSION };
-	char state[3];
+	struct dvb_usb_device *d = adap->dev;
+	struct cinergyt2_state *st = d->priv;
 	int ret;
 
 	adap->fe_adap[0].fe = cinergyt2_fe_attach(adap->dev);
 
-	ret = dvb_usb_generic_rw(adap->dev, query, sizeof(query), state,
-				sizeof(state), 0);
+	st->data[0] = CINERGYT2_EP1_GET_FIRMWARE_VERSION;
+
+	ret = dvb_usb_generic_rw(d, st->data, 1, st->data, 3, 0);
 	if (ret < 0) {
 		deb_rc("cinergyt2_power_ctrl() Failed to retrieve sleep "
 			"state info\n");
@@ -141,13 +149,14 @@ static int repeatable_keys[] = {
 static int cinergyt2_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 {
 	struct cinergyt2_state *st = d->priv;
-	u8 key[5] = {0, 0, 0, 0, 0}, cmd = CINERGYT2_EP1_GET_RC_EVENTS;
 	int i;
 
 	*state = REMOTE_NO_KEY_PRESSED;
 
-	dvb_usb_generic_rw(d, &cmd, 1, key, sizeof(key), 0);
-	if (key[4] == 0xff) {
+	st->data[0] = CINERGYT2_EP1_GET_RC_EVENTS;
+
+	dvb_usb_generic_rw(d, st->data, 1, st->data, 5, 0);
+	if (st->data[4] == 0xff) {
 		/* key repeat */
 		st->rc_counter++;
 		if (st->rc_counter > RC_REPEAT_DELAY) {
@@ -166,13 +175,13 @@ static int cinergyt2_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 	}
 
 	/* hack to pass checksum on the custom field */
-	key[2] = ~key[1];
-	dvb_usb_nec_rc_key_to_event(d, key, event, state);
-	if (key[0] != 0) {
+	st->data[2] = ~st->data[1];
+	dvb_usb_nec_rc_key_to_event(d, st->data, event, state);
+	if (st->data[0] != 0) {
 		if (*event != d->last_event)
 			st->rc_counter = 0;
 
-		deb_rc("key: %*ph\n", 5, key);
+		deb_rc("key: %*ph\n", 5, st->data);
 	}
 	return 0;
 }
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1498124 — Re: [PATCH 02/26] cinergyT2-core: don't do DMA on stack

FromPatrick Boettcher <patrick.boettcher@posteo.de>
Date2016-10-10 08:40 +0200
SubjectRe: [PATCH 02/26] cinergyT2-core: don't do DMA on stack
Message-ID<sqCpH-6ic-1@gated-at.bofh.it>
In reply to#1497401
On Fri,  7 Oct 2016 14:24:12 -0300
Mauro Carvalho Chehab <mchehab@s-opensource.com> 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 <mchehab@s-opensource.com>
> ---
>  drivers/media/usb/dvb-usb/cinergyT2-core.c | 45
> ++++++++++++++++++------------ 1 file changed, 27 insertions(+), 18
> deletions(-)
> 
> diff --git a/drivers/media/usb/dvb-usb/cinergyT2-core.c
> b/drivers/media/usb/dvb-usb/cinergyT2-core.c index
> 9fd1527494eb..91640c927776 100644 ---
> a/drivers/media/usb/dvb-usb/cinergyT2-core.c +++
> b/drivers/media/usb/dvb-usb/cinergyT2-core.c @@ -41,6 +41,7 @@
> DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 
>  struct cinergyt2_state {
>  	u8 rc_counter;
> +	unsigned char data[64];
>  };
>  
>  /* We are missing a release hook with usb_device data */
> @@ -50,29 +51,36 @@ static struct dvb_usb_device_properties
> cinergyt2_properties; 
>  static int cinergyt2_streaming_ctrl(struct dvb_usb_adapter *adap,
> int enable) {
> -	char buf[] = { CINERGYT2_EP1_CONTROL_STREAM_TRANSFER,
> enable ? 1 : 0 };
> -	char result[64];
> -	return dvb_usb_generic_rw(adap->dev, buf, sizeof(buf),
> result,
> -				sizeof(result), 0);
> +	struct dvb_usb_device *d = adap->dev;
> +	struct cinergyt2_state *st = d->priv;
> +
> +	st->data[0] = CINERGYT2_EP1_CONTROL_STREAM_TRANSFER;
> +	st->data[1] = enable ? 1 : 0;
> +
> +	return dvb_usb_generic_rw(d, st->data, 2, st->data, 64, 0);
>  }
>  
>  static int cinergyt2_power_ctrl(struct dvb_usb_device *d, int enable)
>  {
> -	char buf[] = { CINERGYT2_EP1_SLEEP_MODE, enable ? 0 : 1 };
> -	char state[3];
> -	return dvb_usb_generic_rw(d, buf, sizeof(buf), state,
> sizeof(state), 0);
> +	struct cinergyt2_state *st = d->priv;
> +
> +	st->data[0] = CINERGYT2_EP1_SLEEP_MODE;
> +	st->data[1] = enable ? 0 : 1;
> +
> +	return dvb_usb_generic_rw(d, st->data, 2, st->data, 3, 0);
>  }
>  
>  static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap)
>  {
> -	char query[] = { CINERGYT2_EP1_GET_FIRMWARE_VERSION };
> -	char state[3];
> +	struct dvb_usb_device *d = adap->dev;
> +	struct cinergyt2_state *st = d->priv;
>  	int ret;
>  
>  	adap->fe_adap[0].fe = cinergyt2_fe_attach(adap->dev);
>  
> -	ret = dvb_usb_generic_rw(adap->dev, query, sizeof(query),
> state,
> -				sizeof(state), 0);
> +	st->data[0] = CINERGYT2_EP1_GET_FIRMWARE_VERSION;
> +
> +	ret = dvb_usb_generic_rw(d, st->data, 1, st->data, 3, 0);
>  	if (ret < 0) {
>  		deb_rc("cinergyt2_power_ctrl() Failed to retrieve
> sleep " "state info\n");
> @@ -141,13 +149,14 @@ static int repeatable_keys[] = {
>  static int cinergyt2_rc_query(struct dvb_usb_device *d, u32 *event,
> int *state) {
>  	struct cinergyt2_state *st = d->priv;
> -	u8 key[5] = {0, 0, 0, 0, 0}, cmd =
> CINERGYT2_EP1_GET_RC_EVENTS; int i;
>  
>  	*state = REMOTE_NO_KEY_PRESSED;
>  
> -	dvb_usb_generic_rw(d, &cmd, 1, key, sizeof(key), 0);
> -	if (key[4] == 0xff) {
> +	st->data[0] = CINERGYT2_EP1_GET_RC_EVENTS;
> +
> +	dvb_usb_generic_rw(d, st->data, 1, st->data, 5, 0);
> +	if (st->data[4] == 0xff) {
>  		/* key repeat */
>  		st->rc_counter++;
>  		if (st->rc_counter > RC_REPEAT_DELAY) {
> @@ -166,13 +175,13 @@ static int cinergyt2_rc_query(struct
> dvb_usb_device *d, u32 *event, int *state) }
>  
>  	/* hack to pass checksum on the custom field */
> -	key[2] = ~key[1];
> -	dvb_usb_nec_rc_key_to_event(d, key, event, state);
> -	if (key[0] != 0) {
> +	st->data[2] = ~st->data[1];
> +	dvb_usb_nec_rc_key_to_event(d, st->data, event, state);
> +	if (st->data[0] != 0) {
>  		if (*event != d->last_event)
>  			st->rc_counter = 0;
>  
> -		deb_rc("key: %*ph\n", 5, key);
> +		deb_rc("key: %*ph\n", 5, st->data);
>  	}
>  	return 0;
>  }

Reviewed-By: Patrick Boettcher <patrick.boettcher@posteo.de>

[toc] | [prev] | [next] | [standalone]


#1497402 — [PATCH 15/26] dtt200u: handle USB control message errors

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-07 19:30 +0200
Subject[PATCH 15/26] dtt200u: handle USB control message errors
Message-ID<spH86-3EG-43@gated-at.bofh.it>
In reply to#1497395
If something bad happens while an USB control message is
transfered, return an error code.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
 drivers/media/usb/dvb-usb/dtt200u.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/media/usb/dvb-usb/dtt200u.c b/drivers/media/usb/dvb-usb/dtt200u.c
index d6023fb6a1d4..ca8965b8b610 100644
--- a/drivers/media/usb/dvb-usb/dtt200u.c
+++ b/drivers/media/usb/dvb-usb/dtt200u.c
@@ -31,7 +31,7 @@ static int dtt200u_power_ctrl(struct dvb_usb_device *d, int onoff)
 	st->data[0] = SET_INIT;
 
 	if (onoff)
-		dvb_usb_generic_write(d, st->data, 2);
+		return dvb_usb_generic_write(d, st->data, 2);
 
 	return 0;
 }
@@ -39,19 +39,20 @@ static int dtt200u_power_ctrl(struct dvb_usb_device *d, int onoff)
 static int dtt200u_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 {
 	struct dtt200u_state *st = adap->dev->priv;
+	int ret;
 
 	st->data[0] = SET_STREAMING;
 	st->data[1] = onoff;
 
-	dvb_usb_generic_write(adap->dev, st->data, 2);
+	ret = dvb_usb_generic_write(adap->dev, st->data, 2);
+	if (ret < 0)
+		return ret;
 
 	if (onoff)
 		return 0;
 
 	st->data[0] = RESET_PID_FILTER;
-	dvb_usb_generic_write(adap->dev, st->data, 1);
-
-	return 0;
+	return dvb_usb_generic_write(adap->dev, st->data, 1);
 }
 
 static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
@@ -72,10 +73,14 @@ static int dtt200u_rc_query(struct dvb_usb_device *d)
 {
 	struct dtt200u_state *st = d->priv;
 	u32 scancode;
+	int ret;
 
 	st->data[0] = GET_RC_CODE;
 
-	dvb_usb_generic_rw(d, st->data, 1, st->data, 5, 0);
+	ret = dvb_usb_generic_rw(d, st->data, 1, st->data, 5, 0);
+	if (ret < 0)
+		return ret;
+
 	if (st->data[0] == 1) {
 		enum rc_type proto = RC_TYPE_NEC;
 
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1497403 — [PATCH 14/26] dtt200u: don't do DMA on stack

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-07 19:30 +0200
Subject[PATCH 14/26] dtt200u: don't do DMA on stack
Message-ID<spH85-3EG-35@gated-at.bofh.it>
In reply to#1497395
From: Mauro Carvalho Chehab <mchehab@osg.samsung.com>

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 <mchehab@osg.samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
 drivers/media/usb/dvb-usb/dtt200u.c | 73 +++++++++++++++++++++++++------------
 1 file changed, 49 insertions(+), 24 deletions(-)

diff --git a/drivers/media/usb/dvb-usb/dtt200u.c b/drivers/media/usb/dvb-usb/dtt200u.c
index d2a01b50af0d..d6023fb6a1d4 100644
--- a/drivers/media/usb/dvb-usb/dtt200u.c
+++ b/drivers/media/usb/dvb-usb/dtt200u.c
@@ -20,73 +20,88 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB
 
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
+struct dtt200u_state {
+	unsigned char data[80];
+};
+
 static int dtt200u_power_ctrl(struct dvb_usb_device *d, int onoff)
 {
-	u8 b = SET_INIT;
+	struct dtt200u_state *st = d->priv;
+
+	st->data[0] = SET_INIT;
 
 	if (onoff)
-		dvb_usb_generic_write(d,&b,2);
+		dvb_usb_generic_write(d, st->data, 2);
 
 	return 0;
 }
 
 static int dtt200u_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 {
-	u8 b_streaming[2] = { SET_STREAMING, onoff };
-	u8 b_rst_pid = RESET_PID_FILTER;
+	struct dtt200u_state *st = adap->dev->priv;
 
-	dvb_usb_generic_write(adap->dev, b_streaming, 2);
+	st->data[0] = SET_STREAMING;
+	st->data[1] = onoff;
+
+	dvb_usb_generic_write(adap->dev, st->data, 2);
+
+	if (onoff)
+		return 0;
+
+	st->data[0] = RESET_PID_FILTER;
+	dvb_usb_generic_write(adap->dev, st->data, 1);
 
-	if (onoff == 0)
-		dvb_usb_generic_write(adap->dev, &b_rst_pid, 1);
 	return 0;
 }
 
 static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
 {
-	u8 b_pid[4];
+	struct dtt200u_state *st = adap->dev->priv;
+
 	pid = onoff ? pid : 0;
 
-	b_pid[0] = SET_PID_FILTER;
-	b_pid[1] = index;
-	b_pid[2] = pid & 0xff;
-	b_pid[3] = (pid >> 8) & 0x1f;
+	st->data[0] = SET_PID_FILTER;
+	st->data[1] = index;
+	st->data[2] = pid & 0xff;
+	st->data[3] = (pid >> 8) & 0x1f;
 
-	return dvb_usb_generic_write(adap->dev, b_pid, 4);
+	return dvb_usb_generic_write(adap->dev, st->data, 4);
 }
 
 static int dtt200u_rc_query(struct dvb_usb_device *d)
 {
-	u8 key[5],cmd = GET_RC_CODE;
+	struct dtt200u_state *st = d->priv;
 	u32 scancode;
 
-	dvb_usb_generic_rw(d,&cmd,1,key,5,0);
-	if (key[0] == 1) {
+	st->data[0] = GET_RC_CODE;
+
+	dvb_usb_generic_rw(d, st->data, 1, st->data, 5, 0);
+	if (st->data[0] == 1) {
 		enum rc_type proto = RC_TYPE_NEC;
 
-		scancode = key[1];
-		if ((u8) ~key[1] != key[2]) {
+		scancode = st->data[1];
+		if ((u8) ~st->data[1] != st->data[2]) {
 			/* Extended NEC */
 			scancode = scancode << 8;
-			scancode |= key[2];
+			scancode |= st->data[2];
 			proto = RC_TYPE_NECX;
 		}
 		scancode = scancode << 8;
-		scancode |= key[3];
+		scancode |= st->data[3];
 
 		/* Check command checksum is ok */
-		if ((u8) ~key[3] == key[4])
+		if ((u8) ~st->data[3] == st->data[4])
 			rc_keydown(d->rc_dev, proto, scancode, 0);
 		else
 			rc_keyup(d->rc_dev);
-	} else if (key[0] == 2) {
+	} else if (st->data[0] == 2) {
 		rc_repeat(d->rc_dev);
 	} else {
 		rc_keyup(d->rc_dev);
 	}
 
-	if (key[0] != 0)
-		deb_info("key: %*ph\n", 5, key);
+	if (st->data[0] != 0)
+		deb_info("st->data: %*ph\n", 5, st->data);
 
 	return 0;
 }
@@ -140,6 +155,8 @@ static struct dvb_usb_device_properties dtt200u_properties = {
 	.usb_ctrl = CYPRESS_FX2,
 	.firmware = "dvb-usb-dtt200u-01.fw",
 
+	.size_of_priv     = sizeof(struct dtt200u_state),
+
 	.num_adapters = 1,
 	.adapter = {
 		{
@@ -190,6 +207,8 @@ static struct dvb_usb_device_properties wt220u_properties = {
 	.usb_ctrl = CYPRESS_FX2,
 	.firmware = "dvb-usb-wt220u-02.fw",
 
+	.size_of_priv     = sizeof(struct dtt200u_state),
+
 	.num_adapters = 1,
 	.adapter = {
 		{
@@ -240,6 +259,8 @@ static struct dvb_usb_device_properties wt220u_fc_properties = {
 	.usb_ctrl = CYPRESS_FX2,
 	.firmware = "dvb-usb-wt220u-fc03.fw",
 
+	.size_of_priv     = sizeof(struct dtt200u_state),
+
 	.num_adapters = 1,
 	.adapter = {
 		{
@@ -290,6 +311,8 @@ static struct dvb_usb_device_properties wt220u_zl0353_properties = {
 	.usb_ctrl = CYPRESS_FX2,
 	.firmware = "dvb-usb-wt220u-zl0353-01.fw",
 
+	.size_of_priv     = sizeof(struct dtt200u_state),
+
 	.num_adapters = 1,
 	.adapter = {
 		{
@@ -340,6 +363,8 @@ static struct dvb_usb_device_properties wt220u_miglia_properties = {
 	.usb_ctrl = CYPRESS_FX2,
 	.firmware = "dvb-usb-wt220u-miglia-01.fw",
 
+	.size_of_priv     = sizeof(struct dtt200u_state),
+
 	.num_adapters = 1,
 	.generic_bulk_ctrl_endpoint = 0x01,
 
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1498135 — Re: [PATCH 14/26] dtt200u: don't do DMA on stack

FromPatrick Boettcher <patrick.boettcher@posteo.de>
Date2016-10-10 08:40 +0200
SubjectRe: [PATCH 14/26] dtt200u: don't do DMA on stack
Message-ID<sqCpI-6ic-25@gated-at.bofh.it>
In reply to#1497403
On Fri,  7 Oct 2016 14:24:24 -0300
Mauro Carvalho Chehab <mchehab@s-opensource.com> wrote:

> From: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
> 
> 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 <mchehab@osg.samsung.com>
> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
> ---
>  drivers/media/usb/dvb-usb/dtt200u.c | 73
> +++++++++++++++++++++++++------------ 1 file changed, 49
> insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/media/usb/dvb-usb/dtt200u.c
> b/drivers/media/usb/dvb-usb/dtt200u.c index
> d2a01b50af0d..d6023fb6a1d4 100644 ---
> a/drivers/media/usb/dvb-usb/dtt200u.c +++
> b/drivers/media/usb/dvb-usb/dtt200u.c @@ -20,73 +20,88 @@
> MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2
> (or-able))." DVB_USB DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
>  
> +struct dtt200u_state {
> +	unsigned char data[80];
> +};
> +
>  static int dtt200u_power_ctrl(struct dvb_usb_device *d, int onoff)
>  {
> -	u8 b = SET_INIT;
> +	struct dtt200u_state *st = d->priv;
> +
> +	st->data[0] = SET_INIT;
>  
>  	if (onoff)
> -		dvb_usb_generic_write(d,&b,2);
> +		dvb_usb_generic_write(d, st->data, 2);
>  
>  	return 0;
>  }
>  
>  static int dtt200u_streaming_ctrl(struct dvb_usb_adapter *adap, int
> onoff) {
> -	u8 b_streaming[2] = { SET_STREAMING, onoff };
> -	u8 b_rst_pid = RESET_PID_FILTER;
> +	struct dtt200u_state *st = adap->dev->priv;
>  
> -	dvb_usb_generic_write(adap->dev, b_streaming, 2);
> +	st->data[0] = SET_STREAMING;
> +	st->data[1] = onoff;
> +
> +	dvb_usb_generic_write(adap->dev, st->data, 2);
> +
> +	if (onoff)
> +		return 0;
> +
> +	st->data[0] = RESET_PID_FILTER;
> +	dvb_usb_generic_write(adap->dev, st->data, 1);
>  
> -	if (onoff == 0)
> -		dvb_usb_generic_write(adap->dev, &b_rst_pid, 1);
>  	return 0;
>  }
>  
>  static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, int
> index, u16 pid, int onoff) {
> -	u8 b_pid[4];
> +	struct dtt200u_state *st = adap->dev->priv;
> +
>  	pid = onoff ? pid : 0;
>  
> -	b_pid[0] = SET_PID_FILTER;
> -	b_pid[1] = index;
> -	b_pid[2] = pid & 0xff;
> -	b_pid[3] = (pid >> 8) & 0x1f;
> +	st->data[0] = SET_PID_FILTER;
> +	st->data[1] = index;
> +	st->data[2] = pid & 0xff;
> +	st->data[3] = (pid >> 8) & 0x1f;
>  
> -	return dvb_usb_generic_write(adap->dev, b_pid, 4);
> +	return dvb_usb_generic_write(adap->dev, st->data, 4);
>  }
>  
>  static int dtt200u_rc_query(struct dvb_usb_device *d)
>  {
> -	u8 key[5],cmd = GET_RC_CODE;
> +	struct dtt200u_state *st = d->priv;
>  	u32 scancode;
>  
> -	dvb_usb_generic_rw(d,&cmd,1,key,5,0);
> -	if (key[0] == 1) {
> +	st->data[0] = GET_RC_CODE;
> +
> +	dvb_usb_generic_rw(d, st->data, 1, st->data, 5, 0);
> +	if (st->data[0] == 1) {
>  		enum rc_type proto = RC_TYPE_NEC;
>  
> -		scancode = key[1];
> -		if ((u8) ~key[1] != key[2]) {
> +		scancode = st->data[1];
> +		if ((u8) ~st->data[1] != st->data[2]) {
>  			/* Extended NEC */
>  			scancode = scancode << 8;
> -			scancode |= key[2];
> +			scancode |= st->data[2];
>  			proto = RC_TYPE_NECX;
>  		}
>  		scancode = scancode << 8;
> -		scancode |= key[3];
> +		scancode |= st->data[3];
>  
>  		/* Check command checksum is ok */
> -		if ((u8) ~key[3] == key[4])
> +		if ((u8) ~st->data[3] == st->data[4])
>  			rc_keydown(d->rc_dev, proto, scancode, 0);
>  		else
>  			rc_keyup(d->rc_dev);
> -	} else if (key[0] == 2) {
> +	} else if (st->data[0] == 2) {
>  		rc_repeat(d->rc_dev);
>  	} else {
>  		rc_keyup(d->rc_dev);
>  	}
>  
> -	if (key[0] != 0)
> -		deb_info("key: %*ph\n", 5, key);
> +	if (st->data[0] != 0)
> +		deb_info("st->data: %*ph\n", 5, st->data);
>  
>  	return 0;
>  }
> @@ -140,6 +155,8 @@ static struct dvb_usb_device_properties
> dtt200u_properties = { .usb_ctrl = CYPRESS_FX2,
>  	.firmware = "dvb-usb-dtt200u-01.fw",
>  
> +	.size_of_priv     = sizeof(struct dtt200u_state),
> +
>  	.num_adapters = 1,
>  	.adapter = {
>  		{
> @@ -190,6 +207,8 @@ static struct dvb_usb_device_properties
> wt220u_properties = { .usb_ctrl = CYPRESS_FX2,
>  	.firmware = "dvb-usb-wt220u-02.fw",
>  
> +	.size_of_priv     = sizeof(struct dtt200u_state),
> +
>  	.num_adapters = 1,
>  	.adapter = {
>  		{
> @@ -240,6 +259,8 @@ static struct dvb_usb_device_properties
> wt220u_fc_properties = { .usb_ctrl = CYPRESS_FX2,
>  	.firmware = "dvb-usb-wt220u-fc03.fw",
>  
> +	.size_of_priv     = sizeof(struct dtt200u_state),
> +
>  	.num_adapters = 1,
>  	.adapter = {
>  		{
> @@ -290,6 +311,8 @@ static struct dvb_usb_device_properties
> wt220u_zl0353_properties = { .usb_ctrl = CYPRESS_FX2,
>  	.firmware = "dvb-usb-wt220u-zl0353-01.fw",
>  
> +	.size_of_priv     = sizeof(struct dtt200u_state),
> +
>  	.num_adapters = 1,
>  	.adapter = {
>  		{
> @@ -340,6 +363,8 @@ static struct dvb_usb_device_properties
> wt220u_miglia_properties = { .usb_ctrl = CYPRESS_FX2,
>  	.firmware = "dvb-usb-wt220u-miglia-01.fw",
>  
> +	.size_of_priv     = sizeof(struct dtt200u_state),
> +
>  	.num_adapters = 1,
>  	.generic_bulk_ctrl_endpoint = 0x01,
>  

Reviewed-By: Patrick Boettcher <patrick.boettcher@posteo.de>

[toc] | [prev] | [next] | [standalone]


#1497404 — [PATCH 04/26] cinergyT2-fe: cache stats at cinergyt2_fe_read_status()

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-07 19:30 +0200
Subject[PATCH 04/26] cinergyT2-fe: cache stats at cinergyt2_fe_read_status()
Message-ID<spH86-3EG-45@gated-at.bofh.it>
In reply to#1497395
Instead of sending USB commands for every stats call, collect
them once, when status is updated. As the frontend kthread
will call it on every few seconds, the stats will still be
collected.

Besides reducing the amount of USB/I2C transfers, this also
warrants that all stats will be collected at the same time,
and makes easier to convert it to DVBv5 stats in the future.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
 drivers/media/usb/dvb-usb/cinergyT2-fe.c | 48 +++++---------------------------
 1 file changed, 7 insertions(+), 41 deletions(-)

diff --git a/drivers/media/usb/dvb-usb/cinergyT2-fe.c b/drivers/media/usb/dvb-usb/cinergyT2-fe.c
index b3ec743a7a2e..fd8edcb56e61 100644
--- a/drivers/media/usb/dvb-usb/cinergyT2-fe.c
+++ b/drivers/media/usb/dvb-usb/cinergyT2-fe.c
@@ -139,6 +139,7 @@ static uint16_t compute_tps(struct dtv_frontend_properties *op)
 struct cinergyt2_fe_state {
 	struct dvb_frontend fe;
 	struct dvb_usb_device *d;
+	struct dvbt_get_status_msg status;
 };
 
 static int cinergyt2_fe_read_status(struct dvb_frontend *fe,
@@ -154,6 +155,8 @@ static int cinergyt2_fe_read_status(struct dvb_frontend *fe,
 	if (ret < 0)
 		return ret;
 
+	state->status = result;
+
 	*status = 0;
 
 	if (0xffff - le16_to_cpu(result.gain) > 30)
@@ -177,34 +180,16 @@ static int cinergyt2_fe_read_status(struct dvb_frontend *fe,
 static int cinergyt2_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
 {
 	struct cinergyt2_fe_state *state = fe->demodulator_priv;
-	struct dvbt_get_status_msg status;
-	char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
-	int ret;
 
-	ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
-				sizeof(status), 0);
-	if (ret < 0)
-		return ret;
-
-	*ber = le32_to_cpu(status.viterbi_error_rate);
+	*ber = le32_to_cpu(state->status.viterbi_error_rate);
 	return 0;
 }
 
 static int cinergyt2_fe_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
 {
 	struct cinergyt2_fe_state *state = fe->demodulator_priv;
-	struct dvbt_get_status_msg status;
-	u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
-	int ret;
 
-	ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&status,
-				sizeof(status), 0);
-	if (ret < 0) {
-		err("cinergyt2_fe_read_unc_blocks() Failed! (Error=%d)\n",
-			ret);
-		return ret;
-	}
-	*unc = le32_to_cpu(status.uncorrected_block_count);
+	*unc = le32_to_cpu(state->status.uncorrected_block_count);
 	return 0;
 }
 
@@ -212,35 +197,16 @@ static int cinergyt2_fe_read_signal_strength(struct dvb_frontend *fe,
 						u16 *strength)
 {
 	struct cinergyt2_fe_state *state = fe->demodulator_priv;
-	struct dvbt_get_status_msg status;
-	char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
-	int ret;
 
-	ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
-				sizeof(status), 0);
-	if (ret < 0) {
-		err("cinergyt2_fe_read_signal_strength() Failed!"
-			" (Error=%d)\n", ret);
-		return ret;
-	}
-	*strength = (0xffff - le16_to_cpu(status.gain));
+	*strength = (0xffff - le16_to_cpu(state->status.gain));
 	return 0;
 }
 
 static int cinergyt2_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
 {
 	struct cinergyt2_fe_state *state = fe->demodulator_priv;
-	struct dvbt_get_status_msg status;
-	char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
-	int ret;
 
-	ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
-				sizeof(status), 0);
-	if (ret < 0) {
-		err("cinergyt2_fe_read_snr() Failed! (Error=%d)\n", ret);
-		return ret;
-	}
-	*snr = (status.snr << 8) | status.snr;
+	*snr = (state->status.snr << 8) | state->status.snr;
 	return 0;
 }
 
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1497405 — [PATCH 18/26] gp8psk: don't go past the buffer size

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-07 19:30 +0200
Subject[PATCH 18/26] gp8psk: don't go past the buffer size
Message-ID<spH86-3EG-49@gated-at.bofh.it>
In reply to#1497395
Add checks to avoid going out of the buffer.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
 drivers/media/usb/dvb-usb/gp8psk.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/media/usb/dvb-usb/gp8psk.c b/drivers/media/usb/dvb-usb/gp8psk.c
index fa215ad37f7b..a745cf636846 100644
--- a/drivers/media/usb/dvb-usb/gp8psk.c
+++ b/drivers/media/usb/dvb-usb/gp8psk.c
@@ -60,6 +60,9 @@ int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8
 	struct gp8psk_state *st = d->priv;
 	int ret = 0,try = 0;
 
+	if (blen > sizeof(st->data))
+		return -EIO;
+
 	if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
 		return ret;
 
@@ -98,6 +101,9 @@ int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
 	deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
 	debug_dump(b,blen,deb_xfer);
 
+	if (blen > sizeof(st->data))
+		return -EIO;
+
 	if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
 		return ret;
 
@@ -151,6 +157,11 @@ static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d)
 			err("failed to load bcm4500 firmware.");
 			goto out_free;
 		}
+		if (buflen > 64) {
+			err("firmare chunk size bigger than 64 bytes.");
+			goto out_free;
+		}
+
 		memcpy(buf, ptr, buflen);
 		if (dvb_usb_generic_write(d, buf, buflen)) {
 			err("failed to load bcm4500 firmware.");
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1497407 — [PATCH 07/26] dib0700: be sure that dib0700_ctrl_rd() users can do DMA

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-07 19:40 +0200
Subject[PATCH 07/26] dib0700: be sure that dib0700_ctrl_rd() users can do DMA
Message-ID<spHhL-3I7-5@gated-at.bofh.it>
In reply to#1497395
dib0700_ctrl_rd() takes a RX and a TX pointer. Be sure that
both will point to a memory allocated via kmalloc().

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
 drivers/media/usb/dvb-usb/dib0700_core.c    |  4 +++-
 drivers/media/usb/dvb-usb/dib0700_devices.c | 25 +++++++++++++------------
 2 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c
index f3196658fb70..515f89dba199 100644
--- a/drivers/media/usb/dvb-usb/dib0700_core.c
+++ b/drivers/media/usb/dvb-usb/dib0700_core.c
@@ -292,13 +292,15 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
 
 			/* special thing in the current firmware: when length is zero the read-failed */
 			len = dib0700_ctrl_rd(d, st->buf, msg[i].len + 2,
-					msg[i+1].buf, msg[i+1].len);
+					      st->buf, msg[i + 1].len);
 			if (len <= 0) {
 				deb_info("I2C read failed on address 0x%02x\n",
 						msg[i].addr);
 				break;
 			}
 
+			memcpy(msg[i + 1].buf, st->buf, msg[i + 1].len);
+
 			msg[i+1].len = len;
 
 			i++;
diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c
index 0857b56e652c..ef1b8ee75c57 100644
--- a/drivers/media/usb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/usb/dvb-usb/dib0700_devices.c
@@ -508,8 +508,6 @@ static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap)
 
 #define DEFAULT_RC_INTERVAL 50
 
-static u8 rc_request[] = { REQUEST_POLL_RC, 0 };
-
 /*
  * This function is used only when firmware is < 1.20 version. Newer
  * firmwares use bulk mode, with functions implemented at dib0700_core,
@@ -517,7 +515,6 @@ static u8 rc_request[] = { REQUEST_POLL_RC, 0 };
  */
 static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d)
 {
-	u8 key[4];
 	enum rc_type protocol;
 	u32 scancode;
 	u8 toggle;
@@ -532,39 +529,43 @@ static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d)
 		return 0;
 	}
 
-	i = dib0700_ctrl_rd(d, rc_request, 2, key, 4);
+	st->buf[0] = REQUEST_POLL_RC;
+	st->buf[1] = 0;
+
+	i = dib0700_ctrl_rd(d, st->buf, 2, st->buf, 4);
 	if (i <= 0) {
 		err("RC Query Failed");
-		return -1;
+		return -EIO;
 	}
 
 	/* losing half of KEY_0 events from Philipps rc5 remotes.. */
-	if (key[0] == 0 && key[1] == 0 && key[2] == 0 && key[3] == 0)
+	if (st->buf[0] == 0 && st->buf[1] == 0
+	    && st->buf[2] == 0 && st->buf[3] == 0)
 		return 0;
 
-	/* info("%d: %2X %2X %2X %2X",dvb_usb_dib0700_ir_proto,(int)key[3-2],(int)key[3-3],(int)key[3-1],(int)key[3]);  */
+	/* info("%d: %2X %2X %2X %2X",dvb_usb_dib0700_ir_proto,(int)st->buf[3 - 2],(int)st->buf[3 - 3],(int)st->buf[3 - 1],(int)st->buf[3]);  */
 
 	dib0700_rc_setup(d, NULL); /* reset ir sensor data to prevent false events */
 
 	switch (d->props.rc.core.protocol) {
 	case RC_BIT_NEC:
 		/* NEC protocol sends repeat code as 0 0 0 FF */
-		if ((key[3-2] == 0x00) && (key[3-3] == 0x00) &&
-		    (key[3] == 0xff)) {
+		if ((st->buf[3 - 2] == 0x00) && (st->buf[3 - 3] == 0x00) &&
+		    (st->buf[3] == 0xff)) {
 			rc_repeat(d->rc_dev);
 			return 0;
 		}
 
 		protocol = RC_TYPE_NEC;
-		scancode = RC_SCANCODE_NEC(key[3-2], key[3-3]);
+		scancode = RC_SCANCODE_NEC(st->buf[3 - 2], st->buf[3 - 3]);
 		toggle = 0;
 		break;
 
 	default:
 		/* RC-5 protocol changes toggle bit on new keypress */
 		protocol = RC_TYPE_RC5;
-		scancode = RC_SCANCODE_RC5(key[3-2], key[3-3]);
-		toggle = key[3-1];
+		scancode = RC_SCANCODE_RC5(st->buf[3 - 2], st->buf[3 - 3]);
+		toggle = st->buf[3 - 1];
 		break;
 	}
 
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1498126 — Re: [PATCH 07/26] dib0700: be sure that dib0700_ctrl_rd() users can do DMA

FromPatrick Boettcher <patrick.boettcher@posteo.de>
Date2016-10-10 08:40 +0200
SubjectRe: [PATCH 07/26] dib0700: be sure that dib0700_ctrl_rd() users can do DMA
Message-ID<sqCpI-6ic-17@gated-at.bofh.it>
In reply to#1497407
On Fri,  7 Oct 2016 14:24:17 -0300
Mauro Carvalho Chehab <mchehab@s-opensource.com> wrote:

> dib0700_ctrl_rd() takes a RX and a TX pointer. Be sure that
> both will point to a memory allocated via kmalloc().
> 
> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
> ---
>  drivers/media/usb/dvb-usb/dib0700_core.c    |  4 +++-
>  drivers/media/usb/dvb-usb/dib0700_devices.c | 25
> +++++++++++++------------ 2 files changed, 16 insertions(+), 13
> deletions(-)
> 
> diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c
> b/drivers/media/usb/dvb-usb/dib0700_core.c index
> f3196658fb70..515f89dba199 100644 ---
> a/drivers/media/usb/dvb-usb/dib0700_core.c +++
> b/drivers/media/usb/dvb-usb/dib0700_core.c @@ -292,13 +292,15 @@
> static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap, 
>  			/* special thing in the current firmware:
> when length is zero the read-failed */ len = dib0700_ctrl_rd(d,
> st->buf, msg[i].len + 2,
> -					msg[i+1].buf, msg[i+1].len);
> +					      st->buf, msg[i +
> 1].len); if (len <= 0) {
>  				deb_info("I2C read failed on address
> 0x%02x\n", msg[i].addr);
>  				break;
>  			}
>  
> +			memcpy(msg[i + 1].buf, st->buf, msg[i +
> 1].len); +
>  			msg[i+1].len = len;
>  
>  			i++;
> diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c
> b/drivers/media/usb/dvb-usb/dib0700_devices.c index
> 0857b56e652c..ef1b8ee75c57 100644 ---
> a/drivers/media/usb/dvb-usb/dib0700_devices.c +++
> b/drivers/media/usb/dvb-usb/dib0700_devices.c @@ -508,8 +508,6 @@
> static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap) 
>  #define DEFAULT_RC_INTERVAL 50
>  
> -static u8 rc_request[] = { REQUEST_POLL_RC, 0 };
> -
>  /*
>   * This function is used only when firmware is < 1.20 version. Newer
>   * firmwares use bulk mode, with functions implemented at
> dib0700_core, @@ -517,7 +515,6 @@ static u8 rc_request[] =
> { REQUEST_POLL_RC, 0 }; */
>  static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d)
>  {
> -	u8 key[4];
>  	enum rc_type protocol;
>  	u32 scancode;
>  	u8 toggle;
> @@ -532,39 +529,43 @@ static int dib0700_rc_query_old_firmware(struct
> dvb_usb_device *d) return 0;
>  	}
>  
> -	i = dib0700_ctrl_rd(d, rc_request, 2, key, 4);
> +	st->buf[0] = REQUEST_POLL_RC;
> +	st->buf[1] = 0;
> +
> +	i = dib0700_ctrl_rd(d, st->buf, 2, st->buf, 4);
>  	if (i <= 0) {
>  		err("RC Query Failed");
> -		return -1;
> +		return -EIO;
>  	}
>  
>  	/* losing half of KEY_0 events from Philipps rc5 remotes.. */
> -	if (key[0] == 0 && key[1] == 0 && key[2] == 0 && key[3] == 0)
> +	if (st->buf[0] == 0 && st->buf[1] == 0
> +	    && st->buf[2] == 0 && st->buf[3] == 0)
>  		return 0;
>  
> -	/* info("%d: %2X %2X %2X
> %2X",dvb_usb_dib0700_ir_proto,(int)key[3-2],(int)key[3-3],(int)key[3-1],(int)key[3]);
> */
> +	/* info("%d: %2X %2X %2X
> %2X",dvb_usb_dib0700_ir_proto,(int)st->buf[3 - 2],(int)st->buf[3 -
> 3],(int)st->buf[3 - 1],(int)st->buf[3]);  */ dib0700_rc_setup(d,
> NULL); /* reset ir sensor data to prevent false events */ 
>  	switch (d->props.rc.core.protocol) {
>  	case RC_BIT_NEC:
>  		/* NEC protocol sends repeat code as 0 0 0 FF */
> -		if ((key[3-2] == 0x00) && (key[3-3] == 0x00) &&
> -		    (key[3] == 0xff)) {
> +		if ((st->buf[3 - 2] == 0x00) && (st->buf[3 - 3] ==
> 0x00) &&
> +		    (st->buf[3] == 0xff)) {
>  			rc_repeat(d->rc_dev);
>  			return 0;
>  		}
>  
>  		protocol = RC_TYPE_NEC;
> -		scancode = RC_SCANCODE_NEC(key[3-2], key[3-3]);
> +		scancode = RC_SCANCODE_NEC(st->buf[3 - 2], st->buf[3
> - 3]); toggle = 0;
>  		break;
>  
>  	default:
>  		/* RC-5 protocol changes toggle bit on new keypress
> */ protocol = RC_TYPE_RC5;
> -		scancode = RC_SCANCODE_RC5(key[3-2], key[3-3]);
> -		toggle = key[3-1];
> +		scancode = RC_SCANCODE_RC5(st->buf[3 - 2], st->buf[3
> - 3]);
> +		toggle = st->buf[3 - 1];
>  		break;
>  	}
>  

Reviewed-By: Patrick Boettcher <patrick.boettcher@posteo.de>

[toc] | [prev] | [next] | [standalone]


#1497410 — [PATCH 17/26] gp8psk: don't do DMA on stack

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-07 19:40 +0200
Subject[PATCH 17/26] gp8psk: don't do DMA on stack
Message-ID<spHhL-3I7-9@gated-at.bofh.it>
In reply to#1497395
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 <mchehab@s-opensource.com>
---
 drivers/media/usb/dvb-usb/gp8psk.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/media/usb/dvb-usb/gp8psk.c b/drivers/media/usb/dvb-usb/gp8psk.c
index 5d0384dd45b5..fa215ad37f7b 100644
--- a/drivers/media/usb/dvb-usb/gp8psk.c
+++ b/drivers/media/usb/dvb-usb/gp8psk.c
@@ -24,6 +24,10 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DV
 
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
+struct gp8psk_state {
+	unsigned char data[80];
+};
+
 static int gp8psk_get_fw_version(struct dvb_usb_device *d, u8 *fw_vers)
 {
 	return (gp8psk_usb_in_op(d, GET_FW_VERS, 0, 0, fw_vers, 6));
@@ -53,17 +57,19 @@ static void gp8psk_info(struct dvb_usb_device *d)
 
 int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
 {
+	struct gp8psk_state *st = d->priv;
 	int ret = 0,try = 0;
 
 	if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
 		return ret;
 
 	while (ret >= 0 && ret != blen && try < 3) {
+		memcpy(st->data, b, blen);
 		ret = usb_control_msg(d->udev,
 			usb_rcvctrlpipe(d->udev,0),
 			req,
 			USB_TYPE_VENDOR | USB_DIR_IN,
-			value,index,b,blen,
+			value, index, st->data, blen,
 			2000);
 		deb_info("reading number %d (ret: %d)\n",try,ret);
 		try++;
@@ -86,6 +92,7 @@ int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8
 int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
 			     u16 index, u8 *b, int blen)
 {
+	struct gp8psk_state *st = d->priv;
 	int ret;
 
 	deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
@@ -94,11 +101,12 @@ int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
 	if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
 		return ret;
 
+	memcpy(st->data, b, blen);
 	if (usb_control_msg(d->udev,
 			usb_sndctrlpipe(d->udev,0),
 			req,
 			USB_TYPE_VENDOR | USB_DIR_OUT,
-			value,index,b,blen,
+			value,index, st->data, blen,
 			2000) != blen) {
 		warn("usb out operation failed.");
 		ret = -EIO;
@@ -265,6 +273,8 @@ static struct dvb_usb_device_properties gp8psk_properties = {
 	.usb_ctrl = CYPRESS_FX2,
 	.firmware = "dvb-usb-gp8psk-01.fw",
 
+	.size_of_priv = sizeof(struct gp8psk_state),
+
 	.num_adapters = 1,
 	.adapter = {
 		{
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1497411 — [PATCH 23/26] dvb-usb: warn if return value for USB read/write routines is not checked

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-07 19:40 +0200
Subject[PATCH 23/26] dvb-usb: warn if return value for USB read/write routines is not checked
Message-ID<spHhM-3I7-13@gated-at.bofh.it>
In reply to#1497395
the return values for dvb_usb_generic_rw() and dvb_usb_generic_write()
should be checked, as otherwise the drivers won't be doing the right
thing in the case of errors.

So, add __must_check to both declarations.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
 drivers/media/usb/dvb-usb/dvb-usb.h | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/media/usb/dvb-usb/dvb-usb.h b/drivers/media/usb/dvb-usb/dvb-usb.h
index 639c4678c65b..1448c3d27ea2 100644
--- a/drivers/media/usb/dvb-usb/dvb-usb.h
+++ b/drivers/media/usb/dvb-usb/dvb-usb.h
@@ -462,8 +462,10 @@ extern int dvb_usb_device_init(struct usb_interface *,
 extern void dvb_usb_device_exit(struct usb_interface *);
 
 /* the generic read/write method for device control */
-extern int dvb_usb_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16,int);
-extern int dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16);
+extern int __must_check
+dvb_usb_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16, int);
+extern int __must_check
+dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16);
 
 /* commonly used remote control parsing */
 extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *);
-- 
2.7.4

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web