brintos

brintos / linux-shallow public Read only

0
0
Text · 35.0 KiB · 9ce5f01 Raw
1478 lines · c
1// SPDX-License-Identifier: LGPL-2.1-or-later2/*3 * dmxdev.c - DVB demultiplexer device4 *5 * Copyright (C) 2000 Ralph Metzler & Marcus Metzler6 *		      for convergence integrated media GmbH7 */8 9#define pr_fmt(fmt) "dmxdev: " fmt10 11#include <linux/sched.h>12#include <linux/spinlock.h>13#include <linux/slab.h>14#include <linux/vmalloc.h>15#include <linux/module.h>16#include <linux/poll.h>17#include <linux/ioctl.h>18#include <linux/wait.h>19#include <linux/uaccess.h>20#include <media/dmxdev.h>21#include <media/dvb_vb2.h>22 23static int debug;24 25module_param(debug, int, 0644);26MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");27 28#define dprintk(fmt, arg...) do {					\29	if (debug)							\30		printk(KERN_DEBUG pr_fmt("%s: " fmt),			\31			__func__, ##arg);				\32} while (0)33 34static int dvb_dmxdev_buffer_write(struct dvb_ringbuffer *buf,35				   const u8 *src, size_t len)36{37	ssize_t free;38 39	if (!len)40		return 0;41	if (!buf->data)42		return 0;43 44	free = dvb_ringbuffer_free(buf);45	if (len > free) {46		dprintk("buffer overflow\n");47		return -EOVERFLOW;48	}49 50	return dvb_ringbuffer_write(buf, src, len);51}52 53static ssize_t dvb_dmxdev_buffer_read(struct dvb_ringbuffer *src,54				      int non_blocking, char __user *buf,55				      size_t count, loff_t *ppos)56{57	size_t todo;58	ssize_t avail;59	ssize_t ret = 0;60 61	if (!src->data)62		return 0;63 64	if (src->error) {65		ret = src->error;66		dvb_ringbuffer_flush(src);67		return ret;68	}69 70	for (todo = count; todo > 0; todo -= ret) {71		if (non_blocking && dvb_ringbuffer_empty(src)) {72			ret = -EWOULDBLOCK;73			break;74		}75 76		ret = wait_event_interruptible(src->queue,77					       !dvb_ringbuffer_empty(src) ||78					       (src->error != 0));79		if (ret < 0)80			break;81 82		if (src->error) {83			ret = src->error;84			dvb_ringbuffer_flush(src);85			break;86		}87 88		avail = dvb_ringbuffer_avail(src);89		if (avail > todo)90			avail = todo;91 92		ret = dvb_ringbuffer_read_user(src, buf, avail);93		if (ret < 0)94			break;95 96		buf += ret;97	}98 99	return (count - todo) ? (count - todo) : ret;100}101 102static struct dmx_frontend *get_fe(struct dmx_demux *demux, int type)103{104	struct list_head *head, *pos;105 106	head = demux->get_frontends(demux);107	if (!head)108		return NULL;109	list_for_each(pos, head)110		if (DMX_FE_ENTRY(pos)->source == type)111			return DMX_FE_ENTRY(pos);112 113	return NULL;114}115 116static int dvb_dvr_open(struct inode *inode, struct file *file)117{118	struct dvb_device *dvbdev = file->private_data;119	struct dmxdev *dmxdev = dvbdev->priv;120	struct dmx_frontend *front;121	bool need_ringbuffer = false;122 123	dprintk("%s\n", __func__);124 125	if (mutex_lock_interruptible(&dmxdev->mutex))126		return -ERESTARTSYS;127 128	if (dmxdev->exit) {129		mutex_unlock(&dmxdev->mutex);130		return -ENODEV;131	}132 133	dmxdev->may_do_mmap = 0;134 135	/*136	 * The logic here is a little tricky due to the ifdef.137	 *138	 * The ringbuffer is used for both read and mmap.139	 *140	 * It is not needed, however, on two situations:141	 *	- Write devices (access with O_WRONLY);142	 *	- For duplex device nodes, opened with O_RDWR.143	 */144 145	if ((file->f_flags & O_ACCMODE) == O_RDONLY)146		need_ringbuffer = true;147	else if ((file->f_flags & O_ACCMODE) == O_RDWR) {148		if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) {149#ifdef CONFIG_DVB_MMAP150			dmxdev->may_do_mmap = 1;151			need_ringbuffer = true;152#else153			mutex_unlock(&dmxdev->mutex);154			return -EOPNOTSUPP;155#endif156		}157	}158 159	if (need_ringbuffer) {160		void *mem;161 162		if (!dvbdev->readers) {163			mutex_unlock(&dmxdev->mutex);164			return -EBUSY;165		}166		mem = vmalloc(DVR_BUFFER_SIZE);167		if (!mem) {168			mutex_unlock(&dmxdev->mutex);169			return -ENOMEM;170		}171		dvb_ringbuffer_init(&dmxdev->dvr_buffer, mem, DVR_BUFFER_SIZE);172		if (dmxdev->may_do_mmap)173			dvb_vb2_init(&dmxdev->dvr_vb2_ctx, "dvr",174				     file->f_flags & O_NONBLOCK);175		dvbdev->readers--;176	}177 178	if ((file->f_flags & O_ACCMODE) == O_WRONLY) {179		dmxdev->dvr_orig_fe = dmxdev->demux->frontend;180 181		if (!dmxdev->demux->write) {182			mutex_unlock(&dmxdev->mutex);183			return -EOPNOTSUPP;184		}185 186		front = get_fe(dmxdev->demux, DMX_MEMORY_FE);187 188		if (!front) {189			mutex_unlock(&dmxdev->mutex);190			return -EINVAL;191		}192		dmxdev->demux->disconnect_frontend(dmxdev->demux);193		dmxdev->demux->connect_frontend(dmxdev->demux, front);194	}195	dvbdev->users++;196	mutex_unlock(&dmxdev->mutex);197	return 0;198}199 200static int dvb_dvr_release(struct inode *inode, struct file *file)201{202	struct dvb_device *dvbdev = file->private_data;203	struct dmxdev *dmxdev = dvbdev->priv;204 205	mutex_lock(&dmxdev->mutex);206 207	if ((file->f_flags & O_ACCMODE) == O_WRONLY) {208		dmxdev->demux->disconnect_frontend(dmxdev->demux);209		dmxdev->demux->connect_frontend(dmxdev->demux,210						dmxdev->dvr_orig_fe);211	}212 213	if (((file->f_flags & O_ACCMODE) == O_RDONLY) ||214	    dmxdev->may_do_mmap) {215		if (dmxdev->may_do_mmap) {216			if (dvb_vb2_is_streaming(&dmxdev->dvr_vb2_ctx))217				dvb_vb2_stream_off(&dmxdev->dvr_vb2_ctx);218			dvb_vb2_release(&dmxdev->dvr_vb2_ctx);219		}220		dvbdev->readers++;221		if (dmxdev->dvr_buffer.data) {222			void *mem = dmxdev->dvr_buffer.data;223			/*memory barrier*/224			mb();225			spin_lock_irq(&dmxdev->lock);226			dmxdev->dvr_buffer.data = NULL;227			spin_unlock_irq(&dmxdev->lock);228			vfree(mem);229		}230	}231	/* TODO */232	dvbdev->users--;233	if (dvbdev->users == 1 && dmxdev->exit == 1) {234		mutex_unlock(&dmxdev->mutex);235		wake_up(&dvbdev->wait_queue);236	} else237		mutex_unlock(&dmxdev->mutex);238 239	return 0;240}241 242static ssize_t dvb_dvr_write(struct file *file, const char __user *buf,243			     size_t count, loff_t *ppos)244{245	struct dvb_device *dvbdev = file->private_data;246	struct dmxdev *dmxdev = dvbdev->priv;247	int ret;248 249	if (!dmxdev->demux->write)250		return -EOPNOTSUPP;251	if ((file->f_flags & O_ACCMODE) != O_WRONLY)252		return -EINVAL;253	if (mutex_lock_interruptible(&dmxdev->mutex))254		return -ERESTARTSYS;255 256	if (dmxdev->exit) {257		mutex_unlock(&dmxdev->mutex);258		return -ENODEV;259	}260	ret = dmxdev->demux->write(dmxdev->demux, buf, count);261	mutex_unlock(&dmxdev->mutex);262	return ret;263}264 265static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count,266			    loff_t *ppos)267{268	struct dvb_device *dvbdev = file->private_data;269	struct dmxdev *dmxdev = dvbdev->priv;270 271	if (dmxdev->exit)272		return -ENODEV;273 274	return dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer,275				      file->f_flags & O_NONBLOCK,276				      buf, count, ppos);277}278 279static int dvb_dvr_set_buffer_size(struct dmxdev *dmxdev,280				      unsigned long size)281{282	struct dvb_ringbuffer *buf = &dmxdev->dvr_buffer;283	void *newmem;284	void *oldmem;285 286	dprintk("%s\n", __func__);287 288	if (buf->size == size)289		return 0;290	if (!size)291		return -EINVAL;292 293	newmem = vmalloc(size);294	if (!newmem)295		return -ENOMEM;296 297	oldmem = buf->data;298 299	spin_lock_irq(&dmxdev->lock);300	buf->data = newmem;301	buf->size = size;302 303	/* reset and not flush in case the buffer shrinks */304	dvb_ringbuffer_reset(buf);305	spin_unlock_irq(&dmxdev->lock);306 307	vfree(oldmem);308 309	return 0;310}311 312static inline void dvb_dmxdev_filter_state_set(struct dmxdev_filter313					       *dmxdevfilter, int state)314{315	spin_lock_irq(&dmxdevfilter->dev->lock);316	dmxdevfilter->state = state;317	spin_unlock_irq(&dmxdevfilter->dev->lock);318}319 320static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter,321				      unsigned long size)322{323	struct dvb_ringbuffer *buf = &dmxdevfilter->buffer;324	void *newmem;325	void *oldmem;326 327	if (buf->size == size)328		return 0;329	if (!size)330		return -EINVAL;331	if (dmxdevfilter->state >= DMXDEV_STATE_GO)332		return -EBUSY;333 334	newmem = vmalloc(size);335	if (!newmem)336		return -ENOMEM;337 338	oldmem = buf->data;339 340	spin_lock_irq(&dmxdevfilter->dev->lock);341	buf->data = newmem;342	buf->size = size;343 344	/* reset and not flush in case the buffer shrinks */345	dvb_ringbuffer_reset(buf);346	spin_unlock_irq(&dmxdevfilter->dev->lock);347 348	vfree(oldmem);349 350	return 0;351}352 353static void dvb_dmxdev_filter_timeout(struct timer_list *t)354{355	struct dmxdev_filter *dmxdevfilter = from_timer(dmxdevfilter, t, timer);356 357	dmxdevfilter->buffer.error = -ETIMEDOUT;358	spin_lock_irq(&dmxdevfilter->dev->lock);359	dmxdevfilter->state = DMXDEV_STATE_TIMEDOUT;360	spin_unlock_irq(&dmxdevfilter->dev->lock);361	wake_up(&dmxdevfilter->buffer.queue);362}363 364static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter)365{366	struct dmx_sct_filter_params *para = &dmxdevfilter->params.sec;367 368	del_timer(&dmxdevfilter->timer);369	if (para->timeout) {370		dmxdevfilter->timer.expires =371		    jiffies + 1 + (HZ / 2 + HZ * para->timeout) / 1000;372		add_timer(&dmxdevfilter->timer);373	}374}375 376static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,377				       const u8 *buffer2, size_t buffer2_len,378				       struct dmx_section_filter *filter,379				       u32 *buffer_flags)380{381	struct dmxdev_filter *dmxdevfilter = filter->priv;382	int ret;383 384	if (!dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx) &&385	    dmxdevfilter->buffer.error) {386		wake_up(&dmxdevfilter->buffer.queue);387		return 0;388	}389	spin_lock(&dmxdevfilter->dev->lock);390	if (dmxdevfilter->state != DMXDEV_STATE_GO) {391		spin_unlock(&dmxdevfilter->dev->lock);392		return 0;393	}394	del_timer(&dmxdevfilter->timer);395	dprintk("section callback %*ph\n", 6, buffer1);396	if (dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx)) {397		ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx,398					  buffer1, buffer1_len,399					  buffer_flags);400		if (ret == buffer1_len)401			ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx,402						  buffer2, buffer2_len,403						  buffer_flags);404	} else {405		ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer,406					      buffer1, buffer1_len);407		if (ret == buffer1_len) {408			ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer,409						      buffer2, buffer2_len);410		}411	}412	if (ret < 0)413		dmxdevfilter->buffer.error = ret;414	if (dmxdevfilter->params.sec.flags & DMX_ONESHOT)415		dmxdevfilter->state = DMXDEV_STATE_DONE;416	spin_unlock(&dmxdevfilter->dev->lock);417	wake_up(&dmxdevfilter->buffer.queue);418	return 0;419}420 421static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,422				  const u8 *buffer2, size_t buffer2_len,423				  struct dmx_ts_feed *feed,424				  u32 *buffer_flags)425{426	struct dmxdev_filter *dmxdevfilter = feed->priv;427	struct dvb_ringbuffer *buffer;428#ifdef CONFIG_DVB_MMAP429	struct dvb_vb2_ctx *ctx;430#endif431	int ret;432 433	spin_lock(&dmxdevfilter->dev->lock);434	if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) {435		spin_unlock(&dmxdevfilter->dev->lock);436		return 0;437	}438 439	if (dmxdevfilter->params.pes.output == DMX_OUT_TAP ||440	    dmxdevfilter->params.pes.output == DMX_OUT_TSDEMUX_TAP) {441		buffer = &dmxdevfilter->buffer;442#ifdef CONFIG_DVB_MMAP443		ctx = &dmxdevfilter->vb2_ctx;444#endif445	} else {446		buffer = &dmxdevfilter->dev->dvr_buffer;447#ifdef CONFIG_DVB_MMAP448		ctx = &dmxdevfilter->dev->dvr_vb2_ctx;449#endif450	}451 452	if (dvb_vb2_is_streaming(ctx)) {453		ret = dvb_vb2_fill_buffer(ctx, buffer1, buffer1_len,454					  buffer_flags);455		if (ret == buffer1_len)456			ret = dvb_vb2_fill_buffer(ctx, buffer2, buffer2_len,457						  buffer_flags);458	} else {459		if (buffer->error) {460			spin_unlock(&dmxdevfilter->dev->lock);461			wake_up(&buffer->queue);462			return 0;463		}464		ret = dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len);465		if (ret == buffer1_len)466			ret = dvb_dmxdev_buffer_write(buffer,467						      buffer2, buffer2_len);468	}469	if (ret < 0)470		buffer->error = ret;471	spin_unlock(&dmxdevfilter->dev->lock);472	wake_up(&buffer->queue);473	return 0;474}475 476/* stop feed but only mark the specified filter as stopped (state set) */477static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter)478{479	struct dmxdev_feed *feed;480 481	dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);482 483	switch (dmxdevfilter->type) {484	case DMXDEV_TYPE_SEC:485		del_timer(&dmxdevfilter->timer);486		dmxdevfilter->feed.sec->stop_filtering(dmxdevfilter->feed.sec);487		break;488	case DMXDEV_TYPE_PES:489		list_for_each_entry(feed, &dmxdevfilter->feed.ts, next)490			feed->ts->stop_filtering(feed->ts);491		break;492	default:493		return -EINVAL;494	}495	return 0;496}497 498/* start feed associated with the specified filter */499static int dvb_dmxdev_feed_start(struct dmxdev_filter *filter)500{501	struct dmxdev_feed *feed;502	int ret;503 504	dvb_dmxdev_filter_state_set(filter, DMXDEV_STATE_GO);505 506	switch (filter->type) {507	case DMXDEV_TYPE_SEC:508		return filter->feed.sec->start_filtering(filter->feed.sec);509	case DMXDEV_TYPE_PES:510		list_for_each_entry(feed, &filter->feed.ts, next) {511			ret = feed->ts->start_filtering(feed->ts);512			if (ret < 0) {513				dvb_dmxdev_feed_stop(filter);514				return ret;515			}516		}517		break;518	default:519		return -EINVAL;520	}521 522	return 0;523}524 525/* restart section feed if it has filters left associated with it,526   otherwise release the feed */527static int dvb_dmxdev_feed_restart(struct dmxdev_filter *filter)528{529	int i;530	struct dmxdev *dmxdev = filter->dev;531	u16 pid = filter->params.sec.pid;532 533	for (i = 0; i < dmxdev->filternum; i++)534		if (dmxdev->filter[i].state >= DMXDEV_STATE_GO &&535		    dmxdev->filter[i].type == DMXDEV_TYPE_SEC &&536		    dmxdev->filter[i].params.sec.pid == pid) {537			dvb_dmxdev_feed_start(&dmxdev->filter[i]);538			return 0;539		}540 541	filter->dev->demux->release_section_feed(dmxdev->demux,542						 filter->feed.sec);543 544	return 0;545}546 547static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter)548{549	struct dmxdev_feed *feed;550	struct dmx_demux *demux;551 552	if (dmxdevfilter->state < DMXDEV_STATE_GO)553		return 0;554 555	switch (dmxdevfilter->type) {556	case DMXDEV_TYPE_SEC:557		if (!dmxdevfilter->feed.sec)558			break;559		dvb_dmxdev_feed_stop(dmxdevfilter);560		if (dmxdevfilter->filter.sec)561			dmxdevfilter->feed.sec->562			    release_filter(dmxdevfilter->feed.sec,563					   dmxdevfilter->filter.sec);564		dvb_dmxdev_feed_restart(dmxdevfilter);565		dmxdevfilter->feed.sec = NULL;566		break;567	case DMXDEV_TYPE_PES:568		dvb_dmxdev_feed_stop(dmxdevfilter);569		demux = dmxdevfilter->dev->demux;570		list_for_each_entry(feed, &dmxdevfilter->feed.ts, next) {571			demux->release_ts_feed(demux, feed->ts);572			feed->ts = NULL;573		}574		break;575	default:576		if (dmxdevfilter->state == DMXDEV_STATE_ALLOCATED)577			return 0;578		return -EINVAL;579	}580 581	dvb_ringbuffer_flush(&dmxdevfilter->buffer);582	return 0;583}584 585static void dvb_dmxdev_delete_pids(struct dmxdev_filter *dmxdevfilter)586{587	struct dmxdev_feed *feed, *tmp;588 589	/* delete all PIDs */590	list_for_each_entry_safe(feed, tmp, &dmxdevfilter->feed.ts, next) {591		list_del(&feed->next);592		kfree(feed);593	}594 595	BUG_ON(!list_empty(&dmxdevfilter->feed.ts));596}597 598static inline int dvb_dmxdev_filter_reset(struct dmxdev_filter *dmxdevfilter)599{600	if (dmxdevfilter->state < DMXDEV_STATE_SET)601		return 0;602 603	if (dmxdevfilter->type == DMXDEV_TYPE_PES)604		dvb_dmxdev_delete_pids(dmxdevfilter);605 606	dmxdevfilter->type = DMXDEV_TYPE_NONE;607	dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);608	return 0;609}610 611static int dvb_dmxdev_start_feed(struct dmxdev *dmxdev,612				 struct dmxdev_filter *filter,613				 struct dmxdev_feed *feed)614{615	ktime_t timeout = ktime_set(0, 0);616	struct dmx_pes_filter_params *para = &filter->params.pes;617	enum dmx_output otype;618	int ret;619	int ts_type;620	enum dmx_ts_pes ts_pes;621	struct dmx_ts_feed *tsfeed;622 623	feed->ts = NULL;624	otype = para->output;625 626	ts_pes = para->pes_type;627 628	if (ts_pes < DMX_PES_OTHER)629		ts_type = TS_DECODER;630	else631		ts_type = 0;632 633	if (otype == DMX_OUT_TS_TAP)634		ts_type |= TS_PACKET;635	else if (otype == DMX_OUT_TSDEMUX_TAP)636		ts_type |= TS_PACKET | TS_DEMUX;637	else if (otype == DMX_OUT_TAP)638		ts_type |= TS_PACKET | TS_DEMUX | TS_PAYLOAD_ONLY;639 640	ret = dmxdev->demux->allocate_ts_feed(dmxdev->demux, &feed->ts,641					      dvb_dmxdev_ts_callback);642	if (ret < 0)643		return ret;644 645	tsfeed = feed->ts;646	tsfeed->priv = filter;647 648	ret = tsfeed->set(tsfeed, feed->pid, ts_type, ts_pes, timeout);649	if (ret < 0) {650		dmxdev->demux->release_ts_feed(dmxdev->demux, tsfeed);651		return ret;652	}653 654	ret = tsfeed->start_filtering(tsfeed);655	if (ret < 0) {656		dmxdev->demux->release_ts_feed(dmxdev->demux, tsfeed);657		return ret;658	}659 660	return 0;661}662 663static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)664{665	struct dmxdev *dmxdev = filter->dev;666	struct dmxdev_feed *feed;667	void *mem;668	int ret, i;669 670	if (filter->state < DMXDEV_STATE_SET)671		return -EINVAL;672 673	if (filter->state >= DMXDEV_STATE_GO)674		dvb_dmxdev_filter_stop(filter);675 676	if (!filter->buffer.data) {677		mem = vmalloc(filter->buffer.size);678		if (!mem)679			return -ENOMEM;680		spin_lock_irq(&filter->dev->lock);681		filter->buffer.data = mem;682		spin_unlock_irq(&filter->dev->lock);683	}684 685	dvb_ringbuffer_flush(&filter->buffer);686 687	switch (filter->type) {688	case DMXDEV_TYPE_SEC:689	{690		struct dmx_sct_filter_params *para = &filter->params.sec;691		struct dmx_section_filter **secfilter = &filter->filter.sec;692		struct dmx_section_feed **secfeed = &filter->feed.sec;693 694		*secfilter = NULL;695		*secfeed = NULL;696 697 698		/* find active filter/feed with same PID */699		for (i = 0; i < dmxdev->filternum; i++) {700			if (dmxdev->filter[i].state >= DMXDEV_STATE_GO &&701			    dmxdev->filter[i].type == DMXDEV_TYPE_SEC &&702			    dmxdev->filter[i].params.sec.pid == para->pid) {703				*secfeed = dmxdev->filter[i].feed.sec;704				break;705			}706		}707 708		/* if no feed found, try to allocate new one */709		if (!*secfeed) {710			ret = dmxdev->demux->allocate_section_feed(dmxdev->demux,711								   secfeed,712								   dvb_dmxdev_section_callback);713			if (!*secfeed) {714				pr_err("DVB (%s): could not alloc feed\n",715				       __func__);716				return ret;717			}718 719			ret = (*secfeed)->set(*secfeed, para->pid,720					      (para->flags & DMX_CHECK_CRC) ? 1 : 0);721			if (ret < 0) {722				pr_err("DVB (%s): could not set feed\n",723				       __func__);724				dvb_dmxdev_feed_restart(filter);725				return ret;726			}727		} else {728			dvb_dmxdev_feed_stop(filter);729		}730 731		ret = (*secfeed)->allocate_filter(*secfeed, secfilter);732		if (ret < 0) {733			dvb_dmxdev_feed_restart(filter);734			filter->feed.sec->start_filtering(*secfeed);735			dprintk("could not get filter\n");736			return ret;737		}738 739		(*secfilter)->priv = filter;740 741		memcpy(&((*secfilter)->filter_value[3]),742		       &(para->filter.filter[1]), DMX_FILTER_SIZE - 1);743		memcpy(&(*secfilter)->filter_mask[3],744		       &para->filter.mask[1], DMX_FILTER_SIZE - 1);745		memcpy(&(*secfilter)->filter_mode[3],746		       &para->filter.mode[1], DMX_FILTER_SIZE - 1);747 748		(*secfilter)->filter_value[0] = para->filter.filter[0];749		(*secfilter)->filter_mask[0] = para->filter.mask[0];750		(*secfilter)->filter_mode[0] = para->filter.mode[0];751		(*secfilter)->filter_mask[1] = 0;752		(*secfilter)->filter_mask[2] = 0;753 754		filter->todo = 0;755 756		ret = filter->feed.sec->start_filtering(filter->feed.sec);757		if (ret < 0)758			return ret;759 760		dvb_dmxdev_filter_timer(filter);761		break;762	}763	case DMXDEV_TYPE_PES:764		list_for_each_entry(feed, &filter->feed.ts, next) {765			ret = dvb_dmxdev_start_feed(dmxdev, filter, feed);766			if (ret < 0) {767				dvb_dmxdev_filter_stop(filter);768				return ret;769			}770		}771		break;772	default:773		return -EINVAL;774	}775 776	dvb_dmxdev_filter_state_set(filter, DMXDEV_STATE_GO);777	return 0;778}779 780static int dvb_demux_open(struct inode *inode, struct file *file)781{782	struct dvb_device *dvbdev = file->private_data;783	struct dmxdev *dmxdev = dvbdev->priv;784	int i;785	struct dmxdev_filter *dmxdevfilter;786 787	if (!dmxdev->filter)788		return -EINVAL;789 790	if (mutex_lock_interruptible(&dmxdev->mutex))791		return -ERESTARTSYS;792 793	if (dmxdev->exit) {794		mutex_unlock(&dmxdev->mutex);795		return -ENODEV;796	}797 798	for (i = 0; i < dmxdev->filternum; i++)799		if (dmxdev->filter[i].state == DMXDEV_STATE_FREE)800			break;801 802	if (i == dmxdev->filternum) {803		mutex_unlock(&dmxdev->mutex);804		return -EMFILE;805	}806 807	dmxdevfilter = &dmxdev->filter[i];808	mutex_init(&dmxdevfilter->mutex);809	file->private_data = dmxdevfilter;810 811#ifdef CONFIG_DVB_MMAP812	dmxdev->may_do_mmap = 1;813#else814	dmxdev->may_do_mmap = 0;815#endif816 817	dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192);818	dvb_vb2_init(&dmxdevfilter->vb2_ctx, "demux_filter",819		     file->f_flags & O_NONBLOCK);820	dmxdevfilter->type = DMXDEV_TYPE_NONE;821	dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);822	timer_setup(&dmxdevfilter->timer, dvb_dmxdev_filter_timeout, 0);823 824	dvbdev->users++;825 826	mutex_unlock(&dmxdev->mutex);827	return 0;828}829 830static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev,831				  struct dmxdev_filter *dmxdevfilter)832{833	mutex_lock(&dmxdev->mutex);834	mutex_lock(&dmxdevfilter->mutex);835	if (dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx))836		dvb_vb2_stream_off(&dmxdevfilter->vb2_ctx);837	dvb_vb2_release(&dmxdevfilter->vb2_ctx);838 839 840	dvb_dmxdev_filter_stop(dmxdevfilter);841	dvb_dmxdev_filter_reset(dmxdevfilter);842 843	if (dmxdevfilter->buffer.data) {844		void *mem = dmxdevfilter->buffer.data;845 846		spin_lock_irq(&dmxdev->lock);847		dmxdevfilter->buffer.data = NULL;848		spin_unlock_irq(&dmxdev->lock);849		vfree(mem);850	}851 852	dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_FREE);853	wake_up(&dmxdevfilter->buffer.queue);854	mutex_unlock(&dmxdevfilter->mutex);855	mutex_unlock(&dmxdev->mutex);856	return 0;857}858 859static inline void invert_mode(struct dmx_filter *filter)860{861	int i;862 863	for (i = 0; i < DMX_FILTER_SIZE; i++)864		filter->mode[i] ^= 0xff;865}866 867static int dvb_dmxdev_add_pid(struct dmxdev *dmxdev,868			      struct dmxdev_filter *filter, u16 pid)869{870	struct dmxdev_feed *feed;871 872	if ((filter->type != DMXDEV_TYPE_PES) ||873	    (filter->state < DMXDEV_STATE_SET))874		return -EINVAL;875 876	/* only TS packet filters may have multiple PIDs */877	if ((filter->params.pes.output != DMX_OUT_TSDEMUX_TAP) &&878	    (!list_empty(&filter->feed.ts)))879		return -EINVAL;880 881	feed = kzalloc(sizeof(struct dmxdev_feed), GFP_KERNEL);882	if (feed == NULL)883		return -ENOMEM;884 885	feed->pid = pid;886	list_add(&feed->next, &filter->feed.ts);887 888	if (filter->state >= DMXDEV_STATE_GO)889		return dvb_dmxdev_start_feed(dmxdev, filter, feed);890 891	return 0;892}893 894static int dvb_dmxdev_remove_pid(struct dmxdev *dmxdev,895				  struct dmxdev_filter *filter, u16 pid)896{897	struct dmxdev_feed *feed, *tmp;898 899	if ((filter->type != DMXDEV_TYPE_PES) ||900	    (filter->state < DMXDEV_STATE_SET))901		return -EINVAL;902 903	list_for_each_entry_safe(feed, tmp, &filter->feed.ts, next) {904		if ((feed->pid == pid) && (feed->ts != NULL)) {905			feed->ts->stop_filtering(feed->ts);906			filter->dev->demux->release_ts_feed(filter->dev->demux,907							    feed->ts);908			list_del(&feed->next);909			kfree(feed);910		}911	}912 913	return 0;914}915 916static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev,917				 struct dmxdev_filter *dmxdevfilter,918				 struct dmx_sct_filter_params *params)919{920	dprintk("%s: PID=0x%04x, flags=%02x, timeout=%d\n",921		__func__, params->pid, params->flags, params->timeout);922 923	dvb_dmxdev_filter_stop(dmxdevfilter);924 925	dmxdevfilter->type = DMXDEV_TYPE_SEC;926	memcpy(&dmxdevfilter->params.sec,927	       params, sizeof(struct dmx_sct_filter_params));928	invert_mode(&dmxdevfilter->params.sec.filter);929	dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);930 931	if (params->flags & DMX_IMMEDIATE_START)932		return dvb_dmxdev_filter_start(dmxdevfilter);933 934	return 0;935}936 937static int dvb_dmxdev_pes_filter_set(struct dmxdev *dmxdev,938				     struct dmxdev_filter *dmxdevfilter,939				     struct dmx_pes_filter_params *params)940{941	int ret;942 943	dvb_dmxdev_filter_stop(dmxdevfilter);944	dvb_dmxdev_filter_reset(dmxdevfilter);945 946	if ((unsigned int)params->pes_type > DMX_PES_OTHER)947		return -EINVAL;948 949	dmxdevfilter->type = DMXDEV_TYPE_PES;950	memcpy(&dmxdevfilter->params, params,951	       sizeof(struct dmx_pes_filter_params));952	INIT_LIST_HEAD(&dmxdevfilter->feed.ts);953 954	dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);955 956	ret = dvb_dmxdev_add_pid(dmxdev, dmxdevfilter,957				 dmxdevfilter->params.pes.pid);958	if (ret < 0)959		return ret;960 961	if (params->flags & DMX_IMMEDIATE_START)962		return dvb_dmxdev_filter_start(dmxdevfilter);963 964	return 0;965}966 967static ssize_t dvb_dmxdev_read_sec(struct dmxdev_filter *dfil,968				   struct file *file, char __user *buf,969				   size_t count, loff_t *ppos)970{971	int result, hcount;972	int done = 0;973 974	if (dfil->todo <= 0) {975		hcount = 3 + dfil->todo;976		if (hcount > count)977			hcount = count;978		result = dvb_dmxdev_buffer_read(&dfil->buffer,979						file->f_flags & O_NONBLOCK,980						buf, hcount, ppos);981		if (result < 0) {982			dfil->todo = 0;983			return result;984		}985		if (copy_from_user(dfil->secheader - dfil->todo, buf, result))986			return -EFAULT;987		buf += result;988		done = result;989		count -= result;990		dfil->todo -= result;991		if (dfil->todo > -3)992			return done;993		dfil->todo = ((dfil->secheader[1] << 8) | dfil->secheader[2]) & 0xfff;994		if (!count)995			return done;996	}997	if (count > dfil->todo)998		count = dfil->todo;999	result = dvb_dmxdev_buffer_read(&dfil->buffer,1000					file->f_flags & O_NONBLOCK,1001					buf, count, ppos);1002	if (result < 0)1003		return result;1004	dfil->todo -= result;1005	return (result + done);1006}1007 1008static ssize_t1009dvb_demux_read(struct file *file, char __user *buf, size_t count,1010	       loff_t *ppos)1011{1012	struct dmxdev_filter *dmxdevfilter = file->private_data;1013	int ret;1014 1015	if (mutex_lock_interruptible(&dmxdevfilter->mutex))1016		return -ERESTARTSYS;1017 1018	if (dmxdevfilter->type == DMXDEV_TYPE_SEC)1019		ret = dvb_dmxdev_read_sec(dmxdevfilter, file, buf, count, ppos);1020	else1021		ret = dvb_dmxdev_buffer_read(&dmxdevfilter->buffer,1022					     file->f_flags & O_NONBLOCK,1023					     buf, count, ppos);1024 1025	mutex_unlock(&dmxdevfilter->mutex);1026	return ret;1027}1028 1029static int dvb_demux_do_ioctl(struct file *file,1030			      unsigned int cmd, void *parg)1031{1032	struct dmxdev_filter *dmxdevfilter = file->private_data;1033	struct dmxdev *dmxdev = dmxdevfilter->dev;1034	unsigned long arg = (unsigned long)parg;1035	int ret = 0;1036 1037	if (mutex_lock_interruptible(&dmxdev->mutex))1038		return -ERESTARTSYS;1039 1040	switch (cmd) {1041	case DMX_START:1042		if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {1043			mutex_unlock(&dmxdev->mutex);1044			return -ERESTARTSYS;1045		}1046		if (dmxdevfilter->state < DMXDEV_STATE_SET)1047			ret = -EINVAL;1048		else1049			ret = dvb_dmxdev_filter_start(dmxdevfilter);1050		mutex_unlock(&dmxdevfilter->mutex);1051		break;1052 1053	case DMX_STOP:1054		if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {1055			mutex_unlock(&dmxdev->mutex);1056			return -ERESTARTSYS;1057		}1058		ret = dvb_dmxdev_filter_stop(dmxdevfilter);1059		mutex_unlock(&dmxdevfilter->mutex);1060		break;1061 1062	case DMX_SET_FILTER:1063		if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {1064			mutex_unlock(&dmxdev->mutex);1065			return -ERESTARTSYS;1066		}1067		ret = dvb_dmxdev_filter_set(dmxdev, dmxdevfilter, parg);1068		mutex_unlock(&dmxdevfilter->mutex);1069		break;1070 1071	case DMX_SET_PES_FILTER:1072		if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {1073			mutex_unlock(&dmxdev->mutex);1074			return -ERESTARTSYS;1075		}1076		ret = dvb_dmxdev_pes_filter_set(dmxdev, dmxdevfilter, parg);1077		mutex_unlock(&dmxdevfilter->mutex);1078		break;1079 1080	case DMX_SET_BUFFER_SIZE:1081		if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {1082			mutex_unlock(&dmxdev->mutex);1083			return -ERESTARTSYS;1084		}1085		ret = dvb_dmxdev_set_buffer_size(dmxdevfilter, arg);1086		mutex_unlock(&dmxdevfilter->mutex);1087		break;1088 1089	case DMX_GET_PES_PIDS:1090		if (!dmxdev->demux->get_pes_pids) {1091			ret = -EINVAL;1092			break;1093		}1094		dmxdev->demux->get_pes_pids(dmxdev->demux, parg);1095		break;1096 1097	case DMX_GET_STC:1098		if (!dmxdev->demux->get_stc) {1099			ret = -EINVAL;1100			break;1101		}1102		ret = dmxdev->demux->get_stc(dmxdev->demux,1103					     ((struct dmx_stc *)parg)->num,1104					     &((struct dmx_stc *)parg)->stc,1105					     &((struct dmx_stc *)parg)->base);1106		break;1107 1108	case DMX_ADD_PID:1109		if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {1110			ret = -ERESTARTSYS;1111			break;1112		}1113		ret = dvb_dmxdev_add_pid(dmxdev, dmxdevfilter, *(u16 *)parg);1114		mutex_unlock(&dmxdevfilter->mutex);1115		break;1116 1117	case DMX_REMOVE_PID:1118		if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {1119			ret = -ERESTARTSYS;1120			break;1121		}1122		ret = dvb_dmxdev_remove_pid(dmxdev, dmxdevfilter, *(u16 *)parg);1123		mutex_unlock(&dmxdevfilter->mutex);1124		break;1125 1126#ifdef CONFIG_DVB_MMAP1127	case DMX_REQBUFS:1128		if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {1129			mutex_unlock(&dmxdev->mutex);1130			return -ERESTARTSYS;1131		}1132		ret = dvb_vb2_reqbufs(&dmxdevfilter->vb2_ctx, parg);1133		mutex_unlock(&dmxdevfilter->mutex);1134		break;1135 1136	case DMX_QUERYBUF:1137		if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {1138			mutex_unlock(&dmxdev->mutex);1139			return -ERESTARTSYS;1140		}1141		ret = dvb_vb2_querybuf(&dmxdevfilter->vb2_ctx, parg);1142		mutex_unlock(&dmxdevfilter->mutex);1143		break;1144 1145	case DMX_EXPBUF:1146		if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {1147			mutex_unlock(&dmxdev->mutex);1148			return -ERESTARTSYS;1149		}1150		ret = dvb_vb2_expbuf(&dmxdevfilter->vb2_ctx, parg);1151		mutex_unlock(&dmxdevfilter->mutex);1152		break;1153 1154	case DMX_QBUF:1155		if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {1156			mutex_unlock(&dmxdev->mutex);1157			return -ERESTARTSYS;1158		}1159		ret = dvb_vb2_qbuf(&dmxdevfilter->vb2_ctx, parg);1160		if (ret == 0 && !dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx))1161			ret = dvb_vb2_stream_on(&dmxdevfilter->vb2_ctx);1162		mutex_unlock(&dmxdevfilter->mutex);1163		break;1164 1165	case DMX_DQBUF:1166		if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {1167			mutex_unlock(&dmxdev->mutex);1168			return -ERESTARTSYS;1169		}1170		ret = dvb_vb2_dqbuf(&dmxdevfilter->vb2_ctx, parg);1171		mutex_unlock(&dmxdevfilter->mutex);1172		break;1173#endif1174	default:1175		ret = -ENOTTY;1176		break;1177	}1178	mutex_unlock(&dmxdev->mutex);1179	return ret;1180}1181 1182static long dvb_demux_ioctl(struct file *file, unsigned int cmd,1183			    unsigned long arg)1184{1185	return dvb_usercopy(file, cmd, arg, dvb_demux_do_ioctl);1186}1187 1188static __poll_t dvb_demux_poll(struct file *file, poll_table *wait)1189{1190	struct dmxdev_filter *dmxdevfilter = file->private_data;1191	__poll_t mask = 0;1192 1193	poll_wait(file, &dmxdevfilter->buffer.queue, wait);1194 1195	if ((!dmxdevfilter) || dmxdevfilter->dev->exit)1196		return EPOLLERR;1197	if (dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx))1198		return dvb_vb2_poll(&dmxdevfilter->vb2_ctx, file, wait);1199 1200	if (dmxdevfilter->state != DMXDEV_STATE_GO &&1201	    dmxdevfilter->state != DMXDEV_STATE_DONE &&1202	    dmxdevfilter->state != DMXDEV_STATE_TIMEDOUT)1203		return 0;1204 1205	if (dmxdevfilter->buffer.error)1206		mask |= (EPOLLIN | EPOLLRDNORM | EPOLLPRI | EPOLLERR);1207 1208	if (!dvb_ringbuffer_empty(&dmxdevfilter->buffer))1209		mask |= (EPOLLIN | EPOLLRDNORM | EPOLLPRI);1210 1211	return mask;1212}1213 1214#ifdef CONFIG_DVB_MMAP1215static int dvb_demux_mmap(struct file *file, struct vm_area_struct *vma)1216{1217	struct dmxdev_filter *dmxdevfilter = file->private_data;1218	struct dmxdev *dmxdev = dmxdevfilter->dev;1219	int ret;1220 1221	if (!dmxdev->may_do_mmap)1222		return -ENOTTY;1223 1224	if (mutex_lock_interruptible(&dmxdev->mutex))1225		return -ERESTARTSYS;1226 1227	if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {1228		mutex_unlock(&dmxdev->mutex);1229		return -ERESTARTSYS;1230	}1231	ret = dvb_vb2_mmap(&dmxdevfilter->vb2_ctx, vma);1232 1233	mutex_unlock(&dmxdevfilter->mutex);1234	mutex_unlock(&dmxdev->mutex);1235 1236	return ret;1237}1238#endif1239 1240static int dvb_demux_release(struct inode *inode, struct file *file)1241{1242	struct dmxdev_filter *dmxdevfilter = file->private_data;1243	struct dmxdev *dmxdev = dmxdevfilter->dev;1244	int ret;1245 1246	ret = dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);1247 1248	mutex_lock(&dmxdev->mutex);1249	dmxdev->dvbdev->users--;1250	if (dmxdev->dvbdev->users == 1 && dmxdev->exit == 1) {1251		mutex_unlock(&dmxdev->mutex);1252		wake_up(&dmxdev->dvbdev->wait_queue);1253	} else1254		mutex_unlock(&dmxdev->mutex);1255 1256	return ret;1257}1258 1259static const struct file_operations dvb_demux_fops = {1260	.owner = THIS_MODULE,1261	.read = dvb_demux_read,1262	.unlocked_ioctl = dvb_demux_ioctl,1263	.compat_ioctl = dvb_demux_ioctl,1264	.open = dvb_demux_open,1265	.release = dvb_demux_release,1266	.poll = dvb_demux_poll,1267	.llseek = default_llseek,1268#ifdef CONFIG_DVB_MMAP1269	.mmap = dvb_demux_mmap,1270#endif1271};1272 1273static const struct dvb_device dvbdev_demux = {1274	.priv = NULL,1275	.users = 1,1276	.writers = 1,1277#if defined(CONFIG_MEDIA_CONTROLLER_DVB)1278	.name = "dvb-demux",1279#endif1280	.fops = &dvb_demux_fops1281};1282 1283static int dvb_dvr_do_ioctl(struct file *file,1284			    unsigned int cmd, void *parg)1285{1286	struct dvb_device *dvbdev = file->private_data;1287	struct dmxdev *dmxdev = dvbdev->priv;1288	unsigned long arg = (unsigned long)parg;1289	int ret;1290 1291	if (mutex_lock_interruptible(&dmxdev->mutex))1292		return -ERESTARTSYS;1293 1294	switch (cmd) {1295	case DMX_SET_BUFFER_SIZE:1296		ret = dvb_dvr_set_buffer_size(dmxdev, arg);1297		break;1298 1299#ifdef CONFIG_DVB_MMAP1300	case DMX_REQBUFS:1301		ret = dvb_vb2_reqbufs(&dmxdev->dvr_vb2_ctx, parg);1302		break;1303 1304	case DMX_QUERYBUF:1305		ret = dvb_vb2_querybuf(&dmxdev->dvr_vb2_ctx, parg);1306		break;1307 1308	case DMX_EXPBUF:1309		ret = dvb_vb2_expbuf(&dmxdev->dvr_vb2_ctx, parg);1310		break;1311 1312	case DMX_QBUF:1313		ret = dvb_vb2_qbuf(&dmxdev->dvr_vb2_ctx, parg);1314		if (ret == 0 && !dvb_vb2_is_streaming(&dmxdev->dvr_vb2_ctx))1315			ret = dvb_vb2_stream_on(&dmxdev->dvr_vb2_ctx);1316		break;1317 1318	case DMX_DQBUF:1319		ret = dvb_vb2_dqbuf(&dmxdev->dvr_vb2_ctx, parg);1320		break;1321#endif1322	default:1323		ret = -ENOTTY;1324		break;1325	}1326	mutex_unlock(&dmxdev->mutex);1327	return ret;1328}1329 1330static long dvb_dvr_ioctl(struct file *file,1331			 unsigned int cmd, unsigned long arg)1332{1333	return dvb_usercopy(file, cmd, arg, dvb_dvr_do_ioctl);1334}1335 1336static __poll_t dvb_dvr_poll(struct file *file, poll_table *wait)1337{1338	struct dvb_device *dvbdev = file->private_data;1339	struct dmxdev *dmxdev = dvbdev->priv;1340	__poll_t mask = 0;1341 1342	dprintk("%s\n", __func__);1343 1344	poll_wait(file, &dmxdev->dvr_buffer.queue, wait);1345 1346	if (dmxdev->exit)1347		return EPOLLERR;1348	if (dvb_vb2_is_streaming(&dmxdev->dvr_vb2_ctx))1349		return dvb_vb2_poll(&dmxdev->dvr_vb2_ctx, file, wait);1350 1351	if (((file->f_flags & O_ACCMODE) == O_RDONLY) ||1352	    dmxdev->may_do_mmap) {1353		if (dmxdev->dvr_buffer.error)1354			mask |= (EPOLLIN | EPOLLRDNORM | EPOLLPRI | EPOLLERR);1355 1356		if (!dvb_ringbuffer_empty(&dmxdev->dvr_buffer))1357			mask |= (EPOLLIN | EPOLLRDNORM | EPOLLPRI);1358	} else1359		mask |= (EPOLLOUT | EPOLLWRNORM | EPOLLPRI);1360 1361	return mask;1362}1363 1364#ifdef CONFIG_DVB_MMAP1365static int dvb_dvr_mmap(struct file *file, struct vm_area_struct *vma)1366{1367	struct dvb_device *dvbdev = file->private_data;1368	struct dmxdev *dmxdev = dvbdev->priv;1369	int ret;1370 1371	if (!dmxdev->may_do_mmap)1372		return -ENOTTY;1373 1374	if (dmxdev->exit)1375		return -ENODEV;1376 1377	if (mutex_lock_interruptible(&dmxdev->mutex))1378		return -ERESTARTSYS;1379 1380	ret = dvb_vb2_mmap(&dmxdev->dvr_vb2_ctx, vma);1381	mutex_unlock(&dmxdev->mutex);1382	return ret;1383}1384#endif1385 1386static const struct file_operations dvb_dvr_fops = {1387	.owner = THIS_MODULE,1388	.read = dvb_dvr_read,1389	.write = dvb_dvr_write,1390	.unlocked_ioctl = dvb_dvr_ioctl,1391	.open = dvb_dvr_open,1392	.release = dvb_dvr_release,1393	.poll = dvb_dvr_poll,1394	.llseek = default_llseek,1395#ifdef CONFIG_DVB_MMAP1396	.mmap = dvb_dvr_mmap,1397#endif1398};1399 1400static const struct dvb_device dvbdev_dvr = {1401	.priv = NULL,1402	.readers = 1,1403	.users = 1,1404#if defined(CONFIG_MEDIA_CONTROLLER_DVB)1405	.name = "dvb-dvr",1406#endif1407	.fops = &dvb_dvr_fops1408};1409int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)1410{1411	int i, ret;1412 1413	if (dmxdev->demux->open(dmxdev->demux) < 0)1414		return -EUSERS;1415 1416	dmxdev->filter = vmalloc(array_size(sizeof(struct dmxdev_filter),1417					    dmxdev->filternum));1418	if (!dmxdev->filter)1419		return -ENOMEM;1420 1421	mutex_init(&dmxdev->mutex);1422	spin_lock_init(&dmxdev->lock);1423	for (i = 0; i < dmxdev->filternum; i++) {1424		dmxdev->filter[i].dev = dmxdev;1425		dmxdev->filter[i].buffer.data = NULL;1426		dvb_dmxdev_filter_state_set(&dmxdev->filter[i],1427					    DMXDEV_STATE_FREE);1428	}1429 1430	ret = dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev,1431			    DVB_DEVICE_DEMUX, dmxdev->filternum);1432	if (ret < 0)1433		goto err_register_dvbdev;1434 1435	ret = dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr,1436			    dmxdev, DVB_DEVICE_DVR, dmxdev->filternum);1437	if (ret < 0)1438		goto err_register_dvr_dvbdev;1439 1440	dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192);1441 1442	return 0;1443 1444err_register_dvr_dvbdev:1445	dvb_unregister_device(dmxdev->dvbdev);1446err_register_dvbdev:1447	vfree(dmxdev->filter);1448	dmxdev->filter = NULL;1449	return ret;1450}1451 1452EXPORT_SYMBOL(dvb_dmxdev_init);1453 1454void dvb_dmxdev_release(struct dmxdev *dmxdev)1455{1456	mutex_lock(&dmxdev->mutex);1457	dmxdev->exit = 1;1458	mutex_unlock(&dmxdev->mutex);1459 1460	if (dmxdev->dvbdev->users > 1) {1461		wait_event(dmxdev->dvbdev->wait_queue,1462				dmxdev->dvbdev->users == 1);1463	}1464	if (dmxdev->dvr_dvbdev->users > 1) {1465		wait_event(dmxdev->dvr_dvbdev->wait_queue,1466				dmxdev->dvr_dvbdev->users == 1);1467	}1468 1469	dvb_unregister_device(dmxdev->dvbdev);1470	dvb_unregister_device(dmxdev->dvr_dvbdev);1471 1472	vfree(dmxdev->filter);1473	dmxdev->filter = NULL;1474	dmxdev->demux->close(dmxdev->demux);1475}1476 1477EXPORT_SYMBOL(dvb_dmxdev_release);1478