summaryrefslogtreecommitdiff
path: root/sound/core/rawmidi.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core/rawmidi.c')
-rw-r--r--sound/core/rawmidi.c32
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(&register_mutex);
if (rmidi->ops && rmidi->ops->dev_unregister)
rmidi->ops->dev_unregister(rmidi);
- mutex_unlock(&register_mutex);
snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]);
snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]);