smbpbi: Optimize i2cReadDataBytes using combined ioctl transaction

Refactor i2cReadDataBytes to perform a single ioctl call that combines
both I2C write and read operations into one atomic transaction.

This change avoid race conditions when multiple sensors are queried at
same time.

Change-Id: Id30e25560c3dfba6d5eec87efde2a1cc3b554f8d
Signed-off-by: Potin Lai <potin.lai@quantatw.com>
diff --git a/src/smbpbi/SmbpbiSensor.cpp b/src/smbpbi/SmbpbiSensor.cpp
index 238cbcf..e0610fe 100644
--- a/src/smbpbi/SmbpbiSensor.cpp
+++ b/src/smbpbi/SmbpbiSensor.cpp
@@ -232,28 +232,34 @@
 
     int ret = 0;
     struct i2c_rdwr_ioctl_data args = {nullptr, 0};
-    struct i2c_msg msg = {0, 0, 0, nullptr};
+    std::array<struct i2c_msg, 2> msgs = {
+        {{0, 0, 0, nullptr}, {0, 0, 0, nullptr}}};
     std::array<uint8_t, 8> cmd{};
 
-    msg.addr = addr;
-    args.msgs = &msg;
-    args.nmsgs = 1;
+    args.msgs = msgs.data();
+    args.nmsgs = msgs.size();
 
-    msg.flags = 0;
-    msg.buf = cmd.data();
+    msgs[0].addr = addr;
+    msgs[0].flags = 0;
+    msgs[0].buf = cmd.data();
     // handle two bytes offset
     if (offset > 255)
     {
-        msg.len = 2;
-        msg.buf[0] = offset >> 8;
-        msg.buf[1] = offset & 0xFF;
+        msgs[0].len = 2;
+        msgs[0].buf[0] = offset >> 8;
+        msgs[0].buf[1] = offset & 0xFF;
     }
     else
     {
-        msg.len = 1;
-        msg.buf[0] = offset & 0xFF;
+        msgs[0].len = 1;
+        msgs[0].buf[0] = offset & 0xFF;
     }
 
+    msgs[1].addr = addr;
+    msgs[1].flags = I2C_M_RD;
+    msgs[1].len = length;
+    msgs[1].buf = reading;
+
     // write offset
     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
     ret = ioctl(fd, I2C_RDWR, &args);
@@ -261,17 +267,6 @@
     {
         return ret;
     }
-
-    msg.flags = I2C_M_RD;
-    msg.len = length;
-    msg.buf = reading;
-
-    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
-    ret = ioctl(fd, I2C_RDWR, &args);
-    if (ret < 0)
-    {
-        return ret;
-    }
     return 0;
 }