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