xref: /rk3399_rockchip-uboot/lib/membuff.c (revision b7b65090b29e6bc133c7922f8290c1e2f75b064a)
1*b7b65090SSimon Glass /*
2*b7b65090SSimon Glass  * Copyright (c) 2015 Google, Inc
3*b7b65090SSimon Glass  * Written by Simon Glass <sjg@chromium.org>
4*b7b65090SSimon Glass  *
5*b7b65090SSimon Glass  * Copyright (c) 1992 Simon Glass
6*b7b65090SSimon Glass  *
7*b7b65090SSimon Glass  * SPDX-License-Identifier:	GPL-2.0+
8*b7b65090SSimon Glass  */
9*b7b65090SSimon Glass 
10*b7b65090SSimon Glass #include <common.h>
11*b7b65090SSimon Glass #include <errno.h>
12*b7b65090SSimon Glass #include <malloc.h>
13*b7b65090SSimon Glass #include "membuff.h"
14*b7b65090SSimon Glass 
membuff_purge(struct membuff * mb)15*b7b65090SSimon Glass void membuff_purge(struct membuff *mb)
16*b7b65090SSimon Glass {
17*b7b65090SSimon Glass 	/* set mb->head and mb->tail so the buffers look empty */
18*b7b65090SSimon Glass 	mb->head = mb->start;
19*b7b65090SSimon Glass 	mb->tail = mb->start;
20*b7b65090SSimon Glass }
21*b7b65090SSimon Glass 
membuff_putrawflex(struct membuff * mb,int maxlen,bool update,char *** data,int * offsetp)22*b7b65090SSimon Glass static int membuff_putrawflex(struct membuff *mb, int maxlen, bool update,
23*b7b65090SSimon Glass 			      char ***data, int *offsetp)
24*b7b65090SSimon Glass {
25*b7b65090SSimon Glass 	int len;
26*b7b65090SSimon Glass 
27*b7b65090SSimon Glass 	/* always write to 'mb->head' */
28*b7b65090SSimon Glass 	assert(data && offsetp);
29*b7b65090SSimon Glass 	*data = &mb->start;
30*b7b65090SSimon Glass 	*offsetp = mb->head - mb->start;
31*b7b65090SSimon Glass 
32*b7b65090SSimon Glass 	/* if there is no buffer, we can do nothing */
33*b7b65090SSimon Glass 	if (!mb->start)
34*b7b65090SSimon Glass 		return 0;
35*b7b65090SSimon Glass 
36*b7b65090SSimon Glass 	/*
37*b7b65090SSimon Glass 	 * if head is ahead of tail, we can write from head until the end of
38*b7b65090SSimon Glass 	 * the buffer
39*b7b65090SSimon Glass 	 */
40*b7b65090SSimon Glass 	if (mb->head >= mb->tail) {
41*b7b65090SSimon Glass 		/* work out how many bytes can fit here */
42*b7b65090SSimon Glass 		len = mb->end - mb->head - 1;
43*b7b65090SSimon Glass 		if (maxlen >= 0 && len > maxlen)
44*b7b65090SSimon Glass 			len = maxlen;
45*b7b65090SSimon Glass 
46*b7b65090SSimon Glass 		/* update the head pointer to mark these bytes as written */
47*b7b65090SSimon Glass 		if (update)
48*b7b65090SSimon Glass 			mb->head += len;
49*b7b65090SSimon Glass 
50*b7b65090SSimon Glass 		/*
51*b7b65090SSimon Glass 		 * if the tail isn't at start of the buffer, then we can
52*b7b65090SSimon Glass 		 * write one more byte right at the end
53*b7b65090SSimon Glass 		 */
54*b7b65090SSimon Glass 		if ((maxlen < 0 || len < maxlen) && mb->tail != mb->start) {
55*b7b65090SSimon Glass 			len++;
56*b7b65090SSimon Glass 			if (update)
57*b7b65090SSimon Glass 				mb->head = mb->start;
58*b7b65090SSimon Glass 		}
59*b7b65090SSimon Glass 
60*b7b65090SSimon Glass 	/* otherwise now we can write until head almost reaches tail */
61*b7b65090SSimon Glass 	} else {
62*b7b65090SSimon Glass 		/* work out how many bytes can fit here */
63*b7b65090SSimon Glass 		len = mb->tail - mb->head - 1;
64*b7b65090SSimon Glass 		if (maxlen >= 0 && len > maxlen)
65*b7b65090SSimon Glass 			len = maxlen;
66*b7b65090SSimon Glass 
67*b7b65090SSimon Glass 		/* update the head pointer to mark these bytes as written */
68*b7b65090SSimon Glass 		if (update)
69*b7b65090SSimon Glass 			mb->head += len;
70*b7b65090SSimon Glass 	}
71*b7b65090SSimon Glass 
72*b7b65090SSimon Glass 	/* return the number of bytes which can be/must be written */
73*b7b65090SSimon Glass 	return len;
74*b7b65090SSimon Glass }
75*b7b65090SSimon Glass 
membuff_putraw(struct membuff * mb,int maxlen,bool update,char ** data)76*b7b65090SSimon Glass int membuff_putraw(struct membuff *mb, int maxlen, bool update, char **data)
77*b7b65090SSimon Glass {
78*b7b65090SSimon Glass 	char **datap;
79*b7b65090SSimon Glass 	int offset;
80*b7b65090SSimon Glass 	int size;
81*b7b65090SSimon Glass 
82*b7b65090SSimon Glass 	size = membuff_putrawflex(mb, maxlen, update, &datap, &offset);
83*b7b65090SSimon Glass 	*data = *datap + offset;
84*b7b65090SSimon Glass 
85*b7b65090SSimon Glass 	return size;
86*b7b65090SSimon Glass }
87*b7b65090SSimon Glass 
membuff_putbyte(struct membuff * mb,int ch)88*b7b65090SSimon Glass bool membuff_putbyte(struct membuff *mb, int ch)
89*b7b65090SSimon Glass {
90*b7b65090SSimon Glass 	char *data;
91*b7b65090SSimon Glass 
92*b7b65090SSimon Glass 	if (membuff_putraw(mb, 1, true, &data) != 1)
93*b7b65090SSimon Glass 		return false;
94*b7b65090SSimon Glass 	*data = ch;
95*b7b65090SSimon Glass 
96*b7b65090SSimon Glass 	return true;
97*b7b65090SSimon Glass }
98*b7b65090SSimon Glass 
membuff_getraw(struct membuff * mb,int maxlen,bool update,char ** data)99*b7b65090SSimon Glass int membuff_getraw(struct membuff *mb, int maxlen, bool update, char **data)
100*b7b65090SSimon Glass {
101*b7b65090SSimon Glass 	int len;
102*b7b65090SSimon Glass 
103*b7b65090SSimon Glass 	/* assume for now there is no data to get */
104*b7b65090SSimon Glass 	len = 0;
105*b7b65090SSimon Glass 
106*b7b65090SSimon Glass 	/*
107*b7b65090SSimon Glass 	 * in this case head is ahead of tail, so we must return data between
108*b7b65090SSimon Glass 	 *'tail' and 'head'
109*b7b65090SSimon Glass 	 */
110*b7b65090SSimon Glass 	if (mb->head > mb->tail) {
111*b7b65090SSimon Glass 		/* work out the amount of data */
112*b7b65090SSimon Glass 		*data = mb->tail;
113*b7b65090SSimon Glass 		len = mb->head - mb->tail;
114*b7b65090SSimon Glass 
115*b7b65090SSimon Glass 		/* check it isn't too much */
116*b7b65090SSimon Glass 		if (maxlen >= 0 && len > maxlen)
117*b7b65090SSimon Glass 			len = maxlen;
118*b7b65090SSimon Glass 
119*b7b65090SSimon Glass 		/* & mark it as read from the buffer */
120*b7b65090SSimon Glass 		if (update)
121*b7b65090SSimon Glass 			mb->tail += len;
122*b7b65090SSimon Glass 	}
123*b7b65090SSimon Glass 
124*b7b65090SSimon Glass 	/*
125*b7b65090SSimon Glass 	 * if head is before tail, then we have data between 'tail' and 'end'
126*b7b65090SSimon Glass 	 * and some more data between 'start' and 'head'(which we can't
127*b7b65090SSimon Glass 	 * return this time
128*b7b65090SSimon Glass 	 */
129*b7b65090SSimon Glass 	else if (mb->head < mb->tail) {
130*b7b65090SSimon Glass 		/* work out the amount of data */
131*b7b65090SSimon Glass 		*data = mb->tail;
132*b7b65090SSimon Glass 		len = mb->end - mb->tail;
133*b7b65090SSimon Glass 		if (maxlen >= 0 && len > maxlen)
134*b7b65090SSimon Glass 			len = maxlen;
135*b7b65090SSimon Glass 		if (update) {
136*b7b65090SSimon Glass 			mb->tail += len;
137*b7b65090SSimon Glass 			if (mb->tail == mb->end)
138*b7b65090SSimon Glass 				mb->tail = mb->start;
139*b7b65090SSimon Glass 		}
140*b7b65090SSimon Glass 	}
141*b7b65090SSimon Glass 
142*b7b65090SSimon Glass 	debug("getraw: maxlen=%d, update=%d, head=%d, tail=%d, data=%d, len=%d",
143*b7b65090SSimon Glass 	      maxlen, update, (int)(mb->head - mb->start),
144*b7b65090SSimon Glass 	      (int)(mb->tail - mb->start), (int)(*data - mb->start), len);
145*b7b65090SSimon Glass 
146*b7b65090SSimon Glass 	/* return the number of bytes we found */
147*b7b65090SSimon Glass 	return len;
148*b7b65090SSimon Glass }
149*b7b65090SSimon Glass 
membuff_getbyte(struct membuff * mb)150*b7b65090SSimon Glass int membuff_getbyte(struct membuff *mb)
151*b7b65090SSimon Glass {
152*b7b65090SSimon Glass 	char *data = 0;
153*b7b65090SSimon Glass 
154*b7b65090SSimon Glass 	return membuff_getraw(mb, 1, true, &data) != 1 ? -1 : *(uint8_t *)data;
155*b7b65090SSimon Glass }
156*b7b65090SSimon Glass 
membuff_peekbyte(struct membuff * mb)157*b7b65090SSimon Glass int membuff_peekbyte(struct membuff *mb)
158*b7b65090SSimon Glass {
159*b7b65090SSimon Glass 	char *data = 0;
160*b7b65090SSimon Glass 
161*b7b65090SSimon Glass 	return membuff_getraw(mb, 1, false, &data) != 1 ? -1 : *(uint8_t *)data;
162*b7b65090SSimon Glass }
163*b7b65090SSimon Glass 
membuff_get(struct membuff * mb,char * buff,int maxlen)164*b7b65090SSimon Glass int membuff_get(struct membuff *mb, char *buff, int maxlen)
165*b7b65090SSimon Glass {
166*b7b65090SSimon Glass 	char *data = 0, *buffptr = buff;
167*b7b65090SSimon Glass 	int len = 1, i;
168*b7b65090SSimon Glass 
169*b7b65090SSimon Glass 	/*
170*b7b65090SSimon Glass 	 * do this in up to two lots(see GetRaw for why) stopping when there
171*b7b65090SSimon Glass 	 * is no more data
172*b7b65090SSimon Glass 	 */
173*b7b65090SSimon Glass 	for (i = 0; len && i < 2; i++) {
174*b7b65090SSimon Glass 		/* get a pointer to the data available */
175*b7b65090SSimon Glass 		len = membuff_getraw(mb, maxlen, true, &data);
176*b7b65090SSimon Glass 
177*b7b65090SSimon Glass 		/* copy it into the buffer */
178*b7b65090SSimon Glass 		memcpy(buffptr, data, len);
179*b7b65090SSimon Glass 		buffptr += len;
180*b7b65090SSimon Glass 		maxlen -= len;
181*b7b65090SSimon Glass 	}
182*b7b65090SSimon Glass 
183*b7b65090SSimon Glass 	/* return the number of bytes read */
184*b7b65090SSimon Glass 	return buffptr - buff;
185*b7b65090SSimon Glass }
186*b7b65090SSimon Glass 
membuff_put(struct membuff * mb,const char * buff,int length)187*b7b65090SSimon Glass int membuff_put(struct membuff *mb, const char *buff, int length)
188*b7b65090SSimon Glass {
189*b7b65090SSimon Glass 	char *data;
190*b7b65090SSimon Glass 	int towrite, i, written;
191*b7b65090SSimon Glass 
192*b7b65090SSimon Glass 	for (i = written = 0; i < 2; i++) {
193*b7b65090SSimon Glass 		/* ask where some data can be written */
194*b7b65090SSimon Glass 		towrite = membuff_putraw(mb, length, true, &data);
195*b7b65090SSimon Glass 
196*b7b65090SSimon Glass 		/* and write it, updating the bytes length */
197*b7b65090SSimon Glass 		memcpy(data, buff, towrite);
198*b7b65090SSimon Glass 		written += towrite;
199*b7b65090SSimon Glass 		buff += towrite;
200*b7b65090SSimon Glass 		length -= towrite;
201*b7b65090SSimon Glass 	}
202*b7b65090SSimon Glass 
203*b7b65090SSimon Glass 	/* return the number of bytes written */
204*b7b65090SSimon Glass 	return written;
205*b7b65090SSimon Glass }
206*b7b65090SSimon Glass 
membuff_isempty(struct membuff * mb)207*b7b65090SSimon Glass bool membuff_isempty(struct membuff *mb)
208*b7b65090SSimon Glass {
209*b7b65090SSimon Glass 	return mb->head == mb->tail;
210*b7b65090SSimon Glass }
211*b7b65090SSimon Glass 
membuff_avail(struct membuff * mb)212*b7b65090SSimon Glass int membuff_avail(struct membuff *mb)
213*b7b65090SSimon Glass {
214*b7b65090SSimon Glass 	struct membuff copy;
215*b7b65090SSimon Glass 	int i, avail;
216*b7b65090SSimon Glass 	char *data = 0;
217*b7b65090SSimon Glass 
218*b7b65090SSimon Glass 	/* make a copy of this buffer's control data */
219*b7b65090SSimon Glass 	copy = *mb;
220*b7b65090SSimon Glass 
221*b7b65090SSimon Glass 	/* now read everything out of the copied buffer */
222*b7b65090SSimon Glass 	for (i = avail = 0; i < 2; i++)
223*b7b65090SSimon Glass 		avail += membuff_getraw(&copy, -1, true, &data);
224*b7b65090SSimon Glass 
225*b7b65090SSimon Glass 	/* and return how much we read */
226*b7b65090SSimon Glass 	return avail;
227*b7b65090SSimon Glass }
228*b7b65090SSimon Glass 
membuff_size(struct membuff * mb)229*b7b65090SSimon Glass int membuff_size(struct membuff *mb)
230*b7b65090SSimon Glass {
231*b7b65090SSimon Glass 	return mb->end - mb->start;
232*b7b65090SSimon Glass }
233*b7b65090SSimon Glass 
membuff_makecontig(struct membuff * mb)234*b7b65090SSimon Glass bool membuff_makecontig(struct membuff *mb)
235*b7b65090SSimon Glass {
236*b7b65090SSimon Glass 	int topsize, botsize;
237*b7b65090SSimon Glass 
238*b7b65090SSimon Glass 	debug("makecontig: head=%d, tail=%d, size=%d",
239*b7b65090SSimon Glass 	      (int)(mb->head - mb->start), (int)(mb->tail - mb->start),
240*b7b65090SSimon Glass 	      (int)(mb->end - mb->start));
241*b7b65090SSimon Glass 
242*b7b65090SSimon Glass 	/*
243*b7b65090SSimon Glass 	 * first we move anything at the start of the buffer into the correct
244*b7b65090SSimon Glass 	 * place some way along
245*b7b65090SSimon Glass 	 */
246*b7b65090SSimon Glass 	if (mb->tail > mb->head) {
247*b7b65090SSimon Glass 		/*
248*b7b65090SSimon Glass 		 * the data is split into two parts, from 0 to ->head and
249*b7b65090SSimon Glass 		 * from ->tail to ->end. We move the stuff from 0 to ->head
250*b7b65090SSimon Glass 		 * up to make space for the other data before it
251*b7b65090SSimon Glass 		 */
252*b7b65090SSimon Glass 		topsize = mb->end - mb->tail;
253*b7b65090SSimon Glass 		botsize = mb->head - mb->start;
254*b7b65090SSimon Glass 
255*b7b65090SSimon Glass 		/*
256*b7b65090SSimon Glass 		 * must move data at bottom up by 'topsize' bytes - check if
257*b7b65090SSimon Glass 		 * there's room
258*b7b65090SSimon Glass 		 */
259*b7b65090SSimon Glass 		if (mb->head + topsize >= mb->tail)
260*b7b65090SSimon Glass 			return false;
261*b7b65090SSimon Glass 		memmove(mb->start + topsize, mb->start, botsize);
262*b7b65090SSimon Glass 		debug("	- memmove(%d, %d, %d)", topsize, 0, botsize);
263*b7b65090SSimon Glass 
264*b7b65090SSimon Glass 	/* nothing at the start, so skip that step */
265*b7b65090SSimon Glass 	} else {
266*b7b65090SSimon Glass 		topsize = mb->head - mb->tail;
267*b7b65090SSimon Glass 		botsize = 0;
268*b7b65090SSimon Glass 	}
269*b7b65090SSimon Glass 
270*b7b65090SSimon Glass 	/* now move data at top down to the bottom */
271*b7b65090SSimon Glass 	memcpy(mb->start, mb->tail, topsize);
272*b7b65090SSimon Glass 	debug("	- memcpy(%d, %d, %d)", 0, (int)(mb->tail - mb->start), topsize);
273*b7b65090SSimon Glass 
274*b7b65090SSimon Glass 	/* adjust pointers */
275*b7b65090SSimon Glass 	mb->tail = mb->start;
276*b7b65090SSimon Glass 	mb->head = mb->start + topsize + botsize;
277*b7b65090SSimon Glass 
278*b7b65090SSimon Glass 	debug("	- head=%d, tail=%d", (int)(mb->head - mb->start),
279*b7b65090SSimon Glass 	      (int)(mb->tail - mb->start));
280*b7b65090SSimon Glass 
281*b7b65090SSimon Glass 	/* all ok */
282*b7b65090SSimon Glass 	return true;
283*b7b65090SSimon Glass }
284*b7b65090SSimon Glass 
membuff_free(struct membuff * mb)285*b7b65090SSimon Glass int membuff_free(struct membuff *mb)
286*b7b65090SSimon Glass {
287*b7b65090SSimon Glass 	return mb->end == mb->start ? 0 :
288*b7b65090SSimon Glass 			(mb->end - mb->start) - 1 - membuff_avail(mb);
289*b7b65090SSimon Glass }
290*b7b65090SSimon Glass 
membuff_readline(struct membuff * mb,char * str,int maxlen,int minch)291*b7b65090SSimon Glass int membuff_readline(struct membuff *mb, char *str, int maxlen, int minch)
292*b7b65090SSimon Glass {
293*b7b65090SSimon Glass 	int len;  /* number of bytes read (!= string length) */
294*b7b65090SSimon Glass 	char *s, *end;
295*b7b65090SSimon Glass 	bool ok = false;
296*b7b65090SSimon Glass 	char *orig = str;
297*b7b65090SSimon Glass 
298*b7b65090SSimon Glass 	end = mb->head >= mb->tail ? mb->head : mb->end;
299*b7b65090SSimon Glass 	for (len = 0, s = mb->tail; s < end && len < maxlen - 1; str++) {
300*b7b65090SSimon Glass 		*str = *s++;
301*b7b65090SSimon Glass 		len++;
302*b7b65090SSimon Glass 		if (*str == '\n' || *str < minch) {
303*b7b65090SSimon Glass 			ok = true;
304*b7b65090SSimon Glass 			break;
305*b7b65090SSimon Glass 		}
306*b7b65090SSimon Glass 		if (s == end && mb->tail > mb->head) {
307*b7b65090SSimon Glass 			s = mb->start;
308*b7b65090SSimon Glass 			end = mb->head;
309*b7b65090SSimon Glass 		}
310*b7b65090SSimon Glass 	}
311*b7b65090SSimon Glass 
312*b7b65090SSimon Glass 	/* couldn't get the whole string */
313*b7b65090SSimon Glass 	if (!ok) {
314*b7b65090SSimon Glass 		if (maxlen)
315*b7b65090SSimon Glass 			*orig = '\0';
316*b7b65090SSimon Glass 		return 0;
317*b7b65090SSimon Glass 	}
318*b7b65090SSimon Glass 
319*b7b65090SSimon Glass 	/* terminate the string, update the membuff and return success */
320*b7b65090SSimon Glass 	*str = '\0';
321*b7b65090SSimon Glass 	mb->tail = s == mb->end ? mb->start : s;
322*b7b65090SSimon Glass 
323*b7b65090SSimon Glass 	return len;
324*b7b65090SSimon Glass }
325*b7b65090SSimon Glass 
membuff_extend_by(struct membuff * mb,int by,int max)326*b7b65090SSimon Glass int membuff_extend_by(struct membuff *mb, int by, int max)
327*b7b65090SSimon Glass {
328*b7b65090SSimon Glass 	int oldhead, oldtail;
329*b7b65090SSimon Glass 	int size, orig;
330*b7b65090SSimon Glass 	char *ptr;
331*b7b65090SSimon Glass 
332*b7b65090SSimon Glass 	/* double the buffer size until it is big enough */
333*b7b65090SSimon Glass 	assert(by >= 0);
334*b7b65090SSimon Glass 	for (orig = mb->end - mb->start, size = orig; size < orig + by;)
335*b7b65090SSimon Glass 		size *= 2;
336*b7b65090SSimon Glass 	if (max != -1)
337*b7b65090SSimon Glass 		size = min(size, max);
338*b7b65090SSimon Glass 	by = size - orig;
339*b7b65090SSimon Glass 
340*b7b65090SSimon Glass 	/* if we're already at maximum, give up */
341*b7b65090SSimon Glass 	if (by <= 0)
342*b7b65090SSimon Glass 		return -E2BIG;
343*b7b65090SSimon Glass 
344*b7b65090SSimon Glass 	oldhead = mb->head - mb->start;
345*b7b65090SSimon Glass 	oldtail = mb->tail - mb->start;
346*b7b65090SSimon Glass 	ptr = realloc(mb->start, size);
347*b7b65090SSimon Glass 	if (!ptr)
348*b7b65090SSimon Glass 		return -ENOMEM;
349*b7b65090SSimon Glass 	mb->start = ptr;
350*b7b65090SSimon Glass 	mb->head = mb->start + oldhead;
351*b7b65090SSimon Glass 	mb->tail = mb->start + oldtail;
352*b7b65090SSimon Glass 
353*b7b65090SSimon Glass 	if (mb->head < mb->tail) {
354*b7b65090SSimon Glass 		memmove(mb->tail + by, mb->tail, orig - oldtail);
355*b7b65090SSimon Glass 		mb->tail += by;
356*b7b65090SSimon Glass 	}
357*b7b65090SSimon Glass 	mb->end = mb->start + size;
358*b7b65090SSimon Glass 
359*b7b65090SSimon Glass 	return 0;
360*b7b65090SSimon Glass }
361*b7b65090SSimon Glass 
membuff_init(struct membuff * mb,char * buff,int size)362*b7b65090SSimon Glass void membuff_init(struct membuff *mb, char *buff, int size)
363*b7b65090SSimon Glass {
364*b7b65090SSimon Glass 	mb->start = buff;
365*b7b65090SSimon Glass 	mb->end = mb->start + size;
366*b7b65090SSimon Glass 	membuff_purge(mb);
367*b7b65090SSimon Glass }
368*b7b65090SSimon Glass 
membuff_new(struct membuff * mb,int size)369*b7b65090SSimon Glass int membuff_new(struct membuff *mb, int size)
370*b7b65090SSimon Glass {
371*b7b65090SSimon Glass 	mb->start = malloc(size);
372*b7b65090SSimon Glass 	if (!mb->start)
373*b7b65090SSimon Glass 		return -ENOMEM;
374*b7b65090SSimon Glass 
375*b7b65090SSimon Glass 	membuff_init(mb, mb->start, size);
376*b7b65090SSimon Glass 	return 0;
377*b7b65090SSimon Glass }
378*b7b65090SSimon Glass 
membuff_uninit(struct membuff * mb)379*b7b65090SSimon Glass void membuff_uninit(struct membuff *mb)
380*b7b65090SSimon Glass {
381*b7b65090SSimon Glass 	mb->end = NULL;
382*b7b65090SSimon Glass 	mb->start = NULL;
383*b7b65090SSimon Glass 	membuff_purge(mb);
384*b7b65090SSimon Glass }
385*b7b65090SSimon Glass 
membuff_dispose(struct membuff * mb)386*b7b65090SSimon Glass void membuff_dispose(struct membuff *mb)
387*b7b65090SSimon Glass {
388*b7b65090SSimon Glass 	free(&mb->start);
389*b7b65090SSimon Glass 	membuff_uninit(mb);
390*b7b65090SSimon Glass }
391