summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2010-08-20 10:57:19 +0200
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2010-08-20 10:57:19 +0200
commit0e61c58c9f73dedbde3d35cdca608038643c2547 (patch)
tree6a1590a3b3d2170b74346f586b490be1e97115df
parent468bc21f8c6c7eca85477680752052e1ead0e515 (diff)
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 <laurent.pinchart@ideasonboard.com>
-rw-r--r--media.c41
1 files changed, 24 insertions, 17 deletions
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;