diff options
author | Sylwester Nawrocki <s.nawrocki@samsung.com> | 2012-04-22 16:07:09 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-05-08 08:11:32 -0400 |
commit | 63746be543db923a8337e26c4723e65c38a99dc7 (patch) | |
tree | f9f38c304d03b5c2ec5027d60a27eb87b88d7483 /drivers/media/video/s5p-fimc | |
parent | e985dbf7d93e2a3e114b4525413e50f83613e0cb (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.c | 31 | ||||
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-core.c | 4 | ||||
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-core.h | 2 |
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 | ||
249 | static unsigned int get_plane_size(struct fimc_frame *fr, unsigned int plane) | 249 | static 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 | |||
256 | static 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 | */ |
1051 | struct fimc_fmt *fimc_find_format(u32 *pixelformat, u32 *mbus_code, | 1051 | struct 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); | |||
718 | int fimc_fill_format(struct fimc_frame *frame, struct v4l2_format *f); | 718 | int fimc_fill_format(struct fimc_frame *frame, struct v4l2_format *f); |
719 | void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height, | 719 | void 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); |
721 | struct fimc_fmt *fimc_find_format(u32 *pixelformat, u32 *mbus_code, | 721 | struct 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 | ||
724 | int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh, | 724 | int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh, |