From: Greg Kroah-Hartman Date: Mon, 5 Jun 2017 12:21:15 +0000 (+0200) Subject: 3.18-stable patches X-Git-Tag: v3.18.56~27 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e4ac9c04a86ef2018d8629fd058e904f40e35a43;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches added patches: i2c-i2c-tiny-usb-fix-buffer-not-being-dma-capable.patch --- diff --git a/queue-3.18/i2c-i2c-tiny-usb-fix-buffer-not-being-dma-capable.patch b/queue-3.18/i2c-i2c-tiny-usb-fix-buffer-not-being-dma-capable.patch new file mode 100644 index 00000000000..8a6d3b4b52a --- /dev/null +++ b/queue-3.18/i2c-i2c-tiny-usb-fix-buffer-not-being-dma-capable.patch @@ -0,0 +1,104 @@ +From 5165da5923d6c7df6f2927b0113b2e4d9288661e Mon Sep 17 00:00:00 2001 +From: Sebastian Reichel +Date: Fri, 5 May 2017 11:06:50 +0200 +Subject: i2c: i2c-tiny-usb: fix buffer not being DMA capable + +From: Sebastian Reichel + +commit 5165da5923d6c7df6f2927b0113b2e4d9288661e upstream. + +Since v4.9 i2c-tiny-usb generates the below call trace +and longer works, since it can't communicate with the +USB device. The reason is, that since v4.9 the USB +stack checks, that the buffer it should transfer is DMA +capable. This was a requirement since v2.2 days, but it +usually worked nevertheless. + +[ 17.504959] ------------[ cut here ]------------ +[ 17.505488] WARNING: CPU: 0 PID: 93 at drivers/usb/core/hcd.c:1587 usb_hcd_map_urb_for_dma+0x37c/0x570 +[ 17.506545] transfer buffer not dma capable +[ 17.507022] Modules linked in: +[ 17.507370] CPU: 0 PID: 93 Comm: i2cdetect Not tainted 4.11.0-rc8+ #10 +[ 17.508103] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014 +[ 17.509039] Call Trace: +[ 17.509320] ? dump_stack+0x5c/0x78 +[ 17.509714] ? __warn+0xbe/0xe0 +[ 17.510073] ? warn_slowpath_fmt+0x5a/0x80 +[ 17.510532] ? nommu_map_sg+0xb0/0xb0 +[ 17.510949] ? usb_hcd_map_urb_for_dma+0x37c/0x570 +[ 17.511482] ? usb_hcd_submit_urb+0x336/0xab0 +[ 17.511976] ? wait_for_completion_timeout+0x12f/0x1a0 +[ 17.512549] ? wait_for_completion_timeout+0x65/0x1a0 +[ 17.513125] ? usb_start_wait_urb+0x65/0x160 +[ 17.513604] ? usb_control_msg+0xdc/0x130 +[ 17.514061] ? usb_xfer+0xa4/0x2a0 +[ 17.514445] ? __i2c_transfer+0x108/0x3c0 +[ 17.514899] ? i2c_transfer+0x57/0xb0 +[ 17.515310] ? i2c_smbus_xfer_emulated+0x12f/0x590 +[ 17.515851] ? _raw_spin_unlock_irqrestore+0x11/0x20 +[ 17.516408] ? i2c_smbus_xfer+0x125/0x330 +[ 17.516876] ? i2c_smbus_xfer+0x125/0x330 +[ 17.517329] ? i2cdev_ioctl_smbus+0x1c1/0x2b0 +[ 17.517824] ? i2cdev_ioctl+0x75/0x1c0 +[ 17.518248] ? do_vfs_ioctl+0x9f/0x600 +[ 17.518671] ? vfs_write+0x144/0x190 +[ 17.519078] ? SyS_ioctl+0x74/0x80 +[ 17.519463] ? entry_SYSCALL_64_fastpath+0x1e/0xad +[ 17.519959] ---[ end trace d047c04982f5ac50 ]--- + +Signed-off-by: Sebastian Reichel +Reviewed-by: Greg Kroah-Hartman +Acked-by: Till Harbaum +Signed-off-by: Wolfram Sang +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-tiny-usb.c | 25 +++++++++++++++++++++---- + 1 file changed, 21 insertions(+), 4 deletions(-) + +--- a/drivers/i2c/busses/i2c-tiny-usb.c ++++ b/drivers/i2c/busses/i2c-tiny-usb.c +@@ -178,22 +178,39 @@ static int usb_read(struct i2c_adapter * + int value, int index, void *data, int len) + { + struct i2c_tiny_usb *dev = (struct i2c_tiny_usb *)adapter->algo_data; ++ void *dmadata = kmalloc(len, GFP_KERNEL); ++ int ret; ++ ++ if (!dmadata) ++ return -ENOMEM; + + /* do control transfer */ +- return usb_control_msg(dev->usb_dev, usb_rcvctrlpipe(dev->usb_dev, 0), ++ ret = usb_control_msg(dev->usb_dev, usb_rcvctrlpipe(dev->usb_dev, 0), + cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE | +- USB_DIR_IN, value, index, data, len, 2000); ++ USB_DIR_IN, value, index, dmadata, len, 2000); ++ ++ memcpy(data, dmadata, len); ++ kfree(dmadata); ++ return ret; + } + + static int usb_write(struct i2c_adapter *adapter, int cmd, + int value, int index, void *data, int len) + { + struct i2c_tiny_usb *dev = (struct i2c_tiny_usb *)adapter->algo_data; ++ void *dmadata = kmemdup(data, len, GFP_KERNEL); ++ int ret; ++ ++ if (!dmadata) ++ return -ENOMEM; + + /* do control transfer */ +- return usb_control_msg(dev->usb_dev, usb_sndctrlpipe(dev->usb_dev, 0), ++ ret = usb_control_msg(dev->usb_dev, usb_sndctrlpipe(dev->usb_dev, 0), + cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE, +- value, index, data, len, 2000); ++ value, index, dmadata, len, 2000); ++ ++ kfree(dmadata); ++ return ret; + } + + static void i2c_tiny_usb_free(struct i2c_tiny_usb *dev) diff --git a/queue-3.18/series b/queue-3.18/series index 8c399be96ea..a20a951f0be 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -14,3 +14,4 @@ qmi_wwan-add-another-lenovo-em74xx-device-id.patch ipv6-fix-out-of-bound-writes-in-__ip6_append_data.patch tcp-avoid-fastopen-api-to-be-used-on-af_unspec.patch sctp-fix-icmp-processing-if-skb-is-non-linear.patch +i2c-i2c-tiny-usb-fix-buffer-not-being-dma-capable.patch