1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz> 4 * 5 * Misc memory accessors 6 */ 7 8 #include <linux/export.h> 9 #include <linux/io.h> 10 #include <linux/uaccess.h> 11 #include <sound/core.h> 12 #include <sound/pcm.h> 13 14 /** 15 * copy_to_user_fromio - copy data from mmio-space to user-space 16 * @dst: the destination pointer on user-space 17 * @src: the source pointer on mmio 18 * @count: the data size to copy in bytes 19 * 20 * Copies the data from mmio-space to user-space. 21 * 22 * Return: Zero if successful, or non-zero on failure. 23 */ 24 int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size_t count) 25 { 26 struct iov_iter iter; 27 28 if (import_ubuf(ITER_DEST, dst, count, &iter)) 29 return -EFAULT; 30 if (copy_to_iter_fromio((const void __iomem *)src, count, &iter) != count) 31 return -EFAULT; 32 return 0; 33 } 34 EXPORT_SYMBOL(copy_to_user_fromio); 35 36 /** 37 * copy_to_iter_fromio - copy data from mmio-space to iov_iter 38 * @src: the source pointer on mmio 39 * @count: the data size to copy in bytes 40 * @dst: the destination iov_iter 41 * 42 * Copies the data from mmio-space to iov_iter. 43 * 44 * Return: number of bytes to be copied 45 */ 46 size_t copy_to_iter_fromio(const void __iomem *src, size_t count, 47 struct iov_iter *dst) 48 { 49 #if defined(__i386__) || defined(CONFIG_SPARC32) 50 return copy_to_iter((const void __force *)src, count, dst); 51 #else 52 char buf[256]; 53 size_t res = 0; 54 55 while (count) { 56 size_t c = count; 57 if (c > sizeof(buf)) 58 c = sizeof(buf); 59 memcpy_fromio(buf, (void __iomem *)src, c); 60 if (copy_to_iter(buf, c, dst) != c) 61 return res; 62 count -= c; 63 src += c; 64 res += c; 65 } 66 return res; 67 #endif 68 } 69 EXPORT_SYMBOL(copy_to_iter_fromio); 70 71 /** 72 * copy_from_user_toio - copy data from user-space to mmio-space 73 * @dst: the destination pointer on mmio-space 74 * @src: the source pointer on user-space 75 * @count: the data size to copy in bytes 76 * 77 * Copies the data from user-space to mmio-space. 78 * 79 * Return: Zero if successful, or non-zero on failure. 80 */ 81 int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size_t count) 82 { 83 struct iov_iter iter; 84 85 if (import_ubuf(ITER_SOURCE, (void __user *)src, count, &iter)) 86 return -EFAULT; 87 if (copy_from_iter_toio((void __iomem *)dst, count, &iter) != count) 88 return -EFAULT; 89 return 0; 90 } 91 EXPORT_SYMBOL(copy_from_user_toio); 92 93 /** 94 * copy_from_iter_toio - copy data from iov_iter to mmio-space 95 * @dst: the destination pointer on mmio-space 96 * @count: the data size to copy in bytes 97 * @src: the source iov_iter 98 * 99 * Copies the data from iov_iter to mmio-space. 100 * 101 * Return: number of bytes to be copied 102 */ 103 size_t copy_from_iter_toio(void __iomem *dst, size_t count, 104 struct iov_iter *src) 105 { 106 #if defined(__i386__) || defined(CONFIG_SPARC32) 107 return copy_from_iter((void __force *)dst, count, src); 108 #else 109 char buf[256]; 110 size_t res = 0; 111 112 while (count) { 113 size_t c = count; 114 if (c > sizeof(buf)) 115 c = sizeof(buf); 116 if (copy_from_iter(buf, c, src) != c) 117 return res; 118 memcpy_toio(dst, buf, c); 119 count -= c; 120 dst += c; 121 res += c; 122 } 123 return res; 124 #endif 125 } 126 EXPORT_SYMBOL(copy_from_iter_toio); 127