18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * The Virtual DVB test driver serves as a reference DVB driver and helps
48c2ecf20Sopenharmony_ci * validate the existing APIs in the media subsystem. It can also aid
58c2ecf20Sopenharmony_ci * developers working on userspace applications.
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Copyright (C) 2020 Daniel W. S. Almeida
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ":%s, %d: " fmt, __func__, __LINE__
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include <linux/printk.h>
128c2ecf20Sopenharmony_ci#include <linux/ratelimit.h>
138c2ecf20Sopenharmony_ci#include <linux/string.h>
148c2ecf20Sopenharmony_ci#include <linux/types.h>
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#include "vidtv_common.h"
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci/**
198c2ecf20Sopenharmony_ci * vidtv_memcpy() - wrapper routine to be used by MPEG-TS
208c2ecf20Sopenharmony_ci *	generator, in order to avoid going past the
218c2ecf20Sopenharmony_ci *	output buffer.
228c2ecf20Sopenharmony_ci * @to:	Starting element to where a MPEG-TS packet will
238c2ecf20Sopenharmony_ci *	be copied.
248c2ecf20Sopenharmony_ci * @to_offset:	Starting position of the @to buffer to be filled.
258c2ecf20Sopenharmony_ci * @to_size:	Size of the @to buffer.
268c2ecf20Sopenharmony_ci * @from:	Starting element of the buffer to be copied.
278c2ecf20Sopenharmony_ci * @len:	Number of elements to be copy from @from buffer
288c2ecf20Sopenharmony_ci *	into @to+ @to_offset buffer.
298c2ecf20Sopenharmony_ci *
308c2ecf20Sopenharmony_ci * Note:
318c2ecf20Sopenharmony_ci *	Real digital TV demod drivers should not have memcpy
328c2ecf20Sopenharmony_ci *	wrappers. We use it here because emulating MPEG-TS
338c2ecf20Sopenharmony_ci *	generation at kernelspace requires some extra care.
348c2ecf20Sopenharmony_ci *
358c2ecf20Sopenharmony_ci * Return:
368c2ecf20Sopenharmony_ci *	Returns the number of bytes written
378c2ecf20Sopenharmony_ci */
388c2ecf20Sopenharmony_ciu32 vidtv_memcpy(void *to,
398c2ecf20Sopenharmony_ci		 size_t to_offset,
408c2ecf20Sopenharmony_ci		 size_t to_size,
418c2ecf20Sopenharmony_ci		 const void *from,
428c2ecf20Sopenharmony_ci		 size_t len)
438c2ecf20Sopenharmony_ci{
448c2ecf20Sopenharmony_ci	if (unlikely(to_offset + len > to_size)) {
458c2ecf20Sopenharmony_ci		pr_err_ratelimited("overflow detected, skipping. Try increasing the buffer size. Needed %zu, had %zu\n",
468c2ecf20Sopenharmony_ci				   to_offset + len,
478c2ecf20Sopenharmony_ci				   to_size);
488c2ecf20Sopenharmony_ci		return 0;
498c2ecf20Sopenharmony_ci	}
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	memcpy(to + to_offset, from, len);
528c2ecf20Sopenharmony_ci	return len;
538c2ecf20Sopenharmony_ci}
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci/**
568c2ecf20Sopenharmony_ci * vidtv_memset() - wrapper routine to be used by MPEG-TS
578c2ecf20Sopenharmony_ci *	generator, in order to avoid going past the
588c2ecf20Sopenharmony_ci *	output buffer.
598c2ecf20Sopenharmony_ci * @to:	Starting element to set
608c2ecf20Sopenharmony_ci * @to_offset:	Starting position of the @to buffer to be filled.
618c2ecf20Sopenharmony_ci * @to_size:	Size of the @to buffer.
628c2ecf20Sopenharmony_ci * @c:		The value to set the memory to.
638c2ecf20Sopenharmony_ci * @len:	Number of elements to be copy from @from buffer
648c2ecf20Sopenharmony_ci *	into @to+ @to_offset buffer.
658c2ecf20Sopenharmony_ci *
668c2ecf20Sopenharmony_ci * Note:
678c2ecf20Sopenharmony_ci *	Real digital TV demod drivers should not have memset
688c2ecf20Sopenharmony_ci *	wrappers. We use it here because emulating MPEG-TS
698c2ecf20Sopenharmony_ci *	generation at kernelspace requires some extra care.
708c2ecf20Sopenharmony_ci *
718c2ecf20Sopenharmony_ci * Return:
728c2ecf20Sopenharmony_ci *	Returns the number of bytes written
738c2ecf20Sopenharmony_ci */
748c2ecf20Sopenharmony_ciu32 vidtv_memset(void *to,
758c2ecf20Sopenharmony_ci		 size_t to_offset,
768c2ecf20Sopenharmony_ci		 size_t to_size,
778c2ecf20Sopenharmony_ci		 const int c,
788c2ecf20Sopenharmony_ci		 size_t len)
798c2ecf20Sopenharmony_ci{
808c2ecf20Sopenharmony_ci	if (unlikely(to_offset + len > to_size)) {
818c2ecf20Sopenharmony_ci		pr_err_ratelimited("overflow detected, skipping. Try increasing the buffer size. Needed %zu, had %zu\n",
828c2ecf20Sopenharmony_ci				   to_offset + len,
838c2ecf20Sopenharmony_ci				   to_size);
848c2ecf20Sopenharmony_ci		return 0;
858c2ecf20Sopenharmony_ci	}
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci	memset(to + to_offset, c, len);
888c2ecf20Sopenharmony_ci	return len;
898c2ecf20Sopenharmony_ci}
90