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