mceusb: sporadic RX truncation corruption fix
authorA Sun <as1033x@comcast.net>
Sun, 26 Mar 2017 18:33:07 +0000 (15:33 -0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 13 Apr 2018 17:48:22 +0000 (19:48 +0200)
[ Upstream commit 8e175b22e8640bf3a58e071af54190b909e4a944 ]

Intermittent RX truncation and loss of IR received data. This resulted
in receive stream synchronization errors where driver attempted to
incorrectly parse IR data (eg 0x90 below) as command response.

[ 3969.139898] mceusb 1-1.2:1.0: processed IR data
[ 3969.151315] mceusb 1-1.2:1.0: rx data: 00 90 (length=2)
[ 3969.151321] mceusb 1-1.2:1.0: Unknown command 0x00 0x90
[ 3969.151336] mceusb 1-1.2:1.0: rx data: 98 0a 8d 0a 8e 0a 8e 0a 8e 0a 8e 0a 9a 0a 8e 0a 0b 3a 8e 00 80 41 59 00 00 (length=25)
[ 3969.151341] mceusb 1-1.2:1.0: Raw IR data, 24 pulse/space samples
[ 3969.151348] mceusb 1-1.2:1.0: Storing space with duration 500000

Bug trigger appears to be normal, but heavy, IR receiver use.

Signed-off-by: A Sun <as1033x@comcast.net>
Signed-off-by: Sean Young <sean@mess.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/media/rc/mceusb.c

index db525cdfac88f56479e186538db1f85e97aa481f..d9f88a4a96bd1677c5f891bf14be52184bf8d460 100644 (file)
@@ -1381,8 +1381,13 @@ static int mceusb_dev_probe(struct usb_interface *intf,
                goto rc_dev_fail;
 
        /* wire up inbound data handler */
-       usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in, maxp,
-                               mceusb_dev_recv, ir, ep_in->bInterval);
+       if (usb_endpoint_xfer_int(ep_in))
+               usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in, maxp,
+                                mceusb_dev_recv, ir, ep_in->bInterval);
+       else
+               usb_fill_bulk_urb(ir->urb_in, dev, pipe, ir->buf_in, maxp,
+                                 mceusb_dev_recv, ir);
+
        ir->urb_in->transfer_dma = ir->dma_in;
        ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;