[pulseaudio-discuss] [PATCH 2/2] alsa: load jack detection module

Tanu Kaskinen tanuk at iki.fi
Wed May 25 12:51:16 PDT 2011


On Thu, 2011-05-19 at 11:44 -0500, Jorge Eduardo Candelaria wrote:
> From: Margarita Olaya Cabrera <magi at slimlogic.co.uk>
> 
> This patch adds support for udev detection of sound card jack event devices.
> 
> When a new card is detected, the code now also checks for the presence of any
> associated input device via udev, and report the device to module-alsa-card
> via its jack_id parameter.
> 
> Jack support development was kindly sponsored by Wolfson Microelectronics PLC
> 
> Signed-off-by: Margarita Olaya Cabrera <magi at slimlogic.co.uk>
> Signed-off-by: Jorge Eduardo Candelaria <jedu at slimlogic.co.uk>
> ---
> src/modules/module-udev-detect.c |   68 ++++++++++++++++++++++++++++++++++---
> 1 files changed, 62 insertions(+), 6 deletions(-)
> 
> diff --git a/src/modules/module-udev-detect.c b/src/modules/module-udev-detect.c
> index 63ad195..4321b32 100644
> --- a/src/modules/module-udev-detect.c
> +++ b/src/modules/module-udev-detect.c
> @@ -71,6 +71,8 @@ struct userdata {
> 
>     int inotify_fd;
>     pa_io_event *inotify_io;
> +
> +    char *card_name;

This doesn't really seem to be used for anything.

> };
> 
> static const char* const valid_modargs[] = {
> @@ -163,6 +165,21 @@ static pa_bool_t pcm_is_modem(const char *card_idx, const char *pcm) {
>     return is_modem;
> }
> 
> +static pa_bool_t input_node_belongs_to_device(
> +        struct device *d,
> +        const char *node) {
> +
> +    char *cd;
> +    pa_bool_t b;
> +
> +    cd = pa_sprintf_malloc("/sys%s", d->path);
> +
> +    b = pa_startswith(node, cd);
> +    pa_xfree(cd);
> +
> +    return b;
> +}
> +
> static pa_bool_t is_card_busy(const char *id) {
>     char *card_path = NULL, *pcm_path = NULL, *sub_status = NULL;
>     DIR *card_dir = NULL, *pcm_dir = NULL;
> @@ -352,11 +369,26 @@ static void verify_access(struct userdata *u, struct device *d) {
>     }
> }
> 
> +static const char *jack_get_input_id(const char *path) {
> +    int i;
> +
> +    for( i = 0; i < strlen(path); i++) {

strlen() is called in each iteration - it would be better to save its
return value outside the loop.

> +        if (pa_startswith(path + i, "/input"))
> +            return path + i + 6;
> +    }
> +
> +    return NULL;
> +}
> +
> static void card_changed(struct userdata *u, struct udev_device *dev) {
>     struct device *d;
> +    struct udev_enumerate *enumerate;
> +    struct udev_list_entry *item, *first;
>     const char *path;
>     const char *t;
>     char *n;
> +    char *jack_path;
> +    char *jack_input;
> 
>     pa_assert(u);
>     pa_assert(dev);
> @@ -383,6 +415,28 @@ static void card_changed(struct userdata *u, struct udev_device *dev) {
> 
>     n = pa_namereg_make_valid_name(t);
>     d->card_name = pa_sprintf_malloc("alsa_card.%s", n);
> +
> +    if (!(enumerate = udev_enumerate_new(u->udev)))
> +        pa_log("Failed to initialize udev enumerator");
> +    else {
> +        if (!udev_enumerate_add_match_subsystem(enumerate, "input"))
> +            pa_log_debug("Failed to match to subsystem input");
> +
> +        if (udev_enumerate_scan_devices(enumerate))
> +            pa_log_debug("Failed to scan for devices");

Should these two errors abort the enumeration, or is a debug message
really good enough error handling here?

> +
> +        first = udev_enumerate_get_list_entry(enumerate);
> +        udev_list_entry_foreach(item, first) {
> +            jack_path = udev_list_entry_get_name(item);
> +            if (input_node_belongs_to_device(d, jack_path)) {
> +                jack_input = pa_xstrdup(jack_get_input_id(jack_path));
> +                pa_log_debug("jack is %s\n", jack_input);

jack_input can, at least in theory, be null (or if it can't, you should
add an assertion to jack_get_input_id() instead of returning NULL). I'm
not sure what happens if you pass a null pointer as a string to the log
functions - does it crash, or does it work? There's the pa_strnull()
function that returns the string "(null)" if the argument is null, and
the function is being used in similar contexts as this one. Either you
should call pa_strnull() here, or the other uses of pa_strnull() are
redundant.

> +                break;
> +            }
> +        }
> +        udev_enumerate_unref(enumerate);
> +    }
> +
>     d->args = pa_sprintf_malloc("device_id=\"%s\" "
>                                 "name=\"%s\" "
>                                 "card_name=\"%s\" "
> @@ -390,15 +444,19 @@ static void card_changed(struct userdata *u, struct udev_device *dev) {
>                                 "tsched=%s "
>                                 "ignore_dB=%s "
>                                 "sync_volume=%s "
> +                                "jack_id=\"%s\" "
>                                 "card_properties=\"module-udev-detect.discovered=1\"",
>                                 path_get_card_id(path),
>                                 n,
>                                 d->card_name,
>                                 pa_yes_no(u->use_tsched),
>                                 pa_yes_no(u->ignore_dB),
> -                                pa_yes_no(u->sync_volume));
> -    pa_xfree(n);
> +                                pa_yes_no(u->sync_volume),
> +                                jack_input);

The comment about pa_strnull() applies here too.

> 
> +    pa_xfree(n);
> +    pa_xfree(jack_input);
> +    u->card_name = d->card_name;
>     pa_hashmap_put(u->devices, d->path, d);
> 
>     verify_access(u, d);
> @@ -481,13 +539,11 @@ static void monitor_cb(
>         goto fail;
>     }
> 
> -    if (!path_get_card_id(udev_device_get_devpath(dev))) {
> +    if (path_get_card_id(udev_device_get_devpath(dev))) {
> +        process_device(u, dev);
>         udev_device_unref(dev);
> -        return;
>     }
> 
> -    process_device(u, dev);
> -    udev_device_unref(dev);

If path_get_card_id() returns zero, dev doesn't get unreffed. Is this
intentional - did you fix a bug, or introduce one?

>     return;
> 
> fail:


-- 
Tanu




More information about the pulseaudio-discuss mailing list