⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dvb_frontend.c

📁 dvb的系统程序。基于lunix系统.经过改进更新
💻 C
📖 第 1 页 / 共 3 页
字号:
        // if the frontend has just been set, wait until the first tune has finished.	// This ensures the app doesn't start reading data too quickly, perhaps from the	// previous lock, which is REALLY CONFUSING TO DEBUG!	if ((cmd == FE_SET_FRONTEND) && (err == 0)) {	   // note: cannot use wait_event_interruptible_* here as that	   // causes the thread not to wake until AFTER the call here returns. This is useless	   // because the whole point is to have the thread wake first, and perform at least one tune	   wake_up_interruptible(&fe->wait_queue);	   while(fe->state & FESTATE_RETUNE) {	      dvb_delay(10);	   }	}	return err;}static unsigned int dvb_frontend_poll (struct file *file, struct poll_table_struct *wait){	struct dvb_device *dvbdev = file->private_data;	struct dvb_frontend_data *fe = dvbdev->priv;	dprintk ("%s\n", __FUNCTION__);	poll_wait (file, &fe->events.wait_queue, wait);	if (fe->events.eventw != fe->events.eventr)		return (POLLIN | POLLRDNORM | POLLPRI);	return 0;}static int dvb_frontend_open (struct inode *inode, struct file *file){	struct dvb_device *dvbdev = file->private_data;	struct dvb_frontend_data *fe = dvbdev->priv;	int ret;	dprintk ("%s\n", __FUNCTION__);	if ((ret = dvb_generic_open (inode, file)) < 0)		return ret;	if ((file->f_flags & O_ACCMODE) != O_RDONLY) {		ret = dvb_frontend_start (fe);		if (ret)			dvb_generic_release (inode, file);		/*  empty event queue */		fe->events.eventr = fe->events.eventw = 0;	}	return ret;}static int dvb_frontend_release (struct inode *inode, struct file *file){	struct dvb_device *dvbdev = file->private_data;	struct dvb_frontend_data *fe = dvbdev->priv;	dprintk ("%s\n", __FUNCTION__);	if ((file->f_flags & O_ACCMODE) != O_RDONLY)		fe->release_jiffies = jiffies;	return dvb_generic_release (inode, file);}intdvb_add_frontend_ioctls (struct dvb_adapter *adapter,                         int (*before_ioctl) (struct dvb_frontend *frontend,                                              unsigned int cmd, void *arg),                         int (*after_ioctl)  (struct dvb_frontend *frontend,                                              unsigned int cmd, void *arg),			 void *before_after_data){	struct dvb_frontend_ioctl_data *ioctl;        struct list_head *entry;	dprintk ("%s\n", __FUNCTION__);	if (down_interruptible (&frontend_mutex))		return -ERESTARTSYS;	ioctl = kmalloc (sizeof(struct dvb_frontend_ioctl_data), GFP_KERNEL);	if (!ioctl) {		up (&frontend_mutex);		return -ENOMEM;	}	ioctl->adapter = adapter;	ioctl->before_ioctl = before_ioctl;	ioctl->after_ioctl = after_ioctl;	ioctl->before_after_data = before_after_data;	list_add_tail (&ioctl->list_head, &frontend_ioctl_list);	list_for_each (entry, &frontend_list) {		struct dvb_frontend_data *fe;		fe = list_entry (entry, struct dvb_frontend_data, list_head);		if (fe->frontend.i2c->adapter == adapter &&		    fe->frontend.before_ioctl == NULL &&		    fe->frontend.after_ioctl == NULL)		{			fe->frontend.before_ioctl = before_ioctl;			fe->frontend.after_ioctl = after_ioctl;			fe->frontend.before_after_data = before_after_data;		}	}	up (&frontend_mutex);	return 0;}voiddvb_remove_frontend_ioctls (struct dvb_adapter *adapter,			    int (*before_ioctl) (struct dvb_frontend *frontend,                                                 unsigned int cmd, void *arg),                            int (*after_ioctl)  (struct dvb_frontend *frontend,                                                 unsigned int cmd, void *arg)){	struct list_head *entry, *n;	dprintk ("%s\n", __FUNCTION__);	down (&frontend_mutex);	list_for_each (entry, &frontend_list) {		struct dvb_frontend_data *fe;		fe = list_entry (entry, struct dvb_frontend_data, list_head);		if (fe->frontend.i2c->adapter == adapter &&		    fe->frontend.before_ioctl == before_ioctl &&		    fe->frontend.after_ioctl == after_ioctl)		{			fe->frontend.before_ioctl = NULL;			fe->frontend.after_ioctl = NULL;		}	}	list_for_each_safe (entry, n, &frontend_ioctl_list) {		struct dvb_frontend_ioctl_data *ioctl;		ioctl = list_entry (entry, struct dvb_frontend_ioctl_data, list_head);		if (ioctl->adapter == adapter &&		    ioctl->before_ioctl == before_ioctl &&		    ioctl->after_ioctl == after_ioctl)		{			list_del (&ioctl->list_head);			kfree (ioctl);						break;		}	}	up (&frontend_mutex);}intdvb_add_frontend_notifier (struct dvb_adapter *adapter,			   void (*callback) (fe_status_t s, void *data),			   void *data){	struct dvb_frontend_notifier_data *notifier;	struct list_head *entry;	dprintk ("%s\n", __FUNCTION__);	if (down_interruptible (&frontend_mutex))		return -ERESTARTSYS;	notifier = kmalloc (sizeof(struct dvb_frontend_notifier_data), GFP_KERNEL);	if (!notifier) {		up (&frontend_mutex);		return -ENOMEM;	}	notifier->adapter = adapter;	notifier->callback = callback;	notifier->data = data;	list_add_tail (&notifier->list_head, &frontend_notifier_list);	list_for_each (entry, &frontend_list) {		struct dvb_frontend_data *fe;		fe = list_entry (entry, struct dvb_frontend_data, list_head);		if (fe->frontend.i2c->adapter == adapter &&		    fe->frontend.notifier_callback == NULL)		{			fe->frontend.notifier_callback = callback;			fe->frontend.notifier_data = data;		}	}	up (&frontend_mutex);	return 0;}voiddvb_remove_frontend_notifier (struct dvb_adapter *adapter,			      void (*callback) (fe_status_t s, void *data)){	struct list_head *entry, *n;	dprintk ("%s\n", __FUNCTION__);	down (&frontend_mutex);	list_for_each (entry, &frontend_list) {		struct dvb_frontend_data *fe;		fe = list_entry (entry, struct dvb_frontend_data, list_head);		if (fe->frontend.i2c->adapter == adapter &&		    fe->frontend.notifier_callback == callback)		{			fe->frontend.notifier_callback = NULL;		}	}	list_for_each_safe (entry, n, &frontend_notifier_list) {		struct dvb_frontend_notifier_data *notifier;		notifier = list_entry (entry, struct dvb_frontend_notifier_data, list_head);		if (notifier->adapter == adapter &&		    notifier->callback == callback)		{			list_del (&notifier->list_head);			kfree (notifier);						break;		}	}	up (&frontend_mutex);}static struct file_operations dvb_frontend_fops = {	.owner		= THIS_MODULE,	.ioctl		= dvb_generic_ioctl,	.poll		= dvb_frontend_poll,	.open		= dvb_frontend_open,	.release	= dvb_frontend_release};intdvb_register_frontend (int (*ioctl) (struct dvb_frontend *frontend,				     unsigned int cmd, void *arg),		       struct dvb_i2c_bus *i2c,		       void *data,		       struct dvb_frontend_info *info){	struct list_head *entry;	struct dvb_frontend_data *fe;	static const struct dvb_device dvbdev_template = {		.users = ~0,		.writers = 1,		.readers = (~0)-1,		.fops = &dvb_frontend_fops,		.kernel_ioctl = dvb_frontend_ioctl	};	dprintk ("%s\n", __FUNCTION__);	if (down_interruptible (&frontend_mutex))		return -ERESTARTSYS;	if (!(fe = kmalloc (sizeof (struct dvb_frontend_data), GFP_KERNEL))) {		up (&frontend_mutex);		return -ENOMEM;	}	memset (fe, 0, sizeof (struct dvb_frontend_data));	init_MUTEX (&fe->sem);	init_waitqueue_head (&fe->wait_queue);	init_waitqueue_head (&fe->events.wait_queue);	init_MUTEX (&fe->events.sem);	fe->events.eventw = fe->events.eventr = 0;	fe->events.overflow = 0;	fe->frontend.ioctl = ioctl;	fe->frontend.i2c = i2c;	fe->frontend.data = data;	fe->info = info;	list_for_each (entry, &frontend_ioctl_list) {		struct dvb_frontend_ioctl_data *ioctl;		ioctl = list_entry (entry,				    struct dvb_frontend_ioctl_data,				    list_head);		if (ioctl->adapter == i2c->adapter) {			fe->frontend.before_ioctl = ioctl->before_ioctl;			fe->frontend.after_ioctl = ioctl->after_ioctl;			fe->frontend.before_after_data = ioctl->before_after_data;			break;		}	}	list_for_each (entry, &frontend_notifier_list) {		struct dvb_frontend_notifier_data *notifier;		notifier = list_entry (entry,				       struct dvb_frontend_notifier_data,				       list_head);		if (notifier->adapter == i2c->adapter) {			fe->frontend.notifier_callback = notifier->callback;			fe->frontend.notifier_data = notifier->data;			break;		}	}	list_add_tail (&fe->list_head, &frontend_list);	printk ("DVB: registering frontend %i:%i (%s)...\n",		fe->frontend.i2c->adapter->num, fe->frontend.i2c->id,		fe->info->name);	dvb_register_device (i2c->adapter, &fe->dvbdev, &dvbdev_template,			     fe, DVB_DEVICE_FRONTEND);	up (&frontend_mutex);	return 0;}int dvb_unregister_frontend (int (*ioctl) (struct dvb_frontend *frontend,					   unsigned int cmd, void *arg),			     struct dvb_i2c_bus *i2c){        struct list_head *entry, *n;	dprintk ("%s\n", __FUNCTION__);	down (&frontend_mutex);	list_for_each_safe (entry, n, &frontend_list) {		struct dvb_frontend_data *fe;		fe = list_entry (entry, struct dvb_frontend_data, list_head);		if (fe->frontend.ioctl == ioctl && fe->frontend.i2c == i2c) {			dvb_unregister_device (fe->dvbdev);			list_del (entry);			up (&frontend_mutex);			dvb_frontend_stop (fe);			kfree (fe);			return 0;		}	}	up (&frontend_mutex);	return -EINVAL;}MODULE_PARM(dvb_frontend_debug,"i");MODULE_PARM(dvb_shutdown_timeout,"i");MODULE_PARM(dvb_frequency_bending,"i");MODULE_PARM_DESC(dvb_frontend_debug, "enable verbose debug messages");MODULE_PARM_DESC(dvb_shutdown_timeout, "wait <shutdown_timeout> seconds after close() before suspending hardware");MODULE_PARM_DESC(dvb_frequency_bending, "0: disable frequency bending, 1: enable (default)");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -