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