#include "dvb_adapter.h" #include "dvbdev.h" #define dprintk printk static DEFINE_MUTEX(adaptor_mutex); struct dvb_adaptor_private { struct dvb_device *dvbdev; struct semaphore sem; unsigned int exit; }; static int dvb_adaptor_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; struct dvb_adaptor *adaptor = dvbdev->priv; struct dvb_adaptor_private *adaptor_priv = adaptor->adaptor_priv; int err = -EOPNOTSUPP; dprintk("%s\n", __func__); if (!adaptor || adaptor_priv->exit) return -ENODEV; if ((file->f_flags & O_ACCMODE) == O_RDONLY && (_IOC_DIR(cmd) != _IOC_READ)) return -EPERM; if (down_interruptible(&adaptor_priv->sem)) return -ERESTARTSYS; switch (cmd) { }; up(&adaptor_priv->sem); return err; } static int dvb_adaptor_open(struct inode *inode, struct file *file) { struct dvb_device *dvbdev = file->private_data; struct dvb_adaptor *adaptor = dvbdev->priv; struct dvb_adaptor_private *adaptor_priv = adaptor->adaptor_priv; int ret; dprintk("%s\n", __func__); if ((ret = dvb_generic_open(inode, file)) < 0) return ret; if ((file->f_flags & O_ACCMODE) != O_RDONLY) { } return ret; } static int dvb_adaptor_release(struct inode *inode, struct file *file) { struct dvb_device *dvbdev = file->private_data; struct dvb_adaptor *adaptor = dvbdev->priv; struct dvb_adaptor_private *adaptor_priv = adaptor->adaptor_priv; dprintk("%s\n", __func__); // if ((file->f_flags & O_ACCMODE) != O_RDONLY) // fepriv->release_jiffies = jiffies; return dvb_generic_release(inode, file); } static struct file_operations dvb_adaptor_fops = { .owner = THIS_MODULE, .ioctl = dvb_generic_ioctl, .open = dvb_adaptor_open, .release = dvb_adaptor_release // .poll = dvb_adaptor_poll, }; struct dvb_adaptor_obj *dvb_adapter_obj_register(struct dvb_adaptor *adaptor, char *name, enum dvb_adaptor_type type) { struct dvb_adaptor_obj *adaptor_obj = NULL; adaptor_obj = kzalloc(sizeof (struct dvb_adaptor_obj), GFP_KERNEL); adaptor_obj->dvb = adaptor; adaptor_obj->object_type = type; strlcpy(adaptor_obj->object_name, name, sizeof (name)); list_add_tail(&adaptor_obj->list, &adaptor->list); return adaptor_obj; } int dvb_adapter_obj_unregister(struct dvb_adaptor_obj *adaptor_obj) { if (adaptor_obj->dvb) list_del(&adaptor_obj->list); kfree(adaptor_obj); return 0; } int dvb_register_adaptor(struct dvb_adapter *dvb, struct dvb_adaptor *adaptor) { struct dvb_adaptor_private *adaptor_priv = NULL; static const struct dvb_device dvbdev_template = { .users = ~0, .writers = 1, .readers = (~0)-1, .fops = &dvb_adaptor_fops, .kernel_ioctl = dvb_adaptor_ioctl }; if (mutex_lock_interruptible(&adaptor_mutex)) return -ERESTARTSYS; adaptor->adaptor_priv = kzalloc(sizeof (struct dvb_adaptor_private), GFP_KERNEL); if (adaptor->adaptor_priv == NULL) { mutex_unlock(&adaptor_mutex); return -ENOMEM; } INIT_LIST_HEAD(&adaptor->list); adaptor_priv = adaptor->adaptor_priv; adaptor->dvb = dvb; printk("DVB: registering adaptor (%d) (%s Rev %d on a %s %s)\n", adaptor->dvb->num, adaptor->ops.info.adaptor_name, adaptor->ops.info.adaptor_rev, adaptor->ops.info.adaptor_model); dvb_register_device(adaptor->dvb, &adaptor_priv->dvbdev, &dvbdev_template, adaptor, DVB_DEVICE_ADAPTOR); mutex_unlock(&adaptor_mutex); return 0; } EXPORT_SYMBOL(dvb_register_adaptor); int dvb_unregister_adaptor(struct dvb_adaptor *adaptor) { struct dvb_adaptor_private *adaptor_priv = adaptor->adaptor_priv; dprintk("%s\n", __func__); mutex_lock(&adaptor_mutex); dvb_unregister_device(adaptor_priv->dvbdev); kfree(adaptor_priv); mutex_unlock(&adaptor_mutex); return 0; } EXPORT_SYMBOL(dvb_unregister_adaptor);