Message ID | 20210112164130.47895-4-wsa+renesas@sang-engineering.com |
---|---|
State | Superseded |
Headers | show |
Series | None | expand |
On Tue, Jan 12, 2021 at 05:41:29PM +0100, Wolfram Sang wrote: > The block-write function of the core was not used because there was no > client-struct to use. However, in this case it seems apropriate to use a > temporary client struct. Because we are answering a request we recieved > when being a client ourselves. So, convert the code to use a temporary > client and use the block-write function of the I2C core. I asked the original authors of this about the change, and apparently is results in a stack size warning. Arnd Bergmann ask for it to be changed from what you are suggesting to what it currently is. See: https://www.lkml.org/lkml/2019/6/19/440 So apparently this change will cause compile warnings due to the size of struct i2c_client. -corey > > Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> > --- > drivers/char/ipmi/ipmb_dev_int.c | 21 ++++++++------------- > 1 file changed, 8 insertions(+), 13 deletions(-) > > diff --git a/drivers/char/ipmi/ipmb_dev_int.c b/drivers/char/ipmi/ipmb_dev_int.c > index 382b28f1cf2f..10d89886e5f3 100644 > --- a/drivers/char/ipmi/ipmb_dev_int.c > +++ b/drivers/char/ipmi/ipmb_dev_int.c > @@ -137,7 +137,7 @@ static ssize_t ipmb_write(struct file *file, const char __user *buf, > { > struct ipmb_dev *ipmb_dev = to_ipmb_dev(file); > u8 rq_sa, netf_rq_lun, msg_len; > - union i2c_smbus_data data; > + struct i2c_client temp_client; > u8 msg[MAX_MSG_LEN]; > ssize_t ret; > > @@ -160,21 +160,16 @@ static ssize_t ipmb_write(struct file *file, const char __user *buf, > } > > /* > - * subtract rq_sa and netf_rq_lun from the length of the msg passed to > - * i2c_smbus_xfer > + * subtract rq_sa and netf_rq_lun from the length of the msg. Fill the > + * temporary client. Note that its use is an exception for IPMI. > */ > msg_len = msg[IPMB_MSG_LEN_IDX] - SMBUS_MSG_HEADER_LENGTH; > - if (msg_len > I2C_SMBUS_BLOCK_MAX) > - msg_len = I2C_SMBUS_BLOCK_MAX; > + memcpy(&temp_client, ipmb_dev->client, sizeof(temp_client)); > + temp_client.addr = rq_sa; > > - data.block[0] = msg_len; > - memcpy(&data.block[1], msg + SMBUS_MSG_IDX_OFFSET, msg_len); > - ret = i2c_smbus_xfer(ipmb_dev->client->adapter, rq_sa, > - ipmb_dev->client->flags, > - I2C_SMBUS_WRITE, netf_rq_lun, > - I2C_SMBUS_BLOCK_DATA, &data); > - > - return ret ? : count; > + ret = i2c_smbus_write_block_data(&temp_client, netf_rq_lun, msg_len, > + msg + SMBUS_MSG_IDX_OFFSET); > + return ret < 0 ? ret : count; > } > > static __poll_t ipmb_poll(struct file *file, poll_table *wait) > -- > 2.29.2 >
> I asked the original authors of this about the change, and apparently is > results in a stack size warning. Arnd Bergmann ask for it to be changed > from what you are suggesting to what it currently is. See: > > https://www.lkml.org/lkml/2019/6/19/440 > > So apparently this change will cause compile warnings due to the size of > struct i2c_client. Wow, didn't know that my patch was actually a revert. I replaced now the stack usage with kmemdup and will have a second thought about this patch. Thanks for the heads up!
diff --git a/drivers/char/ipmi/ipmb_dev_int.c b/drivers/char/ipmi/ipmb_dev_int.c index 382b28f1cf2f..10d89886e5f3 100644 --- a/drivers/char/ipmi/ipmb_dev_int.c +++ b/drivers/char/ipmi/ipmb_dev_int.c @@ -137,7 +137,7 @@ static ssize_t ipmb_write(struct file *file, const char __user *buf, { struct ipmb_dev *ipmb_dev = to_ipmb_dev(file); u8 rq_sa, netf_rq_lun, msg_len; - union i2c_smbus_data data; + struct i2c_client temp_client; u8 msg[MAX_MSG_LEN]; ssize_t ret; @@ -160,21 +160,16 @@ static ssize_t ipmb_write(struct file *file, const char __user *buf, } /* - * subtract rq_sa and netf_rq_lun from the length of the msg passed to - * i2c_smbus_xfer + * subtract rq_sa and netf_rq_lun from the length of the msg. Fill the + * temporary client. Note that its use is an exception for IPMI. */ msg_len = msg[IPMB_MSG_LEN_IDX] - SMBUS_MSG_HEADER_LENGTH; - if (msg_len > I2C_SMBUS_BLOCK_MAX) - msg_len = I2C_SMBUS_BLOCK_MAX; + memcpy(&temp_client, ipmb_dev->client, sizeof(temp_client)); + temp_client.addr = rq_sa; - data.block[0] = msg_len; - memcpy(&data.block[1], msg + SMBUS_MSG_IDX_OFFSET, msg_len); - ret = i2c_smbus_xfer(ipmb_dev->client->adapter, rq_sa, - ipmb_dev->client->flags, - I2C_SMBUS_WRITE, netf_rq_lun, - I2C_SMBUS_BLOCK_DATA, &data); - - return ret ? : count; + ret = i2c_smbus_write_block_data(&temp_client, netf_rq_lun, msg_len, + msg + SMBUS_MSG_IDX_OFFSET); + return ret < 0 ? ret : count; } static __poll_t ipmb_poll(struct file *file, poll_table *wait)
The block-write function of the core was not used because there was no client-struct to use. However, in this case it seems apropriate to use a temporary client struct. Because we are answering a request we recieved when being a client ourselves. So, convert the code to use a temporary client and use the block-write function of the I2C core. Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> --- drivers/char/ipmi/ipmb_dev_int.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-)