From 0e61c58c9f73dedbde3d35cdca608038643c2547 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 20 Aug 2010 10:57:19 +0200 Subject: Use sysfs to locate devices nodes Changes made during the v4l2_subdev API review renamed the /dev/subdev* device nodes to /dev/v4l-subdev*. Instead of hardcoding the names in the media-ctl application, use sysfs to retrieve the kernel device name and assume the device node name is identical. This isn't a perfect solution, we should really use libudev, but it will do for now. Signed-off-by: Laurent Pinchart --- media.c | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) (limited to 'media.c') diff --git a/media.c b/media.c index aaa1005..1bc39e1 100644 --- a/media.c +++ b/media.c @@ -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; -- cgit v1.2.3