예제 #1
0
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
int mpq_streambuffer_data_read_dispose(
			struct mpq_streambuffer *sbuff,
			size_t len)
{
	if (NULL == sbuff)
		return -EINVAL;

	if (MPQ_STREAMBUFFER_BUFFER_MODE_RING == sbuff->mode) {
		if (unlikely(dvb_ringbuffer_avail(&sbuff->raw_data) < len))
			return -EINVAL;

		DVB_RINGBUFFER_SKIP(&sbuff->raw_data, len);
		wake_up_all(&sbuff->raw_data.queue);
	} else {
		struct mpq_streambuffer_buffer_desc *desc;

		desc = (struct mpq_streambuffer_buffer_desc *)
				&sbuff->raw_data.data[sbuff->raw_data.pread];
		if ((desc->read_ptr + len) > desc->size)
			desc->read_ptr = desc->size;
		else
			desc->read_ptr += len;
	}

	return 0;
}
예제 #3
0
int mpq_streambuffer_pkt_dispose(
			struct mpq_streambuffer *sbuff,
			size_t idx,
			int dispose_data)
{
	int ret;
	struct mpq_streambuffer_packet_header packet;

	if (NULL == sbuff)
		return -EINVAL;

	/* read-out the packet header first */
	ret = dvb_ringbuffer_pkt_read(&sbuff->packet_data, idx,
			0,
			(u8 *)&packet,
			sizeof(struct mpq_streambuffer_packet_header));

	if (ret != sizeof(struct mpq_streambuffer_packet_header))
		return -EINVAL;

	if ((MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR == sbuff->mode) ||
		(dispose_data)) {
		/* Advance the read pointer in the raw-data buffer first */
		ret = mpq_streambuffer_data_read_dispose(sbuff,
				packet.raw_data_len);
		if (ret != 0)
			return ret;
	}

	/* Move read pointer to the next linear buffer for subsequent reads */
	if ((MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR == sbuff->mode) &&
		(packet.raw_data_len > 0)) {
		struct mpq_streambuffer_buffer_desc *desc;

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

		desc->write_ptr = 0;
		desc->read_ptr = 0;

		DVB_RINGBUFFER_SKIP(&sbuff->raw_data,
				sizeof(struct mpq_streambuffer_buffer_desc));
		sbuff->pending_buffers_count--;

		wake_up_all(&sbuff->raw_data.queue);
	}

	/* Now clear the packet from the packet header */
	dvb_ringbuffer_pkt_dispose(&sbuff->packet_data, idx);

	if (sbuff->cb)
		sbuff->cb(sbuff, sbuff->cb_user_data);

	return 0;
}
예제 #4
0
void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx)
{
	size_t pktlen;

	rbuf->data[(idx + 2) % rbuf->size] = PKT_DISPOSED;

	// clean up disposed packets
	while(dvb_ringbuffer_avail(rbuf) > DVB_RINGBUFFER_PKTHDRSIZE) {
		if (DVB_RINGBUFFER_PEEK(rbuf, 2) == PKT_DISPOSED) {
			pktlen = DVB_RINGBUFFER_PEEK(rbuf, 0) << 8;
			pktlen |= DVB_RINGBUFFER_PEEK(rbuf, 1);
			DVB_RINGBUFFER_SKIP(rbuf, pktlen + DVB_RINGBUFFER_PKTHDRSIZE);
		} else {
			// first packet is not disposed, so we stop cleaning now
			break;
		}
	}
}