diff options
author | Janne Grunau <j@jannau.net> | 2009-03-27 19:21:17 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-03-30 11:43:43 -0400 |
commit | 7d771ff0dc3371923db929d9f88932acec3fc8e8 (patch) | |
tree | 0b138d8896e464f27788ac47230cd8d804dbde6c /drivers/media/video/hdpvr/hdpvr-video.c | |
parent | 9ef77adfb9ac170bcaf449530cf129c48547fd55 (diff) |
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>
Diffstat (limited to 'drivers/media/video/hdpvr/hdpvr-video.c')
-rw-r--r-- | drivers/media/video/hdpvr/hdpvr-video.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c index f6e1bcefddb7..3e6ffee8dfed 100644 --- a/drivers/media/video/hdpvr/hdpvr-video.c +++ b/drivers/media/video/hdpvr/hdpvr-video.c | |||
@@ -298,11 +298,20 @@ static int hdpvr_start_streaming(struct hdpvr_device *dev) | |||
298 | /* function expects dev->io_mutex to be hold by caller */ | 298 | /* function expects dev->io_mutex to be hold by caller */ |
299 | static int hdpvr_stop_streaming(struct hdpvr_device *dev) | 299 | static int hdpvr_stop_streaming(struct hdpvr_device *dev) |
300 | { | 300 | { |
301 | uint actual_length, c = 0; | ||
302 | u8 *buf; | ||
303 | |||
301 | if (dev->status == STATUS_IDLE) | 304 | if (dev->status == STATUS_IDLE) |
302 | return 0; | 305 | return 0; |
303 | else if (dev->status != STATUS_STREAMING) | 306 | else if (dev->status != STATUS_STREAMING) |
304 | return -EAGAIN; | 307 | return -EAGAIN; |
305 | 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"); | ||
314 | |||
306 | dev->status = STATUS_SHUTTING_DOWN; | 315 | dev->status = STATUS_SHUTTING_DOWN; |
307 | hdpvr_config_call(dev, CTRL_STOP_STREAMING_VALUE, 0x00); | 316 | hdpvr_config_call(dev, CTRL_STOP_STREAMING_VALUE, 0x00); |
308 | mutex_unlock(&dev->io_mutex); | 317 | mutex_unlock(&dev->io_mutex); |
@@ -316,6 +325,23 @@ static int hdpvr_stop_streaming(struct hdpvr_device *dev) | |||
316 | /* kill the still outstanding urbs */ | 325 | /* kill the still outstanding urbs */ |
317 | hdpvr_cancel_queue(dev); | 326 | hdpvr_cancel_queue(dev); |
318 | 327 | ||
328 | /* emptying the device buffer beforeshutting it down */ | ||
329 | while (buf && ++c < 500 && | ||
330 | !usb_bulk_msg(dev->udev, | ||
331 | usb_rcvbulkpipe(dev->udev, | ||
332 | dev->bulk_in_endpointAddr), | ||
333 | buf, dev->bulk_in_size, &actual_length, | ||
334 | BULK_URB_TIMEOUT)) { | ||
335 | /* wait */ | ||
336 | msleep(5); | ||
337 | v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, | ||
338 | "%2d: got %d bytes\n", c, actual_length); | ||
339 | } | ||
340 | kfree(buf); | ||
341 | v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, | ||
342 | "used %d urbs to empty device buffers\n", c-1); | ||
343 | msleep(10); | ||
344 | |||
319 | dev->status = STATUS_IDLE; | 345 | dev->status = STATUS_IDLE; |
320 | 346 | ||
321 | return 0; | 347 | return 0; |