^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <stdbool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <internal/lib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) unsigned int page_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) static ssize_t ion(bool is_read, int fd, void *buf, size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) void *buf_start = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) size_t left = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) while (left) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /* buf must be treated as const if !is_read. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) ssize_t ret = is_read ? read(fd, buf, left) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) write(fd, buf, left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) if (ret < 0 && errno == EINTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) if (ret <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) left -= ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) buf += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) BUG_ON((size_t)(buf - buf_start) != n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * Read exactly 'n' bytes or return an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) ssize_t readn(int fd, void *buf, size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) return ion(true, fd, buf, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * Write exactly 'n' bytes or return an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) ssize_t writen(int fd, const void *buf, size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /* ion does not modify buf. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) return ion(false, fd, (void *)buf, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }