git: 855405e1750d - stable/13 - LinuxKPI: extend kfifo to be usable

From: Bjoern A. Zeeb <bz_at_FreeBSD.org>
Date: Wed, 21 Sep 2022 14:01:24 UTC
The branch stable/13 has been updated by bz:

URL: https://cgit.FreeBSD.org/src/commit/?id=855405e1750df5fcd003af127bfbe47bc0f35d04

commit 855405e1750df5fcd003af127bfbe47bc0f35d04
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2022-07-16 00:36:55 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2022-09-21 11:46:45 +0000

    LinuxKPI: extend kfifo to be usable
    
    Implement some basic kfifo pieces as needed by drivers.
    
    Reviewed by:    wulf, hselasky
    Differential Revision: https://reviews.freebsd.org/D35829
    
    (cherry picked from commit 4a7e8c7bd40bc39b3e247df069fa913f0197ea01)
---
 sys/compat/linuxkpi/common/include/linux/kfifo.h | 89 ++++++++++++++++++++++++
 1 file changed, 89 insertions(+)

diff --git a/sys/compat/linuxkpi/common/include/linux/kfifo.h b/sys/compat/linuxkpi/common/include/linux/kfifo.h
index 6ba1528d965c..d2f570781661 100644
--- a/sys/compat/linuxkpi/common/include/linux/kfifo.h
+++ b/sys/compat/linuxkpi/common/include/linux/kfifo.h
@@ -1,5 +1,6 @@
 /*-
  * Copyright (c) 2021 Beckhoff Automation GmbH & Co. KG
+ * Copyright (c) 2022 Bjoern A. Zeeb
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -27,7 +28,95 @@
 #ifndef _LINUXKPI_LINUX_KFIFO_H_
 #define	_LINUXKPI_LINUX_KFIFO_H_
 
+#include <sys/types.h>
+
+#include <linux/slab.h>
+#include <linux/gfp.h>
+
 #define	INIT_KFIFO(x)	0
 #define	DECLARE_KFIFO(x, y, z)
 
+#define	DECLARE_KFIFO_PTR(_name, _type)					\
+	struct kfifo_ ## _name {					\
+		size_t		total;					\
+		size_t		count;					\
+		size_t		first;					\
+		size_t		last;					\
+		_type		*head;					\
+	} _name
+
+#define	kfifo_len(_kf)							\
+({									\
+	(_kf)->count;							\
+})
+
+#define	kfifo_is_empty(_kf)						\
+({									\
+	((_kf)->count == 0) ? true : false;				\
+})
+
+#define	kfifo_is_full(_kf)						\
+({									\
+	((_kf)->count == (_kf)->total) ? true : false;			\
+})
+
+#define	kfifo_put(_kf, _e)						\
+({									\
+	bool _rc;							\
+									\
+	/* Would overflow. */						\
+	if (kfifo_is_full(_kf)) {					\
+		_rc = false;						\
+	} else {							\
+		(_kf)->head[(_kf)->last] = (_e);			\
+		(_kf)->count++;						\
+		(_kf)->last++;						\
+		if ((_kf)->last > (_kf)->total)				\
+			(_kf)->last = 0;				\
+		_rc = true;						\
+	}								\
+									\
+	_rc;								\
+})
+
+#define	kfifo_get(_kf, _e)						\
+({									\
+	bool _rc;							\
+									\
+	if (kfifo_is_empty(_kf)) {					\
+		_rc = false;						\
+	} else {							\
+		*(_e) = (_kf)->head[(_kf)->first];			\
+		(_kf)->count--;						\
+		(_kf)->first++;						\
+		if ((_kf)->first > (_kf)->total)			\
+			(_kf)->first = 0;				\
+		_rc = true;						\
+	}								\
+									\
+	_rc;								\
+})
+
+#define	kfifo_alloc(_kf, _s, _gfp)					\
+({									\
+	int _error;							\
+									\
+	(_kf)->head = kmalloc(sizeof(__typeof(*(_kf)->head)) * (_s), _gfp); \
+	if ((_kf)->head == NULL)					\
+		_error = ENOMEM;					\
+	else {								\
+		(_kf)->total = (_s);					\
+		_error = 0;						\
+	}								\
+									\
+	_error;								\
+})
+
+#define	kfifo_free(_kf)							\
+({									\
+	kfree((_kf)->head);						\
+	(_kf)->head = NULL;						\
+	(_kf)->total = (_kf)->count = (_kf)->first = (_kf)->last = 0;	\
+})
+
 #endif	/* _LINUXKPI_LINUX_KFIFO_H_*/