> * Allocated bit 4 (I2C_SMBUS3_BLOCK=0x10), to simplify Smbus2 > compatibility: I2C_SMBUS_*BLOCK* = (|0x10) I think the code becomes easier to understand, if we use new transfer types a bit more explicitly. Also, I am not sure of the extra bit because it is not clearly visible that types >= 16 and <= 31 will have a special meaning. We could do like this if we sacrifice one number for an unused BROKEN with 255 byte: -#define I2C_SMBUS_BLOCK_DATA 5 +#define I2C_SMBUS2_BLOCK_DATA 5 /* 32 byte only, deprecated */ -#define I2C_SMBUS_I2C_BLOCK_BROKEN 6 +#define I2C_SMBUS2_I2C_BLOCK_BROKEN 6 /* 32 byte only, deprecated */ -#define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */ +#define I2C_SMBUS2_BLOCK_PROC_CALL 7 /* SMBus 2.0, 32 byte only, deprecated */ -#define I2C_SMBUS_I2C_BLOCK_DATA 8 +#define I2C_SMBUS2_I2C_BLOCK_DATA 8 /* 32 byte only, deprecated */ +#define I2C_SMBUS_BLOCK_DATA 9 +#define I2C_SMBUS_I2C_BLOCK_BROKEN 10 /* FIXME: probably say "don't use" here +#define I2C_SMBUS_BLOCK_PROC_CALL 11 /* SMBus >= 2.0 */ +#define I2C_SMBUS_I2C_BLOCK_DATA 12 > > + user_len = kmalloc_array(nmsgs, sizeof(*user_len), GFP_KERNEL); > + if (!user_len) { > + res = -ENOMEM; > + goto out; > + } Maybe on stack? I2C_RDWR_IOCTL_MAX_MSGS will ensure this will stay at a sane value. > @@ -313,7 +357,19 @@ static noinline int i2cdev_ioctl_smbus(struct i2c_client *client, > union i2c_smbus_data __user *data) > { > union i2c_smbus_data temp = {}; > - int datasize, res; > + int block_max, datasize, res; > + 'size' is really a misleading name :( + if (size <= I2C_SMBUS2_I2C_BLOCK_DATA) { + if (size >= I2C_SMBUS2_BLOCK_DATA) + size += I2C_SMBUS_BLOCK_DATA - I2C_SMBUS2_BLOCK_DATA; + block_max = I2C_SMBUS_BLOCK_MAX; + } else { + block_max = I2C_SMBUS3_BLOCK_MAX; + } Would this work, too?