Skip to content

Commit 8126fdb

Browse files
Patrick BoettcherLinus Torvalds
authored andcommitted
[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>
1 parent 820d220 commit 8126fdb

File tree

2 files changed

+17
-7
lines changed

2 files changed

+17
-7
lines changed

drivers/media/dvb/dvb-usb/dibusb-common.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,22 @@ EXPORT_SYMBOL(dibusb_power_ctrl);
7070

7171
int dibusb2_0_streaming_ctrl(struct dvb_usb_device *d, int onoff)
7272
{
73-
u8 b[2];
74-
b[0] = DIBUSB_REQ_SET_IOCTL;
75-
b[1] = onoff ? DIBUSB_IOCTL_CMD_ENABLE_STREAM : DIBUSB_IOCTL_CMD_DISABLE_STREAM;
73+
u8 b[3] = { 0 };
74+
int ret;
75+
76+
if ((ret = dibusb_streaming_ctrl(d,onoff)) < 0)
77+
return ret;
7678

77-
dvb_usb_generic_write(d,b,3);
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+
}
7885

79-
return dibusb_streaming_ctrl(d,onoff);
86+
b[0] = DIBUSB_REQ_SET_IOCTL;
87+
b[1] = onoff ? DIBUSB_IOCTL_CMD_ENABLE_STREAM : DIBUSB_IOCTL_CMD_DISABLE_STREAM;
88+
return dvb_usb_generic_write(d,b,3);
8089
}
8190
EXPORT_SYMBOL(dibusb2_0_streaming_ctrl);
8291

drivers/media/dvb/dvb-usb/dvb-usb-dvb.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
2323
*/
2424
if (newfeedcount == 0) {
2525
deb_ts("stop feeding\n");
26+
dvb_usb_urb_kill(d);
2627

2728
if (d->props.streaming_ctrl != NULL)
2829
if ((ret = d->props.streaming_ctrl(d,0)))
2930
err("error while stopping stream.");
3031

31-
dvb_usb_urb_kill(d);
3232
}
3333

3434
d->feedcount = newfeedcount;
@@ -44,6 +44,8 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
4444
* for reception.
4545
*/
4646
if (d->feedcount == onoff && d->feedcount > 0) {
47+
deb_ts("submitting all URBs\n");
48+
dvb_usb_urb_submit(d);
4749

4850
deb_ts("controlling pid parser\n");
4951
if (d->props.caps & DVB_USB_HAS_PID_FILTER &&
@@ -59,7 +61,6 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
5961
return -ENODEV;
6062
}
6163

62-
dvb_usb_urb_submit(d);
6364
}
6465
return 0;
6566
}

0 commit comments

Comments
 (0)