summaryrefslogtreecommitdiffstats
path: root/drivers/media/usb/airspy/airspy.c
diff options
context:
space:
mode:
authorAntti Palosaari <crope@iki.fi>2014-08-25 02:59:36 +0200
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2014-09-21 21:42:31 +0200
commit6b831d78477c9bbfbcb4cb60af13e13bd2c7467e (patch)
tree2549759d70611afb0608ec30f57a0f2590b174a5 /drivers/media/usb/airspy/airspy.c
parentMerge remote-tracking branch 'linus/master' into patchwork (diff)
downloadlinux-6b831d78477c9bbfbcb4cb60af13e13bd2c7467e.tar.xz
linux-6b831d78477c9bbfbcb4cb60af13e13bd2c7467e.zip
[media] airspy: fix error handling on start streaming
Free all reserved USB buffers and URBs on failure. Return all queued buffers to vb2 with state queued on error case. Signed-off-by: Antti Palosaari <crope@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/usb/airspy/airspy.c')
-rw-r--r--drivers/media/usb/airspy/airspy.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/drivers/media/usb/airspy/airspy.c b/drivers/media/usb/airspy/airspy.c
index cb0e515d80ae..56a1ae05ea7b 100644
--- a/drivers/media/usb/airspy/airspy.c
+++ b/drivers/media/usb/airspy/airspy.c
@@ -540,27 +540,49 @@ static int airspy_start_streaming(struct vb2_queue *vq, unsigned int count)
mutex_lock(&s->v4l2_lock);
- set_bit(POWER_ON, &s->flags);
-
s->sequence = 0;
+ set_bit(POWER_ON, &s->flags);
+
ret = airspy_alloc_stream_bufs(s);
if (ret)
- goto err;
+ goto err_clear_bit;
ret = airspy_alloc_urbs(s);
if (ret)
- goto err;
+ goto err_free_stream_bufs;
ret = airspy_submit_urbs(s);
if (ret)
- goto err;
+ goto err_free_urbs;
/* start hardware streaming */
ret = airspy_ctrl_msg(s, CMD_RECEIVER_MODE, 1, 0, NULL, 0);
if (ret)
- goto err;
-err:
+ goto err_kill_urbs;
+
+ goto exit_mutex_unlock;
+
+err_kill_urbs:
+ airspy_kill_urbs(s);
+err_free_urbs:
+ airspy_free_urbs(s);
+err_free_stream_bufs:
+ airspy_free_stream_bufs(s);
+err_clear_bit:
+ clear_bit(POWER_ON, &s->flags);
+
+ /* return all queued buffers to vb2 */
+ {
+ struct airspy_frame_buf *buf, *tmp;
+
+ list_for_each_entry_safe(buf, tmp, &s->queued_bufs, list) {
+ list_del(&buf->list);
+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
+ }
+ }
+
+exit_mutex_unlock:
mutex_unlock(&s->v4l2_lock);
return ret;