diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2012-01-06 13:44:44 +0100 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2012-01-06 14:02:57 +0100 |
commit | 64967ec99ba606b98d913ffa90a824d4466c4b3b (patch) | |
tree | 0f010dfeea12bb6c8a59e042c7700e88a1415122 | |
parent | 38591700b3a570861c4fc4223cd7bc05d4cf7e21 (diff) |
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 <laurent.pinchart@ideasonboard.com>
-rw-r--r-- | live.c | 36 |
1 files changed, 31 insertions, 5 deletions
@@ -21,6 +21,7 @@ */ #define _BSD_SOURCE +#include <ctype.h> #include <dirent.h> #include <endian.h> #include <errno.h> @@ -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; |