cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cx18-fileops.c (25258B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  cx18 file operation functions
      4 *
      5 *  Derived from ivtv-fileops.c
      6 *
      7 *  Copyright (C) 2007  Hans Verkuil <hverkuil@xs4all.nl>
      8 *  Copyright (C) 2008  Andy Walls <awalls@md.metrocast.net>
      9 */
     10
     11#include "cx18-driver.h"
     12#include "cx18-fileops.h"
     13#include "cx18-i2c.h"
     14#include "cx18-queue.h"
     15#include "cx18-vbi.h"
     16#include "cx18-audio.h"
     17#include "cx18-mailbox.h"
     18#include "cx18-scb.h"
     19#include "cx18-streams.h"
     20#include "cx18-controls.h"
     21#include "cx18-ioctl.h"
     22#include "cx18-cards.h"
     23#include <media/v4l2-event.h>
     24
     25/* This function tries to claim the stream for a specific file descriptor.
     26   If no one else is using this stream then the stream is claimed and
     27   associated VBI and IDX streams are also automatically claimed.
     28   Possible error returns: -EBUSY if someone else has claimed
     29   the stream or 0 on success. */
     30int cx18_claim_stream(struct cx18_open_id *id, int type)
     31{
     32	struct cx18 *cx = id->cx;
     33	struct cx18_stream *s = &cx->streams[type];
     34	struct cx18_stream *s_assoc;
     35
     36	/* Nothing should ever try to directly claim the IDX stream */
     37	if (type == CX18_ENC_STREAM_TYPE_IDX) {
     38		CX18_WARN("MPEG Index stream cannot be claimed directly, but something tried.\n");
     39		return -EINVAL;
     40	}
     41
     42	if (test_and_set_bit(CX18_F_S_CLAIMED, &s->s_flags)) {
     43		/* someone already claimed this stream */
     44		if (s->id == id->open_id) {
     45			/* yes, this file descriptor did. So that's OK. */
     46			return 0;
     47		}
     48		if (s->id == -1 && type == CX18_ENC_STREAM_TYPE_VBI) {
     49			/* VBI is handled already internally, now also assign
     50			   the file descriptor to this stream for external
     51			   reading of the stream. */
     52			s->id = id->open_id;
     53			CX18_DEBUG_INFO("Start Read VBI\n");
     54			return 0;
     55		}
     56		/* someone else is using this stream already */
     57		CX18_DEBUG_INFO("Stream %d is busy\n", type);
     58		return -EBUSY;
     59	}
     60	s->id = id->open_id;
     61
     62	/*
     63	 * CX18_ENC_STREAM_TYPE_MPG needs to claim:
     64	 * CX18_ENC_STREAM_TYPE_VBI, if VBI insertion is on for sliced VBI, or
     65	 * CX18_ENC_STREAM_TYPE_IDX, if VBI insertion is off for sliced VBI
     66	 * (We don't yet fix up MPEG Index entries for our inserted packets).
     67	 *
     68	 * For all other streams we're done.
     69	 */
     70	if (type != CX18_ENC_STREAM_TYPE_MPG)
     71		return 0;
     72
     73	s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
     74	if (cx->vbi.insert_mpeg && !cx18_raw_vbi(cx))
     75		s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
     76	else if (!cx18_stream_enabled(s_assoc))
     77		return 0;
     78
     79	set_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
     80
     81	/* mark that it is used internally */
     82	set_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags);
     83	return 0;
     84}
     85EXPORT_SYMBOL(cx18_claim_stream);
     86
     87/* This function releases a previously claimed stream. It will take into
     88   account associated VBI streams. */
     89void cx18_release_stream(struct cx18_stream *s)
     90{
     91	struct cx18 *cx = s->cx;
     92	struct cx18_stream *s_assoc;
     93
     94	s->id = -1;
     95	if (s->type == CX18_ENC_STREAM_TYPE_IDX) {
     96		/*
     97		 * The IDX stream is only used internally, and can
     98		 * only be indirectly unclaimed by unclaiming the MPG stream.
     99		 */
    100		return;
    101	}
    102
    103	if (s->type == CX18_ENC_STREAM_TYPE_VBI &&
    104		test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags)) {
    105		/* this stream is still in use internally */
    106		return;
    107	}
    108	if (!test_and_clear_bit(CX18_F_S_CLAIMED, &s->s_flags)) {
    109		CX18_DEBUG_WARN("Release stream %s not in use!\n", s->name);
    110		return;
    111	}
    112
    113	cx18_flush_queues(s);
    114
    115	/*
    116	 * CX18_ENC_STREAM_TYPE_MPG needs to release the
    117	 * CX18_ENC_STREAM_TYPE_VBI and/or CX18_ENC_STREAM_TYPE_IDX streams.
    118	 *
    119	 * For all other streams we're done.
    120	 */
    121	if (s->type != CX18_ENC_STREAM_TYPE_MPG)
    122		return;
    123
    124	/* Unclaim the associated MPEG Index stream */
    125	s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
    126	if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
    127		clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
    128		cx18_flush_queues(s_assoc);
    129	}
    130
    131	/* Unclaim the associated VBI stream */
    132	s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
    133	if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
    134		if (s_assoc->id == -1) {
    135			/*
    136			 * The VBI stream is not still claimed by a file
    137			 * descriptor, so completely unclaim it.
    138			 */
    139			clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
    140			cx18_flush_queues(s_assoc);
    141		}
    142	}
    143}
    144EXPORT_SYMBOL(cx18_release_stream);
    145
    146static void cx18_dualwatch(struct cx18 *cx)
    147{
    148	struct v4l2_tuner vt;
    149	u32 new_stereo_mode;
    150	const u32 dual = 0x0200;
    151
    152	new_stereo_mode = v4l2_ctrl_g_ctrl(cx->cxhdl.audio_mode);
    153	memset(&vt, 0, sizeof(vt));
    154	cx18_call_all(cx, tuner, g_tuner, &vt);
    155	if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 &&
    156			(vt.rxsubchans & V4L2_TUNER_SUB_LANG2))
    157		new_stereo_mode = dual;
    158
    159	if (new_stereo_mode == cx->dualwatch_stereo_mode)
    160		return;
    161
    162	CX18_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x.\n",
    163			   cx->dualwatch_stereo_mode, new_stereo_mode);
    164	if (v4l2_ctrl_s_ctrl(cx->cxhdl.audio_mode, new_stereo_mode))
    165		CX18_DEBUG_INFO("dualwatch: changing stereo flag failed\n");
    166}
    167
    168
    169static struct cx18_mdl *cx18_get_mdl(struct cx18_stream *s, int non_block,
    170				     int *err)
    171{
    172	struct cx18 *cx = s->cx;
    173	struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
    174	struct cx18_mdl *mdl;
    175	DEFINE_WAIT(wait);
    176
    177	*err = 0;
    178	while (1) {
    179		if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
    180			/* Process pending program updates and VBI data */
    181			if (time_after(jiffies, cx->dualwatch_jiffies + msecs_to_jiffies(1000))) {
    182				cx->dualwatch_jiffies = jiffies;
    183				cx18_dualwatch(cx);
    184			}
    185			if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
    186			    !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
    187				while ((mdl = cx18_dequeue(s_vbi,
    188							   &s_vbi->q_full))) {
    189					/* byteswap and process VBI data */
    190					cx18_process_vbi_data(cx, mdl,
    191							      s_vbi->type);
    192					cx18_stream_put_mdl_fw(s_vbi, mdl);
    193				}
    194			}
    195			mdl = &cx->vbi.sliced_mpeg_mdl;
    196			if (mdl->readpos != mdl->bytesused)
    197				return mdl;
    198		}
    199
    200		/* do we have new data? */
    201		mdl = cx18_dequeue(s, &s->q_full);
    202		if (mdl) {
    203			if (!test_and_clear_bit(CX18_F_M_NEED_SWAP,
    204						&mdl->m_flags))
    205				return mdl;
    206			if (s->type == CX18_ENC_STREAM_TYPE_MPG)
    207				/* byteswap MPG data */
    208				cx18_mdl_swap(mdl);
    209			else {
    210				/* byteswap and process VBI data */
    211				cx18_process_vbi_data(cx, mdl, s->type);
    212			}
    213			return mdl;
    214		}
    215
    216		/* return if end of stream */
    217		if (!test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
    218			CX18_DEBUG_INFO("EOS %s\n", s->name);
    219			return NULL;
    220		}
    221
    222		/* return if file was opened with O_NONBLOCK */
    223		if (non_block) {
    224			*err = -EAGAIN;
    225			return NULL;
    226		}
    227
    228		/* wait for more data to arrive */
    229		prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
    230		/* New buffers might have become available before we were added
    231		   to the waitqueue */
    232		if (!atomic_read(&s->q_full.depth))
    233			schedule();
    234		finish_wait(&s->waitq, &wait);
    235		if (signal_pending(current)) {
    236			/* return if a signal was received */
    237			CX18_DEBUG_INFO("User stopped %s\n", s->name);
    238			*err = -EINTR;
    239			return NULL;
    240		}
    241	}
    242}
    243
    244static void cx18_setup_sliced_vbi_mdl(struct cx18 *cx)
    245{
    246	struct cx18_mdl *mdl = &cx->vbi.sliced_mpeg_mdl;
    247	struct cx18_buffer *buf = &cx->vbi.sliced_mpeg_buf;
    248	int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
    249
    250	buf->buf = cx->vbi.sliced_mpeg_data[idx];
    251	buf->bytesused = cx->vbi.sliced_mpeg_size[idx];
    252	buf->readpos = 0;
    253
    254	mdl->curr_buf = NULL;
    255	mdl->bytesused = cx->vbi.sliced_mpeg_size[idx];
    256	mdl->readpos = 0;
    257}
    258
    259static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
    260	struct cx18_buffer *buf, char __user *ubuf, size_t ucount, bool *stop)
    261{
    262	struct cx18 *cx = s->cx;
    263	size_t len = buf->bytesused - buf->readpos;
    264
    265	*stop = false;
    266	if (len > ucount)
    267		len = ucount;
    268	if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG &&
    269	    !cx18_raw_vbi(cx) && buf != &cx->vbi.sliced_mpeg_buf) {
    270		/*
    271		 * Try to find a good splice point in the PS, just before
    272		 * an MPEG-2 Program Pack start code, and provide only
    273		 * up to that point to the user, so it's easy to insert VBI data
    274		 * the next time around.
    275		 *
    276		 * This will not work for an MPEG-2 TS and has only been
    277		 * verified by analysis to work for an MPEG-2 PS.  Helen Buus
    278		 * pointed out this works for the CX23416 MPEG-2 DVD compatible
    279		 * stream, and research indicates both the MPEG 2 SVCD and DVD
    280		 * stream types use an MPEG-2 PS container.
    281		 */
    282		/*
    283		 * An MPEG-2 Program Stream (PS) is a series of
    284		 * MPEG-2 Program Packs terminated by an
    285		 * MPEG Program End Code after the last Program Pack.
    286		 * A Program Pack may hold a PS System Header packet and any
    287		 * number of Program Elementary Stream (PES) Packets
    288		 */
    289		const char *start = buf->buf + buf->readpos;
    290		const char *p = start + 1;
    291		const u8 *q;
    292		u8 ch = cx->search_pack_header ? 0xba : 0xe0;
    293		int stuffing, i;
    294
    295		while (start + len > p) {
    296			/* Scan for a 0 to find a potential MPEG-2 start code */
    297			q = memchr(p, 0, start + len - p);
    298			if (q == NULL)
    299				break;
    300			p = q + 1;
    301			/*
    302			 * Keep looking if not a
    303			 * MPEG-2 Pack header start code:  0x00 0x00 0x01 0xba
    304			 * or MPEG-2 video PES start code: 0x00 0x00 0x01 0xe0
    305			 */
    306			if ((char *)q + 15 >= buf->buf + buf->bytesused ||
    307			    q[1] != 0 || q[2] != 1 || q[3] != ch)
    308				continue;
    309
    310			/* If expecting the primary video PES */
    311			if (!cx->search_pack_header) {
    312				/* Continue if it couldn't be a PES packet */
    313				if ((q[6] & 0xc0) != 0x80)
    314					continue;
    315				/* Check if a PTS or PTS & DTS follow */
    316				if (((q[7] & 0xc0) == 0x80 &&  /* PTS only */
    317				     (q[9] & 0xf0) == 0x20) || /* PTS only */
    318				    ((q[7] & 0xc0) == 0xc0 &&  /* PTS & DTS */
    319				     (q[9] & 0xf0) == 0x30)) { /* DTS follows */
    320					/* Assume we found the video PES hdr */
    321					ch = 0xba; /* next want a Program Pack*/
    322					cx->search_pack_header = 1;
    323					p = q + 9; /* Skip this video PES hdr */
    324				}
    325				continue;
    326			}
    327
    328			/* We may have found a Program Pack start code */
    329
    330			/* Get the count of stuffing bytes & verify them */
    331			stuffing = q[13] & 7;
    332			/* all stuffing bytes must be 0xff */
    333			for (i = 0; i < stuffing; i++)
    334				if (q[14 + i] != 0xff)
    335					break;
    336			if (i == stuffing && /* right number of stuffing bytes*/
    337			    (q[4] & 0xc4) == 0x44 && /* marker check */
    338			    (q[12] & 3) == 3 &&  /* marker check */
    339			    q[14 + stuffing] == 0 && /* PES Pack or Sys Hdr */
    340			    q[15 + stuffing] == 0 &&
    341			    q[16 + stuffing] == 1) {
    342				/* We declare we actually found a Program Pack*/
    343				cx->search_pack_header = 0; /* expect vid PES */
    344				len = (char *)q - start;
    345				cx18_setup_sliced_vbi_mdl(cx);
    346				*stop = true;
    347				break;
    348			}
    349		}
    350	}
    351	if (copy_to_user(ubuf, (u8 *)buf->buf + buf->readpos, len)) {
    352		CX18_DEBUG_WARN("copy %zd bytes to user failed for %s\n",
    353				len, s->name);
    354		return -EFAULT;
    355	}
    356	buf->readpos += len;
    357	if (s->type == CX18_ENC_STREAM_TYPE_MPG &&
    358	    buf != &cx->vbi.sliced_mpeg_buf)
    359		cx->mpg_data_received += len;
    360	return len;
    361}
    362
    363static size_t cx18_copy_mdl_to_user(struct cx18_stream *s,
    364		struct cx18_mdl *mdl, char __user *ubuf, size_t ucount)
    365{
    366	size_t tot_written = 0;
    367	int rc;
    368	bool stop = false;
    369
    370	if (mdl->curr_buf == NULL)
    371		mdl->curr_buf = list_first_entry(&mdl->buf_list,
    372						 struct cx18_buffer, list);
    373
    374	if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) {
    375		/*
    376		 * For some reason we've exhausted the buffers, but the MDL
    377		 * object still said some data was unread.
    378		 * Fix that and bail out.
    379		 */
    380		mdl->readpos = mdl->bytesused;
    381		return 0;
    382	}
    383
    384	list_for_each_entry_from(mdl->curr_buf, &mdl->buf_list, list) {
    385
    386		if (mdl->curr_buf->readpos >= mdl->curr_buf->bytesused)
    387			continue;
    388
    389		rc = cx18_copy_buf_to_user(s, mdl->curr_buf, ubuf + tot_written,
    390					   ucount - tot_written, &stop);
    391		if (rc < 0)
    392			return rc;
    393		mdl->readpos += rc;
    394		tot_written += rc;
    395
    396		if (stop ||	/* Forced stopping point for VBI insertion */
    397		    tot_written >= ucount ||	/* Reader request satisfied */
    398		    mdl->curr_buf->readpos < mdl->curr_buf->bytesused ||
    399		    mdl->readpos >= mdl->bytesused) /* MDL buffers drained */
    400			break;
    401	}
    402	return tot_written;
    403}
    404
    405static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf,
    406		size_t tot_count, int non_block)
    407{
    408	struct cx18 *cx = s->cx;
    409	size_t tot_written = 0;
    410	int single_frame = 0;
    411
    412	if (atomic_read(&cx->ana_capturing) == 0 && s->id == -1) {
    413		/* shouldn't happen */
    414		CX18_DEBUG_WARN("Stream %s not initialized before read\n",
    415				s->name);
    416		return -EIO;
    417	}
    418
    419	/* Each VBI buffer is one frame, the v4l2 API says that for VBI the
    420	   frames should arrive one-by-one, so make sure we never output more
    421	   than one VBI frame at a time */
    422	if (s->type == CX18_ENC_STREAM_TYPE_VBI && !cx18_raw_vbi(cx))
    423		single_frame = 1;
    424
    425	for (;;) {
    426		struct cx18_mdl *mdl;
    427		int rc;
    428
    429		mdl = cx18_get_mdl(s, non_block, &rc);
    430		/* if there is no data available... */
    431		if (mdl == NULL) {
    432			/* if we got data, then return that regardless */
    433			if (tot_written)
    434				break;
    435			/* EOS condition */
    436			if (rc == 0) {
    437				clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
    438				clear_bit(CX18_F_S_APPL_IO, &s->s_flags);
    439				cx18_release_stream(s);
    440			}
    441			/* set errno */
    442			return rc;
    443		}
    444
    445		rc = cx18_copy_mdl_to_user(s, mdl, ubuf + tot_written,
    446				tot_count - tot_written);
    447
    448		if (mdl != &cx->vbi.sliced_mpeg_mdl) {
    449			if (mdl->readpos == mdl->bytesused)
    450				cx18_stream_put_mdl_fw(s, mdl);
    451			else
    452				cx18_push(s, mdl, &s->q_full);
    453		} else if (mdl->readpos == mdl->bytesused) {
    454			int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
    455
    456			cx->vbi.sliced_mpeg_size[idx] = 0;
    457			cx->vbi.inserted_frame++;
    458			cx->vbi_data_inserted += mdl->bytesused;
    459		}
    460		if (rc < 0)
    461			return rc;
    462		tot_written += rc;
    463
    464		if (tot_written == tot_count || single_frame)
    465			break;
    466	}
    467	return tot_written;
    468}
    469
    470static ssize_t cx18_read_pos(struct cx18_stream *s, char __user *ubuf,
    471		size_t count, loff_t *pos, int non_block)
    472{
    473	ssize_t rc = count ? cx18_read(s, ubuf, count, non_block) : 0;
    474	struct cx18 *cx = s->cx;
    475
    476	CX18_DEBUG_HI_FILE("read %zd from %s, got %zd\n", count, s->name, rc);
    477	if (rc > 0)
    478		*pos += rc;
    479	return rc;
    480}
    481
    482int cx18_start_capture(struct cx18_open_id *id)
    483{
    484	struct cx18 *cx = id->cx;
    485	struct cx18_stream *s = &cx->streams[id->type];
    486	struct cx18_stream *s_vbi;
    487	struct cx18_stream *s_idx;
    488
    489	if (s->type == CX18_ENC_STREAM_TYPE_RAD) {
    490		/* you cannot read from these stream types. */
    491		return -EPERM;
    492	}
    493
    494	/* Try to claim this stream. */
    495	if (cx18_claim_stream(id, s->type))
    496		return -EBUSY;
    497
    498	/* If capture is already in progress, then we also have to
    499	   do nothing extra. */
    500	if (test_bit(CX18_F_S_STREAMOFF, &s->s_flags) ||
    501	    test_and_set_bit(CX18_F_S_STREAMING, &s->s_flags)) {
    502		set_bit(CX18_F_S_APPL_IO, &s->s_flags);
    503		return 0;
    504	}
    505
    506	/* Start associated VBI or IDX stream capture if required */
    507	s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
    508	s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
    509	if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
    510		/*
    511		 * The VBI and IDX streams should have been claimed
    512		 * automatically, if for internal use, when the MPG stream was
    513		 * claimed.  We only need to start these streams capturing.
    514		 */
    515		if (test_bit(CX18_F_S_INTERNAL_USE, &s_idx->s_flags) &&
    516		    !test_and_set_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
    517			if (cx18_start_v4l2_encode_stream(s_idx)) {
    518				CX18_DEBUG_WARN("IDX capture start failed\n");
    519				clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
    520				goto start_failed;
    521			}
    522			CX18_DEBUG_INFO("IDX capture started\n");
    523		}
    524		if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
    525		    !test_and_set_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) {
    526			if (cx18_start_v4l2_encode_stream(s_vbi)) {
    527				CX18_DEBUG_WARN("VBI capture start failed\n");
    528				clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
    529				goto start_failed;
    530			}
    531			CX18_DEBUG_INFO("VBI insertion started\n");
    532		}
    533	}
    534
    535	/* Tell the card to start capturing */
    536	if (!cx18_start_v4l2_encode_stream(s)) {
    537		/* We're done */
    538		set_bit(CX18_F_S_APPL_IO, &s->s_flags);
    539		/* Resume a possibly paused encoder */
    540		if (test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
    541			cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, s->handle);
    542		return 0;
    543	}
    544
    545start_failed:
    546	CX18_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name);
    547
    548	/*
    549	 * The associated VBI and IDX streams for internal use are released
    550	 * automatically when the MPG stream is released.  We only need to stop
    551	 * the associated stream.
    552	 */
    553	if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
    554		/* Stop the IDX stream which is always for internal use */
    555		if (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
    556			cx18_stop_v4l2_encode_stream(s_idx, 0);
    557			clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
    558		}
    559		/* Stop the VBI stream, if only running for internal use */
    560		if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
    561		    !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
    562			cx18_stop_v4l2_encode_stream(s_vbi, 0);
    563			clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
    564		}
    565	}
    566	clear_bit(CX18_F_S_STREAMING, &s->s_flags);
    567	cx18_release_stream(s); /* Also releases associated streams */
    568	return -EIO;
    569}
    570
    571ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count,
    572		loff_t *pos)
    573{
    574	struct cx18_open_id *id = file2id(filp);
    575	struct cx18 *cx = id->cx;
    576	struct cx18_stream *s = &cx->streams[id->type];
    577	int rc;
    578
    579	CX18_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name);
    580
    581	mutex_lock(&cx->serialize_lock);
    582	rc = cx18_start_capture(id);
    583	mutex_unlock(&cx->serialize_lock);
    584	if (rc)
    585		return rc;
    586
    587	if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
    588		(id->type == CX18_ENC_STREAM_TYPE_YUV)) {
    589		return videobuf_read_stream(&s->vbuf_q, buf, count, pos, 0,
    590			filp->f_flags & O_NONBLOCK);
    591	}
    592
    593	return cx18_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK);
    594}
    595
    596__poll_t cx18_v4l2_enc_poll(struct file *filp, poll_table *wait)
    597{
    598	__poll_t req_events = poll_requested_events(wait);
    599	struct cx18_open_id *id = file2id(filp);
    600	struct cx18 *cx = id->cx;
    601	struct cx18_stream *s = &cx->streams[id->type];
    602	int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags);
    603	__poll_t res = 0;
    604
    605	/* Start a capture if there is none */
    606	if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags) &&
    607			(req_events & (EPOLLIN | EPOLLRDNORM))) {
    608		int rc;
    609
    610		mutex_lock(&cx->serialize_lock);
    611		rc = cx18_start_capture(id);
    612		mutex_unlock(&cx->serialize_lock);
    613		if (rc) {
    614			CX18_DEBUG_INFO("Could not start capture for %s (%d)\n",
    615					s->name, rc);
    616			return EPOLLERR;
    617		}
    618		CX18_DEBUG_FILE("Encoder poll started capture\n");
    619	}
    620
    621	if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
    622		(id->type == CX18_ENC_STREAM_TYPE_YUV)) {
    623		__poll_t videobuf_poll = videobuf_poll_stream(filp, &s->vbuf_q, wait);
    624
    625		if (v4l2_event_pending(&id->fh))
    626			res |= EPOLLPRI;
    627		if (eof && videobuf_poll == EPOLLERR)
    628			return res | EPOLLHUP;
    629		return res | videobuf_poll;
    630	}
    631
    632	/* add stream's waitq to the poll list */
    633	CX18_DEBUG_HI_FILE("Encoder poll\n");
    634	if (v4l2_event_pending(&id->fh))
    635		res |= EPOLLPRI;
    636	else
    637		poll_wait(filp, &s->waitq, wait);
    638
    639	if (atomic_read(&s->q_full.depth))
    640		return res | EPOLLIN | EPOLLRDNORM;
    641	if (eof)
    642		return res | EPOLLHUP;
    643	return res;
    644}
    645
    646int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
    647{
    648	struct cx18_open_id *id = file->private_data;
    649	struct cx18 *cx = id->cx;
    650	struct cx18_stream *s = &cx->streams[id->type];
    651	int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags);
    652
    653	if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
    654		(id->type == CX18_ENC_STREAM_TYPE_YUV)) {
    655
    656		/* Start a capture if there is none */
    657		if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
    658			int rc;
    659
    660			mutex_lock(&cx->serialize_lock);
    661			rc = cx18_start_capture(id);
    662			mutex_unlock(&cx->serialize_lock);
    663			if (rc) {
    664				CX18_DEBUG_INFO(
    665					"Could not start capture for %s (%d)\n",
    666					s->name, rc);
    667				return -EINVAL;
    668			}
    669			CX18_DEBUG_FILE("Encoder mmap started capture\n");
    670		}
    671
    672		return videobuf_mmap_mapper(&s->vbuf_q, vma);
    673	}
    674
    675	return -EINVAL;
    676}
    677
    678void cx18_vb_timeout(struct timer_list *t)
    679{
    680	struct cx18_stream *s = from_timer(s, t, vb_timeout);
    681	struct cx18_videobuf_buffer *buf;
    682	unsigned long flags;
    683
    684	/* Return all of the buffers in error state, so the vbi/vid inode
    685	 * can return from blocking.
    686	 */
    687	spin_lock_irqsave(&s->vb_lock, flags);
    688	while (!list_empty(&s->vb_capture)) {
    689		buf = list_entry(s->vb_capture.next,
    690			struct cx18_videobuf_buffer, vb.queue);
    691		list_del(&buf->vb.queue);
    692		buf->vb.state = VIDEOBUF_ERROR;
    693		wake_up(&buf->vb.done);
    694	}
    695	spin_unlock_irqrestore(&s->vb_lock, flags);
    696}
    697
    698void cx18_stop_capture(struct cx18_open_id *id, int gop_end)
    699{
    700	struct cx18 *cx = id->cx;
    701	struct cx18_stream *s = &cx->streams[id->type];
    702	struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
    703	struct cx18_stream *s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
    704
    705	CX18_DEBUG_IOCTL("close() of %s\n", s->name);
    706
    707	/* 'Unclaim' this stream */
    708
    709	/* Stop capturing */
    710	if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
    711		CX18_DEBUG_INFO("close stopping capture\n");
    712		if (id->type == CX18_ENC_STREAM_TYPE_MPG) {
    713			/* Stop internal use associated VBI and IDX streams */
    714			if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
    715			    !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
    716				CX18_DEBUG_INFO("close stopping embedded VBI capture\n");
    717				cx18_stop_v4l2_encode_stream(s_vbi, 0);
    718			}
    719			if (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
    720				CX18_DEBUG_INFO("close stopping IDX capture\n");
    721				cx18_stop_v4l2_encode_stream(s_idx, 0);
    722			}
    723		}
    724		if (id->type == CX18_ENC_STREAM_TYPE_VBI &&
    725		    test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags))
    726			/* Also used internally, don't stop capturing */
    727			s->id = -1;
    728		else
    729			cx18_stop_v4l2_encode_stream(s, gop_end);
    730	}
    731	if (!gop_end) {
    732		clear_bit(CX18_F_S_APPL_IO, &s->s_flags);
    733		clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
    734		cx18_release_stream(s);
    735	}
    736}
    737
    738int cx18_v4l2_close(struct file *filp)
    739{
    740	struct v4l2_fh *fh = filp->private_data;
    741	struct cx18_open_id *id = fh2id(fh);
    742	struct cx18 *cx = id->cx;
    743	struct cx18_stream *s = &cx->streams[id->type];
    744
    745	CX18_DEBUG_IOCTL("close() of %s\n", s->name);
    746
    747	mutex_lock(&cx->serialize_lock);
    748	/* Stop radio */
    749	if (id->type == CX18_ENC_STREAM_TYPE_RAD &&
    750			v4l2_fh_is_singular_file(filp)) {
    751		/* Closing radio device, return to TV mode */
    752		cx18_mute(cx);
    753		/* Mark that the radio is no longer in use */
    754		clear_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
    755		/* Switch tuner to TV */
    756		cx18_call_all(cx, video, s_std, cx->std);
    757		/* Select correct audio input (i.e. TV tuner or Line in) */
    758		cx18_audio_set_io(cx);
    759		if (atomic_read(&cx->ana_capturing) > 0) {
    760			/* Undo video mute */
    761			cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
    762			    (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute) |
    763			    (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute_yuv) << 8)));
    764		}
    765		/* Done! Unmute and continue. */
    766		cx18_unmute(cx);
    767	}
    768
    769	v4l2_fh_del(fh);
    770	v4l2_fh_exit(fh);
    771
    772	/* 'Unclaim' this stream */
    773	if (s->id == id->open_id)
    774		cx18_stop_capture(id, 0);
    775	kfree(id);
    776	mutex_unlock(&cx->serialize_lock);
    777	return 0;
    778}
    779
    780static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
    781{
    782	struct cx18 *cx = s->cx;
    783	struct cx18_open_id *item;
    784
    785	CX18_DEBUG_FILE("open %s\n", s->name);
    786
    787	/* Allocate memory */
    788	item = kzalloc(sizeof(struct cx18_open_id), GFP_KERNEL);
    789	if (NULL == item) {
    790		CX18_DEBUG_WARN("nomem on v4l2 open\n");
    791		return -ENOMEM;
    792	}
    793	v4l2_fh_init(&item->fh, &s->video_dev);
    794
    795	item->cx = cx;
    796	item->type = s->type;
    797
    798	item->open_id = cx->open_id++;
    799	filp->private_data = &item->fh;
    800	v4l2_fh_add(&item->fh);
    801
    802	if (item->type == CX18_ENC_STREAM_TYPE_RAD &&
    803			v4l2_fh_is_singular_file(filp)) {
    804		if (!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
    805			if (atomic_read(&cx->ana_capturing) > 0) {
    806				/* switching to radio while capture is
    807				   in progress is not polite */
    808				v4l2_fh_del(&item->fh);
    809				v4l2_fh_exit(&item->fh);
    810				kfree(item);
    811				return -EBUSY;
    812			}
    813		}
    814
    815		/* Mark that the radio is being used. */
    816		set_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
    817		/* We have the radio */
    818		cx18_mute(cx);
    819		/* Switch tuner to radio */
    820		cx18_call_all(cx, tuner, s_radio);
    821		/* Select the correct audio input (i.e. radio tuner) */
    822		cx18_audio_set_io(cx);
    823		/* Done! Unmute and continue. */
    824		cx18_unmute(cx);
    825	}
    826	return 0;
    827}
    828
    829int cx18_v4l2_open(struct file *filp)
    830{
    831	int res;
    832	struct video_device *video_dev = video_devdata(filp);
    833	struct cx18_stream *s = video_get_drvdata(video_dev);
    834	struct cx18 *cx = s->cx;
    835
    836	mutex_lock(&cx->serialize_lock);
    837	if (cx18_init_on_first_open(cx)) {
    838		CX18_ERR("Failed to initialize on %s\n",
    839			 video_device_node_name(video_dev));
    840		mutex_unlock(&cx->serialize_lock);
    841		return -ENXIO;
    842	}
    843	res = cx18_serialized_open(s, filp);
    844	mutex_unlock(&cx->serialize_lock);
    845	return res;
    846}
    847
    848void cx18_mute(struct cx18 *cx)
    849{
    850	u32 h;
    851	if (atomic_read(&cx->ana_capturing)) {
    852		h = cx18_find_handle(cx);
    853		if (h != CX18_INVALID_TASK_HANDLE)
    854			cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 1);
    855		else
    856			CX18_ERR("Can't find valid task handle for mute\n");
    857	}
    858	CX18_DEBUG_INFO("Mute\n");
    859}
    860
    861void cx18_unmute(struct cx18 *cx)
    862{
    863	u32 h;
    864	if (atomic_read(&cx->ana_capturing)) {
    865		h = cx18_find_handle(cx);
    866		if (h != CX18_INVALID_TASK_HANDLE) {
    867			cx18_msleep_timeout(100, 0);
    868			cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, h, 12);
    869			cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 0);
    870		} else
    871			CX18_ERR("Can't find valid task handle for unmute\n");
    872	}
    873	CX18_DEBUG_INFO("Unmute\n");
    874}