summaryrefslogtreecommitdiffstats
path: root/sound/core
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/Kconfig1
-rw-r--r--sound/core/Makefile18
-rw-r--r--sound/core/control_led.c35
-rw-r--r--sound/core/init.c14
-rw-r--r--sound/core/oss/Makefile2
-rw-r--r--sound/core/pcm_dmaengine.c27
-rw-r--r--sound/core/pcm_native.c4
-rw-r--r--sound/core/pcm_trace.h2
-rw-r--r--sound/core/seq/Makefile14
-rw-r--r--sound/core/seq/oss/Makefile2
-rw-r--r--sound/core/seq/seq_dummy.c24
-rw-r--r--sound/core/seq/seq_ump_client.c16
-rw-r--r--sound/core/seq/seq_ump_convert.c47
-rw-r--r--sound/core/sound_kunit.c11
-rw-r--r--sound/core/ump.c21
15 files changed, 170 insertions, 68 deletions
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index 8077f481d8..b970a17346 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -262,6 +262,5 @@ config SND_CTL_LED
tristate
select NEW_LEDS if SND_CTL_LED
select LEDS_TRIGGERS if SND_CTL_LED
- select LEDS_TRIGGER_AUDIO if SND_CTL_LED
source "sound/core/seq/Kconfig"
diff --git a/sound/core/Makefile b/sound/core/Makefile
index b8aa886198..31a0623cc8 100644
--- a/sound/core/Makefile
+++ b/sound/core/Makefile
@@ -24,18 +24,18 @@ snd-pcm-$(CONFIG_SND_PCM_IEC958) += pcm_iec958.o
CFLAGS_pcm_lib.o := -I$(src)
CFLAGS_pcm_native.o := -I$(src)
-snd-pcm-dmaengine-objs := pcm_dmaengine.o
+snd-pcm-dmaengine-y := pcm_dmaengine.o
-snd-ctl-led-objs := control_led.o
-snd-rawmidi-objs := rawmidi.o
-snd-ump-objs := ump.o
+snd-ctl-led-y := control_led.o
+snd-rawmidi-y := rawmidi.o
+snd-ump-y := ump.o
snd-ump-$(CONFIG_SND_UMP_LEGACY_RAWMIDI) += ump_convert.o
-snd-timer-objs := timer.o
-snd-hrtimer-objs := hrtimer.o
-snd-hwdep-objs := hwdep.o
-snd-seq-device-objs := seq_device.o
+snd-timer-y := timer.o
+snd-hrtimer-y := hrtimer.o
+snd-hwdep-y := hwdep.o
+snd-seq-device-y := seq_device.o
-snd-compress-objs := compress_offload.o
+snd-compress-y := compress_offload.o
obj-$(CONFIG_SND) += snd.o
obj-$(CONFIG_SND_CTL_LED) += snd-ctl-led.o
diff --git a/sound/core/control_led.c b/sound/core/control_led.c
index 3d37e9fa7b..804805a95e 100644
--- a/sound/core/control_led.c
+++ b/sound/core/control_led.c
@@ -53,6 +53,7 @@ struct snd_ctl_led_ctl {
static DEFINE_MUTEX(snd_ctl_led_mutex);
static bool snd_ctl_led_card_valid[SNDRV_CARDS];
+static struct led_trigger *snd_ctl_ledtrig_audio[NUM_AUDIO_LEDS];
static struct snd_ctl_led snd_ctl_leds[MAX_LED] = {
{
.name = "speaker",
@@ -174,8 +175,11 @@ static void snd_ctl_led_set_state(struct snd_card *card, unsigned int access,
case MODE_FOLLOW_ROUTE: if (route >= 0) route ^= 1; break;
case MODE_FOLLOW_MUTE: /* noop */ break;
}
- if (route >= 0)
- ledtrig_audio_set(led->trigger_type, route ? LED_OFF : LED_ON);
+ if (route >= 0) {
+ struct led_trigger *trig = snd_ctl_ledtrig_audio[led->trigger_type];
+
+ led_trigger_event(trig, route ? LED_OFF : LED_ON);
+ }
}
static struct snd_ctl_led_ctl *snd_ctl_led_find(struct snd_kcontrol *kctl, unsigned int ioff)
@@ -285,25 +289,22 @@ static void snd_ctl_led_ctl_destroy(struct snd_ctl_led_ctl *lctl)
static void snd_ctl_led_clean(struct snd_card *card)
{
unsigned int group;
+ struct snd_ctl_led_ctl *lctl, *_lctl;
struct snd_ctl_led *led;
- struct snd_ctl_led_ctl *lctl;
for (group = 0; group < MAX_LED; group++) {
led = &snd_ctl_leds[group];
-repeat:
- list_for_each_entry(lctl, &led->controls, list)
- if (!card || lctl->card == card) {
+ list_for_each_entry_safe(lctl, _lctl, &led->controls, list)
+ if (!card || lctl->card == card)
snd_ctl_led_ctl_destroy(lctl);
- goto repeat;
- }
}
}
static int snd_ctl_led_reset(int card_number, unsigned int group)
{
struct snd_card *card __free(snd_card_unref) = NULL;
+ struct snd_ctl_led_ctl *lctl, *_lctl;
struct snd_ctl_led *led;
- struct snd_ctl_led_ctl *lctl;
struct snd_kcontrol_volatile *vd;
bool change = false;
@@ -315,14 +316,12 @@ static int snd_ctl_led_reset(int card_number, unsigned int group)
if (!snd_ctl_led_card_valid[card_number])
return -ENXIO;
led = &snd_ctl_leds[group];
-repeat:
- list_for_each_entry(lctl, &led->controls, list)
+ list_for_each_entry_safe(lctl, _lctl, &led->controls, list)
if (lctl->card == card) {
vd = &lctl->kctl->vd[lctl->index_offset];
vd->access &= ~group_to_access(group);
snd_ctl_led_ctl_destroy(lctl);
change = true;
- goto repeat;
}
}
if (change)
@@ -425,8 +424,9 @@ static ssize_t brightness_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct snd_ctl_led *led = container_of(dev, struct snd_ctl_led, dev);
+ struct led_trigger *trig = snd_ctl_ledtrig_audio[led->trigger_type];
- return sysfs_emit(buf, "%u\n", ledtrig_audio_get(led->trigger_type));
+ return sysfs_emit(buf, "%u\n", led_trigger_get_brightness(trig));
}
static DEVICE_ATTR_RW(mode);
@@ -716,6 +716,9 @@ static int __init snd_ctl_led_init(void)
struct snd_ctl_led *led;
unsigned int group;
+ led_trigger_register_simple("audio-mute", &snd_ctl_ledtrig_audio[LED_AUDIO_MUTE]);
+ led_trigger_register_simple("audio-micmute", &snd_ctl_ledtrig_audio[LED_AUDIO_MICMUTE]);
+
device_initialize(&snd_ctl_led_dev);
snd_ctl_led_dev.class = &sound_class;
snd_ctl_led_dev.release = snd_ctl_led_dev_release;
@@ -768,7 +771,13 @@ static void __exit snd_ctl_led_exit(void)
}
device_unregister(&snd_ctl_led_dev);
snd_ctl_led_clean(NULL);
+
+ led_trigger_unregister_simple(snd_ctl_ledtrig_audio[LED_AUDIO_MUTE]);
+ led_trigger_unregister_simple(snd_ctl_ledtrig_audio[LED_AUDIO_MICMUTE]);
}
module_init(snd_ctl_led_init)
module_exit(snd_ctl_led_exit)
+
+MODULE_ALIAS("ledtrig:audio-mute");
+MODULE_ALIAS("ledtrig:audio-micmute");
diff --git a/sound/core/init.c b/sound/core/init.c
index b8912de048..b9b708cf98 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -50,7 +50,7 @@ MODULE_PARM_DESC(slots, "Module names assigned to the slots.");
static int module_slot_match(struct module *module, int idx)
{
int match = 1;
-#ifdef MODULE
+#ifdef CONFIG_MODULES
const char *s1, *s2;
if (!module || !*module->name || !slots[idx])
@@ -77,7 +77,7 @@ static int module_slot_match(struct module *module, int idx)
if (!c1)
break;
}
-#endif /* MODULE */
+#endif /* CONFIG_MODULES */
return match;
}
@@ -311,9 +311,7 @@ static int snd_card_init(struct snd_card *card, struct device *parent,
}
card->dev = parent;
card->number = idx;
-#ifdef MODULE
- WARN_ON(!module);
-#endif
+ WARN_ON(IS_MODULE(CONFIG_SND) && !module);
card->module = module;
INIT_LIST_HEAD(&card->devices);
init_rwsem(&card->controls_rwsem);
@@ -555,9 +553,7 @@ void snd_card_disconnect(struct snd_card *card)
clear_bit(card->number, snd_cards_lock);
}
-#ifdef CONFIG_PM
snd_power_sync_ref(card);
-#endif
}
EXPORT_SYMBOL(snd_card_disconnect);
@@ -972,7 +968,7 @@ void snd_card_info_read_oss(struct snd_info_buffer *buffer)
#endif
-#ifdef MODULE
+#ifdef CONFIG_MODULES
static void snd_card_module_info_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{
@@ -1000,7 +996,7 @@ int __init snd_card_info_init(void)
if (snd_info_register(entry) < 0)
return -ENOMEM; /* freed in error path */
-#ifdef MODULE
+#ifdef CONFIG_MODULES
entry = snd_info_create_module_entry(THIS_MODULE, "modules", NULL);
if (!entry)
return -ENOMEM;
diff --git a/sound/core/oss/Makefile b/sound/core/oss/Makefile
index ae25edcc3b..d5f48ae6ba 100644
--- a/sound/core/oss/Makefile
+++ b/sound/core/oss/Makefile
@@ -4,7 +4,7 @@
# Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
#
-snd-mixer-oss-objs := mixer_oss.o
+snd-mixer-oss-y := mixer_oss.o
snd-pcm-oss-y := pcm_oss.o
snd-pcm-oss-$(CONFIG_SND_PCM_OSS_PLUGINS) += pcm_plugin.o \
diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c
index 494ec0c207..4786b5a0b9 100644
--- a/sound/core/pcm_dmaengine.c
+++ b/sound/core/pcm_dmaengine.c
@@ -349,6 +349,20 @@ int snd_dmaengine_pcm_open_request_chan(struct snd_pcm_substream *substream,
}
EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_open_request_chan);
+int snd_dmaengine_pcm_sync_stop(struct snd_pcm_substream *substream)
+{
+ struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
+ struct dma_tx_state state;
+ enum dma_status status;
+
+ status = dmaengine_tx_status(prtd->dma_chan, prtd->cookie, &state);
+ if (status != DMA_PAUSED)
+ dmaengine_synchronize(prtd->dma_chan);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_sync_stop);
+
/**
* snd_dmaengine_pcm_close - Close a dmaengine based PCM substream
* @substream: PCM substream
@@ -358,6 +372,12 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_open_request_chan);
int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream)
{
struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
+ struct dma_tx_state state;
+ enum dma_status status;
+
+ status = dmaengine_tx_status(prtd->dma_chan, prtd->cookie, &state);
+ if (status == DMA_PAUSED)
+ dmaengine_terminate_async(prtd->dma_chan);
dmaengine_synchronize(prtd->dma_chan);
kfree(prtd);
@@ -378,6 +398,12 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close);
int snd_dmaengine_pcm_close_release_chan(struct snd_pcm_substream *substream)
{
struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
+ struct dma_tx_state state;
+ enum dma_status status;
+
+ status = dmaengine_tx_status(prtd->dma_chan, prtd->cookie, &state);
+ if (status == DMA_PAUSED)
+ dmaengine_terminate_async(prtd->dma_chan);
dmaengine_synchronize(prtd->dma_chan);
dma_release_channel(prtd->dma_chan);
@@ -470,4 +496,5 @@ int snd_dmaengine_pcm_refine_runtime_hwparams(
}
EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_refine_runtime_hwparams);
+MODULE_DESCRIPTION("PCM dmaengine helper APIs");
MODULE_LICENSE("GPL");
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 0b76e76823..c152ccf322 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1775,6 +1775,8 @@ static int snd_pcm_pre_resume(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{
struct snd_pcm_runtime *runtime = substream->runtime;
+ if (runtime->state != SNDRV_PCM_STATE_SUSPENDED)
+ return -EBADFD;
if (!(runtime->info & SNDRV_PCM_INFO_RESUME))
return -ENOSYS;
runtime->trigger_master = substream;
@@ -2416,7 +2418,7 @@ static int snd_pcm_hw_rule_sample_bits(struct snd_pcm_hw_params *params,
static const unsigned int rates[] = {
5512, 8000, 11025, 16000, 22050, 32000, 44100,
- 48000, 64000, 88200, 96000, 176400, 192000, 352800, 384000
+ 48000, 64000, 88200, 96000, 176400, 192000, 352800, 384000, 705600, 768000
};
const struct snd_pcm_hw_constraint_list snd_pcm_known_rates = {
diff --git a/sound/core/pcm_trace.h b/sound/core/pcm_trace.h
index 350b40b906..adb9b1f3bb 100644
--- a/sound/core/pcm_trace.h
+++ b/sound/core/pcm_trace.h
@@ -95,7 +95,7 @@ TRACE_EVENT(hw_ptr_error,
__entry->device = (substream)->pcm->device;
__entry->number = (substream)->number;
__entry->stream = (substream)->stream;
- __assign_str(reason, why);
+ __assign_str(reason);
),
TP_printk("pcmC%dD%d%s/sub%d: ERROR: %s",
__entry->card, __entry->device,
diff --git a/sound/core/seq/Makefile b/sound/core/seq/Makefile
index 990eec7c83..0904aa48d8 100644
--- a/sound/core/seq/Makefile
+++ b/sound/core/seq/Makefile
@@ -4,17 +4,17 @@
# Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
#
-snd-seq-objs := seq.o seq_lock.o seq_clientmgr.o seq_memory.o seq_queue.o \
+snd-seq-y := seq.o seq_lock.o seq_clientmgr.o seq_memory.o seq_queue.o \
seq_fifo.o seq_prioq.o seq_timer.o \
seq_system.o seq_ports.o
snd-seq-$(CONFIG_SND_PROC_FS) += seq_info.o
snd-seq-$(CONFIG_SND_SEQ_UMP) += seq_ump_convert.o
-snd-seq-midi-objs := seq_midi.o
-snd-seq-midi-emul-objs := seq_midi_emul.o
-snd-seq-midi-event-objs := seq_midi_event.o
-snd-seq-dummy-objs := seq_dummy.o
-snd-seq-virmidi-objs := seq_virmidi.o
-snd-seq-ump-client-objs := seq_ump_client.o
+snd-seq-midi-y := seq_midi.o
+snd-seq-midi-emul-y := seq_midi_emul.o
+snd-seq-midi-event-y := seq_midi_event.o
+snd-seq-dummy-y := seq_dummy.o
+snd-seq-virmidi-y := seq_virmidi.o
+snd-seq-ump-client-y := seq_ump_client.o
obj-$(CONFIG_SND_SEQUENCER) += snd-seq.o
obj-$(CONFIG_SND_SEQUENCER_OSS) += oss/
diff --git a/sound/core/seq/oss/Makefile b/sound/core/seq/oss/Makefile
index f1a6087854..4e47418342 100644
--- a/sound/core/seq/oss/Makefile
+++ b/sound/core/seq/oss/Makefile
@@ -4,7 +4,7 @@
# Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
#
-snd-seq-oss-objs := seq_oss.o seq_oss_init.o seq_oss_timer.o seq_oss_ioctl.o \
+snd-seq-oss-y := seq_oss.o seq_oss_init.o seq_oss_timer.o seq_oss_ioctl.o \
seq_oss_event.o seq_oss_rw.o seq_oss_synth.o \
seq_oss_midi.o seq_oss_readq.o seq_oss_writeq.o
diff --git a/sound/core/seq/seq_dummy.c b/sound/core/seq/seq_dummy.c
index 9308194b2d..783fc72c2e 100644
--- a/sound/core/seq/seq_dummy.c
+++ b/sound/core/seq/seq_dummy.c
@@ -58,6 +58,12 @@ MODULE_PARM_DESC(ports, "number of ports to be created");
module_param(duplex, bool, 0444);
MODULE_PARM_DESC(duplex, "create DUPLEX ports");
+#if IS_ENABLED(CONFIG_SND_SEQ_UMP)
+static int ump;
+module_param(ump, int, 0444);
+MODULE_PARM_DESC(ump, "UMP conversion (0: no convert, 1: MIDI 1.0, 2: MIDI 2.0)");
+#endif
+
struct snd_seq_dummy_port {
int client;
int port;
@@ -152,7 +158,9 @@ static int __init
register_client(void)
{
struct snd_seq_dummy_port *rec1, *rec2;
+#if IS_ENABLED(CONFIG_SND_SEQ_UMP)
struct snd_seq_client *client;
+#endif
int i;
if (ports < 1) {
@@ -166,12 +174,24 @@ register_client(void)
if (my_client < 0)
return my_client;
- /* don't convert events but just pass-through */
+#if IS_ENABLED(CONFIG_SND_SEQ_UMP)
client = snd_seq_kernel_client_get(my_client);
if (!client)
return -EINVAL;
- client->filter = SNDRV_SEQ_FILTER_NO_CONVERT;
+ switch (ump) {
+ case 1:
+ client->midi_version = SNDRV_SEQ_CLIENT_UMP_MIDI_1_0;
+ break;
+ case 2:
+ client->midi_version = SNDRV_SEQ_CLIENT_UMP_MIDI_2_0;
+ break;
+ default:
+ /* don't convert events but just pass-through */
+ client->filter = SNDRV_SEQ_FILTER_NO_CONVERT;
+ break;
+ }
snd_seq_kernel_client_put(client);
+#endif
/* create ports */
for (i = 0; i < ports; i++) {
diff --git a/sound/core/seq/seq_ump_client.c b/sound/core/seq/seq_ump_client.c
index c627d72f7f..9cdfbeae3e 100644
--- a/sound/core/seq/seq_ump_client.c
+++ b/sound/core/seq/seq_ump_client.c
@@ -28,6 +28,7 @@ struct seq_ump_group {
int group; /* group index (0-based) */
unsigned int dir_bits; /* directions */
bool active; /* activeness */
+ bool valid; /* valid group (referred by blocks) */
char name[64]; /* seq port name */
};
@@ -210,6 +211,13 @@ static void fill_port_info(struct snd_seq_port_info *port,
sprintf(port->name, "Group %d", group->group + 1);
}
+/* skip non-existing group for static blocks */
+static bool skip_group(struct seq_ump_client *client, struct seq_ump_group *group)
+{
+ return !group->valid &&
+ (client->ump->info.flags & SNDRV_UMP_EP_INFO_STATIC_BLOCKS);
+}
+
/* create a new sequencer port per UMP group */
static int seq_ump_group_init(struct seq_ump_client *client, int group_index)
{
@@ -217,6 +225,9 @@ static int seq_ump_group_init(struct seq_ump_client *client, int group_index)
struct snd_seq_port_info *port __free(kfree) = NULL;
struct snd_seq_port_callback pcallbacks;
+ if (skip_group(client, group))
+ return 0;
+
port = kzalloc(sizeof(*port), GFP_KERNEL);
if (!port)
return -ENOMEM;
@@ -250,6 +261,9 @@ static void update_port_infos(struct seq_ump_client *client)
return;
for (i = 0; i < SNDRV_UMP_MAX_GROUPS; i++) {
+ if (skip_group(client, &client->groups[i]))
+ continue;
+
old->addr.client = client->seq_client;
old->addr.port = i;
err = snd_seq_kernel_client_ctl(client->seq_client,
@@ -284,6 +298,7 @@ static void update_group_attrs(struct seq_ump_client *client)
group->dir_bits = 0;
group->active = 0;
group->group = i;
+ group->valid = false;
}
list_for_each_entry(fb, &client->ump->block_list, list) {
@@ -291,6 +306,7 @@ static void update_group_attrs(struct seq_ump_client *client)
break;
group = &client->groups[fb->info.first_group];
for (i = 0; i < fb->info.num_groups; i++, group++) {
+ group->valid = true;
if (fb->info.active)
group->active = 1;
switch (fb->info.direction) {
diff --git a/sound/core/seq/seq_ump_convert.c b/sound/core/seq/seq_ump_convert.c
index d81f776a4c..d9dacfbe4a 100644
--- a/sound/core/seq/seq_ump_convert.c
+++ b/sound/core/seq/seq_ump_convert.c
@@ -791,7 +791,8 @@ static int paf_ev_to_ump_midi2(const struct snd_seq_event *event,
/* set up the MIDI2 RPN/NRPN packet data from the parsed info */
static void fill_rpn(struct snd_seq_ump_midi2_bank *cc,
- union snd_ump_midi2_msg *data)
+ union snd_ump_midi2_msg *data,
+ unsigned char channel)
{
if (cc->rpn_set) {
data->rpn.status = UMP_MSG_STATUS_RPN;
@@ -808,6 +809,7 @@ static void fill_rpn(struct snd_seq_ump_midi2_bank *cc,
}
data->rpn.data = upscale_14_to_32bit((cc->cc_data_msb << 7) |
cc->cc_data_lsb);
+ data->rpn.channel = channel;
cc->cc_data_msb = cc->cc_data_lsb = 0;
}
@@ -855,7 +857,7 @@ static int cc_ev_to_ump_midi2(const struct snd_seq_event *event,
cc->cc_data_lsb = val;
if (!(cc->rpn_set || cc->nrpn_set))
return 0; // skip
- fill_rpn(cc, data);
+ fill_rpn(cc, data, channel);
return 1;
}
@@ -957,7 +959,7 @@ static int ctrl14_ev_to_ump_midi2(const struct snd_seq_event *event,
cc->cc_data_lsb = lsb;
if (!(cc->rpn_set || cc->nrpn_set))
return 0; // skip
- fill_rpn(cc, data);
+ fill_rpn(cc, data, channel);
return 1;
}
@@ -1018,7 +1020,7 @@ static int system_2p_ev_to_ump_midi2(const struct snd_seq_event *event,
union snd_ump_midi2_msg *data,
unsigned char status)
{
- return system_1p_ev_to_ump_midi1(event, dest_port,
+ return system_2p_ev_to_ump_midi1(event, dest_port,
(union snd_ump_midi1_msg *)data,
status);
}
@@ -1190,44 +1192,53 @@ static int cvt_sysex_to_ump(struct snd_seq_client *dest,
{
struct snd_seq_ump_event ev_cvt;
unsigned char status;
- u8 buf[6], *xbuf;
+ u8 buf[8], *xbuf;
int offset = 0;
int len, err;
+ bool finished = false;
if (!snd_seq_ev_is_variable(event))
return 0;
setup_ump_event(&ev_cvt, event);
- for (;;) {
+ while (!finished) {
len = snd_seq_expand_var_event_at(event, sizeof(buf), buf, offset);
if (len <= 0)
break;
- if (WARN_ON(len > 6))
+ if (WARN_ON(len > sizeof(buf)))
break;
- offset += len;
+
xbuf = buf;
+ status = UMP_SYSEX_STATUS_CONTINUE;
+ /* truncate the sysex start-marker */
if (*xbuf == UMP_MIDI1_MSG_SYSEX_START) {
status = UMP_SYSEX_STATUS_START;
- xbuf++;
len--;
- if (len > 0 && xbuf[len - 1] == UMP_MIDI1_MSG_SYSEX_END) {
+ offset++;
+ xbuf++;
+ }
+
+ /* if the last of this packet or the 1st byte of the next packet
+ * is the end-marker, finish the transfer with this packet
+ */
+ if (len > 0 && len < 8 &&
+ xbuf[len - 1] == UMP_MIDI1_MSG_SYSEX_END) {
+ if (status == UMP_SYSEX_STATUS_START)
status = UMP_SYSEX_STATUS_SINGLE;
- len--;
- }
- } else {
- if (xbuf[len - 1] == UMP_MIDI1_MSG_SYSEX_END) {
+ else
status = UMP_SYSEX_STATUS_END;
- len--;
- } else {
- status = UMP_SYSEX_STATUS_CONTINUE;
- }
+ len--;
+ finished = true;
}
+
+ len = min(len, 6);
fill_sysex7_ump(dest_port, ev_cvt.ump, status, xbuf, len);
err = __snd_seq_deliver_single_event(dest, dest_port,
(struct snd_seq_event *)&ev_cvt,
atomic, hop);
if (err < 0)
return err;
+ offset += len;
}
return 0;
}
diff --git a/sound/core/sound_kunit.c b/sound/core/sound_kunit.c
index eb90f62228..bfed1a25fc 100644
--- a/sound/core/sound_kunit.c
+++ b/sound/core/sound_kunit.c
@@ -45,7 +45,7 @@ struct avail_test_data {
snd_pcm_uframes_t expected_avail;
};
-static struct snd_format_test_data valid_fmt[] = {
+static const struct snd_format_test_data valid_fmt[] = {
DEFINE_FORMAT(S8, 8, 8, -1, 1, SILENCE()),
DEFINE_FORMAT(U8, 8, 8, -1, 0, SILENCE(0x80)),
DEFINE_FORMAT(S16_LE, 16, 16, 1, 1, SILENCE()),
@@ -154,7 +154,7 @@ static void test_format_endianness(struct kunit *test)
KUNIT_EXPECT_EQ(test, snd_pcm_format_big_endian(WRONG_FORMAT_2), -EINVAL);
}
-static void _test_fill_silence(struct kunit *test, struct snd_format_test_data *data,
+static void _test_fill_silence(struct kunit *test, const struct snd_format_test_data *data,
u8 *buffer, size_t samples_count)
{
size_t sample_bytes = data->physical_bits >> 3;
@@ -167,7 +167,7 @@ static void _test_fill_silence(struct kunit *test, struct snd_format_test_data *
static void test_format_fill_silence(struct kunit *test)
{
- u32 buf_samples[] = { 10, 20, 32, 64, 129, SILENCE_BUFFER_MAX_FRAMES };
+ static const u32 buf_samples[] = { 10, 20, 32, 64, 129, SILENCE_BUFFER_MAX_FRAMES };
u8 *buffer;
u32 i, j;
@@ -191,7 +191,7 @@ static snd_pcm_uframes_t calculate_boundary(snd_pcm_uframes_t buffer_size)
return boundary;
}
-static struct avail_test_data p_avail_data[] = {
+static const struct avail_test_data p_avail_data[] = {
/* buf_size + hw_ptr < appl_ptr => avail = buf_size + hw_ptr - appl_ptr + boundary */
{ 128, 1000, 1129, 1073741824UL - 1 },
/*
@@ -220,7 +220,7 @@ static void test_playback_avail(struct kunit *test)
}
}
-static struct avail_test_data c_avail_data[] = {
+static const struct avail_test_data c_avail_data[] = {
/* hw_ptr - appl_ptr < 0 => avail = hw_ptr - appl_ptr + boundary */
{ 128, 1000, 1001, 1073741824UL - 1 },
/* standard case: avail = hw_ptr - appl_ptr */
@@ -308,5 +308,6 @@ static struct kunit_suite sound_utils_suite = {
};
kunit_test_suite(sound_utils_suite);
+MODULE_DESCRIPTION("Sound core KUnit test");
MODULE_AUTHOR("Ivan Orlov");
MODULE_LICENSE("GPL");
diff --git a/sound/core/ump.c b/sound/core/ump.c
index 117c7ecc48..0f0d7e895c 100644
--- a/sound/core/ump.c
+++ b/sound/core/ump.c
@@ -733,6 +733,12 @@ static void fill_fb_info(struct snd_ump_endpoint *ump,
info->block_id, info->direction, info->active,
info->first_group, info->num_groups, info->midi_ci_version,
info->sysex8_streams, info->flags);
+
+ if ((info->flags & SNDRV_UMP_BLOCK_IS_MIDI1) && info->num_groups != 1) {
+ info->num_groups = 1;
+ ump_dbg(ump, "FB %d: corrected groups to 1 for MIDI1\n",
+ info->block_id);
+ }
}
/* check whether the FB info gets updated by the current message */
@@ -806,6 +812,13 @@ static int ump_handle_fb_name_msg(struct snd_ump_endpoint *ump,
if (!fb)
return -ENODEV;
+ if (ump->parsed &&
+ (ump->info.flags & SNDRV_UMP_EP_INFO_STATIC_BLOCKS)) {
+ ump_dbg(ump, "Skipping static FB name update (blk#%d)\n",
+ fb->info.block_id);
+ return 0;
+ }
+
ret = ump_append_string(ump, fb->info.name, sizeof(fb->info.name),
buf->raw, 3);
/* notify the FB name update to sequencer, too */
@@ -967,6 +980,14 @@ int snd_ump_parse_endpoint(struct snd_ump_endpoint *ump)
if (err < 0)
ump_dbg(ump, "Unable to get UMP EP stream config\n");
+ /* If no protocol is set by some reason, assume the valid one */
+ if (!(ump->info.protocol & SNDRV_UMP_EP_INFO_PROTO_MIDI_MASK)) {
+ if (ump->info.protocol_caps & SNDRV_UMP_EP_INFO_PROTO_MIDI2)
+ ump->info.protocol |= SNDRV_UMP_EP_INFO_PROTO_MIDI2;
+ else if (ump->info.protocol_caps & SNDRV_UMP_EP_INFO_PROTO_MIDI1)
+ ump->info.protocol |= SNDRV_UMP_EP_INFO_PROTO_MIDI1;
+ }
+
/* Query and create blocks from Function Blocks */
for (blk = 0; blk < ump->info.num_blocks; blk++) {
err = create_block_from_fb_info(ump, blk);