static int snd_pcm_unlink(struct snd_pcm_substream *substream)
{
	struct snd_pcm_group *group;
	bool nonatomic = substream->pcm->nonatomic;
	bool do_free = false;
	int res = 0;

	down_write(&snd_pcm_link_rwsem);

	if (!snd_pcm_stream_linked(substream)) {
		res = -EALREADY;
		goto _end;
	}

	group = substream->group;
	snd_pcm_group_lock_irq(group, nonatomic);

	relink_to_local(substream);
	refcount_dec(&group->refs);

	/* detach the last stream, too */
	if (list_is_singular(&group->substreams)) {
		relink_to_local(list_first_entry(&group->substreams,
						 struct snd_pcm_substream,
						 link_list));
		do_free = refcount_dec_and_test(&group->refs);
	}

	snd_pcm_group_unlock_irq(group, nonatomic);
	if (do_free)
		kfree(group);

       _end:
	up_write(&snd_pcm_link_rwsem);
	return res;
}
static int snd_pcm_unlink(struct snd_pcm_substream *substream)
{
	struct snd_pcm_group *group;
	bool nonatomic = substream->pcm->nonatomic;
	bool do_free = false;
	int res = 0;

	down_write(&snd_pcm_link_rwsem);

	if (!snd_pcm_stream_linked(substream)) {
		res = -EALREADY;
		goto _end;
	}

	group = substream->group;
	snd_pcm_group_lock_irq(group, nonatomic);

	relink_to_local(substream);
	refcount_dec(&group->refs);

	 
	if (list_is_singular(&group->substreams)) {
		relink_to_local(list_first_entry(&group->substreams,
						 struct snd_pcm_substream,
						 link_list));
		do_free = refcount_dec_and_test(&group->refs);
	}

	snd_pcm_group_unlock_irq(group, nonatomic);
	if (do_free)
		kfree(group);

       _end:
	up_write(&snd_pcm_link_rwsem);
	return res;
}