Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d2278638 authored by Benoit Goby's avatar Benoit Goby
Browse files

init: Add symlinks to USB character devices

Since we now support USB host mode, devices might get a different device
file depending if other devices are connected on the host port. This
patch creates symlinks to USB character devices that depend on the port
devices are connected to, but not on the order they have been probed.
(e.g. /dev/usb/tty2-1:1.0 -> /dev/ttyUSB0)

Change-Id: I285bcc2d59446fbff8a7abbe39c21781f3bb4bd3
parent da7723ce
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -264,6 +264,57 @@ static void parse_event(const char *msg, struct uevent *uevent)
                    uevent->firmware, uevent->major, uevent->minor);
}

static char **get_character_device_symlinks(struct uevent *uevent)
{
    const char *parent;
    char *slash;
    char **links;
    int link_num = 0;
    int width;

    if (strncmp(uevent->path, "/devices/platform/", 18))
        return NULL;

    links = malloc(sizeof(char *) * 2);
    if (!links)
        return NULL;
    memset(links, 0, sizeof(char *) * 2);

    /* skip "/devices/platform/<driver>" */
    parent = strchr(uevent->path + 18, '/');
    if (!*parent)
        goto err;

    if (!strncmp(parent, "/usb", 4)) {
        /* skip root hub name and device. use device interface */
        while (*++parent && *parent != '/');
        if (*parent)
            while (*++parent && *parent != '/');
        if (!*parent)
            goto err;
        slash = strchr(++parent, '/');
        if (!slash)
            goto err;
        width = slash - parent;
        if (width <= 0)
            goto err;

        if (asprintf(&links[link_num], "/dev/usb/%s%.*s", uevent->subsystem, width, parent) > 0)
            link_num++;
        else
            links[link_num] = NULL;
        mkdir("/dev/usb", 0755);
    }
    else {
        goto err;
    }

    return links;
err:
    free(links);
    return NULL;
}

static char **parse_platform_block_device(struct uevent *uevent)
{
    const char *driver;
@@ -407,6 +458,7 @@ static void handle_device_event(struct uevent *uevent)
            name += 4;
        } else
            base = "/dev/";
        links = get_character_device_symlinks(uevent);
    }

    if (!devpath_ready)