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


Groups > linux.kernel > #1498706 > unrolled thread

[PATCH v2 00/31] Don't use stack for DMA transers on media usb drivers

Started byMauro Carvalho Chehab <mchehab@s-opensource.com>
First post2016-10-11 12:20 +0200
Last post2016-10-11 12:20 +0200
Articles 11 on this page of 31 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v2 00/31]  Don't use stack for DMA transers on media usb drivers Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 04/31] cinergyT2-fe: cache stats at cinergyt2_fe_read_status() Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 05/31] cinergyT2-fe: don't do DMA on stack Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 29/31] s2255drv: don't use stack for DMA Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 26/31] dw2102: return error if su3000_power_ctrl() fails Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 30/31] stk-webcam: don't use stack for DMA Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 28/31] cpia2_usb: don't use stack for DMA Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
      Re: [PATCH v2 28/31] cpia2_usb: don't use stack for DMA  Kosuke Tatsukawa <tatsu@ab.jp.nec.com> - 2016-10-12 01:00 +0200
        [PATCH v2 .1 28/31] cpia2_usb: don't use stack for DMA Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-12 04:20 +0200
        Re: [PATCH v2 28/31] cpia2_usb: don't use stack for DMA Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-12 04:20 +0200
    [PATCH v2 01/31] af9005: don't do DMA on stack Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 15/31] dtt200u: don't do DMA on stack Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 24/31] dvb-usb: warn if return value for USB read/write routines is not checked Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 02/31] cinergyT2-core: don't do DMA on stack Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 07/31] dib0700: be sure that dib0700_ctrl_rd() users can do DMA Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 11/31] digitv: don't do DMA on stack Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 17/31] dtv5100: don't do DMA on stack Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 25/31] nova-t-usb2: handle error code on RC query Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 18/31] gp8psk: don't do DMA on stack Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 20/31] nova-t-usb2: don't do DMA on stack Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 31/31] flexcop-usb: don't use stack for DMA Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 22/31] pctv452e: don't call BUG_ON() on non-fatal error Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 10/31] dibusb: handle error code on RC query Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 27/31] digitv: handle error code on RC query Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 16/31] dtt200u: handle USB control message errors Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 13/31] dtt200u-fe: don't do DMA on stack Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 21/31] pctv452e: don't do DMA on stack Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 19/31] gp8psk: don't go past the buffer size Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 12/31] dtt200u-fe: don't keep waiting for lock at set_frontend() Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 08/31] dib0700_core: don't use stack on I2C reads Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200
    [PATCH v2 06/31] cxusb: don't do DMA on stack Mauro Carvalho Chehab <mchehab@s-opensource.com> - 2016-10-11 12:20 +0200

Page 2 of 2 — ← Prev page 1 [2]


#1498724 — [PATCH v2 31/31] flexcop-usb: don't use stack for DMA

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-11 12:20 +0200
Subject[PATCH v2 31/31] flexcop-usb: don't use stack for DMA
Message-ID<sr2kb-5sy-49@gated-at.bofh.it>
In reply to#1498706
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.

While here, remove a dead function calling usb_control_msg().

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
 drivers/media/usb/b2c2/flexcop-usb.c | 105 +++++++++++++++++++++++------------
 drivers/media/usb/b2c2/flexcop-usb.h |   4 ++
 2 files changed, 72 insertions(+), 37 deletions(-)

diff --git a/drivers/media/usb/b2c2/flexcop-usb.c b/drivers/media/usb/b2c2/flexcop-usb.c
index d4bdba60b0f7..f26fc530564b 100644
--- a/drivers/media/usb/b2c2/flexcop-usb.c
+++ b/drivers/media/usb/b2c2/flexcop-usb.c
@@ -73,23 +73,34 @@ static int flexcop_usb_readwrite_dw(struct flexcop_device *fc, u16 wRegOffsPCI,
 	u8 request_type = (read ? USB_DIR_IN : USB_DIR_OUT) | USB_TYPE_VENDOR;
 	u8 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) |
 		(read ? 0x80 : 0);
+	int ret;
 
-	int len = usb_control_msg(fc_usb->udev,
+	mutex_lock(&fc_usb->data_mutex);
+	if (!read)
+		memcpy(fc_usb->data, val, sizeof(*val));
+
+	ret = usb_control_msg(fc_usb->udev,
 			read ? B2C2_USB_CTRL_PIPE_IN : B2C2_USB_CTRL_PIPE_OUT,
 			request,
 			request_type, /* 0xc0 read or 0x40 write */
 			wAddress,
 			0,
-			val,
+			fc_usb->data,
 			sizeof(u32),
 			B2C2_WAIT_FOR_OPERATION_RDW * HZ);
 
-	if (len != sizeof(u32)) {
+	if (ret != sizeof(u32)) {
 		err("error while %s dword from %d (%d).", read ? "reading" :
 				"writing", wAddress, wRegOffsPCI);
-		return -EIO;
+		if (ret >= 0)
+			ret = -EIO;
 	}
-	return 0;
+
+	if (read && ret >= 0)
+		memcpy(val, fc_usb->data, sizeof(*val));
+	mutex_unlock(&fc_usb->data_mutex);
+
+	return ret;
 }
 /*
  * DKT 010817 - add support for V8 memory read/write and flash update
@@ -100,9 +111,14 @@ static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb,
 {
 	u8 request_type = USB_TYPE_VENDOR;
 	u16 wIndex;
-	int nWaitTime, pipe, len;
+	int nWaitTime, pipe, ret;
 	wIndex = page << 8;
 
+	if (buflen > sizeof(fc_usb->data)) {
+		err("Buffer size bigger than max URB control message\n");
+		return -EIO;
+	}
+
 	switch (req) {
 	case B2C2_USB_READ_V8_MEM:
 		nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ;
@@ -127,17 +143,32 @@ static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb,
 	deb_v8("v8mem: %02x %02x %04x %04x, len: %d\n", request_type, req,
 			wAddress, wIndex, buflen);
 
-	len = usb_control_msg(fc_usb->udev, pipe,
+	mutex_lock(&fc_usb->data_mutex);
+
+	if ((request_type & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)
+		memcpy(fc_usb->data, pbBuffer, buflen);
+
+	ret = usb_control_msg(fc_usb->udev, pipe,
 			req,
 			request_type,
 			wAddress,
 			wIndex,
-			pbBuffer,
+			fc_usb->data,
 			buflen,
 			nWaitTime * HZ);
+	if (ret != buflen)
+		ret = -EIO;
 
-	debug_dump(pbBuffer, len, deb_v8);
-	return len == buflen ? 0 : -EIO;
+	if (ret >= 0) {
+		ret = 0;
+		if ((request_type & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
+			memcpy(pbBuffer, fc_usb->data, buflen);
+	}
+
+	mutex_unlock(&fc_usb->data_mutex);
+
+	debug_dump(pbBuffer, ret, deb_v8);
+	return ret;
 }
 
 #define bytes_left_to_read_on_page(paddr,buflen) \
@@ -196,29 +227,6 @@ static int flexcop_usb_get_mac_addr(struct flexcop_device *fc, int extended)
 		fc->dvb_adapter.proposed_mac, 6);
 }
 
-#if 0
-static int flexcop_usb_utility_req(struct flexcop_usb *fc_usb, int set,
-		flexcop_usb_utility_function_t func, u8 extra, u16 wIndex,
-		u16 buflen, u8 *pvBuffer)
-{
-	u16 wValue;
-	u8 request_type = (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR;
-	int nWaitTime = 2,
-	    pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN, len;
-	wValue = (func << 8) | extra;
-
-	len = usb_control_msg(fc_usb->udev,pipe,
-			B2C2_USB_UTILITY,
-			request_type,
-			wValue,
-			wIndex,
-			pvBuffer,
-			buflen,
-			nWaitTime * HZ);
-	return len == buflen ? 0 : -EIO;
-}
-#endif
-
 /* usb i2c stuff */
 static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c,
 		flexcop_usb_request_t req, flexcop_usb_i2c_function_t func,
@@ -226,9 +234,14 @@ static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c,
 {
 	struct flexcop_usb *fc_usb = i2c->fc->bus_specific;
 	u16 wValue, wIndex;
-	int nWaitTime,pipe,len;
+	int nWaitTime, pipe, ret;
 	u8 request_type = USB_TYPE_VENDOR;
 
+	if (buflen > sizeof(fc_usb->data)) {
+		err("Buffer size bigger than max URB control message\n");
+		return -EIO;
+	}
+
 	switch (func) {
 	case USB_FUNC_I2C_WRITE:
 	case USB_FUNC_I2C_MULTIWRITE:
@@ -257,15 +270,32 @@ static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c,
 			wValue & 0xff, wValue >> 8,
 			wIndex & 0xff, wIndex >> 8);
 
-	len = usb_control_msg(fc_usb->udev,pipe,
+	mutex_lock(&fc_usb->data_mutex);
+
+	if ((request_type & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)
+		memcpy(fc_usb->data, buf, buflen);
+
+	ret = usb_control_msg(fc_usb->udev,pipe,
 			req,
 			request_type,
 			wValue,
 			wIndex,
-			buf,
+			fc_usb->data,
 			buflen,
 			nWaitTime * HZ);
-	return len == buflen ? 0 : -EREMOTEIO;
+
+	if (ret != buflen)
+		ret = -EIO;
+
+	if (ret >= 0) {
+		ret = 0;
+		if ((request_type & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
+			memcpy(buf, fc_usb->data, buflen);
+	}
+
+	mutex_unlock(&fc_usb->data_mutex);
+
+	return 0;
 }
 
 /* actual bus specific access functions,
@@ -516,6 +546,7 @@ static int flexcop_usb_probe(struct usb_interface *intf,
 	/* general flexcop init */
 	fc_usb = fc->bus_specific;
 	fc_usb->fc_dev = fc;
+	mutex_init(&fc_usb->data_mutex);
 
 	fc->read_ibi_reg  = flexcop_usb_read_ibi_reg;
 	fc->write_ibi_reg = flexcop_usb_write_ibi_reg;
diff --git a/drivers/media/usb/b2c2/flexcop-usb.h b/drivers/media/usb/b2c2/flexcop-usb.h
index 92529a9c4475..25ad43166e78 100644
--- a/drivers/media/usb/b2c2/flexcop-usb.h
+++ b/drivers/media/usb/b2c2/flexcop-usb.h
@@ -29,6 +29,10 @@ struct flexcop_usb {
 
 	u8 tmp_buffer[1023+190];
 	int tmp_buffer_length;
+
+	/* for URB control messages */
+	u8 data[80];
+	struct mutex data_mutex;
 };
 
 #if 0
-- 
2.7.4

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


#1498726 — [PATCH v2 22/31] pctv452e: don't call BUG_ON() on non-fatal error

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-11 12:20 +0200
Subject[PATCH v2 22/31] pctv452e: don't call BUG_ON() on non-fatal error
Message-ID<sr2kb-5sy-55@gated-at.bofh.it>
In reply to#1498706
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 | 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 58b685094904..7ad0006c5ae0 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;
+	};
 
 	mutex_lock(&state->ca_mutex);
 	id = state->c++;
-- 
2.7.4

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


#1498727 — [PATCH v2 10/31] dibusb: handle error code on RC query

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-11 12:20 +0200
Subject[PATCH v2 10/31] dibusb: handle error code on RC query
Message-ID<sr2kb-5sy-61@gated-at.bofh.it>
In reply to#1498706
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/dibusb-common.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/media/usb/dvb-usb/dibusb-common.c b/drivers/media/usb/dvb-usb/dibusb-common.c
index 951f3dac9082..b0fd9a609352 100644
--- a/drivers/media/usb/dvb-usb/dibusb-common.c
+++ b/drivers/media/usb/dvb-usb/dibusb-common.c
@@ -366,6 +366,7 @@ EXPORT_SYMBOL(rc_map_dibusb_table);
 int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 {
 	u8 *buf;
+	int ret;
 
 	buf = kmalloc(5, GFP_KERNEL);
 	if (!buf)
@@ -373,7 +374,9 @@ int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 
 	buf[0] = DIBUSB_REQ_POLL_REMOTE;
 
-	dvb_usb_generic_rw(d, buf, 1, buf, 5, 0);
+	ret = dvb_usb_generic_rw(d, buf, 1, buf, 5, 0);
+	if (ret < 0)
+		goto ret;
 
 	dvb_usb_nec_rc_key_to_event(d, buf, event, state);
 
@@ -382,6 +385,7 @@ int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 
 	kfree(buf);
 
-	return 0;
+ret:
+	return ret;
 }
 EXPORT_SYMBOL(dibusb_rc_query);
-- 
2.7.4

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


#1498728 — [PATCH v2 27/31] digitv: handle error code on RC query

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-11 12:20 +0200
Subject[PATCH v2 27/31] digitv: handle error code on RC query
Message-ID<sr2kb-5sy-63@gated-at.bofh.it>
In reply to#1498706
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]


#1498729 — [PATCH v2 16/31] dtt200u: handle USB control message errors

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-11 12:20 +0200
Subject[PATCH v2 16/31] dtt200u: handle USB control message errors
Message-ID<sr2kb-5sy-43@gated-at.bofh.it>
In reply to#1498706
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 | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/media/usb/dvb-usb/dtt200u.c b/drivers/media/usb/dvb-usb/dtt200u.c
index 7706938b5167..f88572c7ae7c 100644
--- a/drivers/media/usb/dvb-usb/dtt200u.c
+++ b/drivers/media/usb/dvb-usb/dtt200u.c
@@ -28,37 +28,42 @@ struct dtt200u_state {
 static int dtt200u_power_ctrl(struct dvb_usb_device *d, int onoff)
 {
 	struct dtt200u_state *st = d->priv;
+	int ret = 0;
 
 	mutex_lock(&st->data_mutex);
 
 	st->data[0] = SET_INIT;
 
 	if (onoff)
-		dvb_usb_generic_write(d, st->data, 2);
+		ret = dvb_usb_generic_write(d, st->data, 2);
 
 	mutex_unlock(&st->data_mutex);
-	return 0;
+	return ret;
 }
 
 static int dtt200u_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 {
 	struct dtt200u_state *st = adap->dev->priv;
+	int ret;
 
 	mutex_lock(&st->data_mutex);
 	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)
+		goto ret;
 
 	if (onoff)
-		return 0;
+		goto ret;
 
 	st->data[0] = RESET_PID_FILTER;
-	dvb_usb_generic_write(adap->dev, st->data, 1);
+	ret = dvb_usb_generic_write(adap->dev, st->data, 1);
 
+ret:
 	mutex_unlock(&st->data_mutex);
 
-	return 0;
+	return ret;
 }
 
 static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
@@ -84,11 +89,15 @@ static int dtt200u_rc_query(struct dvb_usb_device *d)
 {
 	struct dtt200u_state *st = d->priv;
 	u32 scancode;
+	int ret;
 
 	mutex_lock(&st->data_mutex);
 	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)
+		goto ret;
+
 	if (st->data[0] == 1) {
 		enum rc_type proto = RC_TYPE_NEC;
 
@@ -116,8 +125,9 @@ static int dtt200u_rc_query(struct dvb_usb_device *d)
 	if (st->data[0] != 0)
 		deb_info("st->data: %*ph\n", 5, st->data);
 
+ret:
 	mutex_unlock(&st->data_mutex);
-	return 0;
+	return ret;
 }
 
 static int dtt200u_frontend_attach(struct dvb_usb_adapter *adap)
-- 
2.7.4

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


#1498730 — [PATCH v2 13/31] dtt200u-fe: don't do DMA on stack

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-11 12:20 +0200
Subject[PATCH v2 13/31] dtt200u-fe: don't do DMA on stack
Message-ID<sr2kb-5sy-53@gated-at.bofh.it>
In reply to#1498706
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/dtt200u-fe.c | 95 +++++++++++++++++++++++-----------
 1 file changed, 65 insertions(+), 30 deletions(-)

diff --git a/drivers/media/usb/dvb-usb/dtt200u-fe.c b/drivers/media/usb/dvb-usb/dtt200u-fe.c
index 9bb15f7b48db..7f7f64be6353 100644
--- a/drivers/media/usb/dvb-usb/dtt200u-fe.c
+++ b/drivers/media/usb/dvb-usb/dtt200u-fe.c
@@ -18,17 +18,22 @@ struct dtt200u_fe_state {
 
 	struct dtv_frontend_properties fep;
 	struct dvb_frontend frontend;
+
+	unsigned char data[80];
+	struct mutex data_mutex;
 };
 
 static int dtt200u_fe_read_status(struct dvb_frontend *fe,
 				  enum fe_status *stat)
 {
 	struct dtt200u_fe_state *state = fe->demodulator_priv;
-	u8 st = GET_TUNE_STATUS, b[3];
 
-	dvb_usb_generic_rw(state->d,&st,1,b,3,0);
+	mutex_lock(&state->data_mutex);
+	state->data[0] = GET_TUNE_STATUS;
 
-	switch (b[0]) {
+	dvb_usb_generic_rw(state->d, state->data, 1, state->data, 3, 0);
+
+	switch (state->data[0]) {
 		case 0x01:
 			*stat = FE_HAS_SIGNAL | FE_HAS_CARRIER |
 				FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
@@ -41,51 +46,75 @@ static int dtt200u_fe_read_status(struct dvb_frontend *fe,
 			*stat = 0;
 			break;
 	}
+	mutex_unlock(&state->data_mutex);
 	return 0;
 }
 
 static int dtt200u_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
 {
 	struct dtt200u_fe_state *state = fe->demodulator_priv;
-	u8 bw = GET_VIT_ERR_CNT,b[3];
-	dvb_usb_generic_rw(state->d,&bw,1,b,3,0);
-	*ber = (b[0] << 16) | (b[1] << 8) | b[2];
+
+	mutex_lock(&state->data_mutex);
+	state->data[0] = GET_VIT_ERR_CNT;
+
+	dvb_usb_generic_rw(state->d, state->data, 1, state->data, 3, 0);
+	*ber = (state->data[0] << 16) | (state->data[1] << 8) | state->data[2];
+
+	mutex_unlock(&state->data_mutex);
 	return 0;
 }
 
 static int dtt200u_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
 {
 	struct dtt200u_fe_state *state = fe->demodulator_priv;
-	u8 bw = GET_RS_UNCOR_BLK_CNT,b[2];
 
-	dvb_usb_generic_rw(state->d,&bw,1,b,2,0);
-	*unc = (b[0] << 8) | b[1];
-	return 0;
+	mutex_lock(&state->data_mutex);
+	state->data[0] = GET_RS_UNCOR_BLK_CNT;
+
+	dvb_usb_generic_rw(state->d, state->data, 1, state->data, 2, 0);
+
+	mutex_unlock(&state->data_mutex);
+	return ret;
 }
 
 static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
 {
 	struct dtt200u_fe_state *state = fe->demodulator_priv;
-	u8 bw = GET_AGC, b;
-	dvb_usb_generic_rw(state->d,&bw,1,&b,1,0);
-	*strength = (b << 8) | b;
-	return 0;
+
+	mutex_lock(&state->data_mutex);
+	state->data[0] = GET_AGC;
+
+	dvb_usb_generic_rw(state->d, state->data, 1, state->data, 1, 0);
+
+	mutex_unlock(&state->data_mutex);
+	return ret;
 }
 
 static int dtt200u_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
 {
 	struct dtt200u_fe_state *state = fe->demodulator_priv;
-	u8 bw = GET_SNR,br;
-	dvb_usb_generic_rw(state->d,&bw,1,&br,1,0);
-	*snr = ~((br << 8) | br);
-	return 0;
+
+	mutex_lock(&state->data_mutex);
+	state->data[0] = GET_SNR;
+
+	dvb_usb_generic_rw(state->d, state->data, 1, state->data, 1, 0);
+
+	mutex_unlock(&state->data_mutex);
+	return ret;
 }
 
 static int dtt200u_fe_init(struct dvb_frontend* fe)
 {
 	struct dtt200u_fe_state *state = fe->demodulator_priv;
-	u8 b = SET_INIT;
-	return dvb_usb_generic_write(state->d,&b,1);
+	int ret;
+
+	mutex_lock(&state->data_mutex);
+	state->data[0] = SET_INIT;
+
+	ret = dvb_usb_generic_write(state->d, state->data, 1);
+	mutex_unlock(&state->data_mutex);
+
+	return ret;
 }
 
 static int dtt200u_fe_sleep(struct dvb_frontend* fe)
@@ -106,29 +135,34 @@ static int dtt200u_fe_set_frontend(struct dvb_frontend *fe)
 	struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
 	struct dtt200u_fe_state *state = fe->demodulator_priv;
 	u16 freq = fep->frequency / 250000;
-	u8 bwbuf[2] = { SET_BANDWIDTH, 0 },freqbuf[3] = { SET_RF_FREQ, 0, 0 };
 
+	mutex_lock(&state->data_mutex);
+	state->data[0] = SET_BANDWIDTH;
 	switch (fep->bandwidth_hz) {
 	case 8000000:
-		bwbuf[1] = 8;
+		state->data[1] = 8;
 		break;
 	case 7000000:
-		bwbuf[1] = 7;
+		state->data[1] = 7;
 		break;
 	case 6000000:
-		bwbuf[1] = 6;
+		state->data[1] = 6;
 		break;
 	default:
-		return -EINVAL;
+		ret = -EINVAL;
+		goto ret;
 	}
 
-	dvb_usb_generic_write(state->d,bwbuf,2);
+	dvb_usb_generic_write(state->d, state->data, 2);
 
-	freqbuf[1] = freq & 0xff;
-	freqbuf[2] = (freq >> 8) & 0xff;
-	dvb_usb_generic_write(state->d,freqbuf,3);
+	state->data[0] = SET_RF_FREQ;
+	state->data[1] = freq & 0xff;
+	state->data[2] = (freq >> 8) & 0xff;
+	dvb_usb_generic_write(state->d, state->data, 3);
 
-	return 0;
+ret:
+	mutex_unlock(&state->data_mutex);
+	return ret;
 }
 
 static int dtt200u_fe_get_frontend(struct dvb_frontend* fe,
@@ -160,6 +194,7 @@ struct dvb_frontend* dtt200u_fe_attach(struct dvb_usb_device *d)
 	deb_info("attaching frontend dtt200u\n");
 
 	state->d = d;
+	mutex_init(&state->data_mutex);
 
 	memcpy(&state->frontend.ops,&dtt200u_fe_ops,sizeof(struct dvb_frontend_ops));
 	state->frontend.demodulator_priv = state;
-- 
2.7.4

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


#1498731 — [PATCH v2 21/31] pctv452e: don't do DMA on stack

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-11 12:20 +0200
Subject[PATCH v2 21/31] pctv452e: don't do DMA on stack
Message-ID<sr2kb-5sy-57@gated-at.bofh.it>
In reply to#1498706
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>
---
 drivers/media/usb/dvb-usb/pctv452e.c | 129 ++++++++++++++++++++---------------
 1 file changed, 74 insertions(+), 55 deletions(-)

diff --git a/drivers/media/usb/dvb-usb/pctv452e.c b/drivers/media/usb/dvb-usb/pctv452e.c
index c05de1b088a4..58b685094904 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;
@@ -112,33 +113,36 @@ static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data,
 	BUG_ON(write_len > 64 - 4);
 	BUG_ON(read_len > 64 - 4);
 
+	mutex_lock(&state->ca_mutex);
 	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);
 
+	mutex_unlock(&state->ca_mutex);
 	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);
 
+	mutex_unlock(&state->ca_mutex);
 	return ret;
 }
 
@@ -405,52 +409,53 @@ 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;
 
+	mutex_lock(&state->ca_mutex);
 	id = state->c++;
 
 	ret = -EINVAL;
 	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);
+	mutex_unlock(&state->ca_mutex);
 
 	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);
 
+	mutex_unlock(&state->ca_mutex);
 	return ret;
 }
 
@@ -499,8 +504,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 +515,11 @@ static int pctv452e_power_ctrl(struct dvb_usb_device *d, int i)
 	if (state->initialized)
 		return 0;
 
+	rx = kmalloc(PCTV_ANSWER_LEN, GFP_KERNEL);
+	if (!rx)
+		return -ENOMEM;
+
+	mutex_lock(&state->ca_mutex);
 	/* hmm where shoud this should go? */
 	ret = usb_set_interface(d->udev, 0, ISOC_INTERFACE_ALTERNATIVE);
 	if (ret != 0)
@@ -518,65 +527,75 @@ static int pctv452e_power_ctrl(struct dvb_usb_device *d, int i)
 			__func__, ret);
 
 	/* this is a one-time initialization, dont know where to put */
-	b0[1] = state->c++;
+	state->data[0] = 0xaa;
+	state->data[1] = state->c++;
+	state->data[2] = PCTV_CMD_RESET;
+	state->data[3] = 1;
+	state->data[4] = 0;
 	/* reset board */
-	ret = dvb_usb_generic_rw(d, b0, sizeof(b0), rx, PCTV_ANSWER_LEN, 0);
+	ret = dvb_usb_generic_rw(d, state->data, 5, rx, PCTV_ANSWER_LEN, 0);
 	if (ret)
-		return ret;
+		goto ret;
 
-	b0[1] = state->c++;
-	b0[4] = 1;
+	state->data[1] = state->c++;
+	state->data[4] = 1;
 	/* reset board (again?) */
-	ret = dvb_usb_generic_rw(d, b0, sizeof(b0), rx, PCTV_ANSWER_LEN, 0);
+	ret = dvb_usb_generic_rw(d, state->data, 5, rx, PCTV_ANSWER_LEN, 0);
 	if (ret)
-		return ret;
+		goto ret;
 
 	state->initialized = 1;
 
-	return 0;
+ret:
+	mutex_unlock(&state->ca_mutex);
+	kfree(rx);
+	return ret;
 }
 
 static int pctv452e_rc_query(struct dvb_usb_device *d)
 {
 	struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
-	u8 b[CMD_BUFFER_SIZE];
-	u8 rx[PCTV_ANSWER_LEN];
 	int ret, i;
-	u8 id = state->c++;
+	u8 id;
+
+	mutex_lock(&state->ca_mutex);
+	id = state->c++;
 
 	/* prepare command header  */
-	b[0] = SYNC_BYTE_OUT;
-	b[1] = id;
-	b[2] = PCTV_CMD_IR;
-	b[3] = 0;
+	state->data[0] = SYNC_BYTE_OUT;
+	state->data[1] = id;
+	state->data[2] = PCTV_CMD_IR;
+	state->data[3] = 0;
 
 	/* send ir request */
-	ret = dvb_usb_generic_rw(d, b, 4, rx, PCTV_ANSWER_LEN, 0);
+	ret = dvb_usb_generic_rw(d, state->data, 4,
+				 state->data, PCTV_ANSWER_LEN, 0);
 	if (ret != 0)
-		return ret;
+		goto ret;
 
 	if (debug > 3) {
-		info("%s: read: %2d: %*ph: ", __func__, ret, 3, rx);
-		for (i = 0; (i < rx[3]) && ((i+3) < PCTV_ANSWER_LEN); i++)
-			info(" %02x", rx[i+3]);
+		info("%s: read: %2d: %*ph: ", __func__, ret, 3, state->data);
+		for (i = 0; (i < state->data[3]) && ((i + 3) < PCTV_ANSWER_LEN); i++)
+			info(" %02x", state->data[i + 3]);
 
 		info("\n");
 	}
 
-	if ((rx[3] == 9) &&  (rx[12] & 0x01)) {
+	if ((state->data[3] == 9) &&  (state->data[12] & 0x01)) {
 		/* got a "press" event */
-		state->last_rc_key = RC_SCANCODE_RC5(rx[7], rx[6]);
+		state->last_rc_key = RC_SCANCODE_RC5(state->data[7], state->data[6]);
 		if (debug > 2)
 			info("%s: cmd=0x%02x sys=0x%02x\n",
-				__func__, rx[6], rx[7]);
+				__func__, state->data[6], state->data[7]);
 
 		rc_keydown(d->rc_dev, RC_TYPE_RC5, state->last_rc_key, 0);
 	} else if (state->last_rc_key) {
 		rc_keyup(d->rc_dev);
 		state->last_rc_key = 0;
 	}
-
-	return 0;
+ret:
+	mutex_unlock(&state->ca_mutex);
+	return ret;
 }
 
 static int pctv452e_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
-- 
2.7.4

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


#1498732 — [PATCH v2 19/31] gp8psk: don't go past the buffer size

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-11 12:20 +0200
Subject[PATCH v2 19/31] gp8psk: don't go past the buffer size
Message-ID<sr2kb-5sy-67@gated-at.bofh.it>
In reply to#1498706
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]


#1498733 — [PATCH v2 12/31] dtt200u-fe: don't keep waiting for lock at set_frontend()

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-11 12:20 +0200
Subject[PATCH v2 12/31] dtt200u-fe: don't keep waiting for lock at set_frontend()
Message-ID<sr2kb-5sy-59@gated-at.bofh.it>
In reply to#1498706
It is up to the frontend kthread to wait for lock.

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

diff --git a/drivers/media/usb/dvb-usb/dtt200u-fe.c b/drivers/media/usb/dvb-usb/dtt200u-fe.c
index c09332bd99cb..9bb15f7b48db 100644
--- a/drivers/media/usb/dvb-usb/dtt200u-fe.c
+++ b/drivers/media/usb/dvb-usb/dtt200u-fe.c
@@ -105,8 +105,6 @@ static int dtt200u_fe_set_frontend(struct dvb_frontend *fe)
 {
 	struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
 	struct dtt200u_fe_state *state = fe->demodulator_priv;
-	int i;
-	enum fe_status st;
 	u16 freq = fep->frequency / 250000;
 	u8 bwbuf[2] = { SET_BANDWIDTH, 0 },freqbuf[3] = { SET_RF_FREQ, 0, 0 };
 
@@ -130,13 +128,6 @@ static int dtt200u_fe_set_frontend(struct dvb_frontend *fe)
 	freqbuf[2] = (freq >> 8) & 0xff;
 	dvb_usb_generic_write(state->d,freqbuf,3);
 
-	for (i = 0; i < 30; i++) {
-		msleep(20);
-		dtt200u_fe_read_status(fe, &st);
-		if (st & FE_TIMEDOUT)
-			continue;
-	}
-
 	return 0;
 }
 
-- 
2.7.4

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


#1498734 — [PATCH v2 08/31] dib0700_core: don't use stack on I2C reads

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-11 12:20 +0200
Subject[PATCH v2 08/31] dib0700_core: don't use stack on I2C reads
Message-ID<sr2kb-5sy-65@gated-at.bofh.it>
In reply to#1498706
Be sure that I2C reads won't use stack by passing
a pointer to the state buffer, that we know it was
allocated via kmalloc, instead of relying on the buffer
allocated by an I2C client.

Reviewed-By: Patrick Boettcher <patrick.boettcher@posteo.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
---
 drivers/media/usb/dvb-usb/dib0700_core.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c
index 515f89dba199..92d5408684ac 100644
--- a/drivers/media/usb/dvb-usb/dib0700_core.c
+++ b/drivers/media/usb/dvb-usb/dib0700_core.c
@@ -213,7 +213,7 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
 						 usb_rcvctrlpipe(d->udev, 0),
 						 REQUEST_NEW_I2C_READ,
 						 USB_TYPE_VENDOR | USB_DIR_IN,
-						 value, index, msg[i].buf,
+						 value, index, st->buf,
 						 msg[i].len,
 						 USB_CTRL_GET_TIMEOUT);
 			if (result < 0) {
@@ -221,6 +221,14 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
 				break;
 			}
 
+			if (msg[i].len > sizeof(st->buf)) {
+				deb_info("buffer too small to fit %d bytes\n",
+					 msg[i].len);
+				return -EIO;
+			}
+
+			memcpy(msg[i].buf, st->buf, msg[i].len);
+
 			deb_data("<<< ");
 			debug_dump(msg[i].buf, msg[i].len, deb_data);
 
@@ -238,6 +246,13 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
 			/* I2C ctrl + FE bus; */
 			st->buf[3] = ((gen_mode << 6) & 0xC0) |
 				 ((bus_mode << 4) & 0x30);
+
+			if (msg[i].len > sizeof(st->buf) - 4) {
+				deb_info("i2c message to big: %d\n",
+					 msg[i].len);
+				return -EIO;
+			}
+
 			/* The Actual i2c payload */
 			memcpy(&st->buf[4], msg[i].buf, msg[i].len);
 
@@ -283,6 +298,11 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
 		/* fill in the address */
 		st->buf[1] = msg[i].addr << 1;
 		/* fill the buffer */
+		if (msg[i].len > sizeof(st->buf) - 2) {
+			deb_info("i2c xfer to big: %d\n",
+				msg[i].len);
+			return -EIO;
+		}
 		memcpy(&st->buf[2], msg[i].buf, msg[i].len);
 
 		/* write/read request */
@@ -299,6 +319,11 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
 				break;
 			}
 
+			if (msg[i + 1].len > sizeof(st->buf)) {
+				deb_info("i2c xfer buffer to small for %d\n",
+					msg[i].len);
+				return -EIO;
+			}
 			memcpy(msg[i + 1].buf, st->buf, msg[i + 1].len);
 
 			msg[i+1].len = len;
-- 
2.7.4

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


#1498735 — [PATCH v2 06/31] cxusb: don't do DMA on stack

FromMauro Carvalho Chehab <mchehab@s-opensource.com>
Date2016-10-11 12:20 +0200
Subject[PATCH v2 06/31] cxusb: don't do DMA on stack
Message-ID<sr2kb-5sy-69@gated-at.bofh.it>
In reply to#1498706
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>
---
 drivers/media/usb/dvb-usb/cxusb.c | 62 ++++++++++++++++++++++-----------------
 drivers/media/usb/dvb-usb/cxusb.h |  6 ++++
 2 files changed, 41 insertions(+), 27 deletions(-)

diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c
index 907ac01ae297..39772812269d 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,27 @@ 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)
 {
-	int wo = (rbuf == NULL || rlen == 0); /* write-only */
-	u8 sndbuf[MAX_XFER_SIZE];
+	struct cxusb_state *st = d->priv;
+	int ret, wo;
 
-	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);
+	wo = (rbuf == NULL || rlen == 0); /* write-only */
 
-	sndbuf[0] = cmd;
-	memcpy(&sndbuf[1], wbuf, wlen);
+	mutex_lock(&st->data_mutex);
+	st->data[0] = cmd;
+	memcpy(&st->data[1], wbuf, wlen);
 	if (wo)
-		return dvb_usb_generic_write(d, sndbuf, 1+wlen);
+		ret = dvb_usb_generic_write(d, st->data, 1 + wlen);
 	else
-		return dvb_usb_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen, 0);
+		ret = dvb_usb_generic_rw(d, st->data, 1 + wlen,
+					 rbuf, rlen, 0);
+
+	mutex_unlock(&st->data_mutex);
+	return ret;
 }
 
 /* GPIO */
@@ -1460,36 +1461,43 @@ static struct dvb_usb_device_properties cxusb_mygica_t230_properties;
 static int cxusb_probe(struct usb_interface *intf,
 		       const struct usb_device_id *id)
 {
+	struct dvb_usb_device *d;
+	struct cxusb_state *st;
+
 	if (0 == dvb_usb_device_init(intf, &cxusb_medion_properties,
-				     THIS_MODULE, NULL, adapter_nr) ||
+				     THIS_MODULE, &d, adapter_nr) ||
 	    0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgh064f_properties,
-				     THIS_MODULE, NULL, adapter_nr) ||
+				     THIS_MODULE, &d, adapter_nr) ||
 	    0 == dvb_usb_device_init(intf, &cxusb_bluebird_dee1601_properties,
-				     THIS_MODULE, NULL, adapter_nr) ||
+				     THIS_MODULE, &d, adapter_nr) ||
 	    0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgz201_properties,
-				     THIS_MODULE, NULL, adapter_nr) ||
+				     THIS_MODULE, &d, adapter_nr) ||
 	    0 == dvb_usb_device_init(intf, &cxusb_bluebird_dtt7579_properties,
-				     THIS_MODULE, NULL, adapter_nr) ||
+				     THIS_MODULE, &d, adapter_nr) ||
 	    0 == dvb_usb_device_init(intf, &cxusb_bluebird_dualdig4_properties,
-				     THIS_MODULE, NULL, adapter_nr) ||
+				     THIS_MODULE, &d, adapter_nr) ||
 	    0 == dvb_usb_device_init(intf, &cxusb_bluebird_nano2_properties,
-				     THIS_MODULE, NULL, adapter_nr) ||
+				     THIS_MODULE, &d, adapter_nr) ||
 	    0 == dvb_usb_device_init(intf,
 				&cxusb_bluebird_nano2_needsfirmware_properties,
-				     THIS_MODULE, NULL, adapter_nr) ||
+				     THIS_MODULE, &d, adapter_nr) ||
 	    0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties,
-				     THIS_MODULE, NULL, adapter_nr) ||
+				     THIS_MODULE, &d, adapter_nr) ||
 	    0 == dvb_usb_device_init(intf,
 				     &cxusb_bluebird_dualdig4_rev2_properties,
-				     THIS_MODULE, NULL, adapter_nr) ||
+				     THIS_MODULE, &d, adapter_nr) ||
 	    0 == dvb_usb_device_init(intf, &cxusb_d680_dmb_properties,
-				     THIS_MODULE, NULL, adapter_nr) ||
+				     THIS_MODULE, &d, adapter_nr) ||
 	    0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties,
-				     THIS_MODULE, NULL, adapter_nr) ||
+				     THIS_MODULE, &d, adapter_nr) ||
 	    0 == dvb_usb_device_init(intf, &cxusb_mygica_t230_properties,
-				     THIS_MODULE, NULL, adapter_nr) ||
-	    0)
+				     THIS_MODULE, &d, adapter_nr) ||
+	    0) {
+		st = d->priv;
+		mutex_init(&st->data_mutex);
+
 		return 0;
+	}
 
 	return -EINVAL;
 }
diff --git a/drivers/media/usb/dvb-usb/cxusb.h b/drivers/media/usb/dvb-usb/cxusb.h
index 527ff7905e15..9f3ee0e47d5c 100644
--- a/drivers/media/usb/dvb-usb/cxusb.h
+++ b/drivers/media/usb/dvb-usb/cxusb.h
@@ -28,10 +28,16 @@
 #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];
+	struct mutex data_mutex;
 };
 
 #endif
-- 
2.7.4

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | linux.kernel


csiph-web