mirror of
https://github.com/torvalds/linux.git
synced 2024-11-17 09:31:50 +00:00
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:
commit
eb55a2a95d
@ -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>
|
||||||
|
|
||||||
|
@ -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>
|
||||||
|
@ -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;
|
||||||
|
@ -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>
|
||||||
|
@ -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;
|
||||||
|
@ -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");
|
||||||
|
@ -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;
|
||||||
|
@ -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>
|
||||||
|
@ -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);
|
||||||
|
@ -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 */
|
||||||
|
@ -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;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user