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 char (*rectype)[recsize]; \
71 ptrtype *ptr; \
72 const ptrtype *ptr_const; \
73 }
74
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
95
96struct 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
106
107struct kfifo_rec_ptr_1 __STRUCT_KFIFO_PTR(unsigned char, 1, void);
108struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2, void);
109
110
111
112
113
114
115#define __is_kfifo_ptr(fifo) (sizeof(*fifo) == sizeof(struct __kfifo))
116
117
118
119
120
121
122#define DECLARE_KFIFO_PTR(fifo, type) STRUCT_KFIFO_PTR(type) fifo
123
124
125
126
127
128
129
130#define DECLARE_KFIFO(fifo, type, size) STRUCT_KFIFO(type, size) fifo
131
132
133
134
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
149
150
151
152
153
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
174static inline unsigned int __must_check
175__kfifo_uint_must_check_helper(unsigned int val)
176{
177 return val;
178}
179
180static inline int __must_check
181__kfifo_int_must_check_helper(int val)
182{
183 return val;
184}
185
186
187
188
189
190
191
192
193#define kfifo_initialized(fifo) ((fifo)->kfifo.mask)
194
195
196
197
198
199#define kfifo_esize(fifo) ((fifo)->kfifo.esize)
200
201
202
203
204
205#define kfifo_recsize(fifo) (sizeof(*(fifo)->rectype))
206
207
208
209
210
211#define kfifo_size(fifo) ((fifo)->kfifo.mask + 1)
212
213
214
215
216
217
218
219
220
221#define kfifo_reset(fifo) \
222(void)({ \
223 typeof((fifo) + 1) __tmp = (fifo); \
224 __tmp->kfifo.in = __tmp->kfifo.out = 0; \
225})
226
227
228
229
230
231
232
233
234
235#define kfifo_reset_out(fifo) \
236(void)({ \
237 typeof((fifo) + 1) __tmp = (fifo); \
238 __tmp->kfifo.out = __tmp->kfifo.in; \
239})
240
241
242
243
244
245#define kfifo_len(fifo) \
246({ \
247 typeof((fifo) + 1) __tmpl = (fifo); \
248 __tmpl->kfifo.in - __tmpl->kfifo.out; \
249})
250
251
252
253
254
255#define kfifo_is_empty(fifo) \
256({ \
257 typeof((fifo) + 1) __tmpq = (fifo); \
258 __tmpq->kfifo.in == __tmpq->kfifo.out; \
259})
260
261
262
263
264
265#define kfifo_is_full(fifo) \
266({ \
267 typeof((fifo) + 1) __tmpq = (fifo); \
268 kfifo_len(__tmpq) > __tmpq->kfifo.mask; \
269})
270
271
272
273
274
275#define kfifo_avail(fifo) \
276__kfifo_uint_must_check_helper( \
277({ \
278 typeof((fifo) + 1) __tmpq = (fifo); \
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)
286
287
288
289
290
291#define kfifo_skip(fifo) \
292(void)({ \
293 typeof((fifo) + 1) __tmp = (fifo); \
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
304
305
306
307
308#define kfifo_peek_len(fifo) \
309__kfifo_uint_must_check_helper( \
310({ \
311 typeof((fifo) + 1) __tmp = (fifo); \
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)
318
319
320
321
322
323
324
325
326
327
328
329
330
331#define kfifo_alloc(fifo, size, gfp_mask) \
332__kfifo_int_must_check_helper( \
333({ \
334 typeof((fifo) + 1) __tmp = (fifo); \
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)
341
342
343
344
345
346#define kfifo_free(fifo) \
347({ \
348 typeof((fifo) + 1) __tmp = (fifo); \
349 struct __kfifo *__kfifo = &__tmp->kfifo; \
350 if (__is_kfifo_ptr(__tmp)) \
351 __kfifo_free(__kfifo); \
352})
353
354
355
356
357
358
359
360
361
362
363
364
365#define kfifo_init(fifo, buffer, size) \
366({ \
367 typeof((fifo) + 1) __tmp = (fifo); \
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
376
377
378
379
380
381
382
383
384
385
386#define kfifo_put(fifo, val) \
387({ \
388 typeof((fifo) + 1) __tmp = (fifo); \
389 typeof((val) + 1) __val = (val); \
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})
414
415
416
417
418
419
420
421
422
423
424
425
426
427#define kfifo_get(fifo, val) \
428__kfifo_uint_must_check_helper( \
429({ \
430 typeof((fifo) + 1) __tmp = (fifo); \
431 typeof((val) + 1) __val = (val); \
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)
455
456
457
458
459
460
461
462
463
464
465
466
467
468#define kfifo_peek(fifo, val) \
469__kfifo_uint_must_check_helper( \
470({ \
471 typeof((fifo) + 1) __tmp = (fifo); \
472 typeof((val) + 1) __val = (val); \
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)
495
496
497
498
499
500
501
502
503
504
505
506
507
508#define kfifo_in(fifo, buf, n) \
509({ \
510 typeof((fifo) + 1) __tmp = (fifo); \
511 typeof((buf) + 1) __buf = (buf); \
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})
523
524
525
526
527
528
529
530
531
532
533
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})
543
544
545#define kfifo_in_locked(fifo, buf, n, lock) \
546 kfifo_in_spinlocked(fifo, buf, n, lock)
547
548
549
550
551
552
553
554
555
556
557
558
559
560#define kfifo_out(fifo, buf, n) \
561__kfifo_uint_must_check_helper( \
562({ \
563 typeof((fifo) + 1) __tmp = (fifo); \
564 typeof((buf) + 1) __buf = (buf); \
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)
577
578
579
580
581
582
583
584
585
586
587
588#define kfifo_out_spinlocked(fifo, buf, n, lock) \
589__kfifo_uint_must_check_helper( \
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)
599
600
601#define kfifo_out_locked(fifo, buf, n, lock) \
602 kfifo_out_spinlocked(fifo, buf, n, lock)
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617#define kfifo_from_user(fifo, from, len, copied) \
618__kfifo_uint_must_check_helper( \
619({ \
620 typeof((fifo) + 1) __tmp = (fifo); \
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
634
635
636
637
638
639
640
641
642
643
644
645#define kfifo_to_user(fifo, to, len, copied) \
646__kfifo_uint_must_check_helper( \
647({ \
648 typeof((fifo) + 1) __tmp = (fifo); \
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
662
663
664
665
666
667
668
669
670
671
672
673#define kfifo_dma_in_prepare(fifo, sgl, nents, len) \
674({ \
675 typeof((fifo) + 1) __tmp = (fifo); \
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
688
689
690
691
692
693
694
695
696
697#define kfifo_dma_in_finish(fifo, len) \
698(void)({ \
699 typeof((fifo) + 1) __tmp = (fifo); \
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
711
712
713
714
715
716
717
718
719
720
721
722
723
724#define kfifo_dma_out_prepare(fifo, sgl, nents, len) \
725({ \
726 typeof((fifo) + 1) __tmp = (fifo); \
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
739
740
741
742
743
744
745
746
747
748#define kfifo_dma_out_finish(fifo, len) \
749(void)({ \
750 typeof((fifo) + 1) __tmp = (fifo); \
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
762
763
764
765
766
767
768
769
770
771
772#define kfifo_out_peek(fifo, buf, n) \
773__kfifo_uint_must_check_helper( \
774({ \
775 typeof((fifo) + 1) __tmp = (fifo); \
776 typeof((buf) + 1) __buf = (buf); \
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
790extern int __kfifo_alloc(struct __kfifo *fifo, unsigned int size,
791 size_t esize, gfp_t gfp_mask);
792
793extern void __kfifo_free(struct __kfifo *fifo);
794
795extern int __kfifo_init(struct __kfifo *fifo, void *buffer,
796 unsigned int size, size_t esize);
797
798extern unsigned int __kfifo_in(struct __kfifo *fifo,
799 const void *buf, unsigned int len);
800
801extern unsigned int __kfifo_out(struct __kfifo *fifo,
802 void *buf, unsigned int len);
803
804extern int __kfifo_from_user(struct __kfifo *fifo,
805 const void __user *from, unsigned long len, unsigned int *copied);
806
807extern int __kfifo_to_user(struct __kfifo *fifo,
808 void __user *to, unsigned long len, unsigned int *copied);
809
810extern unsigned int __kfifo_dma_in_prepare(struct __kfifo *fifo,
811 struct scatterlist *sgl, int nents, unsigned int len);
812
813extern unsigned int __kfifo_dma_out_prepare(struct __kfifo *fifo,
814 struct scatterlist *sgl, int nents, unsigned int len);
815
816extern unsigned int __kfifo_out_peek(struct __kfifo *fifo,
817 void *buf, unsigned int len);
818
819extern unsigned int __kfifo_in_r(struct __kfifo *fifo,
820 const void *buf, unsigned int len, size_t recsize);
821
822extern unsigned int __kfifo_out_r(struct __kfifo *fifo,
823 void *buf, unsigned int len, size_t recsize);
824
825extern int __kfifo_from_user_r(struct __kfifo *fifo,
826 const void __user *from, unsigned long len, unsigned int *copied,
827 size_t recsize);
828
829extern int __kfifo_to_user_r(struct __kfifo *fifo, void __user *to,
830 unsigned long len, unsigned int *copied, size_t recsize);
831
832extern unsigned int __kfifo_dma_in_prepare_r(struct __kfifo *fifo,
833 struct scatterlist *sgl, int nents, unsigned int len, size_t recsize);
834
835extern void __kfifo_dma_in_finish_r(struct __kfifo *fifo,
836 unsigned int len, size_t recsize);
837
838extern unsigned int __kfifo_dma_out_prepare_r(struct __kfifo *fifo,
839 struct scatterlist *sgl, int nents, unsigned int len, size_t recsize);
840
841extern void __kfifo_dma_out_finish_r(struct __kfifo *fifo, size_t recsize);
842
843extern unsigned int __kfifo_len_r(struct __kfifo *fifo, size_t recsize);
844
845extern void __kfifo_skip_r(struct __kfifo *fifo, size_t recsize);
846
847extern unsigned int __kfifo_out_peek_r(struct __kfifo *fifo,
848 void *buf, unsigned int len, size_t recsize);
849
850extern unsigned int __kfifo_max_r(unsigned int len, size_t recsize);
851
852#endif
853