CXUSB D680 DMB pipe draining code found to be problematic for new kernels (eg. kernel 2.6.27 @ Ubuntu 8.10) David T.L. Wong
diff -r 626c136ec221 linux/drivers/media/dvb/dvb-usb/cxusb.c --- a/linux/drivers/media/dvb/dvb-usb/cxusb.c Fri Mar 13 14:35:14 2009 -0700 +++ b/linux/drivers/media/dvb/dvb-usb/cxusb.c Tue Mar 17 23:20:00 2009 +0800 @@ -322,58 +322,11 @@ return 0; } -static void cxusb_d680_dmb_drain_message(struct dvb_usb_device *d) -{ - int ep = d->props.generic_bulk_ctrl_endpoint; - const int timeout = 100; - const int junk_len = 32; - u8 *junk; - int rd_count; - - /* Discard remaining data in video pipe */ - junk = kmalloc(junk_len, GFP_KERNEL); - if (!junk) - return; - while (1) { - if (usb_bulk_msg(d->udev, - usb_rcvbulkpipe(d->udev, ep), - junk, junk_len, &rd_count, timeout) < 0) - break; - if (!rd_count) - break; - } - kfree(junk); -} - -static void cxusb_d680_dmb_drain_video(struct dvb_usb_device *d) -{ - struct usb_data_stream_properties *p = &d->props.adapter[0].stream; - const int timeout = 100; - const int junk_len = p->u.bulk.buffersize; - u8 *junk; - int rd_count; - - /* Discard remaining data in video pipe */ - junk = kmalloc(junk_len, GFP_KERNEL); - if (!junk) - return; - while (1) { - if (usb_bulk_msg(d->udev, - usb_rcvbulkpipe(d->udev, p->endpoint), - junk, junk_len, &rd_count, timeout) < 0) - break; - if (!rd_count) - break; - } - kfree(junk); -} - static int cxusb_d680_dmb_streaming_ctrl( struct dvb_usb_adapter *adap, int onoff) { if (onoff) { u8 buf[2] = { 0x03, 0x00 }; - cxusb_d680_dmb_drain_video(adap->dev); return cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON, buf, sizeof(buf), NULL, 0); } else { @@ -1118,13 +1081,6 @@ usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, d->props.adapter[0].stream.endpoint)); - /* Drain USB pipes to avoid hang after reboot */ - for (n = 0; n < 5; n++) { - cxusb_d680_dmb_drain_message(d); - cxusb_d680_dmb_drain_video(d); - msleep(200); - } - /* Reset the tuner */ if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) { err("clear tuner gpio failed");