aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2014-11-04 08:02:40 -0500
committerTakashi Iwai <tiwai@suse.de>2014-11-04 08:09:16 -0500
commit2b30d411dbc6eddfb5b4f9afd5a2c57b6f4dd96c (patch)
tree02f9efaa6a39b5579eb3f708435ef743b2ab4d09
parentf5914908a5b7b2338f210e56827a1ef35585dc6d (diff)
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: Takashi Iwai <tiwai@suse.de>
-rw-r--r--Documentation/sound/alsa/Procfile.txt4
-rw-r--r--include/sound/pcm.h3
-rw-r--r--sound/core/pcm.c33
3 files changed, 40 insertions, 0 deletions
diff --git a/Documentation/sound/alsa/Procfile.txt b/Documentation/sound/alsa/Procfile.txt
index cfc49567b9dc..7f8a0d325905 100644
--- a/Documentation/sound/alsa/Procfile.txt
+++ b/Documentation/sound/alsa/Procfile.txt
@@ -133,6 +133,10 @@ card*/pcm*/sub*/sw_params
133card*/pcm*/sub*/prealloc 133card*/pcm*/sub*/prealloc
134 The buffer pre-allocation information. 134 The buffer pre-allocation information.
135 135
136card*/pcm*/sub*/xrun_injection
137 Triggers an XRUN to the running stream when any value is
138 written to this proc file. Used for fault injection.
139 This entry is write-only.
136 140
137AC97 Codec Information 141AC97 Codec Information
138---------------------- 142----------------------
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 29eb09ef2969..0b8daeed0a33 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -416,7 +416,10 @@ struct snd_pcm_substream {
416 struct snd_info_entry *proc_status_entry; 416 struct snd_info_entry *proc_status_entry;
417 struct snd_info_entry *proc_prealloc_entry; 417 struct snd_info_entry *proc_prealloc_entry;
418 struct snd_info_entry *proc_prealloc_max_entry; 418 struct snd_info_entry *proc_prealloc_max_entry;
419#ifdef CONFIG_SND_PCM_XRUN_DEBUG
420 struct snd_info_entry *proc_xrun_injection_entry;
419#endif 421#endif
422#endif /* CONFIG_SND_VERBOSE_PROCFS */
420 /* misc flags */ 423 /* misc flags */
421 unsigned int hw_opened: 1; 424 unsigned int hw_opened: 1;
422}; 425};
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 31acc3df62cd..8f624b7af0ca 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -483,6 +483,19 @@ static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
483} 483}
484 484
485#ifdef CONFIG_SND_PCM_XRUN_DEBUG 485#ifdef CONFIG_SND_PCM_XRUN_DEBUG
486static void snd_pcm_xrun_injection_write(struct snd_info_entry *entry,
487 struct snd_info_buffer *buffer)
488{
489 struct snd_pcm_substream *substream = entry->private_data;
490 struct snd_pcm_runtime *runtime;
491
492 snd_pcm_stream_lock_irq(substream);
493 runtime = substream->runtime;
494 if (runtime && runtime->status->state == SNDRV_PCM_STATE_RUNNING)
495 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
496 snd_pcm_stream_unlock_irq(substream);
497}
498
486static void snd_pcm_xrun_debug_read(struct snd_info_entry *entry, 499static void snd_pcm_xrun_debug_read(struct snd_info_entry *entry,
487 struct snd_info_buffer *buffer) 500 struct snd_info_buffer *buffer)
488{ 501{
@@ -614,6 +627,22 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
614 } 627 }
615 substream->proc_status_entry = entry; 628 substream->proc_status_entry = entry;
616 629
630#ifdef CONFIG_SND_PCM_XRUN_DEBUG
631 entry = snd_info_create_card_entry(card, "xrun_injection",
632 substream->proc_root);
633 if (entry) {
634 entry->private_data = substream;
635 entry->c.text.read = NULL;
636 entry->c.text.write = snd_pcm_xrun_injection_write;
637 entry->mode = S_IFREG | S_IWUSR;
638 if (snd_info_register(entry) < 0) {
639 snd_info_free_entry(entry);
640 entry = NULL;
641 }
642 }
643 substream->proc_xrun_injection_entry = entry;
644#endif /* CONFIG_SND_PCM_XRUN_DEBUG */
645
617 return 0; 646 return 0;
618} 647}
619 648
@@ -627,6 +656,10 @@ static int snd_pcm_substream_proc_done(struct snd_pcm_substream *substream)
627 substream->proc_sw_params_entry = NULL; 656 substream->proc_sw_params_entry = NULL;
628 snd_info_free_entry(substream->proc_status_entry); 657 snd_info_free_entry(substream->proc_status_entry);
629 substream->proc_status_entry = NULL; 658 substream->proc_status_entry = NULL;
659#ifdef CONFIG_SND_PCM_XRUN_DEBUG
660 snd_info_free_entry(substream->proc_xrun_injection_entry);
661 substream->proc_xrun_injection_entry = NULL;
662#endif
630 snd_info_free_entry(substream->proc_root); 663 snd_info_free_entry(substream->proc_root);
631 substream->proc_root = NULL; 664 substream->proc_root = NULL;
632 return 0; 665 return 0;