11da177e4SLinus Torvalds /* 22e956fb3SStefani Seibold * A generic kernel FIFO implementation 31da177e4SLinus Torvalds * 42e956fb3SStefani Seibold * Copyright (C) 2009/2010 Stefani Seibold <stefani@seibold.net> 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or modify 71da177e4SLinus Torvalds * it under the terms of the GNU General Public License as published by 81da177e4SLinus Torvalds * the Free Software Foundation; either version 2 of the License, or 91da177e4SLinus Torvalds * (at your option) any later version. 101da177e4SLinus Torvalds * 111da177e4SLinus Torvalds * This program is distributed in the hope that it will be useful, 121da177e4SLinus Torvalds * but WITHOUT ANY WARRANTY; without even the implied warranty of 131da177e4SLinus Torvalds * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 141da177e4SLinus Torvalds * GNU General Public License for more details. 151da177e4SLinus Torvalds * 161da177e4SLinus Torvalds * You should have received a copy of the GNU General Public License 171da177e4SLinus Torvalds * along with this program; if not, write to the Free Software 181da177e4SLinus Torvalds * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 191da177e4SLinus Torvalds * 201da177e4SLinus Torvalds */ 217acd72ebSStefani Seibold 222e956fb3SStefani Seibold #ifndef _LINUX_KFIFO_H 232e956fb3SStefani Seibold #define _LINUX_KFIFO_H 242e956fb3SStefani Seibold 257acd72ebSStefani Seibold /* 262e956fb3SStefani Seibold * How to porting drivers to the new generic FIFO API: 277acd72ebSStefani Seibold * 287acd72ebSStefani Seibold * - Modify the declaration of the "struct kfifo *" object into a 297acd72ebSStefani Seibold * in-place "struct kfifo" object 307acd72ebSStefani Seibold * - Init the in-place object with kfifo_alloc() or kfifo_init() 317acd72ebSStefani Seibold * Note: The address of the in-place "struct kfifo" object must be 327acd72ebSStefani Seibold * passed as the first argument to this functions 337acd72ebSStefani Seibold * - Replace the use of __kfifo_put into kfifo_in and __kfifo_get 347acd72ebSStefani Seibold * into kfifo_out 352e956fb3SStefani Seibold * - Replace the use of kfifo_put into kfifo_in_spinlocked and kfifo_get 362e956fb3SStefani Seibold * into kfifo_out_spinlocked 377acd72ebSStefani Seibold * Note: the spinlock pointer formerly passed to kfifo_init/kfifo_alloc 382e956fb3SStefani Seibold * must be passed now to the kfifo_in_spinlocked and kfifo_out_spinlocked 392e956fb3SStefani Seibold * as the last parameter 402e956fb3SStefani Seibold * - The formerly __kfifo_* functions are renamed into kfifo_* 417acd72ebSStefani Seibold */ 427acd72ebSStefani Seibold 432e956fb3SStefani Seibold /* 442e956fb3SStefani Seibold * Note about locking : There is no locking required until only * one reader 452e956fb3SStefani Seibold * and one writer is using the fifo and no kfifo_reset() will be * called 462e956fb3SStefani Seibold * kfifo_reset_out() can be safely used, until it will be only called 472e956fb3SStefani Seibold * in the reader thread. 482e956fb3SStefani Seibold * For multiple writer and one reader there is only a need to lock the writer. 492e956fb3SStefani Seibold * And vice versa for only one writer and multiple reader there is only a need 502e956fb3SStefani Seibold * to lock the reader. 512e956fb3SStefani Seibold */ 521da177e4SLinus Torvalds 531da177e4SLinus Torvalds #include <linux/kernel.h> 541da177e4SLinus Torvalds #include <linux/spinlock.h> 552e956fb3SStefani Seibold #include <linux/stddef.h> 562e956fb3SStefani Seibold #include <linux/scatterlist.h> 571da177e4SLinus Torvalds 582e956fb3SStefani Seibold struct __kfifo { 592e956fb3SStefani Seibold unsigned int in; 602e956fb3SStefani Seibold unsigned int out; 612e956fb3SStefani Seibold unsigned int mask; 622e956fb3SStefani Seibold unsigned int esize; 632e956fb3SStefani Seibold void *data; 641da177e4SLinus Torvalds }; 651da177e4SLinus Torvalds 662e956fb3SStefani Seibold #define __STRUCT_KFIFO_COMMON(datatype, recsize, ptrtype) \ 672e956fb3SStefani Seibold union { \ 682e956fb3SStefani Seibold struct __kfifo kfifo; \ 692e956fb3SStefani Seibold datatype *type; \ 702e956fb3SStefani Seibold char (*rectype)[recsize]; \ 712e956fb3SStefani Seibold ptrtype *ptr; \ 722e956fb3SStefani Seibold const ptrtype *ptr_const; \ 732e956fb3SStefani Seibold } 7437bdfbbfSStefani Seibold 752e956fb3SStefani Seibold #define __STRUCT_KFIFO(type, size, recsize, ptrtype) \ 762e956fb3SStefani Seibold { \ 772e956fb3SStefani Seibold __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ 782e956fb3SStefani Seibold type buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \ 792e956fb3SStefani Seibold } 802e956fb3SStefani Seibold 812e956fb3SStefani Seibold #define STRUCT_KFIFO(type, size) \ 822e956fb3SStefani Seibold struct __STRUCT_KFIFO(type, size, 0, type) 832e956fb3SStefani Seibold 842e956fb3SStefani Seibold #define __STRUCT_KFIFO_PTR(type, recsize, ptrtype) \ 852e956fb3SStefani Seibold { \ 862e956fb3SStefani Seibold __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ 872e956fb3SStefani Seibold type buf[0]; \ 882e956fb3SStefani Seibold } 892e956fb3SStefani Seibold 902e956fb3SStefani Seibold #define STRUCT_KFIFO_PTR(type) \ 912e956fb3SStefani Seibold struct __STRUCT_KFIFO_PTR(type, 0, type) 922e956fb3SStefani Seibold 932e956fb3SStefani Seibold /* 942e956fb3SStefani Seibold * define compatibility "struct kfifo" for dynamic allocated fifos 952e956fb3SStefani Seibold */ 962e956fb3SStefani Seibold struct kfifo __STRUCT_KFIFO_PTR(unsigned char, 0, void); 972e956fb3SStefani Seibold 982e956fb3SStefani Seibold #define STRUCT_KFIFO_REC_1(size) \ 992e956fb3SStefani Seibold struct __STRUCT_KFIFO(unsigned char, size, 1, void) 1002e956fb3SStefani Seibold 1012e956fb3SStefani Seibold #define STRUCT_KFIFO_REC_2(size) \ 1022e956fb3SStefani Seibold struct __STRUCT_KFIFO(unsigned char, size, 2, void) 1032e956fb3SStefani Seibold 1042e956fb3SStefani Seibold /* 1052e956fb3SStefani Seibold * define kfifo_rec types 1062e956fb3SStefani Seibold */ 1072e956fb3SStefani Seibold struct kfifo_rec_ptr_1 __STRUCT_KFIFO_PTR(unsigned char, 1, void); 1082e956fb3SStefani Seibold struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2, void); 1092e956fb3SStefani Seibold 1102e956fb3SStefani Seibold /* 1112e956fb3SStefani Seibold * helper macro to distinguish between real in place fifo where the fifo 1122e956fb3SStefani Seibold * array is a part of the structure and the fifo type where the array is 1132e956fb3SStefani Seibold * outside of the fifo structure. 1142e956fb3SStefani Seibold */ 1152e956fb3SStefani Seibold #define __is_kfifo_ptr(fifo) (sizeof(*fifo) == sizeof(struct __kfifo)) 1162e956fb3SStefani Seibold 1172e956fb3SStefani Seibold /** 1182e956fb3SStefani Seibold * DECLARE_KFIFO_PTR - macro to declare a fifo pointer object 1192e956fb3SStefani Seibold * @fifo: name of the declared fifo 1202e956fb3SStefani Seibold * @type: type of the fifo elements 1212e956fb3SStefani Seibold */ 1222e956fb3SStefani Seibold #define DECLARE_KFIFO_PTR(fifo, type) STRUCT_KFIFO_PTR(type) fifo 1232e956fb3SStefani Seibold 1242e956fb3SStefani Seibold /** 1252e956fb3SStefani Seibold * DECLARE_KFIFO - macro to declare a fifo object 1262e956fb3SStefani Seibold * @fifo: name of the declared fifo 1272e956fb3SStefani Seibold * @type: type of the fifo elements 1282e956fb3SStefani Seibold * @size: the number of elements in the fifo, this must be a power of 2 1292e956fb3SStefani Seibold */ 1302e956fb3SStefani Seibold #define DECLARE_KFIFO(fifo, type, size) STRUCT_KFIFO(type, size) fifo 1312e956fb3SStefani Seibold 1322e956fb3SStefani Seibold /** 1332e956fb3SStefani Seibold * INIT_KFIFO - Initialize a fifo declared by DECLARE_KFIFO 1342e956fb3SStefani Seibold * @fifo: name of the declared fifo datatype 1352e956fb3SStefani Seibold */ 1362e956fb3SStefani Seibold #define INIT_KFIFO(fifo) \ 1372e956fb3SStefani Seibold (void)({ \ 1382e956fb3SStefani Seibold typeof(&(fifo)) __tmp = &(fifo); \ 1392e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 1402e956fb3SStefani Seibold __kfifo->in = 0; \ 1412e956fb3SStefani Seibold __kfifo->out = 0; \ 1422e956fb3SStefani Seibold __kfifo->mask = __is_kfifo_ptr(__tmp) ? 0 : ARRAY_SIZE(__tmp->buf) - 1;\ 1432e956fb3SStefani Seibold __kfifo->esize = sizeof(*__tmp->buf); \ 1442e956fb3SStefani Seibold __kfifo->data = __is_kfifo_ptr(__tmp) ? NULL : __tmp->buf; \ 1452e956fb3SStefani Seibold }) 1462e956fb3SStefani Seibold 1472e956fb3SStefani Seibold /** 1482e956fb3SStefani Seibold * DEFINE_KFIFO - macro to define and initialize a fifo 1492e956fb3SStefani Seibold * @fifo: name of the declared fifo datatype 1502e956fb3SStefani Seibold * @type: type of the fifo elements 1512e956fb3SStefani Seibold * @size: the number of elements in the fifo, this must be a power of 2 1522e956fb3SStefani Seibold * 1532e956fb3SStefani Seibold * Note: the macro can be used for global and local fifo data type variables. 1542e956fb3SStefani Seibold */ 1552e956fb3SStefani Seibold #define DEFINE_KFIFO(fifo, type, size) \ 1562e956fb3SStefani Seibold DECLARE_KFIFO(fifo, type, size) = \ 1572e956fb3SStefani Seibold (typeof(fifo)) { \ 1582e956fb3SStefani Seibold { \ 1592e956fb3SStefani Seibold { \ 16037bdfbbfSStefani Seibold .in = 0, \ 16137bdfbbfSStefani Seibold .out = 0, \ 1622e956fb3SStefani Seibold .mask = __is_kfifo_ptr(&(fifo)) ? \ 1632e956fb3SStefani Seibold 0 : \ 1642e956fb3SStefani Seibold ARRAY_SIZE((fifo).buf) - 1, \ 1652e956fb3SStefani Seibold .esize = sizeof(*(fifo).buf), \ 1662e956fb3SStefani Seibold .data = __is_kfifo_ptr(&(fifo)) ? \ 1672e956fb3SStefani Seibold NULL : \ 1682e956fb3SStefani Seibold (fifo).buf, \ 1692e956fb3SStefani Seibold } \ 1702e956fb3SStefani Seibold } \ 1712e956fb3SStefani Seibold } 1722e956fb3SStefani Seibold 1732e956fb3SStefani Seibold 174*144ecf31SStefani Seibold static inline unsigned int __must_check 175*144ecf31SStefani Seibold __kfifo_uint_must_check_helper(unsigned int val) 176*144ecf31SStefani Seibold { 177*144ecf31SStefani Seibold return val; 178*144ecf31SStefani Seibold } 179*144ecf31SStefani Seibold 180*144ecf31SStefani Seibold static inline int __must_check 181*144ecf31SStefani Seibold __kfifo_int_must_check_helper(int val) 182*144ecf31SStefani Seibold { 183*144ecf31SStefani Seibold return val; 184*144ecf31SStefani Seibold } 18537bdfbbfSStefani Seibold 18637bdfbbfSStefani Seibold /** 1872e956fb3SStefani Seibold * kfifo_initialized - Check if the fifo is initialized 1882e956fb3SStefani Seibold * @fifo: address of the fifo to check 18937bdfbbfSStefani Seibold * 1902e956fb3SStefani Seibold * Return %true if fifo is initialized, otherwise %false. 191d994ffc2SAndi Kleen * Assumes the fifo was 0 before. 192d994ffc2SAndi Kleen */ 1932e956fb3SStefani Seibold #define kfifo_initialized(fifo) ((fifo)->kfifo.mask) 1941da177e4SLinus Torvalds 1951da177e4SLinus Torvalds /** 1962e956fb3SStefani Seibold * kfifo_esize - returns the size of the element managed by the fifo 1972e956fb3SStefani Seibold * @fifo: address of the fifo to be used 1981da177e4SLinus Torvalds */ 1992e956fb3SStefani Seibold #define kfifo_esize(fifo) ((fifo)->kfifo.esize) 2001da177e4SLinus Torvalds 2011da177e4SLinus Torvalds /** 2022e956fb3SStefani Seibold * kfifo_recsize - returns the size of the record length field 2032e956fb3SStefani Seibold * @fifo: address of the fifo to be used 204a121f24aSStefani Seibold */ 2052e956fb3SStefani Seibold #define kfifo_recsize(fifo) (sizeof(*(fifo)->rectype)) 206a121f24aSStefani Seibold 207a121f24aSStefani Seibold /** 2082e956fb3SStefani Seibold * kfifo_size - returns the size of the fifo in elements 2092e956fb3SStefani Seibold * @fifo: address of the fifo to be used 21037bdfbbfSStefani Seibold */ 2112e956fb3SStefani Seibold #define kfifo_size(fifo) ((fifo)->kfifo.mask + 1) 21237bdfbbfSStefani Seibold 21337bdfbbfSStefani Seibold /** 2142e956fb3SStefani Seibold * kfifo_reset - removes the entire fifo content 2152e956fb3SStefani Seibold * @fifo: address of the fifo to be used 2162e956fb3SStefani Seibold * 2172e956fb3SStefani Seibold * Note: usage of kfifo_reset() is dangerous. It should be only called when the 2182e956fb3SStefani Seibold * fifo is exclusived locked or when it is secured that no other thread is 2192e956fb3SStefani Seibold * accessing the fifo. 220c1e13f25SStefani Seibold */ 2212e956fb3SStefani Seibold #define kfifo_reset(fifo) \ 2222e956fb3SStefani Seibold (void)({ \ 223e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 2242e956fb3SStefani Seibold __tmp->kfifo.in = __tmp->kfifo.out = 0; \ 2252e956fb3SStefani Seibold }) 226c1e13f25SStefani Seibold 2272e956fb3SStefani Seibold /** 2282e956fb3SStefani Seibold * kfifo_reset_out - skip fifo content 2292e956fb3SStefani Seibold * @fifo: address of the fifo to be used 2302e956fb3SStefani Seibold * 2312e956fb3SStefani Seibold * Note: The usage of kfifo_reset_out() is safe until it will be only called 2322e956fb3SStefani Seibold * from the reader thread and there is only one concurrent reader. Otherwise 2332e956fb3SStefani Seibold * it is dangerous and must be handled in the same way as kfifo_reset(). 2342e956fb3SStefani Seibold */ 2352e956fb3SStefani Seibold #define kfifo_reset_out(fifo) \ 2362e956fb3SStefani Seibold (void)({ \ 237e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 2382e956fb3SStefani Seibold __tmp->kfifo.out = __tmp->kfifo.in; \ 2392e956fb3SStefani Seibold }) 2402e956fb3SStefani Seibold 2412e956fb3SStefani Seibold /** 2422e956fb3SStefani Seibold * kfifo_len - returns the number of used elements in the fifo 2432e956fb3SStefani Seibold * @fifo: address of the fifo to be used 2442e956fb3SStefani Seibold */ 2452e956fb3SStefani Seibold #define kfifo_len(fifo) \ 2462e956fb3SStefani Seibold ({ \ 247e0bf1024SHuang Ying typeof((fifo) + 1) __tmpl = (fifo); \ 2482e956fb3SStefani Seibold __tmpl->kfifo.in - __tmpl->kfifo.out; \ 2492e956fb3SStefani Seibold }) 250c1e13f25SStefani Seibold 251c1e13f25SStefani Seibold /** 25237bdfbbfSStefani Seibold * kfifo_is_empty - returns true if the fifo is empty 2532e956fb3SStefani Seibold * @fifo: address of the fifo to be used 25437bdfbbfSStefani Seibold */ 2552e956fb3SStefani Seibold #define kfifo_is_empty(fifo) \ 2562e956fb3SStefani Seibold ({ \ 257e0bf1024SHuang Ying typeof((fifo) + 1) __tmpq = (fifo); \ 2582e956fb3SStefani Seibold __tmpq->kfifo.in == __tmpq->kfifo.out; \ 2592e956fb3SStefani Seibold }) 26037bdfbbfSStefani Seibold 26137bdfbbfSStefani Seibold /** 26237bdfbbfSStefani Seibold * kfifo_is_full - returns true if the fifo is full 2632e956fb3SStefani Seibold * @fifo: address of the fifo to be used 26437bdfbbfSStefani Seibold */ 2652e956fb3SStefani Seibold #define kfifo_is_full(fifo) \ 2662e956fb3SStefani Seibold ({ \ 267e0bf1024SHuang Ying typeof((fifo) + 1) __tmpq = (fifo); \ 2682e956fb3SStefani Seibold kfifo_len(__tmpq) > __tmpq->kfifo.mask; \ 2692e956fb3SStefani Seibold }) 27037bdfbbfSStefani Seibold 27137bdfbbfSStefani Seibold /** 2722e956fb3SStefani Seibold * kfifo_avail - returns the number of unused elements in the fifo 2732e956fb3SStefani Seibold * @fifo: address of the fifo to be used 27437bdfbbfSStefani Seibold */ 2752e956fb3SStefani Seibold #define kfifo_avail(fifo) \ 276*144ecf31SStefani Seibold __kfifo_uint_must_check_helper( \ 2772e956fb3SStefani Seibold ({ \ 278e0bf1024SHuang Ying typeof((fifo) + 1) __tmpq = (fifo); \ 2792e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmpq->rectype); \ 2802e956fb3SStefani Seibold unsigned int __avail = kfifo_size(__tmpq) - kfifo_len(__tmpq); \ 2812e956fb3SStefani Seibold (__recsize) ? ((__avail <= __recsize) ? 0 : \ 2822e956fb3SStefani Seibold __kfifo_max_r(__avail - __recsize, __recsize)) : \ 2832e956fb3SStefani Seibold __avail; \ 2842e956fb3SStefani Seibold }) \ 28586d48803SStefani Seibold ) 28686d48803SStefani Seibold 2872e956fb3SStefani Seibold /** 2882e956fb3SStefani Seibold * kfifo_skip - skip output data 2892e956fb3SStefani Seibold * @fifo: address of the fifo to be used 29086d48803SStefani Seibold */ 2912e956fb3SStefani Seibold #define kfifo_skip(fifo) \ 2922e956fb3SStefani Seibold (void)({ \ 293e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 2942e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmp->rectype); \ 2952e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 2962e956fb3SStefani Seibold if (__recsize) \ 2972e956fb3SStefani Seibold __kfifo_skip_r(__kfifo, __recsize); \ 2982e956fb3SStefani Seibold else \ 2992e956fb3SStefani Seibold __kfifo->out++; \ 3002e956fb3SStefani Seibold }) 30186d48803SStefani Seibold 30286d48803SStefani Seibold /** 3032e956fb3SStefani Seibold * kfifo_peek_len - gets the size of the next fifo record 3042e956fb3SStefani Seibold * @fifo: address of the fifo to be used 30586d48803SStefani Seibold * 3062e956fb3SStefani Seibold * This function returns the size of the next fifo record in number of bytes. 3072e956fb3SStefani Seibold */ 3082e956fb3SStefani Seibold #define kfifo_peek_len(fifo) \ 309*144ecf31SStefani Seibold __kfifo_uint_must_check_helper( \ 3102e956fb3SStefani Seibold ({ \ 311e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 3122e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmp->rectype); \ 3132e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 3142e956fb3SStefani Seibold (!__recsize) ? kfifo_len(__tmp) * sizeof(*__tmp->type) : \ 3152e956fb3SStefani Seibold __kfifo_len_r(__kfifo, __recsize); \ 3162e956fb3SStefani Seibold }) \ 3172e956fb3SStefani Seibold ) 3182e956fb3SStefani Seibold 3192e956fb3SStefani Seibold /** 3202e956fb3SStefani Seibold * kfifo_alloc - dynamically allocates a new fifo buffer 3212e956fb3SStefani Seibold * @fifo: pointer to the fifo 3222e956fb3SStefani Seibold * @size: the number of elements in the fifo, this must be a power of 2 3232e956fb3SStefani Seibold * @gfp_mask: get_free_pages mask, passed to kmalloc() 3242e956fb3SStefani Seibold * 3252e956fb3SStefani Seibold * This macro dynamically allocates a new fifo buffer. 3262e956fb3SStefani Seibold * 3272e956fb3SStefani Seibold * The numer of elements will be rounded-up to a power of 2. 3282e956fb3SStefani Seibold * The fifo will be release with kfifo_free(). 3292e956fb3SStefani Seibold * Return 0 if no error, otherwise an error code. 3302e956fb3SStefani Seibold */ 3312e956fb3SStefani Seibold #define kfifo_alloc(fifo, size, gfp_mask) \ 332*144ecf31SStefani Seibold __kfifo_int_must_check_helper( \ 3332e956fb3SStefani Seibold ({ \ 334e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 3352e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 3362e956fb3SStefani Seibold __is_kfifo_ptr(__tmp) ? \ 3372e956fb3SStefani Seibold __kfifo_alloc(__kfifo, size, sizeof(*__tmp->type), gfp_mask) : \ 3382e956fb3SStefani Seibold -EINVAL; \ 3392e956fb3SStefani Seibold }) \ 3402e956fb3SStefani Seibold ) 3412e956fb3SStefani Seibold 3422e956fb3SStefani Seibold /** 3432e956fb3SStefani Seibold * kfifo_free - frees the fifo 3442e956fb3SStefani Seibold * @fifo: the fifo to be freed 3452e956fb3SStefani Seibold */ 3462e956fb3SStefani Seibold #define kfifo_free(fifo) \ 3472e956fb3SStefani Seibold ({ \ 348e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 3492e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 3502e956fb3SStefani Seibold if (__is_kfifo_ptr(__tmp)) \ 3512e956fb3SStefani Seibold __kfifo_free(__kfifo); \ 3522e956fb3SStefani Seibold }) 3532e956fb3SStefani Seibold 3542e956fb3SStefani Seibold /** 3552e956fb3SStefani Seibold * kfifo_init - initialize a fifo using a preallocated buffer 3562e956fb3SStefani Seibold * @fifo: the fifo to assign the buffer 3572e956fb3SStefani Seibold * @buffer: the preallocated buffer to be used 3582e956fb3SStefani Seibold * @size: the size of the internal buffer, this have to be a power of 2 3592e956fb3SStefani Seibold * 3602e956fb3SStefani Seibold * This macro initialize a fifo using a preallocated buffer. 3612e956fb3SStefani Seibold * 3622e956fb3SStefani Seibold * The numer of elements will be rounded-up to a power of 2. 3632e956fb3SStefani Seibold * Return 0 if no error, otherwise an error code. 3642e956fb3SStefani Seibold */ 3652e956fb3SStefani Seibold #define kfifo_init(fifo, buffer, size) \ 3662e956fb3SStefani Seibold ({ \ 367e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 3682e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 3692e956fb3SStefani Seibold __is_kfifo_ptr(__tmp) ? \ 3702e956fb3SStefani Seibold __kfifo_init(__kfifo, buffer, size, sizeof(*__tmp->type)) : \ 3712e956fb3SStefani Seibold -EINVAL; \ 3722e956fb3SStefani Seibold }) 3732e956fb3SStefani Seibold 3742e956fb3SStefani Seibold /** 3752e956fb3SStefani Seibold * kfifo_put - put data into the fifo 3762e956fb3SStefani Seibold * @fifo: address of the fifo to be used 3772e956fb3SStefani Seibold * @val: the data to be added 3782e956fb3SStefani Seibold * 3792e956fb3SStefani Seibold * This macro copies the given value into the fifo. 3802e956fb3SStefani Seibold * It returns 0 if the fifo was full. Otherwise it returns the number 3812e956fb3SStefani Seibold * processed elements. 38286d48803SStefani Seibold * 38386d48803SStefani Seibold * Note that with only one concurrent reader and one concurrent 3842e956fb3SStefani Seibold * writer, you don't need extra locking to use these macro. 38586d48803SStefani Seibold */ 3862e956fb3SStefani Seibold #define kfifo_put(fifo, val) \ 3872e956fb3SStefani Seibold ({ \ 388e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 389e0bf1024SHuang Ying typeof((val) + 1) __val = (val); \ 3902e956fb3SStefani Seibold unsigned int __ret; \ 3912e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmp->rectype); \ 3922e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 3932e956fb3SStefani Seibold if (0) { \ 3942e956fb3SStefani Seibold typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \ 3952e956fb3SStefani Seibold __dummy = (typeof(__val))NULL; \ 3962e956fb3SStefani Seibold } \ 3972e956fb3SStefani Seibold if (__recsize) \ 3982e956fb3SStefani Seibold __ret = __kfifo_in_r(__kfifo, __val, sizeof(*__val), \ 3992e956fb3SStefani Seibold __recsize); \ 4002e956fb3SStefani Seibold else { \ 4012e956fb3SStefani Seibold __ret = !kfifo_is_full(__tmp); \ 4022e956fb3SStefani Seibold if (__ret) { \ 4032e956fb3SStefani Seibold (__is_kfifo_ptr(__tmp) ? \ 4042e956fb3SStefani Seibold ((typeof(__tmp->type))__kfifo->data) : \ 4052e956fb3SStefani Seibold (__tmp->buf) \ 4062e956fb3SStefani Seibold )[__kfifo->in & __tmp->kfifo.mask] = \ 4072e956fb3SStefani Seibold *(typeof(__tmp->type))__val; \ 4082e956fb3SStefani Seibold smp_wmb(); \ 4092e956fb3SStefani Seibold __kfifo->in++; \ 4102e956fb3SStefani Seibold } \ 4112e956fb3SStefani Seibold } \ 4122e956fb3SStefani Seibold __ret; \ 4132e956fb3SStefani Seibold }) 41486d48803SStefani Seibold 41586d48803SStefani Seibold /** 4162e956fb3SStefani Seibold * kfifo_get - get data from the fifo 4172e956fb3SStefani Seibold * @fifo: address of the fifo to be used 4182e956fb3SStefani Seibold * @val: the var where to store the data to be added 41986d48803SStefani Seibold * 4202e956fb3SStefani Seibold * This macro reads the data from the fifo. 4212e956fb3SStefani Seibold * It returns 0 if the fifo was empty. Otherwise it returns the number 4222e956fb3SStefani Seibold * processed elements. 42386d48803SStefani Seibold * 42486d48803SStefani Seibold * Note that with only one concurrent reader and one concurrent 4252e956fb3SStefani Seibold * writer, you don't need extra locking to use these macro. 42686d48803SStefani Seibold */ 4272e956fb3SStefani Seibold #define kfifo_get(fifo, val) \ 428*144ecf31SStefani Seibold __kfifo_uint_must_check_helper( \ 4292e956fb3SStefani Seibold ({ \ 430e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 431e0bf1024SHuang Ying typeof((val) + 1) __val = (val); \ 4322e956fb3SStefani Seibold unsigned int __ret; \ 4332e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmp->rectype); \ 4342e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 4352e956fb3SStefani Seibold if (0) \ 4362e956fb3SStefani Seibold __val = (typeof(__tmp->ptr))0; \ 4372e956fb3SStefani Seibold if (__recsize) \ 4382e956fb3SStefani Seibold __ret = __kfifo_out_r(__kfifo, __val, sizeof(*__val), \ 4392e956fb3SStefani Seibold __recsize); \ 4402e956fb3SStefani Seibold else { \ 4412e956fb3SStefani Seibold __ret = !kfifo_is_empty(__tmp); \ 4422e956fb3SStefani Seibold if (__ret) { \ 4432e956fb3SStefani Seibold *(typeof(__tmp->type))__val = \ 4442e956fb3SStefani Seibold (__is_kfifo_ptr(__tmp) ? \ 4452e956fb3SStefani Seibold ((typeof(__tmp->type))__kfifo->data) : \ 4462e956fb3SStefani Seibold (__tmp->buf) \ 4472e956fb3SStefani Seibold )[__kfifo->out & __tmp->kfifo.mask]; \ 4482e956fb3SStefani Seibold smp_wmb(); \ 4492e956fb3SStefani Seibold __kfifo->out++; \ 4502e956fb3SStefani Seibold } \ 4512e956fb3SStefani Seibold } \ 4522e956fb3SStefani Seibold __ret; \ 4532e956fb3SStefani Seibold }) \ 4542e956fb3SStefani Seibold ) 45586d48803SStefani Seibold 45686d48803SStefani Seibold /** 4572e956fb3SStefani Seibold * kfifo_peek - get data from the fifo without removing 4582e956fb3SStefani Seibold * @fifo: address of the fifo to be used 4592e956fb3SStefani Seibold * @val: the var where to store the data to be added 46086d48803SStefani Seibold * 4612e956fb3SStefani Seibold * This reads the data from the fifo without removing it from the fifo. 4622e956fb3SStefani Seibold * It returns 0 if the fifo was empty. Otherwise it returns the number 4632e956fb3SStefani Seibold * processed elements. 46486d48803SStefani Seibold * 46586d48803SStefani Seibold * Note that with only one concurrent reader and one concurrent 4662e956fb3SStefani Seibold * writer, you don't need extra locking to use these macro. 46786d48803SStefani Seibold */ 4682e956fb3SStefani Seibold #define kfifo_peek(fifo, val) \ 469*144ecf31SStefani Seibold __kfifo_uint_must_check_helper( \ 4702e956fb3SStefani Seibold ({ \ 471e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 472e0bf1024SHuang Ying typeof((val) + 1) __val = (val); \ 4732e956fb3SStefani Seibold unsigned int __ret; \ 4742e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmp->rectype); \ 4752e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 4762e956fb3SStefani Seibold if (0) \ 4772e956fb3SStefani Seibold __val = (typeof(__tmp->ptr))NULL; \ 4782e956fb3SStefani Seibold if (__recsize) \ 4792e956fb3SStefani Seibold __ret = __kfifo_out_peek_r(__kfifo, __val, sizeof(*__val), \ 4802e956fb3SStefani Seibold __recsize); \ 4812e956fb3SStefani Seibold else { \ 4822e956fb3SStefani Seibold __ret = !kfifo_is_empty(__tmp); \ 4832e956fb3SStefani Seibold if (__ret) { \ 4842e956fb3SStefani Seibold *(typeof(__tmp->type))__val = \ 4852e956fb3SStefani Seibold (__is_kfifo_ptr(__tmp) ? \ 4862e956fb3SStefani Seibold ((typeof(__tmp->type))__kfifo->data) : \ 4872e956fb3SStefani Seibold (__tmp->buf) \ 4882e956fb3SStefani Seibold )[__kfifo->out & __tmp->kfifo.mask]; \ 4892e956fb3SStefani Seibold smp_wmb(); \ 4902e956fb3SStefani Seibold } \ 4912e956fb3SStefani Seibold } \ 4922e956fb3SStefani Seibold __ret; \ 4932e956fb3SStefani Seibold }) \ 4942e956fb3SStefani Seibold ) 49586d48803SStefani Seibold 49686d48803SStefani Seibold /** 4972e956fb3SStefani Seibold * kfifo_in - put data into the fifo 4982e956fb3SStefani Seibold * @fifo: address of the fifo to be used 4992e956fb3SStefani Seibold * @buf: the data to be added 5002e956fb3SStefani Seibold * @n: number of elements to be added 50186d48803SStefani Seibold * 5022e956fb3SStefani Seibold * This macro copies the given buffer into the fifo and returns the 5032e956fb3SStefani Seibold * number of copied elements. 50486d48803SStefani Seibold * 50586d48803SStefani Seibold * Note that with only one concurrent reader and one concurrent 5062e956fb3SStefani Seibold * writer, you don't need extra locking to use these macro. 50786d48803SStefani Seibold */ 5082e956fb3SStefani Seibold #define kfifo_in(fifo, buf, n) \ 5092e956fb3SStefani Seibold ({ \ 510e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 511e0bf1024SHuang Ying typeof((buf) + 1) __buf = (buf); \ 5122e956fb3SStefani Seibold unsigned long __n = (n); \ 5132e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmp->rectype); \ 5142e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 5152e956fb3SStefani Seibold if (0) { \ 5162e956fb3SStefani Seibold typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \ 5172e956fb3SStefani Seibold __dummy = (typeof(__buf))NULL; \ 5182e956fb3SStefani Seibold } \ 5192e956fb3SStefani Seibold (__recsize) ?\ 5202e956fb3SStefani Seibold __kfifo_in_r(__kfifo, __buf, __n, __recsize) : \ 5212e956fb3SStefani Seibold __kfifo_in(__kfifo, __buf, __n); \ 5222e956fb3SStefani Seibold }) 52386d48803SStefani Seibold 52486d48803SStefani Seibold /** 5252e956fb3SStefani Seibold * kfifo_in_spinlocked - put data into the fifo using a spinlock for locking 5262e956fb3SStefani Seibold * @fifo: address of the fifo to be used 5272e956fb3SStefani Seibold * @buf: the data to be added 5282e956fb3SStefani Seibold * @n: number of elements to be added 5292e956fb3SStefani Seibold * @lock: pointer to the spinlock to use for locking 53086d48803SStefani Seibold * 5312e956fb3SStefani Seibold * This macro copies the given values buffer into the fifo and returns the 5322e956fb3SStefani Seibold * number of copied elements. 53386d48803SStefani Seibold */ 5342e956fb3SStefani Seibold #define kfifo_in_spinlocked(fifo, buf, n, lock) \ 5352e956fb3SStefani Seibold ({ \ 5362e956fb3SStefani Seibold unsigned long __flags; \ 5372e956fb3SStefani Seibold unsigned int __ret; \ 5382e956fb3SStefani Seibold spin_lock_irqsave(lock, __flags); \ 5392e956fb3SStefani Seibold __ret = kfifo_in(fifo, buf, n); \ 5402e956fb3SStefani Seibold spin_unlock_irqrestore(lock, __flags); \ 5412e956fb3SStefani Seibold __ret; \ 5422e956fb3SStefani Seibold }) 54386d48803SStefani Seibold 5442e956fb3SStefani Seibold /* alias for kfifo_in_spinlocked, will be removed in a future release */ 5452e956fb3SStefani Seibold #define kfifo_in_locked(fifo, buf, n, lock) \ 5462e956fb3SStefani Seibold kfifo_in_spinlocked(fifo, buf, n, lock) 54786d48803SStefani Seibold 54886d48803SStefani Seibold /** 5492e956fb3SStefani Seibold * kfifo_out - get data from the fifo 5502e956fb3SStefani Seibold * @fifo: address of the fifo to be used 5512e956fb3SStefani Seibold * @buf: pointer to the storage buffer 5522e956fb3SStefani Seibold * @n: max. number of elements to get 55386d48803SStefani Seibold * 5542e956fb3SStefani Seibold * This macro get some data from the fifo and return the numbers of elements 5552e956fb3SStefani Seibold * copied. 5562e956fb3SStefani Seibold * 5572e956fb3SStefani Seibold * Note that with only one concurrent reader and one concurrent 5582e956fb3SStefani Seibold * writer, you don't need extra locking to use these macro. 55986d48803SStefani Seibold */ 5602e956fb3SStefani Seibold #define kfifo_out(fifo, buf, n) \ 561*144ecf31SStefani Seibold __kfifo_uint_must_check_helper( \ 5622e956fb3SStefani Seibold ({ \ 563e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 564e0bf1024SHuang Ying typeof((buf) + 1) __buf = (buf); \ 5652e956fb3SStefani Seibold unsigned long __n = (n); \ 5662e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmp->rectype); \ 5672e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 5682e956fb3SStefani Seibold if (0) { \ 5692e956fb3SStefani Seibold typeof(__tmp->ptr) __dummy = NULL; \ 5702e956fb3SStefani Seibold __buf = __dummy; \ 5712e956fb3SStefani Seibold } \ 5722e956fb3SStefani Seibold (__recsize) ?\ 5732e956fb3SStefani Seibold __kfifo_out_r(__kfifo, __buf, __n, __recsize) : \ 5742e956fb3SStefani Seibold __kfifo_out(__kfifo, __buf, __n); \ 5752e956fb3SStefani Seibold }) \ 5762e956fb3SStefani Seibold ) 57786d48803SStefani Seibold 57886d48803SStefani Seibold /** 5792e956fb3SStefani Seibold * kfifo_out_spinlocked - get data from the fifo using a spinlock for locking 5802e956fb3SStefani Seibold * @fifo: address of the fifo to be used 5812e956fb3SStefani Seibold * @buf: pointer to the storage buffer 5822e956fb3SStefani Seibold * @n: max. number of elements to get 5832e956fb3SStefani Seibold * @lock: pointer to the spinlock to use for locking 5842e956fb3SStefani Seibold * 5852e956fb3SStefani Seibold * This macro get the data from the fifo and return the numbers of elements 5862e956fb3SStefani Seibold * copied. 58786d48803SStefani Seibold */ 5882e956fb3SStefani Seibold #define kfifo_out_spinlocked(fifo, buf, n, lock) \ 589*144ecf31SStefani Seibold __kfifo_uint_must_check_helper( \ 5902e956fb3SStefani Seibold ({ \ 5912e956fb3SStefani Seibold unsigned long __flags; \ 5922e956fb3SStefani Seibold unsigned int __ret; \ 5932e956fb3SStefani Seibold spin_lock_irqsave(lock, __flags); \ 5942e956fb3SStefani Seibold __ret = kfifo_out(fifo, buf, n); \ 5952e956fb3SStefani Seibold spin_unlock_irqrestore(lock, __flags); \ 5962e956fb3SStefani Seibold __ret; \ 5972e956fb3SStefani Seibold }) \ 5982e956fb3SStefani Seibold ) 59986d48803SStefani Seibold 6002e956fb3SStefani Seibold /* alias for kfifo_out_spinlocked, will be removed in a future release */ 6012e956fb3SStefani Seibold #define kfifo_out_locked(fifo, buf, n, lock) \ 6022e956fb3SStefani Seibold kfifo_out_spinlocked(fifo, buf, n, lock) 6032e956fb3SStefani Seibold 6042e956fb3SStefani Seibold /** 6052e956fb3SStefani Seibold * kfifo_from_user - puts some data from user space into the fifo 6062e956fb3SStefani Seibold * @fifo: address of the fifo to be used 6072e956fb3SStefani Seibold * @from: pointer to the data to be added 6082e956fb3SStefani Seibold * @len: the length of the data to be added 6092e956fb3SStefani Seibold * @copied: pointer to output variable to store the number of copied bytes 6102e956fb3SStefani Seibold * 6112e956fb3SStefani Seibold * This macro copies at most @len bytes from the @from into the 6122e956fb3SStefani Seibold * fifo, depending of the available space and returns -EFAULT/0. 6132e956fb3SStefani Seibold * 6142e956fb3SStefani Seibold * Note that with only one concurrent reader and one concurrent 6152e956fb3SStefani Seibold * writer, you don't need extra locking to use these macro. 6162e956fb3SStefani Seibold */ 6172e956fb3SStefani Seibold #define kfifo_from_user(fifo, from, len, copied) \ 618*144ecf31SStefani Seibold __kfifo_uint_must_check_helper( \ 6192e956fb3SStefani Seibold ({ \ 620e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 6212e956fb3SStefani Seibold const void __user *__from = (from); \ 6222e956fb3SStefani Seibold unsigned int __len = (len); \ 6232e956fb3SStefani Seibold unsigned int *__copied = (copied); \ 6242e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmp->rectype); \ 6252e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 6262e956fb3SStefani Seibold (__recsize) ? \ 6272e956fb3SStefani Seibold __kfifo_from_user_r(__kfifo, __from, __len, __copied, __recsize) : \ 6282e956fb3SStefani Seibold __kfifo_from_user(__kfifo, __from, __len, __copied); \ 6292e956fb3SStefani Seibold }) \ 6302e956fb3SStefani Seibold ) 6312e956fb3SStefani Seibold 6322e956fb3SStefani Seibold /** 6332e956fb3SStefani Seibold * kfifo_to_user - copies data from the fifo into user space 6342e956fb3SStefani Seibold * @fifo: address of the fifo to be used 6352e956fb3SStefani Seibold * @to: where the data must be copied 6362e956fb3SStefani Seibold * @len: the size of the destination buffer 6372e956fb3SStefani Seibold * @copied: pointer to output variable to store the number of copied bytes 6382e956fb3SStefani Seibold * 6392e956fb3SStefani Seibold * This macro copies at most @len bytes from the fifo into the 6402e956fb3SStefani Seibold * @to buffer and returns -EFAULT/0. 6412e956fb3SStefani Seibold * 6422e956fb3SStefani Seibold * Note that with only one concurrent reader and one concurrent 6432e956fb3SStefani Seibold * writer, you don't need extra locking to use these macro. 6442e956fb3SStefani Seibold */ 6452e956fb3SStefani Seibold #define kfifo_to_user(fifo, to, len, copied) \ 646*144ecf31SStefani Seibold __kfifo_uint_must_check_helper( \ 6472e956fb3SStefani Seibold ({ \ 648e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 6492e956fb3SStefani Seibold void __user *__to = (to); \ 6502e956fb3SStefani Seibold unsigned int __len = (len); \ 6512e956fb3SStefani Seibold unsigned int *__copied = (copied); \ 6522e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmp->rectype); \ 6532e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 6542e956fb3SStefani Seibold (__recsize) ? \ 6552e956fb3SStefani Seibold __kfifo_to_user_r(__kfifo, __to, __len, __copied, __recsize) : \ 6562e956fb3SStefani Seibold __kfifo_to_user(__kfifo, __to, __len, __copied); \ 6572e956fb3SStefani Seibold }) \ 6582e956fb3SStefani Seibold ) 6592e956fb3SStefani Seibold 6602e956fb3SStefani Seibold /** 6612e956fb3SStefani Seibold * kfifo_dma_in_prepare - setup a scatterlist for DMA input 6622e956fb3SStefani Seibold * @fifo: address of the fifo to be used 6632e956fb3SStefani Seibold * @sgl: pointer to the scatterlist array 6642e956fb3SStefani Seibold * @nents: number of entries in the scatterlist array 6652e956fb3SStefani Seibold * @len: number of elements to transfer 6662e956fb3SStefani Seibold * 6672e956fb3SStefani Seibold * This macro fills a scatterlist for DMA input. 6682e956fb3SStefani Seibold * It returns the number entries in the scatterlist array. 6692e956fb3SStefani Seibold * 6702e956fb3SStefani Seibold * Note that with only one concurrent reader and one concurrent 6712e956fb3SStefani Seibold * writer, you don't need extra locking to use these macros. 6722e956fb3SStefani Seibold */ 6732e956fb3SStefani Seibold #define kfifo_dma_in_prepare(fifo, sgl, nents, len) \ 6742e956fb3SStefani Seibold ({ \ 675e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 6762e956fb3SStefani Seibold struct scatterlist *__sgl = (sgl); \ 6772e956fb3SStefani Seibold int __nents = (nents); \ 6782e956fb3SStefani Seibold unsigned int __len = (len); \ 6792e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmp->rectype); \ 6802e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 6812e956fb3SStefani Seibold (__recsize) ? \ 6822e956fb3SStefani Seibold __kfifo_dma_in_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \ 6832e956fb3SStefani Seibold __kfifo_dma_in_prepare(__kfifo, __sgl, __nents, __len); \ 6842e956fb3SStefani Seibold }) 6852e956fb3SStefani Seibold 6862e956fb3SStefani Seibold /** 6872e956fb3SStefani Seibold * kfifo_dma_in_finish - finish a DMA IN operation 6882e956fb3SStefani Seibold * @fifo: address of the fifo to be used 6892e956fb3SStefani Seibold * @len: number of bytes to received 6902e956fb3SStefani Seibold * 6912e956fb3SStefani Seibold * This macro finish a DMA IN operation. The in counter will be updated by 6922e956fb3SStefani Seibold * the len parameter. No error checking will be done. 6932e956fb3SStefani Seibold * 6942e956fb3SStefani Seibold * Note that with only one concurrent reader and one concurrent 6952e956fb3SStefani Seibold * writer, you don't need extra locking to use these macros. 6962e956fb3SStefani Seibold */ 6972e956fb3SStefani Seibold #define kfifo_dma_in_finish(fifo, len) \ 6982e956fb3SStefani Seibold (void)({ \ 699e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 7002e956fb3SStefani Seibold unsigned int __len = (len); \ 7012e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmp->rectype); \ 7022e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 7032e956fb3SStefani Seibold if (__recsize) \ 7042e956fb3SStefani Seibold __kfifo_dma_in_finish_r(__kfifo, __len, __recsize); \ 7052e956fb3SStefani Seibold else \ 7062e956fb3SStefani Seibold __kfifo->in += __len / sizeof(*__tmp->type); \ 7072e956fb3SStefani Seibold }) 7082e956fb3SStefani Seibold 7092e956fb3SStefani Seibold /** 7102e956fb3SStefani Seibold * kfifo_dma_out_prepare - setup a scatterlist for DMA output 7112e956fb3SStefani Seibold * @fifo: address of the fifo to be used 7122e956fb3SStefani Seibold * @sgl: pointer to the scatterlist array 7132e956fb3SStefani Seibold * @nents: number of entries in the scatterlist array 7142e956fb3SStefani Seibold * @len: number of elements to transfer 7152e956fb3SStefani Seibold * 7162e956fb3SStefani Seibold * This macro fills a scatterlist for DMA output which at most @len bytes 7172e956fb3SStefani Seibold * to transfer. 7182e956fb3SStefani Seibold * It returns the number entries in the scatterlist array. 7192e956fb3SStefani Seibold * A zero means there is no space available and the scatterlist is not filled. 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_out_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_out_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \ 7342e956fb3SStefani Seibold __kfifo_dma_out_prepare(__kfifo, __sgl, __nents, __len); \ 7352e956fb3SStefani Seibold }) 7362e956fb3SStefani Seibold 7372e956fb3SStefani Seibold /** 7382e956fb3SStefani Seibold * kfifo_dma_out_finish - finish a DMA OUT operation 7392e956fb3SStefani Seibold * @fifo: address of the fifo to be used 7402e956fb3SStefani Seibold * @len: number of bytes transferd 7412e956fb3SStefani Seibold * 7422e956fb3SStefani Seibold * This macro finish a DMA OUT operation. The out 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_out_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_out_finish_r(__kfifo, __recsize); \ 7562e956fb3SStefani Seibold else \ 7572e956fb3SStefani Seibold __kfifo->out += __len / sizeof(*__tmp->type); \ 7582e956fb3SStefani Seibold }) 7592e956fb3SStefani Seibold 7602e956fb3SStefani Seibold /** 7612e956fb3SStefani Seibold * kfifo_out_peek - gets some data from the fifo 7622e956fb3SStefani Seibold * @fifo: address of the fifo to be used 7632e956fb3SStefani Seibold * @buf: pointer to the storage buffer 7642e956fb3SStefani Seibold * @n: max. number of elements to get 7652e956fb3SStefani Seibold * 7662e956fb3SStefani Seibold * This macro get the data from the fifo and return the numbers of elements 7672e956fb3SStefani Seibold * copied. The data is not removed from the fifo. 7682e956fb3SStefani Seibold * 7692e956fb3SStefani Seibold * Note that with only one concurrent reader and one concurrent 7702e956fb3SStefani Seibold * writer, you don't need extra locking to use these macro. 7712e956fb3SStefani Seibold */ 7722e956fb3SStefani Seibold #define kfifo_out_peek(fifo, buf, n) \ 773*144ecf31SStefani Seibold __kfifo_uint_must_check_helper( \ 7742e956fb3SStefani Seibold ({ \ 775e0bf1024SHuang Ying typeof((fifo) + 1) __tmp = (fifo); \ 776e0bf1024SHuang Ying typeof((buf) + 1) __buf = (buf); \ 7772e956fb3SStefani Seibold unsigned long __n = (n); \ 7782e956fb3SStefani Seibold const size_t __recsize = sizeof(*__tmp->rectype); \ 7792e956fb3SStefani Seibold struct __kfifo *__kfifo = &__tmp->kfifo; \ 7802e956fb3SStefani Seibold if (0) { \ 7812e956fb3SStefani Seibold typeof(__tmp->ptr) __dummy __attribute__ ((unused)) = NULL; \ 7822e956fb3SStefani Seibold __buf = __dummy; \ 7832e956fb3SStefani Seibold } \ 7842e956fb3SStefani Seibold (__recsize) ? \ 7852e956fb3SStefani Seibold __kfifo_out_peek_r(__kfifo, __buf, __n, __recsize) : \ 7862e956fb3SStefani Seibold __kfifo_out_peek(__kfifo, __buf, __n); \ 7872e956fb3SStefani Seibold }) \ 7882e956fb3SStefani Seibold ) 7892e956fb3SStefani Seibold 7902e956fb3SStefani Seibold extern int __kfifo_alloc(struct __kfifo *fifo, unsigned int size, 7912e956fb3SStefani Seibold size_t esize, gfp_t gfp_mask); 7922e956fb3SStefani Seibold 7932e956fb3SStefani Seibold extern void __kfifo_free(struct __kfifo *fifo); 7942e956fb3SStefani Seibold 7952e956fb3SStefani Seibold extern int __kfifo_init(struct __kfifo *fifo, void *buffer, 7962e956fb3SStefani Seibold unsigned int size, size_t esize); 7972e956fb3SStefani Seibold 7982e956fb3SStefani Seibold extern unsigned int __kfifo_in(struct __kfifo *fifo, 7992e956fb3SStefani Seibold const void *buf, unsigned int len); 8002e956fb3SStefani Seibold 8012e956fb3SStefani Seibold extern unsigned int __kfifo_out(struct __kfifo *fifo, 8022e956fb3SStefani Seibold void *buf, unsigned int len); 8032e956fb3SStefani Seibold 8042e956fb3SStefani Seibold extern int __kfifo_from_user(struct __kfifo *fifo, 8052e956fb3SStefani Seibold const void __user *from, unsigned long len, unsigned int *copied); 8062e956fb3SStefani Seibold 8072e956fb3SStefani Seibold extern int __kfifo_to_user(struct __kfifo *fifo, 8082e956fb3SStefani Seibold void __user *to, unsigned long len, unsigned int *copied); 8092e956fb3SStefani Seibold 8102e956fb3SStefani Seibold extern unsigned int __kfifo_dma_in_prepare(struct __kfifo *fifo, 8112e956fb3SStefani Seibold struct scatterlist *sgl, int nents, unsigned int len); 8122e956fb3SStefani Seibold 8132e956fb3SStefani Seibold extern unsigned int __kfifo_dma_out_prepare(struct __kfifo *fifo, 8142e956fb3SStefani Seibold struct scatterlist *sgl, int nents, unsigned int len); 8152e956fb3SStefani Seibold 8162e956fb3SStefani Seibold extern unsigned int __kfifo_out_peek(struct __kfifo *fifo, 8172e956fb3SStefani Seibold void *buf, unsigned int len); 8182e956fb3SStefani Seibold 8192e956fb3SStefani Seibold extern unsigned int __kfifo_in_r(struct __kfifo *fifo, 8202e956fb3SStefani Seibold const void *buf, unsigned int len, size_t recsize); 8212e956fb3SStefani Seibold 8222e956fb3SStefani Seibold extern unsigned int __kfifo_out_r(struct __kfifo *fifo, 8232e956fb3SStefani Seibold void *buf, unsigned int len, size_t recsize); 8242e956fb3SStefani Seibold 8252e956fb3SStefani Seibold extern int __kfifo_from_user_r(struct __kfifo *fifo, 8262e956fb3SStefani Seibold const void __user *from, unsigned long len, unsigned int *copied, 8272e956fb3SStefani Seibold size_t recsize); 8282e956fb3SStefani Seibold 8292e956fb3SStefani Seibold extern int __kfifo_to_user_r(struct __kfifo *fifo, void __user *to, 8302e956fb3SStefani Seibold unsigned long len, unsigned int *copied, size_t recsize); 8312e956fb3SStefani Seibold 8322e956fb3SStefani Seibold extern unsigned int __kfifo_dma_in_prepare_r(struct __kfifo *fifo, 8332e956fb3SStefani Seibold struct scatterlist *sgl, int nents, unsigned int len, size_t recsize); 8342e956fb3SStefani Seibold 8352e956fb3SStefani Seibold extern void __kfifo_dma_in_finish_r(struct __kfifo *fifo, 8362e956fb3SStefani Seibold unsigned int len, size_t recsize); 8372e956fb3SStefani Seibold 8382e956fb3SStefani Seibold extern unsigned int __kfifo_dma_out_prepare_r(struct __kfifo *fifo, 8392e956fb3SStefani Seibold struct scatterlist *sgl, int nents, unsigned int len, size_t recsize); 8402e956fb3SStefani Seibold 8412e956fb3SStefani Seibold extern void __kfifo_dma_out_finish_r(struct __kfifo *fifo, size_t recsize); 8422e956fb3SStefani Seibold 8432e956fb3SStefani Seibold extern unsigned int __kfifo_len_r(struct __kfifo *fifo, size_t recsize); 8442e956fb3SStefani Seibold 845b35de43bSAndrea Righi extern void __kfifo_skip_r(struct __kfifo *fifo, size_t recsize); 846b35de43bSAndrea Righi 8472e956fb3SStefani Seibold extern unsigned int __kfifo_out_peek_r(struct __kfifo *fifo, 8482e956fb3SStefani Seibold void *buf, unsigned int len, size_t recsize); 8492e956fb3SStefani Seibold 8502e956fb3SStefani Seibold extern unsigned int __kfifo_max_r(unsigned int len, size_t recsize); 85186d48803SStefani Seibold 8521da177e4SLinus Torvalds #endif 853