xref: /linux/include/linux/kfifo.h (revision 144ecf310eb52d9df607b9b7eeb096743e232a96)
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