summaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/dvb-usb
diff options
context:
space:
mode:
authorAntti Palosaari <crope@iki.fi>2012-06-17 00:27:00 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-08-04 07:56:35 -0300
commit191f79a4d78292a82f9be9cc6c9c974365792f8f (patch)
tree1da2baa5280f68e337475f53163a64ecfeca510d /drivers/media/dvb/dvb-usb
parente80896616c11f4c0a0bc17ebd87b86da194b859a (diff)
downloadop-kernel-dev-191f79a4d78292a82f9be9cc6c9c974365792f8f.zip
op-kernel-dev-191f79a4d78292a82f9be9cc6c9c974365792f8f.tar.gz
[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: Antti Palosaari <crope@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/dvb-usb')
-rw-r--r--drivers/media/dvb/dvb-usb/dvb_usb.h3
-rw-r--r--drivers/media/dvb/dvb-usb/dvb_usb_dvb.c26
2 files changed, 22 insertions, 7 deletions
diff --git a/drivers/media/dvb/dvb-usb/dvb_usb.h b/drivers/media/dvb/dvb-usb/dvb_usb.h
index fadc0f9..6bd27e5 100644
--- a/drivers/media/dvb/dvb-usb/dvb_usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb_usb.h
@@ -309,6 +309,9 @@ struct dvb_usb_adapter {
int feedcount;
int max_feed_count;
+ /* sync frontend and streaming as those are different tasks */
+ struct mutex sync_mutex;
+
/* dvb */
struct dvb_adapter dvb_adap;
struct dmxdev dmxdev;
diff --git a/drivers/media/dvb/dvb-usb/dvb_usb_dvb.c b/drivers/media/dvb/dvb-usb/dvb_usb_dvb.c
index 484114c..97b5093 100644
--- a/drivers/media/dvb/dvb-usb/dvb_usb_dvb.c
+++ b/drivers/media/dvb/dvb-usb/dvb_usb_dvb.c
@@ -77,9 +77,10 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
if (ret < 0) {
pr_err("%s: error while stopping stream\n",
KBUILD_MODNAME);
- return ret;
+ goto err_mutex_unlock;
}
}
+ mutex_unlock(&adap->sync_mutex);
}
adap->feedcount = newfeedcount;
@@ -95,12 +96,14 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
adap->props->pid_filter(adap, dvbdmxfeed->index,
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.
*/
if (adap->feedcount == onoff && adap->feedcount > 0) {
struct usb_data_stream_properties stream_props;
unsigned int ts_props;
+ mutex_lock(&adap->sync_mutex);
/* resolve TS configuration */
if (adap->dev->props->get_ts_config) {
@@ -108,7 +111,7 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
adap->fe[adap->active_fe],
&ts_props);
if (ret < 0)
- return ret;
+ goto err_mutex_unlock;
} else {
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)
adap->fe[adap->active_fe],
&stream_props);
if (ret < 0)
- return ret;
+ goto err_mutex_unlock;
} else {
stream_props = adap->props->stream;
}
pr_debug("%s: submitting all URBs\n", __func__);
-
usb_urb_submitv2(&adap->stream, &stream_props);
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)
if (ret < 0) {
pr_err("%s: could not handle pid_parser\n",
KBUILD_MODNAME);
- return ret;
+ goto err_mutex_unlock;
}
}
pr_debug("%s: start feeding\n", __func__);
@@ -156,12 +158,15 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
if (ret < 0) {
pr_err("%s: error while enabling fifo\n",
KBUILD_MODNAME);
- return ret;
+ goto err_mutex_unlock;
}
}
}
+
return 0;
+err_mutex_unlock:
+ mutex_unlock(&adap->sync_mutex);
err:
pr_debug("%s: failed=%d\n", __func__, ret);
return ret;
@@ -238,6 +243,7 @@ int dvb_usbv2_adapter_dvb_init(struct dvb_usb_adapter *adap)
goto err_net_init;
}
+ mutex_init(&adap->sync_mutex);
adap->state |= DVB_USB_ADAP_STATE_DVB;
return 0;
@@ -271,6 +277,7 @@ static int dvb_usb_fe_wakeup(struct dvb_frontend *fe)
{
int ret;
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);
ret = dvb_usbv2_device_power_ctrl(adap->dev, 1);
@@ -290,9 +297,11 @@ static int dvb_usb_fe_wakeup(struct dvb_frontend *fe)
}
adap->active_fe = fe->id;
+ mutex_unlock(&adap->sync_mutex);
return 0;
err:
+ mutex_unlock(&adap->sync_mutex);
pr_debug("%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -301,6 +310,7 @@ static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
{
int ret;
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);
if (adap->fe_sleep[fe->id]) {
@@ -320,9 +330,11 @@ static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
goto err;
adap->active_fe = -1;
+ mutex_unlock(&adap->sync_mutex);
return 0;
err:
+ mutex_unlock(&adap->sync_mutex);
pr_debug("%s: failed=%d\n", __func__, ret);
return ret;
}
OpenPOWER on IntegriCloud