diff options
author | Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 2011-09-05 18:24:05 +0300 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2011-09-06 12:19:43 +0200 |
commit | dfcdee310100fa0297f6d15dbadb673283c9a06a (patch) | |
tree | ca0cad903ef9835d4f85149cf75d1cff777b0c3d /src | |
parent | 1690efe5a4daf5cd2d1b71c49286c376cc7fcc15 (diff) |
libmediactl: get the device name via udev
If configured with --with-libudev, the libmediactl is built with libudev
support. It allows to get the device name in right way in the modern linux
systems.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[laurent.pinchart@ideasonboard.com: Remove media_private structure]
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/media.c | 85 |
2 files changed, 83 insertions, 4 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 267ea83..52628d2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,6 +5,8 @@ mediactl_includedir=$(includedir)/mediactl mediactl_include_HEADERS = media.h subdev.h bin_PROGRAMS = media-ctl +media_ctl_CFLAGS = $(LIBUDEV_CFLAGS) +media_ctl_LDFLAGS = $(LIBUDEV_LIBS) media_ctl_SOURCES = main.c options.c options.h tools.h media_ctl_LDADD = libmediactl.la libv4l2subdev.la diff --git a/src/media.c b/src/media.c index 30d603b..099e77e 100644 --- a/src/media.c +++ b/src/media.c @@ -17,6 +17,8 @@ * with this program; if not, write to the Free Software Foundation, Inc., */ +#include "config.h" + #include <sys/ioctl.h> #include <sys/stat.h> #include <sys/types.h> @@ -245,6 +247,69 @@ static int media_enum_links(struct media_device *media) return ret; } +#ifdef HAVE_LIBUDEV + +#include <libudev.h> + +static inline int media_udev_open(struct udev **udev) +{ + *udev = udev_new(); + if (*udev == NULL) + return -ENOMEM; + return 0; +} + +static inline void media_udev_close(struct udev *udev) +{ + if (udev != NULL) + udev_unref(udev); +} + +static int media_get_devname_udev(struct udev *udev, + struct media_entity *entity, int verbose) +{ + struct udev_device *device; + dev_t devnum; + const char *p; + int ret = -ENODEV; + + if (udev == NULL) + return -EINVAL; + + devnum = makedev(entity->info.v4l.major, entity->info.v4l.minor); + if (verbose) + printf("looking up device: %u:%u\n", major(devnum), minor(devnum)); + device = udev_device_new_from_devnum(udev, 'c', devnum); + if (device) { + p = udev_device_get_devnode(device); + if (p) { + strncpy(entity->devname, p, sizeof(entity->devname)); + entity->devname[sizeof(entity->devname) - 1] = '\0'; + } + ret = 0; + } + + udev_device_unref(device); + + return ret; +} + +#else /* HAVE_LIBUDEV */ + +struct udev; + +static inline int media_udev_open(struct udev **udev) { return 0; } + +static inline void media_udev_close(struct udev *udev) { } + +static inline int media_get_devname_udev(struct udev *udev, + struct media_entity *entity, int verbose) +{ + return -ENOTSUP; +} + +#endif /* HAVE_LIBUDEV */ + static int media_get_devname_sysfs(struct media_entity *entity) { struct stat devstat; @@ -281,14 +346,19 @@ static int media_get_devname_sysfs(struct media_entity *entity) return 0; } -static int media_enum_entities(struct media_device *media) +static int media_enum_entities(struct media_device *media, int verbose) { struct media_entity *entity; + struct udev *udev; unsigned int size; __u32 id; - int ret = 0; + int ret; - for (id = 0; ; id = entity->info.id) { + ret = media_udev_open(&udev); + if (ret < 0) + printf("%s: Can't get udev context\n", __func__); + + for (id = 0, ret = 0; ; id = entity->info.id) { size = (media->entities_count + 1) * sizeof(*media->entities); media->entities = realloc(media->entities, size); @@ -323,9 +393,15 @@ static int media_enum_entities(struct media_device *media) media_entity_type(entity) != MEDIA_ENT_T_V4L2_SUBDEV) continue; + /* Try to get the device name via udev */ + if (!media_get_devname_udev(udev, entity, verbose)) + continue; + + /* Fall back to get the device name via sysfs */ media_get_devname_sysfs(entity); } + media_udev_close(udev); return ret; } @@ -353,7 +429,8 @@ struct media_device *media_open(const char *name, int verbose) if (verbose) printf("Enumerating entities\n"); - ret = media_enum_entities(media); + ret = media_enum_entities(media, verbose); + if (ret < 0) { printf("%s: Unable to enumerate entities for device %s (%s)\n", __func__, name, strerror(-ret)); |