18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci#include <unistd.h>
38c2ecf20Sopenharmony_ci#include <stdbool.h>
48c2ecf20Sopenharmony_ci#include <errno.h>
58c2ecf20Sopenharmony_ci#include <linux/kernel.h>
68c2ecf20Sopenharmony_ci#include <internal/lib.h>
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ciunsigned int page_size;
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_cistatic ssize_t ion(bool is_read, int fd, void *buf, size_t n)
118c2ecf20Sopenharmony_ci{
128c2ecf20Sopenharmony_ci	void *buf_start = buf;
138c2ecf20Sopenharmony_ci	size_t left = n;
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci	while (left) {
168c2ecf20Sopenharmony_ci		/* buf must be treated as const if !is_read. */
178c2ecf20Sopenharmony_ci		ssize_t ret = is_read ? read(fd, buf, left) :
188c2ecf20Sopenharmony_ci					write(fd, buf, left);
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci		if (ret < 0 && errno == EINTR)
218c2ecf20Sopenharmony_ci			continue;
228c2ecf20Sopenharmony_ci		if (ret <= 0)
238c2ecf20Sopenharmony_ci			return ret;
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci		left -= ret;
268c2ecf20Sopenharmony_ci		buf  += ret;
278c2ecf20Sopenharmony_ci	}
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci	BUG_ON((size_t)(buf - buf_start) != n);
308c2ecf20Sopenharmony_ci	return n;
318c2ecf20Sopenharmony_ci}
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci/*
348c2ecf20Sopenharmony_ci * Read exactly 'n' bytes or return an error.
358c2ecf20Sopenharmony_ci */
368c2ecf20Sopenharmony_cissize_t readn(int fd, void *buf, size_t n)
378c2ecf20Sopenharmony_ci{
388c2ecf20Sopenharmony_ci	return ion(true, fd, buf, n);
398c2ecf20Sopenharmony_ci}
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci/*
428c2ecf20Sopenharmony_ci * Write exactly 'n' bytes or return an error.
438c2ecf20Sopenharmony_ci */
448c2ecf20Sopenharmony_cissize_t writen(int fd, const void *buf, size_t n)
458c2ecf20Sopenharmony_ci{
468c2ecf20Sopenharmony_ci	/* ion does not modify buf. */
478c2ecf20Sopenharmony_ci	return ion(false, fd, (void *)buf, n);
488c2ecf20Sopenharmony_ci}
49