video: adf: add supported formats to adf_overlay_engine_data
authorGreg Hackmann <ghackmann@google.com>
Tue, 11 Jun 2013 19:59:41 +0000 (12:59 -0700)
committerJohn Stultz <john.stultz@linaro.org>
Tue, 16 Feb 2016 21:53:11 +0000 (13:53 -0800)
Change-Id: If2aa783b9ece60160f465bf697508fc58682e1bc
Signed-off-by: Greg Hackmann <ghackmann@google.com>
drivers/video/adf/adf.c
drivers/video/adf/adf_fops.c
drivers/video/adf/adf_fops32.c
drivers/video/adf/adf_fops32.h
include/uapi/video/adf.h
include/video/adf.h

index 4e359602748f0aad957542cadef9de2e5f34a6fe..15fbc4a0d53bf87b66c1bdab8290ac612b1d0625 100644 (file)
@@ -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",
index d2e30c9cddcf3e357c4066e8b52607b022585065..343bdcc77443a44a95ff7a7bfb2310dde1f06ea0 100644 (file)
@@ -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,
index a7d5381295e9e1ea46cdc0e7dccf829b364b0250..2ecf8c8001f377897de25aec99c776b4b3de4219 100644 (file)
@@ -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)))
index c3e9c2282100028f4777da7979efa77d4dd312a4..8d0413274bcde74b535439d0bef596084b050412 100644 (file)
@@ -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;
 };
index bd046c6c34093fc1c8f6e01e42a98edae1932f4f..e35a505882dae2e620e6953739f3ea4085a819e8 100644 (file)
@@ -275,15 +275,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)
index 6c2191a318a5514759d4bbd649958c1f356c9219..eb7b9be19c7e20c4d1ac20c49f98862bd8a16534 100644 (file)
@@ -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;