|
@@ -13,9 +13,9 @@ static int enable_pid_filtering = 1;
|
|
module_param(enable_pid_filtering, int, 0444);
|
|
module_param(enable_pid_filtering, int, 0444);
|
|
MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1");
|
|
MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1");
|
|
|
|
|
|
-static int irq_chk_intv;
|
|
|
|
|
|
+static int irq_chk_intv = 100;
|
|
module_param(irq_chk_intv, int, 0644);
|
|
module_param(irq_chk_intv, int, 0644);
|
|
-MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ watchdog (currently just debugging).");
|
|
|
|
|
|
+MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ streaming watchdog.");
|
|
|
|
|
|
#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
|
|
#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
|
|
#define dprintk(level,args...) \
|
|
#define dprintk(level,args...) \
|
|
@@ -34,7 +34,9 @@ MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ watchdog (currently jus
|
|
|
|
|
|
static int debug;
|
|
static int debug;
|
|
module_param(debug, int, 0644);
|
|
module_param(debug, int, 0644);
|
|
-MODULE_PARM_DESC(debug, "set debug level (1=info,2=regs,4=TS,8=irqdma (|-able))." DEBSTATUS);
|
|
|
|
|
|
+MODULE_PARM_DESC(debug,
|
|
|
|
+ "set debug level (1=info,2=regs,4=TS,8=irqdma,16=check (|-able))."
|
|
|
|
+ DEBSTATUS);
|
|
|
|
|
|
#define DRIVER_VERSION "0.1"
|
|
#define DRIVER_VERSION "0.1"
|
|
#define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver"
|
|
#define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver"
|
|
@@ -58,6 +60,8 @@ struct flexcop_pci {
|
|
int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */
|
|
int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */
|
|
u32 last_dma1_cur_pos; /* position of the pointer last time the timer/packet irq occured */
|
|
u32 last_dma1_cur_pos; /* position of the pointer last time the timer/packet irq occured */
|
|
int count;
|
|
int count;
|
|
|
|
+ int count_prev;
|
|
|
|
+ int stream_problem;
|
|
|
|
|
|
spinlock_t irq_lock;
|
|
spinlock_t irq_lock;
|
|
|
|
|
|
@@ -103,18 +107,32 @@ static void flexcop_pci_irq_check_work(struct work_struct *work)
|
|
container_of(work, struct flexcop_pci, irq_check_work.work);
|
|
container_of(work, struct flexcop_pci, irq_check_work.work);
|
|
struct flexcop_device *fc = fc_pci->fc_dev;
|
|
struct flexcop_device *fc = fc_pci->fc_dev;
|
|
|
|
|
|
- flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714);
|
|
|
|
-
|
|
|
|
- flexcop_dump_reg(fc_pci->fc_dev,dma1_000,4);
|
|
|
|
-
|
|
|
|
- if (v.sram_dest_reg_714.net_ovflow_error)
|
|
|
|
- deb_chk("sram net_ovflow_error\n");
|
|
|
|
- if (v.sram_dest_reg_714.media_ovflow_error)
|
|
|
|
- deb_chk("sram media_ovflow_error\n");
|
|
|
|
- if (v.sram_dest_reg_714.cai_ovflow_error)
|
|
|
|
- deb_chk("sram cai_ovflow_error\n");
|
|
|
|
- if (v.sram_dest_reg_714.cai_ovflow_error)
|
|
|
|
- deb_chk("sram cai_ovflow_error\n");
|
|
|
|
|
|
+ if (fc->feedcount) {
|
|
|
|
+
|
|
|
|
+ if (fc_pci->count == fc_pci->count_prev) {
|
|
|
|
+ deb_chk("no IRQ since the last check\n");
|
|
|
|
+ if (fc_pci->stream_problem++ == 3) {
|
|
|
|
+ struct dvb_demux_feed *feed;
|
|
|
|
+
|
|
|
|
+ spin_lock_irq(&fc->demux.lock);
|
|
|
|
+ list_for_each_entry(feed, &fc->demux.feed_list,
|
|
|
|
+ list_head) {
|
|
|
|
+ flexcop_pid_feed_control(fc, feed, 0);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ list_for_each_entry(feed, &fc->demux.feed_list,
|
|
|
|
+ list_head) {
|
|
|
|
+ flexcop_pid_feed_control(fc, feed, 1);
|
|
|
|
+ }
|
|
|
|
+ spin_unlock_irq(&fc->demux.lock);
|
|
|
|
+
|
|
|
|
+ fc_pci->stream_problem = 0;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ fc_pci->stream_problem = 0;
|
|
|
|
+ fc_pci->count_prev = fc_pci->count;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
schedule_delayed_work(&fc_pci->irq_check_work,
|
|
schedule_delayed_work(&fc_pci->irq_check_work,
|
|
msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
|
|
msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
|
|
@@ -216,16 +234,12 @@ static int flexcop_pci_stream_control(struct flexcop_device *fc, int onoff)
|
|
flexcop_dma_control_timer_irq(fc,FC_DMA_1,1);
|
|
flexcop_dma_control_timer_irq(fc,FC_DMA_1,1);
|
|
deb_irq("IRQ enabled\n");
|
|
deb_irq("IRQ enabled\n");
|
|
|
|
|
|
|
|
+ fc_pci->count_prev = fc_pci->count;
|
|
|
|
+
|
|
// fc_pci->active_dma1_addr = 0;
|
|
// fc_pci->active_dma1_addr = 0;
|
|
// flexcop_dma_control_size_irq(fc,FC_DMA_1,1);
|
|
// flexcop_dma_control_size_irq(fc,FC_DMA_1,1);
|
|
|
|
|
|
- if (irq_chk_intv > 0)
|
|
|
|
- schedule_delayed_work(&fc_pci->irq_check_work,
|
|
|
|
- msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
|
|
|
|
} else {
|
|
} else {
|
|
- if (irq_chk_intv > 0)
|
|
|
|
- cancel_delayed_work(&fc_pci->irq_check_work);
|
|
|
|
-
|
|
|
|
flexcop_dma_control_timer_irq(fc,FC_DMA_1,0);
|
|
flexcop_dma_control_timer_irq(fc,FC_DMA_1,0);
|
|
deb_irq("IRQ disabled\n");
|
|
deb_irq("IRQ disabled\n");
|
|
|
|
|
|
@@ -299,8 +313,6 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci)
|
|
IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0)
|
|
IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0)
|
|
goto err_pci_iounmap;
|
|
goto err_pci_iounmap;
|
|
|
|
|
|
-
|
|
|
|
-
|
|
|
|
fc_pci->init_state |= FC_PCI_INIT;
|
|
fc_pci->init_state |= FC_PCI_INIT;
|
|
return ret;
|
|
return ret;
|
|
|
|
|
|
@@ -375,6 +387,10 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
|
|
|
|
|
|
INIT_DELAYED_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work);
|
|
INIT_DELAYED_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work);
|
|
|
|
|
|
|
|
+ if (irq_chk_intv > 0)
|
|
|
|
+ schedule_delayed_work(&fc_pci->irq_check_work,
|
|
|
|
+ msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
|
|
|
|
+
|
|
return ret;
|
|
return ret;
|
|
|
|
|
|
err_fc_exit:
|
|
err_fc_exit:
|
|
@@ -393,6 +409,9 @@ static void flexcop_pci_remove(struct pci_dev *pdev)
|
|
{
|
|
{
|
|
struct flexcop_pci *fc_pci = pci_get_drvdata(pdev);
|
|
struct flexcop_pci *fc_pci = pci_get_drvdata(pdev);
|
|
|
|
|
|
|
|
+ if (irq_chk_intv > 0)
|
|
|
|
+ cancel_delayed_work(&fc_pci->irq_check_work);
|
|
|
|
+
|
|
flexcop_pci_dma_exit(fc_pci);
|
|
flexcop_pci_dma_exit(fc_pci);
|
|
flexcop_device_exit(fc_pci->fc_dev);
|
|
flexcop_device_exit(fc_pci->fc_dev);
|
|
flexcop_pci_exit(fc_pci);
|
|
flexcop_pci_exit(fc_pci);
|