diff options
author | Takashi Iwai <tiwai@suse.de> | 2008-11-03 02:17:05 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2008-11-03 02:57:12 -0500 |
commit | 219df32faec97349516c29f33008fea59a46e99a (patch) | |
tree | 36dcaeaa04b23c35e6abbec1b219618b9e459dbb /sound/core/rawmidi.c | |
parent | 8cd2b264d92bb949ddccfb6db6a82254bb07af75 (diff) |
ALSA: rawmidi - Add open check in rawmidi callbacks
The drivers (e.g. mtpav) may call rawmidi functions in irq handlers
even though the streams are not opened. This results in Oops or panic.
This patch adds the rawmidi state check before actually operating the
rawmidi buffers.
Tested-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/core/rawmidi.c')
-rw-r--r-- | sound/core/rawmidi.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index c4995c9f5730..39672f68ce5d 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c | |||
@@ -148,6 +148,8 @@ static int snd_rawmidi_runtime_free(struct snd_rawmidi_substream *substream) | |||
148 | 148 | ||
149 | static inline void snd_rawmidi_output_trigger(struct snd_rawmidi_substream *substream,int up) | 149 | static inline void snd_rawmidi_output_trigger(struct snd_rawmidi_substream *substream,int up) |
150 | { | 150 | { |
151 | if (!substream->opened) | ||
152 | return; | ||
151 | if (up) { | 153 | if (up) { |
152 | tasklet_hi_schedule(&substream->runtime->tasklet); | 154 | tasklet_hi_schedule(&substream->runtime->tasklet); |
153 | } else { | 155 | } else { |
@@ -158,6 +160,8 @@ static inline void snd_rawmidi_output_trigger(struct snd_rawmidi_substream *subs | |||
158 | 160 | ||
159 | static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, int up) | 161 | static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, int up) |
160 | { | 162 | { |
163 | if (!substream->opened) | ||
164 | return; | ||
161 | substream->ops->trigger(substream, up); | 165 | substream->ops->trigger(substream, up); |
162 | if (!up && substream->runtime->event) | 166 | if (!up && substream->runtime->event) |
163 | tasklet_kill(&substream->runtime->tasklet); | 167 | tasklet_kill(&substream->runtime->tasklet); |
@@ -857,6 +861,8 @@ int snd_rawmidi_receive(struct snd_rawmidi_substream *substream, | |||
857 | int result = 0, count1; | 861 | int result = 0, count1; |
858 | struct snd_rawmidi_runtime *runtime = substream->runtime; | 862 | struct snd_rawmidi_runtime *runtime = substream->runtime; |
859 | 863 | ||
864 | if (!substream->opened) | ||
865 | return -EBADFD; | ||
860 | if (runtime->buffer == NULL) { | 866 | if (runtime->buffer == NULL) { |
861 | snd_printd("snd_rawmidi_receive: input is not active!!!\n"); | 867 | snd_printd("snd_rawmidi_receive: input is not active!!!\n"); |
862 | return -EINVAL; | 868 | return -EINVAL; |
@@ -1126,6 +1132,8 @@ int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count) | |||
1126 | int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream, | 1132 | int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream, |
1127 | unsigned char *buffer, int count) | 1133 | unsigned char *buffer, int count) |
1128 | { | 1134 | { |
1135 | if (!substream->opened) | ||
1136 | return -EBADFD; | ||
1129 | count = snd_rawmidi_transmit_peek(substream, buffer, count); | 1137 | count = snd_rawmidi_transmit_peek(substream, buffer, count); |
1130 | if (count < 0) | 1138 | if (count < 0) |
1131 | return count; | 1139 | return count; |