--- zzzz-none-000/linux-3.10.107/sound/core/seq/seq_clientmgr.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/sound/core/seq/seq_clientmgr.c 2021-02-04 17:41:59.000000000 +0000 @@ -123,7 +123,7 @@ static struct snd_seq_client *clientptr(int clientid) { if (clientid < 0 || clientid >= SNDRV_SEQ_MAX_CLIENTS) { - snd_printd("Seq: oops. Trying to get pointer to client %d\n", + pr_debug("ALSA: seq: oops. Trying to get pointer to client %d\n", clientid); return NULL; } @@ -136,7 +136,7 @@ struct snd_seq_client *client; if (clientid < 0 || clientid >= SNDRV_SEQ_MAX_CLIENTS) { - snd_printd("Seq: oops. Trying to get pointer to client %d\n", + pr_debug("ALSA: seq: oops. Trying to get pointer to client %d\n", clientid); return NULL; } @@ -291,8 +291,8 @@ mutex_lock(®ister_mutex); switch (client->type) { case NO_CLIENT: - snd_printk(KERN_WARNING "Seq: Trying to free unused client %d\n", - client->number); + pr_warn("ALSA: seq: Trying to free unused client %d\n", + client->number); break; case USER_CLIENT: case KERNEL_CLIENT: @@ -301,7 +301,7 @@ break; default: - snd_printk(KERN_ERR "Seq: Trying to free client %d with undefined type = %d\n", + pr_err("ALSA: seq: Trying to free client %d with undefined type = %d\n", client->number, client->type); } mutex_unlock(®ister_mutex); @@ -660,7 +660,7 @@ int atomic, int hop) { struct snd_seq_subscribers *subs; - int err = 0, num_ev = 0; + int err, result = 0, num_ev = 0; struct snd_seq_event event_saved; struct snd_seq_client_port *src_port; struct snd_seq_port_subs_info *grp; @@ -688,8 +688,12 @@ subs->info.flags & SNDRV_SEQ_PORT_SUBS_TIME_REAL); err = snd_seq_deliver_single_event(client, event, 0, atomic, hop); - if (err < 0) - break; + if (err < 0) { + /* save first error that occurs and continue */ + if (!result) + result = err; + continue; + } num_ev++; /* restore original event record */ *event = event_saved; @@ -700,7 +704,7 @@ up_read(&grp->list_mutex); *event = event_saved; /* restore */ snd_seq_port_unlock(src_port); - return (err < 0) ? err : num_ev; + return (result < 0) ? result : num_ev; } @@ -712,7 +716,7 @@ struct snd_seq_event *event, int atomic, int hop) { - int num_ev = 0, err = 0; + int num_ev = 0, err, result = 0; struct snd_seq_client *dest_client; struct snd_seq_client_port *port; @@ -727,14 +731,18 @@ err = snd_seq_deliver_single_event(NULL, event, SNDRV_SEQ_FILTER_BROADCAST, atomic, hop); - if (err < 0) - break; + if (err < 0) { + /* save first error that occurs and continue */ + if (!result) + result = err; + continue; + } num_ev++; } read_unlock(&dest_client->ports_lock); snd_seq_client_unlock(dest_client); event->dest.port = SNDRV_SEQ_ADDRESS_BROADCAST; /* restore */ - return (err < 0) ? err : num_ev; + return (result < 0) ? result : num_ev; } /* @@ -744,7 +752,7 @@ static int broadcast_event(struct snd_seq_client *client, struct snd_seq_event *event, int atomic, int hop) { - int err = 0, num_ev = 0; + int err, result = 0, num_ev = 0; int dest; struct snd_seq_addr addr; @@ -763,12 +771,16 @@ err = snd_seq_deliver_single_event(NULL, event, SNDRV_SEQ_FILTER_BROADCAST, atomic, hop); - if (err < 0) - break; + if (err < 0) { + /* save first error that occurs and continue */ + if (!result) + result = err; + continue; + } num_ev += err; } event->dest = addr; /* restore */ - return (err < 0) ? err : num_ev; + return (result < 0) ? result : num_ev; } @@ -776,7 +788,7 @@ static int multicast_event(struct snd_seq_client *client, struct snd_seq_event *event, int atomic, int hop) { - snd_printd("seq: multicast not supported yet.\n"); + pr_debug("ALSA: seq: multicast not supported yet.\n"); return 0; /* ignored */ } #endif /* SUPPORT_BROADCAST */ @@ -797,7 +809,7 @@ hop++; if (hop >= SNDRV_SEQ_MAX_HOPS) { - snd_printd("too long delivery path (%d:%d->%d:%d)\n", + pr_debug("ALSA: seq: too long delivery path (%d:%d->%d:%d)\n", event->source.client, event->source.port, event->dest.client, event->dest.port); return -EMLINK; @@ -1124,7 +1136,7 @@ /* fill the info fields */ info.queues = SNDRV_SEQ_MAX_QUEUES; info.clients = SNDRV_SEQ_MAX_CLIENTS; - info.ports = 256; /* fixed limit */ + info.ports = SNDRV_SEQ_MAX_PORTS; info.channels = 256; /* fixed limit */ info.cur_clients = client_usage.cur; info.cur_queues = snd_seq_queue_get_cur_queues(); @@ -1248,6 +1260,7 @@ 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; @@ -1261,7 +1274,9 @@ 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) { @@ -1270,7 +1285,6 @@ port->owner = callback->owner; port->private_data = callback->private_data; port->private_free = callback->private_free; - port->callback_all = callback->callback_all; port->event_input = callback->event_input; port->c_src.open = callback->subscribe; port->c_src.close = callback->unsubscribe; @@ -1283,6 +1297,7 @@ 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; @@ -1871,6 +1886,7 @@ if (cptr == NULL) return -ENOENT; memset(&info, 0, sizeof(info)); + info.client = cptr->number; info.output_pool = cptr->pool->size; info.output_room = cptr->pool->room; info.output_free = info.output_pool; @@ -2200,7 +2216,7 @@ if (p->cmd == cmd) return p->func(client, arg); } - snd_printd("seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n", + pr_debug("ALSA: seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n", cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)); return -ENOTTY; } @@ -2439,7 +2455,7 @@ /*---------------------------------------------------------------------------*/ -#ifdef CONFIG_PROC_FS +#ifdef CONFIG_SND_PROC_FS /* * /proc interface */ @@ -2541,7 +2557,7 @@ snd_seq_client_unlock(client); } } -#endif /* CONFIG_PROC_FS */ +#endif /* CONFIG_SND_PROC_FS */ /*---------------------------------------------------------------------------*/ @@ -2563,6 +2579,8 @@ .compat_ioctl = snd_seq_ioctl_compat, }; +static struct device seq_dev; + /* * register sequencer device */ @@ -2570,12 +2588,17 @@ { int err; + snd_device_initialize(&seq_dev, NULL); + dev_set_name(&seq_dev, "seq"); + if (mutex_lock_interruptible(®ister_mutex)) return -ERESTARTSYS; - if ((err = snd_register_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, 0, - &snd_seq_f_ops, NULL, "seq")) < 0) { + err = snd_register_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, 0, + &snd_seq_f_ops, NULL, &seq_dev); + if (err < 0) { mutex_unlock(®ister_mutex); + put_device(&seq_dev); return err; } @@ -2591,5 +2614,6 @@ */ void __exit snd_sequencer_device_done(void) { - snd_unregister_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, 0); + snd_unregister_device(&seq_dev); + put_device(&seq_dev); }