xref: /linux/sound/hda/core/array.c (revision 177bf8620cf4ed290ee170a6c5966adc0924b336)
1*b2660d1eSTakashi Iwai // SPDX-License-Identifier: GPL-2.0-only
2*b2660d1eSTakashi Iwai /*
3*b2660d1eSTakashi Iwai  * generic arrays
4*b2660d1eSTakashi Iwai  */
5*b2660d1eSTakashi Iwai 
6*b2660d1eSTakashi Iwai #include <linux/slab.h>
7*b2660d1eSTakashi Iwai #include <sound/core.h>
8*b2660d1eSTakashi Iwai #include <sound/hdaudio.h>
9*b2660d1eSTakashi Iwai 
10*b2660d1eSTakashi Iwai /**
11*b2660d1eSTakashi Iwai  * snd_array_new - get a new element from the given array
12*b2660d1eSTakashi Iwai  * @array: the array object
13*b2660d1eSTakashi Iwai  *
14*b2660d1eSTakashi Iwai  * Get a new element from the given array.  If it exceeds the
15*b2660d1eSTakashi Iwai  * pre-allocated array size, re-allocate the array.
16*b2660d1eSTakashi Iwai  *
17*b2660d1eSTakashi Iwai  * Returns NULL if allocation failed.
18*b2660d1eSTakashi Iwai  */
snd_array_new(struct snd_array * array)19*b2660d1eSTakashi Iwai void *snd_array_new(struct snd_array *array)
20*b2660d1eSTakashi Iwai {
21*b2660d1eSTakashi Iwai 	if (snd_BUG_ON(!array->elem_size))
22*b2660d1eSTakashi Iwai 		return NULL;
23*b2660d1eSTakashi Iwai 	if (array->used >= array->alloced) {
24*b2660d1eSTakashi Iwai 		int num = array->alloced + array->alloc_align;
25*b2660d1eSTakashi Iwai 		int oldsize = array->alloced * array->elem_size;
26*b2660d1eSTakashi Iwai 		int size = (num + 1) * array->elem_size;
27*b2660d1eSTakashi Iwai 		void *nlist;
28*b2660d1eSTakashi Iwai 		if (snd_BUG_ON(num >= 4096))
29*b2660d1eSTakashi Iwai 			return NULL;
30*b2660d1eSTakashi Iwai 		nlist = krealloc(array->list, size, GFP_KERNEL);
31*b2660d1eSTakashi Iwai 		if (!nlist)
32*b2660d1eSTakashi Iwai 			return NULL;
33*b2660d1eSTakashi Iwai 		memset(nlist + oldsize, 0, size - oldsize);
34*b2660d1eSTakashi Iwai 		array->list = nlist;
35*b2660d1eSTakashi Iwai 		array->alloced = num;
36*b2660d1eSTakashi Iwai 	}
37*b2660d1eSTakashi Iwai 	return snd_array_elem(array, array->used++);
38*b2660d1eSTakashi Iwai }
39*b2660d1eSTakashi Iwai EXPORT_SYMBOL_GPL(snd_array_new);
40*b2660d1eSTakashi Iwai 
41*b2660d1eSTakashi Iwai /**
42*b2660d1eSTakashi Iwai  * snd_array_free - free the given array elements
43*b2660d1eSTakashi Iwai  * @array: the array object
44*b2660d1eSTakashi Iwai  */
snd_array_free(struct snd_array * array)45*b2660d1eSTakashi Iwai void snd_array_free(struct snd_array *array)
46*b2660d1eSTakashi Iwai {
47*b2660d1eSTakashi Iwai 	kfree(array->list);
48*b2660d1eSTakashi Iwai 	array->used = 0;
49*b2660d1eSTakashi Iwai 	array->alloced = 0;
50*b2660d1eSTakashi Iwai 	array->list = NULL;
51*b2660d1eSTakashi Iwai }
52*b2660d1eSTakashi Iwai EXPORT_SYMBOL_GPL(snd_array_free);
53