1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#ifndef _LINUX_KFIFO_H
23#define _LINUX_KFIFO_H
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53#include <linux/kernel.h>
54#include <linux/spinlock.h>
55#include <linux/stddef.h>
56#include <linux/scatterlist.h>
57
58struct __kfifo {
59 unsigned int in;
60 unsigned int out;
61 unsigned int mask;
62 unsigned int esize;
63 void *data;
64};
65
66#define __STRUCT_KFIFO_COMMON(datatype, recsize, ptrtype) \
67 union { \
68 struct __kfifo kfifo; \
69 datatype *type; \
70 const datatype *const_type; \
71 char (*rectype)[recsize]; \
72 ptrtype *ptr; \
73 ptrtype const *ptr_const; \
74 }
75
76#define __STRUCT_KFIFO(type, size, recsize, ptrtype) \
77{ \
78 __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \
79 type buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \
80}
81
82#define STRUCT_KFIFO(type, size) \
83 struct __STRUCT_KFIFO(type, size, 0, type)
84
85#define __STRUCT_KFIFO_PTR(type, recsize, ptrtype) \
86{ \
87 __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \
88 type buf[0]; \
89}
90
91#define STRUCT_KFIFO_PTR(type) \
92 struct __STRUCT_KFIFO_PTR(type, 0, type)
93
94
95
96
97struct kfifo __STRUCT_KFIFO_PTR(unsigned char, 0, void);
98
99#define STRUCT_KFIFO_REC_1(size) \
100 struct __STRUCT_KFIFO(unsigned char, size, 1, void)
101
102#define STRUCT_KFIFO_REC_2(size) \
103 struct __STRUCT_KFIFO(unsigned char, size, 2, void)
104
105
106
107
108struct kfifo_rec_ptr_1 __STRUCT_KFIFO_PTR(unsigned char, 1, void);
109struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2, void);
110
111
112
113
114
115
116#define __is_kfifo_ptr(fifo) (sizeof(*fifo) == sizeof(struct __kfifo))
117
118
119
120
121
122
123#define DECLARE_KFIFO_PTR(fifo, type) STRUCT_KFIFO_PTR(type) fifo
124
125
126
127
128
129
130
131#define DECLARE_KFIFO(fifo, type, size) STRUCT_KFIFO(type, size) fifo
132
133
134
135
136
137#define INIT_KFIFO(fifo) \
138(void)({ \
139 typeof(&(fifo)) __tmp = &(fifo); \
140 struct __kfifo *__kfifo = &__tmp->kfifo; \
141 __kfifo->in = 0; \
142 __kfifo->out = 0; \
143 __kfifo->mask = __is_kfifo_ptr(__tmp) ? 0 : ARRAY_SIZE(__tmp->buf) - 1;\
144 __kfifo->esize = sizeof(*__tmp->buf); \
145 __kfifo->data = __is_kfifo_ptr(__tmp) ? NULL : __tmp->buf; \
146})
147
148
149
150
151
152
153
154
155
156#define DEFINE_KFIFO(fifo, type, size) \
157 DECLARE_KFIFO(fifo, type, size) = \
158 (typeof(fifo)) { \
159 { \
160 { \
161 .in = 0, \
162 .out = 0, \
163 .mask = __is_kfifo_ptr(&(fifo)) ? \
164 0 : \
165 ARRAY_SIZE((fifo).buf) - 1, \
166 .esize = sizeof(*(fifo).buf), \
167 .data = __is_kfifo_ptr(&(fifo)) ? \
168 NULL : \
169 (fifo).buf, \
170 } \
171 } \
172 }
173
174
175static inline unsigned int __must_check
176__kfifo_uint_must_check_helper(unsigned int val)
177{
178 return val;
179}
180
181static inline int __must_check
182__kfifo_int_must_check_helper(int val)
183{
184 return val;
185}
186
187
188
189
190
191
192
193
194#define kfifo_initialized(fifo) ((fifo)->kfifo.mask)
195
196
197
198
199
200#define kfifo_esize(fifo) ((fifo)->kfifo.esize)
201
202
203
204
205
206#define kfifo_recsize(fifo) (sizeof(*(fifo)->rectype))
207
208
209
210
211
212#define kfifo_size(fifo) ((fifo)->kfifo.mask + 1)
213
214
215
216
217
218
219
220
221
222#define kfifo_reset(fifo) \
223(void)({ \
224 typeof((fifo) + 1) __tmp = (fifo); \
225 __tmp->kfifo.in = __tmp->kfifo.out = 0; \
226})
227
228
229
230
231
232
233
234
235
236#define kfifo_reset_out(fifo) \
237(void)({ \
238 typeof((fifo) + 1) __tmp = (fifo); \
239 __tmp->kfifo.out = __tmp->kfifo.in; \
240})
241
242
243
244
245
246#define kfifo_len(fifo) \
247({ \
248 typeof((fifo) + 1) __tmpl = (fifo); \
249 __tmpl->kfifo.in - __tmpl->kfifo.out; \
250})
251
252
253
254
255
256#define kfifo_is_empty(fifo) \
257({ \
258 typeof((fifo) + 1) __tmpq = (fifo); \
259 __tmpq->kfifo.in == __tmpq->kfifo.out; \
260})
261
262
263
264
265
266#define kfifo_is_full(fifo) \
267({ \
268 typeof((fifo) + 1) __tmpq = (fifo); \
269 kfifo_len(__tmpq) > __tmpq->kfifo.mask; \
270})
271
272
273
274
275
276#define kfifo_avail(fifo) \
277__kfifo_uint_must_check_helper( \
278({ \
279 typeof((fifo) + 1) __tmpq = (fifo); \
280 const size_t __recsize = sizeof(*__tmpq->rectype); \
281 unsigned int __avail = kfifo_size(__tmpq) - kfifo_len(__tmpq); \
282 (__recsize) ? ((__avail <= __recsize) ? 0 : \
283 __kfifo_max_r(__avail - __recsize, __recsize)) : \
284 __avail; \
285}) \
286)
287
288
289
290
291
292#define kfifo_skip(fifo) \
293(void)({ \
294 typeof((fifo) + 1) __tmp = (fifo); \
295 const size_t __recsize = sizeof(*__tmp->rectype); \
296 struct __kfifo *__kfifo = &__tmp->kfifo; \
297 if (__recsize) \
298 __kfifo_skip_r(__kfifo, __recsize); \
299 else \
300 __kfifo->out++; \
301})
302
303
304
305
306
307
308
309#define kfifo_peek_len(fifo) \
310__kfifo_uint_must_check_helper( \
311({ \
312 typeof((fifo) + 1) __tmp = (fifo); \
313 const size_t __recsize = sizeof(*__tmp->rectype); \
314 struct __kfifo *__kfifo = &__tmp->kfifo; \
315 (!__recsize) ? kfifo_len(__tmp) * sizeof(*__tmp->type) : \
316 __kfifo_len_r(__kfifo, __recsize); \
317}) \
318)
319
320
321
322
323
324
325
326
327
328
329
330
331
332#define kfifo_alloc(fifo, size, gfp_mask) \
333__kfifo_int_must_check_helper( \
334({ \
335 typeof((fifo) + 1) __tmp = (fifo); \
336 struct __kfifo *__kfifo = &__tmp->kfifo; \
337 __is_kfifo_ptr(__tmp) ? \
338 __kfifo_alloc(__kfifo, size, sizeof(*__tmp->type), gfp_mask) : \
339 -EINVAL; \
340}) \
341)
342
343
344
345
346
347#define kfifo_free(fifo) \
348({ \
349 typeof((fifo) + 1) __tmp = (fifo); \
350 struct __kfifo *__kfifo = &__tmp->kfifo; \
351 if (__is_kfifo_ptr(__tmp)) \
352 __kfifo_free(__kfifo); \
353})
354
355
356
357
358
359
360
361
362
363
364
365
366#define kfifo_init(fifo, buffer, size) \
367({ \
368 typeof((fifo) + 1) __tmp = (fifo); \
369 struct __kfifo *__kfifo = &__tmp->kfifo; \
370 __is_kfifo_ptr(__tmp) ? \
371 __kfifo_init(__kfifo, buffer, size, sizeof(*__tmp->type)) : \
372 -EINVAL; \
373})
374
375
376
377
378
379
380
381
382
383
384
385
386
387#define kfifo_put(fifo, val) \
388({ \
389 typeof((fifo) + 1) __tmp = (fifo); \
390 typeof(*__tmp->const_type) __val = (val); \
391 unsigned int __ret; \
392 size_t __recsize = sizeof(*__tmp->rectype); \
393 struct __kfifo *__kfifo = &__tmp->kfifo; \
394 if (__recsize) \
395 __ret = __kfifo_in_r(__kfifo, &__val, sizeof(__val), \
396 __recsize); \
397 else { \
398 __ret = !kfifo_is_full(__tmp); \
399 if (__ret) { \
400 (__is_kfifo_ptr(__tmp) ? \
401 ((typeof(__tmp->type))__kfifo->data) : \
402 (__tmp->buf) \
403 )[__kfifo->in & __tmp->kfifo.mask] = \
404 *(typeof(__tmp->type))&__val; \
405 smp_wmb(); \
406 __kfifo->in++; \
407 } \
408 } \
409 __ret; \
410})
411
412
413
414
415
416
417
418
419
420
421
422
423
424#define kfifo_get(fifo, val) \
425__kfifo_uint_must_check_helper( \
426({ \
427 typeof((fifo) + 1) __tmp = (fifo); \
428 typeof(__tmp->ptr) __val = (val); \
429 unsigned int __ret; \
430 const size_t __recsize = sizeof(*__tmp->rectype); \
431 struct __kfifo *__kfifo = &__tmp->kfifo; \
432 if (__recsize) \
433 __ret = __kfifo_out_r(__kfifo, __val, sizeof(*__val), \
434 __recsize); \
435 else { \
436 __ret = !kfifo_is_empty(__tmp); \
437 if (__ret) { \
438 *(typeof(__tmp->type))__val = \
439 (__is_kfifo_ptr(__tmp) ? \
440 ((typeof(__tmp->type))__kfifo->data) : \
441 (__tmp->buf) \
442 )[__kfifo->out & __tmp->kfifo.mask]; \
443 smp_wmb(); \
444 __kfifo->out++; \
445 } \
446 } \
447 __ret; \
448}) \
449)
450
451
452
453
454
455
456
457
458
459
460
461
462
463#define kfifo_peek(fifo, val) \
464__kfifo_uint_must_check_helper( \
465({ \
466 typeof((fifo) + 1) __tmp = (fifo); \
467 typeof(__tmp->ptr) __val = (val); \
468 unsigned int __ret; \
469 const size_t __recsize = sizeof(*__tmp->rectype); \
470 struct __kfifo *__kfifo = &__tmp->kfifo; \
471 if (__recsize) \
472 __ret = __kfifo_out_peek_r(__kfifo, __val, sizeof(*__val), \
473 __recsize); \
474 else { \
475 __ret = !kfifo_is_empty(__tmp); \
476 if (__ret) { \
477 *(typeof(__tmp->type))__val = \
478 (__is_kfifo_ptr(__tmp) ? \
479 ((typeof(__tmp->type))__kfifo->data) : \
480 (__tmp->buf) \
481 )[__kfifo->out & __tmp->kfifo.mask]; \
482 smp_wmb(); \
483 } \
484 } \
485 __ret; \
486}) \
487)
488
489
490
491
492
493
494
495
496
497
498
499
500
501#define kfifo_in(fifo, buf, n) \
502({ \
503 typeof((fifo) + 1) __tmp = (fifo); \
504 typeof(__tmp->ptr_const) __buf = (buf); \
505 unsigned long __n = (n); \
506 const size_t __recsize = sizeof(*__tmp->rectype); \
507 struct __kfifo *__kfifo = &__tmp->kfifo; \
508 (__recsize) ?\
509 __kfifo_in_r(__kfifo, __buf, __n, __recsize) : \
510 __kfifo_in(__kfifo, __buf, __n); \
511})
512
513
514
515
516
517
518
519
520
521
522
523#define kfifo_in_spinlocked(fifo, buf, n, lock) \
524({ \
525 unsigned long __flags; \
526 unsigned int __ret; \
527 spin_lock_irqsave(lock, __flags); \
528 __ret = kfifo_in(fifo, buf, n); \
529 spin_unlock_irqrestore(lock, __flags); \
530 __ret; \
531})
532
533
534#define kfifo_in_locked(fifo, buf, n, lock) \
535 kfifo_in_spinlocked(fifo, buf, n, lock)
536
537
538
539
540
541
542
543
544
545
546
547
548
549#define kfifo_out(fifo, buf, n) \
550__kfifo_uint_must_check_helper( \
551({ \
552 typeof((fifo) + 1) __tmp = (fifo); \
553 typeof(__tmp->ptr) __buf = (buf); \
554 unsigned long __n = (n); \
555 const size_t __recsize = sizeof(*__tmp->rectype); \
556 struct __kfifo *__kfifo = &__tmp->kfifo; \
557 (__recsize) ?\
558 __kfifo_out_r(__kfifo, __buf, __n, __recsize) : \
559 __kfifo_out(__kfifo, __buf, __n); \
560}) \
561)
562
563
564
565
566
567
568
569
570
571
572
573#define kfifo_out_spinlocked(fifo, buf, n, lock) \
574__kfifo_uint_must_check_helper( \
575({ \
576 unsigned long __flags; \
577 unsigned int __ret; \
578 spin_lock_irqsave(lock, __flags); \
579 __ret = kfifo_out(fifo, buf, n); \
580 spin_unlock_irqrestore(lock, __flags); \
581 __ret; \
582}) \
583)
584
585
586#define kfifo_out_locked(fifo, buf, n, lock) \
587 kfifo_out_spinlocked(fifo, buf, n, lock)
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602#define kfifo_from_user(fifo, from, len, copied) \
603__kfifo_uint_must_check_helper( \
604({ \
605 typeof((fifo) + 1) __tmp = (fifo); \
606 const void __user *__from = (from); \
607 unsigned int __len = (len); \
608 unsigned int *__copied = (copied); \
609 const size_t __recsize = sizeof(*__tmp->rectype); \
610 struct __kfifo *__kfifo = &__tmp->kfifo; \
611 (__recsize) ? \
612 __kfifo_from_user_r(__kfifo, __from, __len, __copied, __recsize) : \
613 __kfifo_from_user(__kfifo, __from, __len, __copied); \
614}) \
615)
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630#define kfifo_to_user(fifo, to, len, copied) \
631__kfifo_uint_must_check_helper( \
632({ \
633 typeof((fifo) + 1) __tmp = (fifo); \
634 void __user *__to = (to); \
635 unsigned int __len = (len); \
636 unsigned int *__copied = (copied); \
637 const size_t __recsize = sizeof(*__tmp->rectype); \
638 struct __kfifo *__kfifo = &__tmp->kfifo; \
639 (__recsize) ? \
640 __kfifo_to_user_r(__kfifo, __to, __len, __copied, __recsize) : \
641 __kfifo_to_user(__kfifo, __to, __len, __copied); \
642}) \
643)
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658#define kfifo_dma_in_prepare(fifo, sgl, nents, len) \
659({ \
660 typeof((fifo) + 1) __tmp = (fifo); \
661 struct scatterlist *__sgl = (sgl); \
662 int __nents = (nents); \
663 unsigned int __len = (len); \
664 const size_t __recsize = sizeof(*__tmp->rectype); \
665 struct __kfifo *__kfifo = &__tmp->kfifo; \
666 (__recsize) ? \
667 __kfifo_dma_in_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \
668 __kfifo_dma_in_prepare(__kfifo, __sgl, __nents, __len); \
669})
670
671
672
673
674
675
676
677
678
679
680
681
682#define kfifo_dma_in_finish(fifo, len) \
683(void)({ \
684 typeof((fifo) + 1) __tmp = (fifo); \
685 unsigned int __len = (len); \
686 const size_t __recsize = sizeof(*__tmp->rectype); \
687 struct __kfifo *__kfifo = &__tmp->kfifo; \
688 if (__recsize) \
689 __kfifo_dma_in_finish_r(__kfifo, __len, __recsize); \
690 else \
691 __kfifo->in += __len / sizeof(*__tmp->type); \
692})
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709#define kfifo_dma_out_prepare(fifo, sgl, nents, len) \
710({ \
711 typeof((fifo) + 1) __tmp = (fifo); \
712 struct scatterlist *__sgl = (sgl); \
713 int __nents = (nents); \
714 unsigned int __len = (len); \
715 const size_t __recsize = sizeof(*__tmp->rectype); \
716 struct __kfifo *__kfifo = &__tmp->kfifo; \
717 (__recsize) ? \
718 __kfifo_dma_out_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \
719 __kfifo_dma_out_prepare(__kfifo, __sgl, __nents, __len); \
720})
721
722
723
724
725
726
727
728
729
730
731
732
733#define kfifo_dma_out_finish(fifo, len) \
734(void)({ \
735 typeof((fifo) + 1) __tmp = (fifo); \
736 unsigned int __len = (len); \
737 const size_t __recsize = sizeof(*__tmp->rectype); \
738 struct __kfifo *__kfifo = &__tmp->kfifo; \
739 if (__recsize) \
740 __kfifo_dma_out_finish_r(__kfifo, __recsize); \
741 else \
742 __kfifo->out += __len / sizeof(*__tmp->type); \
743})
744
745
746
747
748
749
750
751
752
753
754
755
756
757#define kfifo_out_peek(fifo, buf, n) \
758__kfifo_uint_must_check_helper( \
759({ \
760 typeof((fifo) + 1) __tmp = (fifo); \
761 typeof(__tmp->ptr) __buf = (buf); \
762 unsigned long __n = (n); \
763 const size_t __recsize = sizeof(*__tmp->rectype); \
764 struct __kfifo *__kfifo = &__tmp->kfifo; \
765 (__recsize) ? \
766 __kfifo_out_peek_r(__kfifo, __buf, __n, __recsize) : \
767 __kfifo_out_peek(__kfifo, __buf, __n); \
768}) \
769)
770
771extern int __kfifo_alloc(struct __kfifo *fifo, unsigned int size,
772 size_t esize, gfp_t gfp_mask);
773
774extern void __kfifo_free(struct __kfifo *fifo);
775
776extern int __kfifo_init(struct __kfifo *fifo, void *buffer,
777 unsigned int size, size_t esize);
778
779extern unsigned int __kfifo_in(struct __kfifo *fifo,
780 const void *buf, unsigned int len);
781
782extern unsigned int __kfifo_out(struct __kfifo *fifo,
783 void *buf, unsigned int len);
784
785extern int __kfifo_from_user(struct __kfifo *fifo,
786 const void __user *from, unsigned long len, unsigned int *copied);
787
788extern int __kfifo_to_user(struct __kfifo *fifo,
789 void __user *to, unsigned long len, unsigned int *copied);
790
791extern unsigned int __kfifo_dma_in_prepare(struct __kfifo *fifo,
792 struct scatterlist *sgl, int nents, unsigned int len);
793
794extern unsigned int __kfifo_dma_out_prepare(struct __kfifo *fifo,
795 struct scatterlist *sgl, int nents, unsigned int len);
796
797extern unsigned int __kfifo_out_peek(struct __kfifo *fifo,
798 void *buf, unsigned int len);
799
800extern unsigned int __kfifo_in_r(struct __kfifo *fifo,
801 const void *buf, unsigned int len, size_t recsize);
802
803extern unsigned int __kfifo_out_r(struct __kfifo *fifo,
804 void *buf, unsigned int len, size_t recsize);
805
806extern int __kfifo_from_user_r(struct __kfifo *fifo,
807 const void __user *from, unsigned long len, unsigned int *copied,
808 size_t recsize);
809
810extern int __kfifo_to_user_r(struct __kfifo *fifo, void __user *to,
811 unsigned long len, unsigned int *copied, size_t recsize);
812
813extern unsigned int __kfifo_dma_in_prepare_r(struct __kfifo *fifo,
814 struct scatterlist *sgl, int nents, unsigned int len, size_t recsize);
815
816extern void __kfifo_dma_in_finish_r(struct __kfifo *fifo,
817 unsigned int len, size_t recsize);
818
819extern unsigned int __kfifo_dma_out_prepare_r(struct __kfifo *fifo,
820 struct scatterlist *sgl, int nents, unsigned int len, size_t recsize);
821
822extern void __kfifo_dma_out_finish_r(struct __kfifo *fifo, size_t recsize);
823
824extern unsigned int __kfifo_len_r(struct __kfifo *fifo, size_t recsize);
825
826extern void __kfifo_skip_r(struct __kfifo *fifo, size_t recsize);
827
828extern unsigned int __kfifo_out_peek_r(struct __kfifo *fifo,
829 void *buf, unsigned int len, size_t recsize);
830
831extern unsigned int __kfifo_max_r(unsigned int len, size_t recsize);
832
833#endif
834