summaryrefslogtreecommitdiff
path: root/tmp.dif
blob: 87c57b71f310a957bfcae6bef9054d95c73f4fa4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
--- dvb.c
+++ dvb.c	Wed May 29 17:41:53 2002
@@ -444,6 +444,8 @@
 			break;
                 if (!dvb->arm_ready)
                         continue;
+		if (down_interruptible(&dvb->dcomlock))
+			continue;
                 newloops=rdebi(dvb, DEBINOSWAP, STATUS_LOOPS, 0, 2);
                 if (newloops==dvb->arm_loops) {
                         printk("dvb%d: ARM crashed!\n", dvb->num);
@@ -451,6 +453,7 @@
                         newloops=rdebi(dvb, DEBINOSWAP, STATUS_LOOPS, 0, 2)-1;
                 }
                 dvb->arm_loops=newloops;
+		up(&dvb->dcomlock);
 	}
 	dvb->arm_thread = NULL;
 	return 0;
@@ -1158,6 +1161,31 @@
         return blen;
 }
 
+/* Timer to avoid broken data transfer in gpioirq() */
+
+#define GPIO_RXTIME_FRAME	((32*HZ)/1000)
+
+static void gpio_receive_timeout(unsigned long data)
+{
+	struct dvb_struct *dvb = (struct dvb_struct *)data;
+	dvb->debitimer.expires = 0;
+}
+
+static void gpio_receive_timer(struct dvb_struct *dvb, unsigned long ticks)
+{
+	dvb_demux_filter_t *dvbdmxfilter = dvb->handle2filter[((dvb->debitype)>>8)&0x1f];
+
+	if (!dvbdmxfilter || dvbdmxfilter->type != DMX_TYPE_TS)
+		return;
+	mod_timer(&dvb->debitimer, jiffies + ticks);
+}
+
+static inline int gpio_rx_pending(struct dvb_struct *dvb)
+{
+	return !timer_pending(&dvb->debitimer) && \
+		dvb->debitimer.expires == 0;
+}
+
 static void 
 gpioirq(struct saa7146* saa, void *data)
 {
@@ -1313,6 +1341,7 @@
                         iwdebi(dvb, DEBINOSWAP, RX_BUFF, 0, 2);
                         break;
                 }                  /* yes, fall through */
+		gpio_receive_timer(dvb, GPIO_RXTIME_FRAME);
         case DATA_TS_RECORD:
         case DATA_PES_RECORD:
                 saa7146_write(dvb->saa_mem, IER, 
@@ -1843,7 +1872,7 @@
         bpp=dvb->osdbpp[dvb->osdwin]+1; 
         bpl=((w*bpp+7)&~7)/8; 
         size=h*bpl;
-        lpb=(32*1024)/bpl; 
+        lpb=(16*1024)/bpl; 
         bnum=size/(lpb*bpl);
         brest=size-bnum*lpb*bpl;
 
@@ -1851,6 +1880,10 @@
                 LoadBitmap(dvb, bpp2bit[dvb->osdbpp[dvb->osdwin]], w, lpb, inc, data); 
                 BlitBitmap(dvb, dvb->osdwin, x0, y0+i*lpb, 0);
                 data+=lpb*inc; 
+		if (gpio_rx_pending(dvb)) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(GPIO_RXTIME_FRAME);
+		}
         }
         if (brest) {
                 LoadBitmap(dvb, bpp2bit[dvb->osdbpp[dvb->osdwin]], w, brest/bpl, inc, data); 
@@ -3819,6 +3852,7 @@
                 return TTBStop(dvb); 
 
         if (dvbdmxfeed->type == DMX_TYPE_TS) {
+		del_timer(&dvb->debitimer);
                 if (dvbdmxfeed->ts_type & TS_DECODER) {
                         if (dvbdmxfeed->pes_type>=DMX_TS_PES_OTHER ||
                             !dvbdmx->pesfilter[dvbdmxfeed->pes_type]) 
@@ -5472,8 +5506,12 @@
         spin_lock_init (&dvb->debilock);
         sema_init(&dvb->dcomlock, 1);
         init_waitqueue_head(&dvb->debiq);
+	init_timer(&dvb->debitimer);
         dvb->debilock=SPIN_LOCK_UNLOCKED;
         dvb->debitype=-1;
+	dvb->debitimer.function = gpio_receive_timeout;
+	dvb->debitimer.data = (unsigned long) dvb;
+	dvb->debitimer.expires = jiffies;
 
         dvb->num=num;
         dvb->i2cbus=adap;
@@ -5741,6 +5779,7 @@
 
 	/* release the saa7146s */
 	for( i = 0; i < num_dvb; i++) {
+		del_timer_sync(&(dvbs[i].debitimer));
 		dvbs[i].arm_rmmod=1;
 		wake_up_interruptible(&dvbs[i].arm_wait);
                 while (dvbs[i].arm_thread)
--- dvb.h
+++ dvb.h	Wed May 29 17:41:08 2002
@@ -566,6 +566,7 @@
         spinlock_t              debilock;
         struct semaphore        dcomlock;
         WAIT_QUEUE              debiq;
+	struct timer_list	debitimer;
         int                     debitype;
         int                     debilen;
         int                     debibuf;