diff options
Diffstat (limited to 'drivers/media/v4l2-core/v4l2-subdev.c')
| -rw-r--r-- | drivers/media/v4l2-core/v4l2-subdev.c | 125 | 
1 files changed, 79 insertions, 46 deletions
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 058c1a6e8392..b4d235c13fbf 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -126,6 +126,57 @@ static int subdev_close(struct file *file)  	return 0;  } +#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) +static int check_format(struct v4l2_subdev *sd, +			struct v4l2_subdev_format *format) +{ +	if (format->which != V4L2_SUBDEV_FORMAT_TRY && +	    format->which != V4L2_SUBDEV_FORMAT_ACTIVE) +		return -EINVAL; + +	if (format->pad >= sd->entity.num_pads) +		return -EINVAL; + +	return 0; +} + +static int check_crop(struct v4l2_subdev *sd, struct v4l2_subdev_crop *crop) +{ +	if (crop->which != V4L2_SUBDEV_FORMAT_TRY && +	    crop->which != V4L2_SUBDEV_FORMAT_ACTIVE) +		return -EINVAL; + +	if (crop->pad >= sd->entity.num_pads) +		return -EINVAL; + +	return 0; +} + +static int check_selection(struct v4l2_subdev *sd, +			   struct v4l2_subdev_selection *sel) +{ +	if (sel->which != V4L2_SUBDEV_FORMAT_TRY && +	    sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) +		return -EINVAL; + +	if (sel->pad >= sd->entity.num_pads) +		return -EINVAL; + +	return 0; +} + +static int check_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid) +{ +	if (edid->pad >= sd->entity.num_pads) +		return -EINVAL; + +	if (edid->blocks && edid->edid == NULL) +		return -EINVAL; + +	return 0; +} +#endif +  static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)  {  	struct video_device *vdev = video_devdata(file); @@ -133,12 +184,16 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)  	struct v4l2_fh *vfh = file->private_data;  #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)  	struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh); +	int rval;  #endif  	switch (cmd) {  	case VIDIOC_QUERYCTRL:  		return v4l2_queryctrl(vfh->ctrl_handler, arg); +	case VIDIOC_QUERY_EXT_CTRL: +		return v4l2_query_ext_ctrl(vfh->ctrl_handler, arg); +  	case VIDIOC_QUERYMENU:  		return v4l2_querymenu(vfh->ctrl_handler, arg); @@ -203,12 +258,9 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)  	case VIDIOC_SUBDEV_G_FMT: {  		struct v4l2_subdev_format *format = arg; -		if (format->which != V4L2_SUBDEV_FORMAT_TRY && -		    format->which != V4L2_SUBDEV_FORMAT_ACTIVE) -			return -EINVAL; - -		if (format->pad >= sd->entity.num_pads) -			return -EINVAL; +		rval = check_format(sd, format); +		if (rval) +			return rval;  		return v4l2_subdev_call(sd, pad, get_fmt, subdev_fh, format);  	} @@ -216,12 +268,9 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)  	case VIDIOC_SUBDEV_S_FMT: {  		struct v4l2_subdev_format *format = arg; -		if (format->which != V4L2_SUBDEV_FORMAT_TRY && -		    format->which != V4L2_SUBDEV_FORMAT_ACTIVE) -			return -EINVAL; - -		if (format->pad >= sd->entity.num_pads) -			return -EINVAL; +		rval = check_format(sd, format); +		if (rval) +			return rval;  		return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh, format);  	} @@ -229,14 +278,10 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)  	case VIDIOC_SUBDEV_G_CROP: {  		struct v4l2_subdev_crop *crop = arg;  		struct v4l2_subdev_selection sel; -		int rval; - -		if (crop->which != V4L2_SUBDEV_FORMAT_TRY && -		    crop->which != V4L2_SUBDEV_FORMAT_ACTIVE) -			return -EINVAL; -		if (crop->pad >= sd->entity.num_pads) -			return -EINVAL; +		rval = check_crop(sd, crop); +		if (rval) +			return rval;  		rval = v4l2_subdev_call(sd, pad, get_crop, subdev_fh, crop);  		if (rval != -ENOIOCTLCMD) @@ -258,14 +303,10 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)  	case VIDIOC_SUBDEV_S_CROP: {  		struct v4l2_subdev_crop *crop = arg;  		struct v4l2_subdev_selection sel; -		int rval; - -		if (crop->which != V4L2_SUBDEV_FORMAT_TRY && -		    crop->which != V4L2_SUBDEV_FORMAT_ACTIVE) -			return -EINVAL; -		if (crop->pad >= sd->entity.num_pads) -			return -EINVAL; +		rval = check_crop(sd, crop); +		if (rval) +			return rval;  		rval = v4l2_subdev_call(sd, pad, set_crop, subdev_fh, crop);  		if (rval != -ENOIOCTLCMD) @@ -336,12 +377,9 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)  	case VIDIOC_SUBDEV_G_SELECTION: {  		struct v4l2_subdev_selection *sel = arg; -		if (sel->which != V4L2_SUBDEV_FORMAT_TRY && -		    sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) -			return -EINVAL; - -		if (sel->pad >= sd->entity.num_pads) -			return -EINVAL; +		rval = check_selection(sd, sel); +		if (rval) +			return rval;  		return v4l2_subdev_call(  			sd, pad, get_selection, subdev_fh, sel); @@ -350,12 +388,9 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)  	case VIDIOC_SUBDEV_S_SELECTION: {  		struct v4l2_subdev_selection *sel = arg; -		if (sel->which != V4L2_SUBDEV_FORMAT_TRY && -		    sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) -			return -EINVAL; - -		if (sel->pad >= sd->entity.num_pads) -			return -EINVAL; +		rval = check_selection(sd, sel); +		if (rval) +			return rval;  		return v4l2_subdev_call(  			sd, pad, set_selection, subdev_fh, sel); @@ -364,10 +399,9 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)  	case VIDIOC_G_EDID: {  		struct v4l2_subdev_edid *edid = arg; -		if (edid->pad >= sd->entity.num_pads) -			return -EINVAL; -		if (edid->blocks && edid->edid == NULL) -			return -EINVAL; +		rval = check_edid(sd, edid); +		if (rval) +			return rval;  		return v4l2_subdev_call(sd, pad, get_edid, edid);  	} @@ -375,10 +409,9 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)  	case VIDIOC_S_EDID: {  		struct v4l2_subdev_edid *edid = arg; -		if (edid->pad >= sd->entity.num_pads) -			return -EINVAL; -		if (edid->blocks && edid->edid == NULL) -			return -EINVAL; +		rval = check_edid(sd, edid); +		if (rval) +			return rval;  		return v4l2_subdev_call(sd, pad, set_edid, edid);  	}  |