summaryrefslogtreecommitdiff
path: root/sound/core
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/compress_offload.c43
-rw-r--r--sound/core/control_led.c14
-rw-r--r--sound/core/memalloc.c2
-rw-r--r--sound/core/seq/oss/seq_oss_synth.c2
-rw-r--r--sound/core/seq/seq_clientmgr.c14
-rw-r--r--sound/core/seq/seq_ump_client.c6
-rw-r--r--sound/core/ump.c28
7 files changed, 73 insertions, 36 deletions
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
index 86ed2fbee0c8..840bb9cfe789 100644
--- a/sound/core/compress_offload.c
+++ b/sound/core/compress_offload.c
@@ -1025,7 +1025,7 @@ static u64 snd_compr_seqno_next(struct snd_compr_stream *stream)
static int snd_compr_task_new(struct snd_compr_stream *stream, struct snd_compr_task *utask)
{
struct snd_compr_task_runtime *task;
- int retval;
+ int retval, fd_i, fd_o;
if (stream->runtime->total_tasks >= stream->runtime->fragments)
return -EBUSY;
@@ -1039,19 +1039,27 @@ static int snd_compr_task_new(struct snd_compr_stream *stream, struct snd_compr_
retval = stream->ops->task_create(stream, task);
if (retval < 0)
goto cleanup;
- utask->input_fd = dma_buf_fd(task->input, O_WRONLY|O_CLOEXEC);
- if (utask->input_fd < 0) {
- retval = utask->input_fd;
+ /* similar functionality as in dma_buf_fd(), but ensure that both
+ file descriptors are allocated before fd_install() */
+ if (!task->input || !task->input->file || !task->output || !task->output->file) {
+ retval = -EINVAL;
goto cleanup;
}
- utask->output_fd = dma_buf_fd(task->output, O_RDONLY|O_CLOEXEC);
- if (utask->output_fd < 0) {
- retval = utask->output_fd;
+ fd_i = get_unused_fd_flags(O_WRONLY|O_CLOEXEC);
+ if (fd_i < 0)
+ goto cleanup;
+ fd_o = get_unused_fd_flags(O_RDONLY|O_CLOEXEC);
+ if (fd_o < 0) {
+ put_unused_fd(fd_i);
goto cleanup;
}
/* keep dmabuf reference until freed with task free ioctl */
- dma_buf_get(utask->input_fd);
- dma_buf_get(utask->output_fd);
+ get_dma_buf(task->input);
+ get_dma_buf(task->output);
+ fd_install(fd_i, task->input->file);
+ fd_install(fd_o, task->output->file);
+ utask->input_fd = fd_i;
+ utask->output_fd = fd_o;
list_add_tail(&task->list, &stream->runtime->tasks);
stream->runtime->total_tasks++;
return 0;
@@ -1069,7 +1077,7 @@ static int snd_compr_task_create(struct snd_compr_stream *stream, unsigned long
return -EPERM;
task = memdup_user((void __user *)arg, sizeof(*task));
if (IS_ERR(task))
- return PTR_ERR(no_free_ptr(task));
+ return PTR_ERR(task);
retval = snd_compr_task_new(stream, task);
if (retval >= 0)
if (copy_to_user((void __user *)arg, task, sizeof(*task)))
@@ -1130,7 +1138,7 @@ static int snd_compr_task_start_ioctl(struct snd_compr_stream *stream, unsigned
return -EPERM;
task = memdup_user((void __user *)arg, sizeof(*task));
if (IS_ERR(task))
- return PTR_ERR(no_free_ptr(task));
+ return PTR_ERR(task);
retval = snd_compr_task_start(stream, task);
if (retval >= 0)
if (copy_to_user((void __user *)arg, task, sizeof(*task)))
@@ -1174,18 +1182,18 @@ typedef void (*snd_compr_seq_func_t)(struct snd_compr_stream *stream,
static int snd_compr_task_seq(struct snd_compr_stream *stream, unsigned long arg,
snd_compr_seq_func_t fcn)
{
- struct snd_compr_task_runtime *task;
+ struct snd_compr_task_runtime *task, *temp;
__u64 seqno;
int retval;
if (stream->runtime->state != SNDRV_PCM_STATE_SETUP)
return -EPERM;
- retval = get_user(seqno, (__u64 __user *)arg);
- if (retval < 0)
- return retval;
+ retval = copy_from_user(&seqno, (__u64 __user *)arg, sizeof(seqno));
+ if (retval)
+ return -EFAULT;
retval = 0;
if (seqno == 0) {
- list_for_each_entry_reverse(task, &stream->runtime->tasks, list)
+ list_for_each_entry_safe_reverse(task, temp, &stream->runtime->tasks, list)
fcn(stream, task);
} else {
task = snd_compr_find_task(stream, seqno);
@@ -1221,7 +1229,7 @@ static int snd_compr_task_status_ioctl(struct snd_compr_stream *stream, unsigned
return -EPERM;
status = memdup_user((void __user *)arg, sizeof(*status));
if (IS_ERR(status))
- return PTR_ERR(no_free_ptr(status));
+ return PTR_ERR(status);
retval = snd_compr_task_status(stream, status);
if (retval >= 0)
if (copy_to_user((void __user *)arg, status, sizeof(*status)))
@@ -1247,6 +1255,7 @@ void snd_compr_task_finished(struct snd_compr_stream *stream,
}
EXPORT_SYMBOL_GPL(snd_compr_task_finished);
+MODULE_IMPORT_NS("DMA_BUF");
#endif /* CONFIG_SND_COMPRESS_ACCEL */
static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
diff --git a/sound/core/control_led.c b/sound/core/control_led.c
index 65a1ebe87776..e33dfcf863cf 100644
--- a/sound/core/control_led.c
+++ b/sound/core/control_led.c
@@ -668,10 +668,16 @@ static void snd_ctl_led_sysfs_add(struct snd_card *card)
goto cerr;
led->cards[card->number] = led_card;
snprintf(link_name, sizeof(link_name), "led-%s", led->name);
- WARN(sysfs_create_link(&card->ctl_dev->kobj, &led_card->dev.kobj, link_name),
- "can't create symlink to controlC%i device\n", card->number);
- WARN(sysfs_create_link(&led_card->dev.kobj, &card->card_dev.kobj, "card"),
- "can't create symlink to card%i\n", card->number);
+ if (sysfs_create_link(&card->ctl_dev->kobj, &led_card->dev.kobj,
+ link_name))
+ dev_err(card->dev,
+ "%s: can't create symlink to controlC%i device\n",
+ __func__, card->number);
+ if (sysfs_create_link(&led_card->dev.kobj, &card->card_dev.kobj,
+ "card"))
+ dev_err(card->dev,
+ "%s: can't create symlink to card%i\n",
+ __func__, card->number);
continue;
cerr:
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index 13b71069ae18..b3853583d2ae 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -505,7 +505,7 @@ static void *snd_dma_wc_alloc(struct snd_dma_buffer *dmab, size_t size)
if (!p)
return NULL;
dmab->addr = dma_map_single(dmab->dev.dev, p, size, DMA_BIDIRECTIONAL);
- if (dmab->addr == DMA_MAPPING_ERROR) {
+ if (dma_mapping_error(dmab->dev.dev, dmab->addr)) {
do_free_pages(dmab->area, size, true);
return NULL;
}
diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c
index e3394919daa0..51ee4c00a843 100644
--- a/sound/core/seq/oss/seq_oss_synth.c
+++ b/sound/core/seq/oss/seq_oss_synth.c
@@ -66,6 +66,7 @@ static struct seq_oss_synth midi_synth_dev = {
};
static DEFINE_SPINLOCK(register_lock);
+static DEFINE_MUTEX(sysex_mutex);
/*
* prototypes
@@ -497,6 +498,7 @@ snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf,
if (!info)
return -ENXIO;
+ guard(mutex)(&sysex_mutex);
sysex = info->sysex;
if (sysex == NULL) {
sysex = kzalloc(sizeof(*sysex), GFP_KERNEL);
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index 3930e2f9082f..77b6ac9b5c11 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -1275,10 +1275,16 @@ static int snd_seq_ioctl_set_client_info(struct snd_seq_client *client,
if (client->type != client_info->type)
return -EINVAL;
- /* check validity of midi_version field */
- if (client->user_pversion >= SNDRV_PROTOCOL_VERSION(1, 0, 3) &&
- client_info->midi_version > SNDRV_SEQ_CLIENT_UMP_MIDI_2_0)
- return -EINVAL;
+ if (client->user_pversion >= SNDRV_PROTOCOL_VERSION(1, 0, 3)) {
+ /* check validity of midi_version field */
+ if (client_info->midi_version > SNDRV_SEQ_CLIENT_UMP_MIDI_2_0)
+ return -EINVAL;
+
+ /* check if UMP is supported in kernel */
+ if (!IS_ENABLED(CONFIG_SND_SEQ_UMP) &&
+ client_info->midi_version > 0)
+ return -EINVAL;
+ }
/* fill the info fields */
if (client_info->name[0])
diff --git a/sound/core/seq/seq_ump_client.c b/sound/core/seq/seq_ump_client.c
index e5d3f4d206bf..e956f17f3792 100644
--- a/sound/core/seq/seq_ump_client.c
+++ b/sound/core/seq/seq_ump_client.c
@@ -257,12 +257,12 @@ static void update_port_infos(struct seq_ump_client *client)
continue;
old->addr.client = client->seq_client;
- old->addr.port = i;
+ old->addr.port = ump_group_to_seq_port(i);
err = snd_seq_kernel_client_ctl(client->seq_client,
SNDRV_SEQ_IOCTL_GET_PORT_INFO,
old);
if (err < 0)
- return;
+ continue;
fill_port_info(new, client, &client->ump->groups[i]);
if (old->capability == new->capability &&
!strcmp(old->name, new->name))
@@ -271,7 +271,7 @@ static void update_port_infos(struct seq_ump_client *client)
SNDRV_SEQ_IOCTL_SET_PORT_INFO,
new);
if (err < 0)
- return;
+ continue;
/* notify to system port */
snd_seq_system_client_ev_port_change(client->seq_client, i);
}
diff --git a/sound/core/ump.c b/sound/core/ump.c
index 6d0aac6c763f..9198bff4768c 100644
--- a/sound/core/ump.c
+++ b/sound/core/ump.c
@@ -37,6 +37,7 @@ static int process_legacy_output(struct snd_ump_endpoint *ump,
u32 *buffer, int count);
static void process_legacy_input(struct snd_ump_endpoint *ump, const u32 *src,
int words);
+static void update_legacy_names(struct snd_ump_endpoint *ump);
#else
static inline int process_legacy_output(struct snd_ump_endpoint *ump,
u32 *buffer, int count)
@@ -47,6 +48,9 @@ static inline void process_legacy_input(struct snd_ump_endpoint *ump,
const u32 *src, int words)
{
}
+static inline void update_legacy_names(struct snd_ump_endpoint *ump)
+{
+}
#endif
static const struct snd_rawmidi_global_ops snd_ump_rawmidi_ops = {
@@ -861,6 +865,7 @@ static int ump_handle_fb_info_msg(struct snd_ump_endpoint *ump,
fill_fb_info(ump, &fb->info, buf);
if (ump->parsed) {
snd_ump_update_group_attrs(ump);
+ update_legacy_names(ump);
seq_notify_fb_change(ump, fb);
}
}
@@ -893,6 +898,7 @@ static int ump_handle_fb_name_msg(struct snd_ump_endpoint *ump,
/* notify the FB name update to sequencer, too */
if (ret > 0 && ump->parsed) {
snd_ump_update_group_attrs(ump);
+ update_legacy_names(ump);
seq_notify_fb_change(ump, fb);
}
return ret;
@@ -1087,6 +1093,8 @@ static int snd_ump_legacy_open(struct snd_rawmidi_substream *substream)
guard(mutex)(&ump->open_mutex);
if (ump->legacy_substreams[dir][group])
return -EBUSY;
+ if (!ump->groups[group].active)
+ return -ENODEV;
if (dir == SNDRV_RAWMIDI_STREAM_OUTPUT) {
if (!ump->legacy_out_opens) {
err = snd_rawmidi_kernel_open(&ump->core, 0,
@@ -1236,7 +1244,7 @@ static int fill_legacy_mapping(struct snd_ump_endpoint *ump)
num = 0;
for (i = 0; i < SNDRV_UMP_MAX_GROUPS; i++)
- if ((group_maps & (1U << i)) && ump->groups[i].valid)
+ if (group_maps & (1U << i))
ump->legacy_mapping[num++] = i;
return num;
@@ -1254,11 +1262,20 @@ static void fill_substream_names(struct snd_ump_endpoint *ump,
name = ump->groups[idx].name;
if (!*name)
name = ump->info.name;
- snprintf(s->name, sizeof(s->name), "Group %d (%.16s)",
- idx + 1, name);
+ scnprintf(s->name, sizeof(s->name), "Group %d (%.16s)%s",
+ idx + 1, name,
+ ump->groups[idx].active ? "" : " [Inactive]");
}
}
+static void update_legacy_names(struct snd_ump_endpoint *ump)
+{
+ struct snd_rawmidi *rmidi = ump->legacy_rmidi;
+
+ fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_INPUT);
+ fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT);
+}
+
int snd_ump_attach_legacy_rawmidi(struct snd_ump_endpoint *ump,
char *id, int device)
{
@@ -1295,10 +1312,7 @@ int snd_ump_attach_legacy_rawmidi(struct snd_ump_endpoint *ump,
rmidi->ops = &snd_ump_legacy_ops;
rmidi->private_data = ump;
ump->legacy_rmidi = rmidi;
- if (input)
- fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_INPUT);
- if (output)
- fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT);
+ update_legacy_names(ump);
ump_dbg(ump, "Created a legacy rawmidi #%d (%s)\n", device, id);
return 0;