static ssize_t ci_ll_read(struct dvb_ringbuffer *cibuf, struct file *file,
			  char __user *buf, size_t count, loff_t *ppos)
{
	int avail;
	int non_blocking = file->f_flags & O_NONBLOCK;
	ssize_t len;

	if (!cibuf->data || !count)
		return 0;
	if (non_blocking && (dvb_ringbuffer_empty(cibuf)))
		return -EWOULDBLOCK;
	if (wait_event_interruptible(cibuf->queue,
				     !dvb_ringbuffer_empty(cibuf)))
		return -ERESTARTSYS;
	avail = dvb_ringbuffer_avail(cibuf);
	if (avail < 4)
		return 0;
	len = DVB_RINGBUFFER_PEEK(cibuf, 0) << 8;
	len |= DVB_RINGBUFFER_PEEK(cibuf, 1);
	if (avail < len + 2 || count < len)
		return -EINVAL;
	DVB_RINGBUFFER_SKIP(cibuf, 2);

	return dvb_ringbuffer_read_user(cibuf, buf, len);
}
示例#2
0
static ssize_t dvb_dmxdev_buffer_read(struct dvb_ringbuffer *src,
				      int non_blocking, char __user *buf,
				      size_t count, loff_t *ppos)
{
	size_t todo;
	ssize_t avail;
	ssize_t ret = 0;

	if (!src->data)
		return 0;

	if (src->error) {
		ret = src->error;
		dvb_ringbuffer_flush(src);
		return ret;
	}

	for (todo = count; todo > 0; todo -= ret) {
		if (non_blocking && dvb_ringbuffer_empty(src)) {
			ret = -EWOULDBLOCK;
			break;
		}

		ret = wait_event_interruptible(src->queue,
					       !dvb_ringbuffer_empty(src) ||
					       (src->error != 0));
		if (ret < 0)
			break;

		if (src->error) {
			ret = src->error;
			dvb_ringbuffer_flush(src);
			break;
		}

		avail = dvb_ringbuffer_avail(src);
		if (avail > todo)
			avail = todo;

		ret = dvb_ringbuffer_read_user(src, buf, avail);
		if (ret < 0)
			break;

		buf += ret;
	}

	return (count - todo) ? (count - todo) : ret;
}
示例#3
0
ssize_t mpq_streambuffer_data_read_user(
		struct mpq_streambuffer *sbuff,
		u8 __user *buf, size_t len)
{
	ssize_t actual_len = 0;

	if ((NULL == sbuff) || (NULL == buf))
		return -EINVAL;

	if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
		/*
		 * Secure buffers are not permitted to be mapped into kernel
		 * memory, and so buffer base address may be NULL
		 */
		if (NULL == sbuff->raw_data.data)
			return -EPERM;

		actual_len = dvb_ringbuffer_avail(&sbuff->raw_data);
		if (actual_len < len)
			len = actual_len;
		if (len)
			dvb_ringbuffer_read_user(&sbuff->raw_data, buf, len);
		wake_up_all(&sbuff->raw_data.queue);
	} else {
		/* Linear buffer group */
		struct mpq_streambuffer_buffer_desc *desc;

		desc = (struct mpq_streambuffer_buffer_desc *)
				&sbuff->raw_data.data[sbuff->raw_data.pread];

		/*
		 * Secure buffers are not permitted to be mapped into kernel
		 * memory, and so buffer base address may be NULL
		 */
		if (NULL == desc->base)
			return -EPERM;

		actual_len = (desc->write_ptr - desc->read_ptr);
		if (actual_len < len)
			len = actual_len;
		if (copy_to_user(buf, desc->base + desc->read_ptr, len))
			return -EFAULT;
		desc->read_ptr += len;
	}

	return len;
}
示例#4
0
文件: front.c 项目: Audioniek/driver
/*=============================================================================
	Function	: kfront_read
	Description	:
	Input		:
	Output		:
	Return		:
=============================================================================*/
static ssize_t kfront_read(struct file *file, char __user *buf, size_t count,
			   loff_t *ppos)
{
	int avail;
	int non_blocking = file->f_flags & O_NONBLOCK;

	if (!ci_rbuffer.data || !count)
		return 0;
	if (non_blocking && (dvb_ringbuffer_empty(&ci_rbuffer)))
		return -EWOULDBLOCK;
	if (wait_event_interruptible(ci_rbuffer.queue,
				     !dvb_ringbuffer_empty(&ci_rbuffer)))
		return -ERESTARTSYS;
	avail = dvb_ringbuffer_avail(&ci_rbuffer);
	if (avail < 1)
		return 0;

	return dvb_ringbuffer_read_user(&ci_rbuffer, buf, 1);
}
示例#5
0
文件: ngene-av.c 项目: mona66/sifbox
ssize_t video_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
	struct dvb_device *dvbdev = file->private_data;
	struct ngene_channel *chan = dvbdev->priv;
	struct ngene *dev = chan->dev;
	int left, avail;

	left = count;
	while (left) {
		if (wait_event_interruptible(
				dev->vin_rbuf.queue,
				dvb_ringbuffer_avail(&dev->vin_rbuf) > 0) < 0)
			return -EAGAIN;
		avail = dvb_ringbuffer_avail(&dev->vin_rbuf);
		if (avail > left)
			avail = left;
		dvb_ringbuffer_read_user(&dev->vin_rbuf, buf, avail);
		left -= avail;
		buf += avail;
	}
	return count;
}