ALSA: control: Keep the previous numid at snd_ctl_rename_id()
authorTakashi Iwai <tiwai@suse.de>
Tue, 6 Jun 2023 09:40:35 +0000 (11:40 +0200)
committerTakashi Iwai <tiwai@suse.de>
Tue, 6 Jun 2023 12:34:30 +0000 (14:34 +0200)
We don't need to change the numid at each time snd_ctl_rename_id() is
called, as the control element size itself doesn't change.  Let's keep
the previous numid value.

Along with it, add a note about calling this function only in the
card init phase.

Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20230606094035.14808-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/core/control.c

index 82aa1af..8386b53 100644 (file)
@@ -730,12 +730,20 @@ EXPORT_SYMBOL_GPL(snd_ctl_activate_id);
  * Finds the control with the old id from the card, and replaces the
  * id with the new one.
  *
+ * The function tries to keep the already assigned numid while replacing
+ * the rest.
+ *
+ * Note that this function should be used only in the card initialization
+ * phase.  Calling after the card instantiation may cause issues with
+ * user-space expecting persistent numids.
+ *
  * Return: Zero if successful, or a negative error code on failure.
  */
 int snd_ctl_rename_id(struct snd_card *card, struct snd_ctl_elem_id *src_id,
                      struct snd_ctl_elem_id *dst_id)
 {
        struct snd_kcontrol *kctl;
+       int saved_numid;
 
        down_write(&card->controls_rwsem);
        kctl = snd_ctl_find_id(card, src_id);
@@ -743,10 +751,10 @@ int snd_ctl_rename_id(struct snd_card *card, struct snd_ctl_elem_id *src_id,
                up_write(&card->controls_rwsem);
                return -ENOENT;
        }
+       saved_numid = kctl->id.numid;
        remove_hash_entries(card, kctl);
        kctl->id = *dst_id;
-       kctl->id.numid = card->last_numid + 1;
-       card->last_numid += kctl->count;
+       kctl->id.numid = saved_numid;
        add_hash_entries(card, kctl);
        up_write(&card->controls_rwsem);
        return 0;