diff options
Diffstat (limited to 'sound/core/rawmidi.c')
| -rw-r--r-- | sound/core/rawmidi.c | 20 | 
1 files changed, 14 insertions, 6 deletions
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 69616d00481c..b53026a72e73 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -635,7 +635,7 @@ static int snd_rawmidi_info_select_user(struct snd_card *card,  int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream,  			      struct snd_rawmidi_params * params)  { -	char *newbuf; +	char *newbuf, *oldbuf;  	struct snd_rawmidi_runtime *runtime = substream->runtime;  	if (substream->append && substream->use_count > 1) @@ -648,13 +648,17 @@ int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream,  		return -EINVAL;  	}  	if (params->buffer_size != runtime->buffer_size) { -		newbuf = krealloc(runtime->buffer, params->buffer_size, -				  GFP_KERNEL); +		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->avail = runtime->buffer_size; +		runtime->appl_ptr = runtime->hw_ptr = 0; +		spin_unlock_irq(&runtime->lock); +		kfree(oldbuf);  	}  	runtime->avail_min = params->avail_min;  	substream->active_sensing = !params->no_active_sensing; @@ -665,7 +669,7 @@ EXPORT_SYMBOL(snd_rawmidi_output_params);  int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream,  			     struct snd_rawmidi_params * params)  { -	char *newbuf; +	char *newbuf, *oldbuf;  	struct snd_rawmidi_runtime *runtime = substream->runtime;  	snd_rawmidi_drain_input(substream); @@ -676,12 +680,16 @@ int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream,  		return -EINVAL;  	}  	if (params->buffer_size != runtime->buffer_size) { -		newbuf = krealloc(runtime->buffer, params->buffer_size, -				  GFP_KERNEL); +		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;  | 
