Skip to content

Commit b2cd274

Browse files
committed
[media] media-device: map new functions into old types for legacy API
The legacy media controller userspace API exposes entity types that carry both type and function information. The new API replaces the type with a function. It preserves backward compatibility by defining legacy functions for the existing types and using them in drivers. This works fine, as long as newer entity functions won't be added. Unfortunately, some tools, like media-ctl with --print-dot argument rely on the now legacy MEDIA_ENT_T_V4L2_SUBDEV and MEDIA_ENT_T_DEVNODE numeric ranges to identify what entities will be shown. Also, if the entity doesn't match those ranges, it will ignore the major/minor information on devnodes, and won't be getting the devnode name via udev or sysfs. As we're now adding devices outside the old range, the legacy ioctl needs to map the new entity functions into a type at the old range, or otherwise we'll have a regression. Detected on all released media-ctl versions (e. g. versions <= 1.10). Fix this by deriving the type from the function to emulate the legacy API if the function isn't in the legacy functions range. Reported-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
1 parent fbe093a commit b2cd274

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

drivers/media/media-device.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2121
*/
2222

23+
/* We need to access legacy defines from linux/media.h */
24+
#define __NEED_MEDIA_LEGACY_API
25+
2326
#include <linux/compat.h>
2427
#include <linux/export.h>
2528
#include <linux/idr.h>
@@ -115,6 +118,26 @@ static long media_device_enum_entities(struct media_device *mdev,
115118
u_ent.group_id = 0; /* Unused */
116119
u_ent.pads = ent->num_pads;
117120
u_ent.links = ent->num_links - ent->num_backlinks;
121+
122+
/*
123+
* Workaround for a bug at media-ctl <= v1.10 that makes it to
124+
* do the wrong thing if the entity function doesn't belong to
125+
* either MEDIA_ENT_F_OLD_BASE or MEDIA_ENT_F_OLD_SUBDEV_BASE
126+
* Ranges.
127+
*
128+
* Non-subdevices are expected to be at the MEDIA_ENT_F_OLD_BASE,
129+
* or, otherwise, will be silently ignored by media-ctl when
130+
* printing the graphviz diagram. So, map them into the devnode
131+
* old range.
132+
*/
133+
if (ent->function < MEDIA_ENT_F_OLD_BASE ||
134+
ent->function > MEDIA_ENT_T_DEVNODE_UNKNOWN) {
135+
if (is_media_entity_v4l2_subdev(ent))
136+
u_ent.type = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN;
137+
else if (ent->function != MEDIA_ENT_F_IO_V4L)
138+
u_ent.type = MEDIA_ENT_T_DEVNODE_UNKNOWN;
139+
}
140+
118141
memcpy(&u_ent.raw, &ent->info, sizeof(ent->info));
119142
if (copy_to_user(uent, &u_ent, sizeof(u_ent)))
120143
return -EFAULT;

include/uapi/linux/media.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ struct media_device_info {
120120

121121
#define MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN MEDIA_ENT_F_OLD_SUBDEV_BASE
122122

123-
#ifndef __KERNEL__
123+
#if !defined(__KERNEL__) || defined(__NEED_MEDIA_LEGACY_API)
124124

125125
/*
126126
* Legacy symbols used to avoid userspace compilation breakages
@@ -133,6 +133,10 @@ struct media_device_info {
133133
#define MEDIA_ENT_TYPE_MASK 0x00ff0000
134134
#define MEDIA_ENT_SUBTYPE_MASK 0x0000ffff
135135

136+
/* End of the old subdev reserved numberspace */
137+
#define MEDIA_ENT_T_DEVNODE_UNKNOWN (MEDIA_ENT_T_DEVNODE | \
138+
MEDIA_ENT_SUBTYPE_MASK)
139+
136140
#define MEDIA_ENT_T_DEVNODE MEDIA_ENT_F_OLD_BASE
137141
#define MEDIA_ENT_T_DEVNODE_V4L MEDIA_ENT_F_IO_V4L
138142
#define MEDIA_ENT_T_DEVNODE_FB (MEDIA_ENT_T_DEVNODE + 2)

0 commit comments

Comments
 (0)