Commit fcae73fa authored by Mats Randgaard's avatar Mats Randgaard Committed by Mauro Carvalho Chehab

[media] tc358743: Use local array with fixed size in i2c write

i2c_wr() is called from ops and the interrupt service routine, while
state->wr_data is shared and unprotected, and could be overwritten.

This shared buffer is therefore replaced with a local array with fixed
size. The array has the size of one EDID block (128 bytes) + 2 bytes
i2c address, and the EDID is written block by block (up to 8 blocks).
Signed-off-by: default avatarMats Randgaard <matrandg@cisco.com>
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent 8e20b803
...@@ -59,8 +59,7 @@ MODULE_LICENSE("GPL"); ...@@ -59,8 +59,7 @@ MODULE_LICENSE("GPL");
#define EDID_NUM_BLOCKS_MAX 8 #define EDID_NUM_BLOCKS_MAX 8
#define EDID_BLOCK_SIZE 128 #define EDID_BLOCK_SIZE 128
/* Max transfer size done by I2C transfer functions */ #define I2C_MAX_XFER_SIZE (EDID_BLOCK_SIZE + 2)
#define MAX_XFER_SIZE (EDID_NUM_BLOCKS_MAX * EDID_BLOCK_SIZE + 2)
static const struct v4l2_dv_timings_cap tc358743_timings_cap = { static const struct v4l2_dv_timings_cap tc358743_timings_cap = {
.type = V4L2_DV_BT_656_1120, .type = V4L2_DV_BT_656_1120,
...@@ -97,9 +96,6 @@ struct tc358743_state { ...@@ -97,9 +96,6 @@ struct tc358743_state {
/* edid */ /* edid */
u8 edid_blocks_written; u8 edid_blocks_written;
/* used by i2c_wr() */
u8 wr_data[MAX_XFER_SIZE];
struct v4l2_dv_timings timings; struct v4l2_dv_timings timings;
u32 mbus_fmt_code; u32 mbus_fmt_code;
...@@ -149,13 +145,15 @@ static void i2c_wr(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n) ...@@ -149,13 +145,15 @@ static void i2c_wr(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n)
{ {
struct tc358743_state *state = to_state(sd); struct tc358743_state *state = to_state(sd);
struct i2c_client *client = state->i2c_client; struct i2c_client *client = state->i2c_client;
u8 *data = state->wr_data;
int err, i; int err, i;
struct i2c_msg msg; struct i2c_msg msg;
u8 data[I2C_MAX_XFER_SIZE];
if ((2 + n) > sizeof(state->wr_data)) if ((2 + n) > I2C_MAX_XFER_SIZE) {
n = I2C_MAX_XFER_SIZE - 2;
v4l2_warn(sd, "i2c wr reg=%04x: len=%d is too big!\n", v4l2_warn(sd, "i2c wr reg=%04x: len=%d is too big!\n",
reg, 2 + n); reg, 2 + n);
}
msg.addr = client->addr; msg.addr = client->addr;
msg.buf = data; msg.buf = data;
...@@ -1582,6 +1580,7 @@ static int tc358743_s_edid(struct v4l2_subdev *sd, ...@@ -1582,6 +1580,7 @@ static int tc358743_s_edid(struct v4l2_subdev *sd,
{ {
struct tc358743_state *state = to_state(sd); struct tc358743_state *state = to_state(sd);
u16 edid_len = edid->blocks * EDID_BLOCK_SIZE; u16 edid_len = edid->blocks * EDID_BLOCK_SIZE;
int i;
v4l2_dbg(2, debug, sd, "%s, pad %d, start block %d, blocks %d\n", v4l2_dbg(2, debug, sd, "%s, pad %d, start block %d, blocks %d\n",
__func__, edid->pad, edid->start_block, edid->blocks); __func__, edid->pad, edid->start_block, edid->blocks);
...@@ -1607,7 +1606,8 @@ static int tc358743_s_edid(struct v4l2_subdev *sd, ...@@ -1607,7 +1606,8 @@ static int tc358743_s_edid(struct v4l2_subdev *sd,
return 0; return 0;
} }
i2c_wr(sd, EDID_RAM, edid->edid, edid_len); for (i = 0; i < edid_len; i += EDID_BLOCK_SIZE)
i2c_wr(sd, EDID_RAM + i, edid->edid + i, EDID_BLOCK_SIZE);
state->edid_blocks_written = edid->blocks; state->edid_blocks_written = edid->blocks;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment