summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/modules/alsa/alsa-ucm.c20
-rw-r--r--src/modules/alsa/alsa-util.h7
-rw-r--r--src/modules/alsa/module-alsa-card.c10
-rw-r--r--src/modules/module-udev-detect.c14
-rw-r--r--src/pulsecore/module.c8
-rw-r--r--src/pulsecore/module.h5
6 files changed, 54 insertions, 10 deletions
diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c
index b63ae364f..18925b792 100644
--- a/src/modules/alsa/alsa-ucm.c
+++ b/src/modules/alsa/alsa-ucm.c
@@ -757,13 +757,11 @@ static void append_lost_relationship(pa_alsa_ucm_device *dev) {
int pa_alsa_ucm_query_profiles(pa_alsa_ucm_config *ucm, int card_index) {
char *card_name;
- const char **verb_list;
+ const char **verb_list, *value;
int num_verbs, i, err = 0;
/* support multiple card instances, address card directly by index */
card_name = pa_sprintf_malloc("hw:%i", card_index);
- if (card_name == NULL)
- return -ENOMEM;
err = snd_use_case_mgr_open(&ucm->ucm_mgr, card_name);
if (err < 0) {
/* fallback longname: is UCM available for this card ? */
@@ -771,22 +769,36 @@ int pa_alsa_ucm_query_profiles(pa_alsa_ucm_config *ucm, int card_index) {
err = snd_card_get_name(card_index, &card_name);
if (err < 0) {
pa_log("Card can't get card_name from card_index %d", card_index);
+ err = -PA_ALSA_ERR_UNSPECIFIED;
goto name_fail;
}
err = snd_use_case_mgr_open(&ucm->ucm_mgr, card_name);
if (err < 0) {
pa_log_info("UCM not available for card %s", card_name);
+ err = -PA_ALSA_ERR_UCM_OPEN;
goto ucm_mgr_fail;
}
}
+ err = snd_use_case_get(ucm->ucm_mgr, "=Linked", &value);
+ if (err >= 0) {
+ if (strcasecmp(value, "true") == 0 || strcasecmp(value, "1") == 0) {
+ free((void *)value);
+ pa_log_info("Empty (linked) UCM for card %s", card_name);
+ err = -PA_ALSA_ERR_UCM_LINKED;
+ goto ucm_verb_fail;
+ }
+ free((void *)value);
+ }
+
pa_log_info("UCM available for card %s", card_name);
/* get a list of all UCM verbs (profiles) for this card */
num_verbs = snd_use_case_verb_list(ucm->ucm_mgr, &verb_list);
if (num_verbs < 0) {
pa_log("UCM verb list not found for %s", card_name);
+ err = -PA_ALSA_ERR_UNSPECIFIED;
goto ucm_verb_fail;
}
@@ -806,7 +818,7 @@ int pa_alsa_ucm_query_profiles(pa_alsa_ucm_config *ucm, int card_index) {
if (!ucm->verbs) {
pa_log("No UCM verb is valid for %s", card_name);
- err = -1;
+ err = -PA_ALSA_ERR_UCM_NO_VERB;
}
snd_use_case_free_list(verb_list, num_verbs);
diff --git a/src/modules/alsa/alsa-util.h b/src/modules/alsa/alsa-util.h
index 0d3d5af13..cb8be22fb 100644
--- a/src/modules/alsa/alsa-util.h
+++ b/src/modules/alsa/alsa-util.h
@@ -33,6 +33,13 @@
#include "alsa-mixer.h"
+enum {
+ PA_ALSA_ERR_UNSPECIFIED = 1,
+ PA_ALSA_ERR_UCM_OPEN = 1000,
+ PA_ALSA_ERR_UCM_NO_VERB = 1001,
+ PA_ALSA_ERR_UCM_LINKED = 1002
+};
+
int pa_alsa_set_hw_params(
snd_pcm_t *pcm_handle,
pa_sample_spec *ss, /* modified at return */
diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c
index d312fb5d9..267d30c3b 100644
--- a/src/modules/alsa/module-alsa-card.c
+++ b/src/modules/alsa/module-alsa-card.c
@@ -785,6 +785,7 @@ int pa__init(pa_module *m) {
const char *profile_str = NULL;
char *fn = NULL;
bool namereg_fail = false;
+ int err = -PA_MODULE_ERR_UNSPECIFIED, rval;
pa_alsa_refcnt_inc();
@@ -841,7 +842,12 @@ int pa__init(pa_module *m) {
snd_config_update_free_global();
- if (u->use_ucm && !pa_alsa_ucm_query_profiles(&u->ucm, u->alsa_card_index)) {
+ rval = u->use_ucm ? pa_alsa_ucm_query_profiles(&u->ucm, u->alsa_card_index) : -1;
+ if (rval == -PA_ALSA_ERR_UCM_LINKED) {
+ err = -PA_MODULE_ERR_SKIP;
+ goto fail;
+ }
+ if (rval == 0) {
pa_log_info("Found UCM profiles");
u->profile_set = pa_alsa_ucm_add_profile_set(&u->ucm, &u->core->default_channel_map);
@@ -1009,7 +1015,7 @@ fail:
pa__done(m);
- return -1;
+ return err;
}
int pa__get_n_used(pa_module *m) {
diff --git a/src/modules/module-udev-detect.c b/src/modules/module-udev-detect.c
index d119f96ae..7a107c44d 100644
--- a/src/modules/module-udev-detect.c
+++ b/src/modules/module-udev-detect.c
@@ -52,6 +52,7 @@ PA_MODULE_USAGE(
struct device {
char *path;
bool need_verify;
+ bool ignore;
char *card_name;
char *args;
uint32_t module;
@@ -286,6 +287,9 @@ static void verify_access(struct userdata *u, struct device *d) {
pa_assert(u);
pa_assert(d);
+ if (d->ignore)
+ return;
+
cd = pa_sprintf_malloc("/dev/snd/controlC%s", path_get_card_id(d->path));
accessible = access(cd, R_OK|W_OK) >= 0;
pa_log_debug("%s is accessible: %s", cd, pa_yes_no(accessible));
@@ -332,14 +336,20 @@ static void verify_access(struct userdata *u, struct device *d) {
* failure or a "fatal" failure. */
if (pa_ratelimit_test(&d->ratelimit, PA_LOG_DEBUG)) {
+ int err;
+
pa_log_debug("Loading module-alsa-card with arguments '%s'", d->args);
- pa_module_load(&m, u->core, "module-alsa-card", d->args);
+ err = pa_module_load(&m, u->core, "module-alsa-card", d->args);
if (m) {
d->module = m->index;
pa_log_info("Card %s (%s) module loaded.", d->path, d->card_name);
- } else
+ } else if (err == -PA_ERR_NOENTITY) {
+ pa_log_info("Card %s (%s) module skipped.", d->path, d->card_name);
+ d->ignore = true;
+ } else {
pa_log_info("Card %s (%s) failed to load module.", d->path, d->card_name);
+ }
} else
pa_log_warn("Tried to configure %s (%s) more often than %u times in %llus",
d->path,
diff --git a/src/pulsecore/module.c b/src/pulsecore/module.c
index 70b816072..15a54b6ec 100644
--- a/src/pulsecore/module.c
+++ b/src/pulsecore/module.c
@@ -116,7 +116,7 @@ int pa_module_load(pa_module** module, pa_core *c, const char *name, const char
bool (*load_once)(void);
const char* (*get_deprecated)(void);
pa_modinfo *mi;
- int errcode;
+ int errcode, rval;
pa_assert(module);
pa_assert(c);
@@ -188,7 +188,11 @@ int pa_module_load(pa_module** module, pa_core *c, const char *name, const char
pa_assert_se(pa_idxset_put(c->modules, m, &m->index) >= 0);
pa_assert(m->index != PA_IDXSET_INVALID);
- if (m->init(m) < 0) {
+ if ((rval = m->init(m)) < 0) {
+ if (rval == -PA_MODULE_ERR_SKIP) {
+ errcode = -PA_ERR_NOENTITY;
+ goto fail;
+ }
pa_log_error("Failed to load module \"%s\" (argument: \"%s\"): initialization failed.", name, argument ? argument : "");
errcode = -PA_ERR_IO;
goto fail;
diff --git a/src/pulsecore/module.h b/src/pulsecore/module.h
index b5a7fad77..f918ea605 100644
--- a/src/pulsecore/module.h
+++ b/src/pulsecore/module.h
@@ -30,6 +30,11 @@ typedef struct pa_module pa_module;
#include <pulsecore/core.h>
+enum {
+ PA_MODULE_ERR_UNSPECIFIED = 1,
+ PA_MODULE_ERR_SKIP = 2
+};
+
struct pa_module {
pa_core *core;
char *name, *argument;