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