mjc_kernel_compat_driver.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. #include <linux/compat.h>
  2. #include <linux/fs.h>
  3. #include <linux/uaccess.h>
  4. #include <linux/printk.h>
  5. #include "mjc_kernel_driver.h"
  6. #include "mjc_kernel_compat_driver.h"
  7. #define MJCDBG(string, args...) pr_debug("MJC [pid=%d]"string, current->tgid, ##args)
  8. /* ************************************ */
  9. /* IO control structure */
  10. /* ************************************ */
  11. /* See mjc_kernel_compat_driver.h for the definition of these structs */
  12. typedef struct {
  13. compat_ulong_t reg;
  14. compat_uint_t val;
  15. compat_uint_t mask;
  16. } compat_MJC_READ_REG_T;
  17. typedef struct {
  18. compat_ulong_t reg;
  19. compat_uint_t val;
  20. compat_uint_t mask;
  21. } compat_MJC_WRITE_REG_T;
  22. typedef struct {
  23. compat_uint_t u4StructSize;
  24. compat_ulong_t ulRegPAddress;
  25. compat_ulong_t ulRegPSize;
  26. } compat_MJC_IOCTL_REG_INFO_T;
  27. #define MJC_IOC_MAGIC 'N'
  28. #define COMPAT_MJC_READ_REG _IOW(MJC_IOC_MAGIC, 0x02, compat_MJC_READ_REG_T)
  29. #define COMPAT_MJC_WRITE_REG _IOW(MJC_IOC_MAGIC, 0x03, compat_MJC_WRITE_REG_T)
  30. #define COMPAT_MJC_REG_INFO _IOW(MJC_IOC_MAGIC, 0x07, compat_MJC_IOCTL_REG_INFO_T)
  31. /*****************************************************************************
  32. * FUNCTION
  33. * compat_get_mjc_read_reg
  34. * DESCRIPTION
  35. *
  36. * PARAMETERS
  37. * None.
  38. * RETURNS
  39. * None.
  40. ****************************************************************************/
  41. static int compat_get_mjc_read_reg(compat_MJC_READ_REG_T __user *data32,
  42. MJC_READ_REG_T __user *data)
  43. {
  44. compat_ulong_t reg;
  45. compat_uint_t val;
  46. compat_uint_t mask;
  47. int err;
  48. err = get_user(reg, &data32->reg);
  49. err |= put_user(reg, &data->reg);
  50. err |= get_user(val, &data32->val);
  51. err |= put_user(val, &data->val);
  52. err |= get_user(mask, &data32->mask);
  53. err |= put_user(mask, &data->mask);
  54. return err;
  55. }
  56. /*****************************************************************************
  57. * FUNCTION
  58. * compat_put_mjc_read_reg
  59. * DESCRIPTION
  60. *
  61. * PARAMETERS
  62. * None.
  63. * RETURNS
  64. * None.
  65. ****************************************************************************/
  66. static int compat_put_mjc_read_reg(compat_MJC_READ_REG_T __user *data32,
  67. MJC_READ_REG_T __user *data)
  68. {
  69. compat_ulong_t reg;
  70. compat_uint_t val;
  71. compat_uint_t mask;
  72. int err;
  73. err = get_user(reg, &data->reg);
  74. err |= put_user(reg, &data32->reg);
  75. err |= get_user(val, &data->val);
  76. err |= put_user(val, &data32->val);
  77. err |= get_user(mask, &data->mask);
  78. err |= put_user(mask, &data32->mask);
  79. return err;
  80. }
  81. /*****************************************************************************
  82. * FUNCTION
  83. * compat_get_mjc_write_reg
  84. * DESCRIPTION
  85. *
  86. * PARAMETERS
  87. * None.
  88. * RETURNS
  89. * None.
  90. ****************************************************************************/
  91. static int compat_get_mjc_write_reg(compat_MJC_WRITE_REG_T __user *data32,
  92. MJC_WRITE_REG_T __user *data)
  93. {
  94. compat_ulong_t reg;
  95. compat_uint_t val;
  96. compat_uint_t mask;
  97. int err;
  98. err = get_user(reg, &data32->reg);
  99. err |= put_user(reg, &data->reg);
  100. err |= get_user(val, &data32->val);
  101. err |= put_user(val, &data->val);
  102. err |= get_user(mask, &data32->mask);
  103. err |= put_user(mask, &data->mask);
  104. return err;
  105. }
  106. /*****************************************************************************
  107. * FUNCTION
  108. * compat_get_mjc_reg_info
  109. * DESCRIPTION
  110. *
  111. * PARAMETERS
  112. * None.
  113. * RETURNS
  114. * None.
  115. ****************************************************************************/
  116. static int compat_get_mjc_reg_info(compat_MJC_IOCTL_REG_INFO_T __user *data32,
  117. MJC_IOCTL_REG_INFO_T __user *data)
  118. {
  119. compat_uint_t u4StructSize;
  120. compat_ulong_t ulRegPAddress;
  121. compat_ulong_t ulRegPSize;
  122. int err;
  123. err = get_user(u4StructSize, &data32->u4StructSize);
  124. if (u4StructSize != sizeof(compat_MJC_IOCTL_REG_INFO_T)) {
  125. MJCDBG("[Error] compat_get_mjc_reg_info() structure size mismatch (%d, %ld)",
  126. u4StructSize, sizeof(compat_MJC_IOCTL_REG_INFO_T));
  127. err = -EFAULT;
  128. }
  129. u4StructSize = sizeof(MJC_IOCTL_REG_INFO_T);
  130. err |= put_user(u4StructSize, &data->u4StructSize);
  131. err |= get_user(ulRegPAddress, &data32->ulRegPAddress);
  132. err |= put_user(ulRegPAddress, &data->ulRegPAddress);
  133. err |= get_user(ulRegPSize, &data32->ulRegPSize);
  134. err |= put_user(ulRegPSize, &data->ulRegPSize);
  135. return err;
  136. }
  137. /*****************************************************************************
  138. * FUNCTION
  139. * compat_put_mjc_reg_info
  140. * DESCRIPTION
  141. *
  142. * PARAMETERS
  143. * None.
  144. * RETURNS
  145. * None.
  146. ****************************************************************************/
  147. static int compat_put_mjc_reg_info(compat_MJC_IOCTL_REG_INFO_T __user *data32,
  148. MJC_IOCTL_REG_INFO_T __user *data)
  149. {
  150. /* compat_uint_t u4StructSize; */
  151. compat_ulong_t ulRegPAddress;
  152. compat_ulong_t ulRegPSize;
  153. int err;
  154. /* err = get_user(u4StructSize, &data->u4StructSize); */
  155. /* err |= put_user(u4StructSize, &data32->u4StructSize); */
  156. err = get_user(ulRegPAddress, &data->ulRegPAddress);
  157. err |= put_user(ulRegPAddress, &data32->ulRegPAddress);
  158. err |= get_user(ulRegPSize, &data->ulRegPSize);
  159. err |= put_user(ulRegPSize, &data32->ulRegPSize);
  160. return err;
  161. }
  162. /*****************************************************************************
  163. * FUNCTION
  164. * compat_mjc_ioctls
  165. * DESCRIPTION
  166. *
  167. * PARAMETERS
  168. * None.
  169. * RETURNS
  170. * None.
  171. ****************************************************************************/
  172. long compat_mjc_ioctl(struct file *pfile, unsigned int u4cmd, unsigned long u4arg)
  173. {
  174. long ret = 0;
  175. if (!pfile->f_op || !pfile->f_op->unlocked_ioctl) {
  176. MJCDBG("[Error] compat_mjc_ioctl() null pointer");
  177. return -ENOTTY;
  178. }
  179. switch (u4cmd) {
  180. case COMPAT_MJC_READ_REG:
  181. {
  182. compat_MJC_READ_REG_T __user *data32;
  183. MJC_READ_REG_T __user *data;
  184. int err;
  185. data32 = compat_ptr(u4arg);
  186. data = compat_alloc_user_space(sizeof(*data));
  187. if (data == NULL) {
  188. MJCDBG
  189. ("[Error] compat_mjc_ioctl() can't allocate user sapce");
  190. return -EFAULT;
  191. }
  192. err = compat_get_mjc_read_reg(data32, data);
  193. if (err) {
  194. MJCDBG
  195. ("[Error] compat_mjc_ioctl(), compat_get_mjc_read_reg() error");
  196. return err;
  197. }
  198. ret = pfile->f_op->unlocked_ioctl(pfile, MJC_READ_REG, (unsigned long)data);
  199. err = compat_put_mjc_read_reg(data32, data);
  200. if (err) {
  201. MJCDBG
  202. ("[Error] compat_mjc_ioctl(), compat_put_mjc_read_reg() error");
  203. return err;
  204. }
  205. }
  206. break;
  207. case COMPAT_MJC_WRITE_REG:
  208. {
  209. compat_MJC_WRITE_REG_T __user *data32;
  210. MJC_WRITE_REG_T __user *data;
  211. int err;
  212. data32 = compat_ptr(u4arg);
  213. data = compat_alloc_user_space(sizeof(*data));
  214. if (data == NULL) {
  215. MJCDBG
  216. ("[Error] compat_mjc_ioctl() can't allocate user sapce");
  217. return -EFAULT;
  218. }
  219. err = compat_get_mjc_write_reg(data32, data);
  220. if (err) {
  221. MJCDBG
  222. ("[Error] compat_mjc_ioctl(), compat_get_mjc_write_reg() error");
  223. return err;
  224. }
  225. ret =
  226. pfile->f_op->unlocked_ioctl(pfile, MJC_WRITE_REG, (unsigned long)data);
  227. }
  228. break;
  229. case COMPAT_MJC_REG_INFO:
  230. {
  231. compat_MJC_IOCTL_REG_INFO_T __user *data32;
  232. MJC_IOCTL_REG_INFO_T __user *data;
  233. int err;
  234. data32 = compat_ptr(u4arg);
  235. data = compat_alloc_user_space(sizeof(*data));
  236. if (data == NULL) {
  237. MJCDBG
  238. ("[Error] compat_mjc_ioctl() can't allocate user sapce");
  239. return -EFAULT;
  240. }
  241. err = compat_get_mjc_reg_info(data32, data);
  242. if (err) {
  243. MJCDBG
  244. ("[Error] compat_mjc_ioctl(), compat_get_mjc_reg_info() error");
  245. return err;
  246. }
  247. ret = pfile->f_op->unlocked_ioctl(pfile, MJC_REG_INFO, (unsigned long)data);
  248. err = compat_put_mjc_reg_info(data32, data);
  249. if (err) {
  250. MJCDBG
  251. ("[Error] compat_mjc_ioctl(), compat_put_mjc_reg_info() error");
  252. return err;
  253. }
  254. }
  255. break;
  256. case MJC_LOCKHW:
  257. case MJC_WAITISR:
  258. case MJC_WRITE_REG_TBL:
  259. case MJC_CLEAR_REG_TBL:
  260. case MJC_SOURCE_CLK:
  261. {
  262. ret =
  263. pfile->f_op->unlocked_ioctl(pfile, u4cmd,
  264. (unsigned long)compat_ptr(u4arg));
  265. }
  266. break;
  267. default:
  268. MJCDBG("[ERROR] compat_mjc_ioctl() No such command 0x%x!!\n", u4cmd);
  269. break;
  270. }
  271. return ret;
  272. }