mirror of
https://github.com/Fishwaldo/build.git
synced 2025-03-28 17:51:40 +00:00
171 lines
6.5 KiB
Diff
171 lines
6.5 KiB
Diff
From d04dea80f1c9c2a1e036cc18a791041ce9da0925 Mon Sep 17 00:00:00 2001
|
|
From: jahutchi <jahutchinson99@googlemail.com>
|
|
Date: Fri, 11 Jan 2019 13:35:00 +0000
|
|
Subject: [PATCH] media: m88ds3103: serialize reset messages in m88ds3103_set_frontend
|
|
|
|
Ref: https://bugzilla.kernel.org/show_bug.cgi?id=199323
|
|
|
|
Users are experiencing problems with the DVBSky S960/S960C USB devices
|
|
since the following commit:
|
|
|
|
9d659ae: ("locking/mutex: Add lock handoff to avoid starvation")
|
|
|
|
The device malfunctions after running for an indeterminable period of
|
|
time, and the problem can only be cleared by rebooting the machine.
|
|
|
|
It is possible to encourage the problem to surface by blocking the
|
|
signal to the LNB.
|
|
|
|
Further debugging reveals the cause of the problem.
|
|
|
|
In the following capture:
|
|
- thread #1325 is running m88ds3103_set_frontend
|
|
- thread #42 is running ts2020_stat_work
|
|
|
|
a> [1325] usb 1-1: dvb_usb_v2_generic_io: >>> 08 68 02 07 80
|
|
[1325] usb 1-1: dvb_usb_v2_generic_io: <<< 08
|
|
[42] usb 1-1: dvb_usb_v2_generic_io: >>> 09 01 01 68 3f
|
|
[42] usb 1-1: dvb_usb_v2_generic_io: <<< 08 ff
|
|
[42] usb 1-1: dvb_usb_v2_generic_io: >>> 08 68 02 03 11
|
|
[42] usb 1-1: dvb_usb_v2_generic_io: <<< 07
|
|
[42] usb 1-1: dvb_usb_v2_generic_io: >>> 09 01 01 60 3d
|
|
[42] usb 1-1: dvb_usb_v2_generic_io: <<< 07 ff
|
|
b> [1325] usb 1-1: dvb_usb_v2_generic_io: >>> 08 68 02 07 00
|
|
[1325] usb 1-1: dvb_usb_v2_generic_io: <<< 07
|
|
[42] usb 1-1: dvb_usb_v2_generic_io: >>> 08 68 02 03 11
|
|
[42] usb 1-1: dvb_usb_v2_generic_io: <<< 07
|
|
[42] usb 1-1: dvb_usb_v2_generic_io: >>> 09 01 01 60 21
|
|
[42] usb 1-1: dvb_usb_v2_generic_io: <<< 07 ff
|
|
[42] usb 1-1: dvb_usb_v2_generic_io: >>> 08 68 02 03 11
|
|
[42] usb 1-1: dvb_usb_v2_generic_io: <<< 07
|
|
[42] usb 1-1: dvb_usb_v2_generic_io: >>> 09 01 01 60 66
|
|
[42] usb 1-1: dvb_usb_v2_generic_io: <<< 07 ff
|
|
[1325] usb 1-1: dvb_usb_v2_generic_io: >>> 08 68 02 03 11
|
|
[1325] usb 1-1: dvb_usb_v2_generic_io: <<< 07
|
|
[1325] usb 1-1: dvb_usb_v2_generic_io: >>> 08 60 02 10 0b
|
|
[1325] usb 1-1: dvb_usb_v2_generic_io: <<< 07
|
|
|
|
Two i2c messages are sent to perform a reset in m88ds3103_set_frontend:
|
|
|
|
a. 0x07, 0x80
|
|
b. 0x07, 0x00
|
|
|
|
However, as shown in the capture, the regmap mutex is being handed over
|
|
to another thread (ts2020_stat_work) in between these two messages.
|
|
|
|
From here, the device responds to every i2c message with an 07 message,
|
|
and will only return to normal operation following a power cycle.
|
|
|
|
Use regmap_multi_reg_write to group the two reset messages, ensuring
|
|
both are processed before the regmap mutex is unlocked.
|
|
---
|
|
drivers/media/dvb-frontends/m88ds3103.c | 7 ++-----
|
|
1 file changed, 2 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c
|
|
index dffd2d4bf..e495a26e6 100644
|
|
--- a/drivers/media/dvb-frontends/m88ds3103.c
|
|
+++ b/drivers/media/dvb-frontends/m88ds3103.c
|
|
@@ -309,6 +309,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
|
|
u16 u16tmp;
|
|
u32 tuner_frequency_khz, target_mclk;
|
|
s32 s32tmp;
|
|
+ static const struct reg_sequence reset_buf[] = {{0x07, 0x80}, {0x07, 0x00}};
|
|
|
|
dev_dbg(&client->dev,
|
|
"delivery_system=%d modulation=%d frequency=%u symbol_rate=%d inversion=%d pilot=%d rolloff=%d\n",
|
|
@@ -321,11 +322,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe)
|
|
}
|
|
|
|
/* reset */
|
|
- ret = regmap_write(dev->regmap, 0x07, 0x80);
|
|
- if (ret)
|
|
- goto err;
|
|
-
|
|
- ret = regmap_write(dev->regmap, 0x07, 0x00);
|
|
+ ret = regmap_multi_reg_write(dev->regmap, reset_buf, 2);
|
|
if (ret)
|
|
goto err;
|
|
|
|
|
|
--
|
|
2.7.4
|
|
|
|
From 398be6861aeb95001252a2371ff4c06047dfa276 Mon Sep 17 00:00:00 2001
|
|
From: James Hutchinson <jahutchinson99@googlemail.com>
|
|
Date: Fri, 12 Oct 2018 10:57:34 +0100
|
|
Subject: [PATCH] media: dvbsky: use a single mutex and state buffers for all R/W ops
|
|
|
|
See: https://bugzilla.kernel.org/show_bug.cgi?id=199323
|
|
|
|
This builds on the previous attempt to serialize all R/W ops, which caused bad effects for several users:
|
|
media: dvbsky: use just one mutex for serializing device R/W ops
|
|
|
|
Mutex locking and timeout issues have been reported by several users, on various kernel versions. With the issue seemingly more prevalent on kernel 4.10 and above following changes to the mutex/locking code.
|
|
|
|
Debug tracing shows the device malfunctioning shortly after receiving an extra {10} message in-between the {37 00 00}, {36 03 00} message pair.
|
|
|
|
dvb_usb_v2:dvb_usb_v2_generic_io: usb 1-1: dvb_usb_v2_generic_io: >>> 37 00 00
|
|
dvb_usb_v2:dvb_usb_v2_generic_io: usb 1-1: dvb_usb_v2_generic_io: >>> 10
|
|
dvb_usb_v2:dvb_usb_v2_generic_io: usb 1-1: dvb_usb_v2_generic_io: <<< ff ff
|
|
dvb_usb_v2:dvb_usb_v2_generic_io: usb 1-1: dvb_usb_v2_generic_io: >>> 36 03 00
|
|
...
|
|
m88ds3103:m88ds3103_diseqc_send_master_cmd: m88ds3103 4-0068: diseqc tx timeout
|
|
m88ds3103:m88ds3103_diseqc_send_master_cmd: m88ds3103 4-0068: failed=-110
|
|
|
|
Resolve this by using the single usb_mutex as attempted previously, this time using the obuf state buffer.
|
|
|
|
Also simplify things a little by using dvb_usbv2_generic_write_locked rather than dvb_usbv2_generic_rw_locked.
|
|
---
|
|
drivers/media/usb/dvb-usb-v2/dvbsky.c | 17 ++++++++---------
|
|
1 file changed, 8 insertions(+), 9 deletions(-)
|
|
|
|
diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c
|
|
index 02dbc6c..8de4a86 100644
|
|
--- a/drivers/media/usb/dvb-usb-v2/dvbsky.c
|
|
+++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c
|
|
@@ -35,7 +35,6 @@ MODULE_PARM_DESC(disable_rc, "Disable inbuilt IR receiver.");
|
|
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
|
|
|
|
struct dvbsky_state {
|
|
- struct mutex stream_mutex;
|
|
u8 ibuf[DVBSKY_BUF_LEN];
|
|
u8 obuf[DVBSKY_BUF_LEN];
|
|
u8 last_lock;
|
|
@@ -74,16 +73,18 @@ static int dvbsky_stream_ctrl(struct dvb_usb_device *d, u8 onoff)
|
|
{
|
|
struct dvbsky_state *state = d_to_priv(d);
|
|
int ret;
|
|
- u8 obuf_pre[3] = { 0x37, 0, 0 };
|
|
- u8 obuf_post[3] = { 0x36, 3, 0 };
|
|
+ static u8 obuf_pre[3] = { 0x37, 0, 0 };
|
|
+ static u8 obuf_post[3] = { 0x36, 3, 0 };
|
|
|
|
- mutex_lock(&state->stream_mutex);
|
|
- ret = dvbsky_usb_generic_rw(d, obuf_pre, 3, NULL, 0);
|
|
+ mutex_lock(&d->usb_mutex);
|
|
+ memcpy(state->obuf, obuf_pre, 3);
|
|
+ ret = dvb_usbv2_generic_write_locked(d, state->obuf, 3);
|
|
if (!ret && onoff) {
|
|
msleep(20);
|
|
- ret = dvbsky_usb_generic_rw(d, obuf_post, 3, NULL, 0);
|
|
+ memcpy(state->obuf, obuf_post, 3);
|
|
+ ret = dvb_usbv2_generic_write_locked(d, state->obuf, 3);
|
|
}
|
|
- mutex_unlock(&state->stream_mutex);
|
|
+ mutex_unlock(&d->usb_mutex);
|
|
return ret;
|
|
}
|
|
|
|
@@ -689,8 +690,6 @@ static int dvbsky_init(struct dvb_usb_device *d)
|
|
if (ret)
|
|
return ret;
|
|
*/
|
|
- mutex_init(&state->stream_mutex);
|
|
-
|
|
state->last_lock = 0;
|
|
|
|
return 0;
|
|
--
|
|
2.11.0
|
|
|