spin_lock_init(&queue->irqlock);
INIT_LIST_HEAD(&queue->mainqueue);
INIT_LIST_HEAD(&queue->irqqueue);
+ init_waitqueue_head(&queue->wait); /* ddl@rock-chips.com : This design copied from video-buf */
queue->flags = drop_corrupted ? UVC_QUEUE_DROP_CORRUPTED : 0;
queue->type = type;
}
list_add_tail(&buf->queue, &queue->irqqueue);
spin_unlock_irqrestore(&queue->irqlock, flags);
+ wake_up_interruptible_sync(&queue->wait); /* ddl@rock-chips.com : This design copied from video-buf */
+
done:
mutex_unlock(&queue->mutex);
return ret;
buf->state != UVC_BUF_STATE_READY)
? 0 : -EAGAIN;
}
-
+#if 0
return wait_event_interruptible(buf->wait,
buf->state != UVC_BUF_STATE_QUEUED &&
buf->state != UVC_BUF_STATE_ACTIVE &&
buf->state != UVC_BUF_STATE_READY);
+#else
+ /* ddl@rock-chips.com: wait_event_interruptible -> wait_event_interruptible_timeout */
+ return wait_event_interruptible_timeout(buf->wait,
+ buf->state != UVC_BUF_STATE_QUEUED &&
+ buf->state != UVC_BUF_STATE_ACTIVE &&
+ buf->state != UVC_BUF_STATE_READYi,
+ msecs_to_jiffies(800);
}
/*
}
mutex_lock(&queue->mutex);
+ /* ddl@rock-chips.com : This design copied from video-buf */
+checks:
if (list_empty(&queue->mainqueue)) {
- uvc_trace(UVC_TRACE_CAPTURE, "[E] Empty buffer queue.\n");
- ret = -EINVAL;
- goto done;
+ if (nonblocking) {
+ uvc_trace(UVC_TRACE_CAPTURE, "[E] Empty buffer queue.\n");
+ ret = -EINVAL;
+ goto done;
+ } else {
+ //uvc_trace(UVC_TRACE_CAPTURE, "dequeue_buffer: waiting on buffer\n");
+ printk("dequeue_buffer: waiting on buffer\n");
+ /* Drop lock to avoid deadlock with qbuf */
+ mutex_unlock(&queue->mutex);
+
+ /* Checking list_empty and streaming is safe without
+ * locks because we goto checks to validate while
+ * holding locks before proceeding */
+ ret = wait_event_interruptible(queue->wait,
+ ((!list_empty(&queue->mainqueue)) || (!(queue->flags & UVC_QUEUE_STREAMING))));
+ mutex_lock(&queue->mutex);
+
+ if (ret)
+ goto done;
+
+ goto checks;
+ }
}
buf = list_first_entry(&queue->mainqueue, struct uvc_buffer, stream);
- if ((ret = uvc_queue_waiton(buf, nonblocking)) < 0)
+ if ((ret = uvc_queue_waiton(buf, nonblocking)) <= 0) {
+ /* ddl@rock-chips.com: It is timeout */
+ if (ret == 0) {
+ ret = -EINVAL;
+ printk(KERN_ERR "uvcvideo: uvc_dequeue_buffer is timeout!!");
+ } else {
+ printk(KERN_ERR "uvcvideo: uvc_dequeue_buffer is failed!!(ret:%d)",ret);
+ }
goto done;
+ }
uvc_trace(UVC_TRACE_CAPTURE, "Dequeuing buffer %u (%u, %u bytes).\n",
buf->buf.index, buf->state, buf->buf.bytesused);
struct uvc_buffer *buf;
unsigned long flags;
+ wake_up_interruptible_sync(&queue->wait); /* ddl@rock-chips.com : This design copied from video-buf */
+
spin_lock_irqsave(&queue->irqlock, flags);
while (!list_empty(&queue->irqqueue)) {
buf = list_first_entry(&queue->irqqueue, struct uvc_buffer,