summaryrefslogtreecommitdiff
path: root/live.c
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-01-06 13:44:44 +0100
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-01-06 14:02:57 +0100
commit64967ec99ba606b98d913ffa90a824d4466c4b3b (patch)
tree0f010dfeea12bb6c8a59e042c7700e88a1415122 /live.c
parent38591700b3a570861c4fc4223cd7bc05d4cf7e21 (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>
Diffstat (limited to 'live.c')
-rw-r--r--live.c36
1 files changed, 31 insertions, 5 deletions
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 <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;