From c63760d026b263145f348d0b6090ab5164ad251b Mon Sep 17 00:00:00 2001 From: zzy <2450266535@qq.com> Date: Mon, 30 Oct 2023 22:08:24 +0800 Subject: [PATCH] dev bkfifo init --- include/bkfifo.h | 1483 ---------------------------------------------- 1 file changed, 1483 deletions(-) diff --git a/include/bkfifo.h b/include/bkfifo.h index c53749a..25d4ee3 100644 --- a/include/bkfifo.h +++ b/include/bkfifo.h @@ -20,1490 +20,7 @@ struct __bkfifo { type buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \ } -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * A generic kernel FIFO implementation - * - * Copyright (C) 2013 Stefani Seibold - */ -#ifndef _LINUX_KFIFO_H -#define _LINUX_KFIFO_H - - /* - * How to porting drivers to the new generic FIFO API: - * - * - Modify the declaration of the "struct kfifo *" object into a - * in-place "struct kfifo" object - * - Init the in-place object with kfifo_alloc() or kfifo_init() - * Note: The address of the in-place "struct kfifo" object must be - * passed as the first argument to this functions - * - Replace the use of __kfifo_put into kfifo_in and __kfifo_get - * into kfifo_out - * - Replace the use of kfifo_put into kfifo_in_spinlocked and kfifo_get - * into kfifo_out_spinlocked - * Note: the spinlock pointer formerly passed to kfifo_init/kfifo_alloc - * must be passed now to the kfifo_in_spinlocked and kfifo_out_spinlocked - * as the last parameter - * - The formerly __kfifo_* functions are renamed into kfifo_* - */ - - /* - * Note about locking: There is no locking required until only one reader - * and one writer is using the fifo and no kfifo_reset() will be called. - * kfifo_reset_out() can be safely used, until it will be only called - * in the reader thread. - * For multiple writer and one reader there is only a need to lock the writer. - * And vice versa for only one writer and multiple reader there is only a need - * to lock the reader. - */ - -struct __kfifo { - unsigned int in; - unsigned int out; - unsigned int mask; - unsigned int esize; - void* data; -}; - -#define __STRUCT_KFIFO_COMMON(datatype, recsize, ptrtype) \ - union { \ - struct __kfifo kfifo; \ - datatype *type; \ - const datatype *const_type; \ - char (*rectype)[recsize]; \ - ptrtype *ptr; \ - ptrtype const *ptr_const; \ - } - -#define __STRUCT_KFIFO(type, size, recsize, ptrtype) \ -{ \ - __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ - type buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \ -} - -#define STRUCT_KFIFO(type, size) \ - struct __STRUCT_KFIFO(type, size, 0, type) - -#define __STRUCT_KFIFO_PTR(type, recsize, ptrtype) \ -{ \ - __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ - type buf[0]; \ -} - -#define STRUCT_KFIFO_PTR(type) \ - struct __STRUCT_KFIFO_PTR(type, 0, type) - -/* - * define compatibility "struct kfifo" for dynamic allocated fifos - */ -struct kfifo __STRUCT_KFIFO_PTR(unsigned char, 0, void); - -#define STRUCT_KFIFO_REC_1(size) \ - struct __STRUCT_KFIFO(unsigned char, size, 1, void) - -#define STRUCT_KFIFO_REC_2(size) \ - struct __STRUCT_KFIFO(unsigned char, size, 2, void) - -/* - * define kfifo_rec types - */ -struct kfifo_rec_ptr_1 __STRUCT_KFIFO_PTR(unsigned char, 1, void); -struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2, void); - -/* - * helper macro to distinguish between real in place fifo where the fifo - * array is a part of the structure and the fifo type where the array is - * outside of the fifo structure. - */ -#define __is_kfifo_ptr(fifo) \ - (sizeof(*fifo) == sizeof(STRUCT_KFIFO_PTR(typeof(*(fifo)->type)))) - - /** - * DECLARE_KFIFO_PTR - macro to declare a fifo pointer object - * @fifo: name of the declared fifo - * @type: type of the fifo elements - */ -#define DECLARE_KFIFO_PTR(fifo, type) STRUCT_KFIFO_PTR(type) fifo - - /** - * DECLARE_KFIFO - macro to declare a fifo object - * @fifo: name of the declared fifo - * @type: type of the fifo elements - * @size: the number of elements in the fifo, this must be a power of 2 - */ -#define DECLARE_KFIFO(fifo, type, size) STRUCT_KFIFO(type, size) fifo - - /** - * INIT_KFIFO - Initialize a fifo declared by DECLARE_KFIFO - * @fifo: name of the declared fifo datatype - */ -#define INIT_KFIFO(fifo) \ -(void)({ \ - typeof(&(fifo)) __tmp = &(fifo); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - __kfifo->in = 0; \ - __kfifo->out = 0; \ - __kfifo->mask = __is_kfifo_ptr(__tmp) ? 0 : ARRAY_SIZE(__tmp->buf) - 1;\ - __kfifo->esize = sizeof(*__tmp->buf); \ - __kfifo->data = __is_kfifo_ptr(__tmp) ? NULL : __tmp->buf; \ -}) - - /** - * DEFINE_KFIFO - macro to define and initialize a fifo - * @fifo: name of the declared fifo datatype - * @type: type of the fifo elements - * @size: the number of elements in the fifo, this must be a power of 2 - * - * Note: the macro can be used for global and local fifo data type variables. - */ -#define DEFINE_KFIFO(fifo, type, size) \ - DECLARE_KFIFO(fifo, type, size) = \ - (typeof(fifo)) { \ - { \ - { \ - .in = 0, \ - .out = 0, \ - .mask = __is_kfifo_ptr(&(fifo)) ? \ - 0 : \ - ARRAY_SIZE((fifo).buf) - 1, \ - .esize = sizeof(*(fifo).buf), \ - .data = __is_kfifo_ptr(&(fifo)) ? \ - NULL : \ - (fifo).buf, \ - } \ - } \ - } - - -//static inline unsigned int __must_check -//__kfifo_uint_must_check_helper(unsigned int val) -//{ -// return val; -//} -// -//static inline int __must_check -//__kfifo_int_must_check_helper(int val) -//{ -// return val; -//} - -/** - * kfifo_initialized - Check if the fifo is initialized - * @fifo: address of the fifo to check - * - * Return %true if fifo is initialized, otherwise %false. - * Assumes the fifo was 0 before. - */ -#define kfifo_initialized(fifo) ((fifo)->kfifo.mask) - - /** - * kfifo_esize - returns the size of the element managed by the fifo - * @fifo: address of the fifo to be used - */ -#define kfifo_esize(fifo) ((fifo)->kfifo.esize) - - /** - * kfifo_recsize - returns the size of the record length field - * @fifo: address of the fifo to be used - */ -#define kfifo_recsize(fifo) (sizeof(*(fifo)->rectype)) - - /** - * kfifo_size - returns the size of the fifo in elements - * @fifo: address of the fifo to be used - */ -#define kfifo_size(fifo) ((fifo)->kfifo.mask + 1) - - /** - * kfifo_reset - removes the entire fifo content - * @fifo: address of the fifo to be used - * - * Note: usage of kfifo_reset() is dangerous. It should be only called when the - * fifo is exclusived locked or when it is secured that no other thread is - * accessing the fifo. - */ -#define kfifo_reset(fifo) \ -(void)({ \ - typeof((fifo) + 1) __tmp = (fifo); \ - __tmp->kfifo.in = __tmp->kfifo.out = 0; \ -}) - - /** - * kfifo_reset_out - skip fifo content - * @fifo: address of the fifo to be used - * - * Note: The usage of kfifo_reset_out() is safe until it will be only called - * from the reader thread and there is only one concurrent reader. Otherwise - * it is dangerous and must be handled in the same way as kfifo_reset(). - */ -#define kfifo_reset_out(fifo) \ -(void)({ \ - typeof((fifo) + 1) __tmp = (fifo); \ - __tmp->kfifo.out = __tmp->kfifo.in; \ -}) - - /** - * kfifo_len - returns the number of used elements in the fifo - * @fifo: address of the fifo to be used - */ -#define kfifo_len(fifo) \ -({ \ - typeof((fifo) + 1) __tmpl = (fifo); \ - __tmpl->kfifo.in - __tmpl->kfifo.out; \ -}) - - /** - * kfifo_is_empty - returns true if the fifo is empty - * @fifo: address of the fifo to be used - */ -#define kfifo_is_empty(fifo) \ -({ \ - typeof((fifo) + 1) __tmpq = (fifo); \ - __tmpq->kfifo.in == __tmpq->kfifo.out; \ -}) - - /** - * kfifo_is_empty_spinlocked - returns true if the fifo is empty using - * a spinlock for locking - * @fifo: address of the fifo to be used - * @lock: spinlock to be used for locking - */ -#define kfifo_is_empty_spinlocked(fifo, lock) \ -({ \ - unsigned long __flags; \ - bool __ret; \ - spin_lock_irqsave(lock, __flags); \ - __ret = kfifo_is_empty(fifo); \ - spin_unlock_irqrestore(lock, __flags); \ - __ret; \ -}) - - /** - * kfifo_is_empty_spinlocked_noirqsave - returns true if the fifo is empty - * using a spinlock for locking, doesn't disable interrupts - * @fifo: address of the fifo to be used - * @lock: spinlock to be used for locking - */ -#define kfifo_is_empty_spinlocked_noirqsave(fifo, lock) \ -({ \ - bool __ret; \ - spin_lock(lock); \ - __ret = kfifo_is_empty(fifo); \ - spin_unlock(lock); \ - __ret; \ -}) - - /** - * kfifo_is_full - returns true if the fifo is full - * @fifo: address of the fifo to be used - */ -#define kfifo_is_full(fifo) \ -({ \ - typeof((fifo) + 1) __tmpq = (fifo); \ - kfifo_len(__tmpq) > __tmpq->kfifo.mask; \ -}) - - /** - * kfifo_avail - returns the number of unused elements in the fifo - * @fifo: address of the fifo to be used - */ -#define kfifo_avail(fifo) \ -__kfifo_uint_must_check_helper( \ -({ \ - typeof((fifo) + 1) __tmpq = (fifo); \ - const size_t __recsize = sizeof(*__tmpq->rectype); \ - unsigned int __avail = kfifo_size(__tmpq) - kfifo_len(__tmpq); \ - (__recsize) ? ((__avail <= __recsize) ? 0 : \ - __kfifo_max_r(__avail - __recsize, __recsize)) : \ - __avail; \ -}) \ -) - - /** - * kfifo_skip - skip output data - * @fifo: address of the fifo to be used - */ -#define kfifo_skip(fifo) \ -(void)({ \ - typeof((fifo) + 1) __tmp = (fifo); \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (__recsize) \ - __kfifo_skip_r(__kfifo, __recsize); \ - else \ - __kfifo->out++; \ -}) - - /** - * kfifo_peek_len - gets the size of the next fifo record - * @fifo: address of the fifo to be used - * - * This function returns the size of the next fifo record in number of bytes. - */ -#define kfifo_peek_len(fifo) \ -__kfifo_uint_must_check_helper( \ -({ \ - typeof((fifo) + 1) __tmp = (fifo); \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - (!__recsize) ? kfifo_len(__tmp) * sizeof(*__tmp->type) : \ - __kfifo_len_r(__kfifo, __recsize); \ -}) \ -) - - /** - * kfifo_alloc - dynamically allocates a new fifo buffer - * @fifo: pointer to the fifo - * @size: the number of elements in the fifo, this must be a power of 2 - * @gfp_mask: get_free_pages mask, passed to kmalloc() - * - * This macro dynamically allocates a new fifo buffer. - * - * The number of elements will be rounded-up to a power of 2. - * The fifo will be release with kfifo_free(). - * Return 0 if no error, otherwise an error code. - */ -#define kfifo_alloc(fifo, size, gfp_mask) \ -__kfifo_int_must_check_helper( \ -({ \ - typeof((fifo) + 1) __tmp = (fifo); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - __is_kfifo_ptr(__tmp) ? \ - __kfifo_alloc(__kfifo, size, sizeof(*__tmp->type), gfp_mask) : \ - -EINVAL; \ -}) \ -) - - /** - * kfifo_free - frees the fifo - * @fifo: the fifo to be freed - */ -#define kfifo_free(fifo) \ -({ \ - typeof((fifo) + 1) __tmp = (fifo); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (__is_kfifo_ptr(__tmp)) \ - __kfifo_free(__kfifo); \ -}) - - /** - * kfifo_init - initialize a fifo using a preallocated buffer - * @fifo: the fifo to assign the buffer - * @buffer: the preallocated buffer to be used - * @size: the size of the internal buffer, this have to be a power of 2 - * - * This macro initializes a fifo using a preallocated buffer. - * - * The number of elements will be rounded-up to a power of 2. - * Return 0 if no error, otherwise an error code. - */ -#define kfifo_init(fifo, buffer, size) \ -({ \ - typeof((fifo) + 1) __tmp = (fifo); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - __is_kfifo_ptr(__tmp) ? \ - __kfifo_init(__kfifo, buffer, size, sizeof(*__tmp->type)) : \ - -EINVAL; \ -}) - - /** - * kfifo_put - put data into the fifo - * @fifo: address of the fifo to be used - * @val: the data to be added - * - * This macro copies the given value into the fifo. - * It returns 0 if the fifo was full. Otherwise it returns the number - * processed elements. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these macro. - */ -#define kfifo_put(fifo, val) \ -({ \ - typeof((fifo) + 1) __tmp = (fifo); \ - typeof(*__tmp->const_type) __val = (val); \ - unsigned int __ret; \ - size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (__recsize) \ - __ret = __kfifo_in_r(__kfifo, &__val, sizeof(__val), \ - __recsize); \ - else { \ - __ret = !kfifo_is_full(__tmp); \ - if (__ret) { \ - (__is_kfifo_ptr(__tmp) ? \ - ((typeof(__tmp->type))__kfifo->data) : \ - (__tmp->buf) \ - )[__kfifo->in & __tmp->kfifo.mask] = \ - *(typeof(__tmp->type))&__val; \ - smp_wmb(); \ - __kfifo->in++; \ - } \ - } \ - __ret; \ -}) - - /** - * kfifo_get - get data from the fifo - * @fifo: address of the fifo to be used - * @val: address where to store the data - * - * This macro reads the data from the fifo. - * It returns 0 if the fifo was empty. Otherwise it returns the number - * processed elements. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these macro. - */ -#define kfifo_get(fifo, val) \ -__kfifo_uint_must_check_helper( \ -({ \ - typeof((fifo) + 1) __tmp = (fifo); \ - typeof(__tmp->ptr) __val = (val); \ - unsigned int __ret; \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (__recsize) \ - __ret = __kfifo_out_r(__kfifo, __val, sizeof(*__val), \ - __recsize); \ - else { \ - __ret = !kfifo_is_empty(__tmp); \ - if (__ret) { \ - *(typeof(__tmp->type))__val = \ - (__is_kfifo_ptr(__tmp) ? \ - ((typeof(__tmp->type))__kfifo->data) : \ - (__tmp->buf) \ - )[__kfifo->out & __tmp->kfifo.mask]; \ - smp_wmb(); \ - __kfifo->out++; \ - } \ - } \ - __ret; \ -}) \ -) - - /** - * kfifo_peek - get data from the fifo without removing - * @fifo: address of the fifo to be used - * @val: address where to store the data - * - * This reads the data from the fifo without removing it from the fifo. - * It returns 0 if the fifo was empty. Otherwise it returns the number - * processed elements. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these macro. - */ -#define kfifo_peek(fifo, val) \ -__kfifo_uint_must_check_helper( \ -({ \ - typeof((fifo) + 1) __tmp = (fifo); \ - typeof(__tmp->ptr) __val = (val); \ - unsigned int __ret; \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (__recsize) \ - __ret = __kfifo_out_peek_r(__kfifo, __val, sizeof(*__val), \ - __recsize); \ - else { \ - __ret = !kfifo_is_empty(__tmp); \ - if (__ret) { \ - *(typeof(__tmp->type))__val = \ - (__is_kfifo_ptr(__tmp) ? \ - ((typeof(__tmp->type))__kfifo->data) : \ - (__tmp->buf) \ - )[__kfifo->out & __tmp->kfifo.mask]; \ - smp_wmb(); \ - } \ - } \ - __ret; \ -}) \ -) - - /** - * kfifo_in - put data into the fifo - * @fifo: address of the fifo to be used - * @buf: the data to be added - * @n: number of elements to be added - * - * This macro copies the given buffer into the fifo and returns the - * number of copied elements. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these macro. - */ -#define kfifo_in(fifo, buf, n) \ -({ \ - typeof((fifo) + 1) __tmp = (fifo); \ - typeof(__tmp->ptr_const) __buf = (buf); \ - unsigned long __n = (n); \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - (__recsize) ?\ - __kfifo_in_r(__kfifo, __buf, __n, __recsize) : \ - __kfifo_in(__kfifo, __buf, __n); \ -}) - - /** - * kfifo_in_spinlocked - put data into the fifo using a spinlock for locking - * @fifo: address of the fifo to be used - * @buf: the data to be added - * @n: number of elements to be added - * @lock: pointer to the spinlock to use for locking - * - * This macro copies the given values buffer into the fifo and returns the - * number of copied elements. - */ -#define kfifo_in_spinlocked(fifo, buf, n, lock) \ -({ \ - unsigned long __flags; \ - unsigned int __ret; \ - spin_lock_irqsave(lock, __flags); \ - __ret = kfifo_in(fifo, buf, n); \ - spin_unlock_irqrestore(lock, __flags); \ - __ret; \ -}) - - /** - * kfifo_in_spinlocked_noirqsave - put data into fifo using a spinlock for - * locking, don't disable interrupts - * @fifo: address of the fifo to be used - * @buf: the data to be added - * @n: number of elements to be added - * @lock: pointer to the spinlock to use for locking - * - * This is a variant of kfifo_in_spinlocked() but uses spin_lock/unlock() - * for locking and doesn't disable interrupts. - */ -#define kfifo_in_spinlocked_noirqsave(fifo, buf, n, lock) \ -({ \ - unsigned int __ret; \ - spin_lock(lock); \ - __ret = kfifo_in(fifo, buf, n); \ - spin_unlock(lock); \ - __ret; \ -}) - - /* alias for kfifo_in_spinlocked, will be removed in a future release */ -#define kfifo_in_locked(fifo, buf, n, lock) \ - kfifo_in_spinlocked(fifo, buf, n, lock) - -/** - * kfifo_out - get data from the fifo - * @fifo: address of the fifo to be used - * @buf: pointer to the storage buffer - * @n: max. number of elements to get - * - * This macro get some data from the fifo and return the numbers of elements - * copied. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these macro. - */ -#define kfifo_out(fifo, buf, n) \ -__kfifo_uint_must_check_helper( \ -({ \ - typeof((fifo) + 1) __tmp = (fifo); \ - typeof(__tmp->ptr) __buf = (buf); \ - unsigned long __n = (n); \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - (__recsize) ?\ - __kfifo_out_r(__kfifo, __buf, __n, __recsize) : \ - __kfifo_out(__kfifo, __buf, __n); \ -}) \ -) - - /** - * kfifo_out_spinlocked - get data from the fifo using a spinlock for locking - * @fifo: address of the fifo to be used - * @buf: pointer to the storage buffer - * @n: max. number of elements to get - * @lock: pointer to the spinlock to use for locking - * - * This macro get the data from the fifo and return the numbers of elements - * copied. - */ -#define kfifo_out_spinlocked(fifo, buf, n, lock) \ -__kfifo_uint_must_check_helper( \ -({ \ - unsigned long __flags; \ - unsigned int __ret; \ - spin_lock_irqsave(lock, __flags); \ - __ret = kfifo_out(fifo, buf, n); \ - spin_unlock_irqrestore(lock, __flags); \ - __ret; \ -}) \ -) - - /** - * kfifo_out_spinlocked_noirqsave - get data from the fifo using a spinlock - * for locking, don't disable interrupts - * @fifo: address of the fifo to be used - * @buf: pointer to the storage buffer - * @n: max. number of elements to get - * @lock: pointer to the spinlock to use for locking - * - * This is a variant of kfifo_out_spinlocked() which uses spin_lock/unlock() - * for locking and doesn't disable interrupts. - */ -#define kfifo_out_spinlocked_noirqsave(fifo, buf, n, lock) \ -__kfifo_uint_must_check_helper( \ -({ \ - unsigned int __ret; \ - spin_lock(lock); \ - __ret = kfifo_out(fifo, buf, n); \ - spin_unlock(lock); \ - __ret; \ -}) \ -) - - /* alias for kfifo_out_spinlocked, will be removed in a future release */ -#define kfifo_out_locked(fifo, buf, n, lock) \ - kfifo_out_spinlocked(fifo, buf, n, lock) - -/** - * kfifo_from_user - puts some data from user space into the fifo - * @fifo: address of the fifo to be used - * @from: pointer to the data to be added - * @len: the length of the data to be added - * @copied: pointer to output variable to store the number of copied bytes - * - * This macro copies at most @len bytes from the @from into the - * fifo, depending of the available space and returns -EFAULT/0. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these macro. - */ -#define kfifo_from_user(fifo, from, len, copied) \ -__kfifo_uint_must_check_helper( \ -({ \ - typeof((fifo) + 1) __tmp = (fifo); \ - const void __user *__from = (from); \ - unsigned int __len = (len); \ - unsigned int *__copied = (copied); \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - (__recsize) ? \ - __kfifo_from_user_r(__kfifo, __from, __len, __copied, __recsize) : \ - __kfifo_from_user(__kfifo, __from, __len, __copied); \ -}) \ -) - - /** - * kfifo_to_user - copies data from the fifo into user space - * @fifo: address of the fifo to be used - * @to: where the data must be copied - * @len: the size of the destination buffer - * @copied: pointer to output variable to store the number of copied bytes - * - * This macro copies at most @len bytes from the fifo into the - * @to buffer and returns -EFAULT/0. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these macro. - */ -#define kfifo_to_user(fifo, to, len, copied) \ -__kfifo_int_must_check_helper( \ -({ \ - typeof((fifo) + 1) __tmp = (fifo); \ - void __user *__to = (to); \ - unsigned int __len = (len); \ - unsigned int *__copied = (copied); \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - (__recsize) ? \ - __kfifo_to_user_r(__kfifo, __to, __len, __copied, __recsize) : \ - __kfifo_to_user(__kfifo, __to, __len, __copied); \ -}) \ -) - - /** - * kfifo_dma_in_prepare - setup a scatterlist for DMA input - * @fifo: address of the fifo to be used - * @sgl: pointer to the scatterlist array - * @nents: number of entries in the scatterlist array - * @len: number of elements to transfer - * - * This macro fills a scatterlist for DMA input. - * It returns the number entries in the scatterlist array. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these macros. - */ -#define kfifo_dma_in_prepare(fifo, sgl, nents, len) \ -({ \ - typeof((fifo) + 1) __tmp = (fifo); \ - struct scatterlist *__sgl = (sgl); \ - int __nents = (nents); \ - unsigned int __len = (len); \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - (__recsize) ? \ - __kfifo_dma_in_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \ - __kfifo_dma_in_prepare(__kfifo, __sgl, __nents, __len); \ -}) - - /** - * kfifo_dma_in_finish - finish a DMA IN operation - * @fifo: address of the fifo to be used - * @len: number of bytes to received - * - * This macro finish a DMA IN operation. The in counter will be updated by - * the len parameter. No error checking will be done. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these macros. - */ -#define kfifo_dma_in_finish(fifo, len) \ -(void)({ \ - typeof((fifo) + 1) __tmp = (fifo); \ - unsigned int __len = (len); \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (__recsize) \ - __kfifo_dma_in_finish_r(__kfifo, __len, __recsize); \ - else \ - __kfifo->in += __len / sizeof(*__tmp->type); \ -}) - - /** - * kfifo_dma_out_prepare - setup a scatterlist for DMA output - * @fifo: address of the fifo to be used - * @sgl: pointer to the scatterlist array - * @nents: number of entries in the scatterlist array - * @len: number of elements to transfer - * - * This macro fills a scatterlist for DMA output which at most @len bytes - * to transfer. - * It returns the number entries in the scatterlist array. - * A zero means there is no space available and the scatterlist is not filled. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these macros. - */ -#define kfifo_dma_out_prepare(fifo, sgl, nents, len) \ -({ \ - typeof((fifo) + 1) __tmp = (fifo); \ - struct scatterlist *__sgl = (sgl); \ - int __nents = (nents); \ - unsigned int __len = (len); \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - (__recsize) ? \ - __kfifo_dma_out_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \ - __kfifo_dma_out_prepare(__kfifo, __sgl, __nents, __len); \ -}) - - /** - * kfifo_dma_out_finish - finish a DMA OUT operation - * @fifo: address of the fifo to be used - * @len: number of bytes transferred - * - * This macro finish a DMA OUT operation. The out counter will be updated by - * the len parameter. No error checking will be done. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these macros. - */ -#define kfifo_dma_out_finish(fifo, len) \ -(void)({ \ - typeof((fifo) + 1) __tmp = (fifo); \ - unsigned int __len = (len); \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (__recsize) \ - __kfifo_dma_out_finish_r(__kfifo, __recsize); \ - else \ - __kfifo->out += __len / sizeof(*__tmp->type); \ -}) - - /** - * kfifo_out_peek - gets some data from the fifo - * @fifo: address of the fifo to be used - * @buf: pointer to the storage buffer - * @n: max. number of elements to get - * - * This macro get the data from the fifo and return the numbers of elements - * copied. The data is not removed from the fifo. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these macro. - */ -#define kfifo_out_peek(fifo, buf, n) \ -__kfifo_uint_must_check_helper( \ -({ \ - typeof((fifo) + 1) __tmp = (fifo); \ - typeof(__tmp->ptr) __buf = (buf); \ - unsigned long __n = (n); \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - (__recsize) ? \ - __kfifo_out_peek_r(__kfifo, __buf, __n, __recsize) : \ - __kfifo_out_peek(__kfifo, __buf, __n); \ -}) \ -) - -//extern int __kfifo_alloc(struct __kfifo* fifo, unsigned int size, -// size_t esize, gfp_t gfp_mask); -// -//extern void __kfifo_free(struct __kfifo* fifo); -// -//extern int __kfifo_init(struct __kfifo* fifo, void* buffer, -// unsigned int size, size_t esize); -// -//extern unsigned int __kfifo_in(struct __kfifo* fifo, -// const void* buf, unsigned int len); -// -//extern unsigned int __kfifo_out(struct __kfifo* fifo, -// void* buf, unsigned int len); -// -//extern int __kfifo_from_user(struct __kfifo* fifo, -// const void __user* from, unsigned long len, unsigned int* copied); -// -//extern int __kfifo_to_user(struct __kfifo* fifo, -// void __user* to, unsigned long len, unsigned int* copied); -// -//extern unsigned int __kfifo_dma_in_prepare(struct __kfifo* fifo, -// struct scatterlist* sgl, int nents, unsigned int len); -// -//extern unsigned int __kfifo_dma_out_prepare(struct __kfifo* fifo, -// struct scatterlist* sgl, int nents, unsigned int len); -// -//extern unsigned int __kfifo_out_peek(struct __kfifo* fifo, -// void* buf, unsigned int len); -// -//extern unsigned int __kfifo_in_r(struct __kfifo* fifo, -// const void* buf, unsigned int len, size_t recsize); -// -//extern unsigned int __kfifo_out_r(struct __kfifo* fifo, -// void* buf, unsigned int len, size_t recsize); -// -//extern int __kfifo_from_user_r(struct __kfifo* fifo, -// const void __user* from, unsigned long len, unsigned int* copied, -// size_t recsize); -// -//extern int __kfifo_to_user_r(struct __kfifo* fifo, void __user* to, -// unsigned long len, unsigned int* copied, size_t recsize); -// -//extern unsigned int __kfifo_dma_in_prepare_r(struct __kfifo* fifo, -// struct scatterlist* sgl, int nents, unsigned int len, size_t recsize); -// -//extern void __kfifo_dma_in_finish_r(struct __kfifo* fifo, -// unsigned int len, size_t recsize); -// -//extern unsigned int __kfifo_dma_out_prepare_r(struct __kfifo* fifo, -// struct scatterlist* sgl, int nents, unsigned int len, size_t recsize); -// -//extern void __kfifo_dma_out_finish_r(struct __kfifo* fifo, size_t recsize); -// -//extern unsigned int __kfifo_len_r(struct __kfifo* fifo, size_t recsize); -// -//extern void __kfifo_skip_r(struct __kfifo* fifo, size_t recsize); -// -//extern unsigned int __kfifo_out_peek_r(struct __kfifo* fifo, -// void* buf, unsigned int len, size_t recsize); -// -//extern unsigned int __kfifo_max_r(unsigned int len, size_t recsize); - -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * A generic kernel FIFO implementation - * - * Copyright (C) 2009/2010 Stefani Seibold - */ - -//#include -//#include -//#include -//#include -//#include -//#include -//#include - -// /* -// * internal helper to calculate the unused elements in a fifo -// */ -//static inline unsigned int kfifo_unused(struct __kfifo* fifo) -//{ -// return (fifo->mask + 1) - (fifo->in - fifo->out); -//} -// -//int __kfifo_alloc(struct __kfifo* fifo, unsigned int size, -// size_t esize, gfp_t gfp_mask) -//{ -// /* -// * round up to the next power of 2, since our 'let the indices -// * wrap' technique works only in this case. -// */ -// size = roundup_pow_of_two(size); -// -// fifo->in = 0; -// fifo->out = 0; -// fifo->esize = esize; -// -// if (size < 2) { -// fifo->data = NULL; -// fifo->mask = 0; -// return -EINVAL; -// } -// -// fifo->data = kmalloc_array(esize, size, gfp_mask); -// -// if (!fifo->data) { -// fifo->mask = 0; -// return -ENOMEM; -// } -// fifo->mask = size - 1; -// -// return 0; -//} -//EXPORT_SYMBOL(__kfifo_alloc); -// -//void __kfifo_free(struct __kfifo* fifo) -//{ -// kfree(fifo->data); -// fifo->in = 0; -// fifo->out = 0; -// fifo->esize = 0; -// fifo->data = NULL; -// fifo->mask = 0; -//} -//EXPORT_SYMBOL(__kfifo_free); -// -//int __kfifo_init(struct __kfifo* fifo, void* buffer, -// unsigned int size, size_t esize) -//{ -// size /= esize; -// -// if (!is_power_of_2(size)) -// size = rounddown_pow_of_two(size); -// -// fifo->in = 0; -// fifo->out = 0; -// fifo->esize = esize; -// fifo->data = buffer; -// -// if (size < 2) { -// fifo->mask = 0; -// return -EINVAL; -// } -// fifo->mask = size - 1; -// -// return 0; -//} -//EXPORT_SYMBOL(__kfifo_init); -// -//static void kfifo_copy_in(struct __kfifo* fifo, const void* src, -// unsigned int len, unsigned int off) -//{ -// unsigned int size = fifo->mask + 1; -// unsigned int esize = fifo->esize; -// unsigned int l; -// -// off &= fifo->mask; -// if (esize != 1) { -// off *= esize; -// size *= esize; -// len *= esize; -// } -// l = min(len, size - off); -// -// memcpy(fifo->data + off, src, l); -// memcpy(fifo->data, src + l, len - l); -// /* -// * make sure that the data in the fifo is up to date before -// * incrementing the fifo->in index counter -// */ -// smp_wmb(); -//} -// -//unsigned int __kfifo_in(struct __kfifo* fifo, -// const void* buf, unsigned int len) -//{ -// unsigned int l; -// -// l = kfifo_unused(fifo); -// if (len > l) -// len = l; -// -// kfifo_copy_in(fifo, buf, len, fifo->in); -// fifo->in += len; -// return len; -//} -//EXPORT_SYMBOL(__kfifo_in); -// -//static void kfifo_copy_out(struct __kfifo* fifo, void* dst, -// unsigned int len, unsigned int off) -//{ -// unsigned int size = fifo->mask + 1; -// unsigned int esize = fifo->esize; -// unsigned int l; -// -// off &= fifo->mask; -// if (esize != 1) { -// off *= esize; -// size *= esize; -// len *= esize; -// } -// l = min(len, size - off); -// -// memcpy(dst, fifo->data + off, l); -// memcpy(dst + l, fifo->data, len - l); -// /* -// * make sure that the data is copied before -// * incrementing the fifo->out index counter -// */ -// smp_wmb(); -//} -// -//unsigned int __kfifo_out_peek(struct __kfifo* fifo, -// void* buf, unsigned int len) -//{ -// unsigned int l; -// -// l = fifo->in - fifo->out; -// if (len > l) -// len = l; -// -// kfifo_copy_out(fifo, buf, len, fifo->out); -// return len; -//} -//EXPORT_SYMBOL(__kfifo_out_peek); -// -//unsigned int __kfifo_out(struct __kfifo* fifo, -// void* buf, unsigned int len) -//{ -// len = __kfifo_out_peek(fifo, buf, len); -// fifo->out += len; -// return len; -//} -//EXPORT_SYMBOL(__kfifo_out); -// -//static unsigned long kfifo_copy_from_user(struct __kfifo* fifo, -// const void __user* from, unsigned int len, unsigned int off, -// unsigned int* copied) -//{ -// unsigned int size = fifo->mask + 1; -// unsigned int esize = fifo->esize; -// unsigned int l; -// unsigned long ret; -// -// off &= fifo->mask; -// if (esize != 1) { -// off *= esize; -// size *= esize; -// len *= esize; -// } -// l = min(len, size - off); -// -// ret = copy_from_user(fifo->data + off, from, l); -// if (unlikely(ret)) -// ret = DIV_ROUND_UP(ret + len - l, esize); -// else { -// ret = copy_from_user(fifo->data, from + l, len - l); -// if (unlikely(ret)) -// ret = DIV_ROUND_UP(ret, esize); -// } -// /* -// * make sure that the data in the fifo is up to date before -// * incrementing the fifo->in index counter -// */ -// smp_wmb(); -// *copied = len - ret * esize; -// /* return the number of elements which are not copied */ -// return ret; -//} -// -//int __kfifo_from_user(struct __kfifo* fifo, const void __user* from, -// unsigned long len, unsigned int* copied) -//{ -// unsigned int l; -// unsigned long ret; -// unsigned int esize = fifo->esize; -// int err; -// -// if (esize != 1) -// len /= esize; -// -// l = kfifo_unused(fifo); -// if (len > l) -// len = l; -// -// ret = kfifo_copy_from_user(fifo, from, len, fifo->in, copied); -// if (unlikely(ret)) { -// len -= ret; -// err = -EFAULT; -// } -// else -// err = 0; -// fifo->in += len; -// return err; -//} -//EXPORT_SYMBOL(__kfifo_from_user); -// -//static unsigned long kfifo_copy_to_user(struct __kfifo* fifo, void __user* to, -// unsigned int len, unsigned int off, unsigned int* copied) -//{ -// unsigned int l; -// unsigned long ret; -// unsigned int size = fifo->mask + 1; -// unsigned int esize = fifo->esize; -// -// off &= fifo->mask; -// if (esize != 1) { -// off *= esize; -// size *= esize; -// len *= esize; -// } -// l = min(len, size - off); -// -// ret = copy_to_user(to, fifo->data + off, l); -// if (unlikely(ret)) -// ret = DIV_ROUND_UP(ret + len - l, esize); -// else { -// ret = copy_to_user(to + l, fifo->data, len - l); -// if (unlikely(ret)) -// ret = DIV_ROUND_UP(ret, esize); -// } -// /* -// * make sure that the data is copied before -// * incrementing the fifo->out index counter -// */ -// smp_wmb(); -// *copied = len - ret * esize; -// /* return the number of elements which are not copied */ -// return ret; -//} -// -//int __kfifo_to_user(struct __kfifo* fifo, void __user* to, -// unsigned long len, unsigned int* copied) -//{ -// unsigned int l; -// unsigned long ret; -// unsigned int esize = fifo->esize; -// int err; -// -// if (esize != 1) -// len /= esize; -// -// l = fifo->in - fifo->out; -// if (len > l) -// len = l; -// ret = kfifo_copy_to_user(fifo, to, len, fifo->out, copied); -// if (unlikely(ret)) { -// len -= ret; -// err = -EFAULT; -// } -// else -// err = 0; -// fifo->out += len; -// return err; -//} -//EXPORT_SYMBOL(__kfifo_to_user); -// -//static int setup_sgl_buf(struct scatterlist* sgl, void* buf, -// int nents, unsigned int len) -//{ -// int n; -// unsigned int l; -// unsigned int off; -// struct page* page; -// -// if (!nents) -// return 0; -// -// if (!len) -// return 0; -// -// n = 0; -// page = virt_to_page(buf); -// off = offset_in_page(buf); -// l = 0; -// -// while (len >= l + PAGE_SIZE - off) { -// struct page* npage; -// -// l += PAGE_SIZE; -// buf += PAGE_SIZE; -// npage = virt_to_page(buf); -// if (page_to_phys(page) != page_to_phys(npage) - l) { -// sg_set_page(sgl, page, l - off, off); -// sgl = sg_next(sgl); -// if (++n == nents || sgl == NULL) -// return n; -// page = npage; -// len -= l - off; -// l = off = 0; -// } -// } -// sg_set_page(sgl, page, len, off); -// return n + 1; -//} -// -//static unsigned int setup_sgl(struct __kfifo* fifo, struct scatterlist* sgl, -// int nents, unsigned int len, unsigned int off) -//{ -// unsigned int size = fifo->mask + 1; -// unsigned int esize = fifo->esize; -// unsigned int l; -// unsigned int n; -// -// off &= fifo->mask; -// if (esize != 1) { -// off *= esize; -// size *= esize; -// len *= esize; -// } -// l = min(len, size - off); -// -// n = setup_sgl_buf(sgl, fifo->data + off, nents, l); -// n += setup_sgl_buf(sgl + n, fifo->data, nents - n, len - l); -// -// return n; -//} -// -//unsigned int __kfifo_dma_in_prepare(struct __kfifo* fifo, -// struct scatterlist* sgl, int nents, unsigned int len) -//{ -// unsigned int l; -// -// l = kfifo_unused(fifo); -// if (len > l) -// len = l; -// -// return setup_sgl(fifo, sgl, nents, len, fifo->in); -//} -//EXPORT_SYMBOL(__kfifo_dma_in_prepare); -// -//unsigned int __kfifo_dma_out_prepare(struct __kfifo* fifo, -// struct scatterlist* sgl, int nents, unsigned int len) -//{ -// unsigned int l; -// -// l = fifo->in - fifo->out; -// if (len > l) -// len = l; -// -// return setup_sgl(fifo, sgl, nents, len, fifo->out); -//} -//EXPORT_SYMBOL(__kfifo_dma_out_prepare); -// -//unsigned int __kfifo_max_r(unsigned int len, size_t recsize) -//{ -// unsigned int max = (1 << (recsize << 3)) - 1; -// -// if (len > max) -// return max; -// return len; -//} -//EXPORT_SYMBOL(__kfifo_max_r); -// -//#define __KFIFO_PEEK(data, out, mask) \ -// ((data)[(out) & (mask)]) -///* -// * __kfifo_peek_n internal helper function for determinate the length of -// * the next record in the fifo -// */ -//static unsigned int __kfifo_peek_n(struct __kfifo* fifo, size_t recsize) -//{ -// unsigned int l; -// unsigned int mask = fifo->mask; -// unsigned char* data = fifo->data; -// -// l = __KFIFO_PEEK(data, fifo->out, mask); -// -// if (--recsize) -// l |= __KFIFO_PEEK(data, fifo->out + 1, mask) << 8; -// -// return l; -//} -// -//#define __KFIFO_POKE(data, in, mask, val) \ -// ( \ -// (data)[(in) & (mask)] = (unsigned char)(val) \ -// ) -// -///* -// * __kfifo_poke_n internal helper function for storing the length of -// * the record into the fifo -// */ -//static void __kfifo_poke_n(struct __kfifo* fifo, unsigned int n, size_t recsize) -//{ -// unsigned int mask = fifo->mask; -// unsigned char* data = fifo->data; -// -// __KFIFO_POKE(data, fifo->in, mask, n); -// -// if (recsize > 1) -// __KFIFO_POKE(data, fifo->in + 1, mask, n >> 8); -//} -// -//unsigned int __kfifo_len_r(struct __kfifo* fifo, size_t recsize) -//{ -// return __kfifo_peek_n(fifo, recsize); -//} -//EXPORT_SYMBOL(__kfifo_len_r); -// -//unsigned int __kfifo_in_r(struct __kfifo* fifo, const void* buf, -// unsigned int len, size_t recsize) -//{ -// if (len + recsize > kfifo_unused(fifo)) -// return 0; -// -// __kfifo_poke_n(fifo, len, recsize); -// -// kfifo_copy_in(fifo, buf, len, fifo->in + recsize); -// fifo->in += len + recsize; -// return len; -//} -//EXPORT_SYMBOL(__kfifo_in_r); -// -//static unsigned int kfifo_out_copy_r(struct __kfifo* fifo, -// void* buf, unsigned int len, size_t recsize, unsigned int* n) -//{ -// *n = __kfifo_peek_n(fifo, recsize); -// -// if (len > *n) -// len = *n; -// -// kfifo_copy_out(fifo, buf, len, fifo->out + recsize); -// return len; -//} -// -//unsigned int __kfifo_out_peek_r(struct __kfifo* fifo, void* buf, -// unsigned int len, size_t recsize) -//{ -// unsigned int n; -// -// if (fifo->in == fifo->out) -// return 0; -// -// return kfifo_out_copy_r(fifo, buf, len, recsize, &n); -//} -//EXPORT_SYMBOL(__kfifo_out_peek_r); -// -//unsigned int __kfifo_out_r(struct __kfifo* fifo, void* buf, -// unsigned int len, size_t recsize) -//{ -// unsigned int n; -// -// if (fifo->in == fifo->out) -// return 0; -// -// len = kfifo_out_copy_r(fifo, buf, len, recsize, &n); -// fifo->out += n + recsize; -// return len; -//} -//EXPORT_SYMBOL(__kfifo_out_r); -// -//void __kfifo_skip_r(struct __kfifo* fifo, size_t recsize) -//{ -// unsigned int n; -// -// n = __kfifo_peek_n(fifo, recsize); -// fifo->out += n + recsize; -//} -//EXPORT_SYMBOL(__kfifo_skip_r); -// -//int __kfifo_from_user_r(struct __kfifo* fifo, const void __user* from, -// unsigned long len, unsigned int* copied, size_t recsize) -//{ -// unsigned long ret; -// -// len = __kfifo_max_r(len, recsize); -// -// if (len + recsize > kfifo_unused(fifo)) { -// *copied = 0; -// return 0; -// } -// -// __kfifo_poke_n(fifo, len, recsize); -// -// ret = kfifo_copy_from_user(fifo, from, len, fifo->in + recsize, copied); -// if (unlikely(ret)) { -// *copied = 0; -// return -EFAULT; -// } -// fifo->in += len + recsize; -// return 0; -//} -//EXPORT_SYMBOL(__kfifo_from_user_r); -// -//int __kfifo_to_user_r(struct __kfifo* fifo, void __user* to, -// unsigned long len, unsigned int* copied, size_t recsize) -//{ -// unsigned long ret; -// unsigned int n; -// -// if (fifo->in == fifo->out) { -// *copied = 0; -// return 0; -// } -// -// n = __kfifo_peek_n(fifo, recsize); -// if (len > n) -// len = n; -// -// ret = kfifo_copy_to_user(fifo, to, len, fifo->out + recsize, copied); -// if (unlikely(ret)) { -// *copied = 0; -// return -EFAULT; -// } -// fifo->out += n + recsize; -// return 0; -//} -//EXPORT_SYMBOL(__kfifo_to_user_r); -// -//unsigned int __kfifo_dma_in_prepare_r(struct __kfifo* fifo, -// struct scatterlist* sgl, int nents, unsigned int len, size_t recsize) -//{ -// BUG_ON(!nents); -// -// len = __kfifo_max_r(len, recsize); -// -// if (len + recsize > kfifo_unused(fifo)) -// return 0; -// -// return setup_sgl(fifo, sgl, nents, len, fifo->in + recsize); -//} -//EXPORT_SYMBOL(__kfifo_dma_in_prepare_r); -// -//void __kfifo_dma_in_finish_r(struct __kfifo* fifo, -// unsigned int len, size_t recsize) -//{ -// len = __kfifo_max_r(len, recsize); -// __kfifo_poke_n(fifo, len, recsize); -// fifo->in += len + recsize; -//} -//EXPORT_SYMBOL(__kfifo_dma_in_finish_r); -// -//unsigned int __kfifo_dma_out_prepare_r(struct __kfifo* fifo, -// struct scatterlist* sgl, int nents, unsigned int len, size_t recsize) -//{ -// BUG_ON(!nents); -// -// len = __kfifo_max_r(len, recsize); -// -// if (len + recsize > fifo->in - fifo->out) -// return 0; -// -// return setup_sgl(fifo, sgl, nents, len, fifo->out + recsize); -//} -//EXPORT_SYMBOL(__kfifo_dma_out_prepare_r); -// -//void __kfifo_dma_out_finish_r(struct __kfifo* fifo, size_t recsize) -//{ -// unsigned int len; -// -// len = __kfifo_peek_n(fifo, recsize); -// fifo->out += len + recsize; -//} -//EXPORT_SYMBOL(__kfifo_dma_out_finish_r); - - -#endif #endif // _BKFIFO_H_ \ No newline at end of file