Commit 7dba48a4 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: control_led: Use guard() for locking



We can simplify the code gracefully with new guard() macro and co for
automatic cleanup of locks.

A couple of functions that use snd_card_ref() and *_unref() are also
cleaned up with a defined class, too.

Only the code refactoring, and no functional changes.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20240227085306.9764-25-tiwai@suse.de
parent 3923de04
Loading
Loading
Loading
Loading
+65 −85
Original line number Diff line number Diff line
@@ -147,12 +147,10 @@ static void snd_ctl_led_set_state(struct snd_card *card, unsigned int access,
		return;
	route = -1;
	found = false;
	mutex_lock(&snd_ctl_led_mutex);
	scoped_guard(mutex, &snd_ctl_led_mutex) {
		/* the card may not be registered (active) at this point */
	if (card && !snd_ctl_led_card_valid[card->number]) {
		mutex_unlock(&snd_ctl_led_mutex);
		if (card && !snd_ctl_led_card_valid[card->number])
			return;
	}
		list_for_each_entry(lctl, &led->controls, list) {
			if (lctl->kctl == kctl && lctl->index_offset == ioff)
				found = true;
@@ -169,7 +167,7 @@ static void snd_ctl_led_set_state(struct snd_card *card, unsigned int access,
				UPDATE_ROUTE(route, snd_ctl_led_get(lctl));
			}
		}
	mutex_unlock(&snd_ctl_led_mutex);
	}
	switch (led->mode) {
	case MODE_OFF:		route = 1; break;
	case MODE_ON:		route = 0; break;
@@ -201,14 +199,13 @@ static unsigned int snd_ctl_led_remove(struct snd_kcontrol *kctl, unsigned int i
	struct snd_ctl_led_ctl *lctl;
	unsigned int ret = 0;

	mutex_lock(&snd_ctl_led_mutex);
	guard(mutex)(&snd_ctl_led_mutex);
	lctl = snd_ctl_led_find(kctl, ioff);
	if (lctl && (access == 0 || access != lctl->access)) {
		ret = lctl->access;
		list_del(&lctl->list);
		kfree(lctl);
	}
	mutex_unlock(&snd_ctl_led_mutex);
	return ret;
}

@@ -239,27 +236,28 @@ static void snd_ctl_led_notify(struct snd_card *card, unsigned int mask,
	}
}

DEFINE_FREE(snd_card_unref, struct snd_card *, if (_T) snd_card_unref(_T))

static int snd_ctl_led_set_id(int card_number, struct snd_ctl_elem_id *id,
			      unsigned int group, bool set)
{
	struct snd_card *card;
	struct snd_card *card __free(snd_card_unref) = NULL;
	struct snd_kcontrol *kctl;
	struct snd_kcontrol_volatile *vd;
	unsigned int ioff, access, new_access;
	int err = 0;

	card = snd_card_ref(card_number);
	if (card) {
		down_write(&card->controls_rwsem);
	if (!card)
		return -ENXIO;
	guard(rwsem_write)(&card->controls_rwsem);
	kctl = snd_ctl_find_id_locked(card, id);
		if (kctl) {
	if (!kctl)
		return -ENOENT;
	ioff = snd_ctl_get_ioff(kctl, id);
	vd = &kctl->vd[ioff];
	access = vd->access & SNDRV_CTL_ELEM_ACCESS_LED_MASK;
			if (access != 0 && access != group_to_access(group)) {
				err = -EXDEV;
				goto unlock;
			}
	if (access != 0 && access != group_to_access(group))
		return -EXDEV;
	new_access = vd->access & ~SNDRV_CTL_ELEM_ACCESS_LED_MASK;
	if (set)
		new_access |= group_to_access(group);
@@ -267,16 +265,7 @@ static int snd_ctl_led_set_id(int card_number, struct snd_ctl_elem_id *id,
		vd->access = new_access;
		snd_ctl_led_notify(card, SNDRV_CTL_EVENT_MASK_INFO, kctl, ioff);
	}
		} else {
			err = -ENOENT;
		}
unlock:
		up_write(&card->controls_rwsem);
		snd_card_unref(card);
	} else {
		err = -ENXIO;
	}
	return err;
	return 0;
}

static void snd_ctl_led_refresh(void)
@@ -312,7 +301,7 @@ static void snd_ctl_led_clean(struct snd_card *card)

static int snd_ctl_led_reset(int card_number, unsigned int group)
{
	struct snd_card *card;
	struct snd_card *card __free(snd_card_unref) = NULL;
	struct snd_ctl_led *led;
	struct snd_ctl_led_ctl *lctl;
	struct snd_kcontrol_volatile *vd;
@@ -322,12 +311,9 @@ static int snd_ctl_led_reset(int card_number, unsigned int group)
	if (!card)
		return -ENXIO;

	mutex_lock(&snd_ctl_led_mutex);
	if (!snd_ctl_led_card_valid[card_number]) {
		mutex_unlock(&snd_ctl_led_mutex);
		snd_card_unref(card);
	scoped_guard(mutex, &snd_ctl_led_mutex) {
		if (!snd_ctl_led_card_valid[card_number])
			return -ENXIO;
	}
		led = &snd_ctl_leds[group];
repeat:
		list_for_each_entry(lctl, &led->controls, list)
@@ -338,10 +324,9 @@ static int snd_ctl_led_reset(int card_number, unsigned int group)
				change = true;
				goto repeat;
			}
	mutex_unlock(&snd_ctl_led_mutex);
	}
	if (change)
		snd_ctl_led_set_state(NULL, group_to_access(group), NULL, 0);
	snd_card_unref(card);
	return 0;
}

@@ -353,9 +338,8 @@ static void snd_ctl_led_register(struct snd_card *card)
	if (snd_BUG_ON(card->number < 0 ||
		       card->number >= ARRAY_SIZE(snd_ctl_led_card_valid)))
		return;
	mutex_lock(&snd_ctl_led_mutex);
	scoped_guard(mutex, &snd_ctl_led_mutex)
		snd_ctl_led_card_valid[card->number] = true;
	mutex_unlock(&snd_ctl_led_mutex);
	/* the register callback is already called with held card->controls_rwsem */
	list_for_each_entry(kctl, &card->controls, list)
		for (ioff = 0; ioff < kctl->count; ioff++)
@@ -367,10 +351,10 @@ static void snd_ctl_led_register(struct snd_card *card)
static void snd_ctl_led_disconnect(struct snd_card *card)
{
	snd_ctl_led_sysfs_remove(card);
	mutex_lock(&snd_ctl_led_mutex);
	scoped_guard(mutex, &snd_ctl_led_mutex) {
		snd_ctl_led_card_valid[card->number] = false;
		snd_ctl_led_clean(card);
	mutex_unlock(&snd_ctl_led_mutex);
	}
	snd_ctl_led_refresh();
}

@@ -430,9 +414,8 @@ static ssize_t mode_store(struct device *dev,
	else
		return count;

	mutex_lock(&snd_ctl_led_mutex);
	scoped_guard(mutex, &snd_ctl_led_mutex)
		led->mode = mode;
	mutex_unlock(&snd_ctl_led_mutex);

	snd_ctl_led_set_state(NULL, group_to_access(led->group), NULL, 0);
	return count;
@@ -615,15 +598,15 @@ static ssize_t list_show(struct device *dev,
			 struct device_attribute *attr, char *buf)
{
	struct snd_ctl_led_card *led_card = container_of(dev, struct snd_ctl_led_card, dev);
	struct snd_card *card;
	struct snd_card *card __free(snd_card_unref) = NULL;
	struct snd_ctl_led_ctl *lctl;
	size_t l = 0;

	card = snd_card_ref(led_card->number);
	if (!card)
		return -ENXIO;
	down_read(&card->controls_rwsem);
	mutex_lock(&snd_ctl_led_mutex);
	guard(rwsem_read)(&card->controls_rwsem);
	guard(mutex)(&snd_ctl_led_mutex);
	if (snd_ctl_led_card_valid[led_card->number]) {
		list_for_each_entry(lctl, &led_card->led->controls, list) {
			if (lctl->card != card)
@@ -634,9 +617,6 @@ static ssize_t list_show(struct device *dev,
					   lctl->kctl->id.numid + lctl->index_offset);
		}
	}
	mutex_unlock(&snd_ctl_led_mutex);
	up_read(&card->controls_rwsem);
	snd_card_unref(card);
	return l;
}