ath10k: don't enable interrupts for the diagnostic window
[cascardo/linux.git] / lib / iovec.c
1 #include <linux/uaccess.h>
2 #include <linux/export.h>
3 #include <linux/uio.h>
4
5 /*
6  *      Copy iovec to kernel. Returns -EFAULT on error.
7  *
8  *      Note: this modifies the original iovec.
9  */
10
11 int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len)
12 {
13         while (len > 0) {
14                 if (iov->iov_len) {
15                         int copy = min_t(unsigned int, len, iov->iov_len);
16                         if (copy_from_user(kdata, iov->iov_base, copy))
17                                 return -EFAULT;
18                         len -= copy;
19                         kdata += copy;
20                         iov->iov_base += copy;
21                         iov->iov_len -= copy;
22                 }
23                 iov++;
24         }
25
26         return 0;
27 }
28 EXPORT_SYMBOL(memcpy_fromiovec);
29
30 /*
31  *      Copy kernel to iovec. Returns -EFAULT on error.
32  *
33  *      Note: this modifies the original iovec.
34  */
35
36 int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len)
37 {
38         while (len > 0) {
39                 if (iov->iov_len) {
40                         int copy = min_t(unsigned int, iov->iov_len, len);
41                         if (copy_to_user(iov->iov_base, kdata, copy))
42                                 return -EFAULT;
43                         kdata += copy;
44                         len -= copy;
45                         iov->iov_len -= copy;
46                         iov->iov_base += copy;
47                 }
48                 iov++;
49         }
50
51         return 0;
52 }
53 EXPORT_SYMBOL(memcpy_toiovec);
54
55 /*
56  *      Copy kernel to iovec. Returns -EFAULT on error.
57  */
58
59 int memcpy_toiovecend(const struct iovec *iov, unsigned char *kdata,
60                       int offset, int len)
61 {
62         int copy;
63         for (; len > 0; ++iov) {
64                 /* Skip over the finished iovecs */
65                 if (unlikely(offset >= iov->iov_len)) {
66                         offset -= iov->iov_len;
67                         continue;
68                 }
69                 copy = min_t(unsigned int, iov->iov_len - offset, len);
70                 if (copy_to_user(iov->iov_base + offset, kdata, copy))
71                         return -EFAULT;
72                 offset = 0;
73                 kdata += copy;
74                 len -= copy;
75         }
76
77         return 0;
78 }
79 EXPORT_SYMBOL(memcpy_toiovecend);
80
81 /*
82  *      Copy iovec to kernel. Returns -EFAULT on error.
83  */
84
85 int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
86                         int offset, int len)
87 {
88         /* No data? Done! */
89         if (len == 0)
90                 return 0;
91
92         /* Skip over the finished iovecs */
93         while (offset >= iov->iov_len) {
94                 offset -= iov->iov_len;
95                 iov++;
96         }
97
98         while (len > 0) {
99                 u8 __user *base = iov->iov_base + offset;
100                 int copy = min_t(unsigned int, len, iov->iov_len - offset);
101
102                 offset = 0;
103                 if (copy_from_user(kdata, base, copy))
104                         return -EFAULT;
105                 len -= copy;
106                 kdata += copy;
107                 iov++;
108         }
109
110         return 0;
111 }
112 EXPORT_SYMBOL(memcpy_fromiovecend);