162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * A generic kernel FIFO implementation
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2013 Stefani Seibold <stefani@seibold.net>
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#ifndef _LINUX_KFIFO_H
962306a36Sopenharmony_ci#define _LINUX_KFIFO_H
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci/*
1262306a36Sopenharmony_ci * How to porting drivers to the new generic FIFO API:
1362306a36Sopenharmony_ci *
1462306a36Sopenharmony_ci * - Modify the declaration of the "struct kfifo *" object into a
1562306a36Sopenharmony_ci *   in-place "struct kfifo" object
1662306a36Sopenharmony_ci * - Init the in-place object with kfifo_alloc() or kfifo_init()
1762306a36Sopenharmony_ci *   Note: The address of the in-place "struct kfifo" object must be
1862306a36Sopenharmony_ci *   passed as the first argument to this functions
1962306a36Sopenharmony_ci * - Replace the use of __kfifo_put into kfifo_in and __kfifo_get
2062306a36Sopenharmony_ci *   into kfifo_out
2162306a36Sopenharmony_ci * - Replace the use of kfifo_put into kfifo_in_spinlocked and kfifo_get
2262306a36Sopenharmony_ci *   into kfifo_out_spinlocked
2362306a36Sopenharmony_ci *   Note: the spinlock pointer formerly passed to kfifo_init/kfifo_alloc
2462306a36Sopenharmony_ci *   must be passed now to the kfifo_in_spinlocked and kfifo_out_spinlocked
2562306a36Sopenharmony_ci *   as the last parameter
2662306a36Sopenharmony_ci * - The formerly __kfifo_* functions are renamed into kfifo_*
2762306a36Sopenharmony_ci */
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci/*
3062306a36Sopenharmony_ci * Note about locking: There is no locking required until only one reader
3162306a36Sopenharmony_ci * and one writer is using the fifo and no kfifo_reset() will be called.
3262306a36Sopenharmony_ci * kfifo_reset_out() can be safely used, until it will be only called
3362306a36Sopenharmony_ci * in the reader thread.
3462306a36Sopenharmony_ci * For multiple writer and one reader there is only a need to lock the writer.
3562306a36Sopenharmony_ci * And vice versa for only one writer and multiple reader there is only a need
3662306a36Sopenharmony_ci * to lock the reader.
3762306a36Sopenharmony_ci */
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci#include <linux/kernel.h>
4062306a36Sopenharmony_ci#include <linux/spinlock.h>
4162306a36Sopenharmony_ci#include <linux/stddef.h>
4262306a36Sopenharmony_ci#include <linux/scatterlist.h>
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_cistruct __kfifo {
4562306a36Sopenharmony_ci	unsigned int	in;
4662306a36Sopenharmony_ci	unsigned int	out;
4762306a36Sopenharmony_ci	unsigned int	mask;
4862306a36Sopenharmony_ci	unsigned int	esize;
4962306a36Sopenharmony_ci	void		*data;
5062306a36Sopenharmony_ci};
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci#define __STRUCT_KFIFO_COMMON(datatype, recsize, ptrtype) \
5362306a36Sopenharmony_ci	union { \
5462306a36Sopenharmony_ci		struct __kfifo	kfifo; \
5562306a36Sopenharmony_ci		datatype	*type; \
5662306a36Sopenharmony_ci		const datatype	*const_type; \
5762306a36Sopenharmony_ci		char		(*rectype)[recsize]; \
5862306a36Sopenharmony_ci		ptrtype		*ptr; \
5962306a36Sopenharmony_ci		ptrtype const	*ptr_const; \
6062306a36Sopenharmony_ci	}
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci#define __STRUCT_KFIFO(type, size, recsize, ptrtype) \
6362306a36Sopenharmony_ci{ \
6462306a36Sopenharmony_ci	__STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \
6562306a36Sopenharmony_ci	type		buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \
6662306a36Sopenharmony_ci}
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci#define STRUCT_KFIFO(type, size) \
6962306a36Sopenharmony_ci	struct __STRUCT_KFIFO(type, size, 0, type)
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci#define __STRUCT_KFIFO_PTR(type, recsize, ptrtype) \
7262306a36Sopenharmony_ci{ \
7362306a36Sopenharmony_ci	__STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \
7462306a36Sopenharmony_ci	type		buf[0]; \
7562306a36Sopenharmony_ci}
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci#define STRUCT_KFIFO_PTR(type) \
7862306a36Sopenharmony_ci	struct __STRUCT_KFIFO_PTR(type, 0, type)
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci/*
8162306a36Sopenharmony_ci * define compatibility "struct kfifo" for dynamic allocated fifos
8262306a36Sopenharmony_ci */
8362306a36Sopenharmony_cistruct kfifo __STRUCT_KFIFO_PTR(unsigned char, 0, void);
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci#define STRUCT_KFIFO_REC_1(size) \
8662306a36Sopenharmony_ci	struct __STRUCT_KFIFO(unsigned char, size, 1, void)
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci#define STRUCT_KFIFO_REC_2(size) \
8962306a36Sopenharmony_ci	struct __STRUCT_KFIFO(unsigned char, size, 2, void)
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci/*
9262306a36Sopenharmony_ci * define kfifo_rec types
9362306a36Sopenharmony_ci */
9462306a36Sopenharmony_cistruct kfifo_rec_ptr_1 __STRUCT_KFIFO_PTR(unsigned char, 1, void);
9562306a36Sopenharmony_cistruct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2, void);
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci/*
9862306a36Sopenharmony_ci * helper macro to distinguish between real in place fifo where the fifo
9962306a36Sopenharmony_ci * array is a part of the structure and the fifo type where the array is
10062306a36Sopenharmony_ci * outside of the fifo structure.
10162306a36Sopenharmony_ci */
10262306a36Sopenharmony_ci#define	__is_kfifo_ptr(fifo) \
10362306a36Sopenharmony_ci	(sizeof(*fifo) == sizeof(STRUCT_KFIFO_PTR(typeof(*(fifo)->type))))
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci/**
10662306a36Sopenharmony_ci * DECLARE_KFIFO_PTR - macro to declare a fifo pointer object
10762306a36Sopenharmony_ci * @fifo: name of the declared fifo
10862306a36Sopenharmony_ci * @type: type of the fifo elements
10962306a36Sopenharmony_ci */
11062306a36Sopenharmony_ci#define DECLARE_KFIFO_PTR(fifo, type)	STRUCT_KFIFO_PTR(type) fifo
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci/**
11362306a36Sopenharmony_ci * DECLARE_KFIFO - macro to declare a fifo object
11462306a36Sopenharmony_ci * @fifo: name of the declared fifo
11562306a36Sopenharmony_ci * @type: type of the fifo elements
11662306a36Sopenharmony_ci * @size: the number of elements in the fifo, this must be a power of 2
11762306a36Sopenharmony_ci */
11862306a36Sopenharmony_ci#define DECLARE_KFIFO(fifo, type, size)	STRUCT_KFIFO(type, size) fifo
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci/**
12162306a36Sopenharmony_ci * INIT_KFIFO - Initialize a fifo declared by DECLARE_KFIFO
12262306a36Sopenharmony_ci * @fifo: name of the declared fifo datatype
12362306a36Sopenharmony_ci */
12462306a36Sopenharmony_ci#define INIT_KFIFO(fifo) \
12562306a36Sopenharmony_ci(void)({ \
12662306a36Sopenharmony_ci	typeof(&(fifo)) __tmp = &(fifo); \
12762306a36Sopenharmony_ci	struct __kfifo *__kfifo = &__tmp->kfifo; \
12862306a36Sopenharmony_ci	__kfifo->in = 0; \
12962306a36Sopenharmony_ci	__kfifo->out = 0; \
13062306a36Sopenharmony_ci	__kfifo->mask = __is_kfifo_ptr(__tmp) ? 0 : ARRAY_SIZE(__tmp->buf) - 1;\
13162306a36Sopenharmony_ci	__kfifo->esize = sizeof(*__tmp->buf); \
13262306a36Sopenharmony_ci	__kfifo->data = __is_kfifo_ptr(__tmp) ?  NULL : __tmp->buf; \
13362306a36Sopenharmony_ci})
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci/**
13662306a36Sopenharmony_ci * DEFINE_KFIFO - macro to define and initialize a fifo
13762306a36Sopenharmony_ci * @fifo: name of the declared fifo datatype
13862306a36Sopenharmony_ci * @type: type of the fifo elements
13962306a36Sopenharmony_ci * @size: the number of elements in the fifo, this must be a power of 2
14062306a36Sopenharmony_ci *
14162306a36Sopenharmony_ci * Note: the macro can be used for global and local fifo data type variables.
14262306a36Sopenharmony_ci */
14362306a36Sopenharmony_ci#define DEFINE_KFIFO(fifo, type, size) \
14462306a36Sopenharmony_ci	DECLARE_KFIFO(fifo, type, size) = \
14562306a36Sopenharmony_ci	(typeof(fifo)) { \
14662306a36Sopenharmony_ci		{ \
14762306a36Sopenharmony_ci			{ \
14862306a36Sopenharmony_ci			.in	= 0, \
14962306a36Sopenharmony_ci			.out	= 0, \
15062306a36Sopenharmony_ci			.mask	= __is_kfifo_ptr(&(fifo)) ? \
15162306a36Sopenharmony_ci				  0 : \
15262306a36Sopenharmony_ci				  ARRAY_SIZE((fifo).buf) - 1, \
15362306a36Sopenharmony_ci			.esize	= sizeof(*(fifo).buf), \
15462306a36Sopenharmony_ci			.data	= __is_kfifo_ptr(&(fifo)) ? \
15562306a36Sopenharmony_ci				NULL : \
15662306a36Sopenharmony_ci				(fifo).buf, \
15762306a36Sopenharmony_ci			} \
15862306a36Sopenharmony_ci		} \
15962306a36Sopenharmony_ci	}
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_cistatic inline unsigned int __must_check
16362306a36Sopenharmony_ci__kfifo_uint_must_check_helper(unsigned int val)
16462306a36Sopenharmony_ci{
16562306a36Sopenharmony_ci	return val;
16662306a36Sopenharmony_ci}
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_cistatic inline int __must_check
16962306a36Sopenharmony_ci__kfifo_int_must_check_helper(int val)
17062306a36Sopenharmony_ci{
17162306a36Sopenharmony_ci	return val;
17262306a36Sopenharmony_ci}
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci/**
17562306a36Sopenharmony_ci * kfifo_initialized - Check if the fifo is initialized
17662306a36Sopenharmony_ci * @fifo: address of the fifo to check
17762306a36Sopenharmony_ci *
17862306a36Sopenharmony_ci * Return %true if fifo is initialized, otherwise %false.
17962306a36Sopenharmony_ci * Assumes the fifo was 0 before.
18062306a36Sopenharmony_ci */
18162306a36Sopenharmony_ci#define kfifo_initialized(fifo) ((fifo)->kfifo.mask)
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci/**
18462306a36Sopenharmony_ci * kfifo_esize - returns the size of the element managed by the fifo
18562306a36Sopenharmony_ci * @fifo: address of the fifo to be used
18662306a36Sopenharmony_ci */
18762306a36Sopenharmony_ci#define kfifo_esize(fifo)	((fifo)->kfifo.esize)
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci/**
19062306a36Sopenharmony_ci * kfifo_recsize - returns the size of the record length field
19162306a36Sopenharmony_ci * @fifo: address of the fifo to be used
19262306a36Sopenharmony_ci */
19362306a36Sopenharmony_ci#define kfifo_recsize(fifo)	(sizeof(*(fifo)->rectype))
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci/**
19662306a36Sopenharmony_ci * kfifo_size - returns the size of the fifo in elements
19762306a36Sopenharmony_ci * @fifo: address of the fifo to be used
19862306a36Sopenharmony_ci */
19962306a36Sopenharmony_ci#define kfifo_size(fifo)	((fifo)->kfifo.mask + 1)
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci/**
20262306a36Sopenharmony_ci * kfifo_reset - removes the entire fifo content
20362306a36Sopenharmony_ci * @fifo: address of the fifo to be used
20462306a36Sopenharmony_ci *
20562306a36Sopenharmony_ci * Note: usage of kfifo_reset() is dangerous. It should be only called when the
20662306a36Sopenharmony_ci * fifo is exclusived locked or when it is secured that no other thread is
20762306a36Sopenharmony_ci * accessing the fifo.
20862306a36Sopenharmony_ci */
20962306a36Sopenharmony_ci#define kfifo_reset(fifo) \
21062306a36Sopenharmony_ci(void)({ \
21162306a36Sopenharmony_ci	typeof((fifo) + 1) __tmp = (fifo); \
21262306a36Sopenharmony_ci	__tmp->kfifo.in = __tmp->kfifo.out = 0; \
21362306a36Sopenharmony_ci})
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ci/**
21662306a36Sopenharmony_ci * kfifo_reset_out - skip fifo content
21762306a36Sopenharmony_ci * @fifo: address of the fifo to be used
21862306a36Sopenharmony_ci *
21962306a36Sopenharmony_ci * Note: The usage of kfifo_reset_out() is safe until it will be only called
22062306a36Sopenharmony_ci * from the reader thread and there is only one concurrent reader. Otherwise
22162306a36Sopenharmony_ci * it is dangerous and must be handled in the same way as kfifo_reset().
22262306a36Sopenharmony_ci */
22362306a36Sopenharmony_ci#define kfifo_reset_out(fifo)	\
22462306a36Sopenharmony_ci(void)({ \
22562306a36Sopenharmony_ci	typeof((fifo) + 1) __tmp = (fifo); \
22662306a36Sopenharmony_ci	__tmp->kfifo.out = __tmp->kfifo.in; \
22762306a36Sopenharmony_ci})
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci/**
23062306a36Sopenharmony_ci * kfifo_len - returns the number of used elements in the fifo
23162306a36Sopenharmony_ci * @fifo: address of the fifo to be used
23262306a36Sopenharmony_ci */
23362306a36Sopenharmony_ci#define kfifo_len(fifo) \
23462306a36Sopenharmony_ci({ \
23562306a36Sopenharmony_ci	typeof((fifo) + 1) __tmpl = (fifo); \
23662306a36Sopenharmony_ci	__tmpl->kfifo.in - __tmpl->kfifo.out; \
23762306a36Sopenharmony_ci})
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ci/**
24062306a36Sopenharmony_ci * kfifo_is_empty - returns true if the fifo is empty
24162306a36Sopenharmony_ci * @fifo: address of the fifo to be used
24262306a36Sopenharmony_ci */
24362306a36Sopenharmony_ci#define	kfifo_is_empty(fifo) \
24462306a36Sopenharmony_ci({ \
24562306a36Sopenharmony_ci	typeof((fifo) + 1) __tmpq = (fifo); \
24662306a36Sopenharmony_ci	__tmpq->kfifo.in == __tmpq->kfifo.out; \
24762306a36Sopenharmony_ci})
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci/**
25062306a36Sopenharmony_ci * kfifo_is_empty_spinlocked - returns true if the fifo is empty using
25162306a36Sopenharmony_ci * a spinlock for locking
25262306a36Sopenharmony_ci * @fifo: address of the fifo to be used
25362306a36Sopenharmony_ci * @lock: spinlock to be used for locking
25462306a36Sopenharmony_ci */
25562306a36Sopenharmony_ci#define kfifo_is_empty_spinlocked(fifo, lock) \
25662306a36Sopenharmony_ci({ \
25762306a36Sopenharmony_ci	unsigned long __flags; \
25862306a36Sopenharmony_ci	bool __ret; \
25962306a36Sopenharmony_ci	spin_lock_irqsave(lock, __flags); \
26062306a36Sopenharmony_ci	__ret = kfifo_is_empty(fifo); \
26162306a36Sopenharmony_ci	spin_unlock_irqrestore(lock, __flags); \
26262306a36Sopenharmony_ci	__ret; \
26362306a36Sopenharmony_ci})
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci/**
26662306a36Sopenharmony_ci * kfifo_is_empty_spinlocked_noirqsave  - returns true if the fifo is empty
26762306a36Sopenharmony_ci * using a spinlock for locking, doesn't disable interrupts
26862306a36Sopenharmony_ci * @fifo: address of the fifo to be used
26962306a36Sopenharmony_ci * @lock: spinlock to be used for locking
27062306a36Sopenharmony_ci */
27162306a36Sopenharmony_ci#define kfifo_is_empty_spinlocked_noirqsave(fifo, lock) \
27262306a36Sopenharmony_ci({ \
27362306a36Sopenharmony_ci	bool __ret; \
27462306a36Sopenharmony_ci	spin_lock(lock); \
27562306a36Sopenharmony_ci	__ret = kfifo_is_empty(fifo); \
27662306a36Sopenharmony_ci	spin_unlock(lock); \
27762306a36Sopenharmony_ci	__ret; \
27862306a36Sopenharmony_ci})
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci/**
28162306a36Sopenharmony_ci * kfifo_is_full - returns true if the fifo is full
28262306a36Sopenharmony_ci * @fifo: address of the fifo to be used
28362306a36Sopenharmony_ci */
28462306a36Sopenharmony_ci#define	kfifo_is_full(fifo) \
28562306a36Sopenharmony_ci({ \
28662306a36Sopenharmony_ci	typeof((fifo) + 1) __tmpq = (fifo); \
28762306a36Sopenharmony_ci	kfifo_len(__tmpq) > __tmpq->kfifo.mask; \
28862306a36Sopenharmony_ci})
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_ci/**
29162306a36Sopenharmony_ci * kfifo_avail - returns the number of unused elements in the fifo
29262306a36Sopenharmony_ci * @fifo: address of the fifo to be used
29362306a36Sopenharmony_ci */
29462306a36Sopenharmony_ci#define	kfifo_avail(fifo) \
29562306a36Sopenharmony_ci__kfifo_uint_must_check_helper( \
29662306a36Sopenharmony_ci({ \
29762306a36Sopenharmony_ci	typeof((fifo) + 1) __tmpq = (fifo); \
29862306a36Sopenharmony_ci	const size_t __recsize = sizeof(*__tmpq->rectype); \
29962306a36Sopenharmony_ci	unsigned int __avail = kfifo_size(__tmpq) - kfifo_len(__tmpq); \
30062306a36Sopenharmony_ci	(__recsize) ? ((__avail <= __recsize) ? 0 : \
30162306a36Sopenharmony_ci	__kfifo_max_r(__avail - __recsize, __recsize)) : \
30262306a36Sopenharmony_ci	__avail; \
30362306a36Sopenharmony_ci}) \
30462306a36Sopenharmony_ci)
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_ci/**
30762306a36Sopenharmony_ci * kfifo_skip - skip output data
30862306a36Sopenharmony_ci * @fifo: address of the fifo to be used
30962306a36Sopenharmony_ci */
31062306a36Sopenharmony_ci#define	kfifo_skip(fifo) \
31162306a36Sopenharmony_ci(void)({ \
31262306a36Sopenharmony_ci	typeof((fifo) + 1) __tmp = (fifo); \
31362306a36Sopenharmony_ci	const size_t __recsize = sizeof(*__tmp->rectype); \
31462306a36Sopenharmony_ci	struct __kfifo *__kfifo = &__tmp->kfifo; \
31562306a36Sopenharmony_ci	if (__recsize) \
31662306a36Sopenharmony_ci		__kfifo_skip_r(__kfifo, __recsize); \
31762306a36Sopenharmony_ci	else \
31862306a36Sopenharmony_ci		__kfifo->out++; \
31962306a36Sopenharmony_ci})
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci/**
32262306a36Sopenharmony_ci * kfifo_peek_len - gets the size of the next fifo record
32362306a36Sopenharmony_ci * @fifo: address of the fifo to be used
32462306a36Sopenharmony_ci *
32562306a36Sopenharmony_ci * This function returns the size of the next fifo record in number of bytes.
32662306a36Sopenharmony_ci */
32762306a36Sopenharmony_ci#define kfifo_peek_len(fifo) \
32862306a36Sopenharmony_ci__kfifo_uint_must_check_helper( \
32962306a36Sopenharmony_ci({ \
33062306a36Sopenharmony_ci	typeof((fifo) + 1) __tmp = (fifo); \
33162306a36Sopenharmony_ci	const size_t __recsize = sizeof(*__tmp->rectype); \
33262306a36Sopenharmony_ci	struct __kfifo *__kfifo = &__tmp->kfifo; \
33362306a36Sopenharmony_ci	(!__recsize) ? kfifo_len(__tmp) * sizeof(*__tmp->type) : \
33462306a36Sopenharmony_ci	__kfifo_len_r(__kfifo, __recsize); \
33562306a36Sopenharmony_ci}) \
33662306a36Sopenharmony_ci)
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_ci/**
33962306a36Sopenharmony_ci * kfifo_alloc - dynamically allocates a new fifo buffer
34062306a36Sopenharmony_ci * @fifo: pointer to the fifo
34162306a36Sopenharmony_ci * @size: the number of elements in the fifo, this must be a power of 2
34262306a36Sopenharmony_ci * @gfp_mask: get_free_pages mask, passed to kmalloc()
34362306a36Sopenharmony_ci *
34462306a36Sopenharmony_ci * This macro dynamically allocates a new fifo buffer.
34562306a36Sopenharmony_ci *
34662306a36Sopenharmony_ci * The number of elements will be rounded-up to a power of 2.
34762306a36Sopenharmony_ci * The fifo will be release with kfifo_free().
34862306a36Sopenharmony_ci * Return 0 if no error, otherwise an error code.
34962306a36Sopenharmony_ci */
35062306a36Sopenharmony_ci#define kfifo_alloc(fifo, size, gfp_mask) \
35162306a36Sopenharmony_ci__kfifo_int_must_check_helper( \
35262306a36Sopenharmony_ci({ \
35362306a36Sopenharmony_ci	typeof((fifo) + 1) __tmp = (fifo); \
35462306a36Sopenharmony_ci	struct __kfifo *__kfifo = &__tmp->kfifo; \
35562306a36Sopenharmony_ci	__is_kfifo_ptr(__tmp) ? \
35662306a36Sopenharmony_ci	__kfifo_alloc(__kfifo, size, sizeof(*__tmp->type), gfp_mask) : \
35762306a36Sopenharmony_ci	-EINVAL; \
35862306a36Sopenharmony_ci}) \
35962306a36Sopenharmony_ci)
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci/**
36262306a36Sopenharmony_ci * kfifo_free - frees the fifo
36362306a36Sopenharmony_ci * @fifo: the fifo to be freed
36462306a36Sopenharmony_ci */
36562306a36Sopenharmony_ci#define kfifo_free(fifo) \
36662306a36Sopenharmony_ci({ \
36762306a36Sopenharmony_ci	typeof((fifo) + 1) __tmp = (fifo); \
36862306a36Sopenharmony_ci	struct __kfifo *__kfifo = &__tmp->kfifo; \
36962306a36Sopenharmony_ci	if (__is_kfifo_ptr(__tmp)) \
37062306a36Sopenharmony_ci		__kfifo_free(__kfifo); \
37162306a36Sopenharmony_ci})
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci/**
37462306a36Sopenharmony_ci * kfifo_init - initialize a fifo using a preallocated buffer
37562306a36Sopenharmony_ci * @fifo: the fifo to assign the buffer
37662306a36Sopenharmony_ci * @buffer: the preallocated buffer to be used
37762306a36Sopenharmony_ci * @size: the size of the internal buffer, this have to be a power of 2
37862306a36Sopenharmony_ci *
37962306a36Sopenharmony_ci * This macro initializes a fifo using a preallocated buffer.
38062306a36Sopenharmony_ci *
38162306a36Sopenharmony_ci * The number of elements will be rounded-up to a power of 2.
38262306a36Sopenharmony_ci * Return 0 if no error, otherwise an error code.
38362306a36Sopenharmony_ci */
38462306a36Sopenharmony_ci#define kfifo_init(fifo, buffer, size) \
38562306a36Sopenharmony_ci({ \
38662306a36Sopenharmony_ci	typeof((fifo) + 1) __tmp = (fifo); \
38762306a36Sopenharmony_ci	struct __kfifo *__kfifo = &__tmp->kfifo; \
38862306a36Sopenharmony_ci	__is_kfifo_ptr(__tmp) ? \
38962306a36Sopenharmony_ci	__kfifo_init(__kfifo, buffer, size, sizeof(*__tmp->type)) : \
39062306a36Sopenharmony_ci	-EINVAL; \
39162306a36Sopenharmony_ci})
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ci/**
39462306a36Sopenharmony_ci * kfifo_put - put data into the fifo
39562306a36Sopenharmony_ci * @fifo: address of the fifo to be used
39662306a36Sopenharmony_ci * @val: the data to be added
39762306a36Sopenharmony_ci *
39862306a36Sopenharmony_ci * This macro copies the given value into the fifo.
39962306a36Sopenharmony_ci * It returns 0 if the fifo was full. Otherwise it returns the number
40062306a36Sopenharmony_ci * processed elements.
40162306a36Sopenharmony_ci *
40262306a36Sopenharmony_ci * Note that with only one concurrent reader and one concurrent
40362306a36Sopenharmony_ci * writer, you don't need extra locking to use these macro.
40462306a36Sopenharmony_ci */
40562306a36Sopenharmony_ci#define	kfifo_put(fifo, val) \
40662306a36Sopenharmony_ci({ \
40762306a36Sopenharmony_ci	typeof((fifo) + 1) __tmp = (fifo); \
40862306a36Sopenharmony_ci	typeof(*__tmp->const_type) __val = (val); \
40962306a36Sopenharmony_ci	unsigned int __ret; \
41062306a36Sopenharmony_ci	size_t __recsize = sizeof(*__tmp->rectype); \
41162306a36Sopenharmony_ci	struct __kfifo *__kfifo = &__tmp->kfifo; \
41262306a36Sopenharmony_ci	if (__recsize) \
41362306a36Sopenharmony_ci		__ret = __kfifo_in_r(__kfifo, &__val, sizeof(__val), \
41462306a36Sopenharmony_ci			__recsize); \
41562306a36Sopenharmony_ci	else { \
41662306a36Sopenharmony_ci		__ret = !kfifo_is_full(__tmp); \
41762306a36Sopenharmony_ci		if (__ret) { \
41862306a36Sopenharmony_ci			(__is_kfifo_ptr(__tmp) ? \
41962306a36Sopenharmony_ci			((typeof(__tmp->type))__kfifo->data) : \
42062306a36Sopenharmony_ci			(__tmp->buf) \
42162306a36Sopenharmony_ci			)[__kfifo->in & __tmp->kfifo.mask] = \
42262306a36Sopenharmony_ci				*(typeof(__tmp->type))&__val; \
42362306a36Sopenharmony_ci			smp_wmb(); \
42462306a36Sopenharmony_ci			__kfifo->in++; \
42562306a36Sopenharmony_ci		} \
42662306a36Sopenharmony_ci	} \
42762306a36Sopenharmony_ci	__ret; \
42862306a36Sopenharmony_ci})
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_ci/**
43162306a36Sopenharmony_ci * kfifo_get - get data from the fifo
43262306a36Sopenharmony_ci * @fifo: address of the fifo to be used
43362306a36Sopenharmony_ci * @val: address where to store the data
43462306a36Sopenharmony_ci *
43562306a36Sopenharmony_ci * This macro reads the data from the fifo.
43662306a36Sopenharmony_ci * It returns 0 if the fifo was empty. Otherwise it returns the number
43762306a36Sopenharmony_ci * processed elements.
43862306a36Sopenharmony_ci *
43962306a36Sopenharmony_ci * Note that with only one concurrent reader and one concurrent
44062306a36Sopenharmony_ci * writer, you don't need extra locking to use these macro.
44162306a36Sopenharmony_ci */
44262306a36Sopenharmony_ci#define	kfifo_get(fifo, val) \
44362306a36Sopenharmony_ci__kfifo_uint_must_check_helper( \
44462306a36Sopenharmony_ci({ \
44562306a36Sopenharmony_ci	typeof((fifo) + 1) __tmp = (fifo); \
44662306a36Sopenharmony_ci	typeof(__tmp->ptr) __val = (val); \
44762306a36Sopenharmony_ci	unsigned int __ret; \
44862306a36Sopenharmony_ci	const size_t __recsize = sizeof(*__tmp->rectype); \
44962306a36Sopenharmony_ci	struct __kfifo *__kfifo = &__tmp->kfifo; \
45062306a36Sopenharmony_ci	if (__recsize) \
45162306a36Sopenharmony_ci		__ret = __kfifo_out_r(__kfifo, __val, sizeof(*__val), \
45262306a36Sopenharmony_ci			__recsize); \
45362306a36Sopenharmony_ci	else { \
45462306a36Sopenharmony_ci		__ret = !kfifo_is_empty(__tmp); \
45562306a36Sopenharmony_ci		if (__ret) { \
45662306a36Sopenharmony_ci			*(typeof(__tmp->type))__val = \
45762306a36Sopenharmony_ci				(__is_kfifo_ptr(__tmp) ? \
45862306a36Sopenharmony_ci				((typeof(__tmp->type))__kfifo->data) : \
45962306a36Sopenharmony_ci				(__tmp->buf) \
46062306a36Sopenharmony_ci				)[__kfifo->out & __tmp->kfifo.mask]; \
46162306a36Sopenharmony_ci			smp_wmb(); \
46262306a36Sopenharmony_ci			__kfifo->out++; \
46362306a36Sopenharmony_ci		} \
46462306a36Sopenharmony_ci	} \
46562306a36Sopenharmony_ci	__ret; \
46662306a36Sopenharmony_ci}) \
46762306a36Sopenharmony_ci)
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_ci/**
47062306a36Sopenharmony_ci * kfifo_peek - get data from the fifo without removing
47162306a36Sopenharmony_ci * @fifo: address of the fifo to be used
47262306a36Sopenharmony_ci * @val: address where to store the data
47362306a36Sopenharmony_ci *
47462306a36Sopenharmony_ci * This reads the data from the fifo without removing it from the fifo.
47562306a36Sopenharmony_ci * It returns 0 if the fifo was empty. Otherwise it returns the number
47662306a36Sopenharmony_ci * processed elements.
47762306a36Sopenharmony_ci *
47862306a36Sopenharmony_ci * Note that with only one concurrent reader and one concurrent
47962306a36Sopenharmony_ci * writer, you don't need extra locking to use these macro.
48062306a36Sopenharmony_ci */
48162306a36Sopenharmony_ci#define	kfifo_peek(fifo, val) \
48262306a36Sopenharmony_ci__kfifo_uint_must_check_helper( \
48362306a36Sopenharmony_ci({ \
48462306a36Sopenharmony_ci	typeof((fifo) + 1) __tmp = (fifo); \
48562306a36Sopenharmony_ci	typeof(__tmp->ptr) __val = (val); \
48662306a36Sopenharmony_ci	unsigned int __ret; \
48762306a36Sopenharmony_ci	const size_t __recsize = sizeof(*__tmp->rectype); \
48862306a36Sopenharmony_ci	struct __kfifo *__kfifo = &__tmp->kfifo; \
48962306a36Sopenharmony_ci	if (__recsize) \
49062306a36Sopenharmony_ci		__ret = __kfifo_out_peek_r(__kfifo, __val, sizeof(*__val), \
49162306a36Sopenharmony_ci			__recsize); \
49262306a36Sopenharmony_ci	else { \
49362306a36Sopenharmony_ci		__ret = !kfifo_is_empty(__tmp); \
49462306a36Sopenharmony_ci		if (__ret) { \
49562306a36Sopenharmony_ci			*(typeof(__tmp->type))__val = \
49662306a36Sopenharmony_ci				(__is_kfifo_ptr(__tmp) ? \
49762306a36Sopenharmony_ci				((typeof(__tmp->type))__kfifo->data) : \
49862306a36Sopenharmony_ci				(__tmp->buf) \
49962306a36Sopenharmony_ci				)[__kfifo->out & __tmp->kfifo.mask]; \
50062306a36Sopenharmony_ci			smp_wmb(); \
50162306a36Sopenharmony_ci		} \
50262306a36Sopenharmony_ci	} \
50362306a36Sopenharmony_ci	__ret; \
50462306a36Sopenharmony_ci}) \
50562306a36Sopenharmony_ci)
50662306a36Sopenharmony_ci
50762306a36Sopenharmony_ci/**
50862306a36Sopenharmony_ci * kfifo_in - put data into the fifo
50962306a36Sopenharmony_ci * @fifo: address of the fifo to be used
51062306a36Sopenharmony_ci * @buf: the data to be added
51162306a36Sopenharmony_ci * @n: number of elements to be added
51262306a36Sopenharmony_ci *
51362306a36Sopenharmony_ci * This macro copies the given buffer into the fifo and returns the
51462306a36Sopenharmony_ci * number of copied elements.
51562306a36Sopenharmony_ci *
51662306a36Sopenharmony_ci * Note that with only one concurrent reader and one concurrent
51762306a36Sopenharmony_ci * writer, you don't need extra locking to use these macro.
51862306a36Sopenharmony_ci */
51962306a36Sopenharmony_ci#define	kfifo_in(fifo, buf, n) \
52062306a36Sopenharmony_ci({ \
52162306a36Sopenharmony_ci	typeof((fifo) + 1) __tmp = (fifo); \
52262306a36Sopenharmony_ci	typeof(__tmp->ptr_const) __buf = (buf); \
52362306a36Sopenharmony_ci	unsigned long __n = (n); \
52462306a36Sopenharmony_ci	const size_t __recsize = sizeof(*__tmp->rectype); \
52562306a36Sopenharmony_ci	struct __kfifo *__kfifo = &__tmp->kfifo; \
52662306a36Sopenharmony_ci	(__recsize) ?\
52762306a36Sopenharmony_ci	__kfifo_in_r(__kfifo, __buf, __n, __recsize) : \
52862306a36Sopenharmony_ci	__kfifo_in(__kfifo, __buf, __n); \
52962306a36Sopenharmony_ci})
53062306a36Sopenharmony_ci
53162306a36Sopenharmony_ci/**
53262306a36Sopenharmony_ci * kfifo_in_spinlocked - put data into the fifo using a spinlock for locking
53362306a36Sopenharmony_ci * @fifo: address of the fifo to be used
53462306a36Sopenharmony_ci * @buf: the data to be added
53562306a36Sopenharmony_ci * @n: number of elements to be added
53662306a36Sopenharmony_ci * @lock: pointer to the spinlock to use for locking
53762306a36Sopenharmony_ci *
53862306a36Sopenharmony_ci * This macro copies the given values buffer into the fifo and returns the
53962306a36Sopenharmony_ci * number of copied elements.
54062306a36Sopenharmony_ci */
54162306a36Sopenharmony_ci#define	kfifo_in_spinlocked(fifo, buf, n, lock) \
54262306a36Sopenharmony_ci({ \
54362306a36Sopenharmony_ci	unsigned long __flags; \
54462306a36Sopenharmony_ci	unsigned int __ret; \
54562306a36Sopenharmony_ci	spin_lock_irqsave(lock, __flags); \
54662306a36Sopenharmony_ci	__ret = kfifo_in(fifo, buf, n); \
54762306a36Sopenharmony_ci	spin_unlock_irqrestore(lock, __flags); \
54862306a36Sopenharmony_ci	__ret; \
54962306a36Sopenharmony_ci})
55062306a36Sopenharmony_ci
55162306a36Sopenharmony_ci/**
55262306a36Sopenharmony_ci * kfifo_in_spinlocked_noirqsave - put data into fifo using a spinlock for
55362306a36Sopenharmony_ci * locking, don't disable interrupts
55462306a36Sopenharmony_ci * @fifo: address of the fifo to be used
55562306a36Sopenharmony_ci * @buf: the data to be added
55662306a36Sopenharmony_ci * @n: number of elements to be added
55762306a36Sopenharmony_ci * @lock: pointer to the spinlock to use for locking
55862306a36Sopenharmony_ci *
55962306a36Sopenharmony_ci * This is a variant of kfifo_in_spinlocked() but uses spin_lock/unlock()
56062306a36Sopenharmony_ci * for locking and doesn't disable interrupts.
56162306a36Sopenharmony_ci */
56262306a36Sopenharmony_ci#define kfifo_in_spinlocked_noirqsave(fifo, buf, n, lock) \
56362306a36Sopenharmony_ci({ \
56462306a36Sopenharmony_ci	unsigned int __ret; \
56562306a36Sopenharmony_ci	spin_lock(lock); \
56662306a36Sopenharmony_ci	__ret = kfifo_in(fifo, buf, n); \
56762306a36Sopenharmony_ci	spin_unlock(lock); \
56862306a36Sopenharmony_ci	__ret; \
56962306a36Sopenharmony_ci})
57062306a36Sopenharmony_ci
57162306a36Sopenharmony_ci/* alias for kfifo_in_spinlocked, will be removed in a future release */
57262306a36Sopenharmony_ci#define kfifo_in_locked(fifo, buf, n, lock) \
57362306a36Sopenharmony_ci		kfifo_in_spinlocked(fifo, buf, n, lock)
57462306a36Sopenharmony_ci
57562306a36Sopenharmony_ci/**
57662306a36Sopenharmony_ci * kfifo_out - get data from the fifo
57762306a36Sopenharmony_ci * @fifo: address of the fifo to be used
57862306a36Sopenharmony_ci * @buf: pointer to the storage buffer
57962306a36Sopenharmony_ci * @n: max. number of elements to get
58062306a36Sopenharmony_ci *
58162306a36Sopenharmony_ci * This macro get some data from the fifo and return the numbers of elements
58262306a36Sopenharmony_ci * copied.
58362306a36Sopenharmony_ci *
58462306a36Sopenharmony_ci * Note that with only one concurrent reader and one concurrent
58562306a36Sopenharmony_ci * writer, you don't need extra locking to use these macro.
58662306a36Sopenharmony_ci */
58762306a36Sopenharmony_ci#define	kfifo_out(fifo, buf, n) \
58862306a36Sopenharmony_ci__kfifo_uint_must_check_helper( \
58962306a36Sopenharmony_ci({ \
59062306a36Sopenharmony_ci	typeof((fifo) + 1) __tmp = (fifo); \
59162306a36Sopenharmony_ci	typeof(__tmp->ptr) __buf = (buf); \
59262306a36Sopenharmony_ci	unsigned long __n = (n); \
59362306a36Sopenharmony_ci	const size_t __recsize = sizeof(*__tmp->rectype); \
59462306a36Sopenharmony_ci	struct __kfifo *__kfifo = &__tmp->kfifo; \
59562306a36Sopenharmony_ci	(__recsize) ?\
59662306a36Sopenharmony_ci	__kfifo_out_r(__kfifo, __buf, __n, __recsize) : \
59762306a36Sopenharmony_ci	__kfifo_out(__kfifo, __buf, __n); \
59862306a36Sopenharmony_ci}) \
59962306a36Sopenharmony_ci)
60062306a36Sopenharmony_ci
60162306a36Sopenharmony_ci/**
60262306a36Sopenharmony_ci * kfifo_out_spinlocked - get data from the fifo using a spinlock for locking
60362306a36Sopenharmony_ci * @fifo: address of the fifo to be used
60462306a36Sopenharmony_ci * @buf: pointer to the storage buffer
60562306a36Sopenharmony_ci * @n: max. number of elements to get
60662306a36Sopenharmony_ci * @lock: pointer to the spinlock to use for locking
60762306a36Sopenharmony_ci *
60862306a36Sopenharmony_ci * This macro get the data from the fifo and return the numbers of elements
60962306a36Sopenharmony_ci * copied.
61062306a36Sopenharmony_ci */
61162306a36Sopenharmony_ci#define	kfifo_out_spinlocked(fifo, buf, n, lock) \
61262306a36Sopenharmony_ci__kfifo_uint_must_check_helper( \
61362306a36Sopenharmony_ci({ \
61462306a36Sopenharmony_ci	unsigned long __flags; \
61562306a36Sopenharmony_ci	unsigned int __ret; \
61662306a36Sopenharmony_ci	spin_lock_irqsave(lock, __flags); \
61762306a36Sopenharmony_ci	__ret = kfifo_out(fifo, buf, n); \
61862306a36Sopenharmony_ci	spin_unlock_irqrestore(lock, __flags); \
61962306a36Sopenharmony_ci	__ret; \
62062306a36Sopenharmony_ci}) \
62162306a36Sopenharmony_ci)
62262306a36Sopenharmony_ci
62362306a36Sopenharmony_ci/**
62462306a36Sopenharmony_ci * kfifo_out_spinlocked_noirqsave - get data from the fifo using a spinlock
62562306a36Sopenharmony_ci * for locking, don't disable interrupts
62662306a36Sopenharmony_ci * @fifo: address of the fifo to be used
62762306a36Sopenharmony_ci * @buf: pointer to the storage buffer
62862306a36Sopenharmony_ci * @n: max. number of elements to get
62962306a36Sopenharmony_ci * @lock: pointer to the spinlock to use for locking
63062306a36Sopenharmony_ci *
63162306a36Sopenharmony_ci * This is a variant of kfifo_out_spinlocked() which uses spin_lock/unlock()
63262306a36Sopenharmony_ci * for locking and doesn't disable interrupts.
63362306a36Sopenharmony_ci */
63462306a36Sopenharmony_ci#define kfifo_out_spinlocked_noirqsave(fifo, buf, n, lock) \
63562306a36Sopenharmony_ci__kfifo_uint_must_check_helper( \
63662306a36Sopenharmony_ci({ \
63762306a36Sopenharmony_ci	unsigned int __ret; \
63862306a36Sopenharmony_ci	spin_lock(lock); \
63962306a36Sopenharmony_ci	__ret = kfifo_out(fifo, buf, n); \
64062306a36Sopenharmony_ci	spin_unlock(lock); \
64162306a36Sopenharmony_ci	__ret; \
64262306a36Sopenharmony_ci}) \
64362306a36Sopenharmony_ci)
64462306a36Sopenharmony_ci
64562306a36Sopenharmony_ci/* alias for kfifo_out_spinlocked, will be removed in a future release */
64662306a36Sopenharmony_ci#define kfifo_out_locked(fifo, buf, n, lock) \
64762306a36Sopenharmony_ci		kfifo_out_spinlocked(fifo, buf, n, lock)
64862306a36Sopenharmony_ci
64962306a36Sopenharmony_ci/**
65062306a36Sopenharmony_ci * kfifo_from_user - puts some data from user space into the fifo
65162306a36Sopenharmony_ci * @fifo: address of the fifo to be used
65262306a36Sopenharmony_ci * @from: pointer to the data to be added
65362306a36Sopenharmony_ci * @len: the length of the data to be added
65462306a36Sopenharmony_ci * @copied: pointer to output variable to store the number of copied bytes
65562306a36Sopenharmony_ci *
65662306a36Sopenharmony_ci * This macro copies at most @len bytes from the @from into the
65762306a36Sopenharmony_ci * fifo, depending of the available space and returns -EFAULT/0.
65862306a36Sopenharmony_ci *
65962306a36Sopenharmony_ci * Note that with only one concurrent reader and one concurrent
66062306a36Sopenharmony_ci * writer, you don't need extra locking to use these macro.
66162306a36Sopenharmony_ci */
66262306a36Sopenharmony_ci#define	kfifo_from_user(fifo, from, len, copied) \
66362306a36Sopenharmony_ci__kfifo_uint_must_check_helper( \
66462306a36Sopenharmony_ci({ \
66562306a36Sopenharmony_ci	typeof((fifo) + 1) __tmp = (fifo); \
66662306a36Sopenharmony_ci	const void __user *__from = (from); \
66762306a36Sopenharmony_ci	unsigned int __len = (len); \
66862306a36Sopenharmony_ci	unsigned int *__copied = (copied); \
66962306a36Sopenharmony_ci	const size_t __recsize = sizeof(*__tmp->rectype); \
67062306a36Sopenharmony_ci	struct __kfifo *__kfifo = &__tmp->kfifo; \
67162306a36Sopenharmony_ci	(__recsize) ? \
67262306a36Sopenharmony_ci	__kfifo_from_user_r(__kfifo, __from, __len,  __copied, __recsize) : \
67362306a36Sopenharmony_ci	__kfifo_from_user(__kfifo, __from, __len, __copied); \
67462306a36Sopenharmony_ci}) \
67562306a36Sopenharmony_ci)
67662306a36Sopenharmony_ci
67762306a36Sopenharmony_ci/**
67862306a36Sopenharmony_ci * kfifo_to_user - copies data from the fifo into user space
67962306a36Sopenharmony_ci * @fifo: address of the fifo to be used
68062306a36Sopenharmony_ci * @to: where the data must be copied
68162306a36Sopenharmony_ci * @len: the size of the destination buffer
68262306a36Sopenharmony_ci * @copied: pointer to output variable to store the number of copied bytes
68362306a36Sopenharmony_ci *
68462306a36Sopenharmony_ci * This macro copies at most @len bytes from the fifo into the
68562306a36Sopenharmony_ci * @to buffer and returns -EFAULT/0.
68662306a36Sopenharmony_ci *
68762306a36Sopenharmony_ci * Note that with only one concurrent reader and one concurrent
68862306a36Sopenharmony_ci * writer, you don't need extra locking to use these macro.
68962306a36Sopenharmony_ci */
69062306a36Sopenharmony_ci#define	kfifo_to_user(fifo, to, len, copied) \
69162306a36Sopenharmony_ci__kfifo_int_must_check_helper( \
69262306a36Sopenharmony_ci({ \
69362306a36Sopenharmony_ci	typeof((fifo) + 1) __tmp = (fifo); \
69462306a36Sopenharmony_ci	void __user *__to = (to); \
69562306a36Sopenharmony_ci	unsigned int __len = (len); \
69662306a36Sopenharmony_ci	unsigned int *__copied = (copied); \
69762306a36Sopenharmony_ci	const size_t __recsize = sizeof(*__tmp->rectype); \
69862306a36Sopenharmony_ci	struct __kfifo *__kfifo = &__tmp->kfifo; \
69962306a36Sopenharmony_ci	(__recsize) ? \
70062306a36Sopenharmony_ci	__kfifo_to_user_r(__kfifo, __to, __len, __copied, __recsize) : \
70162306a36Sopenharmony_ci	__kfifo_to_user(__kfifo, __to, __len, __copied); \
70262306a36Sopenharmony_ci}) \
70362306a36Sopenharmony_ci)
70462306a36Sopenharmony_ci
70562306a36Sopenharmony_ci/**
70662306a36Sopenharmony_ci * kfifo_dma_in_prepare - setup a scatterlist for DMA input
70762306a36Sopenharmony_ci * @fifo: address of the fifo to be used
70862306a36Sopenharmony_ci * @sgl: pointer to the scatterlist array
70962306a36Sopenharmony_ci * @nents: number of entries in the scatterlist array
71062306a36Sopenharmony_ci * @len: number of elements to transfer
71162306a36Sopenharmony_ci *
71262306a36Sopenharmony_ci * This macro fills a scatterlist for DMA input.
71362306a36Sopenharmony_ci * It returns the number entries in the scatterlist array.
71462306a36Sopenharmony_ci *
71562306a36Sopenharmony_ci * Note that with only one concurrent reader and one concurrent
71662306a36Sopenharmony_ci * writer, you don't need extra locking to use these macros.
71762306a36Sopenharmony_ci */
71862306a36Sopenharmony_ci#define	kfifo_dma_in_prepare(fifo, sgl, nents, len) \
71962306a36Sopenharmony_ci({ \
72062306a36Sopenharmony_ci	typeof((fifo) + 1) __tmp = (fifo); \
72162306a36Sopenharmony_ci	struct scatterlist *__sgl = (sgl); \
72262306a36Sopenharmony_ci	int __nents = (nents); \
72362306a36Sopenharmony_ci	unsigned int __len = (len); \
72462306a36Sopenharmony_ci	const size_t __recsize = sizeof(*__tmp->rectype); \
72562306a36Sopenharmony_ci	struct __kfifo *__kfifo = &__tmp->kfifo; \
72662306a36Sopenharmony_ci	(__recsize) ? \
72762306a36Sopenharmony_ci	__kfifo_dma_in_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \
72862306a36Sopenharmony_ci	__kfifo_dma_in_prepare(__kfifo, __sgl, __nents, __len); \
72962306a36Sopenharmony_ci})
73062306a36Sopenharmony_ci
73162306a36Sopenharmony_ci/**
73262306a36Sopenharmony_ci * kfifo_dma_in_finish - finish a DMA IN operation
73362306a36Sopenharmony_ci * @fifo: address of the fifo to be used
73462306a36Sopenharmony_ci * @len: number of bytes to received
73562306a36Sopenharmony_ci *
73662306a36Sopenharmony_ci * This macro finish a DMA IN operation. The in counter will be updated by
73762306a36Sopenharmony_ci * the len parameter. No error checking will be done.
73862306a36Sopenharmony_ci *
73962306a36Sopenharmony_ci * Note that with only one concurrent reader and one concurrent
74062306a36Sopenharmony_ci * writer, you don't need extra locking to use these macros.
74162306a36Sopenharmony_ci */
74262306a36Sopenharmony_ci#define kfifo_dma_in_finish(fifo, len) \
74362306a36Sopenharmony_ci(void)({ \
74462306a36Sopenharmony_ci	typeof((fifo) + 1) __tmp = (fifo); \
74562306a36Sopenharmony_ci	unsigned int __len = (len); \
74662306a36Sopenharmony_ci	const size_t __recsize = sizeof(*__tmp->rectype); \
74762306a36Sopenharmony_ci	struct __kfifo *__kfifo = &__tmp->kfifo; \
74862306a36Sopenharmony_ci	if (__recsize) \
74962306a36Sopenharmony_ci		__kfifo_dma_in_finish_r(__kfifo, __len, __recsize); \
75062306a36Sopenharmony_ci	else \
75162306a36Sopenharmony_ci		__kfifo->in += __len / sizeof(*__tmp->type); \
75262306a36Sopenharmony_ci})
75362306a36Sopenharmony_ci
75462306a36Sopenharmony_ci/**
75562306a36Sopenharmony_ci * kfifo_dma_out_prepare - setup a scatterlist for DMA output
75662306a36Sopenharmony_ci * @fifo: address of the fifo to be used
75762306a36Sopenharmony_ci * @sgl: pointer to the scatterlist array
75862306a36Sopenharmony_ci * @nents: number of entries in the scatterlist array
75962306a36Sopenharmony_ci * @len: number of elements to transfer
76062306a36Sopenharmony_ci *
76162306a36Sopenharmony_ci * This macro fills a scatterlist for DMA output which at most @len bytes
76262306a36Sopenharmony_ci * to transfer.
76362306a36Sopenharmony_ci * It returns the number entries in the scatterlist array.
76462306a36Sopenharmony_ci * A zero means there is no space available and the scatterlist is not filled.
76562306a36Sopenharmony_ci *
76662306a36Sopenharmony_ci * Note that with only one concurrent reader and one concurrent
76762306a36Sopenharmony_ci * writer, you don't need extra locking to use these macros.
76862306a36Sopenharmony_ci */
76962306a36Sopenharmony_ci#define	kfifo_dma_out_prepare(fifo, sgl, nents, len) \
77062306a36Sopenharmony_ci({ \
77162306a36Sopenharmony_ci	typeof((fifo) + 1) __tmp = (fifo);  \
77262306a36Sopenharmony_ci	struct scatterlist *__sgl = (sgl); \
77362306a36Sopenharmony_ci	int __nents = (nents); \
77462306a36Sopenharmony_ci	unsigned int __len = (len); \
77562306a36Sopenharmony_ci	const size_t __recsize = sizeof(*__tmp->rectype); \
77662306a36Sopenharmony_ci	struct __kfifo *__kfifo = &__tmp->kfifo; \
77762306a36Sopenharmony_ci	(__recsize) ? \
77862306a36Sopenharmony_ci	__kfifo_dma_out_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \
77962306a36Sopenharmony_ci	__kfifo_dma_out_prepare(__kfifo, __sgl, __nents, __len); \
78062306a36Sopenharmony_ci})
78162306a36Sopenharmony_ci
78262306a36Sopenharmony_ci/**
78362306a36Sopenharmony_ci * kfifo_dma_out_finish - finish a DMA OUT operation
78462306a36Sopenharmony_ci * @fifo: address of the fifo to be used
78562306a36Sopenharmony_ci * @len: number of bytes transferred
78662306a36Sopenharmony_ci *
78762306a36Sopenharmony_ci * This macro finish a DMA OUT operation. The out counter will be updated by
78862306a36Sopenharmony_ci * the len parameter. No error checking will be done.
78962306a36Sopenharmony_ci *
79062306a36Sopenharmony_ci * Note that with only one concurrent reader and one concurrent
79162306a36Sopenharmony_ci * writer, you don't need extra locking to use these macros.
79262306a36Sopenharmony_ci */
79362306a36Sopenharmony_ci#define kfifo_dma_out_finish(fifo, len) \
79462306a36Sopenharmony_ci(void)({ \
79562306a36Sopenharmony_ci	typeof((fifo) + 1) __tmp = (fifo); \
79662306a36Sopenharmony_ci	unsigned int __len = (len); \
79762306a36Sopenharmony_ci	const size_t __recsize = sizeof(*__tmp->rectype); \
79862306a36Sopenharmony_ci	struct __kfifo *__kfifo = &__tmp->kfifo; \
79962306a36Sopenharmony_ci	if (__recsize) \
80062306a36Sopenharmony_ci		__kfifo_dma_out_finish_r(__kfifo, __recsize); \
80162306a36Sopenharmony_ci	else \
80262306a36Sopenharmony_ci		__kfifo->out += __len / sizeof(*__tmp->type); \
80362306a36Sopenharmony_ci})
80462306a36Sopenharmony_ci
80562306a36Sopenharmony_ci/**
80662306a36Sopenharmony_ci * kfifo_out_peek - gets some data from the fifo
80762306a36Sopenharmony_ci * @fifo: address of the fifo to be used
80862306a36Sopenharmony_ci * @buf: pointer to the storage buffer
80962306a36Sopenharmony_ci * @n: max. number of elements to get
81062306a36Sopenharmony_ci *
81162306a36Sopenharmony_ci * This macro get the data from the fifo and return the numbers of elements
81262306a36Sopenharmony_ci * copied. The data is not removed from the fifo.
81362306a36Sopenharmony_ci *
81462306a36Sopenharmony_ci * Note that with only one concurrent reader and one concurrent
81562306a36Sopenharmony_ci * writer, you don't need extra locking to use these macro.
81662306a36Sopenharmony_ci */
81762306a36Sopenharmony_ci#define	kfifo_out_peek(fifo, buf, n) \
81862306a36Sopenharmony_ci__kfifo_uint_must_check_helper( \
81962306a36Sopenharmony_ci({ \
82062306a36Sopenharmony_ci	typeof((fifo) + 1) __tmp = (fifo); \
82162306a36Sopenharmony_ci	typeof(__tmp->ptr) __buf = (buf); \
82262306a36Sopenharmony_ci	unsigned long __n = (n); \
82362306a36Sopenharmony_ci	const size_t __recsize = sizeof(*__tmp->rectype); \
82462306a36Sopenharmony_ci	struct __kfifo *__kfifo = &__tmp->kfifo; \
82562306a36Sopenharmony_ci	(__recsize) ? \
82662306a36Sopenharmony_ci	__kfifo_out_peek_r(__kfifo, __buf, __n, __recsize) : \
82762306a36Sopenharmony_ci	__kfifo_out_peek(__kfifo, __buf, __n); \
82862306a36Sopenharmony_ci}) \
82962306a36Sopenharmony_ci)
83062306a36Sopenharmony_ci
83162306a36Sopenharmony_ciextern int __kfifo_alloc(struct __kfifo *fifo, unsigned int size,
83262306a36Sopenharmony_ci	size_t esize, gfp_t gfp_mask);
83362306a36Sopenharmony_ci
83462306a36Sopenharmony_ciextern void __kfifo_free(struct __kfifo *fifo);
83562306a36Sopenharmony_ci
83662306a36Sopenharmony_ciextern int __kfifo_init(struct __kfifo *fifo, void *buffer,
83762306a36Sopenharmony_ci	unsigned int size, size_t esize);
83862306a36Sopenharmony_ci
83962306a36Sopenharmony_ciextern unsigned int __kfifo_in(struct __kfifo *fifo,
84062306a36Sopenharmony_ci	const void *buf, unsigned int len);
84162306a36Sopenharmony_ci
84262306a36Sopenharmony_ciextern unsigned int __kfifo_out(struct __kfifo *fifo,
84362306a36Sopenharmony_ci	void *buf, unsigned int len);
84462306a36Sopenharmony_ci
84562306a36Sopenharmony_ciextern int __kfifo_from_user(struct __kfifo *fifo,
84662306a36Sopenharmony_ci	const void __user *from, unsigned long len, unsigned int *copied);
84762306a36Sopenharmony_ci
84862306a36Sopenharmony_ciextern int __kfifo_to_user(struct __kfifo *fifo,
84962306a36Sopenharmony_ci	void __user *to, unsigned long len, unsigned int *copied);
85062306a36Sopenharmony_ci
85162306a36Sopenharmony_ciextern unsigned int __kfifo_dma_in_prepare(struct __kfifo *fifo,
85262306a36Sopenharmony_ci	struct scatterlist *sgl, int nents, unsigned int len);
85362306a36Sopenharmony_ci
85462306a36Sopenharmony_ciextern unsigned int __kfifo_dma_out_prepare(struct __kfifo *fifo,
85562306a36Sopenharmony_ci	struct scatterlist *sgl, int nents, unsigned int len);
85662306a36Sopenharmony_ci
85762306a36Sopenharmony_ciextern unsigned int __kfifo_out_peek(struct __kfifo *fifo,
85862306a36Sopenharmony_ci	void *buf, unsigned int len);
85962306a36Sopenharmony_ci
86062306a36Sopenharmony_ciextern unsigned int __kfifo_in_r(struct __kfifo *fifo,
86162306a36Sopenharmony_ci	const void *buf, unsigned int len, size_t recsize);
86262306a36Sopenharmony_ci
86362306a36Sopenharmony_ciextern unsigned int __kfifo_out_r(struct __kfifo *fifo,
86462306a36Sopenharmony_ci	void *buf, unsigned int len, size_t recsize);
86562306a36Sopenharmony_ci
86662306a36Sopenharmony_ciextern int __kfifo_from_user_r(struct __kfifo *fifo,
86762306a36Sopenharmony_ci	const void __user *from, unsigned long len, unsigned int *copied,
86862306a36Sopenharmony_ci	size_t recsize);
86962306a36Sopenharmony_ci
87062306a36Sopenharmony_ciextern int __kfifo_to_user_r(struct __kfifo *fifo, void __user *to,
87162306a36Sopenharmony_ci	unsigned long len, unsigned int *copied, size_t recsize);
87262306a36Sopenharmony_ci
87362306a36Sopenharmony_ciextern unsigned int __kfifo_dma_in_prepare_r(struct __kfifo *fifo,
87462306a36Sopenharmony_ci	struct scatterlist *sgl, int nents, unsigned int len, size_t recsize);
87562306a36Sopenharmony_ci
87662306a36Sopenharmony_ciextern void __kfifo_dma_in_finish_r(struct __kfifo *fifo,
87762306a36Sopenharmony_ci	unsigned int len, size_t recsize);
87862306a36Sopenharmony_ci
87962306a36Sopenharmony_ciextern unsigned int __kfifo_dma_out_prepare_r(struct __kfifo *fifo,
88062306a36Sopenharmony_ci	struct scatterlist *sgl, int nents, unsigned int len, size_t recsize);
88162306a36Sopenharmony_ci
88262306a36Sopenharmony_ciextern void __kfifo_dma_out_finish_r(struct __kfifo *fifo, size_t recsize);
88362306a36Sopenharmony_ci
88462306a36Sopenharmony_ciextern unsigned int __kfifo_len_r(struct __kfifo *fifo, size_t recsize);
88562306a36Sopenharmony_ci
88662306a36Sopenharmony_ciextern void __kfifo_skip_r(struct __kfifo *fifo, size_t recsize);
88762306a36Sopenharmony_ci
88862306a36Sopenharmony_ciextern unsigned int __kfifo_out_peek_r(struct __kfifo *fifo,
88962306a36Sopenharmony_ci	void *buf, unsigned int len, size_t recsize);
89062306a36Sopenharmony_ci
89162306a36Sopenharmony_ciextern unsigned int __kfifo_max_r(unsigned int len, size_t recsize);
89262306a36Sopenharmony_ci
89362306a36Sopenharmony_ci#endif
894