| #ifndef BACKPORT_LINUX_KFIFO_H |
| #define BACKPORT_LINUX_KFIFO_H |
| |
| #include <linux/version.h> |
| #include_next <linux/kfifo.h> |
| |
| #if LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0) |
| #undef kfifo_put |
| /** |
| * kfifo_put - put data into the fifo |
| * @fifo: address of the fifo to be used |
| * @val: the data to be added |
| * |
| * This macro copies the given value into the fifo. |
| * It returns 0 if the fifo was full. Otherwise it returns the number |
| * processed elements. |
| * |
| * Note that with only one concurrent reader and one concurrent |
| * writer, you don't need extra locking to use these macro. |
| */ |
| #define kfifo_put(fifo, val) \ |
| ({ \ |
| typeof((fifo) + 1) __tmp = (fifo); \ |
| typeof((&val) + 1) __val = (&val); \ |
| unsigned int __ret; \ |
| const size_t __recsize = sizeof(*__tmp->rectype); \ |
| struct __kfifo *__kfifo = &__tmp->kfifo; \ |
| if (0) { \ |
| typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \ |
| __dummy = (typeof(__val))NULL; \ |
| } \ |
| if (__recsize) \ |
| __ret = __kfifo_in_r(__kfifo, __val, sizeof(*__val), \ |
| __recsize); \ |
| else { \ |
| __ret = !kfifo_is_full(__tmp); \ |
| if (__ret) { \ |
| (__is_kfifo_ptr(__tmp) ? \ |
| ((typeof(__tmp->type))__kfifo->data) : \ |
| (__tmp->buf) \ |
| )[__kfifo->in & __tmp->kfifo.mask] = \ |
| *(typeof(__tmp->type))__val; \ |
| smp_wmb(); \ |
| __kfifo->in++; \ |
| } \ |
| } \ |
| __ret; \ |
| }) |
| #endif |
| |
| #endif /* BACKPORT_LINUX_KFIFO_H */ |