linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/4] dvb: earth-pt1: stop polling data when no one accesses the device
@ 2012-03-10 15:38 tskd2
  2012-03-10 15:38 ` [PATCH 2/4] dvb: earth-pt1: add an error check/report on the incoming data tskd2
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: tskd2 @ 2012-03-10 15:38 UTC (permalink / raw)
  To: linux-media; +Cc: Akihiro Tsukada

From: Akihiro Tsukada <tskd2@yahoo.co.jp>

The driver started a kthread to poll the DMA buffers soon after probing,
which relsuleted in 1000/sec sleeps and wakeups of the thread doing nothing
useful until someone started feeding.
This patch changes the creation and destruction of the kthread depending on the number of users.

Signed-off-by: Akihiro Tsukada <tskd2@yahoo.co.jp>
---
 drivers/media/dvb/pt1/pt1.c |   73 +++++++++++++++++++++++++++++-------------
 1 files changed, 50 insertions(+), 23 deletions(-)

diff --git a/drivers/media/dvb/pt1/pt1.c b/drivers/media/dvb/pt1/pt1.c
index b81df5f..463f784 100644
--- a/drivers/media/dvb/pt1/pt1.c
+++ b/drivers/media/dvb/pt1/pt1.c
@@ -77,6 +77,8 @@ struct pt1 {
 	struct pt1_adapter *adaps[PT1_NR_ADAPS];
 	struct pt1_table *tables;
 	struct task_struct *kthread;
+	int table_index;
+	int buf_index;
 
 	struct mutex lock;
 	int power;
@@ -303,30 +305,25 @@ static int pt1_filter(struct pt1 *pt1, struct pt1_buffer_page *page)
 static int pt1_thread(void *data)
 {
 	struct pt1 *pt1;
-	int table_index;
-	int buf_index;
 	struct pt1_buffer_page *page;
 
 	pt1 = data;
 	set_freezable();
 
-	table_index = 0;
-	buf_index = 0;
-
 	while (!kthread_should_stop()) {
 		try_to_freeze();
 
-		page = pt1->tables[table_index].bufs[buf_index].page;
+		page = pt1->tables[pt1->table_index].bufs[pt1->buf_index].page;
 		if (!pt1_filter(pt1, page)) {
 			schedule_timeout_interruptible((HZ + 999) / 1000);
 			continue;
 		}
 
-		if (++buf_index >= PT1_NR_BUFS) {
+		if (++pt1->buf_index >= PT1_NR_BUFS) {
 			pt1_increment_table_count(pt1);
-			buf_index = 0;
-			if (++table_index >= pt1_nr_tables)
-				table_index = 0;
+			pt1->buf_index = 0;
+			if (++pt1->table_index >= pt1_nr_tables)
+				pt1->table_index = 0;
 		}
 	}
 
@@ -477,21 +474,60 @@ err:
 	return ret;
 }
 
+static int pt1_start_polling(struct pt1 *pt1)
+{
+	int ret = 0;
+
+	mutex_lock(&pt1->lock);
+	if (!pt1->kthread) {
+		pt1->kthread = kthread_run(pt1_thread, pt1, "earth-pt1");
+		if (IS_ERR(pt1->kthread)) {
+			ret = PTR_ERR(pt1->kthread);
+			pt1->kthread = NULL;
+		}
+	}
+	mutex_unlock(&pt1->lock);
+	return ret;
+}
+
 static int pt1_start_feed(struct dvb_demux_feed *feed)
 {
 	struct pt1_adapter *adap;
 	adap = container_of(feed->demux, struct pt1_adapter, demux);
-	if (!adap->users++)
+	if (!adap->users++) {
+		int ret;
+
+		ret = pt1_start_polling(adap->pt1);
+		if (ret)
+			return ret;
 		pt1_set_stream(adap->pt1, adap->index, 1);
+	}
 	return 0;
 }
 
+static void pt1_stop_polling(struct pt1 *pt1)
+{
+	int i, count;
+
+	mutex_lock(&pt1->lock);
+	for (i = 0, count = 0; i < PT1_NR_ADAPS; i++)
+		count += pt1->adaps[i]->users;
+
+	if (count == 0 && pt1->kthread) {
+		kthread_stop(pt1->kthread);
+		pt1->kthread = NULL;
+	}
+	mutex_unlock(&pt1->lock);
+}
+
 static int pt1_stop_feed(struct dvb_demux_feed *feed)
 {
 	struct pt1_adapter *adap;
 	adap = container_of(feed->demux, struct pt1_adapter, demux);
-	if (!--adap->users)
+	if (!--adap->users) {
 		pt1_set_stream(adap->pt1, adap->index, 0);
+		pt1_stop_polling(adap->pt1);
+	}
 	return 0;
 }
 
@@ -1020,7 +1056,8 @@ static void __devexit pt1_remove(struct pci_dev *pdev)
 	pt1 = pci_get_drvdata(pdev);
 	regs = pt1->regs;
 
-	kthread_stop(pt1->kthread);
+	if (pt1->kthread)
+		kthread_stop(pt1->kthread);
 	pt1_cleanup_tables(pt1);
 	pt1_cleanup_frontends(pt1);
 	pt1_disable_ram(pt1);
@@ -1043,7 +1080,6 @@ pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	void __iomem *regs;
 	struct pt1 *pt1;
 	struct i2c_adapter *i2c_adap;
-	struct task_struct *kthread;
 
 	ret = pci_enable_device(pdev);
 	if (ret < 0)
@@ -1139,17 +1175,8 @@ pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	if (ret < 0)
 		goto err_pt1_cleanup_frontends;
 
-	kthread = kthread_run(pt1_thread, pt1, "pt1");
-	if (IS_ERR(kthread)) {
-		ret = PTR_ERR(kthread);
-		goto err_pt1_cleanup_tables;
-	}
-
-	pt1->kthread = kthread;
 	return 0;
 
-err_pt1_cleanup_tables:
-	pt1_cleanup_tables(pt1);
 err_pt1_cleanup_frontends:
 	pt1_cleanup_frontends(pt1);
 err_pt1_disable_ram:
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/4] dvb: earth-pt1: add an error check/report on the incoming data
  2012-03-10 15:38 [PATCH 1/4] dvb: earth-pt1: stop polling data when no one accesses the device tskd2
@ 2012-03-10 15:38 ` tskd2
  2012-03-10 15:38 ` [PATCH 3/4] dvb: earth-pt1: decrease the too large DMA buffer size tskd2
  2012-03-10 15:38 ` [PATCH 4/4] dvb: earth-pt1: remove unsupported net subdevices tskd2
  2 siblings, 0 replies; 4+ messages in thread
From: tskd2 @ 2012-03-10 15:38 UTC (permalink / raw)
  To: linux-media; +Cc: Akihiro Tsukada

From: Akihiro Tsukada <tskd2@yahoo.co.jp>

This patch adds a data integrity check using the sequence counter and error flags added by the bridge chip.

Signed-off-by: Akihiro Tsukada <tskd2@yahoo.co.jp>
---
 drivers/media/dvb/pt1/pt1.c |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/drivers/media/dvb/pt1/pt1.c b/drivers/media/dvb/pt1/pt1.c
index 463f784..8229a91 100644
--- a/drivers/media/dvb/pt1/pt1.c
+++ b/drivers/media/dvb/pt1/pt1.c
@@ -28,6 +28,7 @@
 #include <linux/pci.h>
 #include <linux/kthread.h>
 #include <linux/freezer.h>
+#include <linux/ratelimit.h>
 
 #include "dvbdev.h"
 #include "dvb_demux.h"
@@ -92,6 +93,7 @@ struct pt1_adapter {
 	u8 *buf;
 	int upacket_count;
 	int packet_count;
+	int st_count;
 
 	struct dvb_adapter adap;
 	struct dvb_demux demux;
@@ -266,6 +268,7 @@ static int pt1_filter(struct pt1 *pt1, struct pt1_buffer_page *page)
 	struct pt1_adapter *adap;
 	int offset;
 	u8 *buf;
+	int sc;
 
 	if (!page->upackets[PT1_NR_UPACKETS - 1])
 		return 0;
@@ -282,6 +285,16 @@ static int pt1_filter(struct pt1 *pt1, struct pt1_buffer_page *page)
 		else if (!adap->upacket_count)
 			continue;
 
+		if (upacket >> 24 & 1)
+			printk_ratelimited(KERN_INFO "earth-pt1: device "
+				"buffer overflowing. table[%d] buf[%d]\n",
+				pt1->table_index, pt1->buf_index);
+		sc = upacket >> 26 & 0x7;
+		if (adap->st_count != -1 && sc != ((adap->st_count + 1) & 0x7))
+			printk_ratelimited(KERN_INFO "earth-pt1: data loss"
+				" in streamID(adapter)[%d]\n", index);
+		adap->st_count = sc;
+
 		buf = adap->buf;
 		offset = adap->packet_count * 188 + adap->upacket_count * 3;
 		buf[offset] = upacket >> 16;
@@ -652,6 +665,7 @@ pt1_alloc_adapter(struct pt1 *pt1)
 	adap->buf = buf;
 	adap->upacket_count = 0;
 	adap->packet_count = 0;
+	adap->st_count = -1;
 
 	dvb_adap = &adap->adap;
 	dvb_adap->priv = adap;
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 3/4] dvb: earth-pt1: decrease the too large DMA buffer size
  2012-03-10 15:38 [PATCH 1/4] dvb: earth-pt1: stop polling data when no one accesses the device tskd2
  2012-03-10 15:38 ` [PATCH 2/4] dvb: earth-pt1: add an error check/report on the incoming data tskd2
@ 2012-03-10 15:38 ` tskd2
  2012-03-10 15:38 ` [PATCH 4/4] dvb: earth-pt1: remove unsupported net subdevices tskd2
  2 siblings, 0 replies; 4+ messages in thread
From: tskd2 @ 2012-03-10 15:38 UTC (permalink / raw)
  To: linux-media; +Cc: Akihiro Tsukada

From: Akihiro Tsukada <tskd2@yahoo.co.jp>

Current default value of "nr_tables" option corresponds to the DMA buffer of about 10 to 48 seconds long, which is obviously too much.

Signed-off-by: Akihiro Tsukada <tskd2@yahoo.co.jp>
---
 drivers/media/dvb/pt1/pt1.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/media/dvb/pt1/pt1.c b/drivers/media/dvb/pt1/pt1.c
index 8229a91..9cd161c 100644
--- a/drivers/media/dvb/pt1/pt1.c
+++ b/drivers/media/dvb/pt1/pt1.c
@@ -123,7 +123,7 @@ static u32 pt1_read_reg(struct pt1 *pt1, int reg)
 	return readl(pt1->regs + reg * 4);
 }
 
-static int pt1_nr_tables = 64;
+static int pt1_nr_tables = 8;
 module_param_named(nr_tables, pt1_nr_tables, int, 0);
 
 static void pt1_increment_table_count(struct pt1 *pt1)
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 4/4] dvb: earth-pt1: remove unsupported net subdevices
  2012-03-10 15:38 [PATCH 1/4] dvb: earth-pt1: stop polling data when no one accesses the device tskd2
  2012-03-10 15:38 ` [PATCH 2/4] dvb: earth-pt1: add an error check/report on the incoming data tskd2
  2012-03-10 15:38 ` [PATCH 3/4] dvb: earth-pt1: decrease the too large DMA buffer size tskd2
@ 2012-03-10 15:38 ` tskd2
  2 siblings, 0 replies; 4+ messages in thread
From: tskd2 @ 2012-03-10 15:38 UTC (permalink / raw)
  To: linux-media; +Cc: Akihiro Tsukada

From: Akihiro Tsukada <tskd2@yahoo.co.jp>

PT1 and PT2 do not have net functions.

Signed-off-by: Akihiro Tsukada <tskd2@yahoo.co.jp>
---
 drivers/media/dvb/pt1/pt1.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/drivers/media/dvb/pt1/pt1.c b/drivers/media/dvb/pt1/pt1.c
index 9cd161c..15b35c4 100644
--- a/drivers/media/dvb/pt1/pt1.c
+++ b/drivers/media/dvb/pt1/pt1.c
@@ -99,7 +99,6 @@ struct pt1_adapter {
 	struct dvb_demux demux;
 	int users;
 	struct dmxdev dmxdev;
-	struct dvb_net net;
 	struct dvb_frontend *fe;
 	int (*orig_set_voltage)(struct dvb_frontend *fe,
 				fe_sec_voltage_t voltage);
@@ -624,7 +623,6 @@ static int pt1_wakeup(struct dvb_frontend *fe)
 
 static void pt1_free_adapter(struct pt1_adapter *adap)
 {
-	dvb_net_release(&adap->net);
 	adap->demux.dmx.close(&adap->demux.dmx);
 	dvb_dmxdev_release(&adap->dmxdev);
 	dvb_dmx_release(&adap->demux);
@@ -694,8 +692,6 @@ pt1_alloc_adapter(struct pt1 *pt1)
 	if (ret < 0)
 		goto err_dmx_release;
 
-	dvb_net_init(dvb_adap, &adap->net, &demux->dmx);
-
 	return adap;
 
 err_dmx_release:
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2012-03-10 15:45 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-03-10 15:38 [PATCH 1/4] dvb: earth-pt1: stop polling data when no one accesses the device tskd2
2012-03-10 15:38 ` [PATCH 2/4] dvb: earth-pt1: add an error check/report on the incoming data tskd2
2012-03-10 15:38 ` [PATCH 3/4] dvb: earth-pt1: decrease the too large DMA buffer size tskd2
2012-03-10 15:38 ` [PATCH 4/4] dvb: earth-pt1: remove unsupported net subdevices tskd2

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).