Commit ebfc6de2 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: timer: Unify master/slave linking code



The code in both snd_timer_check_master() and snd_timer_check_slave()
are almost identical, both check whether the master/slave link and
does linkage.  Factor out the common code and call it from both
functions for readability.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20191107192008.32331-2-tiwai@suse.de


Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 66a8966a
Loading
Loading
Loading
Loading
+33 −33
Original line number Diff line number Diff line
@@ -163,6 +163,28 @@ static void snd_timer_request(struct snd_timer_id *tid)

#endif

/* move the slave if it belongs to the master; return 1 if match */
static int check_matching_master_slave(struct snd_timer_instance *master,
				       struct snd_timer_instance *slave)
{
	if (slave->slave_class != master->slave_class ||
	    slave->slave_id != master->slave_id)
		return 0;
	if (master->timer->num_instances >= master->timer->max_instances)
		return -EBUSY;
	list_move_tail(&slave->open_list, &master->slave_list_head);
	master->timer->num_instances++;
	spin_lock_irq(&slave_active_lock);
	spin_lock(&master->timer->lock);
	slave->master = master;
	slave->timer = master->timer;
	if (slave->flags & SNDRV_TIMER_IFLG_RUNNING)
		list_add_tail(&slave->active_list, &master->slave_active_head);
	spin_unlock(&master->timer->lock);
	spin_unlock_irq(&slave_active_lock);
	return 1;
}

/*
 * look for a master instance matching with the slave id of the given slave.
 * when found, relink the open_link of the slave.
@@ -173,27 +195,18 @@ static int snd_timer_check_slave(struct snd_timer_instance *slave)
{
	struct snd_timer *timer;
	struct snd_timer_instance *master;
	int err = 0;

	/* FIXME: it's really dumb to look up all entries.. */
	list_for_each_entry(timer, &snd_timer_list, device_list) {
		list_for_each_entry(master, &timer->open_list_head, open_list) {
			if (slave->slave_class == master->slave_class &&
			    slave->slave_id == master->slave_id) {
				if (master->timer->num_instances >=
				    master->timer->max_instances)
					return -EBUSY;
				list_move_tail(&slave->open_list,
					       &master->slave_list_head);
				master->timer->num_instances++;
				spin_lock_irq(&slave_active_lock);
				slave->master = master;
				slave->timer = master->timer;
				spin_unlock_irq(&slave_active_lock);
				return 0;
			err = check_matching_master_slave(master, slave);
			if (err != 0) /* match found or error */
				goto out;
		}
	}
	}
	return 0;
 out:
	return err < 0 ? err : 0;
}

/*
@@ -205,28 +218,15 @@ static int snd_timer_check_slave(struct snd_timer_instance *slave)
static int snd_timer_check_master(struct snd_timer_instance *master)
{
	struct snd_timer_instance *slave, *tmp;
	int err = 0;

	/* check all pending slaves */
	list_for_each_entry_safe(slave, tmp, &snd_timer_slave_list, open_list) {
		if (slave->slave_class == master->slave_class &&
		    slave->slave_id == master->slave_id) {
			if (master->timer->num_instances >=
			    master->timer->max_instances)
				return -EBUSY;
			list_move_tail(&slave->open_list, &master->slave_list_head);
			master->timer->num_instances++;
			spin_lock_irq(&slave_active_lock);
			spin_lock(&master->timer->lock);
			slave->master = master;
			slave->timer = master->timer;
			if (slave->flags & SNDRV_TIMER_IFLG_RUNNING)
				list_add_tail(&slave->active_list,
					      &master->slave_active_head);
			spin_unlock(&master->timer->lock);
			spin_unlock_irq(&slave_active_lock);
		}
		err = check_matching_master_slave(master, slave);
		if (err < 0)
			break;
	}
	return 0;
	return err < 0 ? err : 0;
}

static int snd_timer_close_locked(struct snd_timer_instance *timeri,