Commit f5beb598 authored by Takashi Iwai's avatar Takashi Iwai

ALSA: rawmidi: Minor code refactoring

Unify a few open codes with helper functions to improve the
readability.  Minor behavior changes (rather fixes) are:
- runtime->drain clearance is done within lock
- active_sensing is updated before resizing buffer in
  SNDRV_RAWMIDI_IOCTL_PARAMS ioctl.
Other than that, simply code cleanups.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 7fdc9b08
...@@ -164,17 +164,28 @@ static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, i ...@@ -164,17 +164,28 @@ static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, i
cancel_work_sync(&substream->runtime->event_work); cancel_work_sync(&substream->runtime->event_work);
} }
int snd_rawmidi_drop_output(struct snd_rawmidi_substream *substream) static void __reset_runtime_ptrs(struct snd_rawmidi_runtime *runtime,
bool is_input)
{
runtime->drain = 0;
runtime->appl_ptr = runtime->hw_ptr = 0;
runtime->avail = is_input ? 0 : runtime->buffer_size;
}
static void reset_runtime_ptrs(struct snd_rawmidi_runtime *runtime,
bool is_input)
{ {
unsigned long flags; unsigned long flags;
struct snd_rawmidi_runtime *runtime = substream->runtime;
snd_rawmidi_output_trigger(substream, 0);
runtime->drain = 0;
spin_lock_irqsave(&runtime->lock, flags); spin_lock_irqsave(&runtime->lock, flags);
runtime->appl_ptr = runtime->hw_ptr = 0; __reset_runtime_ptrs(runtime, is_input);
runtime->avail = runtime->buffer_size;
spin_unlock_irqrestore(&runtime->lock, flags); spin_unlock_irqrestore(&runtime->lock, flags);
}
int snd_rawmidi_drop_output(struct snd_rawmidi_substream *substream)
{
snd_rawmidi_output_trigger(substream, 0);
reset_runtime_ptrs(substream->runtime, false);
return 0; return 0;
} }
EXPORT_SYMBOL(snd_rawmidi_drop_output); EXPORT_SYMBOL(snd_rawmidi_drop_output);
...@@ -213,15 +224,8 @@ EXPORT_SYMBOL(snd_rawmidi_drain_output); ...@@ -213,15 +224,8 @@ EXPORT_SYMBOL(snd_rawmidi_drain_output);
int snd_rawmidi_drain_input(struct snd_rawmidi_substream *substream) int snd_rawmidi_drain_input(struct snd_rawmidi_substream *substream)
{ {
unsigned long flags;
struct snd_rawmidi_runtime *runtime = substream->runtime;
snd_rawmidi_input_trigger(substream, 0); snd_rawmidi_input_trigger(substream, 0);
runtime->drain = 0; reset_runtime_ptrs(substream->runtime, true);
spin_lock_irqsave(&runtime->lock, flags);
runtime->appl_ptr = runtime->hw_ptr = 0;
runtime->avail = 0;
spin_unlock_irqrestore(&runtime->lock, flags);
return 0; return 0;
} }
EXPORT_SYMBOL(snd_rawmidi_drain_input); EXPORT_SYMBOL(snd_rawmidi_drain_input);
...@@ -639,15 +643,12 @@ static int snd_rawmidi_info_select_user(struct snd_card *card, ...@@ -639,15 +643,12 @@ static int snd_rawmidi_info_select_user(struct snd_card *card,
return 0; return 0;
} }
int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream, static int resize_runtime_buffer(struct snd_rawmidi_runtime *runtime,
struct snd_rawmidi_params *params) struct snd_rawmidi_params *params,
bool is_input)
{ {
char *newbuf, *oldbuf; char *newbuf, *oldbuf;
struct snd_rawmidi_runtime *runtime = substream->runtime;
if (substream->append && substream->use_count > 1)
return -EBUSY;
snd_rawmidi_drain_output(substream);
if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L) if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L)
return -EINVAL; return -EINVAL;
if (params->avail_min < 1 || params->avail_min > params->buffer_size) if (params->avail_min < 1 || params->avail_min > params->buffer_size)
...@@ -660,42 +661,30 @@ int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream, ...@@ -660,42 +661,30 @@ int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream,
oldbuf = runtime->buffer; oldbuf = runtime->buffer;
runtime->buffer = newbuf; runtime->buffer = newbuf;
runtime->buffer_size = params->buffer_size; runtime->buffer_size = params->buffer_size;
runtime->avail = runtime->buffer_size; __reset_runtime_ptrs(runtime, is_input);
runtime->appl_ptr = runtime->hw_ptr = 0;
spin_unlock_irq(&runtime->lock); spin_unlock_irq(&runtime->lock);
kfree(oldbuf); kfree(oldbuf);
} }
runtime->avail_min = params->avail_min; runtime->avail_min = params->avail_min;
substream->active_sensing = !params->no_active_sensing;
return 0; return 0;
} }
int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream,
struct snd_rawmidi_params *params)
{
if (substream->append && substream->use_count > 1)
return -EBUSY;
snd_rawmidi_drain_output(substream);
substream->active_sensing = !params->no_active_sensing;
return resize_runtime_buffer(substream->runtime, params, false);
}
EXPORT_SYMBOL(snd_rawmidi_output_params); EXPORT_SYMBOL(snd_rawmidi_output_params);
int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream, int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream,
struct snd_rawmidi_params *params) struct snd_rawmidi_params *params)
{ {
char *newbuf, *oldbuf;
struct snd_rawmidi_runtime *runtime = substream->runtime;
snd_rawmidi_drain_input(substream); snd_rawmidi_drain_input(substream);
if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L) return resize_runtime_buffer(substream->runtime, params, true);
return -EINVAL;
if (params->avail_min < 1 || params->avail_min > params->buffer_size)
return -EINVAL;
if (params->buffer_size != runtime->buffer_size) {
newbuf = kmalloc(params->buffer_size, GFP_KERNEL);
if (!newbuf)
return -ENOMEM;
spin_lock_irq(&runtime->lock);
oldbuf = runtime->buffer;
runtime->buffer = newbuf;
runtime->buffer_size = params->buffer_size;
runtime->appl_ptr = runtime->hw_ptr = 0;
spin_unlock_irq(&runtime->lock);
kfree(oldbuf);
}
runtime->avail_min = params->avail_min;
return 0;
} }
EXPORT_SYMBOL(snd_rawmidi_input_params); EXPORT_SYMBOL(snd_rawmidi_input_params);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment