| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 2 |  * A generic kernel FIFO implementation | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 3 |  * | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 4 |  * Copyright (C) 2009/2010 Stefani Seibold <stefani@seibold.net> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 5 |  * | 
 | 6 |  * This program is free software; you can redistribute it and/or modify | 
 | 7 |  * it under the terms of the GNU General Public License as published by | 
 | 8 |  * the Free Software Foundation; either version 2 of the License, or | 
 | 9 |  * (at your option) any later version. | 
 | 10 |  * | 
 | 11 |  * This program is distributed in the hope that it will be useful, | 
 | 12 |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 | 13 |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
 | 14 |  * GNU General Public License for more details. | 
 | 15 |  * | 
 | 16 |  * You should have received a copy of the GNU General Public License | 
 | 17 |  * along with this program; if not, write to the Free Software | 
 | 18 |  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 
 | 19 |  * | 
 | 20 |  */ | 
| Stefani Seibold | 7acd72e | 2009-12-21 14:37:28 -0800 | [diff] [blame] | 21 |  | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 22 | #ifndef _LINUX_KFIFO_H | 
 | 23 | #define _LINUX_KFIFO_H | 
 | 24 |  | 
| Stefani Seibold | 7acd72e | 2009-12-21 14:37:28 -0800 | [diff] [blame] | 25 | /* | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 26 |  * How to porting drivers to the new generic FIFO API: | 
| Stefani Seibold | 7acd72e | 2009-12-21 14:37:28 -0800 | [diff] [blame] | 27 |  * | 
 | 28 |  * - Modify the declaration of the "struct kfifo *" object into a | 
 | 29 |  *   in-place "struct kfifo" object | 
 | 30 |  * - Init the in-place object with kfifo_alloc() or kfifo_init() | 
 | 31 |  *   Note: The address of the in-place "struct kfifo" object must be | 
 | 32 |  *   passed as the first argument to this functions | 
 | 33 |  * - Replace the use of __kfifo_put into kfifo_in and __kfifo_get | 
 | 34 |  *   into kfifo_out | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 35 |  * - Replace the use of kfifo_put into kfifo_in_spinlocked and kfifo_get | 
 | 36 |  *   into kfifo_out_spinlocked | 
| Stefani Seibold | 7acd72e | 2009-12-21 14:37:28 -0800 | [diff] [blame] | 37 |  *   Note: the spinlock pointer formerly passed to kfifo_init/kfifo_alloc | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 38 |  *   must be passed now to the kfifo_in_spinlocked and kfifo_out_spinlocked | 
 | 39 |  *   as the last parameter | 
 | 40 |  * - The formerly __kfifo_* functions are renamed into kfifo_* | 
| Stefani Seibold | 7acd72e | 2009-12-21 14:37:28 -0800 | [diff] [blame] | 41 |  */ | 
 | 42 |  | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 43 | /* | 
 | 44 |  * Note about locking : There is no locking required until only * one reader | 
 | 45 |  * and one writer is using the fifo and no kfifo_reset() will be * called | 
 | 46 |  *  kfifo_reset_out() can be safely used, until it will be only called | 
 | 47 |  * in the reader thread. | 
 | 48 |  *  For multiple writer and one reader there is only a need to lock the writer. | 
 | 49 |  * And vice versa for only one writer and multiple reader there is only a need | 
 | 50 |  * to lock the reader. | 
 | 51 |  */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 52 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 53 | #include <linux/kernel.h> | 
 | 54 | #include <linux/spinlock.h> | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 55 | #include <linux/stddef.h> | 
 | 56 | #include <linux/scatterlist.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 57 |  | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 58 | struct __kfifo { | 
 | 59 | 	unsigned int	in; | 
 | 60 | 	unsigned int	out; | 
 | 61 | 	unsigned int	mask; | 
 | 62 | 	unsigned int	esize; | 
 | 63 | 	void		*data; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 64 | }; | 
 | 65 |  | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 66 | #define __STRUCT_KFIFO_COMMON(datatype, recsize, ptrtype) \ | 
 | 67 | 	union { \ | 
 | 68 | 		struct __kfifo	kfifo; \ | 
 | 69 | 		datatype	*type; \ | 
 | 70 | 		char		(*rectype)[recsize]; \ | 
 | 71 | 		ptrtype		*ptr; \ | 
 | 72 | 		const ptrtype	*ptr_const; \ | 
| Stefani Seibold | 37bdfbb | 2009-12-21 14:37:30 -0800 | [diff] [blame] | 73 | 	} | 
 | 74 |  | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 75 | #define __STRUCT_KFIFO(type, size, recsize, ptrtype) \ | 
 | 76 | { \ | 
 | 77 | 	__STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ | 
 | 78 | 	type		buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \ | 
 | 79 | } | 
 | 80 |  | 
 | 81 | #define STRUCT_KFIFO(type, size) \ | 
 | 82 | 	struct __STRUCT_KFIFO(type, size, 0, type) | 
 | 83 |  | 
 | 84 | #define __STRUCT_KFIFO_PTR(type, recsize, ptrtype) \ | 
 | 85 | { \ | 
 | 86 | 	__STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ | 
 | 87 | 	type		buf[0]; \ | 
 | 88 | } | 
 | 89 |  | 
 | 90 | #define STRUCT_KFIFO_PTR(type) \ | 
 | 91 | 	struct __STRUCT_KFIFO_PTR(type, 0, type) | 
 | 92 |  | 
 | 93 | /* | 
 | 94 |  * define compatibility "struct kfifo" for dynamic allocated fifos | 
| Stefani Seibold | 37bdfbb | 2009-12-21 14:37:30 -0800 | [diff] [blame] | 95 |  */ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 96 | struct kfifo __STRUCT_KFIFO_PTR(unsigned char, 0, void); | 
 | 97 |  | 
 | 98 | #define STRUCT_KFIFO_REC_1(size) \ | 
 | 99 | 	struct __STRUCT_KFIFO(unsigned char, size, 1, void) | 
 | 100 |  | 
 | 101 | #define STRUCT_KFIFO_REC_2(size) \ | 
 | 102 | 	struct __STRUCT_KFIFO(unsigned char, size, 2, void) | 
 | 103 |  | 
 | 104 | /* | 
 | 105 |  * define kfifo_rec types | 
 | 106 |  */ | 
 | 107 | struct kfifo_rec_ptr_1 __STRUCT_KFIFO_PTR(unsigned char, 1, void); | 
 | 108 | struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2, void); | 
 | 109 |  | 
 | 110 | /* | 
 | 111 |  * helper macro to distinguish between real in place fifo where the fifo | 
 | 112 |  * array is a part of the structure and the fifo type where the array is | 
 | 113 |  * outside of the fifo structure. | 
 | 114 |  */ | 
 | 115 | #define	__is_kfifo_ptr(fifo)	(sizeof(*fifo) == sizeof(struct __kfifo)) | 
 | 116 |  | 
 | 117 | /** | 
 | 118 |  * DECLARE_KFIFO_PTR - macro to declare a fifo pointer object | 
 | 119 |  * @fifo: name of the declared fifo | 
 | 120 |  * @type: type of the fifo elements | 
 | 121 |  */ | 
 | 122 | #define DECLARE_KFIFO_PTR(fifo, type)	STRUCT_KFIFO_PTR(type) fifo | 
 | 123 |  | 
 | 124 | /** | 
 | 125 |  * DECLARE_KFIFO - macro to declare a fifo object | 
 | 126 |  * @fifo: name of the declared fifo | 
 | 127 |  * @type: type of the fifo elements | 
 | 128 |  * @size: the number of elements in the fifo, this must be a power of 2 | 
 | 129 |  */ | 
 | 130 | #define DECLARE_KFIFO(fifo, type, size)	STRUCT_KFIFO(type, size) fifo | 
 | 131 |  | 
 | 132 | /** | 
 | 133 |  * INIT_KFIFO - Initialize a fifo declared by DECLARE_KFIFO | 
 | 134 |  * @fifo: name of the declared fifo datatype | 
 | 135 |  */ | 
 | 136 | #define INIT_KFIFO(fifo) \ | 
 | 137 | (void)({ \ | 
 | 138 | 	typeof(&(fifo)) __tmp = &(fifo); \ | 
 | 139 | 	struct __kfifo *__kfifo = &__tmp->kfifo; \ | 
 | 140 | 	__kfifo->in = 0; \ | 
 | 141 | 	__kfifo->out = 0; \ | 
 | 142 | 	__kfifo->mask = __is_kfifo_ptr(__tmp) ? 0 : ARRAY_SIZE(__tmp->buf) - 1;\ | 
 | 143 | 	__kfifo->esize = sizeof(*__tmp->buf); \ | 
 | 144 | 	__kfifo->data = __is_kfifo_ptr(__tmp) ?  NULL : __tmp->buf; \ | 
 | 145 | }) | 
 | 146 |  | 
 | 147 | /** | 
 | 148 |  * DEFINE_KFIFO - macro to define and initialize a fifo | 
 | 149 |  * @fifo: name of the declared fifo datatype | 
 | 150 |  * @type: type of the fifo elements | 
 | 151 |  * @size: the number of elements in the fifo, this must be a power of 2 | 
 | 152 |  * | 
 | 153 |  * Note: the macro can be used for global and local fifo data type variables. | 
 | 154 |  */ | 
 | 155 | #define DEFINE_KFIFO(fifo, type, size) \ | 
 | 156 | 	DECLARE_KFIFO(fifo, type, size) = \ | 
 | 157 | 	(typeof(fifo)) { \ | 
 | 158 | 		{ \ | 
 | 159 | 			{ \ | 
 | 160 | 			.in	= 0, \ | 
 | 161 | 			.out	= 0, \ | 
 | 162 | 			.mask	= __is_kfifo_ptr(&(fifo)) ? \ | 
 | 163 | 				  0 : \ | 
 | 164 | 				  ARRAY_SIZE((fifo).buf) - 1, \ | 
 | 165 | 			.esize	= sizeof(*(fifo).buf), \ | 
 | 166 | 			.data	= __is_kfifo_ptr(&(fifo)) ? \ | 
 | 167 | 				NULL : \ | 
 | 168 | 				(fifo).buf, \ | 
 | 169 | 			} \ | 
 | 170 | 		} \ | 
 | 171 | 	} | 
 | 172 |  | 
 | 173 |  | 
| Stefani Seibold | 144ecf3 | 2010-10-27 15:34:50 -0700 | [diff] [blame] | 174 | static inline unsigned int __must_check | 
 | 175 | __kfifo_uint_must_check_helper(unsigned int val) | 
 | 176 | { | 
 | 177 | 	return val; | 
 | 178 | } | 
 | 179 |  | 
 | 180 | static inline int __must_check | 
 | 181 | __kfifo_int_must_check_helper(int val) | 
 | 182 | { | 
 | 183 | 	return val; | 
 | 184 | } | 
| Stefani Seibold | 37bdfbb | 2009-12-21 14:37:30 -0800 | [diff] [blame] | 185 |  | 
 | 186 | /** | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 187 |  * kfifo_initialized - Check if the fifo is initialized | 
 | 188 |  * @fifo: address of the fifo to check | 
| Stefani Seibold | 37bdfbb | 2009-12-21 14:37:30 -0800 | [diff] [blame] | 189 |  * | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 190 |  * Return %true if fifo is initialized, otherwise %false. | 
| Andi Kleen | d994ffc | 2010-01-15 17:01:17 -0800 | [diff] [blame] | 191 |  * Assumes the fifo was 0 before. | 
 | 192 |  */ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 193 | #define kfifo_initialized(fifo) ((fifo)->kfifo.mask) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 194 |  | 
 | 195 | /** | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 196 |  * kfifo_esize - returns the size of the element managed by the fifo | 
 | 197 |  * @fifo: address of the fifo to be used | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 198 |  */ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 199 | #define kfifo_esize(fifo)	((fifo)->kfifo.esize) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 200 |  | 
 | 201 | /** | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 202 |  * kfifo_recsize - returns the size of the record length field | 
 | 203 |  * @fifo: address of the fifo to be used | 
| Stefani Seibold | a121f24 | 2009-12-21 14:37:31 -0800 | [diff] [blame] | 204 |  */ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 205 | #define kfifo_recsize(fifo)	(sizeof(*(fifo)->rectype)) | 
| Stefani Seibold | a121f24 | 2009-12-21 14:37:31 -0800 | [diff] [blame] | 206 |  | 
 | 207 | /** | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 208 |  * kfifo_size - returns the size of the fifo in elements | 
 | 209 |  * @fifo: address of the fifo to be used | 
| Stefani Seibold | 37bdfbb | 2009-12-21 14:37:30 -0800 | [diff] [blame] | 210 |  */ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 211 | #define kfifo_size(fifo)	((fifo)->kfifo.mask + 1) | 
| Stefani Seibold | 37bdfbb | 2009-12-21 14:37:30 -0800 | [diff] [blame] | 212 |  | 
 | 213 | /** | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 214 |  * kfifo_reset - removes the entire fifo content | 
 | 215 |  * @fifo: address of the fifo to be used | 
 | 216 |  * | 
 | 217 |  * Note: usage of kfifo_reset() is dangerous. It should be only called when the | 
 | 218 |  * fifo is exclusived locked or when it is secured that no other thread is | 
 | 219 |  * accessing the fifo. | 
| Stefani Seibold | c1e13f2 | 2009-12-21 14:37:27 -0800 | [diff] [blame] | 220 |  */ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 221 | #define kfifo_reset(fifo) \ | 
 | 222 | (void)({ \ | 
| Huang Ying | e0bf1024 | 2010-09-09 16:37:26 -0700 | [diff] [blame] | 223 | 	typeof((fifo) + 1) __tmp = (fifo); \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 224 | 	__tmp->kfifo.in = __tmp->kfifo.out = 0; \ | 
 | 225 | }) | 
| Stefani Seibold | c1e13f2 | 2009-12-21 14:37:27 -0800 | [diff] [blame] | 226 |  | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 227 | /** | 
 | 228 |  * kfifo_reset_out - skip fifo content | 
 | 229 |  * @fifo: address of the fifo to be used | 
 | 230 |  * | 
 | 231 |  * Note: The usage of kfifo_reset_out() is safe until it will be only called | 
 | 232 |  * from the reader thread and there is only one concurrent reader. Otherwise | 
 | 233 |  * it is dangerous and must be handled in the same way as kfifo_reset(). | 
 | 234 |  */ | 
 | 235 | #define kfifo_reset_out(fifo)	\ | 
 | 236 | (void)({ \ | 
| Huang Ying | e0bf1024 | 2010-09-09 16:37:26 -0700 | [diff] [blame] | 237 | 	typeof((fifo) + 1) __tmp = (fifo); \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 238 | 	__tmp->kfifo.out = __tmp->kfifo.in; \ | 
 | 239 | }) | 
 | 240 |  | 
 | 241 | /** | 
 | 242 |  * kfifo_len - returns the number of used elements in the fifo | 
 | 243 |  * @fifo: address of the fifo to be used | 
 | 244 |  */ | 
 | 245 | #define kfifo_len(fifo) \ | 
 | 246 | ({ \ | 
| Huang Ying | e0bf1024 | 2010-09-09 16:37:26 -0700 | [diff] [blame] | 247 | 	typeof((fifo) + 1) __tmpl = (fifo); \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 248 | 	__tmpl->kfifo.in - __tmpl->kfifo.out; \ | 
 | 249 | }) | 
| Stefani Seibold | c1e13f2 | 2009-12-21 14:37:27 -0800 | [diff] [blame] | 250 |  | 
 | 251 | /** | 
| Stefani Seibold | 37bdfbb | 2009-12-21 14:37:30 -0800 | [diff] [blame] | 252 |  * kfifo_is_empty - returns true if the fifo is empty | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 253 |  * @fifo: address of the fifo to be used | 
| Stefani Seibold | 37bdfbb | 2009-12-21 14:37:30 -0800 | [diff] [blame] | 254 |  */ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 255 | #define	kfifo_is_empty(fifo) \ | 
 | 256 | ({ \ | 
| Huang Ying | e0bf1024 | 2010-09-09 16:37:26 -0700 | [diff] [blame] | 257 | 	typeof((fifo) + 1) __tmpq = (fifo); \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 258 | 	__tmpq->kfifo.in == __tmpq->kfifo.out; \ | 
 | 259 | }) | 
| Stefani Seibold | 37bdfbb | 2009-12-21 14:37:30 -0800 | [diff] [blame] | 260 |  | 
 | 261 | /** | 
 | 262 |  * kfifo_is_full - returns true if the fifo is full | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 263 |  * @fifo: address of the fifo to be used | 
| Stefani Seibold | 37bdfbb | 2009-12-21 14:37:30 -0800 | [diff] [blame] | 264 |  */ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 265 | #define	kfifo_is_full(fifo) \ | 
 | 266 | ({ \ | 
| Huang Ying | e0bf1024 | 2010-09-09 16:37:26 -0700 | [diff] [blame] | 267 | 	typeof((fifo) + 1) __tmpq = (fifo); \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 268 | 	kfifo_len(__tmpq) > __tmpq->kfifo.mask; \ | 
 | 269 | }) | 
| Stefani Seibold | 37bdfbb | 2009-12-21 14:37:30 -0800 | [diff] [blame] | 270 |  | 
 | 271 | /** | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 272 |  * kfifo_avail - returns the number of unused elements in the fifo | 
 | 273 |  * @fifo: address of the fifo to be used | 
| Stefani Seibold | 37bdfbb | 2009-12-21 14:37:30 -0800 | [diff] [blame] | 274 |  */ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 275 | #define	kfifo_avail(fifo) \ | 
| Stefani Seibold | 144ecf3 | 2010-10-27 15:34:50 -0700 | [diff] [blame] | 276 | __kfifo_uint_must_check_helper( \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 277 | ({ \ | 
| Huang Ying | e0bf1024 | 2010-09-09 16:37:26 -0700 | [diff] [blame] | 278 | 	typeof((fifo) + 1) __tmpq = (fifo); \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 279 | 	const size_t __recsize = sizeof(*__tmpq->rectype); \ | 
 | 280 | 	unsigned int __avail = kfifo_size(__tmpq) - kfifo_len(__tmpq); \ | 
 | 281 | 	(__recsize) ? ((__avail <= __recsize) ? 0 : \ | 
 | 282 | 	__kfifo_max_r(__avail - __recsize, __recsize)) : \ | 
 | 283 | 	__avail; \ | 
 | 284 | }) \ | 
 | 285 | ) | 
| Stefani Seibold | 37bdfbb | 2009-12-21 14:37:30 -0800 | [diff] [blame] | 286 |  | 
 | 287 | /** | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 288 |  * kfifo_skip - skip output data | 
 | 289 |  * @fifo: address of the fifo to be used | 
 | 290 |  */ | 
 | 291 | #define	kfifo_skip(fifo) \ | 
 | 292 | (void)({ \ | 
| Huang Ying | e0bf1024 | 2010-09-09 16:37:26 -0700 | [diff] [blame] | 293 | 	typeof((fifo) + 1) __tmp = (fifo); \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 294 | 	const size_t __recsize = sizeof(*__tmp->rectype); \ | 
 | 295 | 	struct __kfifo *__kfifo = &__tmp->kfifo; \ | 
 | 296 | 	if (__recsize) \ | 
 | 297 | 		__kfifo_skip_r(__kfifo, __recsize); \ | 
 | 298 | 	else \ | 
 | 299 | 		__kfifo->out++; \ | 
 | 300 | }) | 
 | 301 |  | 
 | 302 | /** | 
 | 303 |  * kfifo_peek_len - gets the size of the next fifo record | 
 | 304 |  * @fifo: address of the fifo to be used | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 305 |  * | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 306 |  * This function returns the size of the next fifo record in number of bytes. | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 307 |  */ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 308 | #define kfifo_peek_len(fifo) \ | 
| Stefani Seibold | 144ecf3 | 2010-10-27 15:34:50 -0700 | [diff] [blame] | 309 | __kfifo_uint_must_check_helper( \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 310 | ({ \ | 
| Huang Ying | e0bf1024 | 2010-09-09 16:37:26 -0700 | [diff] [blame] | 311 | 	typeof((fifo) + 1) __tmp = (fifo); \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 312 | 	const size_t __recsize = sizeof(*__tmp->rectype); \ | 
 | 313 | 	struct __kfifo *__kfifo = &__tmp->kfifo; \ | 
 | 314 | 	(!__recsize) ? kfifo_len(__tmp) * sizeof(*__tmp->type) : \ | 
 | 315 | 	__kfifo_len_r(__kfifo, __recsize); \ | 
 | 316 | }) \ | 
 | 317 | ) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 318 |  | 
 | 319 | /** | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 320 |  * kfifo_alloc - dynamically allocates a new fifo buffer | 
 | 321 |  * @fifo: pointer to the fifo | 
 | 322 |  * @size: the number of elements in the fifo, this must be a power of 2 | 
 | 323 |  * @gfp_mask: get_free_pages mask, passed to kmalloc() | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 324 |  * | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 325 |  * This macro dynamically allocates a new fifo buffer. | 
 | 326 |  * | 
 | 327 |  * The numer of elements will be rounded-up to a power of 2. | 
 | 328 |  * The fifo will be release with kfifo_free(). | 
 | 329 |  * Return 0 if no error, otherwise an error code. | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 330 |  */ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 331 | #define kfifo_alloc(fifo, size, gfp_mask) \ | 
| Stefani Seibold | 144ecf3 | 2010-10-27 15:34:50 -0700 | [diff] [blame] | 332 | __kfifo_int_must_check_helper( \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 333 | ({ \ | 
| Huang Ying | e0bf1024 | 2010-09-09 16:37:26 -0700 | [diff] [blame] | 334 | 	typeof((fifo) + 1) __tmp = (fifo); \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 335 | 	struct __kfifo *__kfifo = &__tmp->kfifo; \ | 
 | 336 | 	__is_kfifo_ptr(__tmp) ? \ | 
 | 337 | 	__kfifo_alloc(__kfifo, size, sizeof(*__tmp->type), gfp_mask) : \ | 
 | 338 | 	-EINVAL; \ | 
 | 339 | }) \ | 
 | 340 | ) | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 341 |  | 
 | 342 | /** | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 343 |  * kfifo_free - frees the fifo | 
 | 344 |  * @fifo: the fifo to be freed | 
 | 345 |  */ | 
 | 346 | #define kfifo_free(fifo) \ | 
 | 347 | ({ \ | 
| Huang Ying | e0bf1024 | 2010-09-09 16:37:26 -0700 | [diff] [blame] | 348 | 	typeof((fifo) + 1) __tmp = (fifo); \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 349 | 	struct __kfifo *__kfifo = &__tmp->kfifo; \ | 
 | 350 | 	if (__is_kfifo_ptr(__tmp)) \ | 
 | 351 | 		__kfifo_free(__kfifo); \ | 
 | 352 | }) | 
 | 353 |  | 
 | 354 | /** | 
 | 355 |  * kfifo_init - initialize a fifo using a preallocated buffer | 
 | 356 |  * @fifo: the fifo to assign the buffer | 
 | 357 |  * @buffer: the preallocated buffer to be used | 
 | 358 |  * @size: the size of the internal buffer, this have to be a power of 2 | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 359 |  * | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 360 |  * This macro initialize a fifo using a preallocated buffer. | 
 | 361 |  * | 
 | 362 |  * The numer of elements will be rounded-up to a power of 2. | 
 | 363 |  * Return 0 if no error, otherwise an error code. | 
 | 364 |  */ | 
 | 365 | #define kfifo_init(fifo, buffer, size) \ | 
 | 366 | ({ \ | 
| Huang Ying | e0bf1024 | 2010-09-09 16:37:26 -0700 | [diff] [blame] | 367 | 	typeof((fifo) + 1) __tmp = (fifo); \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 368 | 	struct __kfifo *__kfifo = &__tmp->kfifo; \ | 
 | 369 | 	__is_kfifo_ptr(__tmp) ? \ | 
 | 370 | 	__kfifo_init(__kfifo, buffer, size, sizeof(*__tmp->type)) : \ | 
 | 371 | 	-EINVAL; \ | 
 | 372 | }) | 
 | 373 |  | 
 | 374 | /** | 
 | 375 |  * kfifo_put - put data into the fifo | 
 | 376 |  * @fifo: address of the fifo to be used | 
 | 377 |  * @val: the data to be added | 
 | 378 |  * | 
 | 379 |  * This macro copies the given value into the fifo. | 
 | 380 |  * It returns 0 if the fifo was full. Otherwise it returns the number | 
 | 381 |  * processed elements. | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 382 |  * | 
 | 383 |  * Note that with only one concurrent reader and one concurrent | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 384 |  * writer, you don't need extra locking to use these macro. | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 385 |  */ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 386 | #define	kfifo_put(fifo, val) \ | 
 | 387 | ({ \ | 
| Huang Ying | e0bf1024 | 2010-09-09 16:37:26 -0700 | [diff] [blame] | 388 | 	typeof((fifo) + 1) __tmp = (fifo); \ | 
 | 389 | 	typeof((val) + 1) __val = (val); \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 390 | 	unsigned int __ret; \ | 
 | 391 | 	const size_t __recsize = sizeof(*__tmp->rectype); \ | 
 | 392 | 	struct __kfifo *__kfifo = &__tmp->kfifo; \ | 
 | 393 | 	if (0) { \ | 
 | 394 | 		typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \ | 
 | 395 | 		__dummy = (typeof(__val))NULL; \ | 
 | 396 | 	} \ | 
 | 397 | 	if (__recsize) \ | 
 | 398 | 		__ret = __kfifo_in_r(__kfifo, __val, sizeof(*__val), \ | 
 | 399 | 			__recsize); \ | 
 | 400 | 	else { \ | 
 | 401 | 		__ret = !kfifo_is_full(__tmp); \ | 
 | 402 | 		if (__ret) { \ | 
 | 403 | 			(__is_kfifo_ptr(__tmp) ? \ | 
 | 404 | 			((typeof(__tmp->type))__kfifo->data) : \ | 
 | 405 | 			(__tmp->buf) \ | 
 | 406 | 			)[__kfifo->in & __tmp->kfifo.mask] = \ | 
 | 407 | 				*(typeof(__tmp->type))__val; \ | 
 | 408 | 			smp_wmb(); \ | 
 | 409 | 			__kfifo->in++; \ | 
 | 410 | 		} \ | 
 | 411 | 	} \ | 
 | 412 | 	__ret; \ | 
 | 413 | }) | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 414 |  | 
 | 415 | /** | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 416 |  * kfifo_get - get data from the fifo | 
 | 417 |  * @fifo: address of the fifo to be used | 
 | 418 |  * @val: the var where to store the data to be added | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 419 |  * | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 420 |  * This macro reads the data from the fifo. | 
 | 421 |  * It returns 0 if the fifo was empty. Otherwise it returns the number | 
 | 422 |  * processed elements. | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 423 |  * | 
 | 424 |  * Note that with only one concurrent reader and one concurrent | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 425 |  * writer, you don't need extra locking to use these macro. | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 426 |  */ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 427 | #define	kfifo_get(fifo, val) \ | 
| Stefani Seibold | 144ecf3 | 2010-10-27 15:34:50 -0700 | [diff] [blame] | 428 | __kfifo_uint_must_check_helper( \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 429 | ({ \ | 
| Huang Ying | e0bf1024 | 2010-09-09 16:37:26 -0700 | [diff] [blame] | 430 | 	typeof((fifo) + 1) __tmp = (fifo); \ | 
 | 431 | 	typeof((val) + 1) __val = (val); \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 432 | 	unsigned int __ret; \ | 
 | 433 | 	const size_t __recsize = sizeof(*__tmp->rectype); \ | 
 | 434 | 	struct __kfifo *__kfifo = &__tmp->kfifo; \ | 
 | 435 | 	if (0) \ | 
 | 436 | 		__val = (typeof(__tmp->ptr))0; \ | 
 | 437 | 	if (__recsize) \ | 
 | 438 | 		__ret = __kfifo_out_r(__kfifo, __val, sizeof(*__val), \ | 
 | 439 | 			__recsize); \ | 
 | 440 | 	else { \ | 
 | 441 | 		__ret = !kfifo_is_empty(__tmp); \ | 
 | 442 | 		if (__ret) { \ | 
 | 443 | 			*(typeof(__tmp->type))__val = \ | 
 | 444 | 				(__is_kfifo_ptr(__tmp) ? \ | 
 | 445 | 				((typeof(__tmp->type))__kfifo->data) : \ | 
 | 446 | 				(__tmp->buf) \ | 
 | 447 | 				)[__kfifo->out & __tmp->kfifo.mask]; \ | 
 | 448 | 			smp_wmb(); \ | 
 | 449 | 			__kfifo->out++; \ | 
 | 450 | 		} \ | 
 | 451 | 	} \ | 
 | 452 | 	__ret; \ | 
 | 453 | }) \ | 
 | 454 | ) | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 455 |  | 
 | 456 | /** | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 457 |  * kfifo_peek - get data from the fifo without removing | 
 | 458 |  * @fifo: address of the fifo to be used | 
 | 459 |  * @val: the var where to store the data to be added | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 460 |  * | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 461 |  * This reads the data from the fifo without removing it from the fifo. | 
 | 462 |  * It returns 0 if the fifo was empty. Otherwise it returns the number | 
 | 463 |  * processed elements. | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 464 |  * | 
 | 465 |  * Note that with only one concurrent reader and one concurrent | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 466 |  * writer, you don't need extra locking to use these macro. | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 467 |  */ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 468 | #define	kfifo_peek(fifo, val) \ | 
| Stefani Seibold | 144ecf3 | 2010-10-27 15:34:50 -0700 | [diff] [blame] | 469 | __kfifo_uint_must_check_helper( \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 470 | ({ \ | 
| Huang Ying | e0bf1024 | 2010-09-09 16:37:26 -0700 | [diff] [blame] | 471 | 	typeof((fifo) + 1) __tmp = (fifo); \ | 
 | 472 | 	typeof((val) + 1) __val = (val); \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 473 | 	unsigned int __ret; \ | 
 | 474 | 	const size_t __recsize = sizeof(*__tmp->rectype); \ | 
 | 475 | 	struct __kfifo *__kfifo = &__tmp->kfifo; \ | 
 | 476 | 	if (0) \ | 
 | 477 | 		__val = (typeof(__tmp->ptr))NULL; \ | 
 | 478 | 	if (__recsize) \ | 
 | 479 | 		__ret = __kfifo_out_peek_r(__kfifo, __val, sizeof(*__val), \ | 
 | 480 | 			__recsize); \ | 
 | 481 | 	else { \ | 
 | 482 | 		__ret = !kfifo_is_empty(__tmp); \ | 
 | 483 | 		if (__ret) { \ | 
 | 484 | 			*(typeof(__tmp->type))__val = \ | 
 | 485 | 				(__is_kfifo_ptr(__tmp) ? \ | 
 | 486 | 				((typeof(__tmp->type))__kfifo->data) : \ | 
 | 487 | 				(__tmp->buf) \ | 
 | 488 | 				)[__kfifo->out & __tmp->kfifo.mask]; \ | 
 | 489 | 			smp_wmb(); \ | 
 | 490 | 		} \ | 
 | 491 | 	} \ | 
 | 492 | 	__ret; \ | 
 | 493 | }) \ | 
 | 494 | ) | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 495 |  | 
 | 496 | /** | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 497 |  * kfifo_in - put data into the fifo | 
 | 498 |  * @fifo: address of the fifo to be used | 
 | 499 |  * @buf: the data to be added | 
 | 500 |  * @n: number of elements to be added | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 501 |  * | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 502 |  * This macro copies the given buffer into the fifo and returns the | 
 | 503 |  * number of copied elements. | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 504 |  * | 
 | 505 |  * Note that with only one concurrent reader and one concurrent | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 506 |  * writer, you don't need extra locking to use these macro. | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 507 |  */ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 508 | #define	kfifo_in(fifo, buf, n) \ | 
 | 509 | ({ \ | 
| Huang Ying | e0bf1024 | 2010-09-09 16:37:26 -0700 | [diff] [blame] | 510 | 	typeof((fifo) + 1) __tmp = (fifo); \ | 
 | 511 | 	typeof((buf) + 1) __buf = (buf); \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 512 | 	unsigned long __n = (n); \ | 
 | 513 | 	const size_t __recsize = sizeof(*__tmp->rectype); \ | 
 | 514 | 	struct __kfifo *__kfifo = &__tmp->kfifo; \ | 
 | 515 | 	if (0) { \ | 
 | 516 | 		typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \ | 
 | 517 | 		__dummy = (typeof(__buf))NULL; \ | 
 | 518 | 	} \ | 
 | 519 | 	(__recsize) ?\ | 
 | 520 | 	__kfifo_in_r(__kfifo, __buf, __n, __recsize) : \ | 
 | 521 | 	__kfifo_in(__kfifo, __buf, __n); \ | 
 | 522 | }) | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 523 |  | 
 | 524 | /** | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 525 |  * kfifo_in_spinlocked - put data into the fifo using a spinlock for locking | 
 | 526 |  * @fifo: address of the fifo to be used | 
 | 527 |  * @buf: the data to be added | 
 | 528 |  * @n: number of elements to be added | 
 | 529 |  * @lock: pointer to the spinlock to use for locking | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 530 |  * | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 531 |  * This macro copies the given values buffer into the fifo and returns the | 
 | 532 |  * number of copied elements. | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 533 |  */ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 534 | #define	kfifo_in_spinlocked(fifo, buf, n, lock) \ | 
 | 535 | ({ \ | 
 | 536 | 	unsigned long __flags; \ | 
 | 537 | 	unsigned int __ret; \ | 
 | 538 | 	spin_lock_irqsave(lock, __flags); \ | 
 | 539 | 	__ret = kfifo_in(fifo, buf, n); \ | 
 | 540 | 	spin_unlock_irqrestore(lock, __flags); \ | 
 | 541 | 	__ret; \ | 
 | 542 | }) | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 543 |  | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 544 | /* alias for kfifo_in_spinlocked, will be removed in a future release */ | 
 | 545 | #define kfifo_in_locked(fifo, buf, n, lock) \ | 
 | 546 | 		kfifo_in_spinlocked(fifo, buf, n, lock) | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 547 |  | 
 | 548 | /** | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 549 |  * kfifo_out - get data from the fifo | 
 | 550 |  * @fifo: address of the fifo to be used | 
 | 551 |  * @buf: pointer to the storage buffer | 
 | 552 |  * @n: max. number of elements to get | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 553 |  * | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 554 |  * This macro get some data from the fifo and return the numbers of elements | 
 | 555 |  * copied. | 
 | 556 |  * | 
 | 557 |  * Note that with only one concurrent reader and one concurrent | 
 | 558 |  * writer, you don't need extra locking to use these macro. | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 559 |  */ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 560 | #define	kfifo_out(fifo, buf, n) \ | 
| Stefani Seibold | 144ecf3 | 2010-10-27 15:34:50 -0700 | [diff] [blame] | 561 | __kfifo_uint_must_check_helper( \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 562 | ({ \ | 
| Huang Ying | e0bf1024 | 2010-09-09 16:37:26 -0700 | [diff] [blame] | 563 | 	typeof((fifo) + 1) __tmp = (fifo); \ | 
 | 564 | 	typeof((buf) + 1) __buf = (buf); \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 565 | 	unsigned long __n = (n); \ | 
 | 566 | 	const size_t __recsize = sizeof(*__tmp->rectype); \ | 
 | 567 | 	struct __kfifo *__kfifo = &__tmp->kfifo; \ | 
 | 568 | 	if (0) { \ | 
 | 569 | 		typeof(__tmp->ptr) __dummy = NULL; \ | 
 | 570 | 		__buf = __dummy; \ | 
 | 571 | 	} \ | 
 | 572 | 	(__recsize) ?\ | 
 | 573 | 	__kfifo_out_r(__kfifo, __buf, __n, __recsize) : \ | 
 | 574 | 	__kfifo_out(__kfifo, __buf, __n); \ | 
 | 575 | }) \ | 
 | 576 | ) | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 577 |  | 
 | 578 | /** | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 579 |  * kfifo_out_spinlocked - get data from the fifo using a spinlock for locking | 
 | 580 |  * @fifo: address of the fifo to be used | 
 | 581 |  * @buf: pointer to the storage buffer | 
 | 582 |  * @n: max. number of elements to get | 
 | 583 |  * @lock: pointer to the spinlock to use for locking | 
 | 584 |  * | 
 | 585 |  * This macro get the data from the fifo and return the numbers of elements | 
 | 586 |  * copied. | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 587 |  */ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 588 | #define	kfifo_out_spinlocked(fifo, buf, n, lock) \ | 
| Stefani Seibold | 144ecf3 | 2010-10-27 15:34:50 -0700 | [diff] [blame] | 589 | __kfifo_uint_must_check_helper( \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 590 | ({ \ | 
 | 591 | 	unsigned long __flags; \ | 
 | 592 | 	unsigned int __ret; \ | 
 | 593 | 	spin_lock_irqsave(lock, __flags); \ | 
 | 594 | 	__ret = kfifo_out(fifo, buf, n); \ | 
 | 595 | 	spin_unlock_irqrestore(lock, __flags); \ | 
 | 596 | 	__ret; \ | 
 | 597 | }) \ | 
 | 598 | ) | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 599 |  | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 600 | /* alias for kfifo_out_spinlocked, will be removed in a future release */ | 
 | 601 | #define kfifo_out_locked(fifo, buf, n, lock) \ | 
 | 602 | 		kfifo_out_spinlocked(fifo, buf, n, lock) | 
 | 603 |  | 
 | 604 | /** | 
 | 605 |  * kfifo_from_user - puts some data from user space into the fifo | 
 | 606 |  * @fifo: address of the fifo to be used | 
 | 607 |  * @from: pointer to the data to be added | 
 | 608 |  * @len: the length of the data to be added | 
 | 609 |  * @copied: pointer to output variable to store the number of copied bytes | 
 | 610 |  * | 
 | 611 |  * This macro copies at most @len bytes from the @from into the | 
 | 612 |  * fifo, depending of the available space and returns -EFAULT/0. | 
 | 613 |  * | 
 | 614 |  * Note that with only one concurrent reader and one concurrent | 
 | 615 |  * writer, you don't need extra locking to use these macro. | 
 | 616 |  */ | 
 | 617 | #define	kfifo_from_user(fifo, from, len, copied) \ | 
| Stefani Seibold | 144ecf3 | 2010-10-27 15:34:50 -0700 | [diff] [blame] | 618 | __kfifo_uint_must_check_helper( \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 619 | ({ \ | 
| Huang Ying | e0bf1024 | 2010-09-09 16:37:26 -0700 | [diff] [blame] | 620 | 	typeof((fifo) + 1) __tmp = (fifo); \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 621 | 	const void __user *__from = (from); \ | 
 | 622 | 	unsigned int __len = (len); \ | 
 | 623 | 	unsigned int *__copied = (copied); \ | 
 | 624 | 	const size_t __recsize = sizeof(*__tmp->rectype); \ | 
 | 625 | 	struct __kfifo *__kfifo = &__tmp->kfifo; \ | 
 | 626 | 	(__recsize) ? \ | 
 | 627 | 	__kfifo_from_user_r(__kfifo, __from, __len,  __copied, __recsize) : \ | 
 | 628 | 	__kfifo_from_user(__kfifo, __from, __len, __copied); \ | 
 | 629 | }) \ | 
 | 630 | ) | 
 | 631 |  | 
 | 632 | /** | 
 | 633 |  * kfifo_to_user - copies data from the fifo into user space | 
 | 634 |  * @fifo: address of the fifo to be used | 
 | 635 |  * @to: where the data must be copied | 
 | 636 |  * @len: the size of the destination buffer | 
 | 637 |  * @copied: pointer to output variable to store the number of copied bytes | 
 | 638 |  * | 
 | 639 |  * This macro copies at most @len bytes from the fifo into the | 
 | 640 |  * @to buffer and returns -EFAULT/0. | 
 | 641 |  * | 
 | 642 |  * Note that with only one concurrent reader and one concurrent | 
 | 643 |  * writer, you don't need extra locking to use these macro. | 
 | 644 |  */ | 
 | 645 | #define	kfifo_to_user(fifo, to, len, copied) \ | 
| Stefani Seibold | 144ecf3 | 2010-10-27 15:34:50 -0700 | [diff] [blame] | 646 | __kfifo_uint_must_check_helper( \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 647 | ({ \ | 
| Huang Ying | e0bf1024 | 2010-09-09 16:37:26 -0700 | [diff] [blame] | 648 | 	typeof((fifo) + 1) __tmp = (fifo); \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 649 | 	void __user *__to = (to); \ | 
 | 650 | 	unsigned int __len = (len); \ | 
 | 651 | 	unsigned int *__copied = (copied); \ | 
 | 652 | 	const size_t __recsize = sizeof(*__tmp->rectype); \ | 
 | 653 | 	struct __kfifo *__kfifo = &__tmp->kfifo; \ | 
 | 654 | 	(__recsize) ? \ | 
 | 655 | 	__kfifo_to_user_r(__kfifo, __to, __len, __copied, __recsize) : \ | 
 | 656 | 	__kfifo_to_user(__kfifo, __to, __len, __copied); \ | 
 | 657 | }) \ | 
 | 658 | ) | 
 | 659 |  | 
 | 660 | /** | 
 | 661 |  * kfifo_dma_in_prepare - setup a scatterlist for DMA input | 
 | 662 |  * @fifo: address of the fifo to be used | 
 | 663 |  * @sgl: pointer to the scatterlist array | 
 | 664 |  * @nents: number of entries in the scatterlist array | 
 | 665 |  * @len: number of elements to transfer | 
 | 666 |  * | 
 | 667 |  * This macro fills a scatterlist for DMA input. | 
 | 668 |  * It returns the number entries in the scatterlist array. | 
 | 669 |  * | 
 | 670 |  * Note that with only one concurrent reader and one concurrent | 
 | 671 |  * writer, you don't need extra locking to use these macros. | 
 | 672 |  */ | 
 | 673 | #define	kfifo_dma_in_prepare(fifo, sgl, nents, len) \ | 
 | 674 | ({ \ | 
| Huang Ying | e0bf1024 | 2010-09-09 16:37:26 -0700 | [diff] [blame] | 675 | 	typeof((fifo) + 1) __tmp = (fifo); \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 676 | 	struct scatterlist *__sgl = (sgl); \ | 
 | 677 | 	int __nents = (nents); \ | 
 | 678 | 	unsigned int __len = (len); \ | 
 | 679 | 	const size_t __recsize = sizeof(*__tmp->rectype); \ | 
 | 680 | 	struct __kfifo *__kfifo = &__tmp->kfifo; \ | 
 | 681 | 	(__recsize) ? \ | 
 | 682 | 	__kfifo_dma_in_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \ | 
 | 683 | 	__kfifo_dma_in_prepare(__kfifo, __sgl, __nents, __len); \ | 
 | 684 | }) | 
 | 685 |  | 
 | 686 | /** | 
 | 687 |  * kfifo_dma_in_finish - finish a DMA IN operation | 
 | 688 |  * @fifo: address of the fifo to be used | 
 | 689 |  * @len: number of bytes to received | 
 | 690 |  * | 
 | 691 |  * This macro finish a DMA IN operation. The in counter will be updated by | 
 | 692 |  * the len parameter. No error checking will be done. | 
 | 693 |  * | 
 | 694 |  * Note that with only one concurrent reader and one concurrent | 
 | 695 |  * writer, you don't need extra locking to use these macros. | 
 | 696 |  */ | 
 | 697 | #define kfifo_dma_in_finish(fifo, len) \ | 
 | 698 | (void)({ \ | 
| Huang Ying | e0bf1024 | 2010-09-09 16:37:26 -0700 | [diff] [blame] | 699 | 	typeof((fifo) + 1) __tmp = (fifo); \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 700 | 	unsigned int __len = (len); \ | 
 | 701 | 	const size_t __recsize = sizeof(*__tmp->rectype); \ | 
 | 702 | 	struct __kfifo *__kfifo = &__tmp->kfifo; \ | 
 | 703 | 	if (__recsize) \ | 
 | 704 | 		__kfifo_dma_in_finish_r(__kfifo, __len, __recsize); \ | 
 | 705 | 	else \ | 
 | 706 | 		__kfifo->in += __len / sizeof(*__tmp->type); \ | 
 | 707 | }) | 
 | 708 |  | 
 | 709 | /** | 
 | 710 |  * kfifo_dma_out_prepare - setup a scatterlist for DMA output | 
 | 711 |  * @fifo: address of the fifo to be used | 
 | 712 |  * @sgl: pointer to the scatterlist array | 
 | 713 |  * @nents: number of entries in the scatterlist array | 
 | 714 |  * @len: number of elements to transfer | 
 | 715 |  * | 
 | 716 |  * This macro fills a scatterlist for DMA output which at most @len bytes | 
 | 717 |  * to transfer. | 
 | 718 |  * It returns the number entries in the scatterlist array. | 
 | 719 |  * A zero means there is no space available and the scatterlist is not filled. | 
 | 720 |  * | 
 | 721 |  * Note that with only one concurrent reader and one concurrent | 
 | 722 |  * writer, you don't need extra locking to use these macros. | 
 | 723 |  */ | 
 | 724 | #define	kfifo_dma_out_prepare(fifo, sgl, nents, len) \ | 
 | 725 | ({ \ | 
| Huang Ying | e0bf1024 | 2010-09-09 16:37:26 -0700 | [diff] [blame] | 726 | 	typeof((fifo) + 1) __tmp = (fifo);  \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 727 | 	struct scatterlist *__sgl = (sgl); \ | 
 | 728 | 	int __nents = (nents); \ | 
 | 729 | 	unsigned int __len = (len); \ | 
 | 730 | 	const size_t __recsize = sizeof(*__tmp->rectype); \ | 
 | 731 | 	struct __kfifo *__kfifo = &__tmp->kfifo; \ | 
 | 732 | 	(__recsize) ? \ | 
 | 733 | 	__kfifo_dma_out_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \ | 
 | 734 | 	__kfifo_dma_out_prepare(__kfifo, __sgl, __nents, __len); \ | 
 | 735 | }) | 
 | 736 |  | 
 | 737 | /** | 
 | 738 |  * kfifo_dma_out_finish - finish a DMA OUT operation | 
 | 739 |  * @fifo: address of the fifo to be used | 
 | 740 |  * @len: number of bytes transferd | 
 | 741 |  * | 
 | 742 |  * This macro finish a DMA OUT operation. The out counter will be updated by | 
 | 743 |  * the len parameter. No error checking will be done. | 
 | 744 |  * | 
 | 745 |  * Note that with only one concurrent reader and one concurrent | 
 | 746 |  * writer, you don't need extra locking to use these macros. | 
 | 747 |  */ | 
 | 748 | #define kfifo_dma_out_finish(fifo, len) \ | 
 | 749 | (void)({ \ | 
| Huang Ying | e0bf1024 | 2010-09-09 16:37:26 -0700 | [diff] [blame] | 750 | 	typeof((fifo) + 1) __tmp = (fifo); \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 751 | 	unsigned int __len = (len); \ | 
 | 752 | 	const size_t __recsize = sizeof(*__tmp->rectype); \ | 
 | 753 | 	struct __kfifo *__kfifo = &__tmp->kfifo; \ | 
 | 754 | 	if (__recsize) \ | 
 | 755 | 		__kfifo_dma_out_finish_r(__kfifo, __recsize); \ | 
 | 756 | 	else \ | 
 | 757 | 		__kfifo->out += __len / sizeof(*__tmp->type); \ | 
 | 758 | }) | 
 | 759 |  | 
 | 760 | /** | 
 | 761 |  * kfifo_out_peek - gets some data from the fifo | 
 | 762 |  * @fifo: address of the fifo to be used | 
 | 763 |  * @buf: pointer to the storage buffer | 
 | 764 |  * @n: max. number of elements to get | 
 | 765 |  * | 
 | 766 |  * This macro get the data from the fifo and return the numbers of elements | 
 | 767 |  * copied. The data is not removed from the fifo. | 
 | 768 |  * | 
 | 769 |  * Note that with only one concurrent reader and one concurrent | 
 | 770 |  * writer, you don't need extra locking to use these macro. | 
 | 771 |  */ | 
 | 772 | #define	kfifo_out_peek(fifo, buf, n) \ | 
| Stefani Seibold | 144ecf3 | 2010-10-27 15:34:50 -0700 | [diff] [blame] | 773 | __kfifo_uint_must_check_helper( \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 774 | ({ \ | 
| Huang Ying | e0bf1024 | 2010-09-09 16:37:26 -0700 | [diff] [blame] | 775 | 	typeof((fifo) + 1) __tmp = (fifo); \ | 
 | 776 | 	typeof((buf) + 1) __buf = (buf); \ | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 777 | 	unsigned long __n = (n); \ | 
 | 778 | 	const size_t __recsize = sizeof(*__tmp->rectype); \ | 
 | 779 | 	struct __kfifo *__kfifo = &__tmp->kfifo; \ | 
 | 780 | 	if (0) { \ | 
 | 781 | 		typeof(__tmp->ptr) __dummy __attribute__ ((unused)) = NULL; \ | 
 | 782 | 		__buf = __dummy; \ | 
 | 783 | 	} \ | 
 | 784 | 	(__recsize) ? \ | 
 | 785 | 	__kfifo_out_peek_r(__kfifo, __buf, __n, __recsize) : \ | 
 | 786 | 	__kfifo_out_peek(__kfifo, __buf, __n); \ | 
 | 787 | }) \ | 
 | 788 | ) | 
 | 789 |  | 
 | 790 | extern int __kfifo_alloc(struct __kfifo *fifo, unsigned int size, | 
 | 791 | 	size_t esize, gfp_t gfp_mask); | 
 | 792 |  | 
 | 793 | extern void __kfifo_free(struct __kfifo *fifo); | 
 | 794 |  | 
 | 795 | extern int __kfifo_init(struct __kfifo *fifo, void *buffer, | 
 | 796 | 	unsigned int size, size_t esize); | 
 | 797 |  | 
 | 798 | extern unsigned int __kfifo_in(struct __kfifo *fifo, | 
 | 799 | 	const void *buf, unsigned int len); | 
 | 800 |  | 
 | 801 | extern unsigned int __kfifo_out(struct __kfifo *fifo, | 
 | 802 | 	void *buf, unsigned int len); | 
 | 803 |  | 
 | 804 | extern int __kfifo_from_user(struct __kfifo *fifo, | 
 | 805 | 	const void __user *from, unsigned long len, unsigned int *copied); | 
 | 806 |  | 
 | 807 | extern int __kfifo_to_user(struct __kfifo *fifo, | 
 | 808 | 	void __user *to, unsigned long len, unsigned int *copied); | 
 | 809 |  | 
 | 810 | extern unsigned int __kfifo_dma_in_prepare(struct __kfifo *fifo, | 
 | 811 | 	struct scatterlist *sgl, int nents, unsigned int len); | 
 | 812 |  | 
 | 813 | extern unsigned int __kfifo_dma_out_prepare(struct __kfifo *fifo, | 
 | 814 | 	struct scatterlist *sgl, int nents, unsigned int len); | 
 | 815 |  | 
 | 816 | extern unsigned int __kfifo_out_peek(struct __kfifo *fifo, | 
 | 817 | 	void *buf, unsigned int len); | 
 | 818 |  | 
 | 819 | extern unsigned int __kfifo_in_r(struct __kfifo *fifo, | 
 | 820 | 	const void *buf, unsigned int len, size_t recsize); | 
 | 821 |  | 
 | 822 | extern unsigned int __kfifo_out_r(struct __kfifo *fifo, | 
 | 823 | 	void *buf, unsigned int len, size_t recsize); | 
 | 824 |  | 
 | 825 | extern int __kfifo_from_user_r(struct __kfifo *fifo, | 
 | 826 | 	const void __user *from, unsigned long len, unsigned int *copied, | 
 | 827 | 	size_t recsize); | 
 | 828 |  | 
 | 829 | extern int __kfifo_to_user_r(struct __kfifo *fifo, void __user *to, | 
 | 830 | 	unsigned long len, unsigned int *copied, size_t recsize); | 
 | 831 |  | 
 | 832 | extern unsigned int __kfifo_dma_in_prepare_r(struct __kfifo *fifo, | 
 | 833 | 	struct scatterlist *sgl, int nents, unsigned int len, size_t recsize); | 
 | 834 |  | 
 | 835 | extern void __kfifo_dma_in_finish_r(struct __kfifo *fifo, | 
 | 836 | 	unsigned int len, size_t recsize); | 
 | 837 |  | 
 | 838 | extern unsigned int __kfifo_dma_out_prepare_r(struct __kfifo *fifo, | 
 | 839 | 	struct scatterlist *sgl, int nents, unsigned int len, size_t recsize); | 
 | 840 |  | 
 | 841 | extern void __kfifo_dma_out_finish_r(struct __kfifo *fifo, size_t recsize); | 
 | 842 |  | 
 | 843 | extern unsigned int __kfifo_len_r(struct __kfifo *fifo, size_t recsize); | 
 | 844 |  | 
| Andrea Righi | b35de43 | 2010-08-19 14:13:27 -0700 | [diff] [blame] | 845 | extern void __kfifo_skip_r(struct __kfifo *fifo, size_t recsize); | 
 | 846 |  | 
| Stefani Seibold | 2e956fb | 2010-08-10 18:03:38 -0700 | [diff] [blame] | 847 | extern unsigned int __kfifo_out_peek_r(struct __kfifo *fifo, | 
 | 848 | 	void *buf, unsigned int len, size_t recsize); | 
 | 849 |  | 
 | 850 | extern unsigned int __kfifo_max_r(unsigned int len, size_t recsize); | 
| Stefani Seibold | 86d4880 | 2009-12-21 14:37:32 -0800 | [diff] [blame] | 851 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 852 | #endif |