diff options
-rw-r--r-- | src/modules/alsa/alsa-ucm.c | 20 | ||||
-rw-r--r-- | src/modules/alsa/alsa-util.h | 7 | ||||
-rw-r--r-- | src/modules/alsa/module-alsa-card.c | 10 | ||||
-rw-r--r-- | src/modules/module-udev-detect.c | 14 | ||||
-rw-r--r-- | src/pulsecore/module.c | 8 | ||||
-rw-r--r-- | src/pulsecore/module.h | 5 |
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; |