/* list of slave instances */
static LIST_HEAD(snd_timer_slave_list);
+/* list of open master instances that can accept slave links */
+static LIST_HEAD(snd_timer_master_list);
+
/* lock for slave active lists */
static DEFINE_SPINLOCK(slave_active_lock);
}
INIT_LIST_HEAD(&timeri->open_list);
INIT_LIST_HEAD(&timeri->active_list);
+ INIT_LIST_HEAD(&timeri->master_list);
INIT_LIST_HEAD(&timeri->ack_list);
INIT_LIST_HEAD(&timeri->slave_list_head);
INIT_LIST_HEAD(&timeri->slave_active_head);
return 1;
}
+static bool snd_timer_has_slave_key(const struct snd_timer_instance *timeri)
+{
+ return !(timeri->flags & SNDRV_TIMER_IFLG_SLAVE) &&
+ timeri->slave_class > SNDRV_TIMER_SCLASS_NONE;
+}
+
/*
* look for a master instance matching with the slave id of the given slave.
* when found, relink the open_link of the slave.
*/
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) {
- err = check_matching_master_slave(master, slave);
- if (err != 0) /* match found or error */
- goto out;
- }
+ list_for_each_entry(master, &snd_timer_master_list, master_list) {
+ err = check_matching_master_slave(master, slave);
+ if (err != 0) /* match found or error */
+ goto out;
}
- out:
+out:
return err < 0 ? err : 0;
}
timeri->slave_id = slave_id;
list_add_tail(&timeri->open_list, &timer->open_list_head);
+ if (snd_timer_has_slave_key(timeri))
+ list_add_tail(&timeri->master_list, &snd_timer_master_list);
timer->num_instances++;
err = snd_timer_check_master(timeri);
list_added:
num_slaves--;
}
+ if (!list_empty(&timeri->master_list))
+ list_del_init(&timeri->master_list);
+
/* force to stop the timer */
snd_timer_stop(timeri);