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/media.c | |
| 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/media.c')
| -rw-r--r-- | src/media.c | 85 | 
1 files changed, 81 insertions, 4 deletions
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));  | 
