[PATCH 3/3] i2c_tools: Read all data in both block reads

Olliver Schinagl oliver+busybox at schinagl.nl
Fri May 12 08:35:25 UTC 2023


From: Olliver Schinagl <oliver at schinagl.nl>

The difference between I2C_SMBUS_BLOCK_DATA and I2C_SMBUS_I2C_BLOCK_DATA
is that one takes as an argument, the number of bytes to read, whereas
the other has an (internal) fixed block size.

Both however are expected to return the number of bytes read into the
buffer, as both functions do `return data.block[0];`.

As such, there is nothing preventing us from using the same logic for
both calls.

Signed-off-by: Olliver Schinagl <oliver at schinagl.nl>
---
 miscutils/i2c_tools.c | 47 ++++++++++++++++++-------------------------
 1 file changed, 20 insertions(+), 27 deletions(-)

diff --git a/miscutils/i2c_tools.c b/miscutils/i2c_tools.c
index 166c9f6bb..135bd7d7d 100644
--- a/miscutils/i2c_tools.c
+++ b/miscutils/i2c_tools.c
@@ -768,35 +768,26 @@ int i2cset_main(int argc, char **argv)
 static int read_block_data(int buf_fd, int mode, int *block)
 {
 	uint8_t cblock[I2C_SMBUS_BLOCK_MAX + I2CDUMP_NUM_REGS];
-	int res, blen = 0, tmp, i;
+	int res, blen = 0;
+
+	for (res = 0; res < I2CDUMP_NUM_REGS; res += blen) {
+		if (mode == I2C_SMBUS_I2C_BLOCK_DATA)
+			blen = i2c_smbus_read_i2c_block_data(buf_fd, res,
+			                                    I2C_SMBUS_BLOCK_MAX,
+			                                    cblock + res);
+
+		if (mode == I2C_SMBUS_BLOCK_DATA)
+			blen = i2c_smbus_read_block_data(buf_fd, res,
+			                                cblock + res);
 
-	if (mode == I2C_SMBUS_BLOCK_DATA) {
-		blen = i2c_smbus_read_block_data(buf_fd, 0, cblock);
 		if (blen <= 0)
 			goto fail;
-	} else {
-		for (res = 0; res < I2CDUMP_NUM_REGS; res += tmp) {
-			tmp = i2c_smbus_read_i2c_block_data(
-					buf_fd, res, I2C_SMBUS_BLOCK_MAX,
-					cblock + res);
-			if (tmp <= 0) {
-				blen = tmp;
-				goto fail;
-			}
-		}
-
-		if (res >= I2CDUMP_NUM_REGS)
-			res = I2CDUMP_NUM_REGS;
-
-		for (i = 0; i < res; i++)
-			block[i] = cblock[i];
-
-		if (mode != I2C_SMBUS_BLOCK_DATA)
-			for (i = res; i < I2CDUMP_NUM_REGS; i++)
-				block[i] = -1;
 	}
 
-	return blen;
+	for (int i = 0; i < ((res >= I2CDUMP_NUM_REGS) ? I2CDUMP_NUM_REGS : res); i++)
+		block[i] = cblock[i];
+
+	return res;
 
  fail:
 	bb_error_msg_and_die("block read failed: %d", blen);
@@ -812,7 +803,8 @@ static void dump_data(int bus_fd, int mode, unsigned first,
 	     "    0123456789abcdef");
 
 	for (i = 0; i < I2CDUMP_NUM_REGS; i += 0x10) {
-		if (mode == I2C_SMBUS_BLOCK_DATA && i >= blen)
+		if ((mode == I2C_SMBUS_BLOCK_DATA || mode == I2C_SMBUS_I2C_BLOCK_DATA) &&
+		    i >= blen)
 			break;
 		if (i/16 < first/16)
 			continue;
@@ -855,7 +847,7 @@ static void dump_data(int bus_fd, int mode, unsigned first,
 				res = block[i+j];
 			}
 
-			if (mode == I2C_SMBUS_BLOCK_DATA &&
+			if ((mode == I2C_SMBUS_BLOCK_DATA || mode == I2C_SMBUS_I2C_BLOCK_DATA) &&
 			    i+j >= blen) {
 				printf("   ");
 			} else if (res < 0) {
@@ -874,7 +866,8 @@ static void dump_data(int bus_fd, int mode, unsigned first,
 		printf("   ");
 
 		for (j = 0; j < 16; j++) {
-			if (mode == I2C_SMBUS_BLOCK_DATA && i+j >= blen)
+			if ((mode == I2C_SMBUS_BLOCK_DATA || mode == I2C_SMBUS_I2C_BLOCK_DATA) &&
+			    i+j >= blen)
 				break;
 			/* Skip unwanted registers */
 			if (i+j < first || i+j > last) {
-- 
2.40.1



More information about the busybox mailing list