diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index 5719637575a9..19d6fea012f6 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c @@ -1287,7 +1287,7 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, void *arg) port_idx = -1; if (port_idx >= SNDRV_SEQ_ADDRESS_UNKNOWN) return -EINVAL; - err = snd_seq_create_port(client, port_idx, &port); + err = snd_seq_create_port(client, &port); if (err < 0) return err; @@ -1309,6 +1309,11 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, void *arg) info->addr = port->addr; snd_seq_set_port_info(port, info); + err = snd_seq_insert_port(client, port_idx, port); + if (err < 0) { + kfree(port); + return err; + } if (info->capability & SNDRV_SEQ_PORT_CAP_UMP_ENDPOINT) client->ump_endpoint_port = port->addr.port; snd_seq_system_client_ev_port_start(port->addr.client, port->addr.port); diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c index 31ab4681c601..17daacd4476a 100644 --- a/sound/core/seq/seq_ports.c +++ b/sound/core/seq/seq_ports.c @@ -108,14 +108,13 @@ static void port_subs_info_init(struct snd_seq_port_subs_info *grp) } -/* create a port, port number or a negative error code is returned +/* create a port, 0 on success or a negative error code is returned * the caller needs to unref the port via snd_seq_port_unlock() appropriately */ -int snd_seq_create_port(struct snd_seq_client *client, int port, +int snd_seq_create_port(struct snd_seq_client *client, struct snd_seq_client_port **port_ret) { - struct snd_seq_client_port *new_port, *p; - int num; + struct snd_seq_client_port *new_port; *port_ret = NULL; @@ -141,15 +140,25 @@ int snd_seq_create_port(struct snd_seq_client *client, int port, port_subs_info_init(&new_port->c_dest); snd_use_lock_use(&new_port->use_lock); + *port_ret = new_port; + + return 0; +} + +/* insert the port; return the port address or a negative error code */ +int snd_seq_insert_port(struct snd_seq_client *client, int port, + struct snd_seq_client_port *new_port) +{ + struct snd_seq_client_port *p; + int num; + num = max(port, 0); guard(mutex)(&client->ports_mutex); guard(write_lock_irq)(&client->ports_lock); struct list_head *insert_before = &client->ports_list_head; list_for_each_entry(p, &client->ports_list_head, list) { - if (p->addr.port == port) { - kfree(new_port); + if (p->addr.port == port) return -EBUSY; - } if (p->addr.port > num) { insert_before = &p->list; break; @@ -162,7 +171,6 @@ int snd_seq_create_port(struct snd_seq_client *client, int port, client->num_ports++; new_port->addr.port = num; /* store the port number in the port */ sprintf(new_port->name, "port-%d", num); - *port_ret = new_port; return num; } diff --git a/sound/core/seq/seq_ports.h b/sound/core/seq/seq_ports.h index 40ed6cf7cb90..b689c0f4867c 100644 --- a/sound/core/seq/seq_ports.h +++ b/sound/core/seq/seq_ports.h @@ -98,10 +98,14 @@ struct snd_seq_client_port *snd_seq_port_query_nearest(struct snd_seq_client *cl DEFINE_FREE(snd_seq_port, struct snd_seq_client_port *, if (!IS_ERR_OR_NULL(_T)) snd_seq_port_unlock(_T)) -/* create a port, port number or a negative error code is returned */ -int snd_seq_create_port(struct snd_seq_client *client, int port_index, +/* create a port, 0 on success or a negative error code is returned */ +int snd_seq_create_port(struct snd_seq_client *client, struct snd_seq_client_port **port_ret); +/* insert the port; return the port address or a negative error code */ +int snd_seq_insert_port(struct snd_seq_client *client, int port, + struct snd_seq_client_port *new_port); + /* delete a port */ int snd_seq_delete_port(struct snd_seq_client *client, int port);