diff options
Diffstat (limited to 'sound/core/rawmidi.c')
-rw-r--r-- | sound/core/rawmidi.c | 32 |
1 files changed, 8 insertions, 24 deletions
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 11fdc1d9797e..a7a1b1c4cad9 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -108,17 +108,6 @@ static void snd_rawmidi_input_event_work(struct work_struct *work) runtime->event(runtime->substream); } -/* buffer refcount management: call with runtime->lock held */ -static inline void snd_rawmidi_buffer_ref(struct snd_rawmidi_runtime *runtime) -{ - runtime->buffer_ref++; -} - -static inline void snd_rawmidi_buffer_unref(struct snd_rawmidi_runtime *runtime) -{ - runtime->buffer_ref--; -} - static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream) { struct snd_rawmidi_runtime *runtime; @@ -676,6 +665,7 @@ int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream, runtime->buffer = newbuf; runtime->buffer_size = params->buffer_size; runtime->avail = runtime->buffer_size; + runtime->appl_ptr = runtime->hw_ptr = 0; spin_unlock_irqrestore(&runtime->lock, flags); if (oldbuf != newbuf) kfree(oldbuf); @@ -714,6 +704,7 @@ int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream, oldbuf = runtime->buffer; runtime->buffer = newbuf; runtime->buffer_size = params->buffer_size; + runtime->appl_ptr = runtime->hw_ptr = 0; spin_unlock_irqrestore(&runtime->lock, flags); if (oldbuf != newbuf) kfree(oldbuf); @@ -988,12 +979,10 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream, long result = 0, count1; struct snd_rawmidi_runtime *runtime = substream->runtime; unsigned long appl_ptr; - int err = 0; if (userbuf) mutex_lock(&runtime->realloc_mutex); spin_lock_irqsave(&runtime->lock, flags); - snd_rawmidi_buffer_ref(runtime); while (count > 0 && runtime->avail) { count1 = runtime->buffer_size - runtime->appl_ptr; if (count1 > count) @@ -1012,21 +1001,20 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream, if (userbuf) { spin_unlock_irqrestore(&runtime->lock, flags); if (copy_to_user(userbuf + result, - runtime->buffer + appl_ptr, count1)) - err = -EFAULT; + runtime->buffer + appl_ptr, count1)) { + mutex_unlock(&runtime->realloc_mutex); + return result > 0 ? result : -EFAULT; + } + spin_lock_irqsave(&runtime->lock, flags); - if (err) - goto out; } result += count1; count -= count1; } - out: - snd_rawmidi_buffer_unref(runtime); spin_unlock_irqrestore(&runtime->lock, flags); if (userbuf) mutex_unlock(&runtime->realloc_mutex); - return result > 0 ? result : err; + return result; } long snd_rawmidi_kernel_read(struct snd_rawmidi_substream *substream, @@ -1301,7 +1289,6 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, return -EAGAIN; } } - snd_rawmidi_buffer_ref(runtime); while (count > 0 && runtime->avail > 0) { count1 = runtime->buffer_size - runtime->appl_ptr; if (count1 > count) @@ -1333,7 +1320,6 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, } __end: count1 = runtime->avail < runtime->buffer_size; - snd_rawmidi_buffer_unref(runtime); spin_unlock_irqrestore(&runtime->lock, flags); if (userbuf) mutex_unlock(&runtime->realloc_mutex); @@ -1653,10 +1639,8 @@ static int snd_rawmidi_free(struct snd_rawmidi *rmidi) snd_info_free_entry(rmidi->proc_entry); rmidi->proc_entry = NULL; - mutex_lock(®ister_mutex); if (rmidi->ops && rmidi->ops->dev_unregister) rmidi->ops->dev_unregister(rmidi); - mutex_unlock(®ister_mutex); snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]); snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]); |