aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/s5p-fimc
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2012-04-22 16:07:09 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-05-08 08:11:32 -0400
commit63746be543db923a8337e26c4723e65c38a99dc7 (patch)
treef9f38c304d03b5c2ec5027d60a27eb87b88d7483 /drivers/media/video/s5p-fimc
parente985dbf7d93e2a3e114b4525413e50f83613e0cb (diff)
[media] s5p-fimc: Correct memory allocation for VIDIOC_CREATE_BUFS
The commit 3b4c34aac7abea4754059084d0eef667a1993ac8 "s5p-fimc: Add support for VIDIOC_PREPARE_BUF/CREATE_BUFS ioctls" added a handler for VIDIOC_CREATE_BUFS ioctl, but the queue_setup callback wasn't updated to properly interpret the pixel format. In this situation memory corruption may happen with VIDIOC_CREATE_BUFS ioctl. Update the queue_setup op to fix this. Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/s5p-fimc')
-rw-r--r--drivers/media/video/s5p-fimc/fimc-capture.c31
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.c4
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.h2
3 files changed, 23 insertions, 14 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c
index fcf3a14d013e..7e9b2c612b03 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -246,28 +246,37 @@ int fimc_capture_resume(struct fimc_dev *fimc)
246 246
247} 247}
248 248
249static unsigned int get_plane_size(struct fimc_frame *fr, unsigned int plane) 249static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
250{
251 if (!fr || plane >= fr->fmt->memplanes)
252 return 0;
253 return fr->f_width * fr->f_height * fr->fmt->depth[plane] / 8;
254}
255
256static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
257 unsigned int *num_buffers, unsigned int *num_planes, 250 unsigned int *num_buffers, unsigned int *num_planes,
258 unsigned int sizes[], void *allocators[]) 251 unsigned int sizes[], void *allocators[])
259{ 252{
253 const struct v4l2_pix_format_mplane *pixm = NULL;
260 struct fimc_ctx *ctx = vq->drv_priv; 254 struct fimc_ctx *ctx = vq->drv_priv;
261 struct fimc_fmt *fmt = ctx->d_frame.fmt; 255 struct fimc_frame *frame = &ctx->d_frame;
256 struct fimc_fmt *fmt = frame->fmt;
257 unsigned long wh;
262 int i; 258 int i;
263 259
264 if (!fmt) 260 if (pfmt) {
261 pixm = &pfmt->fmt.pix_mp;
262 fmt = fimc_find_format(&pixm->pixelformat, NULL,
263 FMT_FLAGS_CAM | FMT_FLAGS_M2M, -1);
264 wh = pixm->width * pixm->height;
265 } else {
266 wh = frame->f_width * frame->f_height;
267 }
268
269 if (fmt == NULL)
265 return -EINVAL; 270 return -EINVAL;
266 271
267 *num_planes = fmt->memplanes; 272 *num_planes = fmt->memplanes;
268 273
269 for (i = 0; i < fmt->memplanes; i++) { 274 for (i = 0; i < fmt->memplanes; i++) {
270 sizes[i] = get_plane_size(&ctx->d_frame, i); 275 unsigned int size = (wh * fmt->depth[i]) / 8;
276 if (pixm)
277 sizes[i] = max(size, pixm->plane_fmt[i].sizeimage);
278 else
279 sizes[i] = size;
271 allocators[i] = ctx->fimc_dev->alloc_ctx; 280 allocators[i] = ctx->fimc_dev->alloc_ctx;
272 } 281 }
273 282
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c
index e184e650022a..e09ba7b0076e 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.c
+++ b/drivers/media/video/s5p-fimc/fimc-core.c
@@ -1048,14 +1048,14 @@ static int fimc_m2m_g_fmt_mplane(struct file *file, void *fh,
1048 * @mask: the color flags to match 1048 * @mask: the color flags to match
1049 * @index: offset in the fimc_formats array, ignored if negative 1049 * @index: offset in the fimc_formats array, ignored if negative
1050 */ 1050 */
1051struct fimc_fmt *fimc_find_format(u32 *pixelformat, u32 *mbus_code, 1051struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code,
1052 unsigned int mask, int index) 1052 unsigned int mask, int index)
1053{ 1053{
1054 struct fimc_fmt *fmt, *def_fmt = NULL; 1054 struct fimc_fmt *fmt, *def_fmt = NULL;
1055 unsigned int i; 1055 unsigned int i;
1056 int id = 0; 1056 int id = 0;
1057 1057
1058 if (index >= ARRAY_SIZE(fimc_formats)) 1058 if (index >= (int)ARRAY_SIZE(fimc_formats))
1059 return NULL; 1059 return NULL;
1060 1060
1061 for (i = 0; i < ARRAY_SIZE(fimc_formats); ++i) { 1061 for (i = 0; i < ARRAY_SIZE(fimc_formats); ++i) {
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h
index a18291e648e2..84fd83550bd7 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.h
+++ b/drivers/media/video/s5p-fimc/fimc-core.h
@@ -718,7 +718,7 @@ void fimc_alpha_ctrl_update(struct fimc_ctx *ctx);
718int fimc_fill_format(struct fimc_frame *frame, struct v4l2_format *f); 718int fimc_fill_format(struct fimc_frame *frame, struct v4l2_format *f);
719void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height, 719void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height,
720 struct v4l2_pix_format_mplane *pix); 720 struct v4l2_pix_format_mplane *pix);
721struct fimc_fmt *fimc_find_format(u32 *pixelformat, u32 *mbus_code, 721struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code,
722 unsigned int mask, int index); 722 unsigned int mask, int index);
723 723
724int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh, 724int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh,