XenevaOS
Loading...
Searching...
No Matches
XenevaOS
BaseHdr
linux
kfifo.h
Go to the documentation of this file.
1
#ifndef __LINUX_KFIFO_H__
2
#define __LINUX_KFIFO_H__
3
4
/*
5
* DCL <linux/kfifo.h> -- the byte ring behind a tty port's transmit buffer.
6
*
7
* serial_core.c keeps everything waiting to go out the UART in one of these:
8
* tty_port_alloc_xmit_buf() hands it a PAGE_SIZE buffer (serial_core.c:262),
9
* uart_write() pushes bytes in, and the driver's start_tx pulls them out and
10
* writes them to the shift register. 8250_port.c:1722 decides when to raise a
11
* write wakeup by comparing kfifo_len() against WAKEUP_CHARS, so the length
12
* has to be exact or the tty never learns the port drained.
13
*
14
* Deliberate simplification: mainline's kfifo is a macro-generated type-safe
15
* family with a __kfifo core, a mask for power-of-two indexing, and record
16
* variants for framed data. None of that is needed for a byte ring -- and
17
* mainline's own `size` must be a power of two, which a macro cannot check.
18
* This implementation indexes with `% size` instead: one division per byte on
19
* a 115200-baud transmit path is nothing, and it cannot be wrong if a future
20
* caller passes a size that is not a power of two. The `in`/`out` counters
21
* free-run and wrap, so occupancy is `in - out` in plain unsigned arithmetic.
22
*
23
* The subset is exactly what the staged set calls: kfifo_init, kfifo_reset,
24
* kfifo_is_empty, kfifo_len, kfifo_avail, kfifo_put, kfifo_in. kfifo_get and
25
* kfifo_out were absent for two stages on the grounds that nothing read
26
* through this ring; stage 3 changed that, and serial_core.h now reads it
27
* three ways (uart_fifo_out, uart_fifo_get, uart_xmit_advance), so all three
28
* are at the bottom of this file.
29
*/
30
31
#include <linux/kernel.h>
/* u8, size_t */
32
#include <
linux/string.h
>
/* memcpy */
33
34
struct
kfifo
{
35
unsigned
char
*
buf
;
36
unsigned
int
size
;
/* capacity in bytes */
37
unsigned
int
in
;
/* free-running write counter */
38
unsigned
int
out
;
/* free-running read counter */
39
};
40
41
/* tty_port.h's spelling: `DECLARE_KFIFO_PTR(xmit_fifo, u8)` */
42
#define DECLARE_KFIFO_PTR(fifo, type) struct kfifo fifo
43
44
/* buffer is supplied later (or never: serial_core allocates it on demand) */
45
#define kfifo_init(f, buffer, sz) \
46
do { \
47
(f)->buf = (unsigned char*)(buffer); \
48
(f)->size = (unsigned int)(sz); \
49
(f)->in = 0; \
50
(f)->out = 0; \
51
} while (0)
52
53
/* Takes the object, not a pointer -- serial_core.c:293's spelling. */
54
#define INIT_KFIFO(fifo) kfifo_init(&(fifo), NULL, 0)
55
56
#define kfifo_reset(fifo) \
57
do { (fifo)->in = 0; (fifo)->out = 0; } while (0)
58
59
#define kfifo_is_empty(fifo) ((fifo)->in == (fifo)->out)
60
61
#define kfifo_len(fifo) ((fifo)->in - (fifo)->out)
62
63
#define kfifo_avail(fifo) ((fifo)->size - (fifo)->in + (fifo)->out)
64
65
static
inline
unsigned
int
kfifo_put(
struct
kfifo
*
f
,
unsigned
char
val)
66
{
67
if
(!
f
->buf ||
kfifo_avail
(
f
) == 0)
68
return
0;
69
f
->buf[
f
->in %
f
->size] = val;
70
f
->in++;
71
return
1;
72
}
73
74
static
inline
unsigned
int
kfifo_in(
struct
kfifo
*
f
,
const
void
* buf,
75
unsigned
int
len
)
76
{
77
unsigned
int
avail;
78
unsigned
int
i;
79
80
if
(!
f
->buf)
81
return
0;
82
83
avail =
kfifo_avail
(
f
);
84
if
(
len
> avail)
85
len
= avail;
86
87
for
(i = 0; i <
len
; i++)
88
f
->buf[(
f
->in + i) %
f
->size] = ((
const
unsigned
char
*)buf)[i];
89
f
->in +=
len
;
90
return
len
;
91
}
92
93
94
/*
95
* The three reads serial_core.h asks for and this header did not have.
96
*
97
* mainline spells all three as macros built on __kfifo_out with an element
98
* size; DCL's struct kfifo is byte-oriented (no esize field, `size` is a byte
99
* capacity), so the bodies are plain byte loops below -- same three
100
* behaviours, which is what the callers actually depend on:
101
*
102
* kfifo_out(f, buf, n) copy out and *consume* up to n bytes
103
* kfifo_get(f, val) copy out and consume exactly one byte; the count
104
* it returns is 0 or 1, which is why
105
* uart_fifo_get() can add it straight to
106
* icount.tx as "one more byte left the fifo"
107
* kfifo_skip_count(f, n) consume without copying, for
108
* uart_xmit_advance() -- the transmit path has
109
* already accounted for the bytes it handed to the
110
* UART and only needs the ring to move on
111
*
112
* The clamp to kfifo_len() matters in all three: mainline's variants return
113
* short rather than reading past the consumer mark, and a ring that could be
114
* asked for more than it holds would otherwise wrap and re-deliver bytes.
115
*
116
* out is a free-running counter here (kfifo_len is `in - out`, taken mod
117
* `size` on access), so advancing it needs no mask -- the same convention the
118
* two writers above already use for `in`.
119
*/
120
static
inline
unsigned
int
kfifo_out(
struct
kfifo
*
f
,
void
* buf,
121
unsigned
int
n)
122
{
123
unsigned
int
i;
124
125
if
(!
f
->buf)
126
return
0;
127
if
(n >
kfifo_len
(
f
))
128
n =
kfifo_len
(
f
);
129
130
for
(i = 0; i < n; i++)
131
((
unsigned
char
*)buf)[i] =
f
->buf[(
f
->out + i) %
f
->size];
132
f
->out += n;
133
return
n;
134
}
135
136
static
inline
unsigned
int
kfifo_get(
struct
kfifo
*
f
,
unsigned
char
* val)
137
{
138
return
kfifo_out(
f
, val, 1);
139
}
140
141
static
inline
void
kfifo_skip_count(
struct
kfifo
*
f
,
unsigned
int
n)
142
{
143
if
(!
f
->buf)
144
return
;
145
if
(n >
kfifo_len
(
f
))
146
n =
kfifo_len
(
f
);
147
f
->out += n;
148
}
149
150
#endif
/* __LINUX_KFIFO_H__ */
string.h
f
const char * f
Definition
drm_print.h:205
len
size_t len
Definition
initial.c:23
kfifo_avail
#define kfifo_avail(fifo)
Definition
kfifo.h:63
kfifo_len
#define kfifo_len(fifo)
Definition
kfifo.h:61
kfifo
Definition
kfifo.h:34
kfifo::size
unsigned int size
Definition
kfifo.h:36
kfifo::out
unsigned int out
Definition
kfifo.h:38
kfifo::buf
unsigned char * buf
Definition
kfifo.h:35
kfifo::in
unsigned int in
Definition
kfifo.h:37
Generated by
1.9.8