kfifo_buf.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. #include <linux/slab.h>
  2. #include <linux/kernel.h>
  3. #include <linux/module.h>
  4. #include <linux/device.h>
  5. #include <linux/workqueue.h>
  6. #include <linux/kfifo.h>
  7. #include <linux/mutex.h>
  8. #include <linux/iio/kfifo_buf.h>
  9. #include <linux/sched.h>
  10. #include <linux/poll.h>
  11. struct iio_kfifo {
  12. struct iio_buffer buffer;
  13. struct kfifo kf;
  14. struct mutex user_lock;
  15. int update_needed;
  16. };
  17. #define iio_to_kfifo(r) container_of(r, struct iio_kfifo, buffer)
  18. static inline int __iio_allocate_kfifo(struct iio_kfifo *buf,
  19. int bytes_per_datum, int length)
  20. {
  21. if ((length == 0) || (bytes_per_datum == 0))
  22. return -EINVAL;
  23. return __kfifo_alloc((struct __kfifo *)&buf->kf, length,
  24. bytes_per_datum, GFP_KERNEL);
  25. }
  26. static int iio_request_update_kfifo(struct iio_buffer *r)
  27. {
  28. int ret = 0;
  29. struct iio_kfifo *buf = iio_to_kfifo(r);
  30. mutex_lock(&buf->user_lock);
  31. if (buf->update_needed) {
  32. kfifo_free(&buf->kf);
  33. ret = __iio_allocate_kfifo(buf, buf->buffer.bytes_per_datum,
  34. buf->buffer.length);
  35. buf->update_needed = false;
  36. } else {
  37. kfifo_reset_out(&buf->kf);
  38. }
  39. mutex_unlock(&buf->user_lock);
  40. return ret;
  41. }
  42. static int iio_get_length_kfifo(struct iio_buffer *r)
  43. {
  44. return r->length;
  45. }
  46. static IIO_BUFFER_ENABLE_ATTR;
  47. static IIO_BUFFER_LENGTH_ATTR;
  48. static struct attribute *iio_kfifo_attributes[] = {
  49. &dev_attr_length.attr,
  50. &dev_attr_enable.attr,
  51. NULL,
  52. };
  53. static struct attribute_group iio_kfifo_attribute_group = {
  54. .attrs = iio_kfifo_attributes,
  55. .name = "buffer",
  56. };
  57. static int iio_get_bytes_per_datum_kfifo(struct iio_buffer *r)
  58. {
  59. return r->bytes_per_datum;
  60. }
  61. static int iio_mark_update_needed_kfifo(struct iio_buffer *r)
  62. {
  63. struct iio_kfifo *kf = iio_to_kfifo(r);
  64. kf->update_needed = true;
  65. return 0;
  66. }
  67. static int iio_set_bytes_per_datum_kfifo(struct iio_buffer *r, size_t bpd)
  68. {
  69. if (r->bytes_per_datum != bpd) {
  70. r->bytes_per_datum = bpd;
  71. iio_mark_update_needed_kfifo(r);
  72. }
  73. return 0;
  74. }
  75. static int iio_set_length_kfifo(struct iio_buffer *r, int length)
  76. {
  77. /* Avoid an invalid state */
  78. if (length < 2)
  79. length = 2;
  80. if (r->length != length) {
  81. r->length = length;
  82. iio_mark_update_needed_kfifo(r);
  83. }
  84. return 0;
  85. }
  86. static int iio_store_to_kfifo(struct iio_buffer *r,
  87. const void *data)
  88. {
  89. int ret;
  90. struct iio_kfifo *kf = iio_to_kfifo(r);
  91. ret = kfifo_in(&kf->kf, data, 1);
  92. if (ret != 1)
  93. return -EBUSY;
  94. wake_up_interruptible_poll(&r->pollq, POLLIN | POLLRDNORM);
  95. return 0;
  96. }
  97. static int iio_read_first_n_kfifo(struct iio_buffer *r,
  98. size_t n, char __user *buf)
  99. {
  100. int ret, copied;
  101. struct iio_kfifo *kf = iio_to_kfifo(r);
  102. if (mutex_lock_interruptible(&kf->user_lock))
  103. return -ERESTARTSYS;
  104. if (!kfifo_initialized(&kf->kf) || n < kfifo_esize(&kf->kf))
  105. ret = -EINVAL;
  106. else
  107. ret = kfifo_to_user(&kf->kf, buf, n, &copied);
  108. mutex_unlock(&kf->user_lock);
  109. if (ret < 0)
  110. return ret;
  111. return copied;
  112. }
  113. static bool iio_kfifo_buf_data_available(struct iio_buffer *r)
  114. {
  115. struct iio_kfifo *kf = iio_to_kfifo(r);
  116. bool empty;
  117. mutex_lock(&kf->user_lock);
  118. empty = kfifo_is_empty(&kf->kf);
  119. mutex_unlock(&kf->user_lock);
  120. return !empty;
  121. }
  122. static void iio_kfifo_buffer_release(struct iio_buffer *buffer)
  123. {
  124. struct iio_kfifo *kf = iio_to_kfifo(buffer);
  125. mutex_destroy(&kf->user_lock);
  126. kfifo_free(&kf->kf);
  127. kfree(kf);
  128. }
  129. static const struct iio_buffer_access_funcs kfifo_access_funcs = {
  130. .store_to = &iio_store_to_kfifo,
  131. .read_first_n = &iio_read_first_n_kfifo,
  132. .data_available = iio_kfifo_buf_data_available,
  133. .request_update = &iio_request_update_kfifo,
  134. .get_bytes_per_datum = &iio_get_bytes_per_datum_kfifo,
  135. .set_bytes_per_datum = &iio_set_bytes_per_datum_kfifo,
  136. .get_length = &iio_get_length_kfifo,
  137. .set_length = &iio_set_length_kfifo,
  138. .release = &iio_kfifo_buffer_release,
  139. };
  140. struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev)
  141. {
  142. struct iio_kfifo *kf;
  143. kf = kzalloc(sizeof *kf, GFP_KERNEL);
  144. if (!kf)
  145. return NULL;
  146. kf->update_needed = true;
  147. iio_buffer_init(&kf->buffer);
  148. kf->buffer.attrs = &iio_kfifo_attribute_group;
  149. kf->buffer.access = &kfifo_access_funcs;
  150. kf->buffer.length = 2;
  151. mutex_init(&kf->user_lock);
  152. return &kf->buffer;
  153. }
  154. EXPORT_SYMBOL(iio_kfifo_allocate);
  155. void iio_kfifo_free(struct iio_buffer *r)
  156. {
  157. iio_buffer_put(r);
  158. }
  159. EXPORT_SYMBOL(iio_kfifo_free);
  160. MODULE_LICENSE("GPL");