diff options
Diffstat (limited to 'drivers/media/media-device.c')
-rw-r--r-- | drivers/media/media-device.c | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 7dae0ac0f3ae..711c3674a5d9 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -20,6 +20,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/* We need to access legacy defines from linux/media.h */ +#define __NEED_MEDIA_LEGACY_API + #include <linux/compat.h> #include <linux/export.h> #include <linux/idr.h> @@ -55,7 +58,11 @@ static int media_device_get_info(struct media_device *dev, memset(&info, 0, sizeof(info)); - strlcpy(info.driver, dev->dev->driver->name, sizeof(info.driver)); + if (dev->driver_name[0]) + strlcpy(info.driver, dev->driver_name, sizeof(info.driver)); + else + strlcpy(info.driver, dev->dev->driver->name, sizeof(info.driver)); + strlcpy(info.model, dev->model, sizeof(info.model)); strlcpy(info.serial, dev->serial, sizeof(info.serial)); strlcpy(info.bus_info, dev->bus_info, sizeof(info.bus_info)); @@ -115,6 +122,26 @@ static long media_device_enum_entities(struct media_device *mdev, u_ent.group_id = 0; /* Unused */ u_ent.pads = ent->num_pads; u_ent.links = ent->num_links - ent->num_backlinks; + + /* + * Workaround for a bug at media-ctl <= v1.10 that makes it to + * do the wrong thing if the entity function doesn't belong to + * either MEDIA_ENT_F_OLD_BASE or MEDIA_ENT_F_OLD_SUBDEV_BASE + * Ranges. + * + * Non-subdevices are expected to be at the MEDIA_ENT_F_OLD_BASE, + * or, otherwise, will be silently ignored by media-ctl when + * printing the graphviz diagram. So, map them into the devnode + * old range. + */ + if (ent->function < MEDIA_ENT_F_OLD_BASE || + ent->function > MEDIA_ENT_T_DEVNODE_UNKNOWN) { + if (is_media_entity_v4l2_subdev(ent)) + u_ent.type = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN; + else if (ent->function != MEDIA_ENT_F_IO_V4L) + u_ent.type = MEDIA_ENT_T_DEVNODE_UNKNOWN; + } + memcpy(&u_ent.raw, &ent->info, sizeof(ent->info)); if (copy_to_user(uent, &u_ent, sizeof(u_ent))) return -EFAULT; @@ -234,7 +261,6 @@ static long media_device_setup_link(struct media_device *mdev, return ret; } -#if 0 /* Let's postpone it to Kernel 4.6 */ static long __media_device_get_topology(struct media_device *mdev, struct media_v2_topology *topo) { @@ -390,7 +416,6 @@ static long media_device_get_topology(struct media_device *mdev, return 0; } -#endif static long media_device_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) @@ -424,14 +449,13 @@ static long media_device_ioctl(struct file *filp, unsigned int cmd, mutex_unlock(&dev->graph_mutex); break; -#if 0 /* Let's postpone it to Kernel 4.6 */ case MEDIA_IOC_G_TOPOLOGY: mutex_lock(&dev->graph_mutex); ret = media_device_get_topology(dev, (struct media_v2_topology __user *)arg); mutex_unlock(&dev->graph_mutex); break; -#endif + default: ret = -ENOIOCTLCMD; } @@ -480,9 +504,7 @@ static long media_device_compat_ioctl(struct file *filp, unsigned int cmd, case MEDIA_IOC_DEVICE_INFO: case MEDIA_IOC_ENUM_ENTITIES: case MEDIA_IOC_SETUP_LINK: -#if 0 /* Let's postpone it to Kernel 4.6 */ case MEDIA_IOC_G_TOPOLOGY: -#endif return media_device_ioctl(filp, cmd, arg); case MEDIA_IOC_ENUM_LINKS32: |