]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
ALSA: control: Consolidate helpers for adding and replacing ctl elements
authorTakashi Iwai <tiwai@suse.de>
Thu, 22 Nov 2018 14:22:40 +0000 (15:22 +0100)
committerTakashi Iwai <tiwai@suse.de>
Sat, 24 Nov 2018 19:04:10 +0000 (20:04 +0100)
Both snd_ctl_add() and snd_ctl_replace() process the things in a
fairly similar way, and indeed the most of the codes can be unified.

This patch is a refactoring to consolidate the both functions to call
a single helper with an extra "mode" argument.  There should be no
functional difference, except for one additional sanity check applied
now to snd_ctl_replace() (which was rather overlooking, IMO), too.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/core/control.c

index 649d3217590ed465c6e13e39bdeb2f9e53a4a2e5..fad7db40244341e4d93528953c541de74c62c5c8 100644 (file)
@@ -348,22 +348,41 @@ static int snd_ctl_find_hole(struct snd_card *card, unsigned int count)
        return 0;
 }
 
-/* add a new kcontrol object; call with card->controls_rwsem locked */
-static int __snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
+enum snd_ctl_add_mode {
+       CTL_ADD_EXCLUSIVE, CTL_REPLACE, CTL_ADD_ON_REPLACE,
+};
+
+/* add/replace a new kcontrol object; call with card->controls_rwsem locked */
+static int __snd_ctl_add_replace(struct snd_card *card,
+                                struct snd_kcontrol *kcontrol,
+                                enum snd_ctl_add_mode mode)
 {
        struct snd_ctl_elem_id id;
        unsigned int idx;
        unsigned int count;
+       struct snd_kcontrol *old;
+       int err;
 
        id = kcontrol->id;
        if (id.index > UINT_MAX - kcontrol->count)
                return -EINVAL;
 
-       if (snd_ctl_find_id(card, &id)) {
-               dev_err(card->dev,
-                       "control %i:%i:%i:%s:%i is already present\n",
-                       id.iface, id.device, id.subdevice, id.name, id.index);
-               return -EBUSY;
+       old = snd_ctl_find_id(card, &id);
+       if (!old) {
+               if (mode == CTL_REPLACE)
+                       return -EINVAL;
+       } else {
+               if (mode == CTL_ADD_EXCLUSIVE) {
+                       dev_err(card->dev,
+                               "control %i:%i:%i:%s:%i is already present\n",
+                               id.iface, id.device, id.subdevice, id.name,
+                               id.index);
+                       return -EBUSY;
+               }
+
+               err = snd_ctl_remove(card, old);
+               if (err < 0)
+                       return err;
        }
 
        if (snd_ctl_find_hole(card, kcontrol->count) < 0)
@@ -382,21 +401,9 @@ static int __snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
        return 0;
 }
 
-/**
- * snd_ctl_add - add the control instance to the card
- * @card: the card instance
- * @kcontrol: the control instance to add
- *
- * Adds the control instance created via snd_ctl_new() or
- * snd_ctl_new1() to the given card. Assigns also an unique
- * numid used for fast search.
- *
- * It frees automatically the control which cannot be added.
- *
- * Return: Zero if successful, or a negative error code on failure.
- *
- */
-int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
+static int snd_ctl_add_replace(struct snd_card *card,
+                              struct snd_kcontrol *kcontrol,
+                              enum snd_ctl_add_mode mode)
 {
        int err = -EINVAL;
 
@@ -406,7 +413,7 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
                goto error;
 
        down_write(&card->controls_rwsem);
-       err = __snd_ctl_add(card, kcontrol);
+       err = __snd_ctl_add_replace(card, kcontrol, mode);
        up_write(&card->controls_rwsem);
        if (err < 0)
                goto error;
@@ -416,6 +423,25 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
        snd_ctl_free_one(kcontrol);
        return err;
 }
+
+/**
+ * snd_ctl_add - add the control instance to the card
+ * @card: the card instance
+ * @kcontrol: the control instance to add
+ *
+ * Adds the control instance created via snd_ctl_new() or
+ * snd_ctl_new1() to the given card. Assigns also an unique
+ * numid used for fast search.
+ *
+ * It frees automatically the control which cannot be added.
+ *
+ * Return: Zero if successful, or a negative error code on failure.
+ *
+ */
+int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
+{
+       return snd_ctl_add_replace(card, kcontrol, CTL_ADD_EXCLUSIVE);
+}
 EXPORT_SYMBOL(snd_ctl_add);
 
 /**
@@ -435,53 +461,8 @@ EXPORT_SYMBOL(snd_ctl_add);
 int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol,
                    bool add_on_replace)
 {
-       struct snd_ctl_elem_id id;
-       unsigned int count;
-       unsigned int idx;
-       struct snd_kcontrol *old;
-       int ret;
-
-       if (!kcontrol)
-               return -EINVAL;
-       if (snd_BUG_ON(!card || !kcontrol->info)) {
-               ret = -EINVAL;
-               goto error;
-       }
-       id = kcontrol->id;
-       down_write(&card->controls_rwsem);
-       old = snd_ctl_find_id(card, &id);
-       if (!old) {
-               if (add_on_replace)
-                       goto add;
-               up_write(&card->controls_rwsem);
-               ret = -EINVAL;
-               goto error;
-       }
-       ret = snd_ctl_remove(card, old);
-       if (ret < 0) {
-               up_write(&card->controls_rwsem);
-               goto error;
-       }
-add:
-       if (snd_ctl_find_hole(card, kcontrol->count) < 0) {
-               up_write(&card->controls_rwsem);
-               ret = -ENOMEM;
-               goto error;
-       }
-       list_add_tail(&kcontrol->list, &card->controls);
-       card->controls_count += kcontrol->count;
-       kcontrol->id.numid = card->last_numid + 1;
-       card->last_numid += kcontrol->count;
-       id = kcontrol->id;
-       count = kcontrol->count;
-       up_write(&card->controls_rwsem);
-       for (idx = 0; idx < count; idx++, id.index++, id.numid++)
-               snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
-       return 0;
-
-error:
-       snd_ctl_free_one(kcontrol);
-       return ret;
+       return snd_ctl_add_replace(card, kcontrol,
+                                  add_on_replace ? CTL_ADD_ON_REPLACE : CTL_REPLACE);
 }
 EXPORT_SYMBOL(snd_ctl_replace);
 
@@ -1369,7 +1350,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
 
        /* This function manage to free the instance on failure. */
        down_write(&card->controls_rwsem);
-       err = __snd_ctl_add(card, kctl);
+       err = __snd_ctl_add_replace(card, kctl, CTL_ADD_EXCLUSIVE);
        if (err < 0) {
                snd_ctl_free_one(kctl);
                goto unlock;