mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 16:53:20 -04:00
media: go7007: s2250: propagate control I/O failures
The brightness and contrast paths use oldvalue after read_reg_fp() without checking whether the read succeeded. A failed read leaves oldvalue uninitialized and can write arbitrary reserved register bits. Return read and write errors from every control path so failed hardware access cannot be reported as a successful control update. Signed-off-by: Yousef Alhouseen <alhouseenyousef@gmail.com> Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
This commit is contained in:
committed by
Hans Verkuil
parent
e260d1d771
commit
59dc14a6cb
@@ -365,36 +365,48 @@ static int s2250_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
struct s2250 *state = container_of(ctrl->handler, struct s2250, hdl);
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&state->sd);
|
||||
u16 oldvalue;
|
||||
int ret;
|
||||
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_BRIGHTNESS:
|
||||
read_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, &oldvalue);
|
||||
write_reg_fp(client, VPX322_ADDR_BRIGHTNESS0,
|
||||
ctrl->val | (oldvalue & ~0xff));
|
||||
read_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, &oldvalue);
|
||||
write_reg_fp(client, VPX322_ADDR_BRIGHTNESS1,
|
||||
ctrl->val | (oldvalue & ~0xff));
|
||||
write_reg_fp(client, 0x140, 0x60);
|
||||
break;
|
||||
ret = read_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, &oldvalue);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = write_reg_fp(client, VPX322_ADDR_BRIGHTNESS0,
|
||||
ctrl->val | (oldvalue & ~0xff));
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = read_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, &oldvalue);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = write_reg_fp(client, VPX322_ADDR_BRIGHTNESS1,
|
||||
ctrl->val | (oldvalue & ~0xff));
|
||||
if (ret)
|
||||
return ret;
|
||||
return write_reg_fp(client, 0x140, 0x60);
|
||||
case V4L2_CID_CONTRAST:
|
||||
read_reg_fp(client, VPX322_ADDR_CONTRAST0, &oldvalue);
|
||||
write_reg_fp(client, VPX322_ADDR_CONTRAST0,
|
||||
ctrl->val | (oldvalue & ~0x3f));
|
||||
read_reg_fp(client, VPX322_ADDR_CONTRAST1, &oldvalue);
|
||||
write_reg_fp(client, VPX322_ADDR_CONTRAST1,
|
||||
ctrl->val | (oldvalue & ~0x3f));
|
||||
write_reg_fp(client, 0x140, 0x60);
|
||||
break;
|
||||
ret = read_reg_fp(client, VPX322_ADDR_CONTRAST0, &oldvalue);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = write_reg_fp(client, VPX322_ADDR_CONTRAST0,
|
||||
ctrl->val | (oldvalue & ~0x3f));
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = read_reg_fp(client, VPX322_ADDR_CONTRAST1, &oldvalue);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = write_reg_fp(client, VPX322_ADDR_CONTRAST1,
|
||||
ctrl->val | (oldvalue & ~0x3f));
|
||||
if (ret)
|
||||
return ret;
|
||||
return write_reg_fp(client, 0x140, 0x60);
|
||||
case V4L2_CID_SATURATION:
|
||||
write_reg_fp(client, VPX322_ADDR_SAT, ctrl->val);
|
||||
break;
|
||||
return write_reg_fp(client, VPX322_ADDR_SAT, ctrl->val);
|
||||
case V4L2_CID_HUE:
|
||||
write_reg_fp(client, VPX322_ADDR_HUE, ctrl->val);
|
||||
break;
|
||||
return write_reg_fp(client, VPX322_ADDR_HUE, ctrl->val);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s2250_set_fmt(struct v4l2_subdev *sd,
|
||||
|
||||
Reference in New Issue
Block a user