ALSA: core: use precomputed table to check userspace control params
The parameters can be decided in compile time. This commit adds precomputed table to reduce calculating time. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
ce99198131
commit
4ed56666b7
@ -1161,6 +1161,23 @@ static void snd_ctl_elem_user_free(struct snd_kcontrol *kcontrol)
|
||||
static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||
struct snd_ctl_elem_info *info, int replace)
|
||||
{
|
||||
/* The capacity of struct snd_ctl_elem_value.value.*/
|
||||
static const unsigned int value_sizes[] = {
|
||||
[SNDRV_CTL_ELEM_TYPE_BOOLEAN] = sizeof(long),
|
||||
[SNDRV_CTL_ELEM_TYPE_INTEGER] = sizeof(long),
|
||||
[SNDRV_CTL_ELEM_TYPE_ENUMERATED] = sizeof(unsigned int),
|
||||
[SNDRV_CTL_ELEM_TYPE_BYTES] = sizeof(unsigned char),
|
||||
[SNDRV_CTL_ELEM_TYPE_IEC958] = sizeof(struct snd_aes_iec958),
|
||||
[SNDRV_CTL_ELEM_TYPE_INTEGER64] = sizeof(long long),
|
||||
};
|
||||
static const unsigned int max_value_counts[] = {
|
||||
[SNDRV_CTL_ELEM_TYPE_BOOLEAN] = 128,
|
||||
[SNDRV_CTL_ELEM_TYPE_INTEGER] = 128,
|
||||
[SNDRV_CTL_ELEM_TYPE_ENUMERATED] = 128,
|
||||
[SNDRV_CTL_ELEM_TYPE_BYTES] = 512,
|
||||
[SNDRV_CTL_ELEM_TYPE_IEC958] = 1,
|
||||
[SNDRV_CTL_ELEM_TYPE_INTEGER64] = 64,
|
||||
};
|
||||
struct snd_card *card = file->card;
|
||||
struct snd_kcontrol kctl, *_kctl;
|
||||
unsigned int access;
|
||||
@ -1168,8 +1185,6 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||
struct user_element *ue;
|
||||
int idx, err;
|
||||
|
||||
if (info->count < 1)
|
||||
return -EINVAL;
|
||||
access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
|
||||
(info->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|
|
||||
SNDRV_CTL_ELEM_ACCESS_INACTIVE|
|
||||
@ -1201,37 +1216,18 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||
kctl.tlv.c = snd_ctl_elem_user_tlv;
|
||||
access |= SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
|
||||
}
|
||||
switch (info->type) {
|
||||
case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
|
||||
case SNDRV_CTL_ELEM_TYPE_INTEGER:
|
||||
private_size = sizeof(long);
|
||||
if (info->count > 128)
|
||||
return -EINVAL;
|
||||
break;
|
||||
case SNDRV_CTL_ELEM_TYPE_INTEGER64:
|
||||
private_size = sizeof(long long);
|
||||
if (info->count > 64)
|
||||
return -EINVAL;
|
||||
break;
|
||||
case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
|
||||
private_size = sizeof(unsigned int);
|
||||
if (info->count > 128 || info->value.enumerated.items == 0)
|
||||
return -EINVAL;
|
||||
break;
|
||||
case SNDRV_CTL_ELEM_TYPE_BYTES:
|
||||
private_size = sizeof(unsigned char);
|
||||
if (info->count > 512)
|
||||
return -EINVAL;
|
||||
break;
|
||||
case SNDRV_CTL_ELEM_TYPE_IEC958:
|
||||
private_size = sizeof(struct snd_aes_iec958);
|
||||
if (info->count != 1)
|
||||
return -EINVAL;
|
||||
break;
|
||||
default:
|
||||
|
||||
if (info->type < SNDRV_CTL_ELEM_TYPE_BOOLEAN ||
|
||||
info->type > SNDRV_CTL_ELEM_TYPE_INTEGER64)
|
||||
return -EINVAL;
|
||||
}
|
||||
private_size *= info->count;
|
||||
if (info->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED &&
|
||||
info->value.enumerated.items == 0)
|
||||
return -EINVAL;
|
||||
if (info->count < 1 ||
|
||||
info->count > max_value_counts[info->type])
|
||||
return -EINVAL;
|
||||
|
||||
private_size = value_sizes[info->type] * info->count;
|
||||
ue = kzalloc(sizeof(struct user_element) + private_size, GFP_KERNEL);
|
||||
if (ue == NULL)
|
||||
return -ENOMEM;
|
||||
|
Loading…
x
Reference in New Issue
Block a user