SASC
DVBSoftCAM

dvblb_forward.c

Go to the documentation of this file.
00001 /*
00002  *      dvblb_forward.c
00003  *
00004  *      DVBLoopback Copyright Alan Nisota 2006
00005  *
00006  *      Portions of this code also have copyright:
00007  *      Video Loopback Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2000
00008  *
00009  *      Published under the GNU Public License.
00010  *      DVBLoopback is free software; you can redistribute it and/or modify
00011  *      it under the terms of the GNU General Public License as published by
00012  *      the Free Software Foundation; either version 2 of the License, or
00013  *      (at your option) any later version.
00014  *
00015  *      DVBLoopback is distributed in the hope that it will be useful,
00016  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *      GNU General Public License for more details.
00019  *
00020  *      You should have received a copy of the GNU General Public License
00021  *      along with Foobar; if not, write to the Free Software
00022  *      Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
00023  */
00024 #include <linux/version.h>      /* >= 2.6.14 LINUX_VERSION_CODE */
00025 #include <linux/errno.h>
00026 #include <linux/kernel.h>
00027 #include <linux/module.h>
00028 
00029 #include <linux/fs.h>
00030 #include <linux/file.h>
00031 #include <linux/cdev.h>
00032 #include <linux/err.h>
00033 #include "dvblb_internal.h"
00034 
00035 #define nums2minor(num,type,id) ((num << 6) | (id << 4) | type)
00036 
00037 // forward to correct device
00038 static struct file *find_forwardmap(struct dvblb_devinfo *lbdev,
00039                                     struct dvb_device **f)
00040 {
00041         int i;
00042         for(i = 0; i < DVBLB_MAXFD; i++)
00043                 if(lbdev->forwardmap[i].f == f)
00044                         return lbdev->forwardmap[i].map;
00045         return ERR_PTR(-1);
00046 }
00047 
00048 static int set_forwardmap(struct dvblb_devinfo *lbdev, struct dvb_device **f,
00049                           struct file *map) {
00050         int i;
00051         for(i = 0; i < DVBLB_MAXFD; i++)
00052                 if(lbdev->forwardmap[i].f == NULL) {
00053                         lbdev->forwardmap[i].f = f;
00054                         lbdev->forwardmap[i].map = map;
00055                         return i;
00056                 }
00057         return -1;
00058 }
00059 
00060 static void clear_forwardmap(struct dvblb_devinfo *lbdev, struct dvb_device **f)
00061 {
00062         int i;
00063         for(i = 0; i < DVBLB_MAXFD; i++)
00064                 if(lbdev->forwardmap[i].f == f) {
00065                         lbdev->forwardmap[i].f = NULL;
00066                         return;
00067                 }
00068 }
00069 
00070 int dvblb_forward_open(struct dvblb_devinfo *lbdev, struct inode *inode,
00071                        struct file *f)
00072 {
00073 //      int minor;
00074 //      struct inode *tmpinode;
00075 //      struct dentry *dentry;
00076         struct file *ftmp;
00077         char tmpstr[35];
00078 
00079         if (! inode->i_cdev || ! inode->i_cdev->ops ||
00080             ! inode->i_cdev->ops->open) {
00081                 printk("dvblb_forward_open: "
00082                        "device wasn't correctly initialized\n");
00083                 return -EFAULT;
00084         }
00085         sprintf(tmpstr, "/dev/dvb/adapter%d/%s%d", lbdev->forward_dev->adapter->num, dnames[lbdev->forward_dev->type], lbdev->forward_dev->id);
00086         /* printk("linking to %s\n", tmpstr); */
00087         ftmp = filp_open(tmpstr, f->f_flags, f->f_mode);
00088 
00089         /* It would be nice to find a way to open the device without relying
00090            on a fixed path, but the attempt below certainly isn't it */
00091 /*
00092         minor = nums2minor(lbdev->forward_dev->adapter->num,
00093                            lbdev->forward_dev->type, lbdev->forward_dev->id);
00094         tmpinode = iget_locked(inode->i_sb, MKDEV(DVB_MAJOR, minor));
00095         if (! tmpinode)
00096                 return -EFAULT;
00097         if (is_bad_inode(tmpinode)) {
00098                 iput(tmpinode);
00099                 return -EFAULT;
00100         }
00101         dentry = d_alloc_anon(tmpinode);
00102         if (!dentry) {
00103                 iput(tmpinode);
00104                 return -EFAULT;
00105         }
00106         ftmp = dentry_open(dentry, f->f_vfsmnt, f->f_flags);
00107 */
00108         if (!ftmp || IS_ERR(ftmp)) {
00109                 int fd = PTR_ERR(ftmp);
00110                 printk("open failed: %d\n", fd);
00111                 return fd;
00112         }
00113         if (! ftmp->f_op || ! lbdev->forward_dev->fops ||
00114             ftmp->f_op->open !=  lbdev->forward_dev->fops->open) {
00115                 printk("DVB device din't initialize correctly\n");
00116                 filp_close(ftmp, NULL);
00117                 return -EFAULT;
00118         }
00119         if (set_forwardmap(lbdev, f->private_data, ftmp) == -1) {
00120                 printk("Didn't find a valid forwardmap\n");
00121                 filp_close(ftmp, NULL);
00122                 return -EFAULT;
00123         }
00124         return 0;
00125 }
00126 
00127 int dvblb_forward_release(struct dvblb_devinfo *lbdev, struct file *f)
00128 {
00129         struct file *ftmp = find_forwardmap(lbdev, f->private_data);
00130         if (!ftmp || IS_ERR(ftmp))
00131                 return -EFAULT;
00132         if (lbdev->forward_dev->fops &&lbdev->forward_dev->fops->release) {
00133                 filp_close(ftmp, NULL);
00134                 clear_forwardmap(lbdev, f->private_data);
00135         }
00136         return -EFAULT;
00137 }
00138 
00139 ssize_t dvblb_forward_write(struct dvblb_devinfo *lbdev, struct file *f,
00140                             const char *buf, size_t count, loff_t *offset)
00141 {
00142         struct file *ftmp = find_forwardmap(lbdev, f->private_data);
00143         if (!ftmp || IS_ERR(ftmp))
00144                 return -EFAULT;
00145         if (lbdev->forward_dev->fops &&lbdev->forward_dev->fops->write)
00146                 return lbdev->forward_dev->fops->write(
00147                            ftmp, buf, count, offset);
00148         return -EFAULT;
00149 }
00150 
00151 ssize_t dvblb_forward_read (struct dvblb_devinfo *lbdev, struct file *f,
00152                             char * buf, size_t count, loff_t *offset)
00153 {
00154         struct file *ftmp = find_forwardmap(lbdev, f->private_data);
00155         if (!ftmp || IS_ERR(ftmp))
00156                 return -EFAULT;
00157         if (lbdev->forward_dev->fops &&lbdev->forward_dev->fops->read)
00158                 return lbdev->forward_dev->fops->read(
00159                            ftmp, buf, count, offset);
00160         return -EFAULT;
00161 }
00162 
00163 int dvblb_forward_ioctl(struct dvblb_devinfo *lbdev, struct file *f,
00164                         unsigned int cmd, unsigned long arg)
00165 {
00166         struct file *ftmp = find_forwardmap(lbdev, f->private_data);
00167         if (!ftmp || IS_ERR(ftmp))
00168                 return -EFAULT;
00169 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
00170         if (lbdev->forward_dev->fops &&lbdev->forward_dev->fops->unlocked_ioctl)
00171                 return lbdev->forward_dev->fops->unlocked_ioctl(
00172                            ftmp, cmd, arg);
00173 #else
00174         if (lbdev->forward_dev->fops &&lbdev->forward_dev->fops->ioctl)
00175                 return lbdev->forward_dev->fops->ioctl(
00176                            ftmp->f_dentry->d_inode, ftmp, cmd, arg);
00177 #endif
00178         return -EFAULT;
00179 }
00180 
00181 int dvblb_forward_mmap(struct dvblb_devinfo *lbdev, struct file *f,
00182                        struct vm_area_struct *vma)
00183 {
00184         struct file *ftmp = find_forwardmap(lbdev, f->private_data);
00185         if (!ftmp || IS_ERR(ftmp))
00186                 return -EFAULT;
00187         if (lbdev->forward_dev->fops &&lbdev->forward_dev->fops->mmap)
00188                 return lbdev->forward_dev->fops->mmap(ftmp, vma);
00189         return -EFAULT;
00190 }
00191 
00192 int dvblb_forward_poll(struct dvblb_devinfo *lbdev, struct file *f,
00193                        struct poll_table_struct *wait)
00194 {
00195         struct file *ftmp = find_forwardmap(lbdev, f->private_data);
00196         if (!ftmp || IS_ERR(ftmp))
00197                 return -EFAULT;
00198         if (lbdev->forward_dev->fops &&lbdev->forward_dev->fops->poll)
00199                 return lbdev->forward_dev->fops->poll(ftmp, wait);
00200         return -EFAULT;
00201 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines