xref: /rk3399_rockchip-uboot/include/abuf.h (revision a4578d1a2a1887f67dd4fbf1c3d4325449c6618b)
1*a4578d1aSSimon Glass /* SPDX-License-Identifier: GPL-2.0+ */
2*a4578d1aSSimon Glass /*
3*a4578d1aSSimon Glass  * Handles a buffer that can be allocated and freed
4*a4578d1aSSimon Glass  *
5*a4578d1aSSimon Glass  * Copyright 2021 Google LLC
6*a4578d1aSSimon Glass  * Written by Simon Glass <sjg@chromium.org>
7*a4578d1aSSimon Glass  */
8*a4578d1aSSimon Glass 
9*a4578d1aSSimon Glass #ifndef __ABUF_H
10*a4578d1aSSimon Glass #define __ABUF_H
11*a4578d1aSSimon Glass 
12*a4578d1aSSimon Glass #include <linux/types.h>
13*a4578d1aSSimon Glass 
14*a4578d1aSSimon Glass /**
15*a4578d1aSSimon Glass  * struct abuf - buffer that can be allocated and freed
16*a4578d1aSSimon Glass  *
17*a4578d1aSSimon Glass  * This is useful for a block of data which may be allocated with malloc(), or
18*a4578d1aSSimon Glass  * not, so that it needs to be freed correctly when finished with.
19*a4578d1aSSimon Glass  *
20*a4578d1aSSimon Glass  * For now it has a very simple purpose.
21*a4578d1aSSimon Glass  *
22*a4578d1aSSimon Glass  * Using memset() to zero all fields is guaranteed to be equivalent to
23*a4578d1aSSimon Glass  * abuf_init().
24*a4578d1aSSimon Glass  *
25*a4578d1aSSimon Glass  * @data: Pointer to data
26*a4578d1aSSimon Glass  * @size: Size of data in bytes
27*a4578d1aSSimon Glass  * @alloced: true if allocated with malloc(), so must be freed after use
28*a4578d1aSSimon Glass  */
29*a4578d1aSSimon Glass struct abuf {
30*a4578d1aSSimon Glass 	void *data;
31*a4578d1aSSimon Glass 	size_t size;
32*a4578d1aSSimon Glass 	bool alloced;
33*a4578d1aSSimon Glass };
34*a4578d1aSSimon Glass 
abuf_data(const struct abuf * abuf)35*a4578d1aSSimon Glass static inline void *abuf_data(const struct abuf *abuf)
36*a4578d1aSSimon Glass {
37*a4578d1aSSimon Glass 	return abuf->data;
38*a4578d1aSSimon Glass }
39*a4578d1aSSimon Glass 
abuf_size(const struct abuf * abuf)40*a4578d1aSSimon Glass static inline size_t abuf_size(const struct abuf *abuf)
41*a4578d1aSSimon Glass {
42*a4578d1aSSimon Glass 	return abuf->size;
43*a4578d1aSSimon Glass }
44*a4578d1aSSimon Glass 
45*a4578d1aSSimon Glass /**
46*a4578d1aSSimon Glass  * abuf_set() - set the (unallocated) data in a buffer
47*a4578d1aSSimon Glass  *
48*a4578d1aSSimon Glass  * This simply makes the abuf point to the supplied data, which must be live
49*a4578d1aSSimon Glass  * for the lifetime of the abuf. It is not alloced.
50*a4578d1aSSimon Glass  *
51*a4578d1aSSimon Glass  * Any existing data in the abuf is freed and the alloced member is set to
52*a4578d1aSSimon Glass  * false.
53*a4578d1aSSimon Glass  *
54*a4578d1aSSimon Glass  * @abuf: abuf to adjust
55*a4578d1aSSimon Glass  * @data: New contents of abuf
56*a4578d1aSSimon Glass  * @size: New size of abuf
57*a4578d1aSSimon Glass  */
58*a4578d1aSSimon Glass void abuf_set(struct abuf *abuf, void *data, size_t size);
59*a4578d1aSSimon Glass 
60*a4578d1aSSimon Glass /**
61*a4578d1aSSimon Glass  * abuf_map_sysmem() - calls map_sysmem() to set up an abuf
62*a4578d1aSSimon Glass  *
63*a4578d1aSSimon Glass  * This is equivalent to abuf_set(abuf, map_sysmem(addr, size), size)
64*a4578d1aSSimon Glass  *
65*a4578d1aSSimon Glass  * Any existing data in the abuf is freed and the alloced member is set to
66*a4578d1aSSimon Glass  * false.
67*a4578d1aSSimon Glass  *
68*a4578d1aSSimon Glass  * @abuf: abuf to adjust
69*a4578d1aSSimon Glass  * @addr: Address to set the abuf to
70*a4578d1aSSimon Glass  * @size: New size of abuf
71*a4578d1aSSimon Glass  */
72*a4578d1aSSimon Glass void abuf_map_sysmem(struct abuf *abuf, ulong addr, size_t size);
73*a4578d1aSSimon Glass 
74*a4578d1aSSimon Glass /**
75*a4578d1aSSimon Glass  * abuf_realloc() - Change the size of a buffer
76*a4578d1aSSimon Glass  *
77*a4578d1aSSimon Glass  * This uses realloc() to change the size of the buffer, with the same semantics
78*a4578d1aSSimon Glass  * as that function. If the abuf is not currently alloced, then it will alloc
79*a4578d1aSSimon Glass  * it if the size needs to increase (i.e. set the alloced member to true)
80*a4578d1aSSimon Glass  *
81*a4578d1aSSimon Glass  * @abuf: abuf to adjust
82*a4578d1aSSimon Glass  * @new_size: new size in bytes.
83*a4578d1aSSimon Glass  *	if 0, the abuf is freed
84*a4578d1aSSimon Glass  *	if greater than the current size, the abuf is extended and the new
85*a4578d1aSSimon Glass  *	   space is not inited. The alloced member is set to true
86*a4578d1aSSimon Glass  *	if less than the current size, the abuf is contracted and the data at
87*a4578d1aSSimon Glass  *	   the end is lost. If @new_size is 0, this sets the alloced member to
88*a4578d1aSSimon Glass  *	   false
89*a4578d1aSSimon Glass  * @return true if OK, false if out of memory
90*a4578d1aSSimon Glass  */
91*a4578d1aSSimon Glass bool abuf_realloc(struct abuf *abuf, size_t new_size);
92*a4578d1aSSimon Glass 
93*a4578d1aSSimon Glass /**
94*a4578d1aSSimon Glass  * abuf_uninit_move() - Return the allocated contents and uninit the abuf
95*a4578d1aSSimon Glass  *
96*a4578d1aSSimon Glass  * This returns the abuf data to the caller, allocating it if necessary, so that
97*a4578d1aSSimon Glass  * the caller receives data that it can be sure will hang around. The caller is
98*a4578d1aSSimon Glass  * responsible for freeing the data.
99*a4578d1aSSimon Glass  *
100*a4578d1aSSimon Glass  * If the abuf has allocated data, it is returned. If the abuf has data but it
101*a4578d1aSSimon Glass  * is not allocated, then it is first allocated, then returned.
102*a4578d1aSSimon Glass  *
103*a4578d1aSSimon Glass  * If the abuf size is 0, this returns NULL
104*a4578d1aSSimon Glass  *
105*a4578d1aSSimon Glass  * The abuf is uninited as part of this, except if the allocation fails, in
106*a4578d1aSSimon Glass  * which NULL is returned and the abuf remains untouched.
107*a4578d1aSSimon Glass  *
108*a4578d1aSSimon Glass  * The abuf must be inited before this can be called.
109*a4578d1aSSimon Glass  *
110*a4578d1aSSimon Glass  * @abuf: abuf to uninit
111*a4578d1aSSimon Glass  * @sizep: if non-NULL, returns the size of the returned data
112*a4578d1aSSimon Glass  * @return data contents, allocated with malloc(), or NULL if the data could not
113*a4578d1aSSimon Glass  *	be allocated, or the data size is 0
114*a4578d1aSSimon Glass  */
115*a4578d1aSSimon Glass void *abuf_uninit_move(struct abuf *abuf, size_t *sizep);
116*a4578d1aSSimon Glass 
117*a4578d1aSSimon Glass /**
118*a4578d1aSSimon Glass  * abuf_init_move() - Make abuf take over the management of an allocated region
119*a4578d1aSSimon Glass  *
120*a4578d1aSSimon Glass  * After this, @data must not be used. All access must be via the abuf.
121*a4578d1aSSimon Glass  *
122*a4578d1aSSimon Glass  * @abuf: abuf to init
123*a4578d1aSSimon Glass  * @data: Existing allocated buffer to place in the abuf
124*a4578d1aSSimon Glass  * @size: Size of allocated buffer
125*a4578d1aSSimon Glass  */
126*a4578d1aSSimon Glass void abuf_init_move(struct abuf *abuf, void *data, size_t size);
127*a4578d1aSSimon Glass 
128*a4578d1aSSimon Glass /**
129*a4578d1aSSimon Glass  * abuf_init_set() - Set up a new abuf
130*a4578d1aSSimon Glass  *
131*a4578d1aSSimon Glass  * Inits a new abuf and sets up its (unallocated) data
132*a4578d1aSSimon Glass  *
133*a4578d1aSSimon Glass  * @abuf: abuf to set up
134*a4578d1aSSimon Glass  * @data: New contents of abuf
135*a4578d1aSSimon Glass  * @size: New size of abuf
136*a4578d1aSSimon Glass  */
137*a4578d1aSSimon Glass void abuf_init_set(struct abuf *abuf, void *data, size_t size);
138*a4578d1aSSimon Glass 
139*a4578d1aSSimon Glass /**
140*a4578d1aSSimon Glass  * abuf_uninit() - Free any memory used by an abuf
141*a4578d1aSSimon Glass  *
142*a4578d1aSSimon Glass  * The buffer must be inited before this can be called.
143*a4578d1aSSimon Glass  *
144*a4578d1aSSimon Glass  * @abuf: abuf to uninit
145*a4578d1aSSimon Glass  */
146*a4578d1aSSimon Glass void abuf_uninit(struct abuf *abuf);
147*a4578d1aSSimon Glass 
148*a4578d1aSSimon Glass /**
149*a4578d1aSSimon Glass  * abuf_init() - Set up a new abuf
150*a4578d1aSSimon Glass  *
151*a4578d1aSSimon Glass  * This initially has no data and alloced is set to false. This is equivalent to
152*a4578d1aSSimon Glass  * setting all fields to 0, e.g. with memset(), so callers can do that instead
153*a4578d1aSSimon Glass  * if desired.
154*a4578d1aSSimon Glass  *
155*a4578d1aSSimon Glass  * @abuf: abuf to set up
156*a4578d1aSSimon Glass  */
157*a4578d1aSSimon Glass void abuf_init(struct abuf *abuf);
158*a4578d1aSSimon Glass 
159*a4578d1aSSimon Glass #endif
160