Besides not being understandable at the first glance, the code
might provoke a compiler or a static analyser tool to warn about
out-of-bound access (when len == 0).
Replace it with clear flow an understandable intention.
Signed-off-by: Andy Shevchenko <[email protected]>
---
drivers/media/i2c/ov2740.c | 28 +++++++++++++++++++++++-----
1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c
index c975db1bbe8c..81c0ab220339 100644
--- a/drivers/media/i2c/ov2740.c
+++ b/drivers/media/i2c/ov2740.c
@@ -377,10 +377,10 @@ static int ov2740_read_reg(struct ov2740 *ov2740, u16 reg, u16 len, u32 *val)
struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd);
struct i2c_msg msgs[2];
u8 addr_buf[2];
- u8 data_buf[4] = {0};
+ u8 data_buf[4];
int ret = 0;
- if (len > sizeof(data_buf))
+ if (len > 4)
return -EINVAL;
put_unaligned_be16(reg, addr_buf);
@@ -391,13 +391,22 @@ static int ov2740_read_reg(struct ov2740 *ov2740, u16 reg, u16 len, u32 *val)
msgs[1].addr = client->addr;
msgs[1].flags = I2C_M_RD;
msgs[1].len = len;
- msgs[1].buf = &data_buf[sizeof(data_buf) - len];
+ msgs[1].buf = data_buf;
ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
if (ret != ARRAY_SIZE(msgs))
return ret < 0 ? ret : -EIO;
- *val = get_unaligned_be32(data_buf);
+ if (len == 4)
+ *val = get_unaligned_be32(data_buf);
+ else if (len == 3)
+ *val = get_unaligned_be24(data_buf);
+ else if (len == 2)
+ *val = get_unaligned_be16(data_buf);
+ else if (len == 1)
+ *val = data_buf[0];
+ else
+ return -EINVAL;
return 0;
}
@@ -412,7 +421,16 @@ static int ov2740_write_reg(struct ov2740 *ov2740, u16 reg, u16 len, u32 val)
return -EINVAL;
put_unaligned_be16(reg, buf);
- put_unaligned_be32(val << 8 * (4 - len), buf + 2);
+ if (len == 4)
+ put_unaligned_be32(val, buf + 2);
+ else if (len == 3)
+ put_unaligned_be24(val, buf + 2);
+ else if (len == 2)
+ put_unaligned_be16(val, buf + 2);
+ else if (len == 1)
+ buf[2] = val;
+ else
+ return -EINVAL;
ret = i2c_master_send(client, buf, len + 2);
if (ret != len + 2)
--
2.35.1
Andy,
Thanks for your patch.
Although I am not familiar with the voodoo programming, it looks
good for me.
Reviewed-by: Bingbu Cao <[email protected]>
________________________
BRs,
Bingbu Cao
> -----Original Message-----
> From: Andy Shevchenko <[email protected]>
> Sent: Tuesday, July 26, 2022 8:06 PM
> To: Andy Shevchenko <[email protected]>; linux-
> [email protected]; [email protected]
> Cc: Qiu, Tian Shu <[email protected]>; Tu, ShawnX
> <[email protected]>; Cao, Bingbu <[email protected]>; Mauro Carvalho
> Chehab <[email protected]>
> Subject: [PATCH v1 2/8] media: ov2740: Replace voodoo coding with
> understandle flow
>
> Besides not being understandable at the first glance, the code might
> provoke a compiler or a static analyser tool to warn about out-of-bound
> access (when len == 0).
>
> Replace it with clear flow an understandable intention.
>
> Signed-off-by: Andy Shevchenko <[email protected]>
> ---
> drivers/media/i2c/ov2740.c | 28 +++++++++++++++++++++++-----
> 1 file changed, 23 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c index
> c975db1bbe8c..81c0ab220339 100644
> --- a/drivers/media/i2c/ov2740.c
> +++ b/drivers/media/i2c/ov2740.c
> @@ -377,10 +377,10 @@ static int ov2740_read_reg(struct ov2740 *ov2740,
> u16 reg, u16 len, u32 *val)
> struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd);
> struct i2c_msg msgs[2];
> u8 addr_buf[2];
> - u8 data_buf[4] = {0};
> + u8 data_buf[4];
> int ret = 0;
>
> - if (len > sizeof(data_buf))
> + if (len > 4)
> return -EINVAL;
>
> put_unaligned_be16(reg, addr_buf);
> @@ -391,13 +391,22 @@ static int ov2740_read_reg(struct ov2740 *ov2740,
> u16 reg, u16 len, u32 *val)
> msgs[1].addr = client->addr;
> msgs[1].flags = I2C_M_RD;
> msgs[1].len = len;
> - msgs[1].buf = &data_buf[sizeof(data_buf) - len];
> + msgs[1].buf = data_buf;
>
> ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
> if (ret != ARRAY_SIZE(msgs))
> return ret < 0 ? ret : -EIO;
>
> - *val = get_unaligned_be32(data_buf);
> + if (len == 4)
> + *val = get_unaligned_be32(data_buf);
> + else if (len == 3)
> + *val = get_unaligned_be24(data_buf);
> + else if (len == 2)
> + *val = get_unaligned_be16(data_buf);
> + else if (len == 1)
> + *val = data_buf[0];
> + else
> + return -EINVAL;
>
> return 0;
> }
> @@ -412,7 +421,16 @@ static int ov2740_write_reg(struct ov2740 *ov2740,
> u16 reg, u16 len, u32 val)
> return -EINVAL;
>
> put_unaligned_be16(reg, buf);
> - put_unaligned_be32(val << 8 * (4 - len), buf + 2);
> + if (len == 4)
> + put_unaligned_be32(val, buf + 2);
> + else if (len == 3)
> + put_unaligned_be24(val, buf + 2);
> + else if (len == 2)
> + put_unaligned_be16(val, buf + 2);
> + else if (len == 1)
> + buf[2] = val;
> + else
> + return -EINVAL;
>
> ret = i2c_master_send(client, buf, len + 2);
> if (ret != len + 2)
> --
> 2.35.1
On Fri, Nov 11, 2022 at 05:02:22PM +0200, Sakari Ailus wrote:
> Hi Andy,
>
> On Tue, Jul 26, 2022 at 03:05:50PM +0300, Andy Shevchenko wrote:
> > Besides not being understandable at the first glance, the code
> > might provoke a compiler or a static analyser tool to warn about
> > out-of-bound access (when len == 0).
>
> I've never seen one.
>
> However the same pattern is repeatedly used by many, many drivers and
> addressing just one doesn't make much sense.
>
> The proper way to fix this would be to have a set of common CCI (Camera
> Control Interface) functions that all drivers could use, and then switch
> the drivers to use them.
>
> This isn't currently a great fit for e.g. regmap but perhaps something
> light on top of regmap-i2c could do the trick?
So, then we can skip this one, right?
> The rest of the set seems good to me.
Thank you for the review, can you apply them, or should I send a v2 with
dropped first patch?
--
With Best Regards,
Andy Shevchenko
Hi Andy,
On Tue, Jul 26, 2022 at 03:05:50PM +0300, Andy Shevchenko wrote:
> Besides not being understandable at the first glance, the code
> might provoke a compiler or a static analyser tool to warn about
> out-of-bound access (when len == 0).
I've never seen one.
However the same pattern is repeatedly used by many, many drivers and
addressing just one doesn't make much sense.
The proper way to fix this would be to have a set of common CCI (Camera
Control Interface) functions that all drivers could use, and then switch
the drivers to use them.
This isn't currently a great fit for e.g. regmap but perhaps something
light on top of regmap-i2c could do the trick?
The rest of the set seems good to me.
--
Kind regards,
Sakari Ailus
On Fri, Nov 11, 2022 at 05:30:09PM +0200, Andy Shevchenko wrote:
> On Fri, Nov 11, 2022 at 05:02:22PM +0200, Sakari Ailus wrote:
> > Hi Andy,
> >
> > On Tue, Jul 26, 2022 at 03:05:50PM +0300, Andy Shevchenko wrote:
> > > Besides not being understandable at the first glance, the code
> > > might provoke a compiler or a static analyser tool to warn about
> > > out-of-bound access (when len == 0).
> >
> > I've never seen one.
> >
> > However the same pattern is repeatedly used by many, many drivers and
> > addressing just one doesn't make much sense.
> >
> > The proper way to fix this would be to have a set of common CCI (Camera
> > Control Interface) functions that all drivers could use, and then switch
> > the drivers to use them.
> >
> > This isn't currently a great fit for e.g. regmap but perhaps something
> > light on top of regmap-i2c could do the trick?
>
> So, then we can skip this one, right?
Yes.
>
> > The rest of the set seems good to me.
>
> Thank you for the review, can you apply them, or should I send a v2 with
> dropped first patch?
Already done. I'm still doing more testing before pushing.
Thanks!
--
Sakari Ailus