diff options
author | Jakub Kicinski <kuba@kernel.org> | 2021-11-15 07:49:46 -0800 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2021-11-15 07:53:10 -0800 |
commit | 2f6a470d6545841cf1891b87e360d3998ef024c8 (patch) | |
tree | f7ba8f8b6016fa8741cabe3527c636e94e3a8b79 /drivers/i2c | |
parent | 6d3b1b069946e8a9dbb5e6ea45c3aeee1d56ea44 (diff) | |
download | linux-stable-2f6a470d6545841cf1891b87e360d3998ef024c8.tar.gz linux-stable-2f6a470d6545841cf1891b87e360d3998ef024c8.tar.bz2 linux-stable-2f6a470d6545841cf1891b87e360d3998ef024c8.zip |
Revert "Merge branch 'mctp-i2c-driver'"
This reverts commit 71812af7234f30362b43ccff33f93890ae4c0655, reversing
changes made to cc0be1ad686fb29a4d127948486f40b17fb34b50.
Wolfram Sang says:
Please revert. Besides the driver in net, it modifies the I2C core
code. This has not been acked by the I2C maintainer (in this case me).
So, please don't pull this in via the net tree. The question raised here
(extending SMBus calls to 255 byte) is complicated because we need ABI
backwards compatibility.
Link: https://lore.kernel.org/all/YZJ9H4eM%2FM7OXVN0@shikoro/
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-aspeed.c | 5 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-npcm7xx.c | 3 | ||||
-rw-r--r-- | drivers/i2c/i2c-core-smbus.c | 20 | ||||
-rw-r--r-- | drivers/i2c/i2c-dev.c | 93 |
4 files changed, 24 insertions, 97 deletions
diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c index 7395f3702fae..67e8b97c0c95 100644 --- a/drivers/i2c/busses/i2c-aspeed.c +++ b/drivers/i2c/busses/i2c-aspeed.c @@ -533,7 +533,7 @@ static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status) msg->buf[bus->buf_index++] = recv_byte; if (msg->flags & I2C_M_RECV_LEN) { - if (unlikely(recv_byte > I2C_SMBUS_V3_BLOCK_MAX)) { + if (unlikely(recv_byte > I2C_SMBUS_BLOCK_MAX)) { bus->cmd_err = -EPROTO; aspeed_i2c_do_stop(bus); goto out_no_complete; @@ -718,8 +718,7 @@ static int aspeed_i2c_master_xfer(struct i2c_adapter *adap, static u32 aspeed_i2c_functionality(struct i2c_adapter *adap) { - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | - I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_V3_BLOCK; + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_BLOCK_DATA; } #if IS_ENABLED(CONFIG_I2C_SLAVE) diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c index 6d60f65add85..2ad166355ec9 100644 --- a/drivers/i2c/busses/i2c-npcm7xx.c +++ b/drivers/i2c/busses/i2c-npcm7xx.c @@ -1399,7 +1399,7 @@ static void npcm_i2c_irq_master_handler_read(struct npcm_i2c *bus) if (bus->read_block_use) { /* first byte in block protocol is the size: */ data = npcm_i2c_rd_byte(bus); - data = clamp_val(data, 1, I2C_SMBUS_V3_BLOCK_MAX); + data = clamp_val(data, 1, I2C_SMBUS_BLOCK_MAX); bus->rd_size = data + block_extra_bytes_size; bus->rd_buf[bus->rd_ind++] = data; @@ -2187,7 +2187,6 @@ static u32 npcm_i2c_functionality(struct i2c_adapter *adap) I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_PEC | - I2C_FUNC_SMBUS_V3_BLOCK | I2C_FUNC_SLAVE; } diff --git a/drivers/i2c/i2c-core-smbus.c b/drivers/i2c/i2c-core-smbus.c index 743415584aba..e5b2d1465e7e 100644 --- a/drivers/i2c/i2c-core-smbus.c +++ b/drivers/i2c/i2c-core-smbus.c @@ -303,8 +303,7 @@ static void i2c_smbus_try_get_dmabuf(struct i2c_msg *msg, u8 init_val) bool is_read = msg->flags & I2C_M_RD; unsigned char *dma_buf; - dma_buf = kzalloc(I2C_SMBUS_V3_BLOCK_MAX + (is_read ? 2 : 3), - GFP_KERNEL); + dma_buf = kzalloc(I2C_SMBUS_BLOCK_MAX + (is_read ? 2 : 3), GFP_KERNEL); if (!dma_buf) return; @@ -330,10 +329,9 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr, * initialize most things with sane defaults, to keep the code below * somewhat simpler. */ - unsigned char msgbuf0[I2C_SMBUS_V3_BLOCK_MAX+3]; - unsigned char msgbuf1[I2C_SMBUS_V3_BLOCK_MAX+2]; + unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3]; + unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2]; int nmsgs = read_write == I2C_SMBUS_READ ? 2 : 1; - u16 block_max; u8 partial_pec = 0; int status; struct i2c_msg msg[2] = { @@ -352,10 +350,6 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr, bool wants_pec = ((flags & I2C_CLIENT_PEC) && size != I2C_SMBUS_QUICK && size != I2C_SMBUS_I2C_BLOCK_DATA); - /* Drivers must opt in to 255 byte max block size */ - block_max = i2c_check_functionality(adapter, I2C_FUNC_SMBUS_V3_BLOCK) - ? I2C_SMBUS_V3_BLOCK_MAX : I2C_SMBUS_BLOCK_MAX; - msgbuf0[0] = command; switch (size) { case I2C_SMBUS_QUICK: @@ -405,7 +399,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr, i2c_smbus_try_get_dmabuf(&msg[1], 0); } else { msg[0].len = data->block[0] + 2; - if (msg[0].len > block_max + 2) { + if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) { dev_err(&adapter->dev, "Invalid block write size %d\n", data->block[0]); @@ -419,7 +413,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr, case I2C_SMBUS_BLOCK_PROC_CALL: nmsgs = 2; /* Another special case */ read_write = I2C_SMBUS_READ; - if (data->block[0] > block_max) { + if (data->block[0] > I2C_SMBUS_BLOCK_MAX) { dev_err(&adapter->dev, "Invalid block write size %d\n", data->block[0]); @@ -436,7 +430,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr, i2c_smbus_try_get_dmabuf(&msg[1], 0); break; case I2C_SMBUS_I2C_BLOCK_DATA: - if (data->block[0] > block_max) { + if (data->block[0] > I2C_SMBUS_BLOCK_MAX) { dev_err(&adapter->dev, "Invalid block %s size %d\n", read_write == I2C_SMBUS_READ ? "read" : "write", data->block[0]); @@ -504,7 +498,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr, break; case I2C_SMBUS_BLOCK_DATA: case I2C_SMBUS_BLOCK_PROC_CALL: - if (msg[1].buf[0] > block_max) { + if (msg[1].buf[0] > I2C_SMBUS_BLOCK_MAX) { dev_err(&adapter->dev, "Invalid block size returned: %d\n", msg[1].buf[0]); diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index 5ee9118c0407..bce0e8bb7852 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -46,24 +46,6 @@ struct i2c_dev { struct cdev cdev; }; -/* The userspace union i2c_smbus_data for I2C_SMBUS ioctl is limited - * to 32 bytes (I2C_SMBUS_BLOCK_MAX) for compatibility. - */ -union compat_i2c_smbus_data { - __u8 byte; - __u16 word; - __u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */ - /* and one more for user-space compatibility */ -}; - -/* Must match i2c-dev.h definition with compat .data member */ -struct i2c_smbus_ioctl_data { - __u8 read_write; - __u8 command; - __u32 size; - union compat_i2c_smbus_data __user *data; -}; - #define I2C_MINORS (MINORMASK + 1) static LIST_HEAD(i2c_dev_list); static DEFINE_SPINLOCK(i2c_dev_list_lock); @@ -253,17 +235,14 @@ static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr) static noinline int i2cdev_ioctl_rdwr(struct i2c_client *client, unsigned nmsgs, struct i2c_msg *msgs) { - u8 __user **data_ptrs = NULL; - u16 *orig_lens = NULL; + u8 __user **data_ptrs; int i, res; - res = -ENOMEM; data_ptrs = kmalloc_array(nmsgs, sizeof(u8 __user *), GFP_KERNEL); - if (data_ptrs == NULL) - goto out; - orig_lens = kmalloc_array(nmsgs, sizeof(u16), GFP_KERNEL); - if (orig_lens == NULL) - goto out; + if (data_ptrs == NULL) { + kfree(msgs); + return -ENOMEM; + } res = 0; for (i = 0; i < nmsgs; i++) { @@ -274,30 +253,12 @@ static noinline int i2cdev_ioctl_rdwr(struct i2c_client *client, } data_ptrs[i] = (u8 __user *)msgs[i].buf; - msgs[i].buf = NULL; - if (msgs[i].len < 1) { - /* Sanity check */ - res = -EINVAL; - break; - - } - /* Allocate a larger buffer to accommodate possible 255 byte - * blocks. Read results will be dropped later - * if they are too large for the original length. - */ - orig_lens[i] = msgs[i].len; - msgs[i].buf = kmalloc(msgs[i].len + I2C_SMBUS_V3_BLOCK_MAX, - GFP_USER | __GFP_NOWARN); + msgs[i].buf = memdup_user(data_ptrs[i], msgs[i].len); if (IS_ERR(msgs[i].buf)) { res = PTR_ERR(msgs[i].buf); break; } - if (copy_from_user(msgs[i].buf, data_ptrs[i], msgs[i].len)) { - kfree(msgs[i].buf); - res = -EFAULT; - break; - } - /* Buffer from kmalloc, so DMA is ok */ + /* memdup_user allocates with GFP_KERNEL, so DMA is ok */ msgs[i].flags |= I2C_M_DMA_SAFE; /* @@ -313,7 +274,7 @@ static noinline int i2cdev_ioctl_rdwr(struct i2c_client *client, */ if (msgs[i].flags & I2C_M_RECV_LEN) { if (!(msgs[i].flags & I2C_M_RD) || - msgs[i].buf[0] < 1 || + msgs[i].len < 1 || msgs[i].buf[0] < 1 || msgs[i].len < msgs[i].buf[0] + I2C_SMBUS_BLOCK_MAX) { i++; @@ -336,16 +297,12 @@ static noinline int i2cdev_ioctl_rdwr(struct i2c_client *client, res = i2c_transfer(client->adapter, msgs, nmsgs); while (i-- > 0) { if (res >= 0 && (msgs[i].flags & I2C_M_RD)) { - if (orig_lens[i] < msgs[i].len) - res = -EINVAL; - else if (copy_to_user(data_ptrs[i], msgs[i].buf, - msgs[i].len)) + if (copy_to_user(data_ptrs[i], msgs[i].buf, + msgs[i].len)) res = -EFAULT; } kfree(msgs[i].buf); } -out: - kfree(orig_lens); kfree(data_ptrs); kfree(msgs); return res; @@ -353,7 +310,7 @@ out: static noinline int i2cdev_ioctl_smbus(struct i2c_client *client, u8 read_write, u8 command, u32 size, - union compat_i2c_smbus_data __user *data) + union i2c_smbus_data __user *data) { union i2c_smbus_data temp = {}; int datasize, res; @@ -414,16 +371,6 @@ static noinline int i2cdev_ioctl_smbus(struct i2c_client *client, if (copy_from_user(&temp, data, datasize)) return -EFAULT; } - if ((size == I2C_SMBUS_BLOCK_PROC_CALL || - size == I2C_SMBUS_I2C_BLOCK_DATA || - size == I2C_SMBUS_BLOCK_DATA) && - read_write == I2C_SMBUS_WRITE && - temp.block[0] > I2C_SMBUS_BLOCK_MAX) { - /* Don't accept writes larger than the buffer size */ - dev_dbg(&client->adapter->dev, "block write is too large"); - return -EINVAL; - - } if (size == I2C_SMBUS_I2C_BLOCK_BROKEN) { /* Convert old I2C block commands to the new convention. This preserves binary compatibility. */ @@ -433,21 +380,9 @@ static noinline int i2cdev_ioctl_smbus(struct i2c_client *client, } res = i2c_smbus_xfer(client->adapter, client->addr, client->flags, read_write, command, size, &temp); - if (res) - return res; - if ((size == I2C_SMBUS_BLOCK_PROC_CALL || - size == I2C_SMBUS_I2C_BLOCK_DATA || - size == I2C_SMBUS_BLOCK_DATA) && - read_write == I2C_SMBUS_READ && - temp.block[0] > I2C_SMBUS_BLOCK_MAX) { - /* Don't accept reads larger than the buffer size */ - dev_dbg(&client->adapter->dev, "block read is too large"); - return -EINVAL; - - } - if ((size == I2C_SMBUS_PROC_CALL) || - (size == I2C_SMBUS_BLOCK_PROC_CALL) || - (read_write == I2C_SMBUS_READ)) { + if (!res && ((size == I2C_SMBUS_PROC_CALL) || + (size == I2C_SMBUS_BLOCK_PROC_CALL) || + (read_write == I2C_SMBUS_READ))) { if (copy_to_user(data, &temp, datasize)) return -EFAULT; } |