Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2b30d411 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: pcm: Add xrun_injection proc entry



This patch adds a new proc entry for PCM substreams to inject an
XRUN.  When a PCM substream is running and any value is written to its
xrun_injection proc file, the driver triggers XRUN.  This is a useful
feature for debugging XRUN and error handling code paths.

Note that this entry is enabled only when CONFIG_SND_PCM_XRUN_DEBUG is
set.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent f5914908
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -133,6 +133,10 @@ card*/pcm*/sub*/sw_params
card*/pcm*/sub*/prealloc
card*/pcm*/sub*/prealloc
	The buffer pre-allocation information.
	The buffer pre-allocation information.


card*/pcm*/sub*/xrun_injection
	Triggers an XRUN to the running stream when any value is
	written to this proc file.  Used for fault injection.
	This entry is write-only.


AC97 Codec Information
AC97 Codec Information
----------------------
----------------------
+3 −0
Original line number Original line Diff line number Diff line
@@ -416,7 +416,10 @@ struct snd_pcm_substream {
	struct snd_info_entry *proc_status_entry;
	struct snd_info_entry *proc_status_entry;
	struct snd_info_entry *proc_prealloc_entry;
	struct snd_info_entry *proc_prealloc_entry;
	struct snd_info_entry *proc_prealloc_max_entry;
	struct snd_info_entry *proc_prealloc_max_entry;
#ifdef CONFIG_SND_PCM_XRUN_DEBUG
	struct snd_info_entry *proc_xrun_injection_entry;
#endif
#endif
#endif /* CONFIG_SND_VERBOSE_PROCFS */
	/* misc flags */
	/* misc flags */
	unsigned int hw_opened: 1;
	unsigned int hw_opened: 1;
};
};
+33 −0
Original line number Original line Diff line number Diff line
@@ -483,6 +483,19 @@ static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
}
}


#ifdef CONFIG_SND_PCM_XRUN_DEBUG
#ifdef CONFIG_SND_PCM_XRUN_DEBUG
static void snd_pcm_xrun_injection_write(struct snd_info_entry *entry,
					 struct snd_info_buffer *buffer)
{
	struct snd_pcm_substream *substream = entry->private_data;
	struct snd_pcm_runtime *runtime;

	snd_pcm_stream_lock_irq(substream);
	runtime = substream->runtime;
	if (runtime && runtime->status->state == SNDRV_PCM_STATE_RUNNING)
		snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
	snd_pcm_stream_unlock_irq(substream);
}

static void snd_pcm_xrun_debug_read(struct snd_info_entry *entry,
static void snd_pcm_xrun_debug_read(struct snd_info_entry *entry,
				    struct snd_info_buffer *buffer)
				    struct snd_info_buffer *buffer)
{
{
@@ -614,6 +627,22 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
	}
	}
	substream->proc_status_entry = entry;
	substream->proc_status_entry = entry;


#ifdef CONFIG_SND_PCM_XRUN_DEBUG
	entry = snd_info_create_card_entry(card, "xrun_injection",
					   substream->proc_root);
	if (entry) {
		entry->private_data = substream;
		entry->c.text.read = NULL;
		entry->c.text.write = snd_pcm_xrun_injection_write;
		entry->mode = S_IFREG | S_IWUSR;
		if (snd_info_register(entry) < 0) {
			snd_info_free_entry(entry);
			entry = NULL;
		}
	}
	substream->proc_xrun_injection_entry = entry;
#endif /* CONFIG_SND_PCM_XRUN_DEBUG */

	return 0;
	return 0;
}
}


@@ -627,6 +656,10 @@ static int snd_pcm_substream_proc_done(struct snd_pcm_substream *substream)
	substream->proc_sw_params_entry = NULL;
	substream->proc_sw_params_entry = NULL;
	snd_info_free_entry(substream->proc_status_entry);
	snd_info_free_entry(substream->proc_status_entry);
	substream->proc_status_entry = NULL;
	substream->proc_status_entry = NULL;
#ifdef CONFIG_SND_PCM_XRUN_DEBUG
	snd_info_free_entry(substream->proc_xrun_injection_entry);
	substream->proc_xrun_injection_entry = NULL;
#endif
	snd_info_free_entry(substream->proc_root);
	snd_info_free_entry(substream->proc_root);
	substream->proc_root = NULL;
	substream->proc_root = NULL;
	return 0;
	return 0;