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