diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-08-07 13:11:40 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-08-07 13:11:40 +0000 |
commit | 8b0a8165cdad0f4133837d753649ef4682e42c3b (patch) | |
tree | 5c58f869f31ddb1f7bd6e8bdea269b680b36c5b6 /sound/core/seq | |
parent | Releasing progress-linux version 6.8.12-1~progress7.99u1. (diff) | |
download | linux-8b0a8165cdad0f4133837d753649ef4682e42c3b.tar.xz linux-8b0a8165cdad0f4133837d753649ef4682e42c3b.zip |
Merging upstream version 6.9.7.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sound/core/seq')
-rw-r--r-- | sound/core/seq/Kconfig | 1 | ||||
-rw-r--r-- | sound/core/seq/oss/seq_oss_device.h | 2 | ||||
-rw-r--r-- | sound/core/seq/oss/seq_oss_init.c | 19 | ||||
-rw-r--r-- | sound/core/seq/oss/seq_oss_midi.c | 11 | ||||
-rw-r--r-- | sound/core/seq/seq_compat.c | 12 | ||||
-rw-r--r-- | sound/core/seq/seq_fifo.c | 55 | ||||
-rw-r--r-- | sound/core/seq/seq_memory.c | 28 | ||||
-rw-r--r-- | sound/core/seq/seq_midi.c | 30 | ||||
-rw-r--r-- | sound/core/seq/seq_midi_event.c | 14 | ||||
-rw-r--r-- | sound/core/seq/seq_ports.c | 114 | ||||
-rw-r--r-- | sound/core/seq/seq_prioq.c | 194 | ||||
-rw-r--r-- | sound/core/seq/seq_queue.c | 78 | ||||
-rw-r--r-- | sound/core/seq/seq_timer.c | 155 | ||||
-rw-r--r-- | sound/core/seq/seq_ump_client.c | 46 | ||||
-rw-r--r-- | sound/core/seq/seq_ump_convert.c | 50 | ||||
-rw-r--r-- | sound/core/seq/seq_virmidi.c | 40 |
16 files changed, 348 insertions, 501 deletions
diff --git a/sound/core/seq/Kconfig b/sound/core/seq/Kconfig index c14981daf9..0374bbf51c 100644 --- a/sound/core/seq/Kconfig +++ b/sound/core/seq/Kconfig @@ -71,7 +71,6 @@ config SND_SEQ_UMP among legacy and UMP clients. config SND_SEQ_UMP_CLIENT - tristate def_tristate SND_UMP endif # SND_SEQUENCER diff --git a/sound/core/seq/oss/seq_oss_device.h b/sound/core/seq/oss/seq_oss_device.h index 6c2c4fb9b7..f0e964b19a 100644 --- a/sound/core/seq/oss/seq_oss_device.h +++ b/sound/core/seq/oss/seq_oss_device.h @@ -163,6 +163,6 @@ snd_seq_oss_fill_addr(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, /* misc. functions for proc interface */ -char *enabled_str(int bool); +char *enabled_str(bool b); #endif /* __SEQ_OSS_DEVICE_H */ diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c index 42d4e7535a..676246fa02 100644 --- a/sound/core/seq/oss/seq_oss_init.c +++ b/sound/core/seq/oss/seq_oss_init.c @@ -63,20 +63,18 @@ int __init snd_seq_oss_create_client(void) { int rc; - struct snd_seq_port_info *port; + struct snd_seq_port_info *port __free(kfree) = NULL; struct snd_seq_port_callback port_callback; port = kzalloc(sizeof(*port), GFP_KERNEL); - if (!port) { - rc = -ENOMEM; - goto __error; - } + if (!port) + return -ENOMEM; /* create ALSA client */ rc = snd_seq_create_kernel_client(NULL, SNDRV_SEQ_CLIENT_OSS, "OSS sequencer"); if (rc < 0) - goto __error; + return rc; system_client = rc; @@ -104,14 +102,11 @@ snd_seq_oss_create_client(void) subs.dest.port = system_port; call_ctl(SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, &subs); } - rc = 0; /* look up midi devices */ schedule_work(&async_lookup_work); - __error: - kfree(port); - return rc; + return 0; } @@ -455,9 +450,9 @@ snd_seq_oss_reset(struct seq_oss_devinfo *dp) * misc. functions for proc interface */ char * -enabled_str(int bool) +enabled_str(bool b) { - return bool ? "enabled" : "disabled"; + return b ? "enabled" : "disabled"; } static const char * diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c index f2940b2959..f8e247d9e5 100644 --- a/sound/core/seq/oss/seq_oss_midi.c +++ b/sound/core/seq/oss/seq_oss_midi.c @@ -64,16 +64,13 @@ static int send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, int snd_seq_oss_midi_lookup_ports(int client) { - struct snd_seq_client_info *clinfo; - struct snd_seq_port_info *pinfo; + struct snd_seq_client_info *clinfo __free(kfree) = NULL; + struct snd_seq_port_info *pinfo __free(kfree) = NULL; clinfo = kzalloc(sizeof(*clinfo), GFP_KERNEL); pinfo = kzalloc(sizeof(*pinfo), GFP_KERNEL); - if (! clinfo || ! pinfo) { - kfree(clinfo); - kfree(pinfo); + if (!clinfo || !pinfo) return -ENOMEM; - } clinfo->client = -1; while (snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT, clinfo) == 0) { if (clinfo->client == client) @@ -83,8 +80,6 @@ snd_seq_oss_midi_lookup_ports(int client) while (snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT, pinfo) == 0) snd_seq_oss_midi_check_new_port(pinfo); } - kfree(clinfo); - kfree(pinfo); return 0; } diff --git a/sound/core/seq/seq_compat.c b/sound/core/seq/seq_compat.c index 1e35bf086a..643af4c1e8 100644 --- a/sound/core/seq/seq_compat.c +++ b/sound/core/seq/seq_compat.c @@ -31,8 +31,8 @@ struct snd_seq_port_info32 { static int snd_seq_call_port_info_ioctl(struct snd_seq_client *client, unsigned int cmd, struct snd_seq_port_info32 __user *data32) { - int err = -EFAULT; - struct snd_seq_port_info *data; + struct snd_seq_port_info *data __free(kfree) = NULL; + int err; data = kmalloc(sizeof(*data), GFP_KERNEL); if (!data) @@ -41,20 +41,18 @@ static int snd_seq_call_port_info_ioctl(struct snd_seq_client *client, unsigned if (copy_from_user(data, data32, sizeof(*data32)) || get_user(data->flags, &data32->flags) || get_user(data->time_queue, &data32->time_queue)) - goto error; + return -EFAULT; data->kernel = NULL; err = snd_seq_kernel_client_ctl(client->number, cmd, data); if (err < 0) - goto error; + return err; if (copy_to_user(data32, data, sizeof(*data32)) || put_user(data->flags, &data32->flags) || put_user(data->time_queue, &data32->time_queue)) - err = -EFAULT; + return -EFAULT; - error: - kfree(data); return err; } diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c index f8e02e9870..3a10b081f1 100644 --- a/sound/core/seq/seq_fifo.c +++ b/sound/core/seq/seq_fifo.c @@ -88,12 +88,11 @@ void snd_seq_fifo_clear(struct snd_seq_fifo *f) atomic_set(&f->overflow, 0); snd_use_lock_sync(&f->use_lock); - spin_lock_irq(&f->lock); + guard(spinlock_irq)(&f->lock); /* drain the fifo */ while ((cell = fifo_cell_out(f)) != NULL) { snd_seq_cell_free(cell); } - spin_unlock_irq(&f->lock); } @@ -102,7 +101,6 @@ int snd_seq_fifo_event_in(struct snd_seq_fifo *f, struct snd_seq_event *event) { struct snd_seq_event_cell *cell; - unsigned long flags; int err; if (snd_BUG_ON(!f)) @@ -118,15 +116,15 @@ int snd_seq_fifo_event_in(struct snd_seq_fifo *f, } /* append new cells to fifo */ - spin_lock_irqsave(&f->lock, flags); - if (f->tail != NULL) - f->tail->next = cell; - f->tail = cell; - if (f->head == NULL) - f->head = cell; - cell->next = NULL; - f->cells++; - spin_unlock_irqrestore(&f->lock, flags); + scoped_guard(spinlock_irqsave, &f->lock) { + if (f->tail != NULL) + f->tail->next = cell; + f->tail = cell; + if (f->head == NULL) + f->head = cell; + cell->next = NULL; + f->cells++; + } /* wakeup client */ if (waitqueue_active(&f->input_sleep)) @@ -199,16 +197,13 @@ int snd_seq_fifo_cell_out(struct snd_seq_fifo *f, void snd_seq_fifo_cell_putback(struct snd_seq_fifo *f, struct snd_seq_event_cell *cell) { - unsigned long flags; - if (cell) { - spin_lock_irqsave(&f->lock, flags); + guard(spinlock_irqsave)(&f->lock); cell->next = f->head; f->head = cell; if (!f->tail) f->tail = cell; f->cells++; - spin_unlock_irqrestore(&f->lock, flags); } } @@ -239,17 +234,17 @@ int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize) return -ENOMEM; } - spin_lock_irq(&f->lock); - /* remember old pool */ - oldpool = f->pool; - oldhead = f->head; - /* exchange pools */ - f->pool = newpool; - f->head = NULL; - f->tail = NULL; - f->cells = 0; - /* NOTE: overflow flag is not cleared */ - spin_unlock_irq(&f->lock); + scoped_guard(spinlock_irq, &f->lock) { + /* remember old pool */ + oldpool = f->pool; + oldhead = f->head; + /* exchange pools */ + f->pool = newpool; + f->head = NULL; + f->tail = NULL; + f->cells = 0; + /* NOTE: overflow flag is not cleared */ + } /* close the old pool and wait until all users are gone */ snd_seq_pool_mark_closing(oldpool); @@ -268,16 +263,14 @@ int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize) /* get the number of unused cells safely */ int snd_seq_fifo_unused_cells(struct snd_seq_fifo *f) { - unsigned long flags; int cells; if (!f) return 0; snd_use_lock_use(&f->use_lock); - spin_lock_irqsave(&f->lock, flags); - cells = snd_seq_unused_cells(f->pool); - spin_unlock_irqrestore(&f->lock, flags); + scoped_guard(spinlock_irqsave, &f->lock) + cells = snd_seq_unused_cells(f->pool); snd_use_lock_free(&f->use_lock); return cells; } diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c index e705e75381..20155e3e87 100644 --- a/sound/core/seq/seq_memory.c +++ b/sound/core/seq/seq_memory.c @@ -232,7 +232,6 @@ static inline void free_cell(struct snd_seq_pool *pool, void snd_seq_cell_free(struct snd_seq_event_cell * cell) { - unsigned long flags; struct snd_seq_pool *pool; if (snd_BUG_ON(!cell)) @@ -241,7 +240,7 @@ void snd_seq_cell_free(struct snd_seq_event_cell * cell) if (snd_BUG_ON(!pool)) return; - spin_lock_irqsave(&pool->lock, flags); + guard(spinlock_irqsave)(&pool->lock); free_cell(pool, cell); if (snd_seq_ev_is_variable(&cell->event)) { if (cell->event.data.ext.len & SNDRV_SEQ_EXT_CHAINED) { @@ -259,7 +258,6 @@ void snd_seq_cell_free(struct snd_seq_event_cell * cell) if (snd_seq_output_ok(pool)) wake_up(&pool->output_sleep); } - spin_unlock_irqrestore(&pool->lock, flags); } @@ -449,9 +447,8 @@ int snd_seq_pool_init(struct snd_seq_pool *pool) return -ENOMEM; /* add new cells to the free cell list */ - spin_lock_irq(&pool->lock); + guard(spinlock_irq)(&pool->lock); if (pool->ptr) { - spin_unlock_irq(&pool->lock); kvfree(cellptr); return 0; } @@ -470,20 +467,16 @@ int snd_seq_pool_init(struct snd_seq_pool *pool) /* init statistics */ pool->max_used = 0; pool->total_elements = pool->size; - spin_unlock_irq(&pool->lock); return 0; } /* refuse the further insertion to the pool */ void snd_seq_pool_mark_closing(struct snd_seq_pool *pool) { - unsigned long flags; - if (snd_BUG_ON(!pool)) return; - spin_lock_irqsave(&pool->lock, flags); + guard(spinlock_irqsave)(&pool->lock); pool->closing = 1; - spin_unlock_irqrestore(&pool->lock, flags); } /* remove events */ @@ -502,18 +495,17 @@ int snd_seq_pool_done(struct snd_seq_pool *pool) schedule_timeout_uninterruptible(1); /* release all resources */ - spin_lock_irq(&pool->lock); - ptr = pool->ptr; - pool->ptr = NULL; - pool->free = NULL; - pool->total_elements = 0; - spin_unlock_irq(&pool->lock); + scoped_guard(spinlock_irq, &pool->lock) { + ptr = pool->ptr; + pool->ptr = NULL; + pool->free = NULL; + pool->total_elements = 0; + } kvfree(ptr); - spin_lock_irq(&pool->lock); + guard(spinlock_irq)(&pool->lock); pool->closing = 0; - spin_unlock_irq(&pool->lock); return 0; } diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c index 78dcb0ea15..ba52a77eda 100644 --- a/sound/core/seq/seq_midi.c +++ b/sound/core/seq/seq_midi.c @@ -270,8 +270,8 @@ snd_seq_midisynth_probe(struct device *_dev) struct snd_seq_device *dev = to_seq_dev(_dev); struct seq_midisynth_client *client; struct seq_midisynth *msynth, *ms; - struct snd_seq_port_info *port; - struct snd_rawmidi_info *info; + struct snd_seq_port_info *port __free(kfree) = NULL; + struct snd_rawmidi_info *info __free(kfree) = NULL; struct snd_rawmidi *rmidi = dev->private_data; int newclient = 0; unsigned int p, ports; @@ -297,31 +297,24 @@ snd_seq_midisynth_probe(struct device *_dev) ports = output_count; if (ports < input_count) ports = input_count; - if (ports == 0) { - kfree(info); + if (ports == 0) return -ENODEV; - } if (ports > (256 / SNDRV_RAWMIDI_DEVICES)) ports = 256 / SNDRV_RAWMIDI_DEVICES; - mutex_lock(®ister_mutex); + guard(mutex)(®ister_mutex); client = synths[card->number]; if (client == NULL) { newclient = 1; client = kzalloc(sizeof(*client), GFP_KERNEL); - if (client == NULL) { - mutex_unlock(®ister_mutex); - kfree(info); + if (client == NULL) return -ENOMEM; - } client->seq_client = snd_seq_create_kernel_client( card, 0, "%s", card->shortname[0] ? (const char *)card->shortname : "External MIDI"); if (client->seq_client < 0) { kfree(client); - mutex_unlock(®ister_mutex); - kfree(info); return -ENOMEM; } } @@ -402,9 +395,6 @@ snd_seq_midisynth_probe(struct device *_dev) client->num_ports++; if (newclient) synths[card->number] = client; - mutex_unlock(®ister_mutex); - kfree(info); - kfree(port); return 0; /* success */ __nomem: @@ -417,9 +407,6 @@ snd_seq_midisynth_probe(struct device *_dev) snd_seq_delete_kernel_client(client->seq_client); kfree(client); } - kfree(info); - kfree(port); - mutex_unlock(®ister_mutex); return -ENOMEM; } @@ -433,12 +420,10 @@ snd_seq_midisynth_remove(struct device *_dev) struct snd_card *card = dev->card; int device = dev->device, p, ports; - mutex_lock(®ister_mutex); + guard(mutex)(®ister_mutex); client = synths[card->number]; - if (client == NULL || client->ports[device] == NULL) { - mutex_unlock(®ister_mutex); + if (client == NULL || client->ports[device] == NULL) return -ENODEV; - } ports = client->ports_per_device[device]; client->ports_per_device[device] = 0; msynth = client->ports[device]; @@ -452,7 +437,6 @@ snd_seq_midisynth_remove(struct device *_dev) synths[card->number] = NULL; kfree(client); } - mutex_unlock(®ister_mutex); return 0; } diff --git a/sound/core/seq/seq_midi_event.c b/sound/core/seq/seq_midi_event.c index 7511462fe0..fa9dfc53c3 100644 --- a/sound/core/seq/seq_midi_event.c +++ b/sound/core/seq/seq_midi_event.c @@ -144,21 +144,15 @@ static inline void reset_encode(struct snd_midi_event *dev) void snd_midi_event_reset_encode(struct snd_midi_event *dev) { - unsigned long flags; - - spin_lock_irqsave(&dev->lock, flags); + guard(spinlock_irqsave)(&dev->lock); reset_encode(dev); - spin_unlock_irqrestore(&dev->lock, flags); } EXPORT_SYMBOL(snd_midi_event_reset_encode); void snd_midi_event_reset_decode(struct snd_midi_event *dev) { - unsigned long flags; - - spin_lock_irqsave(&dev->lock, flags); + guard(spinlock_irqsave)(&dev->lock); dev->lastcmd = 0xff; - spin_unlock_irqrestore(&dev->lock, flags); } EXPORT_SYMBOL(snd_midi_event_reset_decode); @@ -177,7 +171,6 @@ bool snd_midi_event_encode_byte(struct snd_midi_event *dev, unsigned char c, struct snd_seq_event *ev) { bool rc = false; - unsigned long flags; if (c >= MIDI_CMD_COMMON_CLOCK) { /* real-time event */ @@ -187,7 +180,7 @@ bool snd_midi_event_encode_byte(struct snd_midi_event *dev, unsigned char c, return ev->type != SNDRV_SEQ_EVENT_NONE; } - spin_lock_irqsave(&dev->lock, flags); + guard(spinlock_irqsave)(&dev->lock); if ((c & 0x80) && (c != MIDI_CMD_COMMON_SYSEX_END || dev->type != ST_SYSEX)) { /* new command */ @@ -236,7 +229,6 @@ bool snd_midi_event_encode_byte(struct snd_midi_event *dev, unsigned char c, } } - spin_unlock_irqrestore(&dev->lock, flags); return rc; } EXPORT_SYMBOL(snd_midi_event_encode_byte); diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c index f3f14ff0f8..ca631ca4f2 100644 --- a/sound/core/seq/seq_ports.c +++ b/sound/core/seq/seq_ports.c @@ -48,17 +48,15 @@ struct snd_seq_client_port *snd_seq_port_use_ptr(struct snd_seq_client *client, if (client == NULL) return NULL; - read_lock(&client->ports_lock); + guard(read_lock)(&client->ports_lock); list_for_each_entry(port, &client->ports_list_head, list) { if (port->addr.port == num) { if (port->closing) break; /* deleting now */ snd_use_lock_use(&port->use_lock); - read_unlock(&client->ports_lock); return port; } } - read_unlock(&client->ports_lock); return NULL; /* not found */ } @@ -73,7 +71,7 @@ struct snd_seq_client_port *snd_seq_port_query_nearest(struct snd_seq_client *cl num = pinfo->addr.port; found = NULL; - read_lock(&client->ports_lock); + guard(read_lock)(&client->ports_lock); list_for_each_entry(port, &client->ports_list_head, list) { if ((port->capability & SNDRV_SEQ_PORT_CAP_INACTIVE) && !check_inactive) @@ -93,7 +91,6 @@ struct snd_seq_client_port *snd_seq_port_query_nearest(struct snd_seq_client *cl else snd_use_lock_use(&found->use_lock); } - read_unlock(&client->ports_lock); return found; } @@ -145,13 +142,12 @@ int snd_seq_create_port(struct snd_seq_client *client, int port, snd_use_lock_use(&new_port->use_lock); num = max(port, 0); - mutex_lock(&client->ports_mutex); - write_lock_irq(&client->ports_lock); + guard(mutex)(&client->ports_mutex); + guard(write_lock_irq)(&client->ports_lock); list_for_each_entry(p, &client->ports_list_head, list) { if (p->addr.port == port) { kfree(new_port); - num = -EBUSY; - goto unlock; + return -EBUSY; } if (p->addr.port > num) break; @@ -164,9 +160,6 @@ int snd_seq_create_port(struct snd_seq_client *client, int port, new_port->addr.port = num; /* store the port number in the port */ sprintf(new_port->name, "port-%d", num); *port_ret = new_port; - unlock: - write_unlock_irq(&client->ports_lock); - mutex_unlock(&client->ports_mutex); return num; } @@ -281,19 +274,18 @@ int snd_seq_delete_port(struct snd_seq_client *client, int port) { struct snd_seq_client_port *found = NULL, *p; - mutex_lock(&client->ports_mutex); - write_lock_irq(&client->ports_lock); - list_for_each_entry(p, &client->ports_list_head, list) { - if (p->addr.port == port) { - /* ok found. delete from the list at first */ - list_del(&p->list); - client->num_ports--; - found = p; - break; + scoped_guard(mutex, &client->ports_mutex) { + guard(write_lock_irq)(&client->ports_lock); + list_for_each_entry(p, &client->ports_list_head, list) { + if (p->addr.port == port) { + /* ok found. delete from the list at first */ + list_del(&p->list); + client->num_ports--; + found = p; + break; + } } } - write_unlock_irq(&client->ports_lock); - mutex_unlock(&client->ports_mutex); if (found) return port_delete(client, found); else @@ -309,16 +301,16 @@ int snd_seq_delete_all_ports(struct snd_seq_client *client) /* move the port list to deleted_list, and * clear the port list in the client data. */ - mutex_lock(&client->ports_mutex); - write_lock_irq(&client->ports_lock); - if (! list_empty(&client->ports_list_head)) { - list_add(&deleted_list, &client->ports_list_head); - list_del_init(&client->ports_list_head); - } else { - INIT_LIST_HEAD(&deleted_list); + guard(mutex)(&client->ports_mutex); + scoped_guard(write_lock_irq, &client->ports_lock) { + if (!list_empty(&client->ports_list_head)) { + list_add(&deleted_list, &client->ports_list_head); + list_del_init(&client->ports_list_head); + } else { + INIT_LIST_HEAD(&deleted_list); + } + client->num_ports = 0; } - client->num_ports = 0; - write_unlock_irq(&client->ports_lock); /* remove each port in deleted_list */ list_for_each_entry_safe(port, tmp, &deleted_list, list) { @@ -326,7 +318,6 @@ int snd_seq_delete_all_ports(struct snd_seq_client *client) snd_seq_system_client_ev_port_exit(port->addr.client, port->addr.port); port_delete(client, port); } - mutex_unlock(&client->ports_mutex); return 0; } @@ -506,42 +497,37 @@ static int check_and_subscribe_port(struct snd_seq_client *client, int err; grp = is_src ? &port->c_src : &port->c_dest; - err = -EBUSY; - down_write(&grp->list_mutex); + guard(rwsem_write)(&grp->list_mutex); if (exclusive) { if (!list_empty(&grp->list_head)) - goto __error; + return -EBUSY; } else { if (grp->exclusive) - goto __error; + return -EBUSY; /* check whether already exists */ list_for_each(p, &grp->list_head) { s = get_subscriber(p, is_src); if (match_subs_info(&subs->info, &s->info)) - goto __error; + return -EBUSY; } } err = subscribe_port(client, port, grp, &subs->info, ack); if (err < 0) { grp->exclusive = 0; - goto __error; + return err; } /* add to list */ - write_lock_irq(&grp->list_lock); + guard(write_lock_irq)(&grp->list_lock); if (is_src) list_add_tail(&subs->src_list, &grp->list_head); else list_add_tail(&subs->dest_list, &grp->list_head); grp->exclusive = exclusive; atomic_inc(&subs->ref_count); - write_unlock_irq(&grp->list_lock); - err = 0; - __error: - up_write(&grp->list_mutex); - return err; + return 0; } /* called with grp->list_mutex held */ @@ -556,12 +542,12 @@ static void __delete_and_unsubscribe_port(struct snd_seq_client *client, grp = is_src ? &port->c_src : &port->c_dest; list = is_src ? &subs->src_list : &subs->dest_list; - write_lock_irq(&grp->list_lock); - empty = list_empty(list); - if (!empty) - list_del_init(list); - grp->exclusive = 0; - write_unlock_irq(&grp->list_lock); + scoped_guard(write_lock_irq, &grp->list_lock) { + empty = list_empty(list); + if (!empty) + list_del_init(list); + grp->exclusive = 0; + } if (!empty) unsubscribe_port(client, port, grp, &subs->info, ack); @@ -575,9 +561,8 @@ static void delete_and_unsubscribe_port(struct snd_seq_client *client, struct snd_seq_port_subs_info *grp; grp = is_src ? &port->c_src : &port->c_dest; - down_write(&grp->list_mutex); + guard(rwsem_write)(&grp->list_mutex); __delete_and_unsubscribe_port(client, port, subs, is_src, ack); - up_write(&grp->list_mutex); } /* connect two ports */ @@ -639,18 +624,18 @@ int snd_seq_port_disconnect(struct snd_seq_client *connector, /* always start from deleting the dest port for avoiding concurrent * deletions */ - down_write(&dest->list_mutex); - /* look for the connection */ - list_for_each_entry(subs, &dest->list_head, dest_list) { - if (match_subs_info(info, &subs->info)) { - __delete_and_unsubscribe_port(dest_client, dest_port, - subs, false, - connector->number != dest_client->number); - err = 0; - break; + scoped_guard(rwsem_write, &dest->list_mutex) { + /* look for the connection */ + list_for_each_entry(subs, &dest->list_head, dest_list) { + if (match_subs_info(info, &subs->info)) { + __delete_and_unsubscribe_port(dest_client, dest_port, + subs, false, + connector->number != dest_client->number); + err = 0; + break; + } } } - up_write(&dest->list_mutex); if (err < 0) return err; @@ -669,7 +654,7 @@ int snd_seq_port_get_subscription(struct snd_seq_port_subs_info *src_grp, struct snd_seq_subscribers *s; int err = -ENOENT; - down_read(&src_grp->list_mutex); + guard(rwsem_read)(&src_grp->list_mutex); list_for_each_entry(s, &src_grp->list_head, src_list) { if (addr_match(dest_addr, &s->info.dest)) { *subs = s->info; @@ -677,7 +662,6 @@ int snd_seq_port_get_subscription(struct snd_seq_port_subs_info *src_grp, break; } } - up_read(&src_grp->list_mutex); return err; } diff --git a/sound/core/seq/seq_prioq.c b/sound/core/seq/seq_prioq.c index 1d857981e8..e649485a87 100644 --- a/sound/core/seq/seq_prioq.c +++ b/sound/core/seq/seq_prioq.c @@ -132,7 +132,6 @@ int snd_seq_prioq_cell_in(struct snd_seq_prioq * f, struct snd_seq_event_cell * cell) { struct snd_seq_event_cell *cur, *prev; - unsigned long flags; int count; int prior; @@ -142,7 +141,7 @@ int snd_seq_prioq_cell_in(struct snd_seq_prioq * f, /* check flags */ prior = (cell->event.flags & SNDRV_SEQ_PRIORITY_MASK); - spin_lock_irqsave(&f->lock, flags); + guard(spinlock_irqsave)(&f->lock); /* check if this element needs to inserted at the end (ie. ordered data is inserted) This will be very likeley if a sequencer @@ -154,7 +153,6 @@ int snd_seq_prioq_cell_in(struct snd_seq_prioq * f, f->tail = cell; cell->next = NULL; f->cells++; - spin_unlock_irqrestore(&f->lock, flags); return 0; } } @@ -179,7 +177,6 @@ int snd_seq_prioq_cell_in(struct snd_seq_prioq * f, prev = cur; cur = cur->next; if (! --count) { - spin_unlock_irqrestore(&f->lock, flags); pr_err("ALSA: seq: cannot find a pointer.. infinite loop?\n"); return -EINVAL; } @@ -195,7 +192,6 @@ int snd_seq_prioq_cell_in(struct snd_seq_prioq * f, if (cur == NULL) /* reached end of the list */ f->tail = cell; f->cells++; - spin_unlock_irqrestore(&f->lock, flags); return 0; } @@ -213,14 +209,13 @@ struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f, void *current_time) { struct snd_seq_event_cell *cell; - unsigned long flags; if (f == NULL) { pr_debug("ALSA: seq: snd_seq_prioq_cell_in() called with NULL prioq\n"); return NULL; } - spin_lock_irqsave(&f->lock, flags); + guard(spinlock_irqsave)(&f->lock); cell = f->head; if (cell && current_time && !event_is_ready(&cell->event, current_time)) cell = NULL; @@ -235,7 +230,6 @@ struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f, f->cells--; } - spin_unlock_irqrestore(&f->lock, flags); return cell; } @@ -249,73 +243,43 @@ int snd_seq_prioq_avail(struct snd_seq_prioq * f) return f->cells; } -static inline int prioq_match(struct snd_seq_event_cell *cell, - int client, int timestamp) -{ - if (cell->event.source.client == client || - cell->event.dest.client == client) - return 1; - if (!timestamp) - return 0; - switch (cell->event.flags & SNDRV_SEQ_TIME_STAMP_MASK) { - case SNDRV_SEQ_TIME_STAMP_TICK: - if (cell->event.time.tick) - return 1; - break; - case SNDRV_SEQ_TIME_STAMP_REAL: - if (cell->event.time.time.tv_sec || - cell->event.time.time.tv_nsec) - return 1; - break; - } - return 0; -} - -/* remove cells for left client */ -void snd_seq_prioq_leave(struct snd_seq_prioq * f, int client, int timestamp) +/* remove cells matching with the condition */ +static void prioq_remove_cells(struct snd_seq_prioq *f, + bool (*match)(struct snd_seq_event_cell *cell, + void *arg), + void *arg) { register struct snd_seq_event_cell *cell, *next; - unsigned long flags; struct snd_seq_event_cell *prev = NULL; struct snd_seq_event_cell *freefirst = NULL, *freeprev = NULL, *freenext; /* collect all removed cells */ - spin_lock_irqsave(&f->lock, flags); - cell = f->head; - while (cell) { - next = cell->next; - if (prioq_match(cell, client, timestamp)) { + scoped_guard(spinlock_irqsave, &f->lock) { + for (cell = f->head; cell; cell = next) { + next = cell->next; + if (!match(cell, arg)) { + prev = cell; + continue; + } + /* remove cell from prioq */ - if (cell == f->head) { + if (cell == f->head) f->head = cell->next; - } else { + else prev->next = cell->next; - } if (cell == f->tail) f->tail = cell->next; f->cells--; + /* add cell to free list */ cell->next = NULL; - if (freefirst == NULL) { + if (freefirst == NULL) freefirst = cell; - } else { + else freeprev->next = cell; - } freeprev = cell; - } else { -#if 0 - pr_debug("ALSA: seq: type = %i, source = %i, dest = %i, " - "client = %i\n", - cell->event.type, - cell->event.source.client, - cell->event.dest.client, - client); -#endif - prev = cell; } - cell = next; } - spin_unlock_irqrestore(&f->lock, flags); /* remove selected cells */ while (freefirst) { @@ -325,22 +289,68 @@ void snd_seq_prioq_leave(struct snd_seq_prioq * f, int client, int timestamp) } } -static int prioq_remove_match(struct snd_seq_remove_events *info, - struct snd_seq_event *ev) +struct prioq_match_arg { + int client; + int timestamp; +}; + +static inline bool prioq_match(struct snd_seq_event_cell *cell, void *arg) +{ + struct prioq_match_arg *v = arg; + + if (cell->event.source.client == v->client || + cell->event.dest.client == v->client) + return true; + if (!v->timestamp) + return false; + switch (cell->event.flags & SNDRV_SEQ_TIME_STAMP_MASK) { + case SNDRV_SEQ_TIME_STAMP_TICK: + if (cell->event.time.tick) + return true; + break; + case SNDRV_SEQ_TIME_STAMP_REAL: + if (cell->event.time.time.tv_sec || + cell->event.time.time.tv_nsec) + return true; + break; + } + return false; +} + +/* remove cells for left client */ +void snd_seq_prioq_leave(struct snd_seq_prioq *f, int client, int timestamp) { + struct prioq_match_arg arg = { client, timestamp }; + + return prioq_remove_cells(f, prioq_match, &arg); +} + +struct prioq_remove_match_arg { + int client; + struct snd_seq_remove_events *info; +}; + +static bool prioq_remove_match(struct snd_seq_event_cell *cell, void *arg) +{ + struct prioq_remove_match_arg *v = arg; + struct snd_seq_event *ev = &cell->event; + struct snd_seq_remove_events *info = v->info; int res; + if (ev->source.client != v->client) + return false; + if (info->remove_mode & SNDRV_SEQ_REMOVE_DEST) { if (ev->dest.client != info->dest.client || ev->dest.port != info->dest.port) - return 0; + return false; } if (info->remove_mode & SNDRV_SEQ_REMOVE_DEST_CHANNEL) { if (! snd_seq_ev_is_channel_type(ev)) - return 0; + return false; /* data.note.channel and data.control.channel are identical */ if (ev->data.note.channel != info->channel) - return 0; + return false; } if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_AFTER) { if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_TICK) @@ -348,7 +358,7 @@ static int prioq_remove_match(struct snd_seq_remove_events *info, else res = snd_seq_compare_real_time(&ev->time.time, &info->time.time); if (!res) - return 0; + return false; } if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_BEFORE) { if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_TICK) @@ -356,81 +366,35 @@ static int prioq_remove_match(struct snd_seq_remove_events *info, else res = snd_seq_compare_real_time(&ev->time.time, &info->time.time); if (res) - return 0; + return false; } if (info->remove_mode & SNDRV_SEQ_REMOVE_EVENT_TYPE) { if (ev->type != info->type) - return 0; + return false; } if (info->remove_mode & SNDRV_SEQ_REMOVE_IGNORE_OFF) { /* Do not remove off events */ switch (ev->type) { case SNDRV_SEQ_EVENT_NOTEOFF: /* case SNDRV_SEQ_EVENT_SAMPLE_STOP: */ - return 0; + return false; default: break; } } if (info->remove_mode & SNDRV_SEQ_REMOVE_TAG_MATCH) { if (info->tag != ev->tag) - return 0; + return false; } - return 1; + return true; } /* remove cells matching remove criteria */ void snd_seq_prioq_remove_events(struct snd_seq_prioq * f, int client, struct snd_seq_remove_events *info) { - struct snd_seq_event_cell *cell, *next; - unsigned long flags; - struct snd_seq_event_cell *prev = NULL; - struct snd_seq_event_cell *freefirst = NULL, *freeprev = NULL, *freenext; - - /* collect all removed cells */ - spin_lock_irqsave(&f->lock, flags); - cell = f->head; - - while (cell) { - next = cell->next; - if (cell->event.source.client == client && - prioq_remove_match(info, &cell->event)) { + struct prioq_remove_match_arg arg = { client, info }; - /* remove cell from prioq */ - if (cell == f->head) { - f->head = cell->next; - } else { - prev->next = cell->next; - } - - if (cell == f->tail) - f->tail = cell->next; - f->cells--; - - /* add cell to free list */ - cell->next = NULL; - if (freefirst == NULL) { - freefirst = cell; - } else { - freeprev->next = cell; - } - - freeprev = cell; - } else { - prev = cell; - } - cell = next; - } - spin_unlock_irqrestore(&f->lock, flags); - - /* remove selected cells */ - while (freefirst) { - freenext = freefirst->next; - snd_seq_cell_free(freefirst); - freefirst = freenext; - } + return prioq_remove_cells(f, prioq_remove_match, &arg); } - - diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c index bc933104c3..500ee6b19c 100644 --- a/sound/core/seq/seq_queue.c +++ b/sound/core/seq/seq_queue.c @@ -50,43 +50,35 @@ int snd_seq_queue_get_cur_queues(void) static int queue_list_add(struct snd_seq_queue *q) { int i; - unsigned long flags; - spin_lock_irqsave(&queue_list_lock, flags); + guard(spinlock_irqsave)(&queue_list_lock); for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) { if (! queue_list[i]) { queue_list[i] = q; q->queue = i; num_queues++; - spin_unlock_irqrestore(&queue_list_lock, flags); return i; } } - spin_unlock_irqrestore(&queue_list_lock, flags); return -1; } static struct snd_seq_queue *queue_list_remove(int id, int client) { struct snd_seq_queue *q; - unsigned long flags; - spin_lock_irqsave(&queue_list_lock, flags); + guard(spinlock_irqsave)(&queue_list_lock); q = queue_list[id]; if (q) { - spin_lock(&q->owner_lock); + guard(spinlock)(&q->owner_lock); if (q->owner == client) { /* found */ q->klocked = 1; - spin_unlock(&q->owner_lock); queue_list[id] = NULL; num_queues--; - spin_unlock_irqrestore(&queue_list_lock, flags); return q; } - spin_unlock(&q->owner_lock); } - spin_unlock_irqrestore(&queue_list_lock, flags); return NULL; } @@ -203,15 +195,13 @@ int snd_seq_queue_delete(int client, int queueid) struct snd_seq_queue *queueptr(int queueid) { struct snd_seq_queue *q; - unsigned long flags; if (queueid < 0 || queueid >= SNDRV_SEQ_MAX_QUEUES) return NULL; - spin_lock_irqsave(&queue_list_lock, flags); + guard(spinlock_irqsave)(&queue_list_lock); q = queue_list[queueid]; if (q) snd_use_lock_use(&q->use_lock); - spin_unlock_irqrestore(&queue_list_lock, flags); return q; } @@ -239,7 +229,6 @@ struct snd_seq_queue *snd_seq_queue_find_name(char *name) void snd_seq_check_queue(struct snd_seq_queue *q, int atomic, int hop) { - unsigned long flags; struct snd_seq_event_cell *cell; snd_seq_tick_time_t cur_tick; snd_seq_real_time_t cur_time; @@ -249,14 +238,13 @@ void snd_seq_check_queue(struct snd_seq_queue *q, int atomic, int hop) return; /* make this function non-reentrant */ - spin_lock_irqsave(&q->check_lock, flags); - if (q->check_blocked) { - q->check_again = 1; - spin_unlock_irqrestore(&q->check_lock, flags); - return; /* other thread is already checking queues */ + scoped_guard(spinlock_irqsave, &q->check_lock) { + if (q->check_blocked) { + q->check_again = 1; + return; /* other thread is already checking queues */ + } + q->check_blocked = 1; } - q->check_blocked = 1; - spin_unlock_irqrestore(&q->check_lock, flags); __again: /* Process tick queue... */ @@ -283,16 +271,14 @@ void snd_seq_check_queue(struct snd_seq_queue *q, int atomic, int hop) out: /* free lock */ - spin_lock_irqsave(&q->check_lock, flags); - if (q->check_again) { - q->check_again = 0; - if (processed < MAX_CELL_PROCESSES_IN_QUEUE) { - spin_unlock_irqrestore(&q->check_lock, flags); - goto __again; + scoped_guard(spinlock_irqsave, &q->check_lock) { + if (q->check_again) { + q->check_again = 0; + if (processed < MAX_CELL_PROCESSES_IN_QUEUE) + goto __again; } + q->check_blocked = 0; } - q->check_blocked = 0; - spin_unlock_irqrestore(&q->check_lock, flags); } @@ -361,25 +347,20 @@ static inline int check_access(struct snd_seq_queue *q, int client) */ static int queue_access_lock(struct snd_seq_queue *q, int client) { - unsigned long flags; int access_ok; - spin_lock_irqsave(&q->owner_lock, flags); + guard(spinlock_irqsave)(&q->owner_lock); access_ok = check_access(q, client); if (access_ok) q->klocked = 1; - spin_unlock_irqrestore(&q->owner_lock, flags); return access_ok; } /* unlock the queue */ static inline void queue_access_unlock(struct snd_seq_queue *q) { - unsigned long flags; - - spin_lock_irqsave(&q->owner_lock, flags); + guard(spinlock_irqsave)(&q->owner_lock); q->klocked = 0; - spin_unlock_irqrestore(&q->owner_lock, flags); } /* exported - only checking permission */ @@ -387,13 +368,11 @@ int snd_seq_queue_check_access(int queueid, int client) { struct snd_seq_queue *q = queueptr(queueid); int access_ok; - unsigned long flags; if (! q) return 0; - spin_lock_irqsave(&q->owner_lock, flags); - access_ok = check_access(q, client); - spin_unlock_irqrestore(&q->owner_lock, flags); + scoped_guard(spinlock_irqsave, &q->owner_lock) + access_ok = check_access(q, client); queuefree(q); return access_ok; } @@ -406,7 +385,6 @@ int snd_seq_queue_check_access(int queueid, int client) int snd_seq_queue_set_owner(int queueid, int client, int locked) { struct snd_seq_queue *q = queueptr(queueid); - unsigned long flags; if (q == NULL) return -EINVAL; @@ -416,10 +394,10 @@ int snd_seq_queue_set_owner(int queueid, int client, int locked) return -EPERM; } - spin_lock_irqsave(&q->owner_lock, flags); - q->locked = locked ? 1 : 0; - q->owner = client; - spin_unlock_irqrestore(&q->owner_lock, flags); + scoped_guard(spinlock_irqsave, &q->owner_lock) { + q->locked = locked ? 1 : 0; + q->owner = client; + } queue_access_unlock(q); queuefree(q); @@ -750,10 +728,10 @@ void snd_seq_info_queues_read(struct snd_info_entry *entry, else bpm = 0; - spin_lock_irq(&q->owner_lock); - locked = q->locked; - owner = q->owner; - spin_unlock_irq(&q->owner_lock); + scoped_guard(spinlock_irq, &q->owner_lock) { + locked = q->locked; + owner = q->owner; + } snd_iprintf(buffer, "queue %d: [%s]\n", q->queue, q->name); snd_iprintf(buffer, "owned by client : %d\n", owner); diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c index 9863be6fd4..ad2b97e276 100644 --- a/sound/core/seq/seq_timer.c +++ b/sound/core/seq/seq_timer.c @@ -75,9 +75,7 @@ void snd_seq_timer_delete(struct snd_seq_timer **tmr) void snd_seq_timer_defaults(struct snd_seq_timer * tmr) { - unsigned long flags; - - spin_lock_irqsave(&tmr->lock, flags); + guard(spinlock_irqsave)(&tmr->lock); /* setup defaults */ tmr->ppq = 96; /* 96 PPQ */ tmr->tempo = 500000; /* 120 BPM */ @@ -93,7 +91,6 @@ void snd_seq_timer_defaults(struct snd_seq_timer * tmr) tmr->preferred_resolution = seq_default_timer_resolution; tmr->skew = tmr->skew_base = SKEW_BASE; - spin_unlock_irqrestore(&tmr->lock, flags); } static void seq_timer_reset(struct snd_seq_timer *tmr) @@ -108,11 +105,8 @@ static void seq_timer_reset(struct snd_seq_timer *tmr) void snd_seq_timer_reset(struct snd_seq_timer *tmr) { - unsigned long flags; - - spin_lock_irqsave(&tmr->lock, flags); + guard(spinlock_irqsave)(&tmr->lock); seq_timer_reset(tmr); - spin_unlock_irqrestore(&tmr->lock, flags); } @@ -121,7 +115,6 @@ static void snd_seq_timer_interrupt(struct snd_timer_instance *timeri, unsigned long resolution, unsigned long ticks) { - unsigned long flags; struct snd_seq_queue *q = timeri->callback_data; struct snd_seq_timer *tmr; @@ -130,29 +123,27 @@ static void snd_seq_timer_interrupt(struct snd_timer_instance *timeri, tmr = q->timer; if (tmr == NULL) return; - spin_lock_irqsave(&tmr->lock, flags); - if (!tmr->running) { - spin_unlock_irqrestore(&tmr->lock, flags); - return; - } - resolution *= ticks; - if (tmr->skew != tmr->skew_base) { - /* FIXME: assuming skew_base = 0x10000 */ - resolution = (resolution >> 16) * tmr->skew + - (((resolution & 0xffff) * tmr->skew) >> 16); - } + scoped_guard(spinlock_irqsave, &tmr->lock) { + if (!tmr->running) + return; - /* update timer */ - snd_seq_inc_time_nsec(&tmr->cur_time, resolution); + resolution *= ticks; + if (tmr->skew != tmr->skew_base) { + /* FIXME: assuming skew_base = 0x10000 */ + resolution = (resolution >> 16) * tmr->skew + + (((resolution & 0xffff) * tmr->skew) >> 16); + } - /* calculate current tick */ - snd_seq_timer_update_tick(&tmr->tick, resolution); + /* update timer */ + snd_seq_inc_time_nsec(&tmr->cur_time, resolution); - /* register actual time of this timer update */ - ktime_get_ts64(&tmr->last_update); + /* calculate current tick */ + snd_seq_timer_update_tick(&tmr->tick, resolution); - spin_unlock_irqrestore(&tmr->lock, flags); + /* register actual time of this timer update */ + ktime_get_ts64(&tmr->last_update); + } /* check queues and dispatch events */ snd_seq_check_queue(q, 1, 0); @@ -161,18 +152,15 @@ static void snd_seq_timer_interrupt(struct snd_timer_instance *timeri, /* set current tempo */ int snd_seq_timer_set_tempo(struct snd_seq_timer * tmr, int tempo) { - unsigned long flags; - if (snd_BUG_ON(!tmr)) return -EINVAL; if (tempo <= 0) return -EINVAL; - spin_lock_irqsave(&tmr->lock, flags); + guard(spinlock_irqsave)(&tmr->lock); if ((unsigned int)tempo != tmr->tempo) { tmr->tempo = tempo; snd_seq_timer_set_tick_resolution(tmr); } - spin_unlock_irqrestore(&tmr->lock, flags); return 0; } @@ -180,17 +168,15 @@ int snd_seq_timer_set_tempo(struct snd_seq_timer * tmr, int tempo) int snd_seq_timer_set_tempo_ppq(struct snd_seq_timer *tmr, int tempo, int ppq) { int changed; - unsigned long flags; if (snd_BUG_ON(!tmr)) return -EINVAL; if (tempo <= 0 || ppq <= 0) return -EINVAL; - spin_lock_irqsave(&tmr->lock, flags); + guard(spinlock_irqsave)(&tmr->lock); if (tmr->running && (ppq != tmr->ppq)) { /* refuse to change ppq on running timers */ /* because it will upset the song position (ticks) */ - spin_unlock_irqrestore(&tmr->lock, flags); pr_debug("ALSA: seq: cannot change ppq of a running timer\n"); return -EBUSY; } @@ -199,7 +185,6 @@ int snd_seq_timer_set_tempo_ppq(struct snd_seq_timer *tmr, int tempo, int ppq) tmr->ppq = ppq; if (changed) snd_seq_timer_set_tick_resolution(tmr); - spin_unlock_irqrestore(&tmr->lock, flags); return 0; } @@ -207,15 +192,12 @@ int snd_seq_timer_set_tempo_ppq(struct snd_seq_timer *tmr, int tempo, int ppq) int snd_seq_timer_set_position_tick(struct snd_seq_timer *tmr, snd_seq_tick_time_t position) { - unsigned long flags; - if (snd_BUG_ON(!tmr)) return -EINVAL; - spin_lock_irqsave(&tmr->lock, flags); + guard(spinlock_irqsave)(&tmr->lock); tmr->tick.cur_tick = position; tmr->tick.fraction = 0; - spin_unlock_irqrestore(&tmr->lock, flags); return 0; } @@ -223,15 +205,12 @@ int snd_seq_timer_set_position_tick(struct snd_seq_timer *tmr, int snd_seq_timer_set_position_time(struct snd_seq_timer *tmr, snd_seq_real_time_t position) { - unsigned long flags; - if (snd_BUG_ON(!tmr)) return -EINVAL; snd_seq_sanity_real_time(&position); - spin_lock_irqsave(&tmr->lock, flags); + guard(spinlock_irqsave)(&tmr->lock); tmr->cur_time = position; - spin_unlock_irqrestore(&tmr->lock, flags); return 0; } @@ -239,8 +218,6 @@ int snd_seq_timer_set_position_time(struct snd_seq_timer *tmr, int snd_seq_timer_set_skew(struct snd_seq_timer *tmr, unsigned int skew, unsigned int base) { - unsigned long flags; - if (snd_BUG_ON(!tmr)) return -EINVAL; @@ -249,9 +226,8 @@ int snd_seq_timer_set_skew(struct snd_seq_timer *tmr, unsigned int skew, pr_debug("ALSA: seq: invalid skew base 0x%x\n", base); return -EINVAL; } - spin_lock_irqsave(&tmr->lock, flags); + guard(spinlock_irqsave)(&tmr->lock); tmr->skew = skew; - spin_unlock_irqrestore(&tmr->lock, flags); return 0; } @@ -296,12 +272,12 @@ int snd_seq_timer_open(struct snd_seq_queue *q) snd_timer_instance_free(t); return err; } - spin_lock_irq(&tmr->lock); - if (tmr->timeri) - err = -EBUSY; - else - tmr->timeri = t; - spin_unlock_irq(&tmr->lock); + scoped_guard(spinlock_irq, &tmr->lock) { + if (tmr->timeri) + err = -EBUSY; + else + tmr->timeri = t; + } if (err < 0) { snd_timer_close(t); snd_timer_instance_free(t); @@ -318,10 +294,10 @@ int snd_seq_timer_close(struct snd_seq_queue *q) tmr = q->timer; if (snd_BUG_ON(!tmr)) return -EINVAL; - spin_lock_irq(&tmr->lock); - t = tmr->timeri; - tmr->timeri = NULL; - spin_unlock_irq(&tmr->lock); + scoped_guard(spinlock_irq, &tmr->lock) { + t = tmr->timeri; + tmr->timeri = NULL; + } if (t) { snd_timer_close(t); snd_timer_instance_free(t); @@ -342,13 +318,8 @@ static int seq_timer_stop(struct snd_seq_timer *tmr) int snd_seq_timer_stop(struct snd_seq_timer *tmr) { - unsigned long flags; - int err; - - spin_lock_irqsave(&tmr->lock, flags); - err = seq_timer_stop(tmr); - spin_unlock_irqrestore(&tmr->lock, flags); - return err; + guard(spinlock_irqsave)(&tmr->lock); + return seq_timer_stop(tmr); } static int initialize_timer(struct snd_seq_timer *tmr) @@ -398,13 +369,8 @@ static int seq_timer_start(struct snd_seq_timer *tmr) int snd_seq_timer_start(struct snd_seq_timer *tmr) { - unsigned long flags; - int err; - - spin_lock_irqsave(&tmr->lock, flags); - err = seq_timer_start(tmr); - spin_unlock_irqrestore(&tmr->lock, flags); - return err; + guard(spinlock_irqsave)(&tmr->lock); + return seq_timer_start(tmr); } static int seq_timer_continue(struct snd_seq_timer *tmr) @@ -426,13 +392,8 @@ static int seq_timer_continue(struct snd_seq_timer *tmr) int snd_seq_timer_continue(struct snd_seq_timer *tmr) { - unsigned long flags; - int err; - - spin_lock_irqsave(&tmr->lock, flags); - err = seq_timer_continue(tmr); - spin_unlock_irqrestore(&tmr->lock, flags); - return err; + guard(spinlock_irqsave)(&tmr->lock); + return seq_timer_continue(tmr); } /* return current 'real' time. use timeofday() to get better granularity. */ @@ -440,9 +401,8 @@ snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr, bool adjust_ktime) { snd_seq_real_time_t cur_time; - unsigned long flags; - spin_lock_irqsave(&tmr->lock, flags); + guard(spinlock_irqsave)(&tmr->lock); cur_time = tmr->cur_time; if (adjust_ktime && tmr->running) { struct timespec64 tm; @@ -453,7 +413,6 @@ snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr, cur_time.tv_sec += tm.tv_sec; snd_seq_sanity_real_time(&cur_time); } - spin_unlock_irqrestore(&tmr->lock, flags); return cur_time; } @@ -461,13 +420,8 @@ snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr, high PPQ values) */ snd_seq_tick_time_t snd_seq_timer_get_cur_tick(struct snd_seq_timer *tmr) { - snd_seq_tick_time_t cur_tick; - unsigned long flags; - - spin_lock_irqsave(&tmr->lock, flags); - cur_tick = tmr->tick.cur_tick; - spin_unlock_irqrestore(&tmr->lock, flags); - return cur_tick; + guard(spinlock_irqsave)(&tmr->lock); + return tmr->tick.cur_tick; } @@ -486,19 +440,18 @@ void snd_seq_info_timer_read(struct snd_info_entry *entry, q = queueptr(idx); if (q == NULL) continue; - mutex_lock(&q->timer_mutex); - tmr = q->timer; - if (!tmr) - goto unlock; - ti = tmr->timeri; - if (!ti) - goto unlock; - snd_iprintf(buffer, "Timer for queue %i : %s\n", q->queue, ti->timer->name); - resolution = snd_timer_resolution(ti) * tmr->ticks; - snd_iprintf(buffer, " Period time : %lu.%09lu\n", resolution / 1000000000, resolution % 1000000000); - snd_iprintf(buffer, " Skew : %u / %u\n", tmr->skew, tmr->skew_base); -unlock: - mutex_unlock(&q->timer_mutex); + scoped_guard(mutex, &q->timer_mutex) { + tmr = q->timer; + if (!tmr) + break; + ti = tmr->timeri; + if (!ti) + break; + snd_iprintf(buffer, "Timer for queue %i : %s\n", q->queue, ti->timer->name); + resolution = snd_timer_resolution(ti) * tmr->ticks; + snd_iprintf(buffer, " Period time : %lu.%09lu\n", resolution / 1000000000, resolution % 1000000000); + snd_iprintf(buffer, " Skew : %u / %u\n", tmr->skew, tmr->skew_base); + } queuefree(q); } } diff --git a/sound/core/seq/seq_ump_client.c b/sound/core/seq/seq_ump_client.c index 2db371d799..c627d72f7f 100644 --- a/sound/core/seq/seq_ump_client.c +++ b/sound/core/seq/seq_ump_client.c @@ -115,21 +115,19 @@ static int seq_ump_process_event(struct snd_seq_event *ev, int direct, static int seq_ump_client_open(struct seq_ump_client *client, int dir) { struct snd_ump_endpoint *ump = client->ump; - int err = 0; + int err; - mutex_lock(&ump->open_mutex); + guard(mutex)(&ump->open_mutex); if (dir == STR_OUT && !client->opened[dir]) { err = snd_rawmidi_kernel_open(&ump->core, 0, SNDRV_RAWMIDI_LFLG_OUTPUT | SNDRV_RAWMIDI_LFLG_APPEND, &client->out_rfile); if (err < 0) - goto unlock; + return err; } client->opened[dir]++; - unlock: - mutex_unlock(&ump->open_mutex); - return err; + return 0; } /* close the rawmidi */ @@ -137,11 +135,10 @@ static int seq_ump_client_close(struct seq_ump_client *client, int dir) { struct snd_ump_endpoint *ump = client->ump; - mutex_lock(&ump->open_mutex); + guard(mutex)(&ump->open_mutex); if (!--client->opened[dir]) if (dir == STR_OUT) snd_rawmidi_kernel_release(&client->out_rfile); - mutex_unlock(&ump->open_mutex); return 0; } @@ -217,15 +214,12 @@ static void fill_port_info(struct snd_seq_port_info *port, static int seq_ump_group_init(struct seq_ump_client *client, int group_index) { struct seq_ump_group *group = &client->groups[group_index]; - struct snd_seq_port_info *port; + struct snd_seq_port_info *port __free(kfree) = NULL; struct snd_seq_port_callback pcallbacks; - int err; port = kzalloc(sizeof(*port), GFP_KERNEL); - if (!port) { - err = -ENOMEM; - goto error; - } + if (!port) + return -ENOMEM; fill_port_info(port, client, group); port->flags = SNDRV_SEQ_PORT_FLG_GIVEN_PORT; @@ -238,24 +232,22 @@ static int seq_ump_group_init(struct seq_ump_client *client, int group_index) pcallbacks.unuse = seq_ump_unuse; pcallbacks.event_input = seq_ump_process_event; port->kernel = &pcallbacks; - err = snd_seq_kernel_client_ctl(client->seq_client, - SNDRV_SEQ_IOCTL_CREATE_PORT, - port); - error: - kfree(port); - return err; + return snd_seq_kernel_client_ctl(client->seq_client, + SNDRV_SEQ_IOCTL_CREATE_PORT, + port); } /* update the sequencer ports; called from notify_fb_change callback */ static void update_port_infos(struct seq_ump_client *client) { - struct snd_seq_port_info *old, *new; + struct snd_seq_port_info *old __free(kfree) = NULL; + struct snd_seq_port_info *new __free(kfree) = NULL; int i, err; old = kzalloc(sizeof(*old), GFP_KERNEL); new = kzalloc(sizeof(*new), GFP_KERNEL); if (!old || !new) - goto error; + return; for (i = 0; i < SNDRV_UMP_MAX_GROUPS; i++) { old->addr.client = client->seq_client; @@ -264,7 +256,7 @@ static void update_port_infos(struct seq_ump_client *client) SNDRV_SEQ_IOCTL_GET_PORT_INFO, old); if (err < 0) - goto error; + return; fill_port_info(new, client, &client->groups[i]); if (old->capability == new->capability && !strcmp(old->name, new->name)) @@ -273,13 +265,10 @@ static void update_port_infos(struct seq_ump_client *client) SNDRV_SEQ_IOCTL_SET_PORT_INFO, new); if (err < 0) - goto error; + return; /* notify to system port */ snd_seq_system_client_ev_port_change(client->seq_client, i); } - error: - kfree(new); - kfree(old); } /* update dir_bits and active flag for all groups in the client */ @@ -334,7 +323,7 @@ static void update_group_attrs(struct seq_ump_client *client) /* create a UMP Endpoint port */ static int create_ump_endpoint_port(struct seq_ump_client *client) { - struct snd_seq_port_info *port; + struct snd_seq_port_info *port __free(kfree) = NULL; struct snd_seq_port_callback pcallbacks; unsigned int rawmidi_info = client->ump->core.info_flags; int err; @@ -383,7 +372,6 @@ static int create_ump_endpoint_port(struct seq_ump_client *client) err = snd_seq_kernel_client_ctl(client->seq_client, SNDRV_SEQ_IOCTL_CREATE_PORT, port); - kfree(port); return err; } diff --git a/sound/core/seq/seq_ump_convert.c b/sound/core/seq/seq_ump_convert.c index ee6ac649df..d81f776a4c 100644 --- a/sound/core/seq/seq_ump_convert.c +++ b/sound/core/seq/seq_ump_convert.c @@ -157,7 +157,7 @@ static void ump_system_to_one_param_ev(const union snd_ump_midi1_msg *val, static void ump_system_to_songpos_ev(const union snd_ump_midi1_msg *val, struct snd_seq_event *ev) { - ev->data.control.value = (val->system.parm1 << 7) | val->system.parm2; + ev->data.control.value = (val->system.parm2 << 7) | val->system.parm1; } /* Encoders for 0xf0 - 0xff */ @@ -368,6 +368,7 @@ static int cvt_ump_midi1_to_midi2(struct snd_seq_client *dest, struct snd_seq_ump_event ev_cvt; const union snd_ump_midi1_msg *midi1 = (const union snd_ump_midi1_msg *)event->ump; union snd_ump_midi2_msg *midi2 = (union snd_ump_midi2_msg *)ev_cvt.ump; + struct snd_seq_ump_midi2_bank *cc; ev_cvt = *event; memset(&ev_cvt.ump, 0, sizeof(ev_cvt.ump)); @@ -387,11 +388,29 @@ static int cvt_ump_midi1_to_midi2(struct snd_seq_client *dest, midi2->paf.data = upscale_7_to_32bit(midi1->paf.data); break; case UMP_MSG_STATUS_CC: + cc = &dest_port->midi2_bank[midi1->note.channel]; + switch (midi1->cc.index) { + case UMP_CC_BANK_SELECT: + cc->bank_set = 1; + cc->cc_bank_msb = midi1->cc.data; + return 0; // skip + case UMP_CC_BANK_SELECT_LSB: + cc->bank_set = 1; + cc->cc_bank_lsb = midi1->cc.data; + return 0; // skip + } midi2->cc.index = midi1->cc.index; midi2->cc.data = upscale_7_to_32bit(midi1->cc.data); break; case UMP_MSG_STATUS_PROGRAM: midi2->pg.program = midi1->pg.program; + cc = &dest_port->midi2_bank[midi1->note.channel]; + if (cc->bank_set) { + midi2->pg.bank_valid = 1; + midi2->pg.bank_msb = cc->cc_bank_msb; + midi2->pg.bank_lsb = cc->cc_bank_lsb; + cc->bank_set = 0; + } break; case UMP_MSG_STATUS_CHANNEL_PRESSURE: midi2->caf.data = upscale_7_to_32bit(midi1->caf.data); @@ -419,6 +438,7 @@ static int cvt_ump_midi2_to_midi1(struct snd_seq_client *dest, struct snd_seq_ump_event ev_cvt; union snd_ump_midi1_msg *midi1 = (union snd_ump_midi1_msg *)ev_cvt.ump; const union snd_ump_midi2_msg *midi2 = (const union snd_ump_midi2_msg *)event->ump; + int err; u16 v; ev_cvt = *event; @@ -443,6 +463,24 @@ static int cvt_ump_midi2_to_midi1(struct snd_seq_client *dest, midi1->cc.data = downscale_32_to_7bit(midi2->cc.data); break; case UMP_MSG_STATUS_PROGRAM: + if (midi2->pg.bank_valid) { + midi1->cc.status = UMP_MSG_STATUS_CC; + midi1->cc.index = UMP_CC_BANK_SELECT; + midi1->cc.data = midi2->pg.bank_msb; + err = __snd_seq_deliver_single_event(dest, dest_port, + (struct snd_seq_event *)&ev_cvt, + atomic, hop); + if (err < 0) + return err; + midi1->cc.index = UMP_CC_BANK_SELECT_LSB; + midi1->cc.data = midi2->pg.bank_lsb; + err = __snd_seq_deliver_single_event(dest, dest_port, + (struct snd_seq_event *)&ev_cvt, + atomic, hop); + if (err < 0) + return err; + midi1->note.status = midi2->note.status; + } midi1->pg.program = midi2->pg.program; break; case UMP_MSG_STATUS_CHANNEL_PRESSURE: @@ -691,6 +729,7 @@ static int system_ev_to_ump_midi1(const struct snd_seq_event *event, union snd_ump_midi1_msg *data, unsigned char status) { + data->system.type = UMP_MSG_TYPE_SYSTEM; // override data->system.status = status; return 1; } @@ -701,6 +740,7 @@ static int system_1p_ev_to_ump_midi1(const struct snd_seq_event *event, union snd_ump_midi1_msg *data, unsigned char status) { + data->system.type = UMP_MSG_TYPE_SYSTEM; // override data->system.status = status; data->system.parm1 = event->data.control.value & 0x7f; return 1; @@ -712,9 +752,10 @@ static int system_2p_ev_to_ump_midi1(const struct snd_seq_event *event, union snd_ump_midi1_msg *data, unsigned char status) { + data->system.type = UMP_MSG_TYPE_SYSTEM; // override data->system.status = status; - data->system.parm1 = (event->data.control.value >> 7) & 0x7f; - data->system.parm2 = event->data.control.value & 0x7f; + data->system.parm1 = event->data.control.value & 0x7f; + data->system.parm2 = (event->data.control.value >> 7) & 0x7f; return 1; } @@ -854,7 +895,6 @@ static int pgm_ev_to_ump_midi2(const struct snd_seq_event *event, data->pg.bank_msb = cc->cc_bank_msb; data->pg.bank_lsb = cc->cc_bank_lsb; cc->bank_set = 0; - cc->cc_bank_msb = cc->cc_bank_lsb = 0; } return 1; } @@ -1035,6 +1075,8 @@ static const struct seq_ev_to_ump seq_ev_ump_encoders[] = { system_ev_to_ump_midi1, system_ev_to_ump_midi2 }, { SNDRV_SEQ_EVENT_SENSING, UMP_SYSTEM_STATUS_ACTIVE_SENSING, system_ev_to_ump_midi1, system_ev_to_ump_midi2 }, + { SNDRV_SEQ_EVENT_RESET, UMP_SYSTEM_STATUS_RESET, + system_ev_to_ump_midi1, system_ev_to_ump_midi2 }, }; static const struct seq_ev_to_ump *find_ump_encoder(int type) diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c index 1678737f11..b4672613c2 100644 --- a/sound/core/seq/seq_virmidi.c +++ b/sound/core/seq/seq_virmidi.c @@ -199,11 +199,10 @@ static int snd_virmidi_input_open(struct snd_rawmidi_substream *substream) vmidi->client = rdev->client; vmidi->port = rdev->port; runtime->private_data = vmidi; - down_write(&rdev->filelist_sem); - write_lock_irq(&rdev->filelist_lock); - list_add_tail(&vmidi->list, &rdev->filelist); - write_unlock_irq(&rdev->filelist_lock); - up_write(&rdev->filelist_sem); + scoped_guard(rwsem_write, &rdev->filelist_sem) { + guard(write_lock_irq)(&rdev->filelist_lock); + list_add_tail(&vmidi->list, &rdev->filelist); + } vmidi->rdev = rdev; return 0; } @@ -243,11 +242,10 @@ static int snd_virmidi_input_close(struct snd_rawmidi_substream *substream) struct snd_virmidi_dev *rdev = substream->rmidi->private_data; struct snd_virmidi *vmidi = substream->runtime->private_data; - down_write(&rdev->filelist_sem); - write_lock_irq(&rdev->filelist_lock); - list_del(&vmidi->list); - write_unlock_irq(&rdev->filelist_lock); - up_write(&rdev->filelist_sem); + scoped_guard(rwsem_write, &rdev->filelist_sem) { + guard(write_lock_irq)(&rdev->filelist_lock); + list_del(&vmidi->list); + } snd_midi_event_free(vmidi->parser); substream->runtime->private_data = NULL; kfree(vmidi); @@ -363,26 +361,22 @@ static int snd_virmidi_dev_attach_seq(struct snd_virmidi_dev *rdev) { int client; struct snd_seq_port_callback pcallbacks; - struct snd_seq_port_info *pinfo; + struct snd_seq_port_info *pinfo __free(kfree) = NULL; int err; if (rdev->client >= 0) return 0; pinfo = kzalloc(sizeof(*pinfo), GFP_KERNEL); - if (!pinfo) { - err = -ENOMEM; - goto __error; - } + if (!pinfo) + return -ENOMEM; client = snd_seq_create_kernel_client(rdev->card, rdev->device, "%s %d-%d", rdev->rmidi->name, rdev->card->number, rdev->device); - if (client < 0) { - err = client; - goto __error; - } + if (client < 0) + return client; rdev->client = client; /* create a port */ @@ -410,15 +404,11 @@ static int snd_virmidi_dev_attach_seq(struct snd_virmidi_dev *rdev) if (err < 0) { snd_seq_delete_kernel_client(client); rdev->client = -1; - goto __error; + return err; } rdev->port = pinfo->addr.port; - err = 0; /* success */ - - __error: - kfree(pinfo); - return err; + return 0; /* success */ } |