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