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