Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[linux-dvb] Crashes in dvb_demux.c



HI

Research on vpeirq() field revealed further bugs and
code dirtyness which causes crashes. Source of this
comes from software demux, the stuff in dvb_demux.c
in dvb-kernel.

I intentionally screwed dmapos by shifting it an
couple of bytes ahead (I used +441, but anything 
not divisible by 188 would do). Second, instead
of checking that block begins with 0x47, i checked
the opposite, i.e. != 0x47 and that revealed all
sorts of hidden sources of crashes that might occur
in case of weak reception and/or garbled data.

Attached are 3 oops-es: swfilter.oops, section1.oops 
and section2,oops each of them freezes machine instantly.

swfilter.oops I was able to fix, for section1 and 2 I need
your help. 

Basically, the swfilter.oops fix is simple: from received
data, an array index is calculated and fetched an element
from the array, but that was done without prior checking
is the index inside negative or outside of the array range.

Having a simple if(outside_of_the_range) return; is the *MUST*
in every code that wants to run cool.

So, the offending example is here:
void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
{
        struct dvb_demux_feed *feed = demux->pid2feed[ts_pid(buf)];

        if (!feed)
                return;

        dvb_dmx_swfilter_packet_type (feed, buf);
}

Simple, but crashable in the very first line. The crash is:












ksymoops 2.4.5 on i686 2.4.20.  Options used
     -V (default)
     -k /proc/ksyms (default)
     -l /proc/modules (default)
     -o /lib/modules/2.4.20/ (default)
     -m /boot/2.4.20-nov4l1/System.map (specified)

115200
Unable to handle kernel paging request at virtual address f8940000
f88ec342
*pde = 019ca067
Oops: 0000
CPU:    0
EIP:    0010:[<f88ec342>]    Not tainted
Using defaults from ksymoops -t elf32-i386 -a i386
EFLAGS: 00010206
eax: 001b0700   ebx: 00000001   ecx: 00020386   edx: f45b0fb0
esi: f893fffe   edi: f45b0e9c   ebp: ae4c415d   esp: c0361f0c
ds: 0018   es: 0018   ss: 0018
Process swapper (pid: 0, stackpage=c0361000)
Stack: 00000001 f893fffe f88ec48e f45b0e9c f893fffe 000002e6 f45b0000 f8911000 
       f890c368 f45b0e9c f8931386 00000143 00000000 c037c280 00000000 c037c380 
       c01199ce f45b0000 00000001 c037c398 fffffff7 c011985a c037c398 00000480 
Call Trace:    [<f88ec48e>] [<f890c368>] [<c01199ce>] [<c011985a>] [<c0109ad2>]
  [<c010bbc8>] [<c0106cf3>] [<f8834415>] [<f883430c>] [<c0106cd0>] [<c0106d59>]
  [<c0105000>] [<c0105027>]
Code: 66 0f b6 56 02 01 d0 8b 54 24 0c 0f b7 c0 81 c2 14 01 00 00 


>>EIP; f88ec342 <[dvb-core]dvb_dmx_swfilter_packet+e/11c>   <=====

>>eax; 001b0700 Before first symbol
>>ecx; 00020386 Before first symbol
>>edx; f45b0fb0 <_end+341f6290/384762e0>
>>esi; f893fffe <[dvb-ttpci-budget].data.end+3223f/2ad241>
>>edi; f45b0e9c <_end+341f617c/384762e0>
>>ebp; ae4c415d Before first symbol
>>esp; c0361f0c <init_task_union+1f0c/2000>

Trace; f88ec48e <[dvb-core]dvb_dmx_swfilter_packets+3e/50>
Trace; f890c368 <[dvb-ttpci-budget]vpeirq+84/d4>
Trace; c01199ce <tasklet_action+46/64>
Trace; c011985a <do_softirq+5a/a4>
Trace; c0109ad2 <do_IRQ+96/a8>
Trace; c010bbc8 <call_do_IRQ+5/d>
Trace; c0106cf3 <default_idle+23/28>
Trace; f8834415 <[apm]apm_cpu_idle+109/13c>
Trace; f883430c <[apm]apm_cpu_idle+0/13c>
Trace; c0106cd0 <default_idle+0/28>
Trace; c0106d59 <cpu_idle+41/54>
Trace; c0105000 <_stext+0/0>
Trace; c0105027 <rest_init+27/28>

Code;  f88ec342 <[dvb-core]dvb_dmx_swfilter_packet+e/11c>
00000000 <_EIP>:
Code;  f88ec342 <[dvb-core]dvb_dmx_swfilter_packet+e/11c>   <=====
   0:   66 0f b6 56 02            movzbw 0x2(%esi),%dx   <=====
Code;  f88ec347 <[dvb-core]dvb_dmx_swfilter_packet+13/11c>
   5:   01 d0                     add    %edx,%eax
Code;  f88ec349 <[dvb-core]dvb_dmx_swfilter_packet+15/11c>
   7:   8b 54 24 0c               mov    0xc(%esp,1),%edx
Code;  f88ec34d <[dvb-core]dvb_dmx_swfilter_packet+19/11c>
   b:   0f b7 c0                  movzwl %ax,%eax
Code;  f88ec350 <[dvb-core]dvb_dmx_swfilter_packet+1c/11c>
   e:   81 c2 14 01 00 00         add    $0x114,%edx

 <0>Kernel panic: Aiee, killing interrupt handler!








The corrected version looks like:




--- orig/dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_demux.c        Wed
Jan
+++ dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_demux.c     Sat Feb  8
23:1
@@ -451,7 +451,13 @@ void dvb_dmx_swfilter_packet_type(struct

 void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
 {
-       struct dvb_demux_feed *feed = demux->pid2feed[ts_pid(buf)];
+       struct dvb_demux_feed *feed;
+       u32 pid = ts_pid(buf);
+
+       if(pid >= DMX_MAX_PID)
+               return;
+
+       feed = demux->pid2feed[pid];

        if (!feed)
                return;

There are tons of other examples like this. Many people has more eyes,
especially if you know how ts/section/packet data structure should look 
like, would be of great help fixing other two oops-es in ..section_packet().

Best regards, Emard
ksymoops 2.4.5 on i686 2.4.20.  Options used
     -V (default)
     -k /proc/ksyms (default)
     -l /proc/modules (default)
     -o /lib/modules/2.4.20/ (default)
     -m /boot/2.4.20-nov4l1/System.map (specified)

115200
Unable to handle kernel paging request at virtual address f8940002
f88ec0c9
*pde = 019ca067
Oops: 0000
CPU:    0
EIP:    0010:[<f88ec0c9>]    Not tainted
Using defaults from ksymoops -t elf32-i386 -a i386
EFLAGS: 00010206
eax: 00000033   ebx: 00000038   ecx: f8940001   edx: f893ffc9
esi: f894c000   edi: f55e0e9c   ebp: 00000084   esp: c0361ee8
ds: 0018   es: 0018   ss: 0018
Process swapper (pid: 0, stackpage=c0361000)
Stack: f894c000 f893ffc9 f55e0e9c ae4c415d 00000038 f55e0e9c f88ec43d f894c000 
       f893ffc9 00000001 f893ffc9 f88ec49a f55e0e9c f893ffc9 000001b9 f55e0000 
       f8911000 f890c36e f55e0e9c f89311d9 00000145 00000000 c037c280 00000000 
Call Trace:    [<f88ec43d>] [<f88ec49a>] [<f890c36e>] [<c01199ce>] [<c011985a>]
  [<c0109ad2>] [<c010bbc8>] [<c0106cf3>] [<f8834415>] [<f883430c>] [<c0106cd0>]
  [<c0106d59>] [<c0105000>] [<c0105027>]
Code: 8a 41 01 24 0f c1 e0 08 83 c0 03 66 0f b6 51 02 01 d0 0f b7 


>>EIP; f88ec0c9 <[dvb-core]dvb_dmx_swfilter_section_packet+231/49c>   <=====

>>ecx; f8940001 <[dvb-ttpci-budget].data.end+32262/2ad261>
>>edx; f893ffc9 <[dvb-ttpci-budget].data.end+3222a/2ad261>
>>esi; f894c000 <[dvb-ttpci-budget].data.end+3e261/2ad261>
>>edi; f55e0e9c <_end+3522617c/384762e0>
>>esp; c0361ee8 <init_task_union+1ee8/2000>

Trace; f88ec43d <[dvb-core]dvb_dmx_swfilter_packet+109/128>
Trace; f88ec49a <[dvb-core]dvb_dmx_swfilter_packets+3e/50>
Trace; f890c36e <[dvb-ttpci-budget]vpeirq+8a/c4>
Trace; c01199ce <tasklet_action+46/64>
Trace; c011985a <do_softirq+5a/a4>
Trace; c0109ad2 <do_IRQ+96/a8>
Trace; c010bbc8 <call_do_IRQ+5/d>
Trace; c0106cf3 <default_idle+23/28>
Trace; f8834415 <[apm]apm_cpu_idle+109/13c>
Trace; f883430c <[apm]apm_cpu_idle+0/13c>
Trace; c0106cd0 <default_idle+0/28>
Trace; c0106d59 <cpu_idle+41/54>
Trace; c0105000 <_stext+0/0>
Trace; c0105027 <rest_init+27/28>

Code;  f88ec0c9 <[dvb-core]dvb_dmx_swfilter_section_packet+231/49c>
00000000 <_EIP>:
Code;  f88ec0c9 <[dvb-core]dvb_dmx_swfilter_section_packet+231/49c>   <=====
   0:   8a 41 01                  mov    0x1(%ecx),%al   <=====
Code;  f88ec0cc <[dvb-core]dvb_dmx_swfilter_section_packet+234/49c>
   3:   24 0f                     and    $0xf,%al
Code;  f88ec0ce <[dvb-core]dvb_dmx_swfilter_section_packet+236/49c>
   5:   c1 e0 08                  shl    $0x8,%eax
Code;  f88ec0d1 <[dvb-core]dvb_dmx_swfilter_section_packet+239/49c>
   8:   83 c0 03                  add    $0x3,%eax
Code;  f88ec0d4 <[dvb-core]dvb_dmx_swfilter_section_packet+23c/49c>
   b:   66 0f b6 51 02            movzbw 0x2(%ecx),%dx
Code;  f88ec0d9 <[dvb-core]dvb_dmx_swfilter_section_packet+241/49c>
  10:   01 d0                     add    %edx,%eax
Code;  f88ec0db <[dvb-core]dvb_dmx_swfilter_section_packet+243/49c>
  12:   0f b7 00                  movzwl (%eax),%eax

 <0>Kernel panic: Aiee, killing interrupt handler!
ksymoops 2.4.5 on i686 2.4.20.  Options used
     -V (default)
     -k /proc/ksyms (default)
     -l /proc/modules (default)
     -o /lib/modules/2.4.20/ (default)
     -m /boot/2.4.20-nov4l1/System.map (specified)

115200
Unable to handle kernel paging request at virtual address f8940066
f88ebf30
*pde = 019ca067
Oops: 0000
CPU:    0
EIP:    0010:[<f88ebf30>]    Not tainted
Using defaults from ksymoops -t elf32-i386 -a i386
EFLAGS: 00010202
eax: 00000000   ebx: 0000009d   ecx: 00000000   edx: f893ffc9
esi: f894d074   edi: f6420e9c   ebp: 0000001f   esp: c0361eb0
ds: 0018   es: 0018   ss: 0018
Process swapper (pid: 0, stackpage=c0361000)
Stack: f894d074 f893ffc9 f6420e9c ae4c415d 0000009d f6420e9c f88ec43d f894d074 
       f893ffc9 00000001 f893ffc9 f88ec49a f6420e9c f893ffc9 00000399 f6420000 
       f8911000 f890c36e f6420e9c f89311d9 00000145 00000000 c037c280 00000000 
Call Trace:    [<f88ec43d>] [<f88ec49a>] [<f890c36e>] [<c01199ce>] [<c011985a>]
  [<c0109ad2>] [<c010bbc8>] [<f8834186>] [<f8834288>] [<f88343c5>] [<f883430c>]
  [<c0106cd0>] [<c0106d59>] [<c0105000>] [<c0105027>]
Code: 0f b6 04 13 01 d8 3d bb 00 00 00 0f 8f bf 03 00 00 8b 6c 24 


>>EIP; f88ebf30 <[dvb-core]dvb_dmx_swfilter_section_packet+98/49c>   <=====

>>edx; f893ffc9 <[dvb-ttpci-budget].data.end+3222a/2ad261>
>>esi; f894d074 <[dvb-ttpci-budget].data.end+3f2d5/2ad261>
>>edi; f6420e9c <_end+3606617c/384762e0>
>>esp; c0361eb0 <init_task_union+1eb0/2000>

Trace; f88ec43d <[dvb-core]dvb_dmx_swfilter_packet+109/128>
Trace; f88ec49a <[dvb-core]dvb_dmx_swfilter_packets+3e/50>
Trace; f890c36e <[dvb-ttpci-budget]vpeirq+8a/c4>
Trace; c01199ce <tasklet_action+46/64>
Trace; c011985a <do_softirq+5a/a4>
Trace; c0109ad2 <do_IRQ+96/a8>
Trace; c010bbc8 <call_do_IRQ+5/d>
Trace; f8834186 <[apm]__module_parm_desc_allow_ints+26/34>
Trace; f8834288 <[apm]__module_parm_desc_idle_threshold+8/58>
Trace; f88343c5 <[apm]apm_cpu_idle+b9/13c>
Trace; f883430c <[apm]apm_cpu_idle+0/13c>
Trace; c0106cd0 <default_idle+0/28>
Trace; c0106d59 <cpu_idle+41/54>
Trace; c0105000 <_stext+0/0>
Trace; c0105027 <rest_init+27/28>

Code;  f88ebf30 <[dvb-core]dvb_dmx_swfilter_section_packet+98/49c>
00000000 <_EIP>:
Code;  f88ebf30 <[dvb-core]dvb_dmx_swfilter_section_packet+98/49c>   <=====
   0:   0f b6 04 13               movzbl (%ebx,%edx,1),%eax   <=====
Code;  f88ebf34 <[dvb-core]dvb_dmx_swfilter_section_packet+9c/49c>
   4:   01 d8                     add    %ebx,%eax
Code;  f88ebf36 <[dvb-core]dvb_dmx_swfilter_section_packet+9e/49c>
   6:   3d bb 00 00 00            cmp    $0xbb,%eax
Code;  f88ebf3b <[dvb-core]dvb_dmx_swfilter_section_packet+a3/49c>
   b:   0f 8f bf 03 00 00         jg     3d0 <_EIP+0x3d0> f88ec300 <[dvb-core]dvb_dmx_swfilter_section_packet+468/49c>
Code;  f88ebf41 <[dvb-core]dvb_dmx_swfilter_section_packet+a9/49c>
  11:   8b 6c 24 00               mov    0x0(%esp,1),%ebp

 <0>Kernel panic: Aiee, killing interrupt handler!
Only in dvb-kernel/build-2.4: .alps_bsrv2.o.flags
Only in dvb-kernel/build-2.4: .alps_tdlb7.o.flags
Only in dvb-kernel/build-2.4: .alps_tdmb7.o.flags
Only in dvb-kernel/build-2.4: .at76c651.o.flags
Only in dvb-kernel/build-2.4: .av7110.o.flags
Only in dvb-kernel/build-2.4: .av7110_ipack.o.flags
Only in dvb-kernel/build-2.4: .av7110_ir.o.flags
Only in dvb-kernel/build-2.4: .bt878.o.flags
Only in dvb-kernel/build-2.4: .budget-av.o.flags
Only in dvb-kernel/build-2.4: .budget-core.o.flags
Only in dvb-kernel/build-2.4: .budget.o.flags
Only in dvb-kernel/build-2.4: .compat.o.flags
Only in dvb-kernel/build-2.4: .dmxdev.o.flags
Only in dvb-kernel/build-2.4: .dvb-bt8xx.o.flags
Only in dvb-kernel/build-2.4: .dvb_demux.o.flags
Only in dvb-kernel/build-2.4: .dvb_filter.o.flags
Only in dvb-kernel/build-2.4: .dvb_frontend.o.flags
Only in dvb-kernel/build-2.4: .dvb_i2c.o.flags
Only in dvb-kernel/build-2.4: .dvb_ksyms.o.flags
Only in dvb-kernel/build-2.4: .dvb_net.o.flags
Only in dvb-kernel/build-2.4: .dvbdev.o.flags
Only in dvb-kernel/build-2.4: .grundig_29504-401.o.flags
Only in dvb-kernel/build-2.4: .grundig_29504-491.o.flags
Only in dvb-kernel/build-2.4: .nxt6000.o.flags
Only in dvb-kernel/build-2.4: .saa7146_core.o.flags
Only in dvb-kernel/build-2.4: .saa7146_fops.o.flags
Only in dvb-kernel/build-2.4: .saa7146_hlp.o.flags
Only in dvb-kernel/build-2.4: .saa7146_i2c.o.flags
Only in dvb-kernel/build-2.4: .saa7146_vbi.o.flags
Only in dvb-kernel/build-2.4: .saa7146_video.o.flags
Only in dvb-kernel/build-2.4: .stv0299.o.flags
Only in dvb-kernel/build-2.4: .v4l1-compat.o.flags
Only in dvb-kernel/build-2.4: .v4l2-common.o.flags
Only in dvb-kernel/build-2.4: .version
Only in dvb-kernel/build-2.4: .ves1820.o.flags
Only in dvb-kernel/build-2.4: .video-buf.o.flags
Only in dvb-kernel/build-2.4: .videodev.o.flags
Only in dvb-kernel/build-2.4: alps_bsrv2.c
Only in dvb-kernel/build-2.4: alps_bsrv2.o
Only in dvb-kernel/build-2.4: alps_tdlb7.c
Only in dvb-kernel/build-2.4: alps_tdlb7.o
Only in dvb-kernel/build-2.4: alps_tdmb7.c
Only in dvb-kernel/build-2.4: alps_tdmb7.o
Only in dvb-kernel/build-2.4: at76c651.c
Only in dvb-kernel/build-2.4: at76c651.o
Only in dvb-kernel/build-2.4: av7110.c
Only in dvb-kernel/build-2.4: av7110.h
Only in dvb-kernel/build-2.4: av7110.o
Only in dvb-kernel/build-2.4: av7110_firm.h
Only in dvb-kernel/build-2.4: av7110_ipack.c
Only in dvb-kernel/build-2.4: av7110_ipack.h
Only in dvb-kernel/build-2.4: av7110_ipack.o
Only in dvb-kernel/build-2.4: av7110_ir.c
Only in dvb-kernel/build-2.4: av7110_ir.o
Only in dvb-kernel/build-2.4: bt848.h
Only in dvb-kernel/build-2.4: bt878.c
Only in dvb-kernel/build-2.4: bt878.h
Only in dvb-kernel/build-2.4: bt878.o
Only in dvb-kernel/build-2.4: budget-av.c
Only in dvb-kernel/build-2.4: budget-av.o
Only in dvb-kernel/build-2.4: budget-core.c
Only in dvb-kernel/build-2.4: budget-core.c~
Only in dvb-kernel/build-2.4: budget-core.o
Only in dvb-kernel/build-2.4: budget.c
Only in dvb-kernel/build-2.4: budget.h
Only in dvb-kernel/build-2.4: budget.o
Only in dvb-kernel/build-2.4: compat.c
Only in dvb-kernel/build-2.4: compat.h
Only in dvb-kernel/build-2.4: compat.o
Only in dvb-kernel/build-2.4: demux.h
Only in dvb-kernel/build-2.4: dmxdev.c
Only in dvb-kernel/build-2.4: dmxdev.h
Only in dvb-kernel/build-2.4: dmxdev.o
Only in dvb-kernel/build-2.4: driver.av7110
Only in dvb-kernel/build-2.4: dvb-bt8xx.c
Only in dvb-kernel/build-2.4: dvb-bt8xx.h
Only in dvb-kernel/build-2.4: dvb-bt8xx.o
Only in dvb-kernel/build-2.4: dvb-core.o
Only in dvb-kernel/build-2.4: dvb-ttpci-budget-av.o
Only in dvb-kernel/build-2.4: dvb-ttpci-budget.o
Only in dvb-kernel/build-2.4: dvb-ttpci.o
Only in dvb-kernel/build-2.4: dvb_demux.c
Only in dvb-kernel/build-2.4: dvb_demux.c~
Only in dvb-kernel/build-2.4: dvb_demux.h
Only in dvb-kernel/build-2.4: dvb_demux.o
Only in dvb-kernel/build-2.4: dvb_demux.s
Only in dvb-kernel/build-2.4: dvb_filter.c
Only in dvb-kernel/build-2.4: dvb_filter.h
Only in dvb-kernel/build-2.4: dvb_filter.o
Only in dvb-kernel/build-2.4: dvb_frontend.c
Only in dvb-kernel/build-2.4: dvb_frontend.h
Only in dvb-kernel/build-2.4: dvb_frontend.o
Only in dvb-kernel/build-2.4: dvb_i2c.c
Only in dvb-kernel/build-2.4: dvb_i2c.h
Only in dvb-kernel/build-2.4: dvb_i2c.o
Only in dvb-kernel/build-2.4: dvb_ksyms.c
Only in dvb-kernel/build-2.4: dvb_ksyms.o
Only in dvb-kernel/build-2.4: dvb_net.c
Only in dvb-kernel/build-2.4: dvb_net.h
Only in dvb-kernel/build-2.4: dvb_net.o
Only in dvb-kernel/build-2.4: dvbdev.c
Only in dvb-kernel/build-2.4: dvbdev.h
Only in dvb-kernel/build-2.4: dvbdev.o
Only in dvb-kernel/build-2.4: grundig_29504-401.c
Only in dvb-kernel/build-2.4: grundig_29504-401.o
Only in dvb-kernel/build-2.4: grundig_29504-491.c
Only in dvb-kernel/build-2.4: grundig_29504-491.o
Only in dvb-kernel/build-2.4: nxt6000.c
Only in dvb-kernel/build-2.4: nxt6000.h
Only in dvb-kernel/build-2.4: nxt6000.o
Only in dvb-kernel/build-2.4: saa7146.h
Only in dvb-kernel/build-2.4: saa7146.o
Only in dvb-kernel/build-2.4: saa7146_core.c
Only in dvb-kernel/build-2.4: saa7146_core.o
Only in dvb-kernel/build-2.4: saa7146_fops.c
Only in dvb-kernel/build-2.4: saa7146_fops.o
Only in dvb-kernel/build-2.4: saa7146_hlp.c
Only in dvb-kernel/build-2.4: saa7146_hlp.o
Only in dvb-kernel/build-2.4: saa7146_i2c.c
Only in dvb-kernel/build-2.4: saa7146_i2c.o
Only in dvb-kernel/build-2.4: saa7146_vbi.c
Only in dvb-kernel/build-2.4: saa7146_vbi.o
Only in dvb-kernel/build-2.4: saa7146_video.c
Only in dvb-kernel/build-2.4: saa7146_video.o
Only in dvb-kernel/build-2.4: saa7146_vv.h
Only in dvb-kernel/build-2.4: saa7146_vv.o
Only in dvb-kernel/build-2.4: stv0299.c
Only in dvb-kernel/build-2.4: stv0299.o
Only in dvb-kernel/build-2.4: v4l1-compat.o
Only in dvb-kernel/build-2.4: v4l2-common.o
Only in dvb-kernel/build-2.4: ves1820.c
Only in dvb-kernel/build-2.4: ves1820.o
Only in dvb-kernel/build-2.4: video-buf.o
Only in dvb-kernel/build-2.4: videodev.o
Only in dvb-kernel/build-2.4: vpeirq
diff -pur orig/dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_demux.c dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_demux.c
--- orig/dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_demux.c	Wed Jan 22 22:00:34 2003
+++ dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_demux.c	Sat Feb  8 23:15:31 2003
@@ -451,7 +451,13 @@ void dvb_dmx_swfilter_packet_type(struct
 
 void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
 {
-	struct dvb_demux_feed *feed = demux->pid2feed[ts_pid(buf)];
+	struct dvb_demux_feed *feed;
+	u32 pid = ts_pid(buf);
+
+	if(pid >= DMX_MAX_PID)
+		return;
+		
+	feed = demux->pid2feed[pid];
 
 	if (!feed)
 		return;
@@ -466,7 +472,7 @@ void dvb_dmx_swfilter_packets(struct dvb
 
 	spin_lock(&demux->lock);
 
-	if ((feed = demux->pid2feed[0x2000]))
+	if ((feed = demux->pid2feed[DMX_MAX_PID]))
 		feed->cb.ts(buf, count*188, 0, 0, &feed->feed.ts, DMX_OK); 
 
 	while (count) {
diff -pur orig/dvb-kernel/linux/drivers/media/dvb/ttpci-budget/budget-core.c dvb-kernel/linux/drivers/media/dvb/ttpci-budget/budget-core.c
--- orig/dvb-kernel/linux/drivers/media/dvb/ttpci-budget/budget-core.c	Fri Feb  7 20:57:15 2003
+++ dvb-kernel/linux/drivers/media/dvb/ttpci-budget/budget-core.c	Sat Feb  8 23:17:29 2003
@@ -111,7 +111,8 @@ static void vpeirq (unsigned long data)
         u32 dmapos;
 
         dmapos=saa7146_read(budget->dev, PCI_VDP3);
-        dmapos-=(dmapos%188);
+        // dmapos-=(dmapos%188);
+        dmapos = (dmapos + 441) % TS_BUFLEN;
 
         if (dmapos >= TS_BUFLEN)
                 return;
@@ -120,7 +121,7 @@ static void vpeirq (unsigned long data)
                mem+=budget->ttbp;
                num=(dmapos-budget->ttbp)/188;
         } else {
-               if (budget->feeding && mem[budget->ttbp]==0x47)
+               if (budget->feeding && *(mem+budget->ttbp) != 0x47)
                          dvb_dmx_swfilter_packets(&budget->demux,
                                  mem+budget->ttbp, 1024-budget->ttbp/188);
 
@@ -129,7 +130,7 @@ static void vpeirq (unsigned long data)
 
         budget->ttbp=dmapos;
 
-        if (budget->feeding && mem[0]==0x47)
+        if (budget->feeding && *mem != 0x47)
                 dvb_dmx_swfilter_packets(&budget->demux, mem, num);
 }
 
@@ -353,6 +354,160 @@ int budget_diseqc_ioctl (struct dvb_fron
 	return 0;
 }
 
+/* Start of budget patch diseqc commands (EMARD)
+*/
+#define COMMAND (DPRAM_BASE + 0x0FC)
+#define DPRAM_BASE 0x4000
+#define DEBINOSWAP 0x000e0000
+
+typedef enum  { 
+	AudioDAC,
+	CabADAC,
+	ON22K,
+	OFF22K,
+	MainSwitch,
+	ADSwitch,
+	SendDiSEqC,
+	SetRegister
+} AUDCOM;
+
+typedef enum  { 
+	COMTYPE_NOCOM,
+	COMTYPE_PIDFILTER,
+	COMTYPE_MPEGDECODER,
+	COMTYPE_OSD,
+	COMTYPE_BMP,
+	COMTYPE_ENCODER,
+	COMTYPE_AUDIODAC,
+	COMTYPE_REQUEST,
+	COMTYPE_SYSTEM,
+	COMTYPE_REC_PLAY,
+	COMTYPE_COMMON_IF,
+	COMTYPE_PID_FILTER,
+	COMTYPE_PES,
+	COMTYPE_TS,
+	COMTYPE_VIDEO,
+	COMTYPE_AUDIO,
+	COMTYPE_CI_LL,
+} COMTYPE;
+
+static int wdebi(struct budget_s *budget, 
+	u32 config, int addr, u32 val, int count)
+{
+        struct saa7146_dev *dev=budget->dev;
+
+	DEB_EE(("budget: %p\n", budget));
+
+	if (count <= 0 || count > 4)
+		return -1;
+
+	saa7146_write(dev, DEBI_CONFIG, config);
+
+	saa7146_write(dev, DEBI_AD, val );
+	saa7146_write(dev, DEBI_COMMAND, (count << 17) | (addr & 0xffff));
+	saa7146_write(dev, MC2, (2 << 16) | 2);
+        mdelay(5);
+
+	return 0;
+}
+
+static int SOutCommand(struct budget_s *budget, u16* buf, int length)
+{
+        int i;
+
+	DEB_EE(("budget: %p\n",budget));
+
+        for (i = 2; i < length; i++)
+                wdebi(budget, DEBINOSWAP, COMMAND + 2*i, (u32) buf[i], 2);
+
+        if (length)
+                wdebi(budget, DEBINOSWAP, COMMAND + 2, (u32) buf[1], 2);
+        else
+                wdebi(budget, DEBINOSWAP, COMMAND + 2, 0, 2);
+
+        wdebi(budget, DEBINOSWAP, COMMAND, (u32) buf[0], 2);
+        return 0;
+}
+
+static void 
+av7110_Set22K(struct budget_s *budget, int state)
+{
+        u16 buf[2] = {( COMTYPE_AUDIODAC << 8) | (state ? ON22K : OFF22K), 0};
+        
+ 	DEB_EE(("budget: %p\n", budget));
+	SOutCommand(budget, buf, 2);
+}
+
+static int
+av7110_SendDiSEqCMsg(struct budget_s *budget, int len, u8 *msg, int burst)
+{
+	int i;
+	u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) | SendDiSEqC),
+		16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+ 	DEB_EE(("budget: %p\n", budget));
+
+        if (len>10)
+		len=10;
+
+	buf[1] = len+2;
+	buf[2] = len;
+
+	if (burst != -1)
+		buf[3]=burst ? 0x01 : 0x00;
+        else
+		buf[3]=0xffff;
+                
+	for (i=0; i<len; i++)
+		buf[i+4]=msg[i];
+
+	SOutCommand(budget, buf, 18);
+	return 0;
+}
+
+static
+int av7110_diseqc_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
+{
+	struct budget_s *budget = fe->before_after_data;
+
+	DEB_EE(("budget: %p\n", budget));
+
+	switch (cmd) {
+	case FE_SET_TONE:
+		switch ((fe_sec_tone_mode_t) arg) {
+		case SEC_TONE_ON:
+			av7110_Set22K (budget, 1);
+			break;
+		case SEC_TONE_OFF:
+			av7110_Set22K (budget, 0);
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
+
+	case FE_DISEQC_SEND_MASTER_CMD:
+	{
+		struct dvb_diseqc_master_cmd *cmd = arg;
+
+		av7110_SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0);
+		break;
+	}
+
+        case FE_DISEQC_SEND_BURST:
+		av7110_SendDiSEqCMsg (budget, 0, NULL, (int) arg);
+		break;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+/* End of budget patch diseqc commands (EMARD)
+*/
+
+
 int budget_register(struct budget_s *budget)
 {
         int ret;
@@ -369,6 +524,9 @@ int budget_register(struct budget_s *bud
 	/* init DiSEqC stuff if necessary */
 	if(budget->card->type == BUDGET_TT)
 		dvb_add_frontend_ioctls (budget->dvb_adapter, budget_diseqc_ioctl, NULL, budget);
+
+	if(budget->card->type == BUDGET_PATCH)
+		dvb_add_frontend_ioctls (budget->dvb_adapter, av7110_diseqc_ioctl, NULL, budget);
 
         memcpy(budget->demux_id, "demux0_0", 9);
         budget->demux_id[5] = budget->dvb_adapter->num + '0';
Only in dvb-kernel/linux/drivers/media/dvb/ttpci-budget: budget-core.c.orig
diff -pur orig/dvb-kernel/linux/drivers/media/dvb/ttpci-budget/budget.c dvb-kernel/linux/drivers/media/dvb/ttpci-budget/budget.c
--- orig/dvb-kernel/linux/drivers/media/dvb/ttpci-budget/budget.c	Fri Feb  7 20:57:15 2003
+++ dvb-kernel/linux/drivers/media/dvb/ttpci-budget/budget.c	Sat Feb  8 22:28:11 2003
@@ -45,7 +45,7 @@ MAKE_BUDGET_INFO(fs_1_3,"Siemens/Technot
 
 static
 struct pci_device_id pci_tbl[] = {
-//	MAKE_EXTENSION_PCI(fs_1_3,0x13c2, 0x0000), /* Uncomment for Budget Patch */
+	MAKE_EXTENSION_PCI(fs_1_3,0x13c2, 0x0000), /* Uncomment for Budget Patch */
 	MAKE_EXTENSION_PCI(ttbs,  0x13c2, 0x1003),
 	MAKE_EXTENSION_PCI(ttbc,  0x13c2, 0x1004),
 	MAKE_EXTENSION_PCI(ttbt,  0x13c2, 0x1005),

Home | Main Index | Thread Index