aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Hackmann <ghackmann@google.com>2013-06-11 12:59:41 -0700
committerGreg Hackmann <ghackmann@google.com>2013-10-11 16:47:44 -0700
commit8bf80c569500ee125d6f85290521b0c1c3f64814 (patch)
tree07362c4e0765a92b425aebd9808c9bca0483d54a
parentb07062e41853a8096096d3a75767b955e13a57bb (diff)
video: adf: add supported formats to adf_overlay_engine_data
Change-Id: If2aa783b9ece60160f465bf697508fc58682e1bc Signed-off-by: Greg Hackmann <ghackmann@google.com>
-rw-r--r--drivers/video/adf/adf.c6
-rw-r--r--drivers/video/adf/adf_fops.c36
-rw-r--r--drivers/video/adf/adf_fops32.c9
-rw-r--r--drivers/video/adf/adf_fops32.h3
-rw-r--r--include/uapi/video/adf.h6
-rw-r--r--include/video/adf.h3
6 files changed, 57 insertions, 6 deletions
diff --git a/drivers/video/adf/adf.c b/drivers/video/adf/adf.c
index 4e359602748..15fbc4a0d53 100644
--- a/drivers/video/adf/adf.c
+++ b/drivers/video/adf/adf.c
@@ -756,6 +756,12 @@ int adf_overlay_engine_init(struct adf_overlay_engine *eng,
return -EINVAL;
}
+ if (ops->n_supported_formats > ADF_MAX_SUPPORTED_FORMATS) {
+ pr_err("%s: overlay engine supports too many formats\n",
+ __func__);
+ return -EINVAL;
+ }
+
if (adf_overlay_engine_has_custom_formats(ops) &&
!dev->ops->validate_custom_format) {
pr_err("%s: overlay engine has custom formats but parent device %s does not implement validate_custom_format\n",
diff --git a/drivers/video/adf/adf_fops.c b/drivers/video/adf/adf_fops.c
index d2e30c9cddc..343bdcc7744 100644
--- a/drivers/video/adf/adf_fops.c
+++ b/drivers/video/adf/adf_fops.c
@@ -105,6 +105,8 @@ static int adf_eng_get_data(struct adf_overlay_engine *eng,
{
struct adf_device *dev = adf_overlay_engine_parent(eng);
struct adf_overlay_engine_data data;
+ size_t n_supported_formats;
+ u32 *supported_formats = NULL;
int ret = 0;
if (copy_from_user(&data, arg, sizeof(data)))
@@ -112,18 +114,44 @@ static int adf_eng_get_data(struct adf_overlay_engine *eng,
strlcpy(data.name, eng->base.name, sizeof(data.name));
+ if (data.n_supported_formats > ADF_MAX_SUPPORTED_FORMATS)
+ return -EINVAL;
+
+ n_supported_formats = data.n_supported_formats;
+ data.n_supported_formats = eng->ops->n_supported_formats;
+
+ if (n_supported_formats) {
+ supported_formats = kzalloc(n_supported_formats *
+ sizeof(supported_formats[0]), GFP_KERNEL);
+ if (!supported_formats)
+ return -ENOMEM;
+ }
+
+ memcpy(supported_formats, eng->ops->supported_formats,
+ sizeof(u32) * min(n_supported_formats,
+ eng->ops->n_supported_formats));
+
mutex_lock(&dev->client_lock);
ret = adf_obj_copy_custom_data_to_user(&eng->base, arg->custom_data,
&data.custom_data_size);
mutex_unlock(&dev->client_lock);
if (ret < 0)
- return ret;
+ goto done;
- if (copy_to_user(arg, &data, sizeof(data)))
- return -EFAULT;
+ if (copy_to_user(arg, &data, sizeof(data))) {
+ ret = -EFAULT;
+ goto done;
+ }
- return 0;
+ if (supported_formats && copy_to_user(arg->supported_formats,
+ supported_formats,
+ n_supported_formats * sizeof(supported_formats[0])))
+ ret = -EFAULT;
+
+done:
+ kfree(supported_formats);
+ return ret;
}
static int adf_buffer_import(struct adf_device *dev,
diff --git a/drivers/video/adf/adf_fops32.c b/drivers/video/adf/adf_fops32.c
index a7d5381295e..2ecf8c8001f 100644
--- a/drivers/video/adf/adf_fops32.c
+++ b/drivers/video/adf/adf_fops32.c
@@ -166,7 +166,11 @@ long adf_compat_get_overlay_engine_data(struct file *file,
if (!access_ok(VERIFY_WRITE, data, sizeof(*data)))
return -EFAULT;
- if (put_user(data32.custom_data_size, &data->custom_data_size) ||
+ if (put_user(data32.n_supported_formats, &data->n_supported_formats) ||
+ put_user(compat_ptr(data32.supported_formats),
+ &data->supported_formats) ||
+ put_user(data32.custom_data_size,
+ &data->custom_data_size) ||
put_user(compat_ptr(data32.custom_data),
&data->custom_data))
return -EFAULT;
@@ -177,6 +181,9 @@ long adf_compat_get_overlay_engine_data(struct file *file,
return ret;
if (copy_in_user(arg->name, data->name, sizeof(arg->name)) ||
+ copy_in_user(&arg->n_supported_formats,
+ &data->n_supported_formats,
+ sizeof(arg->n_supported_formats)) ||
copy_in_user(&arg->custom_data_size,
&data->custom_data_size,
sizeof(arg->custom_data_size)))
diff --git a/drivers/video/adf/adf_fops32.h b/drivers/video/adf/adf_fops32.h
index c3e9c228210..8d0413274bc 100644
--- a/drivers/video/adf/adf_fops32.h
+++ b/drivers/video/adf/adf_fops32.h
@@ -64,6 +64,9 @@ struct adf_interface_data32 {
struct adf_overlay_engine_data32 {
char name[ADF_NAME_LEN];
+ compat_size_t n_supported_formats;
+ compat_uptr_t supported_formats;
+
compat_size_t custom_data_size;
compat_uptr_t custom_data;
};
diff --git a/include/uapi/video/adf.h b/include/uapi/video/adf.h
index 4b9e60c84e6..108064626e0 100644
--- a/include/uapi/video/adf.h
+++ b/include/uapi/video/adf.h
@@ -274,15 +274,21 @@ struct adf_interface_data {
* struct adf_overlay_engine_data - describes an overlay engine
*
* @name: overlay engine's name
+ * @n_supported_formats: number of supported formats
+ * @supported_formats: list of supported formats
* @custom_data_size: size of driver-private data
* @custom_data: driver-private data
*/
struct adf_overlay_engine_data {
char name[ADF_NAME_LEN];
+ size_t n_supported_formats;
+ __u32 __user *supported_formats;
+
size_t custom_data_size;
void __user *custom_data;
};
+#define ADF_MAX_SUPPORTED_FORMATS (PAGE_SIZE / sizeof(__u32))
#define ADF_SET_EVENT _IOW('D', 0, struct adf_set_event)
#define ADF_BLANK _IOW('D', 1, __u8)
diff --git a/include/video/adf.h b/include/video/adf.h
index 6c2191a318a..eb7b9be19c7 100644
--- a/include/video/adf.h
+++ b/include/video/adf.h
@@ -374,7 +374,8 @@ struct adf_interface {
* @base: common operations (see &struct adf_obj_ops)
*
* @supported_formats: list of fourccs the overlay engine can scan out
- * @n_supported_formats: length of supported_formats
+ * @n_supported_formats: length of supported_formats, up to
+ * ADF_MAX_SUPPORTED_FORMATS
*/
struct adf_overlay_engine_ops {
const struct adf_obj_ops base;