Loading include/sound/rawmidi.h +1 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,7 @@ struct snd_rawmidi_runtime { size_t xruns; /* over/underruns counter */ /* misc */ spinlock_t lock; struct mutex realloc_mutex; wait_queue_head_t sleep; /* event handler (new bytes, input only) */ void (*event)(struct snd_rawmidi_substream *substream); Loading sound/core/rawmidi.c +39 −5 Original line number Diff line number Diff line Loading @@ -115,6 +115,7 @@ static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream) return -ENOMEM; runtime->substream = substream; spin_lock_init(&runtime->lock); mutex_init(&runtime->realloc_mutex); init_waitqueue_head(&runtime->sleep); INIT_WORK(&runtime->event_work, snd_rawmidi_input_event_work); runtime->event = NULL; Loading Loading @@ -627,7 +628,9 @@ int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream, struct snd_rawmidi_params * params) { char *newbuf; char *oldbuf; struct snd_rawmidi_runtime *runtime = substream->runtime; unsigned long flags; if (substream->append && substream->use_count > 1) return -EBUSY; Loading @@ -639,13 +642,22 @@ 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, mutex_lock(&runtime->realloc_mutex); newbuf = __krealloc(runtime->buffer, params->buffer_size, GFP_KERNEL); if (!newbuf) if (!newbuf) { mutex_unlock(&runtime->realloc_mutex); return -ENOMEM; } spin_lock_irqsave(&runtime->lock, flags); oldbuf = runtime->buffer; runtime->buffer = newbuf; runtime->buffer_size = params->buffer_size; runtime->avail = runtime->buffer_size; spin_unlock_irqrestore(&runtime->lock, flags); if (oldbuf != newbuf) kfree(oldbuf); mutex_unlock(&runtime->realloc_mutex); } runtime->avail_min = params->avail_min; substream->active_sensing = !params->no_active_sensing; Loading @@ -657,7 +669,9 @@ int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream, struct snd_rawmidi_params * params) { char *newbuf; char *oldbuf; struct snd_rawmidi_runtime *runtime = substream->runtime; unsigned long flags; snd_rawmidi_drain_input(substream); if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L) { Loading @@ -667,12 +681,21 @@ 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, mutex_lock(&runtime->realloc_mutex); newbuf = __krealloc(runtime->buffer, params->buffer_size, GFP_KERNEL); if (!newbuf) if (!newbuf) { mutex_unlock(&runtime->realloc_mutex); return -ENOMEM; } spin_lock_irqsave(&runtime->lock, flags); oldbuf = runtime->buffer; runtime->buffer = newbuf; runtime->buffer_size = params->buffer_size; spin_unlock_irqrestore(&runtime->lock, flags); if (oldbuf != newbuf) kfree(oldbuf); mutex_unlock(&runtime->realloc_mutex); } runtime->avail_min = params->avail_min; return 0; Loading Loading @@ -945,6 +968,8 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream, unsigned long appl_ptr; spin_lock_irqsave(&runtime->lock, flags); if (userbuf) mutex_lock(&runtime->realloc_mutex); while (count > 0 && runtime->avail) { count1 = runtime->buffer_size - runtime->appl_ptr; if (count1 > count) Loading @@ -964,6 +989,7 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream, spin_unlock_irqrestore(&runtime->lock, flags); if (copy_to_user(userbuf + result, runtime->buffer + appl_ptr, count1)) { mutex_unlock(&runtime->realloc_mutex); return result > 0 ? result : -EFAULT; } spin_lock_irqsave(&runtime->lock, flags); Loading @@ -972,6 +998,8 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream, count -= count1; } spin_unlock_irqrestore(&runtime->lock, flags); if (userbuf) mutex_unlock(&runtime->realloc_mutex); return result; } Loading Loading @@ -1236,10 +1264,14 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, return -EINVAL; result = 0; if (userbuf) mutex_lock(&runtime->realloc_mutex); spin_lock_irqsave(&runtime->lock, flags); if (substream->append) { if ((long)runtime->avail < count) { spin_unlock_irqrestore(&runtime->lock, flags); if (userbuf) mutex_unlock(&runtime->realloc_mutex); return -EAGAIN; } } Loading Loading @@ -1275,6 +1307,8 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, __end: count1 = runtime->avail < runtime->buffer_size; spin_unlock_irqrestore(&runtime->lock, flags); if (userbuf) mutex_unlock(&runtime->realloc_mutex); if (count1) snd_rawmidi_output_trigger(substream, 1); return result; Loading sound/core/seq/seq_clientmgr.c +5 −1 Original line number Diff line number Diff line Loading @@ -1260,6 +1260,7 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, struct snd_seq_client_port *port; struct snd_seq_port_info info; struct snd_seq_port_callback *callback; int port_idx; if (copy_from_user(&info, arg, sizeof(info))) return -EFAULT; Loading @@ -1273,7 +1274,9 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, return -ENOMEM; if (client->type == USER_CLIENT && info.kernel) { snd_seq_delete_port(client, port->addr.port); port_idx = port->addr.port; snd_seq_port_unlock(port); snd_seq_delete_port(client, port_idx); return -EINVAL; } if (client->type == KERNEL_CLIENT) { Loading @@ -1294,6 +1297,7 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, snd_seq_set_port_info(port, &info); snd_seq_system_client_ev_port_start(port->addr.client, port->addr.port); snd_seq_port_unlock(port); if (copy_to_user(arg, &info, sizeof(info))) return -EFAULT; Loading sound/core/seq/seq_ports.c +5 −2 Original line number Diff line number Diff line Loading @@ -122,7 +122,9 @@ static void port_subs_info_init(struct snd_seq_port_subs_info *grp) } /* create a port, port number is returned (-1 on failure) */ /* create a port, port number is returned (-1 on failure); * the caller needs to unref the port via snd_seq_port_unlock() appropriately */ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, int port) { Loading Loading @@ -151,6 +153,7 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, snd_use_lock_init(&new_port->use_lock); port_subs_info_init(&new_port->c_src); port_subs_info_init(&new_port->c_dest); snd_use_lock_use(&new_port->use_lock); num = port >= 0 ? port : 0; mutex_lock(&client->ports_mutex); Loading @@ -165,9 +168,9 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, list_add_tail(&new_port->list, &p->list); client->num_ports++; new_port->addr.port = num; /* store the port number in the port */ sprintf(new_port->name, "port-%d", num); write_unlock_irqrestore(&client->ports_lock, flags); mutex_unlock(&client->ports_mutex); sprintf(new_port->name, "port-%d", num); return new_port; } Loading Loading
include/sound/rawmidi.h +1 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,7 @@ struct snd_rawmidi_runtime { size_t xruns; /* over/underruns counter */ /* misc */ spinlock_t lock; struct mutex realloc_mutex; wait_queue_head_t sleep; /* event handler (new bytes, input only) */ void (*event)(struct snd_rawmidi_substream *substream); Loading
sound/core/rawmidi.c +39 −5 Original line number Diff line number Diff line Loading @@ -115,6 +115,7 @@ static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream) return -ENOMEM; runtime->substream = substream; spin_lock_init(&runtime->lock); mutex_init(&runtime->realloc_mutex); init_waitqueue_head(&runtime->sleep); INIT_WORK(&runtime->event_work, snd_rawmidi_input_event_work); runtime->event = NULL; Loading Loading @@ -627,7 +628,9 @@ int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream, struct snd_rawmidi_params * params) { char *newbuf; char *oldbuf; struct snd_rawmidi_runtime *runtime = substream->runtime; unsigned long flags; if (substream->append && substream->use_count > 1) return -EBUSY; Loading @@ -639,13 +642,22 @@ 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, mutex_lock(&runtime->realloc_mutex); newbuf = __krealloc(runtime->buffer, params->buffer_size, GFP_KERNEL); if (!newbuf) if (!newbuf) { mutex_unlock(&runtime->realloc_mutex); return -ENOMEM; } spin_lock_irqsave(&runtime->lock, flags); oldbuf = runtime->buffer; runtime->buffer = newbuf; runtime->buffer_size = params->buffer_size; runtime->avail = runtime->buffer_size; spin_unlock_irqrestore(&runtime->lock, flags); if (oldbuf != newbuf) kfree(oldbuf); mutex_unlock(&runtime->realloc_mutex); } runtime->avail_min = params->avail_min; substream->active_sensing = !params->no_active_sensing; Loading @@ -657,7 +669,9 @@ int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream, struct snd_rawmidi_params * params) { char *newbuf; char *oldbuf; struct snd_rawmidi_runtime *runtime = substream->runtime; unsigned long flags; snd_rawmidi_drain_input(substream); if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L) { Loading @@ -667,12 +681,21 @@ 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, mutex_lock(&runtime->realloc_mutex); newbuf = __krealloc(runtime->buffer, params->buffer_size, GFP_KERNEL); if (!newbuf) if (!newbuf) { mutex_unlock(&runtime->realloc_mutex); return -ENOMEM; } spin_lock_irqsave(&runtime->lock, flags); oldbuf = runtime->buffer; runtime->buffer = newbuf; runtime->buffer_size = params->buffer_size; spin_unlock_irqrestore(&runtime->lock, flags); if (oldbuf != newbuf) kfree(oldbuf); mutex_unlock(&runtime->realloc_mutex); } runtime->avail_min = params->avail_min; return 0; Loading Loading @@ -945,6 +968,8 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream, unsigned long appl_ptr; spin_lock_irqsave(&runtime->lock, flags); if (userbuf) mutex_lock(&runtime->realloc_mutex); while (count > 0 && runtime->avail) { count1 = runtime->buffer_size - runtime->appl_ptr; if (count1 > count) Loading @@ -964,6 +989,7 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream, spin_unlock_irqrestore(&runtime->lock, flags); if (copy_to_user(userbuf + result, runtime->buffer + appl_ptr, count1)) { mutex_unlock(&runtime->realloc_mutex); return result > 0 ? result : -EFAULT; } spin_lock_irqsave(&runtime->lock, flags); Loading @@ -972,6 +998,8 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream, count -= count1; } spin_unlock_irqrestore(&runtime->lock, flags); if (userbuf) mutex_unlock(&runtime->realloc_mutex); return result; } Loading Loading @@ -1236,10 +1264,14 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, return -EINVAL; result = 0; if (userbuf) mutex_lock(&runtime->realloc_mutex); spin_lock_irqsave(&runtime->lock, flags); if (substream->append) { if ((long)runtime->avail < count) { spin_unlock_irqrestore(&runtime->lock, flags); if (userbuf) mutex_unlock(&runtime->realloc_mutex); return -EAGAIN; } } Loading Loading @@ -1275,6 +1307,8 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, __end: count1 = runtime->avail < runtime->buffer_size; spin_unlock_irqrestore(&runtime->lock, flags); if (userbuf) mutex_unlock(&runtime->realloc_mutex); if (count1) snd_rawmidi_output_trigger(substream, 1); return result; Loading
sound/core/seq/seq_clientmgr.c +5 −1 Original line number Diff line number Diff line Loading @@ -1260,6 +1260,7 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, struct snd_seq_client_port *port; struct snd_seq_port_info info; struct snd_seq_port_callback *callback; int port_idx; if (copy_from_user(&info, arg, sizeof(info))) return -EFAULT; Loading @@ -1273,7 +1274,9 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, return -ENOMEM; if (client->type == USER_CLIENT && info.kernel) { snd_seq_delete_port(client, port->addr.port); port_idx = port->addr.port; snd_seq_port_unlock(port); snd_seq_delete_port(client, port_idx); return -EINVAL; } if (client->type == KERNEL_CLIENT) { Loading @@ -1294,6 +1297,7 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, snd_seq_set_port_info(port, &info); snd_seq_system_client_ev_port_start(port->addr.client, port->addr.port); snd_seq_port_unlock(port); if (copy_to_user(arg, &info, sizeof(info))) return -EFAULT; Loading
sound/core/seq/seq_ports.c +5 −2 Original line number Diff line number Diff line Loading @@ -122,7 +122,9 @@ static void port_subs_info_init(struct snd_seq_port_subs_info *grp) } /* create a port, port number is returned (-1 on failure) */ /* create a port, port number is returned (-1 on failure); * the caller needs to unref the port via snd_seq_port_unlock() appropriately */ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, int port) { Loading Loading @@ -151,6 +153,7 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, snd_use_lock_init(&new_port->use_lock); port_subs_info_init(&new_port->c_src); port_subs_info_init(&new_port->c_dest); snd_use_lock_use(&new_port->use_lock); num = port >= 0 ? port : 0; mutex_lock(&client->ports_mutex); Loading @@ -165,9 +168,9 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, list_add_tail(&new_port->list, &p->list); client->num_ports++; new_port->addr.port = num; /* store the port number in the port */ sprintf(new_port->name, "port-%d", num); write_unlock_irqrestore(&client->ports_lock, flags); mutex_unlock(&client->ports_mutex); sprintf(new_port->name, "port-%d", num); return new_port; } Loading