ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / media / dvb / dvb-core / dvb_demux.c
1 /* 
2  * dvb_demux.c - DVB kernel demux API
3  *
4  * Copyright (C) 2000-2001 Ralph  Metzler <ralph@convergence.de>
5  *                     & Marcus Metzler <marcus@convergence.de>
6  *                       for convergence integrated media GmbH
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation; either version 2.1
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  */
23
24 #include <linux/spinlock.h>
25 #include <linux/slab.h>
26 #include <linux/vmalloc.h>
27 #include <linux/module.h>
28 #include <linux/poll.h>
29 #include <linux/string.h>
30         #include <linux/crc32.h>
31 #include <asm/uaccess.h>
32
33 #include "dvb_demux.h"
34 #include "dvb_functions.h"
35
36 #define NOBUFS  
37 /* 
38 ** #define DVB_DEMUX_SECTION_LOSS_LOG to monitor payload loss in the syslog
39 */
40 // #define DVB_DEMUX_SECTION_LOSS_LOG
41
42
43 LIST_HEAD(dmx_muxs);
44
45
46 int dmx_register_demux(struct dmx_demux *demux) 
47 {
48         demux->users = 0;
49         list_add(&demux->reg_list, &dmx_muxs);
50         return 0;
51 }
52
53 int dmx_unregister_demux(struct dmx_demux* demux)
54 {
55         struct list_head *pos, *n, *head=&dmx_muxs;
56
57         list_for_each_safe (pos, n, head) {
58                 if (DMX_DIR_ENTRY(pos) == demux) {
59                         if (demux->users>0)
60                                 return -EINVAL;
61                         list_del(pos);
62                         return 0;
63                 }
64         }
65
66         return -ENODEV;
67 }
68
69
70 struct list_head *dmx_get_demuxes(void)
71 {
72         if (list_empty(&dmx_muxs))
73                 return NULL;
74
75         return &dmx_muxs;
76 }
77
78 /******************************************************************************
79  * static inlined helper functions
80  ******************************************************************************/
81
82
83 static inline u16 section_length(const u8 *buf)
84 {
85         return 3+((buf[1]&0x0f)<<8)+buf[2];
86 }
87
88
89 static inline u16 ts_pid(const u8 *buf)
90 {
91         return ((buf[1]&0x1f)<<8)+buf[2];
92 }
93
94
95 static inline u8 payload(const u8 *tsp)
96 {
97         if (!(tsp[3]&0x10)) // no payload?
98                 return 0;
99         if (tsp[3]&0x20) {  // adaptation field?
100                 if (tsp[4]>183)    // corrupted data?
101                         return 0;
102                 else
103                         return 184-1-tsp[4];
104         }
105         return 184;
106 }
107
108
109 void dvb_set_crc32(u8 *data, int length)
110 {
111         u32 crc;
112
113         crc = crc32_be(~0, data, length);
114
115         data[length]   = (crc >> 24) & 0xff;
116         data[length+1] = (crc >> 16) & 0xff;
117         data[length+2] = (crc >>  8) & 0xff;
118         data[length+3] = (crc)       & 0xff;
119 }
120
121
122 static u32 dvb_dmx_crc32 (struct dvb_demux_feed *f, const u8 *src, size_t len)
123 {
124         return (f->feed.sec.crc_val = crc32_be (f->feed.sec.crc_val, src, len));
125 }
126
127
128 static void dvb_dmx_memcopy (struct dvb_demux_feed *f, u8 *d, const u8 *s, size_t len)
129 {
130         memcpy (d, s, len);
131 }
132
133
134 /******************************************************************************
135  * Software filter functions
136  ******************************************************************************/
137
138 static inline int dvb_dmx_swfilter_payload (struct dvb_demux_feed *feed, const u8 *buf) 
139 {
140         int count = payload(buf);
141         int p;
142         //int ccok;
143         //u8 cc;
144
145         if (count == 0)
146                 return -1;
147
148         p = 188-count;
149
150         /*
151         cc=buf[3]&0x0f;
152         ccok=((dvbdmxfeed->cc+1)&0x0f)==cc ? 1 : 0;
153         dvbdmxfeed->cc=cc;
154         if (!ccok)
155                 printk("missed packet!\n");
156         */
157
158         if (buf[1] & 0x40)  // PUSI ?
159                 feed->peslen = 0xfffa;
160
161         feed->peslen += count;
162
163         return feed->cb.ts (&buf[p], count, 0, 0, &feed->feed.ts, DMX_OK); 
164 }
165
166
167 static int dvb_dmx_swfilter_sectionfilter (struct dvb_demux_feed *feed, 
168                                     struct dvb_demux_filter *f)
169 {
170         u8 neq = 0;
171         int i;
172
173         for (i=0; i<DVB_DEMUX_MASK_MAX; i++) {
174                 u8 xor = f->filter.filter_value[i] ^ feed->feed.sec.secbuf[i];
175
176                 if (f->maskandmode[i] & xor)
177                         return 0;
178
179                 neq |= f->maskandnotmode[i] & xor;
180         }
181
182         if (f->doneq & !neq)
183                 return 0;
184
185         return feed->cb.sec (feed->feed.sec.secbuf, feed->feed.sec.seclen, 
186                              0, 0, &f->filter, DMX_OK); 
187 }
188
189
190 static inline int dvb_dmx_swfilter_section_feed (struct dvb_demux_feed *feed)
191 {
192         struct dvb_demux *demux = feed->demux;
193         struct dvb_demux_filter *f = feed->filter;
194         struct dmx_section_feed *sec = &feed->feed.sec;
195         int section_syntax_indicator;
196
197         if (!sec->is_filtering)
198                 return 0;
199
200         if (!f)
201                 return 0;
202
203         if (sec->check_crc) {
204                 section_syntax_indicator = ((sec->secbuf[1] & 0x80) != 0);
205                 if (section_syntax_indicator &&
206                     demux->check_crc32(feed, sec->secbuf, sec->seclen))
207                 return -1;
208         }
209
210         do {
211                 if (dvb_dmx_swfilter_sectionfilter(feed, f) < 0)
212                         return -1;
213         } while ((f = f->next) && sec->is_filtering);
214
215         sec->seclen = 0;
216
217         return 0;
218 }
219
220
221 static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
222 {
223         struct dmx_section_feed *sec = &feed->feed.sec;
224
225 #ifdef DVB_DEMUX_SECTION_LOSS_LOG
226         if(sec->secbufp < sec->tsfeedp)
227         {
228                 int i, n = sec->tsfeedp - sec->secbufp;
229
230                 /* section padding is done with 0xff bytes entirely.
231                 ** due to speed reasons, we won't check all of them
232                 ** but just first and last
233                 */
234                 if(sec->secbuf[0] != 0xff || sec->secbuf[n-1] != 0xff)
235                 {
236                         printk("dvb_demux.c section ts padding loss: %d/%d\n", 
237                                n, sec->tsfeedp);
238                         printk("dvb_demux.c pad data:");
239                         for(i = 0; i < n; i++)
240                                 printk(" %02x", sec->secbuf[i]);
241                         printk("\n");
242                         }
243                         }
244 #endif
245
246         sec->tsfeedp = sec->secbufp = sec->seclen = 0;
247         sec->secbuf = sec->secbuf_base;
248                 }
249
250 /* 
251 ** Losless Section Demux 1.4 by Emard
252 */
253 static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed, const u8 *buf, u8 len)
254 {
255         struct dvb_demux *demux = feed->demux;
256         struct dmx_section_feed *sec = &feed->feed.sec;
257         u16 limit, seclen, n;
258
259         if(sec->tsfeedp >= DMX_MAX_SECFEED_SIZE)
260                 return 0;
261
262         if(sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE)
263         {
264 #ifdef DVB_DEMUX_SECTION_LOSS_LOG
265                 printk("dvb_demux.c section buffer full loss: %d/%d\n", 
266                        sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE, DMX_MAX_SECFEED_SIZE);
267 #endif
268                 len = DMX_MAX_SECFEED_SIZE - sec->tsfeedp;
269         }
270
271         if(len <= 0)
272                 return 0;
273
274         demux->memcopy(feed, sec->secbuf_base + sec->tsfeedp, buf, len);
275         sec->tsfeedp += len;
276
277         /* -----------------------------------------------------
278         ** Dump all the sections we can find in the data (Emard)
279         */
280
281         limit = sec->tsfeedp;
282         if(limit > DMX_MAX_SECFEED_SIZE)
283                 return -1; /* internal error should never happen */
284
285         /* to be sure always set secbuf */
286         sec->secbuf = sec->secbuf_base + sec->secbufp;
287
288         for(n = 0; sec->secbufp + 2 < limit; n++)
289         {
290                 seclen = section_length(sec->secbuf);
291                 if(seclen <= 0 || seclen > DMX_MAX_SECFEED_SIZE 
292                    || seclen + sec->secbufp > limit)
293                         return 0;
294                 sec->seclen = seclen;
295                 sec->crc_val = ~0;
296                 /* dump [secbuf .. secbuf+seclen) */
297                 dvb_dmx_swfilter_section_feed(feed);
298                 sec->secbufp += seclen; /* secbufp and secbuf moving together is */
299                 sec->secbuf += seclen; /* redundand but saves pointer arithmetic */
300                 }
301
302                 return 0;
303         }
304
305
306 static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, const u8 *buf) 
307 {
308         u8 p, count;
309         int ccok;
310         u8 cc;
311
312         count = payload(buf);
313                 
314         if (count == 0)  /* count == 0 if no payload or out of range */
315                         return -1;
316
317         p = 188-count; /* payload start */
318
319         cc = buf[3] & 0x0f;
320         ccok = ((feed->cc+1) & 0x0f) == cc ? 1 : 0;
321         feed->cc = cc;
322         if(ccok == 0)
323         {
324 #ifdef DVB_DEMUX_SECTION_LOSS_LOG
325                 printk("dvb_demux.c discontinuity detected %d bytes lost\n", count);
326                 /* those bytes under sume circumstances will again be reported
327                 ** in the following dvb_dmx_swfilter_section_new
328                 */
329 #endif
330                 dvb_dmx_swfilter_section_new(feed);
331                 return 0;
332         }
333
334         if(buf[1] & 0x40)
335         {
336                 // PUSI=1 (is set), section boundary is here
337                 if(count > 1 && buf[p] < count)
338                 {
339                         const u8 *before = buf+p+1;
340                         u8 before_len = buf[p];
341                         const u8 *after = before+before_len;
342                         u8 after_len = count-1-before_len;
343
344                         dvb_dmx_swfilter_section_copy_dump(feed, before, before_len);
345                         dvb_dmx_swfilter_section_new(feed);
346                         dvb_dmx_swfilter_section_copy_dump(feed, after, after_len);
347                 }
348 #ifdef DVB_DEMUX_SECTION_LOSS_LOG
349                 else
350                         if(count > 0)
351                                 printk("dvb_demux.c PUSI=1 but %d bytes lost\n", count);
352 #endif
353         }
354         else
355         {
356                 // PUSI=0 (is not set), no section boundary
357                 const u8 *entire = buf+p;
358                 u8 entire_len = count;
359
360                 dvb_dmx_swfilter_section_copy_dump(feed, entire, entire_len);
361         }
362         return 0;
363 }
364
365
366 static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, const u8 *buf)
367 {
368         switch(feed->type) {
369         case DMX_TYPE_TS:
370                 if (!feed->feed.ts.is_filtering)
371                         break;
372                 if (feed->ts_type & TS_PACKET) {
373                         if (feed->ts_type & TS_PAYLOAD_ONLY)
374                                 dvb_dmx_swfilter_payload(feed, buf);
375                         else
376                                 feed->cb.ts(buf, 188, 0, 0, &feed->feed.ts, DMX_OK); 
377                 }
378                 if (feed->ts_type & TS_DECODER) 
379                         if (feed->demux->write_to_decoder)
380                                 feed->demux->write_to_decoder(feed, buf, 188);
381                 break;
382
383         case DMX_TYPE_SEC:
384                 if (!feed->feed.sec.is_filtering)
385                         break;
386                 if (dvb_dmx_swfilter_section_packet(feed, buf) < 0)
387                         feed->feed.sec.seclen = feed->feed.sec.secbufp=0;
388                 break;
389
390         default:
391                 break;
392         }
393 }
394
395 #define DVR_FEED(f)                                                     \
396         (((f)->type == DMX_TYPE_TS) &&                                  \
397         ((f)->feed.ts.is_filtering) &&                                  \
398         (((f)->ts_type & (TS_PACKET|TS_PAYLOAD_ONLY)) == TS_PACKET))
399
400 void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
401 {
402         struct dvb_demux_feed *feed;
403         struct list_head *pos, *head=&demux->feed_list;
404         u16 pid = ts_pid(buf);
405         int dvr_done = 0;
406
407         list_for_each(pos, head) {
408                 feed = list_entry(pos, struct dvb_demux_feed, list_head);
409
410                 if ((feed->pid != pid) && (feed->pid != 0x2000))
411                         continue;
412
413                 /* copy each packet only once to the dvr device, even
414                  * if a PID is in multiple filters (e.g. video + PCR) */
415                 if ((DVR_FEED(feed)) && (dvr_done++))
416                         continue;
417
418                 if (feed->pid == pid) {
419                         dvb_dmx_swfilter_packet_type (feed, buf);
420                         if (DVR_FEED(feed))
421                                 continue;
422                 }
423
424                 if (feed->pid == 0x2000)
425                         feed->cb.ts(buf, 188, 0, 0, &feed->feed.ts, DMX_OK);
426         }
427 }
428
429
430 void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, size_t count)
431 {
432         spin_lock(&demux->lock);
433
434         while (count--) {
435                 if(buf[0] == 0x47) {
436                 dvb_dmx_swfilter_packet(demux, buf);
437                 }
438                 buf += 188;
439         }
440
441         spin_unlock(&demux->lock);
442 }
443
444
445 void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
446 {
447         int p = 0,i, j;
448         
449         spin_lock(&demux->lock);
450
451         if ((i = demux->tsbufp)) {
452                 if (count < (j=188-i)) {
453                         memcpy(&demux->tsbuf[i], buf, count);
454                         demux->tsbufp += count;
455                         goto bailout;
456                 }
457                 memcpy(&demux->tsbuf[i], buf, j);
458                 if (demux->tsbuf[0] == 0x47)
459                 dvb_dmx_swfilter_packet(demux, demux->tsbuf);
460                 demux->tsbufp = 0;
461                 p += j;
462         }
463
464         while (p < count) {
465                 if (buf[p] == 0x47) {
466                         if (count-p >= 188) {
467                                 dvb_dmx_swfilter_packet(demux, buf+p);
468                                 p += 188;
469                         } else {
470                                 i = count-p;
471                                 memcpy(demux->tsbuf, buf+p, i);
472                                 demux->tsbufp=i;
473                                 goto bailout;
474                         }
475                 } else 
476                         p++;
477         }
478
479 bailout:
480         spin_unlock(&demux->lock);
481 }
482
483 void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
484 {
485         int p = 0,i, j;
486         u8 tmppack[188];
487         spin_lock(&demux->lock);
488
489         if ((i = demux->tsbufp)) {
490                 if (count < (j=204-i)) {
491                         memcpy(&demux->tsbuf[i], buf, count);
492                         demux->tsbufp += count;
493                         goto bailout;
494                 }
495                 memcpy(&demux->tsbuf[i], buf, j);
496                 if ((demux->tsbuf[0] == 0x47)|(demux->tsbuf[0]==0xB8))  {
497                         memcpy(tmppack, demux->tsbuf, 188);
498                         if (tmppack[0] == 0xB8) tmppack[0] = 0x47;
499                         dvb_dmx_swfilter_packet(demux, tmppack);
500                 }
501                 demux->tsbufp = 0;
502                 p += j;
503         }
504
505         while (p < count) {
506                 if ((buf[p] == 0x47)|(buf[p] == 0xB8)) {
507                         if (count-p >= 204) {
508                                 memcpy(tmppack, buf+p, 188);
509                                 if (tmppack[0] == 0xB8) tmppack[0] = 0x47;
510                                 dvb_dmx_swfilter_packet(demux, tmppack);
511                                 p += 204;
512                         } else {
513                                 i = count-p;
514                                 memcpy(demux->tsbuf, buf+p, i);
515                                 demux->tsbufp=i;
516                                 goto bailout;
517                         }
518                 } else { 
519                         p++;
520                 }
521         }
522
523 bailout:
524         spin_unlock(&demux->lock);
525 }
526
527
528 static struct dvb_demux_filter * dvb_dmx_filter_alloc(struct dvb_demux *demux)
529 {
530         int i;
531
532         for (i=0; i<demux->filternum; i++)
533                 if (demux->filter[i].state == DMX_STATE_FREE)
534                         break;
535
536         if (i == demux->filternum)
537                 return NULL;
538
539         demux->filter[i].state = DMX_STATE_ALLOCATED;
540
541         return &demux->filter[i];
542 }
543
544 static struct dvb_demux_feed * dvb_dmx_feed_alloc(struct dvb_demux *demux)
545 {
546         int i;
547
548         for (i=0; i<demux->feednum; i++)
549                 if (demux->feed[i].state == DMX_STATE_FREE)
550                         break;
551
552         if (i == demux->feednum)
553                 return NULL;
554
555         demux->feed[i].state = DMX_STATE_ALLOCATED;
556
557         return &demux->feed[i];
558 }
559
560 static int dvb_demux_feed_find(struct dvb_demux_feed *feed)
561 {
562         struct dvb_demux_feed *entry;
563
564         list_for_each_entry(entry, &feed->demux->feed_list, list_head)
565                 if (entry == feed)
566                         return 1;
567
568                 return 0;
569                 }
570
571 static void dvb_demux_feed_add(struct dvb_demux_feed *feed)
572 {
573         if (dvb_demux_feed_find(feed)) {
574                 printk(KERN_ERR "%s: feed already in list (type=%x state=%x pid=%x)\n",
575                                 __FUNCTION__, feed->type, feed->state, feed->pid);
576                 return;
577         }
578
579         list_add(&feed->list_head, &feed->demux->feed_list);
580 }
581
582 static void dvb_demux_feed_del(struct dvb_demux_feed *feed)
583 {
584         if (!(dvb_demux_feed_find(feed))) {
585                 printk(KERN_ERR "%s: feed not in list (type=%x state=%x pid=%x)\n",
586                                 __FUNCTION__, feed->type, feed->state, feed->pid);
587                 return;
588 }
589
590         list_del(&feed->list_head);
591 }
592
593 static int dmx_ts_feed_set (struct dmx_ts_feed* ts_feed, u16 pid, int ts_type, 
594                      enum dmx_ts_pes pes_type, size_t callback_length, 
595                      size_t circular_buffer_size, int descramble, 
596                      struct timespec timeout)
597 {
598         struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed;
599         struct dvb_demux *demux = feed->demux;
600
601         if (pid > DMX_MAX_PID)
602                 return -EINVAL;
603         
604         if (down_interruptible (&demux->mutex))
605                 return -ERESTARTSYS;
606
607         if (ts_type & TS_DECODER) {
608                 if (pes_type >= DMX_TS_PES_OTHER) {
609                         up(&demux->mutex);
610                         return -EINVAL;
611                 }
612
613                 if (demux->pesfilter[pes_type] && 
614                     demux->pesfilter[pes_type] != feed) {
615                         up(&demux->mutex);
616                         return -EINVAL;
617                 }
618
619                 demux->pesfilter[pes_type] = feed;
620                 demux->pids[pes_type] = pid;
621         }
622
623         dvb_demux_feed_add(feed);
624
625         feed->pid = pid;
626         feed->buffer_size = circular_buffer_size;
627         feed->descramble = descramble;
628         feed->timeout = timeout;
629         feed->cb_length = callback_length;
630         feed->ts_type = ts_type;
631         feed->pes_type = pes_type;
632
633         if (feed->descramble) {
634                 up(&demux->mutex);
635                 return -ENOSYS;
636         }
637
638         if (feed->buffer_size) {
639 #ifdef NOBUFS
640                 feed->buffer=0;
641 #else
642                 feed->buffer = vmalloc(feed->buffer_size);
643                 if (!feed->buffer) {
644                         up(&demux->mutex);
645                         return -ENOMEM;
646                 }
647 #endif
648         }
649         
650         feed->state = DMX_STATE_READY;
651         up(&demux->mutex);
652
653         return 0;
654 }
655
656
657 static int dmx_ts_feed_start_filtering(struct dmx_ts_feed* ts_feed)
658 {
659         struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed;
660         struct dvb_demux *demux = feed->demux;
661         int ret;
662
663         if (down_interruptible (&demux->mutex))
664                 return -ERESTARTSYS;
665
666         if (feed->state != DMX_STATE_READY || feed->type != DMX_TYPE_TS) {
667                 up(&demux->mutex);
668                 return -EINVAL;
669         }
670
671         if (!demux->start_feed) {
672                 up(&demux->mutex);
673                 return -ENODEV;
674         }
675
676         if ((ret = demux->start_feed(feed)) < 0) {
677                 up(&demux->mutex);
678                 return ret;
679         }
680
681         spin_lock_irq(&demux->lock);
682         ts_feed->is_filtering = 1;
683         feed->state = DMX_STATE_GO;
684         spin_unlock_irq(&demux->lock);
685         up(&demux->mutex);
686
687         return 0;
688 }
689  
690 static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed* ts_feed)
691 {
692         struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed;
693         struct dvb_demux *demux = feed->demux;
694         int ret;
695
696         if (down_interruptible (&demux->mutex))
697                 return -ERESTARTSYS;
698
699         if (feed->state<DMX_STATE_GO) {
700                 up(&demux->mutex);
701                 return -EINVAL;
702         }
703
704         if (!demux->stop_feed) {
705                 up(&demux->mutex);
706                 return -ENODEV;
707         }
708
709         ret = demux->stop_feed(feed); 
710
711         spin_lock_irq(&demux->lock);
712         ts_feed->is_filtering = 0;
713         feed->state = DMX_STATE_ALLOCATED;
714         spin_unlock_irq(&demux->lock);
715         up(&demux->mutex);
716
717         return ret;
718 }
719
720 static int dvbdmx_allocate_ts_feed (struct dmx_demux *dmx, struct dmx_ts_feed **ts_feed, 
721                              dmx_ts_cb callback)
722 {
723         struct dvb_demux *demux = (struct dvb_demux *) dmx;
724         struct dvb_demux_feed *feed;
725
726         if (down_interruptible (&demux->mutex))
727                 return -ERESTARTSYS;
728
729         if (!(feed = dvb_dmx_feed_alloc(demux))) {
730                 up(&demux->mutex);
731                 return -EBUSY;
732         }
733
734         feed->type = DMX_TYPE_TS;
735         feed->cb.ts = callback;
736         feed->demux = demux;
737         feed->pid = 0xffff;
738         feed->peslen = 0xfffa;
739         feed->buffer = 0;
740
741         (*ts_feed) = &feed->feed.ts;
742         (*ts_feed)->parent = dmx;
743         (*ts_feed)->priv = 0;
744         (*ts_feed)->is_filtering = 0;
745         (*ts_feed)->start_filtering = dmx_ts_feed_start_filtering;
746         (*ts_feed)->stop_filtering = dmx_ts_feed_stop_filtering;
747         (*ts_feed)->set = dmx_ts_feed_set;
748
749
750         if (!(feed->filter = dvb_dmx_filter_alloc(demux))) {
751                 feed->state = DMX_STATE_FREE;
752                 up(&demux->mutex);
753                 return -EBUSY;
754         }
755
756         feed->filter->type = DMX_TYPE_TS;
757         feed->filter->feed = feed;
758         feed->filter->state = DMX_STATE_READY;
759         
760         up(&demux->mutex);
761
762         return 0;
763 }
764
765 static int dvbdmx_release_ts_feed(struct dmx_demux *dmx, struct dmx_ts_feed *ts_feed)
766 {
767         struct dvb_demux *demux = (struct dvb_demux *) dmx;
768         struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed;
769
770         if (down_interruptible (&demux->mutex))
771                 return -ERESTARTSYS;
772
773         if (feed->state == DMX_STATE_FREE) {
774                 up(&demux->mutex);
775                 return -EINVAL;
776         }
777
778 #ifndef NOBUFS
779         if (feed->buffer) { 
780                 vfree(feed->buffer);
781                 feed->buffer=0;
782         }
783 #endif
784
785         feed->state = DMX_STATE_FREE;
786         feed->filter->state = DMX_STATE_FREE;
787
788         dvb_demux_feed_del(feed);
789
790                 feed->pid = 0xffff;
791         
792         if (feed->ts_type & TS_DECODER)
793                 demux->pesfilter[feed->pes_type] = NULL;
794
795         up(&demux->mutex);
796         return 0;
797 }
798
799
800 /******************************************************************************
801  * dmx_section_feed API calls
802  ******************************************************************************/
803
804 static int dmx_section_feed_allocate_filter(struct dmx_section_feed* feed, 
805                                      struct dmx_section_filter** filter) 
806 {
807         struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed;
808         struct dvb_demux *dvbdemux=dvbdmxfeed->demux;
809         struct dvb_demux_filter *dvbdmxfilter;
810
811         if (down_interruptible (&dvbdemux->mutex))
812                 return -ERESTARTSYS;
813
814         dvbdmxfilter=dvb_dmx_filter_alloc(dvbdemux);
815         if (!dvbdmxfilter) {
816                 up(&dvbdemux->mutex);
817                 return -EBUSY;
818         }
819
820         spin_lock_irq(&dvbdemux->lock);
821         *filter=&dvbdmxfilter->filter;
822         (*filter)->parent=feed;
823         (*filter)->priv=0;
824         dvbdmxfilter->feed=dvbdmxfeed;
825         dvbdmxfilter->type=DMX_TYPE_SEC;
826         dvbdmxfilter->state=DMX_STATE_READY;
827
828         dvbdmxfilter->next=dvbdmxfeed->filter;
829         dvbdmxfeed->filter=dvbdmxfilter;
830         spin_unlock_irq(&dvbdemux->lock);
831         up(&dvbdemux->mutex);
832         return 0;
833 }
834
835
836 static int dmx_section_feed_set(struct dmx_section_feed* feed, 
837                      u16 pid, size_t circular_buffer_size, 
838                      int descramble, int check_crc) 
839 {
840         struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed;
841         struct dvb_demux *dvbdmx=dvbdmxfeed->demux;
842
843         if (pid>0x1fff)
844                 return -EINVAL;
845
846         if (down_interruptible (&dvbdmx->mutex))
847                 return -ERESTARTSYS;
848         
849         dvb_demux_feed_add(dvbdmxfeed);
850
851         dvbdmxfeed->pid = pid;
852         dvbdmxfeed->buffer_size=circular_buffer_size;
853         dvbdmxfeed->descramble=descramble;
854         if (dvbdmxfeed->descramble) {
855                 up(&dvbdmx->mutex);
856                 return -ENOSYS;
857         }
858
859         dvbdmxfeed->feed.sec.check_crc=check_crc;
860 #ifdef NOBUFS
861         dvbdmxfeed->buffer=0;
862 #else
863         dvbdmxfeed->buffer=vmalloc(dvbdmxfeed->buffer_size);
864         if (!dvbdmxfeed->buffer) {
865                 up(&dvbdmx->mutex);
866                 return -ENOMEM;
867         }
868 #endif
869         dvbdmxfeed->state=DMX_STATE_READY;
870         up(&dvbdmx->mutex);
871         return 0;
872 }
873
874 static void prepare_secfilters(struct dvb_demux_feed *dvbdmxfeed)
875 {
876         int i;
877         struct dvb_demux_filter *f;
878         struct dmx_section_filter *sf;
879         u8 mask, mode, doneq;
880                 
881         if (!(f=dvbdmxfeed->filter))
882                 return;
883         do {
884                 sf=&f->filter;
885                 doneq=0;
886                 for (i=0; i<DVB_DEMUX_MASK_MAX; i++) {
887                         mode=sf->filter_mode[i];
888                         mask=sf->filter_mask[i];
889                         f->maskandmode[i]=mask&mode;
890                         doneq|=f->maskandnotmode[i]=mask&~mode;
891                 }
892                 f->doneq=doneq ? 1 : 0;
893         } while ((f=f->next));
894 }
895
896
897 static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed)
898 {
899         struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed;
900         struct dvb_demux *dvbdmx=dvbdmxfeed->demux;
901         int ret;
902
903         if (down_interruptible (&dvbdmx->mutex))
904                 return -ERESTARTSYS;
905         
906         if (feed->is_filtering) {
907                 up(&dvbdmx->mutex);
908                 return -EBUSY;
909         }
910         if (!dvbdmxfeed->filter) {
911                 up(&dvbdmx->mutex);
912                 return -EINVAL;
913         }
914
915         dvbdmxfeed->feed.sec.tsfeedp = 0;
916         dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base;
917         dvbdmxfeed->feed.sec.secbufp=0;
918         dvbdmxfeed->feed.sec.seclen=0;
919         
920         if (!dvbdmx->start_feed) {
921                 up(&dvbdmx->mutex);
922                 return -ENODEV;
923         }
924
925         prepare_secfilters(dvbdmxfeed);
926
927         if ((ret = dvbdmx->start_feed(dvbdmxfeed)) < 0) {
928                 up(&dvbdmx->mutex);
929                 return ret;
930         }
931
932         spin_lock_irq(&dvbdmx->lock);
933         feed->is_filtering=1;
934         dvbdmxfeed->state=DMX_STATE_GO;
935         spin_unlock_irq(&dvbdmx->lock);
936         up(&dvbdmx->mutex);
937         return 0;
938 }
939
940
941 static int dmx_section_feed_stop_filtering(struct dmx_section_feed* feed)
942 {
943         struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed;
944         struct dvb_demux *dvbdmx=dvbdmxfeed->demux;
945         int ret;
946
947         if (down_interruptible (&dvbdmx->mutex))
948                 return -ERESTARTSYS;
949
950         if (!dvbdmx->stop_feed) {
951                 up(&dvbdmx->mutex);
952                 return -ENODEV;
953         }
954         ret=dvbdmx->stop_feed(dvbdmxfeed); 
955         spin_lock_irq(&dvbdmx->lock);
956         dvbdmxfeed->state=DMX_STATE_READY;
957         feed->is_filtering=0;
958         spin_unlock_irq(&dvbdmx->lock);
959         up(&dvbdmx->mutex);
960         return ret;
961 }
962
963
964 static int dmx_section_feed_release_filter(struct dmx_section_feed *feed, 
965                                 struct dmx_section_filter* filter)
966 {
967         struct dvb_demux_filter *dvbdmxfilter=(struct dvb_demux_filter *) filter, *f;
968         struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed;
969         struct dvb_demux *dvbdmx=dvbdmxfeed->demux;
970
971         if (down_interruptible (&dvbdmx->mutex))
972                 return -ERESTARTSYS;
973
974         if (dvbdmxfilter->feed!=dvbdmxfeed) {
975                 up(&dvbdmx->mutex);
976                 return -EINVAL;
977         }
978         if (feed->is_filtering) 
979                 feed->stop_filtering(feed);
980         
981         spin_lock_irq(&dvbdmx->lock);
982         f=dvbdmxfeed->filter;
983
984         if (f == dvbdmxfilter) {
985                 dvbdmxfeed->filter=dvbdmxfilter->next;
986         } else {
987                 while(f->next!=dvbdmxfilter)
988                         f=f->next;
989                 f->next=f->next->next;
990         }
991         dvbdmxfilter->state=DMX_STATE_FREE;
992         spin_unlock_irq(&dvbdmx->lock);
993         up(&dvbdmx->mutex);
994         return 0;
995 }
996
997 static int dvbdmx_allocate_section_feed(struct dmx_demux *demux, 
998                                         struct dmx_section_feed **feed,
999                                         dmx_section_cb callback)
1000 {
1001         struct dvb_demux *dvbdmx=(struct dvb_demux *) demux;
1002         struct dvb_demux_feed *dvbdmxfeed;
1003
1004         if (down_interruptible (&dvbdmx->mutex))
1005                 return -ERESTARTSYS;
1006
1007         if (!(dvbdmxfeed=dvb_dmx_feed_alloc(dvbdmx))) {
1008                 up(&dvbdmx->mutex);
1009                 return -EBUSY;
1010         }
1011         dvbdmxfeed->type=DMX_TYPE_SEC;
1012         dvbdmxfeed->cb.sec=callback;
1013         dvbdmxfeed->demux=dvbdmx;
1014         dvbdmxfeed->pid=0xffff;
1015         dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base;
1016         dvbdmxfeed->feed.sec.secbufp = dvbdmxfeed->feed.sec.seclen = 0;
1017         dvbdmxfeed->feed.sec.tsfeedp = 0;
1018         dvbdmxfeed->filter=0;
1019         dvbdmxfeed->buffer=0;
1020
1021         (*feed)=&dvbdmxfeed->feed.sec;
1022         (*feed)->is_filtering=0;
1023         (*feed)->parent=demux;
1024         (*feed)->priv=0;
1025
1026         (*feed)->set=dmx_section_feed_set;
1027         (*feed)->allocate_filter=dmx_section_feed_allocate_filter;
1028         (*feed)->start_filtering=dmx_section_feed_start_filtering;
1029         (*feed)->stop_filtering=dmx_section_feed_stop_filtering;
1030         (*feed)->release_filter = dmx_section_feed_release_filter;
1031
1032         up(&dvbdmx->mutex);
1033         return 0;
1034 }
1035
1036 static int dvbdmx_release_section_feed(struct dmx_demux *demux, 
1037                                        struct dmx_section_feed *feed)
1038 {
1039         struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed;
1040         struct dvb_demux *dvbdmx=(struct dvb_demux *) demux;
1041
1042         if (down_interruptible (&dvbdmx->mutex))
1043                 return -ERESTARTSYS;
1044
1045         if (dvbdmxfeed->state==DMX_STATE_FREE) {
1046                 up(&dvbdmx->mutex);
1047                 return -EINVAL;
1048         }
1049 #ifndef NOBUFS
1050         if (dvbdmxfeed->buffer) {
1051                 vfree(dvbdmxfeed->buffer);
1052                 dvbdmxfeed->buffer=0;
1053         }
1054 #endif
1055         dvbdmxfeed->state=DMX_STATE_FREE;
1056
1057         dvb_demux_feed_del(dvbdmxfeed);
1058
1059                 dvbdmxfeed->pid = 0xffff;
1060
1061         up(&dvbdmx->mutex);
1062         return 0;
1063 }
1064
1065
1066 /******************************************************************************
1067  * dvb_demux kernel data API calls
1068  ******************************************************************************/
1069
1070 static int dvbdmx_open(struct dmx_demux *demux)
1071 {
1072         struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;
1073
1074         if (dvbdemux->users>=MAX_DVB_DEMUX_USERS)
1075                 return -EUSERS;
1076         dvbdemux->users++;
1077         return 0;
1078 }
1079
1080
1081 static int dvbdmx_close(struct dmx_demux *demux)
1082 {
1083         struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;
1084
1085         if (dvbdemux->users==0)
1086                 return -ENODEV;
1087         dvbdemux->users--;
1088         //FIXME: release any unneeded resources if users==0
1089         return 0;
1090 }
1091
1092
1093 static int dvbdmx_write(struct dmx_demux *demux, const char *buf, size_t count)
1094 {
1095         struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;
1096
1097         if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE))
1098                 return -EINVAL;
1099
1100         if (down_interruptible (&dvbdemux->mutex))
1101                 return -ERESTARTSYS;
1102         dvb_dmx_swfilter(dvbdemux, buf, count);
1103         up(&dvbdemux->mutex);
1104
1105         if (signal_pending(current))
1106                 return -EINTR;
1107         return count;
1108 }
1109
1110
1111 static int dvbdmx_add_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend)
1112 {
1113         struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;
1114         struct list_head *head = &dvbdemux->frontend_list;
1115
1116         list_add(&(frontend->connectivity_list), head);
1117
1118         return 0;
1119 }
1120
1121
1122 static int dvbdmx_remove_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend)
1123 {
1124         struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;
1125         struct list_head *pos, *n, *head=&dvbdemux->frontend_list;
1126
1127         list_for_each_safe (pos, n, head) {
1128                 if (DMX_FE_ENTRY(pos) == frontend) {
1129                         list_del(pos);
1130                         return 0;
1131                 }
1132         }
1133         return -ENODEV;
1134 }
1135
1136
1137 static struct list_head * dvbdmx_get_frontends(struct dmx_demux *demux)
1138 {
1139         struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;
1140
1141         if (list_empty(&dvbdemux->frontend_list))
1142                 return NULL;
1143         return &dvbdemux->frontend_list;
1144 }
1145
1146
1147 int dvbdmx_connect_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend)
1148 {
1149         struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;
1150
1151         if (demux->frontend)
1152                 return -EINVAL;
1153         
1154         if (down_interruptible (&dvbdemux->mutex))
1155                 return -ERESTARTSYS;
1156
1157         demux->frontend=frontend;
1158         up(&dvbdemux->mutex);
1159         return 0;
1160 }
1161
1162
1163 int dvbdmx_disconnect_frontend(struct dmx_demux *demux)
1164 {
1165         struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;
1166
1167         if (down_interruptible (&dvbdemux->mutex))
1168                 return -ERESTARTSYS;
1169
1170         demux->frontend=NULL;
1171         up(&dvbdemux->mutex);
1172         return 0;
1173 }
1174
1175
1176 static int dvbdmx_get_pes_pids(struct dmx_demux *demux, u16 *pids)
1177 {
1178         struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;
1179
1180         memcpy(pids, dvbdemux->pids, 5*sizeof(u16));
1181         return 0;
1182 }
1183
1184
1185 int dvb_dmx_init(struct dvb_demux *dvbdemux)
1186 {
1187         int i, err;
1188         struct dmx_demux *dmx = &dvbdemux->dmx;
1189
1190         dvbdemux->users=0;
1191         dvbdemux->filter=vmalloc(dvbdemux->filternum*sizeof(struct dvb_demux_filter));
1192         if (!dvbdemux->filter)
1193                 return -ENOMEM;
1194
1195         dvbdemux->feed=vmalloc(dvbdemux->feednum*sizeof(struct dvb_demux_feed));
1196         if (!dvbdemux->feed) {
1197                 vfree(dvbdemux->filter);
1198                 return -ENOMEM;
1199         }
1200         for (i=0; i<dvbdemux->filternum; i++) {
1201                 dvbdemux->filter[i].state=DMX_STATE_FREE;
1202                 dvbdemux->filter[i].index=i;
1203         }
1204         for (i=0; i<dvbdemux->feednum; i++)
1205                 dvbdemux->feed[i].state=DMX_STATE_FREE;
1206         dvbdemux->frontend_list.next=
1207           dvbdemux->frontend_list.prev=
1208             &dvbdemux->frontend_list;
1209         for (i=0; i<DMX_TS_PES_OTHER; i++) {
1210                 dvbdemux->pesfilter[i]=NULL;
1211                 dvbdemux->pids[i]=0xffff;
1212         }
1213
1214         INIT_LIST_HEAD(&dvbdemux->feed_list);
1215
1216         dvbdemux->playing = 0;
1217         dvbdemux->recording = 0;
1218         dvbdemux->tsbufp=0;
1219
1220         if (!dvbdemux->check_crc32)
1221                 dvbdemux->check_crc32 = dvb_dmx_crc32;
1222
1223          if (!dvbdemux->memcopy)
1224                  dvbdemux->memcopy = dvb_dmx_memcopy;
1225
1226         dmx->frontend=0;
1227         dmx->reg_list.prev = dmx->reg_list.next = &dmx->reg_list;
1228         dmx->priv=(void *) dvbdemux;
1229         dmx->open=dvbdmx_open;
1230         dmx->close=dvbdmx_close;
1231         dmx->write=dvbdmx_write;
1232         dmx->allocate_ts_feed=dvbdmx_allocate_ts_feed;
1233         dmx->release_ts_feed=dvbdmx_release_ts_feed;
1234         dmx->allocate_section_feed=dvbdmx_allocate_section_feed;
1235         dmx->release_section_feed=dvbdmx_release_section_feed;
1236
1237         dmx->descramble_mac_address=NULL;
1238         dmx->descramble_section_payload=NULL;
1239         
1240         dmx->add_frontend=dvbdmx_add_frontend;
1241         dmx->remove_frontend=dvbdmx_remove_frontend;
1242         dmx->get_frontends=dvbdmx_get_frontends;
1243         dmx->connect_frontend=dvbdmx_connect_frontend;
1244         dmx->disconnect_frontend=dvbdmx_disconnect_frontend;
1245         dmx->get_pes_pids=dvbdmx_get_pes_pids;
1246         sema_init(&dvbdemux->mutex, 1);
1247         spin_lock_init(&dvbdemux->lock);
1248
1249         if ((err = dmx_register_demux(dmx)) < 0) 
1250                 return err;
1251
1252         return 0;
1253 }
1254
1255
1256 int dvb_dmx_release(struct dvb_demux *dvbdemux)
1257 {
1258         struct dmx_demux *dmx = &dvbdemux->dmx;
1259
1260         dmx_unregister_demux(dmx);
1261         if (dvbdemux->filter)
1262                 vfree(dvbdemux->filter);
1263         if (dvbdemux->feed)
1264                 vfree(dvbdemux->feed);
1265         return 0;
1266 }