diff options
author | sensoray-dev <linux-dev@sensoray.com> | 2014-11-04 15:34:03 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2014-11-11 05:47:22 -0500 |
commit | 9694fbec951b9aa56815d423f2c53d17a4a9635c (patch) | |
tree | 53e89ee94f14adc07a61528f0ee7533f70d06d40 | |
parent | 6db47fa1f1a214bc1ea5a59a32f58188f6b255e9 (diff) |
[media] s2255drv: fix spinlock issue
qlock spinlock controls access to buf_list and sequence.
qlock spinlock should not be locked during a copy to video buffers, an
operation that may sleep.
Signed-off-by: Dean Anderson <linux-dev@sensoray.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
-rw-r--r-- | drivers/media/usb/s2255/s2255drv.c | 22 |
1 files changed, 10 insertions, 12 deletions
diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index ccc00099b261..a56a05b0c4e1 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c | |||
@@ -558,27 +558,30 @@ static void s2255_fwchunk_complete(struct urb *urb) | |||
558 | 558 | ||
559 | } | 559 | } |
560 | 560 | ||
561 | static int s2255_got_frame(struct s2255_vc *vc, int jpgsize) | 561 | static void s2255_got_frame(struct s2255_vc *vc, int jpgsize) |
562 | { | 562 | { |
563 | struct s2255_buffer *buf; | 563 | struct s2255_buffer *buf; |
564 | struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev); | 564 | struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev); |
565 | unsigned long flags = 0; | 565 | unsigned long flags = 0; |
566 | int rc = 0; | 566 | |
567 | spin_lock_irqsave(&vc->qlock, flags); | 567 | spin_lock_irqsave(&vc->qlock, flags); |
568 | if (list_empty(&vc->buf_list)) { | 568 | if (list_empty(&vc->buf_list)) { |
569 | dprintk(dev, 1, "No active queue to serve\n"); | 569 | dprintk(dev, 1, "No active queue to serve\n"); |
570 | rc = -1; | 570 | spin_unlock_irqrestore(&vc->qlock, flags); |
571 | goto unlock; | 571 | return; |
572 | } | 572 | } |
573 | buf = list_entry(vc->buf_list.next, | 573 | buf = list_entry(vc->buf_list.next, |
574 | struct s2255_buffer, list); | 574 | struct s2255_buffer, list); |
575 | list_del(&buf->list); | 575 | list_del(&buf->list); |
576 | v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp); | 576 | v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp); |
577 | buf->vb.v4l2_buf.field = vc->field; | ||
578 | buf->vb.v4l2_buf.sequence = vc->frame_count; | ||
579 | spin_unlock_irqrestore(&vc->qlock, flags); | ||
580 | |||
577 | s2255_fillbuff(vc, buf, jpgsize); | 581 | s2255_fillbuff(vc, buf, jpgsize); |
582 | /* tell v4l buffer was filled */ | ||
583 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE); | ||
578 | dprintk(dev, 2, "%s: [buf] [%p]\n", __func__, buf); | 584 | dprintk(dev, 2, "%s: [buf] [%p]\n", __func__, buf); |
579 | unlock: | ||
580 | spin_unlock_irqrestore(&vc->qlock, flags); | ||
581 | return rc; | ||
582 | } | 585 | } |
583 | 586 | ||
584 | static const struct s2255_fmt *format_by_fourcc(int fourcc) | 587 | static const struct s2255_fmt *format_by_fourcc(int fourcc) |
@@ -649,11 +652,6 @@ static void s2255_fillbuff(struct s2255_vc *vc, | |||
649 | } | 652 | } |
650 | dprintk(dev, 2, "s2255fill at : Buffer 0x%08lx size= %d\n", | 653 | dprintk(dev, 2, "s2255fill at : Buffer 0x%08lx size= %d\n", |
651 | (unsigned long)vbuf, pos); | 654 | (unsigned long)vbuf, pos); |
652 | /* tell v4l buffer was filled */ | ||
653 | buf->vb.v4l2_buf.field = vc->field; | ||
654 | buf->vb.v4l2_buf.sequence = vc->frame_count; | ||
655 | v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp); | ||
656 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE); | ||
657 | } | 655 | } |
658 | 656 | ||
659 | 657 | ||