adf_fops32.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /*
  2. * Copyright (C) 2013 Google, Inc.
  3. *
  4. * This software is licensed under the terms of the GNU General Public
  5. * License version 2, as published by the Free Software Foundation, and
  6. * may be copied, distributed, and modified under those terms.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. */
  14. #include <linux/uaccess.h>
  15. #include <video/adf.h>
  16. #include "adf_fops.h"
  17. #include "adf_fops32.h"
  18. long adf_compat_post_config(struct file *file,
  19. struct adf_post_config32 __user *arg)
  20. {
  21. struct adf_post_config32 cfg32;
  22. struct adf_post_config __user *cfg;
  23. int ret;
  24. if (copy_from_user(&cfg32, arg, sizeof(cfg32)))
  25. return -EFAULT;
  26. cfg = compat_alloc_user_space(sizeof(*cfg));
  27. if (!access_ok(VERIFY_WRITE, cfg, sizeof(*cfg)))
  28. return -EFAULT;
  29. if (put_user(cfg32.n_interfaces, &cfg->n_interfaces) ||
  30. put_user(compat_ptr(cfg32.interfaces),
  31. &cfg->interfaces) ||
  32. put_user(cfg32.n_bufs, &cfg->n_bufs) ||
  33. put_user(compat_ptr(cfg32.bufs), &cfg->bufs) ||
  34. put_user(cfg32.custom_data_size,
  35. &cfg->custom_data_size) ||
  36. put_user(compat_ptr(cfg32.custom_data),
  37. &cfg->custom_data))
  38. return -EFAULT;
  39. ret = adf_file_ioctl(file, ADF_POST_CONFIG, (unsigned long)cfg);
  40. if (ret < 0)
  41. return ret;
  42. if (copy_in_user(&arg->complete_fence, &cfg->complete_fence,
  43. sizeof(cfg->complete_fence)))
  44. return -EFAULT;
  45. return 0;
  46. }
  47. long adf_compat_get_device_data(struct file *file,
  48. struct adf_device_data32 __user *arg)
  49. {
  50. struct adf_device_data32 data32;
  51. struct adf_device_data __user *data;
  52. int ret;
  53. if (copy_from_user(&data32, arg, sizeof(data32)))
  54. return -EFAULT;
  55. data = compat_alloc_user_space(sizeof(*data));
  56. if (!access_ok(VERIFY_WRITE, data, sizeof(*data)))
  57. return -EFAULT;
  58. if (put_user(data32.n_attachments, &data->n_attachments) ||
  59. put_user(compat_ptr(data32.attachments),
  60. &data->attachments) ||
  61. put_user(data32.n_allowed_attachments,
  62. &data->n_allowed_attachments) ||
  63. put_user(compat_ptr(data32.allowed_attachments),
  64. &data->allowed_attachments) ||
  65. put_user(data32.custom_data_size,
  66. &data->custom_data_size) ||
  67. put_user(compat_ptr(data32.custom_data),
  68. &data->custom_data))
  69. return -EFAULT;
  70. ret = adf_file_ioctl(file, ADF_GET_DEVICE_DATA, (unsigned long)data);
  71. if (ret < 0)
  72. return ret;
  73. if (copy_in_user(arg->name, data->name, sizeof(arg->name)) ||
  74. copy_in_user(&arg->n_attachments, &data->n_attachments,
  75. sizeof(arg->n_attachments)) ||
  76. copy_in_user(&arg->n_allowed_attachments,
  77. &data->n_allowed_attachments,
  78. sizeof(arg->n_allowed_attachments)) ||
  79. copy_in_user(&arg->custom_data_size,
  80. &data->custom_data_size,
  81. sizeof(arg->custom_data_size)))
  82. return -EFAULT;
  83. return 0;
  84. }
  85. long adf_compat_get_interface_data(struct file *file,
  86. struct adf_interface_data32 __user *arg)
  87. {
  88. struct adf_interface_data32 data32;
  89. struct adf_interface_data __user *data;
  90. int ret;
  91. if (copy_from_user(&data32, arg, sizeof(data32)))
  92. return -EFAULT;
  93. data = compat_alloc_user_space(sizeof(*data));
  94. if (!access_ok(VERIFY_WRITE, data, sizeof(*data)))
  95. return -EFAULT;
  96. if (put_user(data32.n_available_modes, &data->n_available_modes) ||
  97. put_user(compat_ptr(data32.available_modes),
  98. &data->available_modes) ||
  99. put_user(data32.custom_data_size,
  100. &data->custom_data_size) ||
  101. put_user(compat_ptr(data32.custom_data),
  102. &data->custom_data))
  103. return -EFAULT;
  104. ret = adf_file_ioctl(file, ADF_GET_INTERFACE_DATA, (unsigned long)data);
  105. if (ret < 0)
  106. return ret;
  107. if (copy_in_user(arg->name, data->name, sizeof(arg->name)) ||
  108. copy_in_user(&arg->type, &data->type,
  109. sizeof(arg->type)) ||
  110. copy_in_user(&arg->id, &data->id, sizeof(arg->id)) ||
  111. copy_in_user(&arg->flags, &data->flags,
  112. sizeof(arg->flags)) ||
  113. copy_in_user(&arg->dpms_state, &data->dpms_state,
  114. sizeof(arg->dpms_state)) ||
  115. copy_in_user(&arg->hotplug_detect,
  116. &data->hotplug_detect,
  117. sizeof(arg->hotplug_detect)) ||
  118. copy_in_user(&arg->width_mm, &data->width_mm,
  119. sizeof(arg->width_mm)) ||
  120. copy_in_user(&arg->height_mm, &data->height_mm,
  121. sizeof(arg->height_mm)) ||
  122. copy_in_user(&arg->current_mode, &data->current_mode,
  123. sizeof(arg->current_mode)) ||
  124. copy_in_user(&arg->n_available_modes,
  125. &data->n_available_modes,
  126. sizeof(arg->n_available_modes)) ||
  127. copy_in_user(&arg->custom_data_size,
  128. &data->custom_data_size,
  129. sizeof(arg->custom_data_size)))
  130. return -EFAULT;
  131. return 0;
  132. }
  133. long adf_compat_get_overlay_engine_data(struct file *file,
  134. struct adf_overlay_engine_data32 __user *arg)
  135. {
  136. struct adf_overlay_engine_data32 data32;
  137. struct adf_overlay_engine_data __user *data;
  138. int ret;
  139. if (copy_from_user(&data32, arg, sizeof(data32)))
  140. return -EFAULT;
  141. data = compat_alloc_user_space(sizeof(*data));
  142. if (!access_ok(VERIFY_WRITE, data, sizeof(*data)))
  143. return -EFAULT;
  144. if (put_user(data32.n_supported_formats, &data->n_supported_formats) ||
  145. put_user(compat_ptr(data32.supported_formats),
  146. &data->supported_formats) ||
  147. put_user(data32.custom_data_size,
  148. &data->custom_data_size) ||
  149. put_user(compat_ptr(data32.custom_data),
  150. &data->custom_data))
  151. return -EFAULT;
  152. ret = adf_file_ioctl(file, ADF_GET_OVERLAY_ENGINE_DATA,
  153. (unsigned long)data);
  154. if (ret < 0)
  155. return ret;
  156. if (copy_in_user(arg->name, data->name, sizeof(arg->name)) ||
  157. copy_in_user(&arg->n_supported_formats,
  158. &data->n_supported_formats,
  159. sizeof(arg->n_supported_formats)) ||
  160. copy_in_user(&arg->custom_data_size,
  161. &data->custom_data_size,
  162. sizeof(arg->custom_data_size)))
  163. return -EFAULT;
  164. return 0;
  165. }
  166. long adf_file_compat_ioctl(struct file *file, unsigned int cmd,
  167. unsigned long arg)
  168. {
  169. switch (cmd) {
  170. case ADF_POST_CONFIG32:
  171. return adf_compat_post_config(file, compat_ptr(arg));
  172. case ADF_GET_DEVICE_DATA32:
  173. return adf_compat_get_device_data(file, compat_ptr(arg));
  174. case ADF_GET_INTERFACE_DATA32:
  175. return adf_compat_get_interface_data(file, compat_ptr(arg));
  176. case ADF_GET_OVERLAY_ENGINE_DATA32:
  177. return adf_compat_get_overlay_engine_data(file,
  178. compat_ptr(arg));
  179. default:
  180. return adf_file_ioctl(file, cmd, arg);
  181. }
  182. }