diff options
Diffstat (limited to 'init/devices.c')
-rw-r--r-- | init/devices.c | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/init/devices.c b/init/devices.c index eb5d84e..9c07e99 100644 --- a/init/devices.c +++ b/init/devices.c @@ -15,6 +15,7 @@ */ #include <errno.h> +#include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> @@ -280,6 +281,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; @@ -426,6 +478,7 @@ static void handle_device_event(struct uevent *uevent) name += 4; } else base = "/dev/"; + links = get_character_device_symlinks(uevent); } if (!devpath_ready) @@ -539,8 +592,10 @@ static void process_firmware_event(struct uevent *uevent) fw_fd = open(file1, O_RDONLY); if(fw_fd < 0) { fw_fd = open(file2, O_RDONLY); - if(fw_fd < 0) + if (fw_fd < 0) { + write(loading_fd, "-1", 2); goto data_close_out; + } } if(!load_firmware(fw_fd, loading_fd, data_fd)) |