From 64967ec99ba606b98d913ffa90a824d4466c4b3b Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 6 Jan 2012 13:44:44 +0100 Subject: live: Fix video output localization As V4L2 subdevice nodes use the V4L2 video device nodes major number, there is no 1:1 correspondance between video device nodes numbers and video device nodes minors. The video output device localization code will thus fail if the omap3_isp driver is loaded before the omap_vout driver. Fix this by reading the video output device major and minor numbers from sysfs and match them against the device node. Signed-off-by: Laurent Pinchart --- live.c | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) (limited to 'live.c') diff --git a/live.c b/live.c index f886fa5..70e4db5 100644 --- a/live.c +++ b/live.c @@ -21,6 +21,7 @@ */ #define _BSD_SOURCE +#include #include #include #include @@ -257,12 +258,16 @@ static struct video_out_operations vo_ops = { static const char *video_out_find(void) { unsigned int video_idx = 256; - static char devname[14]; + static char devname[36]; + static char dev[20]; + unsigned int major; + unsigned int minor; struct stat devstat; struct dirent *ent; char *end; DIR *dir; int ret; + int fd; dir = opendir("/sys/bus/platform/devices/omap_vout/video4linux"); if (dir == NULL) @@ -287,15 +292,36 @@ static const char *video_out_find(void) if (video_idx == 256) return NULL; + /* Read the device major and minor from sysfs. */ + sprintf(devname, "/sys/class/video4linux/video%u/dev", video_idx); + fd = open(devname, O_RDONLY); + if (fd == -1) + return NULL; + + ret = read(fd, dev, sizeof dev - 1); + close(fd); + if (ret < 0) + return NULL; + + dev[ret] = '\0'; + major = strtoul(dev, &end, 10); + if (*end != ':') + return NULL; + + minor = strtoul(end + 1, &end, 10); + if (!isspace(*end) && end != '\0') + return NULL; + + /* Verify that the device node exists. udev might have reordered the + * device nodes, make sure the major/minor match as a sanity check. We + * should really use libudev. + */ sprintf(devname, "/dev/video%u", video_idx); ret = stat(devname, &devstat); if (ret < 0) return NULL; - /* 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) != 81 || minor(devstat.st_rdev) != video_idx) + if (major(devstat.st_rdev) != major || minor(devstat.st_rdev) != minor) return NULL; return devname; -- cgit v1.2.3