Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 285693e4 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "media: dvb: 64 bit demux driver porting"

parents e4b367af f4cde9cf
Loading
Loading
Loading
Loading
+89 −8
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@
#include <linux/seq_file.h>
#include <linux/timer.h>
#include <linux/jiffies.h>
#include <linux/compat.h>
#include "dmxdev.h"

static int overflow_auto_flush = 1;
@@ -795,8 +796,7 @@ static int dvr_input_thread_entry(void *arg)
				feed_cmd.cmd.data_feed_count =
					dvb_ringbuffer_avail(
						&dmxdev->dvr_input_buffer);

				dvb_dvr_feed_cmd(dmxdev, &dvr_cmd);
				dvb_dvr_feed_cmd(dmxdev, &feed_cmd);
			}

			dvb_dvr_oob_cmd(dmxdev, &dvr_cmd.cmd.oobcmd);
@@ -2101,7 +2101,7 @@ static void dvb_dmxdev_queue_ts_insertion(
		tsp_size = 192;

	if (ts_buffer->size % tsp_size) {
		pr_err("%s: Wrong buffer alignment, size=%d, tsp_size=%d\n",
		pr_err("%s: Wrong buffer alignment, size=%zu, tsp_size=%zu\n",
			__func__, ts_buffer->size, tsp_size);
		return;
	}
@@ -2833,7 +2833,7 @@ static int dvb_dmxdev_section_event_cb(struct dmx_section_filter *filter,

	free = dvb_ringbuffer_free(&dmxdevfilter->buffer);
	if (free < dmx_data_ready->data_length) {
		pr_err("%s: invalid data length: data_length=%d > free=%d\n",
		pr_err("%s: invalid data length: data_length=%d > free=%zd\n",
			__func__, dmx_data_ready->data_length, free);
	} else {
		res = dvb_dmxdev_add_event(&dmxdevfilter->events, &event);
@@ -2993,7 +2993,7 @@ static int dvb_dmxdev_ts_event_cb(struct dmx_ts_feed *feed,

	free = dvb_ringbuffer_free(buffer);
	if (free < dmx_data_ready->data_length) {
		pr_err("%s: invalid data length: data_length=%d > free=%d\n",
		pr_err("%s: invalid data length: data_length=%d > free=%zd\n",
			__func__, dmx_data_ready->data_length, free);

		spin_unlock(&dmxdevfilter->dev->lock);
@@ -4394,7 +4394,9 @@ static int dvb_demux_do_ioctl(struct file *file,
		break;

	default:
		ret = -EINVAL;
		pr_err("%s: unknown ioctl code (0x%x)\n",
			__func__, cmd);
		ret = -ENOIOCTLCMD;
		break;
	}
	mutex_unlock(&dmxdev->mutex);
@@ -4407,6 +4409,71 @@ static long dvb_demux_ioctl(struct file *file, unsigned int cmd,
	return dvb_usercopy(file, cmd, arg, dvb_demux_do_ioctl);
}

#ifdef CONFIG_COMPAT

struct dmx_set_ts_insertion32 {
	__u32 identifier;
	__u32 repetition_time;
	compat_uptr_t ts_packets;
	compat_size_t size;
};

static long dmx_set_ts_insertion32_wrapper(struct file *file, unsigned int cmd,
	    unsigned long arg)
{
	int ret;
	struct dmx_set_ts_insertion32 dmx_ts_insert32;
	struct dmx_set_ts_insertion dmx_ts_insert;

	ret = copy_from_user(&dmx_ts_insert32, (void __user *)arg,
		sizeof(dmx_ts_insert32));
	if (ret) {
		pr_err(
			"%s: copy dmx_set_ts_insertion32 from user failed, ret=%d\n",
			__func__, ret);
		return -EFAULT;
	}

	memset(&dmx_ts_insert, 0, sizeof(dmx_ts_insert));
	dmx_ts_insert.identifier = dmx_ts_insert32.identifier;
	dmx_ts_insert.repetition_time = dmx_ts_insert32.repetition_time;
	dmx_ts_insert.ts_packets = compat_ptr(dmx_ts_insert32.ts_packets);
	dmx_ts_insert.size = dmx_ts_insert32.size;

	ret = dvb_demux_do_ioctl(file, DMX_SET_TS_INSERTION, &dmx_ts_insert);

	return ret;
}

#define DMX_SET_TS_INSERTION32 _IOW('o', 70, struct dmx_set_ts_insertion32)

/*
 * compat ioctl is called whenever compatability is required, i.e when a 32bit
 * process calls an ioctl for a 64bit kernel.
 */
static long dvb_demux_compat_ioctl(struct file *file, unsigned int cmd,
			    unsigned long arg)
{
	long ret = 0;

	switch (cmd) {
	case DMX_SET_TS_INSERTION32:
		ret = dmx_set_ts_insertion32_wrapper(file, cmd, arg);
		break;
	case DMX_SET_TS_INSERTION:
		pr_err("%s: 64bit ioctl code (0x%lx) used by 32bit userspace\n",
			__func__, DMX_SET_TS_INSERTION);
		ret = -ENOIOCTLCMD;
		break;
	default:
		/* use regular ioctl */
		ret = dvb_usercopy(file, cmd, arg, dvb_demux_do_ioctl);
	}

	return ret;
}
#endif

static unsigned int dvb_demux_poll(struct file *file, poll_table *wait)
{
	struct dmxdev_filter *dmxdevfilter = file->private_data;
@@ -4521,6 +4588,9 @@ static const struct file_operations dvb_demux_fops = {
	.poll = dvb_demux_poll,
	.llseek = default_llseek,
	.mmap = dvb_demux_mmap,
#ifdef CONFIG_COMPAT
	.compat_ioctl = dvb_demux_compat_ioctl,
#endif
};

static struct dvb_device dvbdev_demux = {
@@ -4580,7 +4650,7 @@ static int dvb_dvr_do_ioctl(struct file *file,
		break;

	default:
		ret = -EINVAL;
		ret = -ENOIOCTLCMD;
		break;
	}
	mutex_unlock(&dmxdev->mutex);
@@ -4593,6 +4663,14 @@ static long dvb_dvr_ioctl(struct file *file,
	return dvb_usercopy(file, cmd, arg, dvb_dvr_do_ioctl);
}

#ifdef CONFIG_COMPAT
static long dvb_dvr_compat_ioctl(struct file *file, unsigned int cmd,
			unsigned long arg)
{
	return dvb_usercopy(file, cmd, arg, dvb_dvr_do_ioctl);
}
#endif

static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait)
{
	struct dvb_device *dvbdev = file->private_data;
@@ -4634,6 +4712,9 @@ static const struct file_operations dvb_dvr_fops = {
	.write = dvb_dvr_write,
	.mmap = dvb_dvr_mmap,
	.unlocked_ioctl = dvb_dvr_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl = dvb_dvr_compat_ioctl,
#endif
	.open = dvb_dvr_open,
	.release = dvb_dvr_release,
	.poll = dvb_dvr_poll,
+2 −2
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
 * Copyright (C) 2003 Oliver Endriss
 * Copyright (C) 2004 Andrew de Quincey
 *
 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
 *
 * based on code originally found in av7110.c & dvb_ci.c:
 * Copyright (C) 1999-2003 Ralph  Metzler
@@ -171,7 +171,7 @@ ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t
}

ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf,
					const u8 *buf, size_t len)
					const u8 __user *buf, size_t len)
{
	size_t todo = len;
	size_t split;
+2 −2
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
 * Copyright (C) 2003 Oliver Endriss
 * Copyright (C) 2004 Andrew de Quincey
 *
 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012,2014 The Linux Foundation. All rights reserved.
 *
 * based on code originally found in av7110.c & dvb_ci.c:
 * Copyright (C) 1999-2003 Ralph Metzler & Marcus Metzler
@@ -141,7 +141,7 @@ extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf,
				    size_t len);

extern ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf,
					const u8 *buf, size_t len);
					const u8 __user *buf, size_t len);

/**
 * Write a packet into the ringbuffer.
+14 −42
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@
#include "mpq_dmx_plugin_common.h"
#include "mpq_sdmx.h"

#define SDMX_MAJOR_VERSION_MATCH	(4)
#define SDMX_MAJOR_VERSION_MATCH	(5)

/* Length of mandatory fields that must exist in header of video PES */
#define PES_MANDATORY_FIELDS_LEN			9
@@ -1672,6 +1672,7 @@ static int mpq_sdmx_init_metadata_buffer(struct mpq_demux *mpq_demux,
	void *metadata_buff_base;
	ion_phys_addr_t temp;
	int ret;
	size_t size;

	feed->metadata_buf_handle = ion_alloc(mpq_demux->ion_client,
		SDMX_METADATA_BUFFER_SIZE,
@@ -1703,24 +1704,15 @@ static int mpq_sdmx_init_metadata_buffer(struct mpq_demux *mpq_demux,
	ret = ion_phys(mpq_demux->ion_client,
		feed->metadata_buf_handle,
		&temp,
		&metadata_buff_desc->size);
		&size);
	if (ret) {
		MPQ_DVB_ERR_PRINT(
			"%s: FAILED to get physical address %d\n",
			__func__, ret);
		goto failed_unmap_metadata_buf;
	}

	/*
	 * NOTE: the following casting to u32 must be done
	 * as long as TZ does not support LPAE. Once TZ supports
	 * LPAE SDMX interface needs to be updated accordingly.
	 */
	if (temp > 0xFFFFFFFF)
		MPQ_DVB_ERR_PRINT(
			"%s: WARNNING - physical address %pa is larger than 32bits!\n",
			__func__, &temp);
	metadata_buff_desc->base_addr = (void *)(u32)temp;
	metadata_buff_desc->size = size;
	metadata_buff_desc->base_addr = (u64)temp;

	dvb_ringbuffer_init(&feed->metadata_buf, metadata_buff_base,
		SDMX_METADATA_BUFFER_SIZE);
@@ -2316,16 +2308,7 @@ static int mpq_sdmx_dvr_buffer_desc(struct mpq_demux *mpq_demux,
		return ret;
	}

	/*
	 * NOTE: the following casting to u32 must be done
	 * as long as TZ does not support LPAE. Once TZ supports
	 * LPAE SDMX interface needs to be updated accordingly.
	 */
	if (phys_addr > 0xFFFFFFFF)
		MPQ_DVB_ERR_PRINT(
			"%s: WARNNING - physical address %pa is larger than 32bits!\n",
			__func__, &phys_addr);
	buf_desc->base_addr = (void *)(u32)phys_addr;
	buf_desc->base_addr = (u64)phys_addr;
	buf_desc->size = rbuf->size;

	return 0;
@@ -3559,18 +3542,7 @@ static int mpq_sdmx_get_buffer_chunks(struct mpq_demux *mpq_demux,

	sg = sg_ptr->sgl;
	for (i = 0; i < sg_ptr->nents; i++) {
		/*
		 * NOTE: the following casting to u32 must be done
		 * as long as TZ does not support LPAE. Once TZ supports
		 * LPAE SDMX interface needs to be updated accordingly.
		 */
		if (sg_dma_address(sg) > 0xFFFFFFFF)
			MPQ_DVB_ERR_PRINT(
				"%s: WARNNING - physical address %pa is larger than 32bits!\n",
				__func__, &sg_dma_address(sg));

		buff_chunks[i].base_addr =
			(void *)(u32)sg_dma_address(sg);
		buff_chunks[i].base_addr = (u64)sg_dma_address(sg);

		if (sg->length > actual_buff_size)
			chunk_size = actual_buff_size;
@@ -4253,7 +4225,7 @@ static int mpq_sdmx_check_ts_stall(struct mpq_demux *mpq_demux,
	 * output data to the still full buffer.
	 */
	if (mpq_demux->demux.playback_mode == DMX_PB_MODE_PULL) {
		MPQ_DVB_DBG_PRINT("%s: Stalling for events and %d bytes\n",
		MPQ_DVB_DBG_PRINT("%s: Stalling for events and %zu bytes\n",
			__func__, req);

		mutex_unlock(&mpq_demux->mutex);
@@ -4325,7 +4297,7 @@ static void mpq_sdmx_pes_filter_results(struct mpq_demux *mpq_demux,
		bytes_avail = dvb_ringbuffer_avail(&mpq_feed->metadata_buf);
		if (bytes_avail < (sizeof(header) + sizeof(counters))) {
			MPQ_DVB_ERR_PRINT(
				"%s: metadata_fill_count is %d less than required %d bytes\n",
				"%s: metadata_fill_count is %d less than required %zu bytes\n",
				__func__,
				sts->metadata_fill_count,
				sizeof(header) + sizeof(counters));
@@ -4440,7 +4412,7 @@ static void mpq_sdmx_section_filter_results(struct mpq_demux *mpq_demux,
		bytes_avail = dvb_ringbuffer_avail(&mpq_feed->metadata_buf);
		if (bytes_avail < sizeof(header)) {
			MPQ_DVB_ERR_PRINT(
				"%s: metadata_fill_count is %d less than required %d bytes\n",
				"%s: metadata_fill_count is %d less than required %zu bytes\n",
				__func__,
				sts->metadata_fill_count,
				sizeof(header));
@@ -4522,7 +4494,7 @@ static void mpq_sdmx_decoder_filter_results(struct mpq_demux *mpq_demux,
		bytes_avail = dvb_ringbuffer_avail(&mpq_feed->metadata_buf);
		if (bytes_avail < (sizeof(header) + sizeof(counters))) {
			MPQ_DVB_ERR_PRINT(
				"%s: metadata_fill_count is %d less than required %d bytes\n",
				"%s: metadata_fill_count is %d less than required %zu bytes\n",
				__func__,
				sts->metadata_fill_count,
				sizeof(header) + sizeof(counters));
@@ -4559,7 +4531,7 @@ static void mpq_sdmx_decoder_filter_results(struct mpq_demux *mpq_demux,
				header.metadata_length - sizeof(counters));
		} else {
			MPQ_DVB_ERR_PRINT(
				"%s: meta-data size %d larger than available meta-data %d or max allowed %d\n",
				"%s: meta-data size %d larger than available meta-data %zd or max allowed %d\n",
				__func__, header.metadata_length,
				bytes_avail,
				MAX_SDMX_METADATA_LENGTH);
@@ -4728,7 +4700,7 @@ static void mpq_sdmx_pcr_filter_results(struct mpq_demux *mpq_demux,
		bytes_avail = dvb_ringbuffer_avail(&mpq_feed->metadata_buf);
		if (bytes_avail < sizeof(header)) {
			MPQ_DVB_ERR_PRINT(
				"%s: metadata_fill_count is %d less than required %d bytes\n",
				"%s: metadata_fill_count is %d less than required %zu bytes\n",
				__func__,
				sts->metadata_fill_count,
				sizeof(header));
@@ -5018,7 +4990,7 @@ int mpq_sdmx_process(struct mpq_demux *mpq_demux,
	int limit = mpq_sdmx_proc_limit * tsp_size;

	MPQ_DVB_DBG_PRINT(
		"\n\n%s: read_offset=%u, fill_count=%u, tsp_size=%u\n",
		"\n\n%s: read_offset=%u, fill_count=%u, tsp_size=%zu\n",
		__func__, read_offset, fill_count, tsp_size);

	while (fill_count >= tsp_size) {
+7 −17
Original line number Diff line number Diff line
@@ -369,25 +369,15 @@ static void mpq_dmx_tspp_aggregated_process(int tsif, int channel_id)
	buff_start_addr_phys =
		mpq_dmx_tspp_info.tsif[tsif].ch_mem_heap_phys_base;

	/*
	 * NOTE: the following casting to u32 must be done
	 * as long as TZ does not support LPAE. Once TZ supports
	 * LPAE SDMX interface needs to be updated accordingly.
	 */
	if (buff_start_addr_phys > 0xFFFFFFFF)
		MPQ_DVB_ERR_PRINT(
			"%s: WARNNING - physical address %pa is larger than 32bits!\n",
			__func__, &buff_start_addr_phys);

	input.base_addr = (void *)(u32)buff_start_addr_phys;
	input.base_addr = (u64)buff_start_addr_phys;
	input.size = mpq_dmx_tspp_info.tsif[tsif].buffer_count *
		TSPP_DESCRIPTOR_SIZE;

	if (mpq_sdmx_is_loaded() && mpq_demux->sdmx_filter_count) {
		MPQ_DVB_DBG_PRINT(
			"%s: SDMX Processing %d descriptors: %d bytes at start address 0x%x, read offset %d\n",
			"%s: SDMX Processing %zu descriptors: %zu bytes at start address 0x%llx, read offset %d\n",
			__func__, aggregate_count, aggregate_len,
			(unsigned int)input.base_addr,
			input.base_addr,
			(int)(buff_current_addr_phys - buff_start_addr_phys));

		mpq_sdmx_process(mpq_demux, &input, aggregate_len,
@@ -408,7 +398,7 @@ static void mpq_dmx_tspp_aggregated_process(int tsif, int channel_id)
 */
static int mpq_dmx_tspp_thread(void *arg)
{
	int tsif = (int)arg;
	int tsif = (int)(uintptr_t)arg;
	struct mpq_demux *mpq_demux;
	const struct tspp_data_descriptor *tspp_data_desc;
	atomic_t *data_cnt;
@@ -500,7 +490,7 @@ static int mpq_dmx_tspp_thread(void *arg)
 */
static void mpq_tspp_callback(int channel_id, void *user)
{
	int tsif = (int)user;
	int tsif = (int)(uintptr_t)user;
	struct mpq_demux *mpq_demux;

	/* Save statistics on TSPP notifications */
@@ -1036,7 +1026,7 @@ static int mpq_tspp_dmx_add_channel(struct dvb_demux_feed *feed)
		tspp_register_notification(0,
					   channel_id,
					   mpq_tspp_callback,
					   (void *)tsif,
					   (void *)(uintptr_t)tsif,
					   tspp_channel_timeout);

		/* register allocator and provide allocation function
@@ -1869,7 +1859,7 @@ static int __init mpq_dmx_tspp_plugin_init(void)
		init_waitqueue_head(&mpq_dmx_tspp_info.tsif[i].wait_queue);
		mpq_dmx_tspp_info.tsif[i].thread =
			kthread_run(
				mpq_dmx_tspp_thread, (void *)i,
				mpq_dmx_tspp_thread, (void *)(uintptr_t)i,
				mpq_dmx_tspp_info.tsif[i].name);

		if (IS_ERR(mpq_dmx_tspp_info.tsif[i].thread)) {
Loading