diff options
author | Antti Palosaari <crope@iki.fi> | 2014-08-25 02:59:36 +0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2014-09-21 21:42:31 +0200 |
commit | 6b831d78477c9bbfbcb4cb60af13e13bd2c7467e (patch) | |
tree | 2549759d70611afb0608ec30f57a0f2590b174a5 /drivers/media/usb/airspy/airspy.c | |
parent | Merge remote-tracking branch 'linus/master' into patchwork (diff) | |
download | linux-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.c | 36 |
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; |