174ba9207SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */ 21da177e4SLinus Torvalds /* 32e956fb3SStefani Seibold * A generic kernel FIFO implementation 41da177e4SLinus Torvalds * 5498d319bSStefani Seibold * Copyright (C) 2013 Stefani Seibold <stefani@seibold.net> 61da177e4SLinus Torvalds */ 77acd72ebSStefani Seibold 82e956fb3SStefani Seibold #ifndef _LINUX_KFIFO_H 92e956fb3SStefani Seibold #define _LINUX_KFIFO_H 102e956fb3SStefani Seibold 117acd72ebSStefani Seibold /* 122e956fb3SStefani Seibold * How to porting drivers to the new generic FIFO API: 137acd72ebSStefani Seibold * 147acd72ebSStefani Seibold * - Modify the declaration of the "struct kfifo *" object into a 157acd72ebSStefani Seibold * in-place "struct kfifo" object 167acd72ebSStefani Seibold * - Init the in-place object with kfifo_alloc() or kfifo_init() 177acd72ebSStefani Seibold * Note: The address of the in-place "struct kfifo" object must be 187acd72ebSStefani Seibold * passed as the first argument to this functions 197acd72ebSStefani Seibold * - Replace the use of __kfifo_put into kfifo_in and __kfifo_get 207acd72ebSStefani Seibold * into kfifo_out 212e956fb3SStefani Seibold * - Replace the use of kfifo_put into kfifo_in_spinlocked and kfifo_get 222e956fb3SStefani Seibold * into kfifo_out_spinlocked 237acd72ebSStefani Seibold * Note: the spinlock pointer formerly passed to kfifo_init/kfifo_alloc 242e956fb3SStefani Seibold * must be passed now to the kfifo_in_spinlocked and kfifo_out_spinlocked 252e956fb3SStefani Seibold * as the last parameter 262e956fb3SStefani Seibold * - The formerly __kfifo_* functions are renamed into kfifo_* 277acd72ebSStefani Seibold */ 287acd72ebSStefani Seibold 292e956fb3SStefani Seibold /* 30de99626cSValentin Vidic * Note about locking: There is no locking required until only one reader 31de99626cSValentin Vidic * and one writer is using the fifo and no kfifo_reset() will be called. 322e956fb3SStefani Seibold * kfifo_reset_out() can be safely used, until it will be only called 332e956fb3SStefani Seibold * in the reader thread. 342e956fb3SStefani Seibold * For multiple writer and one reader there is only a need to lock the writer. 352e956fb3SStefani Seibold * And vice versa for only one writer and multiple reader there is only a need 362e956fb3SStefani Seibold * to lock the reader. 372e956fb3SStefani Seibold */ 381da177e4SLinus Torvalds 391da177e4SLinus Torvalds #include <linux/kernel.h> 401da177e4SLinus Torvalds #include <linux/spinlock.h> 412e956fb3SStefani Seibold #include <linux/stddef.h> 422e956fb3SStefani Seibold #include <linux/scatterlist.h> 431da177e4SLinus Torvalds 442e956fb3SStefani Seibold struct __kfifo { 452e956fb3SStefani Seibold unsigned int in; 462e956fb3SStefani Seibold unsigned int out; 472e956fb3SStefani Seibold unsigned int mask; 482e956fb3SStefani Seibold unsigned int esize; 492e956fb3SStefani Seibold void *data; 501da177e4SLinus Torvalds }; 511da177e4SLinus Torvalds 522e956fb3SStefani Seibold #define __STRUCT_KFIFO_COMMON(datatype, recsize, ptrtype) \ 532e956fb3SStefani Seibold union { \ 542e956fb3SStefani Seibold struct __kfifo kfifo; \ 552e956fb3SStefani Seibold datatype *type; \ 56498d319bSStefani Seibold const datatype *const_type; \ 572e956fb3SStefani Seibold char (*rectype)[recsize]; \ 582e956fb3SStefani Seibold ptrtype *ptr; \ 59498d319bSStefani Seibold ptrtype const *ptr_const; \ 602e956fb3SStefani Seibold } 6137bdfbbfSStefani Seibold 622e956fb3SStefani Seibold #define __STRUCT_KFIFO(type, size, recsize, ptrtype) \ 632e956fb3SStefani Seibold { \ 642e956fb3SStefani Seibold __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ 652e956fb3SStefani Seibold type buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \ 662e956fb3SStefani Seibold } 672e956fb3SStefani Seibold 682e956fb3SStefani Seibold #define STRUCT_KFIFO(type, size) \ 692e956fb3SStefani Seibold struct __STRUCT_KFIFO(type, size, 0, type) 702e956fb3SStefani Seibold 712e956fb3SStefani Seibold #define __STRUCT_KFIFO_PTR(type, recsize, ptrtype) \ 722e956fb3SStefani Seibold { \ 732e956fb3SStefani Seibold __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ 742e956fb3SStefani Seibold type buf[0]; \ 752e956fb3SStefani Seibold } 762e956fb3SStefani Seibold 772e956fb3SStefani Seibold #define STRUCT_KFIFO_PTR(type) \ 782e956fb3SStefani Seibold struct __STRUCT_KFIFO_PTR(type, 0, type) 792e956fb3SStefani Seibold 802e956fb3SStefani Seibold /* 812e956fb3SStefani Seibold * define compatibility "struct kfifo" for dynamic allocated fifos 822e956fb3SStefani Seibold */ 832e956fb3SStefani Seibold struct kfifo __STRUCT_KFIFO_PTR(unsigned char, 0, void); 842e956fb3SStefani Seibold 852e956fb3SStefani Seibold #define STRUCT_KFIFO_REC_1(size) \ 862e956fb3SStefani Seibold struct __STRUCT_KFIFO(unsigned char, size, 1, void) 872e956fb3SStefani Seibold 882e956fb3SStefani Seibold #define STRUCT_KFIFO_REC_2(size) \ 892e956fb3SStefani Seibold struct __STRUCT_KFIFO(unsigned char, size, 2, void) 902e956fb3SStefani Seibold 912e956fb3SStefani Seibold /* 922e956fb3SStefani Seibold * define kfifo_rec types 932e956fb3SStefani Seibold */ 942e956fb3SStefani Seibold struct kfifo_rec_ptr_1 __STRUCT_KFIFO_PTR(unsigned char, 1, void); 952e956fb3SStefani Seibold struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2, void); 962e956fb3SStefani Seibold 972e956fb3SStefani Seibold /* 982e956fb3SStefani Seibold * helper macro to distinguish between real in place fifo where the fifo 992e956fb3SStefani Seibold * array is a part of the structure and the fifo type where the array is 1002e956fb3SStefani Seibold * outside of the fifo structure. 1012e956fb3SStefani Seibold */ 1028a866feeSSean Young #define __is_kfifo_ptr(fifo) \ 1038a866feeSSean Young (sizeof(*fifo) == sizeof(STRUCT_KFIFO_PTR(typeof(*(fifo)->type)))) 1042e956fb3SStefani Seibold 1052e956fb3SStefani Seibold /** 1062e956fb3SStefani Seibold * DECLARE_KFIFO_PTR - macro to declare a fifo pointer object 1072e956fb3SStefani Seibold * @fifo: name of the declared fifo 1082e956fb3SStefani Seibold * @type: type of the fifo elements 1092e956fb3SStefani Seibold */ 1102e956fb3SStefani Seibold #define DECLARE_KFIFO_PTR(fifo, type) STRUCT_KFIFO_PTR(type) fifo 1112e956fb3SStefani Seibold 1122e956fb3SStefani Seibold /** 1132e956fb3SStefani Seibold * DECLARE_KFIFO - macro to declare a fifo object 1142e956fb3SStefani Seibold * @fifo: name of the declared fifo 1152e956fb3SStefani Seibold * @type: type of the fifo elements 1162e956fb3SStefani Seibold * @size: the number of elements in the fifo, this must be a power of 2 1172e956fb3SStefani Seibold */ 1182e956fb3SStefani Seibold #define DECLARE_KFIFO(fifo, type, size) STRUCT_KFIFO(type, size) fifo 1192e956fb3SStefani Seibold 1202e956fb3SStefani Seibold /** 1212e956fb3SStefani Seibold * INIT_KFIFO - Initialize a fifo declared by DECLARE_KFIFO 1222e956fb3SStefani Seibold * @fifo: name of the declared fifo datatype 1232e956fb3SStefani Seibold */ 1242e956fb3SStefani Seibold #define INIT_KFIFO(fifo) \ 1252e956fb3SStefani Seibold (void)({ \ 1262e956fb3SStefani Seibold typeof(&(fifo)) __tmp = &(fifo); \ 1272e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 1282e956fb3SStefani Seibold __kfifo->in = 0; \ 1292e956fb3SStefani Seibold __kfifo->out = 0; \ 1302e956fb3SStefani Seibold __kfifo->mask = __is_kfifo_ptr(__tmp) ? 0 : ARRAY_SIZE(__tmp->buf) - 1;\ 1312e956fb3SStefani Seibold __kfifo->esize = sizeof(*__tmp->buf); \ 1322e956fb3SStefani Seibold __kfifo->data = __is_kfifo_ptr(__tmp) ? NULL : __tmp->buf; \ 1332e956fb3SStefani Seibold }) 1342e956fb3SStefani Seibold 1352e956fb3SStefani Seibold /** 1362e956fb3SStefani Seibold * DEFINE_KFIFO - macro to define and initialize a fifo 1372e956fb3SStefani Seibold * @fifo: name of the declared fifo datatype 1382e956fb3SStefani Seibold * @type: type of the fifo elements 1392e956fb3SStefani Seibold * @size: the number of elements in the fifo, this must be a power of 2 1402e956fb3SStefani Seibold * 1412e956fb3SStefani Seibold * Note: the macro can be used for global and local fifo data type variables. 1422e956fb3SStefani Seibold */ 1432e956fb3SStefani Seibold #define DEFINE_KFIFO(fifo, type, size) \ 1442e956fb3SStefani Seibold DECLARE_KFIFO(fifo, type, size) = \ 1452e956fb3SStefani Seibold (typeof(fifo)) { \ 1462e956fb3SStefani Seibold { \ 1472e956fb3SStefani Seibold { \ 14837bdfbbfSStefani Seibold .in = 0, \ 14937bdfbbfSStefani Seibold .out = 0, \ 1502e956fb3SStefani Seibold .mask = __is_kfifo_ptr(&(fifo)) ? \ 1512e956fb3SStefani Seibold 0 : \ 1522e956fb3SStefani Seibold ARRAY_SIZE((fifo).buf) - 1, \ 1532e956fb3SStefani Seibold .esize = sizeof(*(fifo).buf), \ 1542e956fb3SStefani Seibold .data = __is_kfifo_ptr(&(fifo)) ? \ 1552e956fb3SStefani Seibold NULL : \ 1562e956fb3SStefani Seibold (fifo).buf, \ 1572e956fb3SStefani Seibold } \ 1582e956fb3SStefani Seibold } \ 1592e956fb3SStefani Seibold } 1602e956fb3SStefani Seibold 1612e956fb3SStefani Seibold 162144ecf31SStefani Seibold static inline unsigned int __must_check 163144ecf31SStefani Seibold __kfifo_uint_must_check_helper(unsigned int val) 164144ecf31SStefani Seibold { 165144ecf31SStefani Seibold return val; 166144ecf31SStefani Seibold } 167144ecf31SStefani Seibold 168144ecf31SStefani Seibold static inline int __must_check 169144ecf31SStefani Seibold __kfifo_int_must_check_helper(int val) 170144ecf31SStefani Seibold { 171144ecf31SStefani Seibold return val; 172144ecf31SStefani Seibold } 17337bdfbbfSStefani Seibold 17437bdfbbfSStefani Seibold /** 1752e956fb3SStefani Seibold * kfifo_initialized - Check if the fifo is initialized 1762e956fb3SStefani Seibold * @fifo: address of the fifo to check 17737bdfbbfSStefani Seibold * 1782e956fb3SStefani Seibold * Return %true if fifo is initialized, otherwise %false. 179d994ffc2SAndi Kleen * Assumes the fifo was 0 before. 180d994ffc2SAndi Kleen */ 1812e956fb3SStefani Seibold #define kfifo_initialized(fifo) ((fifo)->kfifo.mask) 1821da177e4SLinus Torvalds 1831da177e4SLinus Torvalds /** 1842e956fb3SStefani Seibold * kfifo_esize - returns the size of the element managed by the fifo 1852e956fb3SStefani Seibold * @fifo: address of the fifo to be used 1861da177e4SLinus Torvalds */ 1872e956fb3SStefani Seibold #define kfifo_esize(fifo) ((fifo)->kfifo.esize) 1881da177e4SLinus Torvalds 1891da177e4SLinus Torvalds /** 1902e956fb3SStefani Seibold * kfifo_recsize - returns the size of the record length field 1912e956fb3SStefani Seibold * @fifo: address of the fifo to be used 192a121f24aSStefani Seibold */ 1932e956fb3SStefani Seibold #define kfifo_recsize(fifo) (sizeof(*(fifo)->rectype)) 194a121f24aSStefani Seibold 195a121f24aSStefani Seibold /** 1962e956fb3SStefani Seibold * kfifo_size - returns the size of the fifo in elements 1972e956fb3SStefani Seibold * @fifo: address of the fifo to be used 19837bdfbbfSStefani Seibold */ 1992e956fb3SStefani Seibold #define kfifo_size(fifo) ((fifo)->kfifo.mask + 1) 20037bdfbbfSStefani Seibold 20137bdfbbfSStefani Seibold /** 2022e956fb3SStefani Seibold * kfifo_reset - removes the entire fifo content 2032e956fb3SStefani Seibold * @fifo: address of the fifo to be used 2042e956fb3SStefani Seibold * 2052e956fb3SStefani Seibold * Note: usage of kfifo_reset() is dangerous. It should be only called when the 2062e956fb3SStefani Seibold * fifo is exclusived locked or when it is secured that no other thread is 2072e956fb3SStefani Seibold * accessing the fifo. 208c1e13f25SStefani Seibold */ 2092e956fb3SStefani Seibold #define kfifo_reset(fifo) \ 2102e956fb3SStefani Seibold (void)({ \ 211e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 2122e956fb3SStefani Seibold __tmp->kfifo.in = __tmp->kfifo.out = 0; \ 2132e956fb3SStefani Seibold }) 214c1e13f25SStefani Seibold 2152e956fb3SStefani Seibold /** 2162e956fb3SStefani Seibold * kfifo_reset_out - skip fifo content 2172e956fb3SStefani Seibold * @fifo: address of the fifo to be used 2182e956fb3SStefani Seibold * 2192e956fb3SStefani Seibold * Note: The usage of kfifo_reset_out() is safe until it will be only called 2202e956fb3SStefani Seibold * from the reader thread and there is only one concurrent reader. Otherwise 2212e956fb3SStefani Seibold * it is dangerous and must be handled in the same way as kfifo_reset(). 2222e956fb3SStefani Seibold */ 2232e956fb3SStefani Seibold #define kfifo_reset_out(fifo) \ 2242e956fb3SStefani Seibold (void)({ \ 225e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 2262e956fb3SStefani Seibold __tmp->kfifo.out = __tmp->kfifo.in; \ 2272e956fb3SStefani Seibold }) 2282e956fb3SStefani Seibold 2292e956fb3SStefani Seibold /** 2302e956fb3SStefani Seibold * kfifo_len - returns the number of used elements in the fifo 2312e956fb3SStefani Seibold * @fifo: address of the fifo to be used 2322e956fb3SStefani Seibold */ 2332e956fb3SStefani Seibold #define kfifo_len(fifo) \ 2342e956fb3SStefani Seibold ({ \ 235e0bf1024SHuang Ying typeof((fifo) + 1) __tmpl = (fifo); \ 2362e956fb3SStefani Seibold __tmpl->kfifo.in - __tmpl->kfifo.out; \ 2372e956fb3SStefani Seibold }) 238c1e13f25SStefani Seibold 239c1e13f25SStefani Seibold /** 24037bdfbbfSStefani Seibold * kfifo_is_empty - returns true if the fifo is empty 2412e956fb3SStefani Seibold * @fifo: address of the fifo to be used 24237bdfbbfSStefani Seibold */ 2432e956fb3SStefani Seibold #define kfifo_is_empty(fifo) \ 2442e956fb3SStefani Seibold ({ \ 245e0bf1024SHuang Ying typeof((fifo) + 1) __tmpq = (fifo); \ 2462e956fb3SStefani Seibold __tmpq->kfifo.in == __tmpq->kfifo.out; \ 2472e956fb3SStefani Seibold }) 24837bdfbbfSStefani Seibold 24937bdfbbfSStefani Seibold /** 2505195a89eSBartosz Golaszewski * kfifo_is_empty_spinlocked - returns true if the fifo is empty using 2515195a89eSBartosz Golaszewski * a spinlock for locking 2525195a89eSBartosz Golaszewski * @fifo: address of the fifo to be used 2535195a89eSBartosz Golaszewski * @lock: spinlock to be used for locking 2545195a89eSBartosz Golaszewski */ 2555195a89eSBartosz Golaszewski #define kfifo_is_empty_spinlocked(fifo, lock) \ 2565195a89eSBartosz Golaszewski ({ \ 2575195a89eSBartosz Golaszewski unsigned long __flags; \ 2585195a89eSBartosz Golaszewski bool __ret; \ 2595195a89eSBartosz Golaszewski spin_lock_irqsave(lock, __flags); \ 2605195a89eSBartosz Golaszewski __ret = kfifo_is_empty(fifo); \ 2615195a89eSBartosz Golaszewski spin_unlock_irqrestore(lock, __flags); \ 2625195a89eSBartosz Golaszewski __ret; \ 2635195a89eSBartosz Golaszewski }) 2645195a89eSBartosz Golaszewski 2655195a89eSBartosz Golaszewski /** 2665195a89eSBartosz Golaszewski * kfifo_is_empty_spinlocked_noirqsave - returns true if the fifo is empty 2675195a89eSBartosz Golaszewski * using a spinlock for locking, doesn't disable interrupts 2685195a89eSBartosz Golaszewski * @fifo: address of the fifo to be used 2695195a89eSBartosz Golaszewski * @lock: spinlock to be used for locking 2705195a89eSBartosz Golaszewski */ 2715195a89eSBartosz Golaszewski #define kfifo_is_empty_spinlocked_noirqsave(fifo, lock) \ 2725195a89eSBartosz Golaszewski ({ \ 2735195a89eSBartosz Golaszewski bool __ret; \ 2745195a89eSBartosz Golaszewski spin_lock(lock); \ 2755195a89eSBartosz Golaszewski __ret = kfifo_is_empty(fifo); \ 2765195a89eSBartosz Golaszewski spin_unlock(lock); \ 2775195a89eSBartosz Golaszewski __ret; \ 2785195a89eSBartosz Golaszewski }) 2795195a89eSBartosz Golaszewski 2805195a89eSBartosz Golaszewski /** 28137bdfbbfSStefani Seibold * kfifo_is_full - returns true if the fifo is full 2822e956fb3SStefani Seibold * @fifo: address of the fifo to be used 28337bdfbbfSStefani Seibold */ 2842e956fb3SStefani Seibold #define kfifo_is_full(fifo) \ 2852e956fb3SStefani Seibold ({ \ 286e0bf1024SHuang Ying typeof((fifo) + 1) __tmpq = (fifo); \ 2872e956fb3SStefani Seibold kfifo_len(__tmpq) > __tmpq->kfifo.mask; \ 2882e956fb3SStefani Seibold }) 28937bdfbbfSStefani Seibold 29037bdfbbfSStefani Seibold /** 2912e956fb3SStefani Seibold * kfifo_avail - returns the number of unused elements in the fifo 2922e956fb3SStefani Seibold * @fifo: address of the fifo to be used 29337bdfbbfSStefani Seibold */ 2942e956fb3SStefani Seibold #define kfifo_avail(fifo) \ 295144ecf31SStefani Seibold __kfifo_uint_must_check_helper( \ 2962e956fb3SStefani Seibold ({ \ 297e0bf1024SHuang Ying typeof((fifo) + 1) __tmpq = (fifo); \ 2982e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmpq->rectype); \ 2992e956fb3SStefani Seibold unsigned int __avail = kfifo_size(__tmpq) - kfifo_len(__tmpq); \ 3002e956fb3SStefani Seibold (__recsize) ? ((__avail <= __recsize) ? 0 : \ 3012e956fb3SStefani Seibold __kfifo_max_r(__avail - __recsize, __recsize)) : \ 3022e956fb3SStefani Seibold __avail; \ 3032e956fb3SStefani Seibold }) \ 30486d48803SStefani Seibold ) 30586d48803SStefani Seibold 3062e956fb3SStefani Seibold /** 307*76738194SJiri Slaby (SUSE) * kfifo_skip_count - skip output data 3082e956fb3SStefani Seibold * @fifo: address of the fifo to be used 309*76738194SJiri Slaby (SUSE) * @count: count of data to skip 31086d48803SStefani Seibold */ 311*76738194SJiri Slaby (SUSE) #define kfifo_skip_count(fifo, count) do { \ 312e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 3132e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmp->rectype); \ 3142e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 3152e956fb3SStefani Seibold if (__recsize) \ 3162e956fb3SStefani Seibold __kfifo_skip_r(__kfifo, __recsize); \ 3172e956fb3SStefani Seibold else \ 318*76738194SJiri Slaby (SUSE) __kfifo->out += (count); \ 319*76738194SJiri Slaby (SUSE) } while(0) 320*76738194SJiri Slaby (SUSE) 321*76738194SJiri Slaby (SUSE) /** 322*76738194SJiri Slaby (SUSE) * kfifo_skip - skip output data 323*76738194SJiri Slaby (SUSE) * @fifo: address of the fifo to be used 324*76738194SJiri Slaby (SUSE) */ 325*76738194SJiri Slaby (SUSE) #define kfifo_skip(fifo) kfifo_skip_count(fifo, 1) 32686d48803SStefani Seibold 32786d48803SStefani Seibold /** 3282e956fb3SStefani Seibold * kfifo_peek_len - gets the size of the next fifo record 3292e956fb3SStefani Seibold * @fifo: address of the fifo to be used 33086d48803SStefani Seibold * 3312e956fb3SStefani Seibold * This function returns the size of the next fifo record in number of bytes. 3322e956fb3SStefani Seibold */ 3332e956fb3SStefani Seibold #define kfifo_peek_len(fifo) \ 334144ecf31SStefani Seibold __kfifo_uint_must_check_helper( \ 3352e956fb3SStefani Seibold ({ \ 336e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 3372e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmp->rectype); \ 3382e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 3392e956fb3SStefani Seibold (!__recsize) ? kfifo_len(__tmp) * sizeof(*__tmp->type) : \ 3402e956fb3SStefani Seibold __kfifo_len_r(__kfifo, __recsize); \ 3412e956fb3SStefani Seibold }) \ 3422e956fb3SStefani Seibold ) 3432e956fb3SStefani Seibold 3442e956fb3SStefani Seibold /** 3452e956fb3SStefani Seibold * kfifo_alloc - dynamically allocates a new fifo buffer 3462e956fb3SStefani Seibold * @fifo: pointer to the fifo 3472e956fb3SStefani Seibold * @size: the number of elements in the fifo, this must be a power of 2 3482e956fb3SStefani Seibold * @gfp_mask: get_free_pages mask, passed to kmalloc() 3492e956fb3SStefani Seibold * 3502e956fb3SStefani Seibold * This macro dynamically allocates a new fifo buffer. 3512e956fb3SStefani Seibold * 35224d654faSChristophe JAILLET * The number of elements will be rounded-up to a power of 2. 3532e956fb3SStefani Seibold * The fifo will be release with kfifo_free(). 3542e956fb3SStefani Seibold * Return 0 if no error, otherwise an error code. 3552e956fb3SStefani Seibold */ 3562e956fb3SStefani Seibold #define kfifo_alloc(fifo, size, gfp_mask) \ 357144ecf31SStefani Seibold __kfifo_int_must_check_helper( \ 3582e956fb3SStefani Seibold ({ \ 359e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 3602e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 3612e956fb3SStefani Seibold __is_kfifo_ptr(__tmp) ? \ 3622e956fb3SStefani Seibold __kfifo_alloc(__kfifo, size, sizeof(*__tmp->type), gfp_mask) : \ 3632e956fb3SStefani Seibold -EINVAL; \ 3642e956fb3SStefani Seibold }) \ 3652e956fb3SStefani Seibold ) 3662e956fb3SStefani Seibold 3672e956fb3SStefani Seibold /** 3682e956fb3SStefani Seibold * kfifo_free - frees the fifo 3692e956fb3SStefani Seibold * @fifo: the fifo to be freed 3702e956fb3SStefani Seibold */ 3712e956fb3SStefani Seibold #define kfifo_free(fifo) \ 3722e956fb3SStefani Seibold ({ \ 373e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 3742e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 3752e956fb3SStefani Seibold if (__is_kfifo_ptr(__tmp)) \ 3762e956fb3SStefani Seibold __kfifo_free(__kfifo); \ 3772e956fb3SStefani Seibold }) 3782e956fb3SStefani Seibold 3792e956fb3SStefani Seibold /** 3802e956fb3SStefani Seibold * kfifo_init - initialize a fifo using a preallocated buffer 3812e956fb3SStefani Seibold * @fifo: the fifo to assign the buffer 3822e956fb3SStefani Seibold * @buffer: the preallocated buffer to be used 3832e956fb3SStefani Seibold * @size: the size of the internal buffer, this have to be a power of 2 3842e956fb3SStefani Seibold * 38524d654faSChristophe JAILLET * This macro initializes a fifo using a preallocated buffer. 3862e956fb3SStefani Seibold * 38724d654faSChristophe JAILLET * The number of elements will be rounded-up to a power of 2. 3882e956fb3SStefani Seibold * Return 0 if no error, otherwise an error code. 3892e956fb3SStefani Seibold */ 3902e956fb3SStefani Seibold #define kfifo_init(fifo, buffer, size) \ 3912e956fb3SStefani Seibold ({ \ 392e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 3932e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 3942e956fb3SStefani Seibold __is_kfifo_ptr(__tmp) ? \ 3952e956fb3SStefani Seibold __kfifo_init(__kfifo, buffer, size, sizeof(*__tmp->type)) : \ 3962e956fb3SStefani Seibold -EINVAL; \ 3972e956fb3SStefani Seibold }) 3982e956fb3SStefani Seibold 3992e956fb3SStefani Seibold /** 4002e956fb3SStefani Seibold * kfifo_put - put data into the fifo 4012e956fb3SStefani Seibold * @fifo: address of the fifo to be used 4022e956fb3SStefani Seibold * @val: the data to be added 4032e956fb3SStefani Seibold * 4042e956fb3SStefani Seibold * This macro copies the given value into the fifo. 4052e956fb3SStefani Seibold * It returns 0 if the fifo was full. Otherwise it returns the number 4062e956fb3SStefani Seibold * processed elements. 40786d48803SStefani Seibold * 40886d48803SStefani Seibold * Note that with only one concurrent reader and one concurrent 4092e956fb3SStefani Seibold * writer, you don't need extra locking to use these macro. 41086d48803SStefani Seibold */ 4112e956fb3SStefani Seibold #define kfifo_put(fifo, val) \ 4122e956fb3SStefani Seibold ({ \ 413e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 414498d319bSStefani Seibold typeof(*__tmp->const_type) __val = (val); \ 4152e956fb3SStefani Seibold unsigned int __ret; \ 416498d319bSStefani Seibold size_t __recsize = sizeof(*__tmp->rectype); \ 4172e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 4182e956fb3SStefani Seibold if (__recsize) \ 419498d319bSStefani Seibold __ret = __kfifo_in_r(__kfifo, &__val, sizeof(__val), \ 4202e956fb3SStefani Seibold __recsize); \ 4212e956fb3SStefani Seibold else { \ 4222e956fb3SStefani Seibold __ret = !kfifo_is_full(__tmp); \ 4232e956fb3SStefani Seibold if (__ret) { \ 4242e956fb3SStefani Seibold (__is_kfifo_ptr(__tmp) ? \ 4252e956fb3SStefani Seibold ((typeof(__tmp->type))__kfifo->data) : \ 4262e956fb3SStefani Seibold (__tmp->buf) \ 4272e956fb3SStefani Seibold )[__kfifo->in & __tmp->kfifo.mask] = \ 42821b2f443SStefani Seibold *(typeof(__tmp->type))&__val; \ 4292e956fb3SStefani Seibold smp_wmb(); \ 4302e956fb3SStefani Seibold __kfifo->in++; \ 4312e956fb3SStefani Seibold } \ 4322e956fb3SStefani Seibold } \ 4332e956fb3SStefani Seibold __ret; \ 4342e956fb3SStefani Seibold }) 43586d48803SStefani Seibold 43686d48803SStefani Seibold /** 4372e956fb3SStefani Seibold * kfifo_get - get data from the fifo 4382e956fb3SStefani Seibold * @fifo: address of the fifo to be used 439498d319bSStefani Seibold * @val: address where to store the data 44086d48803SStefani Seibold * 4412e956fb3SStefani Seibold * This macro reads the data from the fifo. 4422e956fb3SStefani Seibold * It returns 0 if the fifo was empty. Otherwise it returns the number 4432e956fb3SStefani Seibold * processed elements. 44486d48803SStefani Seibold * 44586d48803SStefani Seibold * Note that with only one concurrent reader and one concurrent 4462e956fb3SStefani Seibold * writer, you don't need extra locking to use these macro. 44786d48803SStefani Seibold */ 4482e956fb3SStefani Seibold #define kfifo_get(fifo, val) \ 449144ecf31SStefani Seibold __kfifo_uint_must_check_helper( \ 4502e956fb3SStefani Seibold ({ \ 451e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 452498d319bSStefani Seibold typeof(__tmp->ptr) __val = (val); \ 4532e956fb3SStefani Seibold unsigned int __ret; \ 4542e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmp->rectype); \ 4552e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 4562e956fb3SStefani Seibold if (__recsize) \ 4572e956fb3SStefani Seibold __ret = __kfifo_out_r(__kfifo, __val, sizeof(*__val), \ 4582e956fb3SStefani Seibold __recsize); \ 4592e956fb3SStefani Seibold else { \ 4602e956fb3SStefani Seibold __ret = !kfifo_is_empty(__tmp); \ 4612e956fb3SStefani Seibold if (__ret) { \ 4622e956fb3SStefani Seibold *(typeof(__tmp->type))__val = \ 4632e956fb3SStefani Seibold (__is_kfifo_ptr(__tmp) ? \ 4642e956fb3SStefani Seibold ((typeof(__tmp->type))__kfifo->data) : \ 4652e956fb3SStefani Seibold (__tmp->buf) \ 4662e956fb3SStefani Seibold )[__kfifo->out & __tmp->kfifo.mask]; \ 4672e956fb3SStefani Seibold smp_wmb(); \ 4682e956fb3SStefani Seibold __kfifo->out++; \ 4692e956fb3SStefani Seibold } \ 4702e956fb3SStefani Seibold } \ 4712e956fb3SStefani Seibold __ret; \ 4722e956fb3SStefani Seibold }) \ 4732e956fb3SStefani Seibold ) 47486d48803SStefani Seibold 47586d48803SStefani Seibold /** 4762e956fb3SStefani Seibold * kfifo_peek - get data from the fifo without removing 4772e956fb3SStefani Seibold * @fifo: address of the fifo to be used 478498d319bSStefani Seibold * @val: address where to store the data 47986d48803SStefani Seibold * 4802e956fb3SStefani Seibold * This reads the data from the fifo without removing it from the fifo. 4812e956fb3SStefani Seibold * It returns 0 if the fifo was empty. Otherwise it returns the number 4822e956fb3SStefani Seibold * processed elements. 48386d48803SStefani Seibold * 48486d48803SStefani Seibold * Note that with only one concurrent reader and one concurrent 4852e956fb3SStefani Seibold * writer, you don't need extra locking to use these macro. 48686d48803SStefani Seibold */ 4872e956fb3SStefani Seibold #define kfifo_peek(fifo, val) \ 488144ecf31SStefani Seibold __kfifo_uint_must_check_helper( \ 4892e956fb3SStefani Seibold ({ \ 490e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 491498d319bSStefani Seibold typeof(__tmp->ptr) __val = (val); \ 4922e956fb3SStefani Seibold unsigned int __ret; \ 4932e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmp->rectype); \ 4942e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 4952e956fb3SStefani Seibold if (__recsize) \ 4962e956fb3SStefani Seibold __ret = __kfifo_out_peek_r(__kfifo, __val, sizeof(*__val), \ 4972e956fb3SStefani Seibold __recsize); \ 4982e956fb3SStefani Seibold else { \ 4992e956fb3SStefani Seibold __ret = !kfifo_is_empty(__tmp); \ 5002e956fb3SStefani Seibold if (__ret) { \ 5012e956fb3SStefani Seibold *(typeof(__tmp->type))__val = \ 5022e956fb3SStefani Seibold (__is_kfifo_ptr(__tmp) ? \ 5032e956fb3SStefani Seibold ((typeof(__tmp->type))__kfifo->data) : \ 5042e956fb3SStefani Seibold (__tmp->buf) \ 5052e956fb3SStefani Seibold )[__kfifo->out & __tmp->kfifo.mask]; \ 5062e956fb3SStefani Seibold smp_wmb(); \ 5072e956fb3SStefani Seibold } \ 5082e956fb3SStefani Seibold } \ 5092e956fb3SStefani Seibold __ret; \ 5102e956fb3SStefani Seibold }) \ 5112e956fb3SStefani Seibold ) 51286d48803SStefani Seibold 51386d48803SStefani Seibold /** 5142e956fb3SStefani Seibold * kfifo_in - put data into the fifo 5152e956fb3SStefani Seibold * @fifo: address of the fifo to be used 5162e956fb3SStefani Seibold * @buf: the data to be added 5172e956fb3SStefani Seibold * @n: number of elements to be added 51886d48803SStefani Seibold * 5192e956fb3SStefani Seibold * This macro copies the given buffer into the fifo and returns the 5202e956fb3SStefani Seibold * number of copied elements. 52186d48803SStefani Seibold * 52286d48803SStefani Seibold * Note that with only one concurrent reader and one concurrent 5232e956fb3SStefani Seibold * writer, you don't need extra locking to use these macro. 52486d48803SStefani Seibold */ 5252e956fb3SStefani Seibold #define kfifo_in(fifo, buf, n) \ 5262e956fb3SStefani Seibold ({ \ 527e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 528498d319bSStefani Seibold typeof(__tmp->ptr_const) __buf = (buf); \ 5292e956fb3SStefani Seibold unsigned long __n = (n); \ 5302e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmp->rectype); \ 5312e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 5322e956fb3SStefani Seibold (__recsize) ?\ 5332e956fb3SStefani Seibold __kfifo_in_r(__kfifo, __buf, __n, __recsize) : \ 5342e956fb3SStefani Seibold __kfifo_in(__kfifo, __buf, __n); \ 5352e956fb3SStefani Seibold }) 53686d48803SStefani Seibold 53786d48803SStefani Seibold /** 5382e956fb3SStefani Seibold * kfifo_in_spinlocked - put data into the fifo using a spinlock for locking 5392e956fb3SStefani Seibold * @fifo: address of the fifo to be used 5402e956fb3SStefani Seibold * @buf: the data to be added 5412e956fb3SStefani Seibold * @n: number of elements to be added 5422e956fb3SStefani Seibold * @lock: pointer to the spinlock to use for locking 54386d48803SStefani Seibold * 5442e956fb3SStefani Seibold * This macro copies the given values buffer into the fifo and returns the 5452e956fb3SStefani Seibold * number of copied elements. 54686d48803SStefani Seibold */ 5472e956fb3SStefani Seibold #define kfifo_in_spinlocked(fifo, buf, n, lock) \ 5482e956fb3SStefani Seibold ({ \ 5492e956fb3SStefani Seibold unsigned long __flags; \ 5502e956fb3SStefani Seibold unsigned int __ret; \ 5512e956fb3SStefani Seibold spin_lock_irqsave(lock, __flags); \ 5522e956fb3SStefani Seibold __ret = kfifo_in(fifo, buf, n); \ 5532e956fb3SStefani Seibold spin_unlock_irqrestore(lock, __flags); \ 5542e956fb3SStefani Seibold __ret; \ 5552e956fb3SStefani Seibold }) 55686d48803SStefani Seibold 5573f2e4c11SBartosz Golaszewski /** 5583f2e4c11SBartosz Golaszewski * kfifo_in_spinlocked_noirqsave - put data into fifo using a spinlock for 5593f2e4c11SBartosz Golaszewski * locking, don't disable interrupts 5603f2e4c11SBartosz Golaszewski * @fifo: address of the fifo to be used 5613f2e4c11SBartosz Golaszewski * @buf: the data to be added 5623f2e4c11SBartosz Golaszewski * @n: number of elements to be added 5633f2e4c11SBartosz Golaszewski * @lock: pointer to the spinlock to use for locking 5643f2e4c11SBartosz Golaszewski * 5653f2e4c11SBartosz Golaszewski * This is a variant of kfifo_in_spinlocked() but uses spin_lock/unlock() 5663f2e4c11SBartosz Golaszewski * for locking and doesn't disable interrupts. 5673f2e4c11SBartosz Golaszewski */ 5683f2e4c11SBartosz Golaszewski #define kfifo_in_spinlocked_noirqsave(fifo, buf, n, lock) \ 5693f2e4c11SBartosz Golaszewski ({ \ 5703f2e4c11SBartosz Golaszewski unsigned int __ret; \ 5713f2e4c11SBartosz Golaszewski spin_lock(lock); \ 5723f2e4c11SBartosz Golaszewski __ret = kfifo_in(fifo, buf, n); \ 5733f2e4c11SBartosz Golaszewski spin_unlock(lock); \ 5743f2e4c11SBartosz Golaszewski __ret; \ 5753f2e4c11SBartosz Golaszewski }) 5763f2e4c11SBartosz Golaszewski 5772e956fb3SStefani Seibold /* alias for kfifo_in_spinlocked, will be removed in a future release */ 5782e956fb3SStefani Seibold #define kfifo_in_locked(fifo, buf, n, lock) \ 5792e956fb3SStefani Seibold kfifo_in_spinlocked(fifo, buf, n, lock) 58086d48803SStefani Seibold 58186d48803SStefani Seibold /** 5822e956fb3SStefani Seibold * kfifo_out - get data from the fifo 5832e956fb3SStefani Seibold * @fifo: address of the fifo to be used 5842e956fb3SStefani Seibold * @buf: pointer to the storage buffer 5852e956fb3SStefani Seibold * @n: max. number of elements to get 58686d48803SStefani Seibold * 5872e956fb3SStefani Seibold * This macro get some data from the fifo and return the numbers of elements 5882e956fb3SStefani Seibold * copied. 5892e956fb3SStefani Seibold * 5902e956fb3SStefani Seibold * Note that with only one concurrent reader and one concurrent 5912e956fb3SStefani Seibold * writer, you don't need extra locking to use these macro. 59286d48803SStefani Seibold */ 5932e956fb3SStefani Seibold #define kfifo_out(fifo, buf, n) \ 594144ecf31SStefani Seibold __kfifo_uint_must_check_helper( \ 5952e956fb3SStefani Seibold ({ \ 596e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 597498d319bSStefani Seibold typeof(__tmp->ptr) __buf = (buf); \ 5982e956fb3SStefani Seibold unsigned long __n = (n); \ 5992e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmp->rectype); \ 6002e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 6012e956fb3SStefani Seibold (__recsize) ?\ 6022e956fb3SStefani Seibold __kfifo_out_r(__kfifo, __buf, __n, __recsize) : \ 6032e956fb3SStefani Seibold __kfifo_out(__kfifo, __buf, __n); \ 6042e956fb3SStefani Seibold }) \ 6052e956fb3SStefani Seibold ) 60686d48803SStefani Seibold 60786d48803SStefani Seibold /** 6082e956fb3SStefani Seibold * kfifo_out_spinlocked - get data from the fifo using a spinlock for locking 6092e956fb3SStefani Seibold * @fifo: address of the fifo to be used 6102e956fb3SStefani Seibold * @buf: pointer to the storage buffer 6112e956fb3SStefani Seibold * @n: max. number of elements to get 6122e956fb3SStefani Seibold * @lock: pointer to the spinlock to use for locking 6132e956fb3SStefani Seibold * 6142e956fb3SStefani Seibold * This macro get the data from the fifo and return the numbers of elements 6152e956fb3SStefani Seibold * copied. 61686d48803SStefani Seibold */ 6172e956fb3SStefani Seibold #define kfifo_out_spinlocked(fifo, buf, n, lock) \ 618144ecf31SStefani Seibold __kfifo_uint_must_check_helper( \ 6192e956fb3SStefani Seibold ({ \ 6202e956fb3SStefani Seibold unsigned long __flags; \ 6212e956fb3SStefani Seibold unsigned int __ret; \ 6222e956fb3SStefani Seibold spin_lock_irqsave(lock, __flags); \ 6232e956fb3SStefani Seibold __ret = kfifo_out(fifo, buf, n); \ 6242e956fb3SStefani Seibold spin_unlock_irqrestore(lock, __flags); \ 6252e956fb3SStefani Seibold __ret; \ 6262e956fb3SStefani Seibold }) \ 6272e956fb3SStefani Seibold ) 62886d48803SStefani Seibold 6293f2e4c11SBartosz Golaszewski /** 6303f2e4c11SBartosz Golaszewski * kfifo_out_spinlocked_noirqsave - get data from the fifo using a spinlock 6313f2e4c11SBartosz Golaszewski * for locking, don't disable interrupts 6323f2e4c11SBartosz Golaszewski * @fifo: address of the fifo to be used 6333f2e4c11SBartosz Golaszewski * @buf: pointer to the storage buffer 6343f2e4c11SBartosz Golaszewski * @n: max. number of elements to get 6353f2e4c11SBartosz Golaszewski * @lock: pointer to the spinlock to use for locking 6363f2e4c11SBartosz Golaszewski * 6373f2e4c11SBartosz Golaszewski * This is a variant of kfifo_out_spinlocked() which uses spin_lock/unlock() 6383f2e4c11SBartosz Golaszewski * for locking and doesn't disable interrupts. 6393f2e4c11SBartosz Golaszewski */ 6403f2e4c11SBartosz Golaszewski #define kfifo_out_spinlocked_noirqsave(fifo, buf, n, lock) \ 6413f2e4c11SBartosz Golaszewski __kfifo_uint_must_check_helper( \ 6423f2e4c11SBartosz Golaszewski ({ \ 6433f2e4c11SBartosz Golaszewski unsigned int __ret; \ 6443f2e4c11SBartosz Golaszewski spin_lock(lock); \ 6453f2e4c11SBartosz Golaszewski __ret = kfifo_out(fifo, buf, n); \ 6463f2e4c11SBartosz Golaszewski spin_unlock(lock); \ 6473f2e4c11SBartosz Golaszewski __ret; \ 6483f2e4c11SBartosz Golaszewski }) \ 6493f2e4c11SBartosz Golaszewski ) 6503f2e4c11SBartosz Golaszewski 6512e956fb3SStefani Seibold /* alias for kfifo_out_spinlocked, will be removed in a future release */ 6522e956fb3SStefani Seibold #define kfifo_out_locked(fifo, buf, n, lock) \ 6532e956fb3SStefani Seibold kfifo_out_spinlocked(fifo, buf, n, lock) 6542e956fb3SStefani Seibold 6552e956fb3SStefani Seibold /** 6562e956fb3SStefani Seibold * kfifo_from_user - puts some data from user space into the fifo 6572e956fb3SStefani Seibold * @fifo: address of the fifo to be used 6582e956fb3SStefani Seibold * @from: pointer to the data to be added 6592e956fb3SStefani Seibold * @len: the length of the data to be added 6602e956fb3SStefani Seibold * @copied: pointer to output variable to store the number of copied bytes 6612e956fb3SStefani Seibold * 6622e956fb3SStefani Seibold * This macro copies at most @len bytes from the @from into the 6632e956fb3SStefani Seibold * fifo, depending of the available space and returns -EFAULT/0. 6642e956fb3SStefani Seibold * 6652e956fb3SStefani Seibold * Note that with only one concurrent reader and one concurrent 6662e956fb3SStefani Seibold * writer, you don't need extra locking to use these macro. 6672e956fb3SStefani Seibold */ 6682e956fb3SStefani Seibold #define kfifo_from_user(fifo, from, len, copied) \ 669144ecf31SStefani Seibold __kfifo_uint_must_check_helper( \ 6702e956fb3SStefani Seibold ({ \ 671e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 6722e956fb3SStefani Seibold const void __user *__from = (from); \ 6732e956fb3SStefani Seibold unsigned int __len = (len); \ 6742e956fb3SStefani Seibold unsigned int *__copied = (copied); \ 6752e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmp->rectype); \ 6762e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 6772e956fb3SStefani Seibold (__recsize) ? \ 6782e956fb3SStefani Seibold __kfifo_from_user_r(__kfifo, __from, __len, __copied, __recsize) : \ 6792e956fb3SStefani Seibold __kfifo_from_user(__kfifo, __from, __len, __copied); \ 6802e956fb3SStefani Seibold }) \ 6812e956fb3SStefani Seibold ) 6822e956fb3SStefani Seibold 6832e956fb3SStefani Seibold /** 6842e956fb3SStefani Seibold * kfifo_to_user - copies data from the fifo into user space 6852e956fb3SStefani Seibold * @fifo: address of the fifo to be used 6862e956fb3SStefani Seibold * @to: where the data must be copied 6872e956fb3SStefani Seibold * @len: the size of the destination buffer 6882e956fb3SStefani Seibold * @copied: pointer to output variable to store the number of copied bytes 6892e956fb3SStefani Seibold * 6902e956fb3SStefani Seibold * This macro copies at most @len bytes from the fifo into the 6912e956fb3SStefani Seibold * @to buffer and returns -EFAULT/0. 6922e956fb3SStefani Seibold * 6932e956fb3SStefani Seibold * Note that with only one concurrent reader and one concurrent 6942e956fb3SStefani Seibold * writer, you don't need extra locking to use these macro. 6952e956fb3SStefani Seibold */ 6962e956fb3SStefani Seibold #define kfifo_to_user(fifo, to, len, copied) \ 697045ed31eSDan Carpenter __kfifo_int_must_check_helper( \ 6982e956fb3SStefani Seibold ({ \ 699e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 7002e956fb3SStefani Seibold void __user *__to = (to); \ 7012e956fb3SStefani Seibold unsigned int __len = (len); \ 7022e956fb3SStefani Seibold unsigned int *__copied = (copied); \ 7032e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmp->rectype); \ 7042e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 7052e956fb3SStefani Seibold (__recsize) ? \ 7062e956fb3SStefani Seibold __kfifo_to_user_r(__kfifo, __to, __len, __copied, __recsize) : \ 7072e956fb3SStefani Seibold __kfifo_to_user(__kfifo, __to, __len, __copied); \ 7082e956fb3SStefani Seibold }) \ 7092e956fb3SStefani Seibold ) 7102e956fb3SStefani Seibold 7112e956fb3SStefani Seibold /** 7122e956fb3SStefani Seibold * kfifo_dma_in_prepare - setup a scatterlist for DMA input 7132e956fb3SStefani Seibold * @fifo: address of the fifo to be used 7142e956fb3SStefani Seibold * @sgl: pointer to the scatterlist array 7152e956fb3SStefani Seibold * @nents: number of entries in the scatterlist array 7162e956fb3SStefani Seibold * @len: number of elements to transfer 7172e956fb3SStefani Seibold * 7182e956fb3SStefani Seibold * This macro fills a scatterlist for DMA input. 7192e956fb3SStefani Seibold * It returns the number entries in the scatterlist array. 7202e956fb3SStefani Seibold * 7212e956fb3SStefani Seibold * Note that with only one concurrent reader and one concurrent 7222e956fb3SStefani Seibold * writer, you don't need extra locking to use these macros. 7232e956fb3SStefani Seibold */ 7242e956fb3SStefani Seibold #define kfifo_dma_in_prepare(fifo, sgl, nents, len) \ 7252e956fb3SStefani Seibold ({ \ 726e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 7272e956fb3SStefani Seibold struct scatterlist *__sgl = (sgl); \ 7282e956fb3SStefani Seibold int __nents = (nents); \ 7292e956fb3SStefani Seibold unsigned int __len = (len); \ 7302e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmp->rectype); \ 7312e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 7322e956fb3SStefani Seibold (__recsize) ? \ 7332e956fb3SStefani Seibold __kfifo_dma_in_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \ 7342e956fb3SStefani Seibold __kfifo_dma_in_prepare(__kfifo, __sgl, __nents, __len); \ 7352e956fb3SStefani Seibold }) 7362e956fb3SStefani Seibold 7372e956fb3SStefani Seibold /** 7382e956fb3SStefani Seibold * kfifo_dma_in_finish - finish a DMA IN operation 7392e956fb3SStefani Seibold * @fifo: address of the fifo to be used 7402e956fb3SStefani Seibold * @len: number of bytes to received 7412e956fb3SStefani Seibold * 7422e956fb3SStefani Seibold * This macro finish a DMA IN operation. The in counter will be updated by 7432e956fb3SStefani Seibold * the len parameter. No error checking will be done. 7442e956fb3SStefani Seibold * 7452e956fb3SStefani Seibold * Note that with only one concurrent reader and one concurrent 7462e956fb3SStefani Seibold * writer, you don't need extra locking to use these macros. 7472e956fb3SStefani Seibold */ 7482e956fb3SStefani Seibold #define kfifo_dma_in_finish(fifo, len) \ 7492e956fb3SStefani Seibold (void)({ \ 750e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 7512e956fb3SStefani Seibold unsigned int __len = (len); \ 7522e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmp->rectype); \ 7532e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 7542e956fb3SStefani Seibold if (__recsize) \ 7552e956fb3SStefani Seibold __kfifo_dma_in_finish_r(__kfifo, __len, __recsize); \ 7562e956fb3SStefani Seibold else \ 7572e956fb3SStefani Seibold __kfifo->in += __len / sizeof(*__tmp->type); \ 7582e956fb3SStefani Seibold }) 7592e956fb3SStefani Seibold 7602e956fb3SStefani Seibold /** 7612e956fb3SStefani Seibold * kfifo_dma_out_prepare - setup a scatterlist for DMA output 7622e956fb3SStefani Seibold * @fifo: address of the fifo to be used 7632e956fb3SStefani Seibold * @sgl: pointer to the scatterlist array 7642e956fb3SStefani Seibold * @nents: number of entries in the scatterlist array 7652e956fb3SStefani Seibold * @len: number of elements to transfer 7662e956fb3SStefani Seibold * 7672e956fb3SStefani Seibold * This macro fills a scatterlist for DMA output which at most @len bytes 7682e956fb3SStefani Seibold * to transfer. 7692e956fb3SStefani Seibold * It returns the number entries in the scatterlist array. 7702e956fb3SStefani Seibold * A zero means there is no space available and the scatterlist is not filled. 7712e956fb3SStefani Seibold * 7722e956fb3SStefani Seibold * Note that with only one concurrent reader and one concurrent 7732e956fb3SStefani Seibold * writer, you don't need extra locking to use these macros. 7742e956fb3SStefani Seibold */ 7752e956fb3SStefani Seibold #define kfifo_dma_out_prepare(fifo, sgl, nents, len) \ 7762e956fb3SStefani Seibold ({ \ 777e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 7782e956fb3SStefani Seibold struct scatterlist *__sgl = (sgl); \ 7792e956fb3SStefani Seibold int __nents = (nents); \ 7802e956fb3SStefani Seibold unsigned int __len = (len); \ 7812e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmp->rectype); \ 7822e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 7832e956fb3SStefani Seibold (__recsize) ? \ 7842e956fb3SStefani Seibold __kfifo_dma_out_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \ 7852e956fb3SStefani Seibold __kfifo_dma_out_prepare(__kfifo, __sgl, __nents, __len); \ 7862e956fb3SStefani Seibold }) 7872e956fb3SStefani Seibold 7882e956fb3SStefani Seibold /** 7892e956fb3SStefani Seibold * kfifo_dma_out_finish - finish a DMA OUT operation 7902e956fb3SStefani Seibold * @fifo: address of the fifo to be used 791da3dae54SMasanari Iida * @len: number of bytes transferred 7922e956fb3SStefani Seibold * 7932e956fb3SStefani Seibold * This macro finish a DMA OUT operation. The out counter will be updated by 7942e956fb3SStefani Seibold * the len parameter. No error checking will be done. 7952e956fb3SStefani Seibold * 7962e956fb3SStefani Seibold * Note that with only one concurrent reader and one concurrent 7972e956fb3SStefani Seibold * writer, you don't need extra locking to use these macros. 7982e956fb3SStefani Seibold */ 799*76738194SJiri Slaby (SUSE) #define kfifo_dma_out_finish(fifo, len) do { \ 800*76738194SJiri Slaby (SUSE) typeof((fifo) + 1) ___tmp = (fifo); \ 801*76738194SJiri Slaby (SUSE) kfifo_skip_count(___tmp, (len) / sizeof(*___tmp->type)); \ 802*76738194SJiri Slaby (SUSE) } while (0) 8032e956fb3SStefani Seibold 8042e956fb3SStefani Seibold /** 8052e956fb3SStefani Seibold * kfifo_out_peek - gets some data from the fifo 8062e956fb3SStefani Seibold * @fifo: address of the fifo to be used 8072e956fb3SStefani Seibold * @buf: pointer to the storage buffer 8082e956fb3SStefani Seibold * @n: max. number of elements to get 8092e956fb3SStefani Seibold * 8102e956fb3SStefani Seibold * This macro get the data from the fifo and return the numbers of elements 8112e956fb3SStefani Seibold * copied. The data is not removed from the fifo. 8122e956fb3SStefani Seibold * 8132e956fb3SStefani Seibold * Note that with only one concurrent reader and one concurrent 8142e956fb3SStefani Seibold * writer, you don't need extra locking to use these macro. 8152e956fb3SStefani Seibold */ 8162e956fb3SStefani Seibold #define kfifo_out_peek(fifo, buf, n) \ 817144ecf31SStefani Seibold __kfifo_uint_must_check_helper( \ 8182e956fb3SStefani Seibold ({ \ 819e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 820498d319bSStefani Seibold typeof(__tmp->ptr) __buf = (buf); \ 8212e956fb3SStefani Seibold unsigned long __n = (n); \ 8222e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmp->rectype); \ 8232e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 8242e956fb3SStefani Seibold (__recsize) ? \ 8252e956fb3SStefani Seibold __kfifo_out_peek_r(__kfifo, __buf, __n, __recsize) : \ 8262e956fb3SStefani Seibold __kfifo_out_peek(__kfifo, __buf, __n); \ 8272e956fb3SStefani Seibold }) \ 8282e956fb3SStefani Seibold ) 8292e956fb3SStefani Seibold 8302e956fb3SStefani Seibold extern int __kfifo_alloc(struct __kfifo *fifo, unsigned int size, 8312e956fb3SStefani Seibold size_t esize, gfp_t gfp_mask); 8322e956fb3SStefani Seibold 8332e956fb3SStefani Seibold extern void __kfifo_free(struct __kfifo *fifo); 8342e956fb3SStefani Seibold 8352e956fb3SStefani Seibold extern int __kfifo_init(struct __kfifo *fifo, void *buffer, 8362e956fb3SStefani Seibold unsigned int size, size_t esize); 8372e956fb3SStefani Seibold 8382e956fb3SStefani Seibold extern unsigned int __kfifo_in(struct __kfifo *fifo, 8392e956fb3SStefani Seibold const void *buf, unsigned int len); 8402e956fb3SStefani Seibold 8412e956fb3SStefani Seibold extern unsigned int __kfifo_out(struct __kfifo *fifo, 8422e956fb3SStefani Seibold void *buf, unsigned int len); 8432e956fb3SStefani Seibold 8442e956fb3SStefani Seibold extern int __kfifo_from_user(struct __kfifo *fifo, 8452e956fb3SStefani Seibold const void __user *from, unsigned long len, unsigned int *copied); 8462e956fb3SStefani Seibold 8472e956fb3SStefani Seibold extern int __kfifo_to_user(struct __kfifo *fifo, 8482e956fb3SStefani Seibold void __user *to, unsigned long len, unsigned int *copied); 8492e956fb3SStefani Seibold 8502e956fb3SStefani Seibold extern unsigned int __kfifo_dma_in_prepare(struct __kfifo *fifo, 8512e956fb3SStefani Seibold struct scatterlist *sgl, int nents, unsigned int len); 8522e956fb3SStefani Seibold 8532e956fb3SStefani Seibold extern unsigned int __kfifo_dma_out_prepare(struct __kfifo *fifo, 8542e956fb3SStefani Seibold struct scatterlist *sgl, int nents, unsigned int len); 8552e956fb3SStefani Seibold 8562e956fb3SStefani Seibold extern unsigned int __kfifo_out_peek(struct __kfifo *fifo, 8572e956fb3SStefani Seibold void *buf, unsigned int len); 8582e956fb3SStefani Seibold 8592e956fb3SStefani Seibold extern unsigned int __kfifo_in_r(struct __kfifo *fifo, 8602e956fb3SStefani Seibold const void *buf, unsigned int len, size_t recsize); 8612e956fb3SStefani Seibold 8622e956fb3SStefani Seibold extern unsigned int __kfifo_out_r(struct __kfifo *fifo, 8632e956fb3SStefani Seibold void *buf, unsigned int len, size_t recsize); 8642e956fb3SStefani Seibold 8652e956fb3SStefani Seibold extern int __kfifo_from_user_r(struct __kfifo *fifo, 8662e956fb3SStefani Seibold const void __user *from, unsigned long len, unsigned int *copied, 8672e956fb3SStefani Seibold size_t recsize); 8682e956fb3SStefani Seibold 8692e956fb3SStefani Seibold extern int __kfifo_to_user_r(struct __kfifo *fifo, void __user *to, 8702e956fb3SStefani Seibold unsigned long len, unsigned int *copied, size_t recsize); 8712e956fb3SStefani Seibold 8722e956fb3SStefani Seibold extern unsigned int __kfifo_dma_in_prepare_r(struct __kfifo *fifo, 8732e956fb3SStefani Seibold struct scatterlist *sgl, int nents, unsigned int len, size_t recsize); 8742e956fb3SStefani Seibold 8752e956fb3SStefani Seibold extern void __kfifo_dma_in_finish_r(struct __kfifo *fifo, 8762e956fb3SStefani Seibold unsigned int len, size_t recsize); 8772e956fb3SStefani Seibold 8782e956fb3SStefani Seibold extern unsigned int __kfifo_dma_out_prepare_r(struct __kfifo *fifo, 8792e956fb3SStefani Seibold struct scatterlist *sgl, int nents, unsigned int len, size_t recsize); 8802e956fb3SStefani Seibold 8812e956fb3SStefani Seibold extern unsigned int __kfifo_len_r(struct __kfifo *fifo, size_t recsize); 8822e956fb3SStefani Seibold 883b35de43bSAndrea Righi extern void __kfifo_skip_r(struct __kfifo *fifo, size_t recsize); 884b35de43bSAndrea Righi 8852e956fb3SStefani Seibold extern unsigned int __kfifo_out_peek_r(struct __kfifo *fifo, 8862e956fb3SStefani Seibold void *buf, unsigned int len, size_t recsize); 8872e956fb3SStefani Seibold 8882e956fb3SStefani Seibold extern unsigned int __kfifo_max_r(unsigned int len, size_t recsize); 88986d48803SStefani Seibold 8901da177e4SLinus Torvalds #endif 891