Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

[PATCH] fix for race problem in DVB USB drivers (dibusb)

Fixed race between submitting streaming URBs in the driver and starting
the actual transfer in hardware (demodulator and USB controller) which
sometimes lead to garbled data transfers. URBs are now submitted first,
then the transfer is enabled. Dibusb devices and clones are now fully
functional again.

Signed-off-by: Patrick Boettcher <pb@linuxtv.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Patrick Boettcher and committed by
Linus Torvalds
8126fdbc 820d220d

+17 -7
+14 -5
drivers/media/dvb/dvb-usb/dibusb-common.c
··· 70 70 71 71 int dibusb2_0_streaming_ctrl(struct dvb_usb_device *d, int onoff) 72 72 { 73 - u8 b[2]; 73 + u8 b[3] = { 0 }; 74 + int ret; 75 + 76 + if ((ret = dibusb_streaming_ctrl(d,onoff)) < 0) 77 + return ret; 78 + 79 + if (onoff) { 80 + b[0] = DIBUSB_REQ_SET_STREAMING_MODE; 81 + b[1] = 0x00; 82 + if ((ret = dvb_usb_generic_write(d,b,2)) < 0) 83 + return ret; 84 + } 85 + 74 86 b[0] = DIBUSB_REQ_SET_IOCTL; 75 87 b[1] = onoff ? DIBUSB_IOCTL_CMD_ENABLE_STREAM : DIBUSB_IOCTL_CMD_DISABLE_STREAM; 76 - 77 - dvb_usb_generic_write(d,b,3); 78 - 79 - return dibusb_streaming_ctrl(d,onoff); 88 + return dvb_usb_generic_write(d,b,3); 80 89 } 81 90 EXPORT_SYMBOL(dibusb2_0_streaming_ctrl); 82 91
+3 -2
drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
··· 23 23 */ 24 24 if (newfeedcount == 0) { 25 25 deb_ts("stop feeding\n"); 26 + dvb_usb_urb_kill(d); 26 27 27 28 if (d->props.streaming_ctrl != NULL) 28 29 if ((ret = d->props.streaming_ctrl(d,0))) 29 30 err("error while stopping stream."); 30 31 31 - dvb_usb_urb_kill(d); 32 32 } 33 33 34 34 d->feedcount = newfeedcount; ··· 44 44 * for reception. 45 45 */ 46 46 if (d->feedcount == onoff && d->feedcount > 0) { 47 + deb_ts("submitting all URBs\n"); 48 + dvb_usb_urb_submit(d); 47 49 48 50 deb_ts("controlling pid parser\n"); 49 51 if (d->props.caps & DVB_USB_HAS_PID_FILTER && ··· 61 59 return -ENODEV; 62 60 } 63 61 64 - dvb_usb_urb_submit(d); 65 62 } 66 63 return 0; 67 64 }