memory.c 3.1 KB

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