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 return copy_to_iter_fromio(&iter, (const void __iomem *)src, count); 31 } 32 EXPORT_SYMBOL(copy_to_user_fromio); 33 34 /** 35 * copy_to_iter_fromio - copy data from mmio-space to iov_iter 36 * @dst: the destination iov_iter 37 * @src: the source pointer on mmio 38 * @count: the data size to copy in bytes 39 * 40 * Copies the data from mmio-space to iov_iter. 41 * 42 * Return: Zero if successful, or non-zero on failure. 43 */ 44 int copy_to_iter_fromio(struct iov_iter *dst, const void __iomem *src, 45 size_t count) 46 { 47 #if defined(__i386__) || defined(CONFIG_SPARC32) 48 return copy_to_iter((const void __force *)src, count, dst) == count ? 0 : -EFAULT; 49 #else 50 char buf[256]; 51 while (count) { 52 size_t c = count; 53 if (c > sizeof(buf)) 54 c = sizeof(buf); 55 memcpy_fromio(buf, (void __iomem *)src, c); 56 if (copy_to_iter(buf, c, dst) != c) 57 return -EFAULT; 58 count -= c; 59 src += c; 60 } 61 return 0; 62 #endif 63 } 64 EXPORT_SYMBOL(copy_to_iter_fromio); 65 66 /** 67 * copy_from_user_toio - copy data from user-space to mmio-space 68 * @dst: the destination pointer on mmio-space 69 * @src: the source pointer on user-space 70 * @count: the data size to copy in bytes 71 * 72 * Copies the data from user-space to mmio-space. 73 * 74 * Return: Zero if successful, or non-zero on failure. 75 */ 76 int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size_t count) 77 { 78 struct iov_iter iter; 79 80 if (import_ubuf(ITER_SOURCE, (void __user *)src, count, &iter)) 81 return -EFAULT; 82 return copy_from_iter_toio((void __iomem *)dst, &iter, count); 83 } 84 EXPORT_SYMBOL(copy_from_user_toio); 85 86 /** 87 * copy_from_iter_toio - copy data from iov_iter to mmio-space 88 * @dst: the destination pointer on mmio-space 89 * @src: the source iov_iter 90 * @count: the data size to copy in bytes 91 * 92 * Copies the data from iov_iter to mmio-space. 93 * 94 * Return: Zero if successful, or non-zero on failure. 95 */ 96 int copy_from_iter_toio(void __iomem *dst, struct iov_iter *src, size_t count) 97 { 98 #if defined(__i386__) || defined(CONFIG_SPARC32) 99 return copy_from_iter((void __force *)dst, count, src) == count ? 0 : -EFAULT; 100 #else 101 char buf[256]; 102 while (count) { 103 size_t c = count; 104 if (c > sizeof(buf)) 105 c = sizeof(buf); 106 if (copy_from_iter(buf, c, src) != c) 107 return -EFAULT; 108 memcpy_toio(dst, buf, c); 109 count -= c; 110 dst += c; 111 } 112 return 0; 113 #endif 114 } 115 EXPORT_SYMBOL(copy_from_iter_toio); 116