Commit 191f79a4 authored by Antti Palosaari's avatar Antti Palosaari Committed by Mauro Carvalho Chehab

[media] dvb_usb_v2: use lock to sync feed and frontend control

There was synchronization problem when streaming was stopped.
Frontend was ran down before stream which causes problems.
Use mutex to synchronization. Now it looks like that:
LOCK
start frontend
UNLOCK
LOCK
start streaming
[...]
stop streaming
UNLOCK
LOCK
stop frontend
UNLOCK
Signed-off-by: default avatarAntti Palosaari <crope@iki.fi>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent e8089661
...@@ -309,6 +309,9 @@ struct dvb_usb_adapter { ...@@ -309,6 +309,9 @@ struct dvb_usb_adapter {
int feedcount; int feedcount;
int max_feed_count; int max_feed_count;
/* sync frontend and streaming as those are different tasks */
struct mutex sync_mutex;
/* dvb */ /* dvb */
struct dvb_adapter dvb_adap; struct dvb_adapter dvb_adap;
struct dmxdev dmxdev; struct dmxdev dmxdev;
......
...@@ -77,9 +77,10 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff) ...@@ -77,9 +77,10 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
if (ret < 0) { if (ret < 0) {
pr_err("%s: error while stopping stream\n", pr_err("%s: error while stopping stream\n",
KBUILD_MODNAME); KBUILD_MODNAME);
return ret; goto err_mutex_unlock;
} }
} }
mutex_unlock(&adap->sync_mutex);
} }
adap->feedcount = newfeedcount; adap->feedcount = newfeedcount;
...@@ -95,12 +96,14 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff) ...@@ -95,12 +96,14 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
adap->props->pid_filter(adap, dvbdmxfeed->index, adap->props->pid_filter(adap, dvbdmxfeed->index,
dvbdmxfeed->pid, onoff); dvbdmxfeed->pid, onoff);
/* start the feed if this was the first feed and there is still a feed /*
* Start the feed if this was the first feed and there is still a feed
* for reception. * for reception.
*/ */
if (adap->feedcount == onoff && adap->feedcount > 0) { if (adap->feedcount == onoff && adap->feedcount > 0) {
struct usb_data_stream_properties stream_props; struct usb_data_stream_properties stream_props;
unsigned int ts_props; unsigned int ts_props;
mutex_lock(&adap->sync_mutex);
/* resolve TS configuration */ /* resolve TS configuration */
if (adap->dev->props->get_ts_config) { if (adap->dev->props->get_ts_config) {
...@@ -108,7 +111,7 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff) ...@@ -108,7 +111,7 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
adap->fe[adap->active_fe], adap->fe[adap->active_fe],
&ts_props); &ts_props);
if (ret < 0) if (ret < 0)
return ret; goto err_mutex_unlock;
} else { } else {
ts_props = 0; /* normal 188 payload only TS */ ts_props = 0; /* normal 188 payload only TS */
} }
...@@ -128,13 +131,12 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff) ...@@ -128,13 +131,12 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
adap->fe[adap->active_fe], adap->fe[adap->active_fe],
&stream_props); &stream_props);
if (ret < 0) if (ret < 0)
return ret; goto err_mutex_unlock;
} else { } else {
stream_props = adap->props->stream; stream_props = adap->props->stream;
} }
pr_debug("%s: submitting all URBs\n", __func__); pr_debug("%s: submitting all URBs\n", __func__);
usb_urb_submitv2(&adap->stream, &stream_props); usb_urb_submitv2(&adap->stream, &stream_props);
pr_debug("%s: controlling pid parser\n", __func__); pr_debug("%s: controlling pid parser\n", __func__);
...@@ -147,7 +149,7 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff) ...@@ -147,7 +149,7 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
if (ret < 0) { if (ret < 0) {
pr_err("%s: could not handle pid_parser\n", pr_err("%s: could not handle pid_parser\n",
KBUILD_MODNAME); KBUILD_MODNAME);
return ret; goto err_mutex_unlock;
} }
} }
pr_debug("%s: start feeding\n", __func__); pr_debug("%s: start feeding\n", __func__);
...@@ -156,12 +158,15 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff) ...@@ -156,12 +158,15 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
if (ret < 0) { if (ret < 0) {
pr_err("%s: error while enabling fifo\n", pr_err("%s: error while enabling fifo\n",
KBUILD_MODNAME); KBUILD_MODNAME);
return ret; goto err_mutex_unlock;
} }
} }
} }
return 0; return 0;
err_mutex_unlock:
mutex_unlock(&adap->sync_mutex);
err: err:
pr_debug("%s: failed=%d\n", __func__, ret); pr_debug("%s: failed=%d\n", __func__, ret);
return ret; return ret;
...@@ -238,6 +243,7 @@ int dvb_usbv2_adapter_dvb_init(struct dvb_usb_adapter *adap) ...@@ -238,6 +243,7 @@ int dvb_usbv2_adapter_dvb_init(struct dvb_usb_adapter *adap)
goto err_net_init; goto err_net_init;
} }
mutex_init(&adap->sync_mutex);
adap->state |= DVB_USB_ADAP_STATE_DVB; adap->state |= DVB_USB_ADAP_STATE_DVB;
return 0; return 0;
...@@ -271,6 +277,7 @@ static int dvb_usb_fe_wakeup(struct dvb_frontend *fe) ...@@ -271,6 +277,7 @@ static int dvb_usb_fe_wakeup(struct dvb_frontend *fe)
{ {
int ret; int ret;
struct dvb_usb_adapter *adap = fe->dvb->priv; struct dvb_usb_adapter *adap = fe->dvb->priv;
mutex_lock(&adap->sync_mutex);
pr_debug("%s: adap=%d fe=%d\n", __func__, adap->id, fe->id); pr_debug("%s: adap=%d fe=%d\n", __func__, adap->id, fe->id);
ret = dvb_usbv2_device_power_ctrl(adap->dev, 1); ret = dvb_usbv2_device_power_ctrl(adap->dev, 1);
...@@ -290,9 +297,11 @@ static int dvb_usb_fe_wakeup(struct dvb_frontend *fe) ...@@ -290,9 +297,11 @@ static int dvb_usb_fe_wakeup(struct dvb_frontend *fe)
} }
adap->active_fe = fe->id; adap->active_fe = fe->id;
mutex_unlock(&adap->sync_mutex);
return 0; return 0;
err: err:
mutex_unlock(&adap->sync_mutex);
pr_debug("%s: failed=%d\n", __func__, ret); pr_debug("%s: failed=%d\n", __func__, ret);
return ret; return ret;
} }
...@@ -301,6 +310,7 @@ static int dvb_usb_fe_sleep(struct dvb_frontend *fe) ...@@ -301,6 +310,7 @@ static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
{ {
int ret; int ret;
struct dvb_usb_adapter *adap = fe->dvb->priv; struct dvb_usb_adapter *adap = fe->dvb->priv;
mutex_lock(&adap->sync_mutex);
pr_debug("%s: adap=%d fe=%d\n", __func__, adap->id, fe->id); pr_debug("%s: adap=%d fe=%d\n", __func__, adap->id, fe->id);
if (adap->fe_sleep[fe->id]) { if (adap->fe_sleep[fe->id]) {
...@@ -320,9 +330,11 @@ static int dvb_usb_fe_sleep(struct dvb_frontend *fe) ...@@ -320,9 +330,11 @@ static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
goto err; goto err;
adap->active_fe = -1; adap->active_fe = -1;
mutex_unlock(&adap->sync_mutex);
return 0; return 0;
err: err:
mutex_unlock(&adap->sync_mutex);
pr_debug("%s: failed=%d\n", __func__, ret); pr_debug("%s: failed=%d\n", __func__, ret);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment