media fixes for v3.17-rc7

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJUIpioAAoJEAhfPr2O5OEVlz4QAIpVEnN7p/L2AMEbpzVYEu3f
 hk47HnIBQyCHLMZgjMVNglkXwoOUg4qOF25S16Qgyq8S2Rf/+urP4nBaaGla1C9O
 tYSMih8KpinHtDeSAiEfFF+IKx1M3m0YS/4vSlSrsb0iQnDBuKOCPLQ4C0fvGEFh
 NXjYdAL6rYRvLby9XWaCqgHK10rjeNdLC9R1tZpqtpli1CMlODowfC1IZC0dA+V6
 hs7mnBFk8pkTPrEbcXrifMQqsIDCtkTKRV4VdLCYJA1cz5x3pIQLTmeXIrAcUUjR
 Dygc8evyvUviSm2tQx4KKgX40Qr6yEO06RMrLP4HgTyqMMJqrYJ6xXryA1HpXSwG
 vTCoY++5rlW7xLKO7WOp9oLBuLfayW8CMZZY3dcv1pqi6mo195qdhANRsm0IRmV9
 v9QNrsrPq83TjxolvtU3qUtU80qhovh8nRRxGb2efzhIy6Q6qtw1nfxLIhvFTr7C
 chtSzHeNUnfYU+GVQMEUopM6WYzj2/2O9YDGpMTTaTDiu2iX+AwihzoXdn/9OyXl
 tMsovLOEBjBf4fDfLmEKAMTA11S06QA31COAkGjEZZLPhg9PE4rgBrTX1PxagDHI
 +gA4zxYF4/YSDwrWJSN+laK4scU+pPvG1njnHg18Mj4SCH1+34TyFMzQ5aJgxZ8h
 xh9tmnj5x68BPsXlcJ/f
 =nEDO
 -----END PGP SIGNATURE-----

Merge tag 'media/v3.17-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull media fixes from Mauro Carvalho Chehab:
 "For some last time fixes:
   - a regression detected on Kernel 3.16 related to VBI Teletext
     application breakage on drivers using videobuf2 (see
     https://bugzilla.kernel.org/show_bug.cgi?id=84401).  The bug was
     noticed on saa7134 (migrated to VB2 on 3.16), but also affects
     em28xx (migrated on 3.9 to VB2);
   - two additional sanity checks at videobuf2;
   - two fixups to restore proper VBI support at the em28xx driver;
   - two Kernel oops fixups (at cx24123 and cx2341x drivers);
   - a bug at adv7604 where an if was doing just the opposite as it
     would be expected;
   - some documentation fixups to match the behavior defined at the
     Kernel"

* tag 'media/v3.17-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media:
  [media] em28xx-v4l: get rid of field "users" in struct em28xx_v4l2"
  [media] em28xx: fix VBI handling logic
  [media] DocBook media: improve the poll() documentation
  [media] DocBook media: fix the poll() 'no QBUF' documentation
  [media] vb2: fix VBI/poll regression
  [media] cx2341x: fix kernel oops
  [media] cx24123: fix kernel oops due to missing parent pointer
  [media] adv7604: fix inverted condition
  [media] media/radio: fix radio-miropcm20.c build with io.h header file
  [media] vb2: fix plane index sanity check in vb2_plane_cookie()
  [media] DocBook media: update version number and V4L2 changes
  [media] DocBook media: fix fieldname in struct v4l2_subdev_selection
  [media] vb2: fix vb2 state check when start_streaming fails
  [media] videobuf2-core.h: fix comment
  [media] videobuf2-core: add comments before the WARN_ON
  [media] videobuf2-dma-sg: fix for wrong GFP mask to sg_alloc_table_from_pages
This commit is contained in:
Linus Torvalds 2014-09-24 09:03:43 -07:00
commit eb55a2a95d
13 changed files with 119 additions and 40 deletions

View File

@ -2545,6 +2545,30 @@ fields changed from _s32 to _u32.
</orderedlist> </orderedlist>
</section> </section>
<section>
<title>V4L2 in Linux 3.16</title>
<orderedlist>
<listitem>
<para>Added event V4L2_EVENT_SOURCE_CHANGE.
</para>
</listitem>
</orderedlist>
</section>
<section>
<title>V4L2 in Linux 3.17</title>
<orderedlist>
<listitem>
<para>Extended &v4l2-pix-format;. Added format flags.
</para>
</listitem>
<listitem>
<para>Added compound control types and &VIDIOC-QUERY-EXT-CTRL;.
</para>
</listitem>
</orderedlist>
</section>
<section id="other"> <section id="other">
<title>Relation of V4L2 to other Linux multimedia APIs</title> <title>Relation of V4L2 to other Linux multimedia APIs</title>

View File

@ -29,9 +29,12 @@ can suspend execution until the driver has captured data or is ready
to accept data for output.</para> to accept data for output.</para>
<para>When streaming I/O has been negotiated this function waits <para>When streaming I/O has been negotiated this function waits
until a buffer has been filled or displayed and can be dequeued with until a buffer has been filled by the capture device and can be dequeued
the &VIDIOC-DQBUF; ioctl. When buffers are already in the outgoing with the &VIDIOC-DQBUF; ioctl. For output devices this function waits
queue of the driver the function returns immediately.</para> until the device is ready to accept a new buffer to be queued up with
the &VIDIOC-QBUF; ioctl for display. When buffers are already in the outgoing
queue of the driver (capture) or the incoming queue isn't full (display)
the function returns immediately.</para>
<para>On success <function>poll()</function> returns the number of <para>On success <function>poll()</function> returns the number of
file descriptors that have been selected (that is, file descriptors file descriptors that have been selected (that is, file descriptors
@ -44,10 +47,22 @@ Capture devices set the <constant>POLLIN</constant> and
flags. When the function timed out it returns a value of zero, on flags. When the function timed out it returns a value of zero, on
failure it returns <returnvalue>-1</returnvalue> and the failure it returns <returnvalue>-1</returnvalue> and the
<varname>errno</varname> variable is set appropriately. When the <varname>errno</varname> variable is set appropriately. When the
application did not call &VIDIOC-QBUF; or &VIDIOC-STREAMON; yet the application did not call &VIDIOC-STREAMON; the
<function>poll()</function> function succeeds, but sets the <function>poll()</function> function succeeds, but sets the
<constant>POLLERR</constant> flag in the <constant>POLLERR</constant> flag in the
<structfield>revents</structfield> field.</para> <structfield>revents</structfield> field. When the
application has called &VIDIOC-STREAMON; for a capture device but hasn't
yet called &VIDIOC-QBUF;, the <function>poll()</function> function
succeeds and sets the <constant>POLLERR</constant> flag in the
<structfield>revents</structfield> field. For output devices this
same situation will cause <function>poll()</function> to succeed
as well, but it sets the <constant>POLLOUT</constant> and
<constant>POLLWRNORM</constant> flags in the <structfield>revents</structfield>
field.</para>
<para>If an event occurred (see &VIDIOC-DQEVENT;) then
<constant>POLLPRI</constant> will be set in the <structfield>revents</structfield>
field and <function>poll()</function> will return.</para>
<para>When use of the <function>read()</function> function has <para>When use of the <function>read()</function> function has
been negotiated and the driver does not capture yet, the been negotiated and the driver does not capture yet, the
@ -58,10 +73,18 @@ continuously (as opposed to, for example, still images) the function
may return immediately.</para> may return immediately.</para>
<para>When use of the <function>write()</function> function has <para>When use of the <function>write()</function> function has
been negotiated the <function>poll</function> function just waits been negotiated and the driver does not stream yet, the
<function>poll</function> function starts streaming. When that fails
it returns a <constant>POLLERR</constant> as above. Otherwise it waits
until the driver is ready for a non-blocking until the driver is ready for a non-blocking
<function>write()</function> call.</para> <function>write()</function> call.</para>
<para>If the caller is only interested in events (just
<constant>POLLPRI</constant> is set in the <structfield>events</structfield>
field), then <function>poll()</function> will <emphasis>not</emphasis>
start streaming if the driver does not stream yet. This makes it
possible to just poll for events and not for buffers.</para>
<para>All drivers implementing the <function>read()</function> or <para>All drivers implementing the <function>read()</function> or
<function>write()</function> function or streaming I/O must also <function>write()</function> function or streaming I/O must also
support the <function>poll()</function> function.</para> support the <function>poll()</function> function.</para>

View File

@ -152,10 +152,11 @@ structs, ioctls) must be noted in more detail in the history chapter
applications. --> applications. -->
<revision> <revision>
<revnumber>3.16</revnumber> <revnumber>3.17</revnumber>
<date>2014-05-27</date> <date>2014-08-04</date>
<authorinitials>lp</authorinitials> <authorinitials>lp, hv</authorinitials>
<revremark>Extended &v4l2-pix-format;. Added format flags. <revremark>Extended &v4l2-pix-format;. Added format flags. Added compound control types
and VIDIOC_QUERY_EXT_CTRL.
</revremark> </revremark>
</revision> </revision>
@ -538,7 +539,7 @@ and discussions on the V4L mailing list.</revremark>
</partinfo> </partinfo>
<title>Video for Linux Two API Specification</title> <title>Video for Linux Two API Specification</title>
<subtitle>Revision 3.14</subtitle> <subtitle>Revision 3.17</subtitle>
<chapter id="common"> <chapter id="common">
&sub-common; &sub-common;

View File

@ -119,7 +119,7 @@
</row> </row>
<row> <row>
<entry>&v4l2-rect;</entry> <entry>&v4l2-rect;</entry>
<entry><structfield>rect</structfield></entry> <entry><structfield>r</structfield></entry>
<entry>Selection rectangle, in pixels.</entry> <entry>Selection rectangle, in pixels.</entry>
</row> </row>
<row> <row>

View File

@ -1490,6 +1490,7 @@ static struct v4l2_ctrl *cx2341x_ctrl_new_custom(struct v4l2_ctrl_handler *hdl,
{ {
struct v4l2_ctrl_config cfg; struct v4l2_ctrl_config cfg;
memset(&cfg, 0, sizeof(cfg));
cx2341x_ctrl_fill(id, &cfg.name, &cfg.type, &min, &max, &step, &def, &cfg.flags); cx2341x_ctrl_fill(id, &cfg.name, &cfg.type, &min, &max, &step, &def, &cfg.flags);
cfg.ops = &cx2341x_ops; cfg.ops = &cx2341x_ops;
cfg.id = id; cfg.id = id;

View File

@ -1095,6 +1095,7 @@ struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
sizeof(state->tuner_i2c_adapter.name)); sizeof(state->tuner_i2c_adapter.name));
state->tuner_i2c_adapter.algo = &cx24123_tuner_i2c_algo; state->tuner_i2c_adapter.algo = &cx24123_tuner_i2c_algo;
state->tuner_i2c_adapter.algo_data = NULL; state->tuner_i2c_adapter.algo_data = NULL;
state->tuner_i2c_adapter.dev.parent = i2c->dev.parent;
i2c_set_adapdata(&state->tuner_i2c_adapter, state); i2c_set_adapdata(&state->tuner_i2c_adapter, state);
if (i2c_add_adapter(&state->tuner_i2c_adapter) < 0) { if (i2c_add_adapter(&state->tuner_i2c_adapter) < 0) {
err("tuner i2c bus could not be initialized\n"); err("tuner i2c bus could not be initialized\n");

View File

@ -2325,7 +2325,7 @@ static int adv7604_log_status(struct v4l2_subdev *sd)
v4l2_info(sd, "HDCP keys read: %s%s\n", v4l2_info(sd, "HDCP keys read: %s%s\n",
(hdmi_read(sd, 0x04) & 0x20) ? "yes" : "no", (hdmi_read(sd, 0x04) & 0x20) ? "yes" : "no",
(hdmi_read(sd, 0x04) & 0x10) ? "ERROR" : ""); (hdmi_read(sd, 0x04) & 0x10) ? "ERROR" : "");
if (!is_hdmi(sd)) { if (is_hdmi(sd)) {
bool audio_pll_locked = hdmi_read(sd, 0x04) & 0x01; bool audio_pll_locked = hdmi_read(sd, 0x04) & 0x01;
bool audio_sample_packet_detect = hdmi_read(sd, 0x18) & 0x01; bool audio_sample_packet_detect = hdmi_read(sd, 0x18) & 0x01;
bool audio_mute = io_read(sd, 0x65) & 0x40; bool audio_mute = io_read(sd, 0x65) & 0x40;

View File

@ -27,6 +27,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/io.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/videodev2.h> #include <linux/videodev2.h>
#include <linux/kthread.h> #include <linux/kthread.h>

View File

@ -1342,7 +1342,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct em28xx *dev = video_drvdata(file); struct em28xx *dev = video_drvdata(file);
struct em28xx_v4l2 *v4l2 = dev->v4l2; struct em28xx_v4l2 *v4l2 = dev->v4l2;
if (v4l2->streaming_users > 0) if (vb2_is_busy(&v4l2->vb_vidq))
return -EBUSY; return -EBUSY;
vidioc_try_fmt_vid_cap(file, priv, f); vidioc_try_fmt_vid_cap(file, priv, f);
@ -1883,8 +1883,9 @@ static int em28xx_v4l2_open(struct file *filp)
return -EINVAL; return -EINVAL;
} }
em28xx_videodbg("open dev=%s type=%s\n", em28xx_videodbg("open dev=%s type=%s users=%d\n",
video_device_node_name(vdev), v4l2_type_names[fh_type]); video_device_node_name(vdev), v4l2_type_names[fh_type],
v4l2->users);
if (mutex_lock_interruptible(&dev->lock)) if (mutex_lock_interruptible(&dev->lock))
return -ERESTARTSYS; return -ERESTARTSYS;
@ -1897,9 +1898,7 @@ static int em28xx_v4l2_open(struct file *filp)
return ret; return ret;
} }
if (v4l2_fh_is_singular_file(filp)) { if (v4l2->users == 0) {
em28xx_videodbg("first opened filehandle, initializing device\n");
em28xx_set_mode(dev, EM28XX_ANALOG_MODE); em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
if (vdev->vfl_type != VFL_TYPE_RADIO) if (vdev->vfl_type != VFL_TYPE_RADIO)
@ -1910,8 +1909,6 @@ static int em28xx_v4l2_open(struct file *filp)
* of some i2c devices * of some i2c devices
*/ */
em28xx_wake_i2c(dev); em28xx_wake_i2c(dev);
} else {
em28xx_videodbg("further filehandles are already opened\n");
} }
if (vdev->vfl_type == VFL_TYPE_RADIO) { if (vdev->vfl_type == VFL_TYPE_RADIO) {
@ -1921,6 +1918,7 @@ static int em28xx_v4l2_open(struct file *filp)
kref_get(&dev->ref); kref_get(&dev->ref);
kref_get(&v4l2->ref); kref_get(&v4l2->ref);
v4l2->users++;
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
@ -2027,11 +2025,12 @@ static int em28xx_v4l2_close(struct file *filp)
struct em28xx_v4l2 *v4l2 = dev->v4l2; struct em28xx_v4l2 *v4l2 = dev->v4l2;
int errCode; int errCode;
em28xx_videodbg("users=%d\n", v4l2->users);
vb2_fop_release(filp);
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
if (v4l2_fh_is_singular_file(filp)) { if (v4l2->users == 1) {
em28xx_videodbg("last opened filehandle, shutting down device\n");
/* No sense to try to write to the device */ /* No sense to try to write to the device */
if (dev->disconnected) if (dev->disconnected)
goto exit; goto exit;
@ -2050,12 +2049,10 @@ static int em28xx_v4l2_close(struct file *filp)
em28xx_errdev("cannot change alternate number to " em28xx_errdev("cannot change alternate number to "
"0 (error=%i)\n", errCode); "0 (error=%i)\n", errCode);
} }
} else {
em28xx_videodbg("further opened filehandles left\n");
} }
exit: exit:
vb2_fop_release(filp); v4l2->users--;
kref_put(&v4l2->ref, em28xx_free_v4l2); kref_put(&v4l2->ref, em28xx_free_v4l2);
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
kref_put(&dev->ref, em28xx_free_device); kref_put(&dev->ref, em28xx_free_device);

View File

@ -524,6 +524,7 @@ struct em28xx_v4l2 {
int sensor_yres; int sensor_yres;
int sensor_xtal; int sensor_xtal;
int users; /* user count for exclusive use */
int streaming_users; /* number of actively streaming users */ int streaming_users; /* number of actively streaming users */
u32 frequency; /* selected tuner frequency */ u32 frequency; /* selected tuner frequency */

View File

@ -971,6 +971,7 @@ static int __reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
* to the userspace. * to the userspace.
*/ */
req->count = allocated_buffers; req->count = allocated_buffers;
q->waiting_for_buffers = !V4L2_TYPE_IS_OUTPUT(q->type);
return 0; return 0;
} }
@ -1018,6 +1019,7 @@ static int __create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create
memset(q->plane_sizes, 0, sizeof(q->plane_sizes)); memset(q->plane_sizes, 0, sizeof(q->plane_sizes));
memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx)); memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx));
q->memory = create->memory; q->memory = create->memory;
q->waiting_for_buffers = !V4L2_TYPE_IS_OUTPUT(q->type);
} }
num_buffers = min(create->count, VIDEO_MAX_FRAME - q->num_buffers); num_buffers = min(create->count, VIDEO_MAX_FRAME - q->num_buffers);
@ -1130,7 +1132,7 @@ EXPORT_SYMBOL_GPL(vb2_plane_vaddr);
*/ */
void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no) void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no)
{ {
if (plane_no > vb->num_planes || !vb->planes[plane_no].mem_priv) if (plane_no >= vb->num_planes || !vb->planes[plane_no].mem_priv)
return NULL; return NULL;
return call_ptr_memop(vb, cookie, vb->planes[plane_no].mem_priv); return call_ptr_memop(vb, cookie, vb->planes[plane_no].mem_priv);
@ -1165,13 +1167,10 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state)
if (WARN_ON(vb->state != VB2_BUF_STATE_ACTIVE)) if (WARN_ON(vb->state != VB2_BUF_STATE_ACTIVE))
return; return;
if (!q->start_streaming_called) { if (WARN_ON(state != VB2_BUF_STATE_DONE &&
if (WARN_ON(state != VB2_BUF_STATE_QUEUED)) state != VB2_BUF_STATE_ERROR &&
state = VB2_BUF_STATE_QUEUED; state != VB2_BUF_STATE_QUEUED))
} else if (WARN_ON(state != VB2_BUF_STATE_DONE &&
state != VB2_BUF_STATE_ERROR)) {
state = VB2_BUF_STATE_ERROR; state = VB2_BUF_STATE_ERROR;
}
#ifdef CONFIG_VIDEO_ADV_DEBUG #ifdef CONFIG_VIDEO_ADV_DEBUG
/* /*
@ -1762,6 +1761,12 @@ static int vb2_start_streaming(struct vb2_queue *q)
q->start_streaming_called = 0; q->start_streaming_called = 0;
dprintk(1, "driver refused to start streaming\n"); dprintk(1, "driver refused to start streaming\n");
/*
* If you see this warning, then the driver isn't cleaning up properly
* after a failed start_streaming(). See the start_streaming()
* documentation in videobuf2-core.h for more information how buffers
* should be returned to vb2 in start_streaming().
*/
if (WARN_ON(atomic_read(&q->owned_by_drv_count))) { if (WARN_ON(atomic_read(&q->owned_by_drv_count))) {
unsigned i; unsigned i;
@ -1777,6 +1782,12 @@ static int vb2_start_streaming(struct vb2_queue *q)
/* Must be zero now */ /* Must be zero now */
WARN_ON(atomic_read(&q->owned_by_drv_count)); WARN_ON(atomic_read(&q->owned_by_drv_count));
} }
/*
* If done_list is not empty, then start_streaming() didn't call
* vb2_buffer_done(vb, VB2_BUF_STATE_QUEUED) but STATE_ERROR or
* STATE_DONE.
*/
WARN_ON(!list_empty(&q->done_list));
return ret; return ret;
} }
@ -1812,6 +1823,7 @@ static int vb2_internal_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
*/ */
list_add_tail(&vb->queued_entry, &q->queued_list); list_add_tail(&vb->queued_entry, &q->queued_list);
q->queued_count++; q->queued_count++;
q->waiting_for_buffers = false;
vb->state = VB2_BUF_STATE_QUEUED; vb->state = VB2_BUF_STATE_QUEUED;
if (V4L2_TYPE_IS_OUTPUT(q->type)) { if (V4L2_TYPE_IS_OUTPUT(q->type)) {
/* /*
@ -2123,6 +2135,12 @@ static void __vb2_queue_cancel(struct vb2_queue *q)
if (q->start_streaming_called) if (q->start_streaming_called)
call_void_qop(q, stop_streaming, q); call_void_qop(q, stop_streaming, q);
/*
* If you see this warning, then the driver isn't cleaning up properly
* in stop_streaming(). See the stop_streaming() documentation in
* videobuf2-core.h for more information how buffers should be returned
* to vb2 in stop_streaming().
*/
if (WARN_ON(atomic_read(&q->owned_by_drv_count))) { if (WARN_ON(atomic_read(&q->owned_by_drv_count))) {
for (i = 0; i < q->num_buffers; ++i) for (i = 0; i < q->num_buffers; ++i)
if (q->bufs[i]->state == VB2_BUF_STATE_ACTIVE) if (q->bufs[i]->state == VB2_BUF_STATE_ACTIVE)
@ -2272,6 +2290,7 @@ static int vb2_internal_streamoff(struct vb2_queue *q, enum v4l2_buf_type type)
* their normal dequeued state. * their normal dequeued state.
*/ */
__vb2_queue_cancel(q); __vb2_queue_cancel(q);
q->waiting_for_buffers = !V4L2_TYPE_IS_OUTPUT(q->type);
dprintk(3, "successful\n"); dprintk(3, "successful\n");
return 0; return 0;
@ -2590,10 +2609,17 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
} }
/* /*
* There is nothing to wait for if no buffer has been queued and the * There is nothing to wait for if the queue isn't streaming, or if the
* queue isn't streaming, or if the error flag is set. * error flag is set.
*/ */
if ((list_empty(&q->queued_list) && !vb2_is_streaming(q)) || q->error) if (!vb2_is_streaming(q) || q->error)
return res | POLLERR;
/*
* For compatibility with vb1: if QBUF hasn't been called yet, then
* return POLLERR as well. This only affects capture queues, output
* queues will always initialize waiting_for_buffers to false.
*/
if (q->waiting_for_buffers)
return res | POLLERR; return res | POLLERR;
/* /*

View File

@ -113,7 +113,7 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, gfp_t gfp_fla
goto fail_pages_alloc; goto fail_pages_alloc;
ret = sg_alloc_table_from_pages(&buf->sg_table, buf->pages, ret = sg_alloc_table_from_pages(&buf->sg_table, buf->pages,
buf->num_pages, 0, size, gfp_flags); buf->num_pages, 0, size, GFP_KERNEL);
if (ret) if (ret)
goto fail_table_alloc; goto fail_table_alloc;

View File

@ -295,7 +295,7 @@ struct vb2_buffer {
* can return an error if hardware fails, in that case all * can return an error if hardware fails, in that case all
* buffers that have been already given by the @buf_queue * buffers that have been already given by the @buf_queue
* callback are to be returned by the driver by calling * callback are to be returned by the driver by calling
* @vb2_buffer_done(VB2_BUF_STATE_DEQUEUED). * @vb2_buffer_done(VB2_BUF_STATE_QUEUED).
* If you need a minimum number of buffers before you can * If you need a minimum number of buffers before you can
* start streaming, then set @min_buffers_needed in the * start streaming, then set @min_buffers_needed in the
* vb2_queue structure. If that is non-zero then * vb2_queue structure. If that is non-zero then
@ -380,6 +380,9 @@ struct v4l2_fh;
* @start_streaming_called: start_streaming() was called successfully and we * @start_streaming_called: start_streaming() was called successfully and we
* started streaming. * started streaming.
* @error: a fatal error occurred on the queue * @error: a fatal error occurred on the queue
* @waiting_for_buffers: used in poll() to check if vb2 is still waiting for
* buffers. Only set for capture queues if qbuf has not yet been
* called since poll() needs to return POLLERR in that situation.
* @fileio: file io emulator internal data, used only if emulator is active * @fileio: file io emulator internal data, used only if emulator is active
* @threadio: thread io internal data, used only if thread is active * @threadio: thread io internal data, used only if thread is active
*/ */
@ -417,6 +420,7 @@ struct vb2_queue {
unsigned int streaming:1; unsigned int streaming:1;
unsigned int start_streaming_called:1; unsigned int start_streaming_called:1;
unsigned int error:1; unsigned int error:1;
unsigned int waiting_for_buffers:1;
struct vb2_fileio_data *fileio; struct vb2_fileio_data *fileio;
struct vb2_threadio_data *threadio; struct vb2_threadio_data *threadio;