From patchwork Wed Dec 16 10:49:38 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 68340 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.2) with ESMTP id nBI4ixmr005715 for ; Fri, 18 Dec 2009 04:45:49 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752315AbZLPKrj (ORCPT ); Wed, 16 Dec 2009 05:47:39 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753032AbZLPKrj (ORCPT ); Wed, 16 Dec 2009 05:47:39 -0500 Received: from perceval.irobotique.be ([92.243.18.41]:37530 "EHLO perceval.irobotique.be" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752283AbZLPKrj (ORCPT ); Wed, 16 Dec 2009 05:47:39 -0500 Received: from ravenclaw.localnet (154.22-245-81.adsl-static.isp.belgacom.be [81.245.22.154]) by perceval.irobotique.be (Postfix) with ESMTPSA id 72D0835A10; Wed, 16 Dec 2009 10:47:35 +0000 (UTC) From: Laurent Pinchart To: Pablo Baena Subject: Re: uvcvideo kernel panic when using libv4l Date: Wed, 16 Dec 2009 11:49:38 +0100 User-Agent: KMail/1.12.4 (Linux/2.6.32; KDE/4.3.4; x86_64; ; ) Cc: "lcostantino@gmail.com" , linux-media@vger.kernel.org, Hans de Goede References: <36be2c7a0912070918h23cee33bia26c85b13d242ca9@mail.gmail.com> <200912160112.41754.laurent.pinchart@ideasonboard.com> <36be2c7a0912152251l6e1eb991t773dd26f0a973941@mail.gmail.com> In-Reply-To: <36be2c7a0912152251l6e1eb991t773dd26f0a973941@mail.gmail.com> MIME-Version: 1.0 Message-Id: <200912161149.38618.laurent.pinchart@ideasonboard.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org diff -r c1f376eae978 linux/drivers/media/video/uvc/uvc_queue.c --- a/linux/drivers/media/video/uvc/uvc_queue.c Sat Dec 12 18:57:17 2009 +0100 +++ b/linux/drivers/media/video/uvc/uvc_queue.c Wed Dec 16 11:47:40 2009 +0100 @@ -59,7 +59,7 @@ * returns immediately. * * When the buffer is full, the completion handler removes it from the irq - * queue, marks it as ready (UVC_BUF_STATE_DONE) and wakes its wait queue. + * queue, marks it as ready (UVC_BUF_STATE_READY) and wakes its wait queue. * At that point, any process waiting on the buffer will be woken up. If a * process tries to dequeue a buffer after it has been marked ready, the * dequeing will succeed immediately. @@ -196,11 +196,12 @@ switch (buf->state) { case UVC_BUF_STATE_ERROR: - case UVC_BUF_STATE_DONE: + case UVC_BUF_STATE_READY: v4l2_buf->flags |= V4L2_BUF_FLAG_DONE; break; case UVC_BUF_STATE_QUEUED: case UVC_BUF_STATE_ACTIVE: + case UVC_BUF_STATE_DONE: v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED; break; case UVC_BUF_STATE_IDLE: @@ -295,13 +296,15 @@ { if (nonblocking) { return (buf->state != UVC_BUF_STATE_QUEUED && - buf->state != UVC_BUF_STATE_ACTIVE) + buf->state != UVC_BUF_STATE_ACTIVE && + buf->state != UVC_BUF_STATE_DONE) ? 0 : -EAGAIN; } return wait_event_interruptible(buf->wait, buf->state != UVC_BUF_STATE_QUEUED && - buf->state != UVC_BUF_STATE_ACTIVE); + buf->state != UVC_BUF_STATE_ACTIVE && + buf->state != UVC_BUF_STATE_DONE); } /* @@ -341,13 +344,14 @@ uvc_trace(UVC_TRACE_CAPTURE, "[W] Corrupted data " "(transmission error).\n"); ret = -EIO; - case UVC_BUF_STATE_DONE: + case UVC_BUF_STATE_READY: buf->state = UVC_BUF_STATE_IDLE; break; case UVC_BUF_STATE_IDLE: case UVC_BUF_STATE_QUEUED: case UVC_BUF_STATE_ACTIVE: + case UVC_BUF_STATE_DONE: default: uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer state %u " "(driver bug?).\n", buf->state); @@ -383,7 +387,7 @@ buf = list_first_entry(&queue->mainqueue, struct uvc_buffer, stream); poll_wait(file, &buf->wait, wait); - if (buf->state == UVC_BUF_STATE_DONE || + if (buf->state == UVC_BUF_STATE_READY || buf->state == UVC_BUF_STATE_ERROR) mask |= POLLIN | POLLRDNORM; @@ -489,6 +493,7 @@ spin_lock_irqsave(&queue->irqlock, flags); list_del(&buf->queue); + buf->state = UVC_BUF_STATE_READY; if (!list_empty(&queue->irqqueue)) nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer, queue); diff -r c1f376eae978 linux/drivers/media/video/uvc/uvc_video.c --- a/linux/drivers/media/video/uvc/uvc_video.c Sat Dec 12 18:57:17 2009 +0100 +++ b/linux/drivers/media/video/uvc/uvc_video.c Wed Dec 16 11:47:40 2009 +0100 @@ -578,8 +578,7 @@ uvc_video_decode_end(stream, buf, mem, urb->iso_frame_desc[i].actual_length); - if (buf->state == UVC_BUF_STATE_DONE || - buf->state == UVC_BUF_STATE_ERROR) + if (buf->state == UVC_BUF_STATE_DONE) buf = uvc_queue_next_buffer(&stream->queue, buf); } } @@ -637,8 +636,7 @@ if (!stream->bulk.skip_payload && buf != NULL) { uvc_video_decode_end(stream, buf, stream->bulk.header, stream->bulk.payload_size); - if (buf->state == UVC_BUF_STATE_DONE || - buf->state == UVC_BUF_STATE_ERROR) + if (buf->state == UVC_BUF_STATE_DONE) buf = uvc_queue_next_buffer(&stream->queue, buf); } diff -r c1f376eae978 linux/drivers/media/video/uvc/uvcvideo.h --- a/linux/drivers/media/video/uvc/uvcvideo.h Sat Dec 12 18:57:17 2009 +0100 +++ b/linux/drivers/media/video/uvc/uvcvideo.h Wed Dec 16 11:47:40 2009 +0100 @@ -370,7 +370,8 @@ UVC_BUF_STATE_QUEUED = 1, UVC_BUF_STATE_ACTIVE = 2, UVC_BUF_STATE_DONE = 3, - UVC_BUF_STATE_ERROR = 4, + UVC_BUF_STATE_READY = 4, + UVC_BUF_STATE_ERROR = 5, }; struct uvc_buffer {