linux/drivers/media/dvb-core/dmxdev.c
<<
>>
Prefs
   1/*
   2 * dmxdev.c - DVB demultiplexer device
   3 *
   4 * Copyright (C) 2000 Ralph Metzler & Marcus Metzler
   5 *                    for convergence integrated media GmbH
   6 *
   7 * This program is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU Lesser General Public License
   9 * as published by the Free Software Foundation; either version 2.1
  10 * of the License, or (at your option) any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU Lesser General Public License
  18 * along with this program; if not, write to the Free Software
  19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20 *
  21 */
  22
  23#include <linux/sched.h>
  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/ioctl.h>
  30#include <linux/wait.h>
  31#include <asm/uaccess.h>
  32#include "dmxdev.h"
  33
  34static int debug;
  35
  36module_param(debug, int, 0644);
  37MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
  38
  39#define dprintk if (debug) printk
  40
  41static int dvb_dmxdev_buffer_write(struct dvb_ringbuffer *buf,
  42                                   const u8 *src, size_t len)
  43{
  44        ssize_t free;
  45
  46        if (!len)
  47                return 0;
  48        if (!buf->data)
  49                return 0;
  50
  51        free = dvb_ringbuffer_free(buf);
  52        if (len > free) {
  53                dprintk("dmxdev: buffer overflow\n");
  54                return -EOVERFLOW;
  55        }
  56
  57        return dvb_ringbuffer_write(buf, src, len);
  58}
  59
  60static ssize_t dvb_dmxdev_buffer_read(struct dvb_ringbuffer *src,
  61                                      int non_blocking, char __user *buf,
  62                                      size_t count, loff_t *ppos)
  63{
  64        size_t todo;
  65        ssize_t avail;
  66        ssize_t ret = 0;
  67
  68        if (!src->data)
  69                return 0;
  70
  71        if (src->error) {
  72                ret = src->error;
  73                dvb_ringbuffer_flush(src);
  74                return ret;
  75        }
  76
  77        for (todo = count; todo > 0; todo -= ret) {
  78                if (non_blocking && dvb_ringbuffer_empty(src)) {
  79                        ret = -EWOULDBLOCK;
  80                        break;
  81                }
  82
  83                ret = wait_event_interruptible(src->queue,
  84                                               !dvb_ringbuffer_empty(src) ||
  85                                               (src->error != 0));
  86                if (ret < 0)
  87                        break;
  88
  89                if (src->error) {
  90                        ret = src->error;
  91                        dvb_ringbuffer_flush(src);
  92                        break;
  93                }
  94
  95                avail = dvb_ringbuffer_avail(src);
  96                if (avail > todo)
  97                        avail = todo;
  98
  99                ret = dvb_ringbuffer_read_user(src, buf, avail);
 100                if (ret < 0)
 101                        break;
 102
 103                buf += ret;
 104        }
 105
 106        return (count - todo) ? (count - todo) : ret;
 107}
 108
 109static struct dmx_frontend *get_fe(struct dmx_demux *demux, int type)
 110{
 111        struct list_head *head, *pos;
 112
 113        head = demux->get_frontends(demux);
 114        if (!head)
 115                return NULL;
 116        list_for_each(pos, head)
 117                if (DMX_FE_ENTRY(pos)->source == type)
 118                        return DMX_FE_ENTRY(pos);
 119
 120        return NULL;
 121}
 122
 123static int dvb_dvr_open(struct inode *inode, struct file *file)
 124{
 125        struct dvb_device *dvbdev = file->private_data;
 126        struct dmxdev *dmxdev = dvbdev->priv;
 127        struct dmx_frontend *front;
 128
 129        dprintk("function : %s\n", __func__);
 130
 131        if (mutex_lock_interruptible(&dmxdev->mutex))
 132                return -ERESTARTSYS;
 133
 134        if (dmxdev->exit) {
 135                mutex_unlock(&dmxdev->mutex);
 136                return -ENODEV;
 137        }
 138
 139        if ((file->f_flags & O_ACCMODE) == O_RDWR) {
 140                if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) {
 141                        mutex_unlock(&dmxdev->mutex);
 142                        return -EOPNOTSUPP;
 143                }
 144        }
 145
 146        if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
 147                void *mem;
 148                if (!dvbdev->readers) {
 149                        mutex_unlock(&dmxdev->mutex);
 150                        return -EBUSY;
 151                }
 152                mem = vmalloc(DVR_BUFFER_SIZE);
 153                if (!mem) {
 154                        mutex_unlock(&dmxdev->mutex);
 155                        return -ENOMEM;
 156                }
 157                dvb_ringbuffer_init(&dmxdev->dvr_buffer, mem, DVR_BUFFER_SIZE);
 158                dvbdev->readers--;
 159        }
 160
 161        if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
 162                dmxdev->dvr_orig_fe = dmxdev->demux->frontend;
 163
 164                if (!dmxdev->demux->write) {
 165                        mutex_unlock(&dmxdev->mutex);
 166                        return -EOPNOTSUPP;
 167                }
 168
 169                front = get_fe(dmxdev->demux, DMX_MEMORY_FE);
 170
 171                if (!front) {
 172                        mutex_unlock(&dmxdev->mutex);
 173                        return -EINVAL;
 174                }
 175                dmxdev->demux->disconnect_frontend(dmxdev->demux);
 176                dmxdev->demux->connect_frontend(dmxdev->demux, front);
 177        }
 178        dvbdev->users++;
 179        mutex_unlock(&dmxdev->mutex);
 180        return 0;
 181}
 182
 183static int dvb_dvr_release(struct inode *inode, struct file *file)
 184{
 185        struct dvb_device *dvbdev = file->private_data;
 186        struct dmxdev *dmxdev = dvbdev->priv;
 187
 188        mutex_lock(&dmxdev->mutex);
 189
 190        if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
 191                dmxdev->demux->disconnect_frontend(dmxdev->demux);
 192                dmxdev->demux->connect_frontend(dmxdev->demux,
 193                                                dmxdev->dvr_orig_fe);
 194        }
 195        if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
 196                dvbdev->readers++;
 197                if (dmxdev->dvr_buffer.data) {
 198                        void *mem = dmxdev->dvr_buffer.data;
 199                        mb();
 200                        spin_lock_irq(&dmxdev->lock);
 201                        dmxdev->dvr_buffer.data = NULL;
 202                        spin_unlock_irq(&dmxdev->lock);
 203                        vfree(mem);
 204                }
 205        }
 206        /* TODO */
 207        dvbdev->users--;
 208        if (dvbdev->users == 1 && dmxdev->exit == 1) {
 209                mutex_unlock(&dmxdev->mutex);
 210                wake_up(&dvbdev->wait_queue);
 211        } else
 212                mutex_unlock(&dmxdev->mutex);
 213
 214        return 0;
 215}
 216
 217static ssize_t dvb_dvr_write(struct file *file, const char __user *buf,
 218                             size_t count, loff_t *ppos)
 219{
 220        struct dvb_device *dvbdev = file->private_data;
 221        struct dmxdev *dmxdev = dvbdev->priv;
 222        int ret;
 223
 224        if (!dmxdev->demux->write)
 225                return -EOPNOTSUPP;
 226        if ((file->f_flags & O_ACCMODE) != O_WRONLY)
 227                return -EINVAL;
 228        if (mutex_lock_interruptible(&dmxdev->mutex))
 229                return -ERESTARTSYS;
 230
 231        if (dmxdev->exit) {
 232                mutex_unlock(&dmxdev->mutex);
 233                return -ENODEV;
 234        }
 235        ret = dmxdev->demux->write(dmxdev->demux, buf, count);
 236        mutex_unlock(&dmxdev->mutex);
 237        return ret;
 238}
 239
 240static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count,
 241                            loff_t *ppos)
 242{
 243        struct dvb_device *dvbdev = file->private_data;
 244        struct dmxdev *dmxdev = dvbdev->priv;
 245
 246        if (dmxdev->exit)
 247                return -ENODEV;
 248
 249        return dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer,
 250                                      file->f_flags & O_NONBLOCK,
 251                                      buf, count, ppos);
 252}
 253
 254static int dvb_dvr_set_buffer_size(struct dmxdev *dmxdev,
 255                                      unsigned long size)
 256{
 257        struct dvb_ringbuffer *buf = &dmxdev->dvr_buffer;
 258        void *newmem;
 259        void *oldmem;
 260
 261        dprintk("function : %s\n", __func__);
 262
 263        if (buf->size == size)
 264                return 0;
 265        if (!size)
 266                return -EINVAL;
 267
 268        newmem = vmalloc(size);
 269        if (!newmem)
 270                return -ENOMEM;
 271
 272        oldmem = buf->data;
 273
 274        spin_lock_irq(&dmxdev->lock);
 275        buf->data = newmem;
 276        buf->size = size;
 277
 278        /* reset and not flush in case the buffer shrinks */
 279        dvb_ringbuffer_reset(buf);
 280        spin_unlock_irq(&dmxdev->lock);
 281
 282        vfree(oldmem);
 283
 284        return 0;
 285}
 286
 287static inline void dvb_dmxdev_filter_state_set(struct dmxdev_filter
 288                                               *dmxdevfilter, int state)
 289{
 290        spin_lock_irq(&dmxdevfilter->dev->lock);
 291        dmxdevfilter->state = state;
 292        spin_unlock_irq(&dmxdevfilter->dev->lock);
 293}
 294
 295static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter,
 296                                      unsigned long size)
 297{
 298        struct dvb_ringbuffer *buf = &dmxdevfilter->buffer;
 299        void *newmem;
 300        void *oldmem;
 301
 302        if (buf->size == size)
 303                return 0;
 304        if (!size)
 305                return -EINVAL;
 306        if (dmxdevfilter->state >= DMXDEV_STATE_GO)
 307                return -EBUSY;
 308
 309        newmem = vmalloc(size);
 310        if (!newmem)
 311                return -ENOMEM;
 312
 313        oldmem = buf->data;
 314
 315        spin_lock_irq(&dmxdevfilter->dev->lock);
 316        buf->data = newmem;
 317        buf->size = size;
 318
 319        /* reset and not flush in case the buffer shrinks */
 320        dvb_ringbuffer_reset(buf);
 321        spin_unlock_irq(&dmxdevfilter->dev->lock);
 322
 323        vfree(oldmem);
 324
 325        return 0;
 326}
 327
 328static void dvb_dmxdev_filter_timeout(unsigned long data)
 329{
 330        struct dmxdev_filter *dmxdevfilter = (struct dmxdev_filter *)data;
 331
 332        dmxdevfilter->buffer.error = -ETIMEDOUT;
 333        spin_lock_irq(&dmxdevfilter->dev->lock);
 334        dmxdevfilter->state = DMXDEV_STATE_TIMEDOUT;
 335        spin_unlock_irq(&dmxdevfilter->dev->lock);
 336        wake_up(&dmxdevfilter->buffer.queue);
 337}
 338
 339static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter)
 340{
 341        struct dmx_sct_filter_params *para = &dmxdevfilter->params.sec;
 342
 343        del_timer(&dmxdevfilter->timer);
 344        if (para->timeout) {
 345                dmxdevfilter->timer.function = dvb_dmxdev_filter_timeout;
 346                dmxdevfilter->timer.data = (unsigned long)dmxdevfilter;
 347                dmxdevfilter->timer.expires =
 348                    jiffies + 1 + (HZ / 2 + HZ * para->timeout) / 1000;
 349                add_timer(&dmxdevfilter->timer);
 350        }
 351}
 352
 353static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
 354                                       const u8 *buffer2, size_t buffer2_len,
 355                                       struct dmx_section_filter *filter)
 356{
 357        struct dmxdev_filter *dmxdevfilter = filter->priv;
 358        int ret;
 359
 360        if (dmxdevfilter->buffer.error) {
 361                wake_up(&dmxdevfilter->buffer.queue);
 362                return 0;
 363        }
 364        spin_lock(&dmxdevfilter->dev->lock);
 365        if (dmxdevfilter->state != DMXDEV_STATE_GO) {
 366                spin_unlock(&dmxdevfilter->dev->lock);
 367                return 0;
 368        }
 369        del_timer(&dmxdevfilter->timer);
 370        dprintk("dmxdev: section callback %*ph\n", 6, buffer1);
 371        ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer1,
 372                                      buffer1_len);
 373        if (ret == buffer1_len) {
 374                ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer2,
 375                                              buffer2_len);
 376        }
 377        if (ret < 0)
 378                dmxdevfilter->buffer.error = ret;
 379        if (dmxdevfilter->params.sec.flags & DMX_ONESHOT)
 380                dmxdevfilter->state = DMXDEV_STATE_DONE;
 381        spin_unlock(&dmxdevfilter->dev->lock);
 382        wake_up(&dmxdevfilter->buffer.queue);
 383        return 0;
 384}
 385
 386static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
 387                                  const u8 *buffer2, size_t buffer2_len,
 388                                  struct dmx_ts_feed *feed)
 389{
 390        struct dmxdev_filter *dmxdevfilter = feed->priv;
 391        struct dvb_ringbuffer *buffer;
 392        int ret;
 393
 394        spin_lock(&dmxdevfilter->dev->lock);
 395        if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) {
 396                spin_unlock(&dmxdevfilter->dev->lock);
 397                return 0;
 398        }
 399
 400        if (dmxdevfilter->params.pes.output == DMX_OUT_TAP
 401            || dmxdevfilter->params.pes.output == DMX_OUT_TSDEMUX_TAP)
 402                buffer = &dmxdevfilter->buffer;
 403        else
 404                buffer = &dmxdevfilter->dev->dvr_buffer;
 405        if (buffer->error) {
 406                spin_unlock(&dmxdevfilter->dev->lock);
 407                wake_up(&buffer->queue);
 408                return 0;
 409        }
 410        ret = dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len);
 411        if (ret == buffer1_len)
 412                ret = dvb_dmxdev_buffer_write(buffer, buffer2, buffer2_len);
 413        if (ret < 0)
 414                buffer->error = ret;
 415        spin_unlock(&dmxdevfilter->dev->lock);
 416        wake_up(&buffer->queue);
 417        return 0;
 418}
 419
 420/* stop feed but only mark the specified filter as stopped (state set) */
 421static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter)
 422{
 423        struct dmxdev_feed *feed;
 424
 425        dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
 426
 427        switch (dmxdevfilter->type) {
 428        case DMXDEV_TYPE_SEC:
 429                del_timer(&dmxdevfilter->timer);
 430                dmxdevfilter->feed.sec->stop_filtering(dmxdevfilter->feed.sec);
 431                break;
 432        case DMXDEV_TYPE_PES:
 433                list_for_each_entry(feed, &dmxdevfilter->feed.ts, next)
 434                        feed->ts->stop_filtering(feed->ts);
 435                break;
 436        default:
 437                return -EINVAL;
 438        }
 439        return 0;
 440}
 441
 442/* start feed associated with the specified filter */
 443static int dvb_dmxdev_feed_start(struct dmxdev_filter *filter)
 444{
 445        struct dmxdev_feed *feed;
 446        int ret;
 447
 448        dvb_dmxdev_filter_state_set(filter, DMXDEV_STATE_GO);
 449
 450        switch (filter->type) {
 451        case DMXDEV_TYPE_SEC:
 452                return filter->feed.sec->start_filtering(filter->feed.sec);
 453        case DMXDEV_TYPE_PES:
 454                list_for_each_entry(feed, &filter->feed.ts, next) {
 455                        ret = feed->ts->start_filtering(feed->ts);
 456                        if (ret < 0) {
 457                                dvb_dmxdev_feed_stop(filter);
 458                                return ret;
 459                        }
 460                }
 461                break;
 462        default:
 463                return -EINVAL;
 464        }
 465
 466        return 0;
 467}
 468
 469/* restart section feed if it has filters left associated with it,
 470   otherwise release the feed */
 471static int dvb_dmxdev_feed_restart(struct dmxdev_filter *filter)
 472{
 473        int i;
 474        struct dmxdev *dmxdev = filter->dev;
 475        u16 pid = filter->params.sec.pid;
 476
 477        for (i = 0; i < dmxdev->filternum; i++)
 478                if (dmxdev->filter[i].state >= DMXDEV_STATE_GO &&
 479                    dmxdev->filter[i].type == DMXDEV_TYPE_SEC &&
 480                    dmxdev->filter[i].params.sec.pid == pid) {
 481                        dvb_dmxdev_feed_start(&dmxdev->filter[i]);
 482                        return 0;
 483                }
 484
 485        filter->dev->demux->release_section_feed(dmxdev->demux,
 486                                                 filter->feed.sec);
 487
 488        return 0;
 489}
 490
 491static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter)
 492{
 493        struct dmxdev_feed *feed;
 494        struct dmx_demux *demux;
 495
 496        if (dmxdevfilter->state < DMXDEV_STATE_GO)
 497                return 0;
 498
 499        switch (dmxdevfilter->type) {
 500        case DMXDEV_TYPE_SEC:
 501                if (!dmxdevfilter->feed.sec)
 502                        break;
 503                dvb_dmxdev_feed_stop(dmxdevfilter);
 504                if (dmxdevfilter->filter.sec)
 505                        dmxdevfilter->feed.sec->
 506                            release_filter(dmxdevfilter->feed.sec,
 507                                           dmxdevfilter->filter.sec);
 508                dvb_dmxdev_feed_restart(dmxdevfilter);
 509                dmxdevfilter->feed.sec = NULL;
 510                break;
 511        case DMXDEV_TYPE_PES:
 512                dvb_dmxdev_feed_stop(dmxdevfilter);
 513                demux = dmxdevfilter->dev->demux;
 514                list_for_each_entry(feed, &dmxdevfilter->feed.ts, next) {
 515                        demux->release_ts_feed(demux, feed->ts);
 516                        feed->ts = NULL;
 517                }
 518                break;
 519        default:
 520                if (dmxdevfilter->state == DMXDEV_STATE_ALLOCATED)
 521                        return 0;
 522                return -EINVAL;
 523        }
 524
 525        dvb_ringbuffer_flush(&dmxdevfilter->buffer);
 526        return 0;
 527}
 528
 529static void dvb_dmxdev_delete_pids(struct dmxdev_filter *dmxdevfilter)
 530{
 531        struct dmxdev_feed *feed, *tmp;
 532
 533        /* delete all PIDs */
 534        list_for_each_entry_safe(feed, tmp, &dmxdevfilter->feed.ts, next) {
 535                list_del(&feed->next);
 536                kfree(feed);
 537        }
 538
 539        BUG_ON(!list_empty(&dmxdevfilter->feed.ts));
 540}
 541
 542static inline int dvb_dmxdev_filter_reset(struct dmxdev_filter *dmxdevfilter)
 543{
 544        if (dmxdevfilter->state < DMXDEV_STATE_SET)
 545                return 0;
 546
 547        if (dmxdevfilter->type == DMXDEV_TYPE_PES)
 548                dvb_dmxdev_delete_pids(dmxdevfilter);
 549
 550        dmxdevfilter->type = DMXDEV_TYPE_NONE;
 551        dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
 552        return 0;
 553}
 554
 555static int dvb_dmxdev_start_feed(struct dmxdev *dmxdev,
 556                                 struct dmxdev_filter *filter,
 557                                 struct dmxdev_feed *feed)
 558{
 559        ktime_t timeout = ktime_set(0, 0);
 560        struct dmx_pes_filter_params *para = &filter->params.pes;
 561        dmx_output_t otype;
 562        int ret;
 563        int ts_type;
 564        enum dmx_ts_pes ts_pes;
 565        struct dmx_ts_feed *tsfeed;
 566
 567        feed->ts = NULL;
 568        otype = para->output;
 569
 570        ts_pes = para->pes_type;
 571
 572        if (ts_pes < DMX_PES_OTHER)
 573                ts_type = TS_DECODER;
 574        else
 575                ts_type = 0;
 576
 577        if (otype == DMX_OUT_TS_TAP)
 578                ts_type |= TS_PACKET;
 579        else if (otype == DMX_OUT_TSDEMUX_TAP)
 580                ts_type |= TS_PACKET | TS_DEMUX;
 581        else if (otype == DMX_OUT_TAP)
 582                ts_type |= TS_PACKET | TS_DEMUX | TS_PAYLOAD_ONLY;
 583
 584        ret = dmxdev->demux->allocate_ts_feed(dmxdev->demux, &feed->ts,
 585                                              dvb_dmxdev_ts_callback);
 586        if (ret < 0)
 587                return ret;
 588
 589        tsfeed = feed->ts;
 590        tsfeed->priv = filter;
 591
 592        ret = tsfeed->set(tsfeed, feed->pid, ts_type, ts_pes, 32768, timeout);
 593        if (ret < 0) {
 594                dmxdev->demux->release_ts_feed(dmxdev->demux, tsfeed);
 595                return ret;
 596        }
 597
 598        ret = tsfeed->start_filtering(tsfeed);
 599        if (ret < 0) {
 600                dmxdev->demux->release_ts_feed(dmxdev->demux, tsfeed);
 601                return ret;
 602        }
 603
 604        return 0;
 605}
 606
 607static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
 608{
 609        struct dmxdev *dmxdev = filter->dev;
 610        struct dmxdev_feed *feed;
 611        void *mem;
 612        int ret, i;
 613
 614        if (filter->state < DMXDEV_STATE_SET)
 615                return -EINVAL;
 616
 617        if (filter->state >= DMXDEV_STATE_GO)
 618                dvb_dmxdev_filter_stop(filter);
 619
 620        if (!filter->buffer.data) {
 621                mem = vmalloc(filter->buffer.size);
 622                if (!mem)
 623                        return -ENOMEM;
 624                spin_lock_irq(&filter->dev->lock);
 625                filter->buffer.data = mem;
 626                spin_unlock_irq(&filter->dev->lock);
 627        }
 628
 629        dvb_ringbuffer_flush(&filter->buffer);
 630
 631        switch (filter->type) {
 632        case DMXDEV_TYPE_SEC:
 633        {
 634                struct dmx_sct_filter_params *para = &filter->params.sec;
 635                struct dmx_section_filter **secfilter = &filter->filter.sec;
 636                struct dmx_section_feed **secfeed = &filter->feed.sec;
 637
 638                *secfilter = NULL;
 639                *secfeed = NULL;
 640
 641
 642                /* find active filter/feed with same PID */
 643                for (i = 0; i < dmxdev->filternum; i++) {
 644                        if (dmxdev->filter[i].state >= DMXDEV_STATE_GO &&
 645                            dmxdev->filter[i].type == DMXDEV_TYPE_SEC &&
 646                            dmxdev->filter[i].params.sec.pid == para->pid) {
 647                                *secfeed = dmxdev->filter[i].feed.sec;
 648                                break;
 649                        }
 650                }
 651
 652                /* if no feed found, try to allocate new one */
 653                if (!*secfeed) {
 654                        ret = dmxdev->demux->allocate_section_feed(dmxdev->demux,
 655                                                                   secfeed,
 656                                                                   dvb_dmxdev_section_callback);
 657                        if (ret < 0) {
 658                                printk("DVB (%s): could not alloc feed\n",
 659                                       __func__);
 660                                return ret;
 661                        }
 662
 663                        ret = (*secfeed)->set(*secfeed, para->pid, 32768,
 664                                              (para->flags & DMX_CHECK_CRC) ? 1 : 0);
 665                        if (ret < 0) {
 666                                printk("DVB (%s): could not set feed\n",
 667                                       __func__);
 668                                dvb_dmxdev_feed_restart(filter);
 669                                return ret;
 670                        }
 671                } else {
 672                        dvb_dmxdev_feed_stop(filter);
 673                }
 674
 675                ret = (*secfeed)->allocate_filter(*secfeed, secfilter);
 676                if (ret < 0) {
 677                        dvb_dmxdev_feed_restart(filter);
 678                        filter->feed.sec->start_filtering(*secfeed);
 679                        dprintk("could not get filter\n");
 680                        return ret;
 681                }
 682
 683                (*secfilter)->priv = filter;
 684
 685                memcpy(&((*secfilter)->filter_value[3]),
 686                       &(para->filter.filter[1]), DMX_FILTER_SIZE - 1);
 687                memcpy(&(*secfilter)->filter_mask[3],
 688                       &para->filter.mask[1], DMX_FILTER_SIZE - 1);
 689                memcpy(&(*secfilter)->filter_mode[3],
 690                       &para->filter.mode[1], DMX_FILTER_SIZE - 1);
 691
 692                (*secfilter)->filter_value[0] = para->filter.filter[0];
 693                (*secfilter)->filter_mask[0] = para->filter.mask[0];
 694                (*secfilter)->filter_mode[0] = para->filter.mode[0];
 695                (*secfilter)->filter_mask[1] = 0;
 696                (*secfilter)->filter_mask[2] = 0;
 697
 698                filter->todo = 0;
 699
 700                ret = filter->feed.sec->start_filtering(filter->feed.sec);
 701                if (ret < 0)
 702                        return ret;
 703
 704                dvb_dmxdev_filter_timer(filter);
 705                break;
 706        }
 707        case DMXDEV_TYPE_PES:
 708                list_for_each_entry(feed, &filter->feed.ts, next) {
 709                        ret = dvb_dmxdev_start_feed(dmxdev, filter, feed);
 710                        if (ret < 0) {
 711                                dvb_dmxdev_filter_stop(filter);
 712                                return ret;
 713                        }
 714                }
 715                break;
 716        default:
 717                return -EINVAL;
 718        }
 719
 720        dvb_dmxdev_filter_state_set(filter, DMXDEV_STATE_GO);
 721        return 0;
 722}
 723
 724static int dvb_demux_open(struct inode *inode, struct file *file)
 725{
 726        struct dvb_device *dvbdev = file->private_data;
 727        struct dmxdev *dmxdev = dvbdev->priv;
 728        int i;
 729        struct dmxdev_filter *dmxdevfilter;
 730
 731        if (!dmxdev->filter)
 732                return -EINVAL;
 733
 734        if (mutex_lock_interruptible(&dmxdev->mutex))
 735                return -ERESTARTSYS;
 736
 737        for (i = 0; i < dmxdev->filternum; i++)
 738                if (dmxdev->filter[i].state == DMXDEV_STATE_FREE)
 739                        break;
 740
 741        if (i == dmxdev->filternum) {
 742                mutex_unlock(&dmxdev->mutex);
 743                return -EMFILE;
 744        }
 745
 746        dmxdevfilter = &dmxdev->filter[i];
 747        mutex_init(&dmxdevfilter->mutex);
 748        file->private_data = dmxdevfilter;
 749
 750        dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192);
 751        dmxdevfilter->type = DMXDEV_TYPE_NONE;
 752        dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
 753        init_timer(&dmxdevfilter->timer);
 754
 755        dvbdev->users++;
 756
 757        mutex_unlock(&dmxdev->mutex);
 758        return 0;
 759}
 760
 761static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev,
 762                                  struct dmxdev_filter *dmxdevfilter)
 763{
 764        mutex_lock(&dmxdev->mutex);
 765        mutex_lock(&dmxdevfilter->mutex);
 766
 767        dvb_dmxdev_filter_stop(dmxdevfilter);
 768        dvb_dmxdev_filter_reset(dmxdevfilter);
 769
 770        if (dmxdevfilter->buffer.data) {
 771                void *mem = dmxdevfilter->buffer.data;
 772
 773                spin_lock_irq(&dmxdev->lock);
 774                dmxdevfilter->buffer.data = NULL;
 775                spin_unlock_irq(&dmxdev->lock);
 776                vfree(mem);
 777        }
 778
 779        dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_FREE);
 780        wake_up(&dmxdevfilter->buffer.queue);
 781        mutex_unlock(&dmxdevfilter->mutex);
 782        mutex_unlock(&dmxdev->mutex);
 783        return 0;
 784}
 785
 786static inline void invert_mode(dmx_filter_t *filter)
 787{
 788        int i;
 789
 790        for (i = 0; i < DMX_FILTER_SIZE; i++)
 791                filter->mode[i] ^= 0xff;
 792}
 793
 794static int dvb_dmxdev_add_pid(struct dmxdev *dmxdev,
 795                              struct dmxdev_filter *filter, u16 pid)
 796{
 797        struct dmxdev_feed *feed;
 798
 799        if ((filter->type != DMXDEV_TYPE_PES) ||
 800            (filter->state < DMXDEV_STATE_SET))
 801                return -EINVAL;
 802
 803        /* only TS packet filters may have multiple PIDs */
 804        if ((filter->params.pes.output != DMX_OUT_TSDEMUX_TAP) &&
 805            (!list_empty(&filter->feed.ts)))
 806                return -EINVAL;
 807
 808        feed = kzalloc(sizeof(struct dmxdev_feed), GFP_KERNEL);
 809        if (feed == NULL)
 810                return -ENOMEM;
 811
 812        feed->pid = pid;
 813        list_add(&feed->next, &filter->feed.ts);
 814
 815        if (filter->state >= DMXDEV_STATE_GO)
 816                return dvb_dmxdev_start_feed(dmxdev, filter, feed);
 817
 818        return 0;
 819}
 820
 821static int dvb_dmxdev_remove_pid(struct dmxdev *dmxdev,
 822                                  struct dmxdev_filter *filter, u16 pid)
 823{
 824        struct dmxdev_feed *feed, *tmp;
 825
 826        if ((filter->type != DMXDEV_TYPE_PES) ||
 827            (filter->state < DMXDEV_STATE_SET))
 828                return -EINVAL;
 829
 830        list_for_each_entry_safe(feed, tmp, &filter->feed.ts, next) {
 831                if ((feed->pid == pid) && (feed->ts != NULL)) {
 832                        feed->ts->stop_filtering(feed->ts);
 833                        filter->dev->demux->release_ts_feed(filter->dev->demux,
 834                                                            feed->ts);
 835                        list_del(&feed->next);
 836                        kfree(feed);
 837                }
 838        }
 839
 840        return 0;
 841}
 842
 843static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev,
 844                                 struct dmxdev_filter *dmxdevfilter,
 845                                 struct dmx_sct_filter_params *params)
 846{
 847        dprintk("function : %s, PID=0x%04x, flags=%02x, timeout=%d\n",
 848                __func__, params->pid, params->flags, params->timeout);
 849
 850        dvb_dmxdev_filter_stop(dmxdevfilter);
 851
 852        dmxdevfilter->type = DMXDEV_TYPE_SEC;
 853        memcpy(&dmxdevfilter->params.sec,
 854               params, sizeof(struct dmx_sct_filter_params));
 855        invert_mode(&dmxdevfilter->params.sec.filter);
 856        dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
 857
 858        if (params->flags & DMX_IMMEDIATE_START)
 859                return dvb_dmxdev_filter_start(dmxdevfilter);
 860
 861        return 0;
 862}
 863
 864static int dvb_dmxdev_pes_filter_set(struct dmxdev *dmxdev,
 865                                     struct dmxdev_filter *dmxdevfilter,
 866                                     struct dmx_pes_filter_params *params)
 867{
 868        int ret;
 869
 870        dvb_dmxdev_filter_stop(dmxdevfilter);
 871        dvb_dmxdev_filter_reset(dmxdevfilter);
 872
 873        if ((unsigned)params->pes_type > DMX_PES_OTHER)
 874                return -EINVAL;
 875
 876        dmxdevfilter->type = DMXDEV_TYPE_PES;
 877        memcpy(&dmxdevfilter->params, params,
 878               sizeof(struct dmx_pes_filter_params));
 879        INIT_LIST_HEAD(&dmxdevfilter->feed.ts);
 880
 881        dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
 882
 883        ret = dvb_dmxdev_add_pid(dmxdev, dmxdevfilter,
 884                                 dmxdevfilter->params.pes.pid);
 885        if (ret < 0)
 886                return ret;
 887
 888        if (params->flags & DMX_IMMEDIATE_START)
 889                return dvb_dmxdev_filter_start(dmxdevfilter);
 890
 891        return 0;
 892}
 893
 894static ssize_t dvb_dmxdev_read_sec(struct dmxdev_filter *dfil,
 895                                   struct file *file, char __user *buf,
 896                                   size_t count, loff_t *ppos)
 897{
 898        int result, hcount;
 899        int done = 0;
 900
 901        if (dfil->todo <= 0) {
 902                hcount = 3 + dfil->todo;
 903                if (hcount > count)
 904                        hcount = count;
 905                result = dvb_dmxdev_buffer_read(&dfil->buffer,
 906                                                file->f_flags & O_NONBLOCK,
 907                                                buf, hcount, ppos);
 908                if (result < 0) {
 909                        dfil->todo = 0;
 910                        return result;
 911                }
 912                if (copy_from_user(dfil->secheader - dfil->todo, buf, result))
 913                        return -EFAULT;
 914                buf += result;
 915                done = result;
 916                count -= result;
 917                dfil->todo -= result;
 918                if (dfil->todo > -3)
 919                        return done;
 920                dfil->todo = ((dfil->secheader[1] << 8) | dfil->secheader[2]) & 0xfff;
 921                if (!count)
 922                        return done;
 923        }
 924        if (count > dfil->todo)
 925                count = dfil->todo;
 926        result = dvb_dmxdev_buffer_read(&dfil->buffer,
 927                                        file->f_flags & O_NONBLOCK,
 928                                        buf, count, ppos);
 929        if (result < 0)
 930                return result;
 931        dfil->todo -= result;
 932        return (result + done);
 933}
 934
 935static ssize_t
 936dvb_demux_read(struct file *file, char __user *buf, size_t count,
 937               loff_t *ppos)
 938{
 939        struct dmxdev_filter *dmxdevfilter = file->private_data;
 940        int ret;
 941
 942        if (mutex_lock_interruptible(&dmxdevfilter->mutex))
 943                return -ERESTARTSYS;
 944
 945        if (dmxdevfilter->type == DMXDEV_TYPE_SEC)
 946                ret = dvb_dmxdev_read_sec(dmxdevfilter, file, buf, count, ppos);
 947        else
 948                ret = dvb_dmxdev_buffer_read(&dmxdevfilter->buffer,
 949                                             file->f_flags & O_NONBLOCK,
 950                                             buf, count, ppos);
 951
 952        mutex_unlock(&dmxdevfilter->mutex);
 953        return ret;
 954}
 955
 956static int dvb_demux_do_ioctl(struct file *file,
 957                              unsigned int cmd, void *parg)
 958{
 959        struct dmxdev_filter *dmxdevfilter = file->private_data;
 960        struct dmxdev *dmxdev = dmxdevfilter->dev;
 961        unsigned long arg = (unsigned long)parg;
 962        int ret = 0;
 963
 964        if (mutex_lock_interruptible(&dmxdev->mutex))
 965                return -ERESTARTSYS;
 966
 967        switch (cmd) {
 968        case DMX_START:
 969                if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
 970                        mutex_unlock(&dmxdev->mutex);
 971                        return -ERESTARTSYS;
 972                }
 973                if (dmxdevfilter->state < DMXDEV_STATE_SET)
 974                        ret = -EINVAL;
 975                else
 976                        ret = dvb_dmxdev_filter_start(dmxdevfilter);
 977                mutex_unlock(&dmxdevfilter->mutex);
 978                break;
 979
 980        case DMX_STOP:
 981                if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
 982                        mutex_unlock(&dmxdev->mutex);
 983                        return -ERESTARTSYS;
 984                }
 985                ret = dvb_dmxdev_filter_stop(dmxdevfilter);
 986                mutex_unlock(&dmxdevfilter->mutex);
 987                break;
 988
 989        case DMX_SET_FILTER:
 990                if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
 991                        mutex_unlock(&dmxdev->mutex);
 992                        return -ERESTARTSYS;
 993                }
 994                ret = dvb_dmxdev_filter_set(dmxdev, dmxdevfilter, parg);
 995                mutex_unlock(&dmxdevfilter->mutex);
 996                break;
 997
 998        case DMX_SET_PES_FILTER:
 999                if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
1000                        mutex_unlock(&dmxdev->mutex);
1001                        return -ERESTARTSYS;
1002                }
1003                ret = dvb_dmxdev_pes_filter_set(dmxdev, dmxdevfilter, parg);
1004                mutex_unlock(&dmxdevfilter->mutex);
1005                break;
1006
1007        case DMX_SET_BUFFER_SIZE:
1008                if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
1009                        mutex_unlock(&dmxdev->mutex);
1010                        return -ERESTARTSYS;
1011                }
1012                ret = dvb_dmxdev_set_buffer_size(dmxdevfilter, arg);
1013                mutex_unlock(&dmxdevfilter->mutex);
1014                break;
1015
1016        case DMX_GET_PES_PIDS:
1017                if (!dmxdev->demux->get_pes_pids) {
1018                        ret = -EINVAL;
1019                        break;
1020                }
1021                dmxdev->demux->get_pes_pids(dmxdev->demux, parg);
1022                break;
1023
1024#if 0
1025        /* Not used upstream and never documented */
1026
1027        case DMX_GET_CAPS:
1028                if (!dmxdev->demux->get_caps) {
1029                        ret = -EINVAL;
1030                        break;
1031                }
1032                ret = dmxdev->demux->get_caps(dmxdev->demux, parg);
1033                break;
1034
1035        case DMX_SET_SOURCE:
1036                if (!dmxdev->demux->set_source) {
1037                        ret = -EINVAL;
1038                        break;
1039                }
1040                ret = dmxdev->demux->set_source(dmxdev->demux, parg);
1041                break;
1042#endif
1043
1044        case DMX_GET_STC:
1045                if (!dmxdev->demux->get_stc) {
1046                        ret = -EINVAL;
1047                        break;
1048                }
1049                ret = dmxdev->demux->get_stc(dmxdev->demux,
1050                                             ((struct dmx_stc *)parg)->num,
1051                                             &((struct dmx_stc *)parg)->stc,
1052                                             &((struct dmx_stc *)parg)->base);
1053                break;
1054
1055        case DMX_ADD_PID:
1056                if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
1057                        ret = -ERESTARTSYS;
1058                        break;
1059                }
1060                ret = dvb_dmxdev_add_pid(dmxdev, dmxdevfilter, *(u16 *)parg);
1061                mutex_unlock(&dmxdevfilter->mutex);
1062                break;
1063
1064        case DMX_REMOVE_PID:
1065                if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
1066                        ret = -ERESTARTSYS;
1067                        break;
1068                }
1069                ret = dvb_dmxdev_remove_pid(dmxdev, dmxdevfilter, *(u16 *)parg);
1070                mutex_unlock(&dmxdevfilter->mutex);
1071                break;
1072
1073        default:
1074                ret = -EINVAL;
1075                break;
1076        }
1077        mutex_unlock(&dmxdev->mutex);
1078        return ret;
1079}
1080
1081static long dvb_demux_ioctl(struct file *file, unsigned int cmd,
1082                            unsigned long arg)
1083{
1084        return dvb_usercopy(file, cmd, arg, dvb_demux_do_ioctl);
1085}
1086
1087static unsigned int dvb_demux_poll(struct file *file, poll_table *wait)
1088{
1089        struct dmxdev_filter *dmxdevfilter = file->private_data;
1090        unsigned int mask = 0;
1091
1092        if ((!dmxdevfilter) || dmxdevfilter->dev->exit)
1093                return POLLERR;
1094
1095        poll_wait(file, &dmxdevfilter->buffer.queue, wait);
1096
1097        if (dmxdevfilter->state != DMXDEV_STATE_GO &&
1098            dmxdevfilter->state != DMXDEV_STATE_DONE &&
1099            dmxdevfilter->state != DMXDEV_STATE_TIMEDOUT)
1100                return 0;
1101
1102        if (dmxdevfilter->buffer.error)
1103                mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR);
1104
1105        if (!dvb_ringbuffer_empty(&dmxdevfilter->buffer))
1106                mask |= (POLLIN | POLLRDNORM | POLLPRI);
1107
1108        return mask;
1109}
1110
1111static int dvb_demux_release(struct inode *inode, struct file *file)
1112{
1113        struct dmxdev_filter *dmxdevfilter = file->private_data;
1114        struct dmxdev *dmxdev = dmxdevfilter->dev;
1115
1116        int ret;
1117
1118        ret = dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);
1119
1120        mutex_lock(&dmxdev->mutex);
1121        dmxdev->dvbdev->users--;
1122        if(dmxdev->dvbdev->users==1 && dmxdev->exit==1) {
1123                mutex_unlock(&dmxdev->mutex);
1124                wake_up(&dmxdev->dvbdev->wait_queue);
1125        } else
1126                mutex_unlock(&dmxdev->mutex);
1127
1128        return ret;
1129}
1130
1131static const struct file_operations dvb_demux_fops = {
1132        .owner = THIS_MODULE,
1133        .read = dvb_demux_read,
1134        .unlocked_ioctl = dvb_demux_ioctl,
1135        .open = dvb_demux_open,
1136        .release = dvb_demux_release,
1137        .poll = dvb_demux_poll,
1138        .llseek = default_llseek,
1139};
1140
1141static const struct dvb_device dvbdev_demux = {
1142        .priv = NULL,
1143        .users = 1,
1144        .writers = 1,
1145#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
1146        .name = "dvb-demux",
1147#endif
1148        .fops = &dvb_demux_fops
1149};
1150
1151static int dvb_dvr_do_ioctl(struct file *file,
1152                            unsigned int cmd, void *parg)
1153{
1154        struct dvb_device *dvbdev = file->private_data;
1155        struct dmxdev *dmxdev = dvbdev->priv;
1156        unsigned long arg = (unsigned long)parg;
1157        int ret;
1158
1159        if (mutex_lock_interruptible(&dmxdev->mutex))
1160                return -ERESTARTSYS;
1161
1162        switch (cmd) {
1163        case DMX_SET_BUFFER_SIZE:
1164                ret = dvb_dvr_set_buffer_size(dmxdev, arg);
1165                break;
1166
1167        default:
1168                ret = -EINVAL;
1169                break;
1170        }
1171        mutex_unlock(&dmxdev->mutex);
1172        return ret;
1173}
1174
1175static long dvb_dvr_ioctl(struct file *file,
1176                         unsigned int cmd, unsigned long arg)
1177{
1178        return dvb_usercopy(file, cmd, arg, dvb_dvr_do_ioctl);
1179}
1180
1181static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait)
1182{
1183        struct dvb_device *dvbdev = file->private_data;
1184        struct dmxdev *dmxdev = dvbdev->priv;
1185        unsigned int mask = 0;
1186
1187        dprintk("function : %s\n", __func__);
1188
1189        if (dmxdev->exit)
1190                return POLLERR;
1191
1192        poll_wait(file, &dmxdev->dvr_buffer.queue, wait);
1193
1194        if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
1195                if (dmxdev->dvr_buffer.error)
1196                        mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR);
1197
1198                if (!dvb_ringbuffer_empty(&dmxdev->dvr_buffer))
1199                        mask |= (POLLIN | POLLRDNORM | POLLPRI);
1200        } else
1201                mask |= (POLLOUT | POLLWRNORM | POLLPRI);
1202
1203        return mask;
1204}
1205
1206static const struct file_operations dvb_dvr_fops = {
1207        .owner = THIS_MODULE,
1208        .read = dvb_dvr_read,
1209        .write = dvb_dvr_write,
1210        .unlocked_ioctl = dvb_dvr_ioctl,
1211        .open = dvb_dvr_open,
1212        .release = dvb_dvr_release,
1213        .poll = dvb_dvr_poll,
1214        .llseek = default_llseek,
1215};
1216
1217static const struct dvb_device dvbdev_dvr = {
1218        .priv = NULL,
1219        .readers = 1,
1220        .users = 1,
1221#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
1222        .name = "dvb-dvr",
1223#endif
1224        .fops = &dvb_dvr_fops
1225};
1226int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
1227{
1228        int i;
1229
1230        if (dmxdev->demux->open(dmxdev->demux) < 0)
1231                return -EUSERS;
1232
1233        dmxdev->filter = vmalloc(dmxdev->filternum * sizeof(struct dmxdev_filter));
1234        if (!dmxdev->filter)
1235                return -ENOMEM;
1236
1237        mutex_init(&dmxdev->mutex);
1238        spin_lock_init(&dmxdev->lock);
1239        for (i = 0; i < dmxdev->filternum; i++) {
1240                dmxdev->filter[i].dev = dmxdev;
1241                dmxdev->filter[i].buffer.data = NULL;
1242                dvb_dmxdev_filter_state_set(&dmxdev->filter[i],
1243                                            DMXDEV_STATE_FREE);
1244        }
1245
1246        dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev,
1247                            DVB_DEVICE_DEMUX, dmxdev->filternum);
1248        dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr,
1249                            dmxdev, DVB_DEVICE_DVR, dmxdev->filternum);
1250
1251        dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192);
1252
1253        return 0;
1254}
1255
1256EXPORT_SYMBOL(dvb_dmxdev_init);
1257
1258void dvb_dmxdev_release(struct dmxdev *dmxdev)
1259{
1260        dmxdev->exit=1;
1261        if (dmxdev->dvbdev->users > 1) {
1262                wait_event(dmxdev->dvbdev->wait_queue,
1263                                dmxdev->dvbdev->users==1);
1264        }
1265        if (dmxdev->dvr_dvbdev->users > 1) {
1266                wait_event(dmxdev->dvr_dvbdev->wait_queue,
1267                                dmxdev->dvr_dvbdev->users==1);
1268        }
1269
1270        dvb_unregister_device(dmxdev->dvbdev);
1271        dvb_unregister_device(dmxdev->dvr_dvbdev);
1272
1273        vfree(dmxdev->filter);
1274        dmxdev->filter = NULL;
1275        dmxdev->demux->close(dmxdev->demux);
1276}
1277
1278EXPORT_SYMBOL(dvb_dmxdev_release);
1279