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

V4L/DVB (11247): hdpvr: empty internal device buffer after stopping streaming

Makes the next capturing starting faster and more reliable.

Signed-off-by: Janne Grunau <j@jannau.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

authored by

Janne Grunau and committed by
Mauro Carvalho Chehab
7d771ff0 9ef77adf

+26
+26
drivers/media/video/hdpvr/hdpvr-video.c
··· 298 298 /* function expects dev->io_mutex to be hold by caller */ 299 299 static int hdpvr_stop_streaming(struct hdpvr_device *dev) 300 300 { 301 + uint actual_length, c = 0; 302 + u8 *buf; 303 + 301 304 if (dev->status == STATUS_IDLE) 302 305 return 0; 303 306 else if (dev->status != STATUS_STREAMING) 304 307 return -EAGAIN; 308 + 309 + buf = kmalloc(dev->bulk_in_size, GFP_KERNEL); 310 + if (!buf) 311 + v4l2_err(&dev->v4l2_dev, "failed to allocate temporary buffer " 312 + "for emptying the internal device buffer. " 313 + "Next capture start will be slow\n"); 305 314 306 315 dev->status = STATUS_SHUTTING_DOWN; 307 316 hdpvr_config_call(dev, CTRL_STOP_STREAMING_VALUE, 0x00); ··· 324 315 mutex_lock(&dev->io_mutex); 325 316 /* kill the still outstanding urbs */ 326 317 hdpvr_cancel_queue(dev); 318 + 319 + /* emptying the device buffer beforeshutting it down */ 320 + while (buf && ++c < 500 && 321 + !usb_bulk_msg(dev->udev, 322 + usb_rcvbulkpipe(dev->udev, 323 + dev->bulk_in_endpointAddr), 324 + buf, dev->bulk_in_size, &actual_length, 325 + BULK_URB_TIMEOUT)) { 326 + /* wait */ 327 + msleep(5); 328 + v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, 329 + "%2d: got %d bytes\n", c, actual_length); 330 + } 331 + kfree(buf); 332 + v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, 333 + "used %d urbs to empty device buffers\n", c-1); 334 + msleep(10); 327 335 328 336 dev->status = STATUS_IDLE; 329 337