Message ID | 20181101233144.31507-18-niklas.soderlund+renesas@ragnatech.se (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | v4l: add support for multiplexed streams | expand |
Hi Niklas, Sakari, On Fri, Nov 2, 2018 at 12:33 AM Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> wrote: > From: Sakari Ailus <sakari.ailus@linux.intel.com> > > Implement compat IOCTL handling for VIDIOC_SUBDEV_G_ROUTING and > VIDIOC_SUBDEV_S_ROUTING IOCTLs. > > Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> > Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> > --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c > +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c > @@ -1045,6 +1045,66 @@ static int put_v4l2_event32(struct v4l2_event __user *p64, > return 0; > } > > +struct v4l2_subdev_routing32 { > + compat_caddr_t routes; > + __u32 num_routes; > + __u32 reserved[5]; > +}; > + > +static int get_v4l2_subdev_routing(struct v4l2_subdev_routing __user *p64, > + struct v4l2_subdev_routing32 __user *p32) > +{ > + struct v4l2_subdev_route __user *routes; > + compat_caddr_t p; > + u32 num_routes; > + > + if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) || Please drop the first parameter of all newly-added access_ok() calls, as it has been removed in commit 96d4f267e40f9509 ("Remove 'type' argument from access_ok() function"). Gr{oetje,eeting}s, Geert
Hi Niklas, Thank you for the patch. On Fri, Nov 02, 2018 at 12:31:31AM +0100, Niklas Söderlund wrote: > From: Sakari Ailus <sakari.ailus@linux.intel.com> > > Implement compat IOCTL handling for VIDIOC_SUBDEV_G_ROUTING and > VIDIOC_SUBDEV_S_ROUTING IOCTLs. Let's instead design the ioctl in a way that doesn't require compat handling. > Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> > Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> > --- > drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 77 +++++++++++++++++++ > 1 file changed, 77 insertions(+) > > diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c > index 6481212fda772c73..83af332763f41a6b 100644 > --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c > +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c > @@ -1045,6 +1045,66 @@ static int put_v4l2_event32(struct v4l2_event __user *p64, > return 0; > } > > +struct v4l2_subdev_routing32 { > + compat_caddr_t routes; > + __u32 num_routes; > + __u32 reserved[5]; > +}; > + > +static int get_v4l2_subdev_routing(struct v4l2_subdev_routing __user *p64, > + struct v4l2_subdev_routing32 __user *p32) > +{ > + struct v4l2_subdev_route __user *routes; > + compat_caddr_t p; > + u32 num_routes; > + > + if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) || > + get_user(p, &p32->routes) || > + get_user(num_routes, &p32->num_routes) || > + put_user(num_routes, &p64->num_routes) || > + copy_in_user(&p64->reserved, &p32->reserved, > + sizeof(p64->reserved)) || > + num_routes > U32_MAX / sizeof(*p64->routes)) > + return -EFAULT; > + > + routes = compat_ptr(p); > + > + if (!access_ok(VERIFY_READ, routes, > + num_routes * sizeof(*p64->routes))) > + return -EFAULT; > + > + if (put_user((__force struct v4l2_subdev_route *)routes, > + &p64->routes)) > + return -EFAULT; > + > + return 0; > +} > + > +static int put_v4l2_subdev_routing(struct v4l2_subdev_routing __user *p64, > + struct v4l2_subdev_routing32 __user *p32) > +{ > + struct v4l2_subdev_route __user *routes; > + compat_caddr_t p; > + u32 num_routes; > + > + if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) || > + get_user(p, &p32->routes) || > + get_user(num_routes, &p64->num_routes) || > + put_user(num_routes, &p32->num_routes) || > + copy_in_user(&p32->reserved, &p64->reserved, > + sizeof(p64->reserved)) || > + num_routes > U32_MAX / sizeof(*p64->routes)) > + return -EFAULT; > + > + routes = compat_ptr(p); > + > + if (!access_ok(VERIFY_WRITE, routes, > + num_routes * sizeof(*p64->routes))) > + return -EFAULT; > + > + return 0; > +} > + > struct v4l2_edid32 { > __u32 pad; > __u32 start_block; > @@ -1117,6 +1177,8 @@ static int put_v4l2_edid32(struct v4l2_edid __user *p64, > #define VIDIOC_STREAMOFF32 _IOW ('V', 19, s32) > #define VIDIOC_G_INPUT32 _IOR ('V', 38, s32) > #define VIDIOC_S_INPUT32 _IOWR('V', 39, s32) > +#define VIDIOC_SUBDEV_G_ROUTING32 _IOWR('V', 38, struct v4l2_subdev_routing32) > +#define VIDIOC_SUBDEV_S_ROUTING32 _IOWR('V', 39, struct v4l2_subdev_routing32) > #define VIDIOC_G_OUTPUT32 _IOR ('V', 46, s32) > #define VIDIOC_S_OUTPUT32 _IOWR('V', 47, s32) > > @@ -1195,6 +1257,8 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar > case VIDIOC_STREAMOFF32: cmd = VIDIOC_STREAMOFF; break; > case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break; > case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break; > + case VIDIOC_SUBDEV_G_ROUTING32: cmd = VIDIOC_SUBDEV_G_ROUTING; break; > + case VIDIOC_SUBDEV_S_ROUTING32: cmd = VIDIOC_SUBDEV_S_ROUTING; break; > case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break; > case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break; > case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break; > @@ -1227,6 +1291,15 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar > compatible_arg = 0; > break; > > + case VIDIOC_SUBDEV_G_ROUTING: > + case VIDIOC_SUBDEV_S_ROUTING: > + err = alloc_userspace(sizeof(struct v4l2_subdev_routing), > + 0, &new_p64); > + if (!err) > + err = get_v4l2_subdev_routing(new_p64, p32); > + compatible_arg = 0; > + break; > + > case VIDIOC_G_EDID: > case VIDIOC_S_EDID: > err = alloc_userspace(sizeof(struct v4l2_edid), 0, &new_p64); > @@ -1368,6 +1441,10 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar > if (put_v4l2_edid32(new_p64, p32)) > err = -EFAULT; > break; > + case VIDIOC_SUBDEV_G_ROUTING: > + case VIDIOC_SUBDEV_S_ROUTING: > + err = put_v4l2_subdev_routing(new_p64, p32); > + break; > } > if (err) > return err;
On Wed, Jan 16, 2019 at 01:53:03AM +0200, Laurent Pinchart wrote: > Hi Niklas, > > Thank you for the patch. > > On Fri, Nov 02, 2018 at 12:31:31AM +0100, Niklas Söderlund wrote: > > From: Sakari Ailus <sakari.ailus@linux.intel.com> > > > > Implement compat IOCTL handling for VIDIOC_SUBDEV_G_ROUTING and > > VIDIOC_SUBDEV_S_ROUTING IOCTLs. > > Let's instead design the ioctl in a way that doesn't require compat > handling. Yeah, I wrote the patch back then when the practice hadn't changed yes. I agree. > > > Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> > > Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> > > --- > > drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 77 +++++++++++++++++++ > > 1 file changed, 77 insertions(+) > > > > diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c > > index 6481212fda772c73..83af332763f41a6b 100644 > > --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c > > +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c > > @@ -1045,6 +1045,66 @@ static int put_v4l2_event32(struct v4l2_event __user *p64, > > return 0; > > } > > > > +struct v4l2_subdev_routing32 { > > + compat_caddr_t routes; > > + __u32 num_routes; > > + __u32 reserved[5]; > > +}; > > + > > +static int get_v4l2_subdev_routing(struct v4l2_subdev_routing __user *p64, > > + struct v4l2_subdev_routing32 __user *p32) > > +{ > > + struct v4l2_subdev_route __user *routes; > > + compat_caddr_t p; > > + u32 num_routes; > > + > > + if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) || > > + get_user(p, &p32->routes) || > > + get_user(num_routes, &p32->num_routes) || > > + put_user(num_routes, &p64->num_routes) || > > + copy_in_user(&p64->reserved, &p32->reserved, > > + sizeof(p64->reserved)) || > > + num_routes > U32_MAX / sizeof(*p64->routes)) > > + return -EFAULT; > > + > > + routes = compat_ptr(p); > > + > > + if (!access_ok(VERIFY_READ, routes, > > + num_routes * sizeof(*p64->routes))) > > + return -EFAULT; > > + > > + if (put_user((__force struct v4l2_subdev_route *)routes, > > + &p64->routes)) > > + return -EFAULT; > > + > > + return 0; > > +} > > + > > +static int put_v4l2_subdev_routing(struct v4l2_subdev_routing __user *p64, > > + struct v4l2_subdev_routing32 __user *p32) > > +{ > > + struct v4l2_subdev_route __user *routes; > > + compat_caddr_t p; > > + u32 num_routes; > > + > > + if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) || > > + get_user(p, &p32->routes) || > > + get_user(num_routes, &p64->num_routes) || > > + put_user(num_routes, &p32->num_routes) || > > + copy_in_user(&p32->reserved, &p64->reserved, > > + sizeof(p64->reserved)) || > > + num_routes > U32_MAX / sizeof(*p64->routes)) > > + return -EFAULT; > > + > > + routes = compat_ptr(p); > > + > > + if (!access_ok(VERIFY_WRITE, routes, > > + num_routes * sizeof(*p64->routes))) > > + return -EFAULT; > > + > > + return 0; > > +} > > + > > struct v4l2_edid32 { > > __u32 pad; > > __u32 start_block; > > @@ -1117,6 +1177,8 @@ static int put_v4l2_edid32(struct v4l2_edid __user *p64, > > #define VIDIOC_STREAMOFF32 _IOW ('V', 19, s32) > > #define VIDIOC_G_INPUT32 _IOR ('V', 38, s32) > > #define VIDIOC_S_INPUT32 _IOWR('V', 39, s32) > > +#define VIDIOC_SUBDEV_G_ROUTING32 _IOWR('V', 38, struct v4l2_subdev_routing32) > > +#define VIDIOC_SUBDEV_S_ROUTING32 _IOWR('V', 39, struct v4l2_subdev_routing32) > > #define VIDIOC_G_OUTPUT32 _IOR ('V', 46, s32) > > #define VIDIOC_S_OUTPUT32 _IOWR('V', 47, s32) > > > > @@ -1195,6 +1257,8 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar > > case VIDIOC_STREAMOFF32: cmd = VIDIOC_STREAMOFF; break; > > case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break; > > case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break; > > + case VIDIOC_SUBDEV_G_ROUTING32: cmd = VIDIOC_SUBDEV_G_ROUTING; break; > > + case VIDIOC_SUBDEV_S_ROUTING32: cmd = VIDIOC_SUBDEV_S_ROUTING; break; > > case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break; > > case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break; > > case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break; > > @@ -1227,6 +1291,15 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar > > compatible_arg = 0; > > break; > > > > + case VIDIOC_SUBDEV_G_ROUTING: > > + case VIDIOC_SUBDEV_S_ROUTING: > > + err = alloc_userspace(sizeof(struct v4l2_subdev_routing), > > + 0, &new_p64); > > + if (!err) > > + err = get_v4l2_subdev_routing(new_p64, p32); > > + compatible_arg = 0; > > + break; > > + > > case VIDIOC_G_EDID: > > case VIDIOC_S_EDID: > > err = alloc_userspace(sizeof(struct v4l2_edid), 0, &new_p64); > > @@ -1368,6 +1441,10 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar > > if (put_v4l2_edid32(new_p64, p32)) > > err = -EFAULT; > > break; > > + case VIDIOC_SUBDEV_G_ROUTING: > > + case VIDIOC_SUBDEV_S_ROUTING: > > + err = put_v4l2_subdev_routing(new_p64, p32); > > + break; > > } > > if (err) > > return err; > > -- > Regards, > > Laurent Pinchart
Hi Laurent, Sakari, On Wed, Jan 16, 2019 at 01:53:03AM +0200, Laurent Pinchart wrote: > Hi Niklas, > > Thank you for the patch. > > On Fri, Nov 02, 2018 at 12:31:31AM +0100, Niklas Söderlund wrote: > > From: Sakari Ailus <sakari.ailus@linux.intel.com> > > > > Implement compat IOCTL handling for VIDIOC_SUBDEV_G_ROUTING and > > VIDIOC_SUBDEV_S_ROUTING IOCTLs. > > Let's instead design the ioctl in a way that doesn't require compat > handling. > Care to explain what makes this ioctl require a compat version? I don't see assumptions on the word length on the implementation. What am I missing? Thanks j > > Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> > > Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> > > --- > > drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 77 +++++++++++++++++++ > > 1 file changed, 77 insertions(+) > > > > diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c > > index 6481212fda772c73..83af332763f41a6b 100644 > > --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c > > +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c > > @@ -1045,6 +1045,66 @@ static int put_v4l2_event32(struct v4l2_event __user *p64, > > return 0; > > } > > > > +struct v4l2_subdev_routing32 { > > + compat_caddr_t routes; > > + __u32 num_routes; > > + __u32 reserved[5]; > > +}; > > + > > +static int get_v4l2_subdev_routing(struct v4l2_subdev_routing __user *p64, > > + struct v4l2_subdev_routing32 __user *p32) > > +{ > > + struct v4l2_subdev_route __user *routes; > > + compat_caddr_t p; > > + u32 num_routes; > > + > > + if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) || > > + get_user(p, &p32->routes) || > > + get_user(num_routes, &p32->num_routes) || > > + put_user(num_routes, &p64->num_routes) || > > + copy_in_user(&p64->reserved, &p32->reserved, > > + sizeof(p64->reserved)) || > > + num_routes > U32_MAX / sizeof(*p64->routes)) > > + return -EFAULT; > > + > > + routes = compat_ptr(p); > > + > > + if (!access_ok(VERIFY_READ, routes, > > + num_routes * sizeof(*p64->routes))) > > + return -EFAULT; > > + > > + if (put_user((__force struct v4l2_subdev_route *)routes, > > + &p64->routes)) > > + return -EFAULT; > > + > > + return 0; > > +} > > + > > +static int put_v4l2_subdev_routing(struct v4l2_subdev_routing __user *p64, > > + struct v4l2_subdev_routing32 __user *p32) > > +{ > > + struct v4l2_subdev_route __user *routes; > > + compat_caddr_t p; > > + u32 num_routes; > > + > > + if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) || > > + get_user(p, &p32->routes) || > > + get_user(num_routes, &p64->num_routes) || > > + put_user(num_routes, &p32->num_routes) || > > + copy_in_user(&p32->reserved, &p64->reserved, > > + sizeof(p64->reserved)) || > > + num_routes > U32_MAX / sizeof(*p64->routes)) > > + return -EFAULT; > > + > > + routes = compat_ptr(p); > > + > > + if (!access_ok(VERIFY_WRITE, routes, > > + num_routes * sizeof(*p64->routes))) > > + return -EFAULT; > > + > > + return 0; > > +} > > + > > struct v4l2_edid32 { > > __u32 pad; > > __u32 start_block; > > @@ -1117,6 +1177,8 @@ static int put_v4l2_edid32(struct v4l2_edid __user *p64, > > #define VIDIOC_STREAMOFF32 _IOW ('V', 19, s32) > > #define VIDIOC_G_INPUT32 _IOR ('V', 38, s32) > > #define VIDIOC_S_INPUT32 _IOWR('V', 39, s32) > > +#define VIDIOC_SUBDEV_G_ROUTING32 _IOWR('V', 38, struct v4l2_subdev_routing32) > > +#define VIDIOC_SUBDEV_S_ROUTING32 _IOWR('V', 39, struct v4l2_subdev_routing32) > > #define VIDIOC_G_OUTPUT32 _IOR ('V', 46, s32) > > #define VIDIOC_S_OUTPUT32 _IOWR('V', 47, s32) > > > > @@ -1195,6 +1257,8 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar > > case VIDIOC_STREAMOFF32: cmd = VIDIOC_STREAMOFF; break; > > case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break; > > case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break; > > + case VIDIOC_SUBDEV_G_ROUTING32: cmd = VIDIOC_SUBDEV_G_ROUTING; break; > > + case VIDIOC_SUBDEV_S_ROUTING32: cmd = VIDIOC_SUBDEV_S_ROUTING; break; > > case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break; > > case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break; > > case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break; > > @@ -1227,6 +1291,15 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar > > compatible_arg = 0; > > break; > > > > + case VIDIOC_SUBDEV_G_ROUTING: > > + case VIDIOC_SUBDEV_S_ROUTING: > > + err = alloc_userspace(sizeof(struct v4l2_subdev_routing), > > + 0, &new_p64); > > + if (!err) > > + err = get_v4l2_subdev_routing(new_p64, p32); > > + compatible_arg = 0; > > + break; > > + > > case VIDIOC_G_EDID: > > case VIDIOC_S_EDID: > > err = alloc_userspace(sizeof(struct v4l2_edid), 0, &new_p64); > > @@ -1368,6 +1441,10 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar > > if (put_v4l2_edid32(new_p64, p32)) > > err = -EFAULT; > > break; > > + case VIDIOC_SUBDEV_G_ROUTING: > > + case VIDIOC_SUBDEV_S_ROUTING: > > + err = put_v4l2_subdev_routing(new_p64, p32); > > + break; > > } > > if (err) > > return err; > > -- > Regards, > > Laurent Pinchart
On Mon, Feb 18, 2019 at 12:21:09PM +0100, Jacopo Mondi wrote: > Hi Laurent, Sakari, > > On Wed, Jan 16, 2019 at 01:53:03AM +0200, Laurent Pinchart wrote: > > Hi Niklas, > > > > Thank you for the patch. > > > > On Fri, Nov 02, 2018 at 12:31:31AM +0100, Niklas Söderlund wrote: > > > From: Sakari Ailus <sakari.ailus@linux.intel.com> > > > > > > Implement compat IOCTL handling for VIDIOC_SUBDEV_G_ROUTING and > > > VIDIOC_SUBDEV_S_ROUTING IOCTLs. > > > > Let's instead design the ioctl in a way that doesn't require compat > > handling. > > > > Care to explain what makes this ioctl require a compat version? I > don't see assumptions on the word length on the implementation. What > am I missing? The size of the "routes" pointer isn't constant, therefore affecting the memory layout of the struct (and thus requiring compat code). It should be __u64. (Please see my other reply to the same patch.)
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c index 6481212fda772c73..83af332763f41a6b 100644 --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c @@ -1045,6 +1045,66 @@ static int put_v4l2_event32(struct v4l2_event __user *p64, return 0; } +struct v4l2_subdev_routing32 { + compat_caddr_t routes; + __u32 num_routes; + __u32 reserved[5]; +}; + +static int get_v4l2_subdev_routing(struct v4l2_subdev_routing __user *p64, + struct v4l2_subdev_routing32 __user *p32) +{ + struct v4l2_subdev_route __user *routes; + compat_caddr_t p; + u32 num_routes; + + if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) || + get_user(p, &p32->routes) || + get_user(num_routes, &p32->num_routes) || + put_user(num_routes, &p64->num_routes) || + copy_in_user(&p64->reserved, &p32->reserved, + sizeof(p64->reserved)) || + num_routes > U32_MAX / sizeof(*p64->routes)) + return -EFAULT; + + routes = compat_ptr(p); + + if (!access_ok(VERIFY_READ, routes, + num_routes * sizeof(*p64->routes))) + return -EFAULT; + + if (put_user((__force struct v4l2_subdev_route *)routes, + &p64->routes)) + return -EFAULT; + + return 0; +} + +static int put_v4l2_subdev_routing(struct v4l2_subdev_routing __user *p64, + struct v4l2_subdev_routing32 __user *p32) +{ + struct v4l2_subdev_route __user *routes; + compat_caddr_t p; + u32 num_routes; + + if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) || + get_user(p, &p32->routes) || + get_user(num_routes, &p64->num_routes) || + put_user(num_routes, &p32->num_routes) || + copy_in_user(&p32->reserved, &p64->reserved, + sizeof(p64->reserved)) || + num_routes > U32_MAX / sizeof(*p64->routes)) + return -EFAULT; + + routes = compat_ptr(p); + + if (!access_ok(VERIFY_WRITE, routes, + num_routes * sizeof(*p64->routes))) + return -EFAULT; + + return 0; +} + struct v4l2_edid32 { __u32 pad; __u32 start_block; @@ -1117,6 +1177,8 @@ static int put_v4l2_edid32(struct v4l2_edid __user *p64, #define VIDIOC_STREAMOFF32 _IOW ('V', 19, s32) #define VIDIOC_G_INPUT32 _IOR ('V', 38, s32) #define VIDIOC_S_INPUT32 _IOWR('V', 39, s32) +#define VIDIOC_SUBDEV_G_ROUTING32 _IOWR('V', 38, struct v4l2_subdev_routing32) +#define VIDIOC_SUBDEV_S_ROUTING32 _IOWR('V', 39, struct v4l2_subdev_routing32) #define VIDIOC_G_OUTPUT32 _IOR ('V', 46, s32) #define VIDIOC_S_OUTPUT32 _IOWR('V', 47, s32) @@ -1195,6 +1257,8 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar case VIDIOC_STREAMOFF32: cmd = VIDIOC_STREAMOFF; break; case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break; case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break; + case VIDIOC_SUBDEV_G_ROUTING32: cmd = VIDIOC_SUBDEV_G_ROUTING; break; + case VIDIOC_SUBDEV_S_ROUTING32: cmd = VIDIOC_SUBDEV_S_ROUTING; break; case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break; case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break; case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break; @@ -1227,6 +1291,15 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar compatible_arg = 0; break; + case VIDIOC_SUBDEV_G_ROUTING: + case VIDIOC_SUBDEV_S_ROUTING: + err = alloc_userspace(sizeof(struct v4l2_subdev_routing), + 0, &new_p64); + if (!err) + err = get_v4l2_subdev_routing(new_p64, p32); + compatible_arg = 0; + break; + case VIDIOC_G_EDID: case VIDIOC_S_EDID: err = alloc_userspace(sizeof(struct v4l2_edid), 0, &new_p64); @@ -1368,6 +1441,10 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar if (put_v4l2_edid32(new_p64, p32)) err = -EFAULT; break; + case VIDIOC_SUBDEV_G_ROUTING: + case VIDIOC_SUBDEV_S_ROUTING: + err = put_v4l2_subdev_routing(new_p64, p32); + break; } if (err) return err;