提交 33f6984e 编写于 作者: F Frank Schaefer 提交者: Mauro Carvalho Chehab

[media] em28xx: fix analog streaming with USB bulk transfers

With the conversion to videobuf2, some unnecessary calls of
em28xx_set_alternate() have been removed. It is now called at analog streaming
start only.
This has unveiled a bug that causes USB bulk transfers to fail with all urbs
having status -EVOERFLOW.
The reason is, that for bulk transfers usb_set_interface() needs to be called
even if the previous alt setting was the same (side note: bulk transfers seem
to work only with alt=0).
While it seems to be NOT necessary for isoc transfers, it's reasonable to just
call usb_set_interface() unconditionally in em28xx_set_alternate().
Also add a comment that explains the issue to prevent regressions in the future.

Cc: stable@vger.kernel.org # for 3.8
Signed-off-by: NFrank Schäfer <fschaefer.oss@googlemail.com>
Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
上级 4880f564
...@@ -813,12 +813,12 @@ int em28xx_resolution_set(struct em28xx *dev) ...@@ -813,12 +813,12 @@ int em28xx_resolution_set(struct em28xx *dev)
/* Set USB alternate setting for analog video */ /* Set USB alternate setting for analog video */
int em28xx_set_alternate(struct em28xx *dev) int em28xx_set_alternate(struct em28xx *dev)
{ {
int errCode, prev_alt = dev->alt; int errCode;
int i; int i;
unsigned int min_pkt_size = dev->width * 2 + 4; unsigned int min_pkt_size = dev->width * 2 + 4;
/* NOTE: for isoc transfers, only alt settings > 0 are allowed /* NOTE: for isoc transfers, only alt settings > 0 are allowed
for bulk transfers, use alt=0 as default value */ bulk transfers seem to work only with alt=0 ! */
dev->alt = 0; dev->alt = 0;
if ((alt > 0) && (alt < dev->num_alt)) { if ((alt > 0) && (alt < dev->num_alt)) {
em28xx_coredbg("alternate forced to %d\n", dev->alt); em28xx_coredbg("alternate forced to %d\n", dev->alt);
...@@ -849,7 +849,9 @@ int em28xx_set_alternate(struct em28xx *dev) ...@@ -849,7 +849,9 @@ int em28xx_set_alternate(struct em28xx *dev)
} }
set_alt: set_alt:
if (dev->alt != prev_alt) { /* NOTE: for bulk transfers, we need to call usb_set_interface()
* even if the previous settings were the same. Otherwise streaming
* fails with all urbs having status = -EOVERFLOW ! */
if (dev->analog_xfer_bulk) { if (dev->analog_xfer_bulk) {
dev->max_pkt_size = 512; /* USB 2.0 spec */ dev->max_pkt_size = 512; /* USB 2.0 spec */
dev->packet_multiplier = EM28XX_BULK_PACKET_MULTIPLIER; dev->packet_multiplier = EM28XX_BULK_PACKET_MULTIPLIER;
...@@ -868,7 +870,6 @@ int em28xx_set_alternate(struct em28xx *dev) ...@@ -868,7 +870,6 @@ int em28xx_set_alternate(struct em28xx *dev)
dev->alt, errCode); dev->alt, errCode);
return errCode; return errCode;
} }
}
return 0; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册