diff options
-rw-r--r-- | media.c | 41 |
1 files changed, 24 insertions, 17 deletions
@@ -430,9 +430,11 @@ static int media_enum_entities(struct media_device *media) { struct media_entity *entity; struct stat devstat; - char devname[32]; unsigned int size; - unsigned int i; + char devname[32]; + char sysname[32]; + char target[1024]; + char *p; __u32 id; int ret; @@ -465,24 +467,29 @@ static int media_enum_entities(struct media_device *media) (entity->info.type != MEDIA_ENTITY_TYPE_SUBDEV)) continue; - for (i = 0; i < 256; ++i) { - if (entity->info.type == MEDIA_ENTITY_TYPE_NODE) - sprintf(devname, "/dev/video%u", i); - else - sprintf(devname, "/dev/subdev%u", i); + sprintf(sysname, "/sys/dev/char/%u:%u", entity->info.v4l.major, + entity->info.v4l.minor); + ret = readlink(sysname, target, sizeof(target)); + if (ret < 0) + continue; - ret = stat(devname, &devstat); - if (ret < 0) - continue; + target[ret] = '\0'; + p = strrchr(target, '/'); + if (p == NULL) + continue; - if (major(devstat.st_rdev) == entity->info.v4l.major && - minor(devstat.st_rdev) == entity->info.v4l.minor) { - strcpy(entity->devname, devname); - break; - } - } + sprintf(devname, "/dev/%s", p + 1); + ret = stat(devname, &devstat); + if (ret < 0) + continue; - id = entity->info.id; + /* Sanity check: udev might have reordered the device nodes. + * Make sure the major/minor match. We should really use + * libudev. + */ + if (major(devstat.st_rdev) == entity->info.v4l.major && + minor(devstat.st_rdev) == entity->info.v4l.minor) + strcpy(entity->devname, devname); } return 0; |