From 09fc9802c31a9358a4e34642aa5f569111752879 Mon Sep 17 00:00:00 2001 From: Simon Farnsworth Date: Mon, 5 Sep 2011 12:23:12 -0300 Subject: [media] cx18: Fix videobuf capture When we moved to 3.0, we found that the cx18 driver was oopsing on close with: NULL pointer deref at: [ 2290.461009] Call Trace: [ 2290.461009] [] ? pm_qos_add_request+0xc/0x6e [ 2290.461009] [] __mutex_lock_common+0x87/0x125 [ 2290.461009] [] ? cx18_queue_flush+0x31/0x87 [cx18] [ 2290.461009] [] ? __might_sleep+0x29/0xe4 [ 2290.461009] [] __mutex_lock_slowpath+0x25/0x27 [ 2290.461009] [] ? mutex_lock+0x2e/0x3b [ 2290.461009] [] mutex_lock+0x2e/0x3b [ 2290.461009] [] videobuf_queue_lock+0x13/0x15 [videobuf_core] [ 2290.461009] [] __videobuf_free+0xfc/0x112 [videobuf_core] [ 2290.461009] [] cx18_v4l2_close+0x158/0x172 [cx18] [ 2290.461009] [] ? cpumask_next+0x1a/0x1d [ 2290.461009] [] v4l2_release+0x35/0x52 [videodev] [ 2290.461009] [] fput+0x100/0x1a5 [ 2290.461009] [] filp_close+0x5c/0x64 [ 2290.461009] [] sys_close+0x5f/0x93 [ 2290.461009] [] sysenter_do_call+0x12/0x28 Some digging showed that a merge at some previous point partially added broken mmap() support, causing this trace. Remove the broken code completely. On top of that, the calculation in place for "buffer full" depended on UYUV instead of HM12, while our GStreamer code was picking HM12 in some circumstances. Finally, the V4L2_CAP_STREAMING capability was never exposed. Patch it into the YUV encoder node only. Signed-off-by: Simon Farnsworth Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-ioctl.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'drivers/media/video/cx18/cx18-ioctl.c') diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index afe0a29e720..66b1c15c354 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c @@ -160,12 +160,7 @@ static int cx18_g_fmt_vid_cap(struct file *file, void *fh, pixfmt->priv = 0; if (id->type == CX18_ENC_STREAM_TYPE_YUV) { pixfmt->pixelformat = s->pixelformat; - /* HM12 YUV size is (Y=(h*720) + UV=(h*(720/2))) - UYUV YUV size is (Y=(h*720) + UV=(h*(720))) */ - if (s->pixelformat == V4L2_PIX_FMT_HM12) - pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2; - else - pixfmt->sizeimage = pixfmt->height * 720 * 2; + pixfmt->sizeimage = s->vb_bytes_per_frame; pixfmt->bytesperline = 720; } else { pixfmt->pixelformat = V4L2_PIX_FMT_MPEG; @@ -296,6 +291,12 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh, return -EBUSY; s->pixelformat = fmt->fmt.pix.pixelformat; + /* HM12 YUV size is (Y=(h*720) + UV=(h*(720/2))) + UYUV YUV size is (Y=(h*720) + UV=(h*(720))) */ + if (s->pixelformat == V4L2_PIX_FMT_HM12) + s->vb_bytes_per_frame = h * 720 * 3 / 2; + else + s->vb_bytes_per_frame = h * 720 * 2; mbus_fmt.width = cx->cxhdl.width = w; mbus_fmt.height = cx->cxhdl.height = h; @@ -463,13 +464,16 @@ static int cx18_s_register(struct file *file, void *fh, static int cx18_querycap(struct file *file, void *fh, struct v4l2_capability *vcap) { - struct cx18 *cx = fh2id(fh)->cx; + struct cx18_open_id *id = fh2id(fh); + struct cx18 *cx = id->cx; strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver)); strlcpy(vcap->card, cx->card_name, sizeof(vcap->card)); snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(cx->pci_dev)); vcap->capabilities = cx->v4l2_cap; /* capabilities */ + if (id->type == CX18_ENC_STREAM_TYPE_YUV) + vcap->capabilities |= V4L2_CAP_STREAMING; return 0; } -- cgit v1.2.3-70-g09d2