[v1,2/8] media: ov2740: Replace voodoo coding with understandle flow

Message ID 20220726120556.2881-2-andriy.shevchenko@linux.intel.com (mailing list archive)
State New
Delegated to: Sakari Ailus
Headers
Series [v1,1/8] media: ov2740: Remove duplicative pointer in struct nvm_data |

Commit Message

Andy Shevchenko July 26, 2022, 12:05 p.m. UTC
  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 <andriy.shevchenko@linux.intel.com>
---
 drivers/media/i2c/ov2740.c | 28 +++++++++++++++++++++++-----
 1 file changed, 23 insertions(+), 5 deletions(-)
  

Comments

Cao, Bingbu July 27, 2022, 9:52 a.m. UTC | #1
Andy, 

Thanks for your patch.

Although I am not familiar with the voodoo programming, it looks
good for me.

Reviewed-by: Bingbu Cao <bingbu.cao@intel.com>
  
sakari.ailus@iki.fi Nov. 11, 2022, 3:02 p.m. UTC | #2
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.
  
Andy Shevchenko Nov. 11, 2022, 3:30 p.m. UTC | #3
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?
  
sakari.ailus@iki.fi Nov. 11, 2022, 7:46 p.m. UTC | #4
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!
  

Patch

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)