162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * The Virtual DVB test driver serves as a reference DVB driver and helps
462306a36Sopenharmony_ci * validate the existing APIs in the media subsystem. It can also aid
562306a36Sopenharmony_ci * developers working on userspace applications.
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Copyright (C) 2020 Daniel W. S. Almeida
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ":%s, %d: " fmt, __func__, __LINE__
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <linux/printk.h>
1262306a36Sopenharmony_ci#include <linux/ratelimit.h>
1362306a36Sopenharmony_ci#include <linux/string.h>
1462306a36Sopenharmony_ci#include <linux/types.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#include "vidtv_common.h"
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci/**
1962306a36Sopenharmony_ci * vidtv_memcpy() - wrapper routine to be used by MPEG-TS
2062306a36Sopenharmony_ci *	generator, in order to avoid going past the
2162306a36Sopenharmony_ci *	output buffer.
2262306a36Sopenharmony_ci * @to:	Starting element to where a MPEG-TS packet will
2362306a36Sopenharmony_ci *	be copied.
2462306a36Sopenharmony_ci * @to_offset:	Starting position of the @to buffer to be filled.
2562306a36Sopenharmony_ci * @to_size:	Size of the @to buffer.
2662306a36Sopenharmony_ci * @from:	Starting element of the buffer to be copied.
2762306a36Sopenharmony_ci * @len:	Number of elements to be copy from @from buffer
2862306a36Sopenharmony_ci *	into @to+ @to_offset buffer.
2962306a36Sopenharmony_ci *
3062306a36Sopenharmony_ci * Note:
3162306a36Sopenharmony_ci *	Real digital TV demod drivers should not have memcpy
3262306a36Sopenharmony_ci *	wrappers. We use it here because emulating MPEG-TS
3362306a36Sopenharmony_ci *	generation at kernelspace requires some extra care.
3462306a36Sopenharmony_ci *
3562306a36Sopenharmony_ci * Return:
3662306a36Sopenharmony_ci *	Returns the number of bytes written
3762306a36Sopenharmony_ci */
3862306a36Sopenharmony_ciu32 vidtv_memcpy(void *to,
3962306a36Sopenharmony_ci		 size_t to_offset,
4062306a36Sopenharmony_ci		 size_t to_size,
4162306a36Sopenharmony_ci		 const void *from,
4262306a36Sopenharmony_ci		 size_t len)
4362306a36Sopenharmony_ci{
4462306a36Sopenharmony_ci	if (unlikely(to_offset + len > to_size)) {
4562306a36Sopenharmony_ci		pr_err_ratelimited("overflow detected, skipping. Try increasing the buffer size. Needed %zu, had %zu\n",
4662306a36Sopenharmony_ci				   to_offset + len,
4762306a36Sopenharmony_ci				   to_size);
4862306a36Sopenharmony_ci		return 0;
4962306a36Sopenharmony_ci	}
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci	memcpy(to + to_offset, from, len);
5262306a36Sopenharmony_ci	return len;
5362306a36Sopenharmony_ci}
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci/**
5662306a36Sopenharmony_ci * vidtv_memset() - wrapper routine to be used by MPEG-TS
5762306a36Sopenharmony_ci *	generator, in order to avoid going past the
5862306a36Sopenharmony_ci *	output buffer.
5962306a36Sopenharmony_ci * @to:	Starting element to set
6062306a36Sopenharmony_ci * @to_offset:	Starting position of the @to buffer to be filled.
6162306a36Sopenharmony_ci * @to_size:	Size of the @to buffer.
6262306a36Sopenharmony_ci * @c:		The value to set the memory to.
6362306a36Sopenharmony_ci * @len:	Number of elements to be copy from @from buffer
6462306a36Sopenharmony_ci *	into @to+ @to_offset buffer.
6562306a36Sopenharmony_ci *
6662306a36Sopenharmony_ci * Note:
6762306a36Sopenharmony_ci *	Real digital TV demod drivers should not have memset
6862306a36Sopenharmony_ci *	wrappers. We use it here because emulating MPEG-TS
6962306a36Sopenharmony_ci *	generation at kernelspace requires some extra care.
7062306a36Sopenharmony_ci *
7162306a36Sopenharmony_ci * Return:
7262306a36Sopenharmony_ci *	Returns the number of bytes written
7362306a36Sopenharmony_ci */
7462306a36Sopenharmony_ciu32 vidtv_memset(void *to,
7562306a36Sopenharmony_ci		 size_t to_offset,
7662306a36Sopenharmony_ci		 size_t to_size,
7762306a36Sopenharmony_ci		 const int c,
7862306a36Sopenharmony_ci		 size_t len)
7962306a36Sopenharmony_ci{
8062306a36Sopenharmony_ci	if (unlikely(to_offset + len > to_size)) {
8162306a36Sopenharmony_ci		pr_err_ratelimited("overflow detected, skipping. Try increasing the buffer size. Needed %zu, had %zu\n",
8262306a36Sopenharmony_ci				   to_offset + len,
8362306a36Sopenharmony_ci				   to_size);
8462306a36Sopenharmony_ci		return 0;
8562306a36Sopenharmony_ci	}
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	memset(to + to_offset, c, len);
8862306a36Sopenharmony_ci	return len;
8962306a36Sopenharmony_ci}
90