[media] s5k5baf: allow to handle arbitrary long i2c sequences
Using variable length array in s5k5baf_write_arr_seq caused an implicit assumption that i2c sequences should be short. The patch rewrites the function so it can handle sequences of any length and does not use variable length array. Reported-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Andrzej Hajda <a.hajda@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
This commit is contained in:
parent
c29b8f3149
commit
7e8f15c5aa
|
@ -478,25 +478,33 @@ static void s5k5baf_write_arr_seq(struct s5k5baf *state, u16 addr,
|
|||
u16 count, const u16 *seq)
|
||||
{
|
||||
struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
|
||||
__be16 buf[count + 1];
|
||||
int ret, n;
|
||||
__be16 buf[65];
|
||||
|
||||
s5k5baf_i2c_write(state, REG_CMDWR_ADDR, addr);
|
||||
if (state->error)
|
||||
return;
|
||||
|
||||
buf[0] = __constant_cpu_to_be16(REG_CMD_BUF);
|
||||
for (n = 1; n <= count; ++n)
|
||||
buf[n] = cpu_to_be16(*seq++);
|
||||
|
||||
n *= 2;
|
||||
ret = i2c_master_send(c, (char *)buf, n);
|
||||
v4l2_dbg(3, debug, c, "i2c_write_seq(count=%d): %*ph\n", count,
|
||||
min(2 * count, 64), seq - count);
|
||||
min(2 * count, 64), seq);
|
||||
|
||||
if (ret != n) {
|
||||
v4l2_err(c, "i2c_write_seq: error during transfer (%d)\n", ret);
|
||||
state->error = ret;
|
||||
buf[0] = __constant_cpu_to_be16(REG_CMD_BUF);
|
||||
|
||||
while (count > 0) {
|
||||
int n = min_t(int, count, ARRAY_SIZE(buf) - 1);
|
||||
int ret, i;
|
||||
|
||||
for (i = 1; i <= n; ++i)
|
||||
buf[i] = cpu_to_be16(*seq++);
|
||||
|
||||
i *= 2;
|
||||
ret = i2c_master_send(c, (char *)buf, i);
|
||||
if (ret != i) {
|
||||
v4l2_err(c, "i2c_write_seq: error during transfer (%d)\n", ret);
|
||||
state->error = ret;
|
||||
break;
|
||||
}
|
||||
|
||||
count -= n;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue