mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	module-alsa-card: handle udev PULSE_MODARGS
Allow adding module arguments using udev PULSE_MODARGS environment variable and fail module loading if there is a problem with PULSE_MODARGS This helps setting e.g. 'tsched=0' for specific devices without a need to create full load module entry in default.pa. Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/436>
This commit is contained in:
		
							parent
							
								
									19e34d8d5b
								
							
						
					
					
						commit
						d15b31d751
					
				
					 3 changed files with 77 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -104,6 +104,8 @@ static const char* const valid_modargs[] = {
 | 
			
		|||
 | 
			
		||||
#define DEFAULT_DEVICE_ID "0"
 | 
			
		||||
 | 
			
		||||
#define PULSE_MODARGS "PULSE_MODARGS"
 | 
			
		||||
 | 
			
		||||
struct userdata {
 | 
			
		||||
    pa_core *core;
 | 
			
		||||
    pa_module *module;
 | 
			
		||||
| 
						 | 
				
			
			@ -820,6 +822,7 @@ int pa__init(pa_module *m) {
 | 
			
		|||
    const char *description;
 | 
			
		||||
    const char *profile_str = NULL;
 | 
			
		||||
    char *fn = NULL;
 | 
			
		||||
    char *udev_args = NULL;
 | 
			
		||||
    bool namereg_fail = false;
 | 
			
		||||
    int err = -PA_MODULE_ERR_UNSPECIFIED, rval;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -849,6 +852,47 @@ int pa__init(pa_module *m) {
 | 
			
		|||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_UDEV
 | 
			
		||||
    udev_args = pa_udev_get_property(u->alsa_card_index, PULSE_MODARGS);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (udev_args) {
 | 
			
		||||
        bool udev_modargs_success = true;
 | 
			
		||||
        pa_modargs *temp_ma = pa_modargs_new(udev_args, valid_modargs);
 | 
			
		||||
 | 
			
		||||
        if (temp_ma) {
 | 
			
		||||
            /* do not try to replace device_id */
 | 
			
		||||
 | 
			
		||||
            if (pa_modargs_remove_key(temp_ma, "device_id") == 0) {
 | 
			
		||||
                pa_log_warn("Unexpected 'device_id' module argument override ignored from udev " PULSE_MODARGS "='%s'", udev_args);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* Implement modargs override by copying original module arguments
 | 
			
		||||
             * over udev entry arguments ignoring duplicates. */
 | 
			
		||||
 | 
			
		||||
            if (pa_modargs_merge_missing(temp_ma, u->modargs, valid_modargs) == 0) {
 | 
			
		||||
                /* swap module arguments */
 | 
			
		||||
                pa_modargs *old_ma = u->modargs;
 | 
			
		||||
                u->modargs = temp_ma;
 | 
			
		||||
                temp_ma = old_ma;
 | 
			
		||||
 | 
			
		||||
                pa_log_info("Applied module arguments override from udev " PULSE_MODARGS "='%s'", udev_args);
 | 
			
		||||
            } else {
 | 
			
		||||
                pa_log("Failed to apply module arguments override from udev " PULSE_MODARGS "='%s'", udev_args);
 | 
			
		||||
                udev_modargs_success = false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            pa_modargs_free(temp_ma);
 | 
			
		||||
        } else {
 | 
			
		||||
            pa_log("Failed to parse module arguments from udev " PULSE_MODARGS "='%s'", udev_args);
 | 
			
		||||
            udev_modargs_success = false;
 | 
			
		||||
        }
 | 
			
		||||
        pa_xfree(udev_args);
 | 
			
		||||
 | 
			
		||||
        if (!udev_modargs_success)
 | 
			
		||||
            goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (pa_modargs_get_value_boolean(u->modargs, "ignore_dB", &ignore_dB) < 0) {
 | 
			
		||||
        pa_log("Failed to parse ignore_dB argument.");
 | 
			
		||||
        goto fail;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -272,6 +272,15 @@ int pa_modargs_append(pa_modargs *ma, const char *args, const char* const* valid
 | 
			
		|||
    return parse(ma, args, valid_keys, true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int pa_modargs_remove_key(pa_modargs *ma, const char *key) {
 | 
			
		||||
    if (pa_hashmap_remove_and_free(ma->unescaped, key) == 0) {
 | 
			
		||||
        pa_hashmap_remove_and_free(ma->raw, key);
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void pa_modargs_free(pa_modargs*ma) {
 | 
			
		||||
    pa_assert(ma);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -544,3 +553,20 @@ const char *pa_modargs_iterate(pa_modargs *ma, void **state) {
 | 
			
		|||
 | 
			
		||||
    return e->key;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int pa_modargs_merge_missing(pa_modargs *dst, pa_modargs *src, const char* const valid_keys[]) {
 | 
			
		||||
    void *state;
 | 
			
		||||
    const char *key, *value;
 | 
			
		||||
    int ret = 0;
 | 
			
		||||
 | 
			
		||||
    for (state = NULL, key = pa_modargs_iterate(src, &state); key; key = pa_modargs_iterate(src, &state)) {
 | 
			
		||||
        value = pa_modargs_get_value(src, key, NULL);
 | 
			
		||||
        if (value && add_key_value(dst, pa_xstrdup(key), pa_xstrdup(value), valid_keys, true) < 0) {
 | 
			
		||||
            pa_log_warn("Failed to add module argument '%s=%s'", key, value);
 | 
			
		||||
            ret = -1;
 | 
			
		||||
            /* continue to gather all errors */
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -95,4 +95,11 @@ int pa_modargs_get_proplist(pa_modargs *ma, const char *name, pa_proplist *p, pa
 | 
			
		|||
 * have any particular order. */
 | 
			
		||||
const char *pa_modargs_iterate(pa_modargs *ma, void **state);
 | 
			
		||||
 | 
			
		||||
/* Remove entry by key. Returns 0 if successful, -1 otherwise */
 | 
			
		||||
int pa_modargs_remove_key(pa_modargs *ma, const char *key);
 | 
			
		||||
 | 
			
		||||
/* Add all key/value pairs from src that are is not already present in dst, to dst.
 | 
			
		||||
 * Returns 0 if there were no errors, -1 otherwise. */
 | 
			
		||||
int pa_modargs_merge_missing(pa_modargs *dst, pa_modargs *src, const char* const valid_keys[]);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue