| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- #include <linux/compat.h>
- #include <linux/fs.h>
- #include <linux/uaccess.h>
- #include <linux/printk.h>
- #include "mjc_kernel_driver.h"
- #include "mjc_kernel_compat_driver.h"
- #define MJCDBG(string, args...) pr_debug("MJC [pid=%d]"string, current->tgid, ##args)
- /* ************************************ */
- /* IO control structure */
- /* ************************************ */
- /* See mjc_kernel_compat_driver.h for the definition of these structs */
- typedef struct {
- compat_ulong_t reg;
- compat_uint_t val;
- compat_uint_t mask;
- } compat_MJC_READ_REG_T;
- typedef struct {
- compat_ulong_t reg;
- compat_uint_t val;
- compat_uint_t mask;
- } compat_MJC_WRITE_REG_T;
- typedef struct {
- compat_uint_t u4StructSize;
- compat_ulong_t ulRegPAddress;
- compat_ulong_t ulRegPSize;
- } compat_MJC_IOCTL_REG_INFO_T;
- #define MJC_IOC_MAGIC 'N'
- #define COMPAT_MJC_READ_REG _IOW(MJC_IOC_MAGIC, 0x02, compat_MJC_READ_REG_T)
- #define COMPAT_MJC_WRITE_REG _IOW(MJC_IOC_MAGIC, 0x03, compat_MJC_WRITE_REG_T)
- #define COMPAT_MJC_REG_INFO _IOW(MJC_IOC_MAGIC, 0x07, compat_MJC_IOCTL_REG_INFO_T)
- /*****************************************************************************
- * FUNCTION
- * compat_get_mjc_read_reg
- * DESCRIPTION
- *
- * PARAMETERS
- * None.
- * RETURNS
- * None.
- ****************************************************************************/
- static int compat_get_mjc_read_reg(compat_MJC_READ_REG_T __user *data32,
- MJC_READ_REG_T __user *data)
- {
- compat_ulong_t reg;
- compat_uint_t val;
- compat_uint_t mask;
- int err;
- err = get_user(reg, &data32->reg);
- err |= put_user(reg, &data->reg);
- err |= get_user(val, &data32->val);
- err |= put_user(val, &data->val);
- err |= get_user(mask, &data32->mask);
- err |= put_user(mask, &data->mask);
- return err;
- }
- /*****************************************************************************
- * FUNCTION
- * compat_put_mjc_read_reg
- * DESCRIPTION
- *
- * PARAMETERS
- * None.
- * RETURNS
- * None.
- ****************************************************************************/
- static int compat_put_mjc_read_reg(compat_MJC_READ_REG_T __user *data32,
- MJC_READ_REG_T __user *data)
- {
- compat_ulong_t reg;
- compat_uint_t val;
- compat_uint_t mask;
- int err;
- err = get_user(reg, &data->reg);
- err |= put_user(reg, &data32->reg);
- err |= get_user(val, &data->val);
- err |= put_user(val, &data32->val);
- err |= get_user(mask, &data->mask);
- err |= put_user(mask, &data32->mask);
- return err;
- }
- /*****************************************************************************
- * FUNCTION
- * compat_get_mjc_write_reg
- * DESCRIPTION
- *
- * PARAMETERS
- * None.
- * RETURNS
- * None.
- ****************************************************************************/
- static int compat_get_mjc_write_reg(compat_MJC_WRITE_REG_T __user *data32,
- MJC_WRITE_REG_T __user *data)
- {
- compat_ulong_t reg;
- compat_uint_t val;
- compat_uint_t mask;
- int err;
- err = get_user(reg, &data32->reg);
- err |= put_user(reg, &data->reg);
- err |= get_user(val, &data32->val);
- err |= put_user(val, &data->val);
- err |= get_user(mask, &data32->mask);
- err |= put_user(mask, &data->mask);
- return err;
- }
- /*****************************************************************************
- * FUNCTION
- * compat_get_mjc_reg_info
- * DESCRIPTION
- *
- * PARAMETERS
- * None.
- * RETURNS
- * None.
- ****************************************************************************/
- static int compat_get_mjc_reg_info(compat_MJC_IOCTL_REG_INFO_T __user *data32,
- MJC_IOCTL_REG_INFO_T __user *data)
- {
- compat_uint_t u4StructSize;
- compat_ulong_t ulRegPAddress;
- compat_ulong_t ulRegPSize;
- int err;
- err = get_user(u4StructSize, &data32->u4StructSize);
- if (u4StructSize != sizeof(compat_MJC_IOCTL_REG_INFO_T)) {
- MJCDBG("[Error] compat_get_mjc_reg_info() structure size mismatch (%d, %ld)",
- u4StructSize, sizeof(compat_MJC_IOCTL_REG_INFO_T));
- err = -EFAULT;
- }
- u4StructSize = sizeof(MJC_IOCTL_REG_INFO_T);
- err |= put_user(u4StructSize, &data->u4StructSize);
- err |= get_user(ulRegPAddress, &data32->ulRegPAddress);
- err |= put_user(ulRegPAddress, &data->ulRegPAddress);
- err |= get_user(ulRegPSize, &data32->ulRegPSize);
- err |= put_user(ulRegPSize, &data->ulRegPSize);
- return err;
- }
- /*****************************************************************************
- * FUNCTION
- * compat_put_mjc_reg_info
- * DESCRIPTION
- *
- * PARAMETERS
- * None.
- * RETURNS
- * None.
- ****************************************************************************/
- static int compat_put_mjc_reg_info(compat_MJC_IOCTL_REG_INFO_T __user *data32,
- MJC_IOCTL_REG_INFO_T __user *data)
- {
- /* compat_uint_t u4StructSize; */
- compat_ulong_t ulRegPAddress;
- compat_ulong_t ulRegPSize;
- int err;
- /* err = get_user(u4StructSize, &data->u4StructSize); */
- /* err |= put_user(u4StructSize, &data32->u4StructSize); */
- err = get_user(ulRegPAddress, &data->ulRegPAddress);
- err |= put_user(ulRegPAddress, &data32->ulRegPAddress);
- err |= get_user(ulRegPSize, &data->ulRegPSize);
- err |= put_user(ulRegPSize, &data32->ulRegPSize);
- return err;
- }
- /*****************************************************************************
- * FUNCTION
- * compat_mjc_ioctls
- * DESCRIPTION
- *
- * PARAMETERS
- * None.
- * RETURNS
- * None.
- ****************************************************************************/
- long compat_mjc_ioctl(struct file *pfile, unsigned int u4cmd, unsigned long u4arg)
- {
- long ret = 0;
- if (!pfile->f_op || !pfile->f_op->unlocked_ioctl) {
- MJCDBG("[Error] compat_mjc_ioctl() null pointer");
- return -ENOTTY;
- }
- switch (u4cmd) {
- case COMPAT_MJC_READ_REG:
- {
- compat_MJC_READ_REG_T __user *data32;
- MJC_READ_REG_T __user *data;
- int err;
- data32 = compat_ptr(u4arg);
- data = compat_alloc_user_space(sizeof(*data));
- if (data == NULL) {
- MJCDBG
- ("[Error] compat_mjc_ioctl() can't allocate user sapce");
- return -EFAULT;
- }
- err = compat_get_mjc_read_reg(data32, data);
- if (err) {
- MJCDBG
- ("[Error] compat_mjc_ioctl(), compat_get_mjc_read_reg() error");
- return err;
- }
- ret = pfile->f_op->unlocked_ioctl(pfile, MJC_READ_REG, (unsigned long)data);
- err = compat_put_mjc_read_reg(data32, data);
- if (err) {
- MJCDBG
- ("[Error] compat_mjc_ioctl(), compat_put_mjc_read_reg() error");
- return err;
- }
- }
- break;
- case COMPAT_MJC_WRITE_REG:
- {
- compat_MJC_WRITE_REG_T __user *data32;
- MJC_WRITE_REG_T __user *data;
- int err;
- data32 = compat_ptr(u4arg);
- data = compat_alloc_user_space(sizeof(*data));
- if (data == NULL) {
- MJCDBG
- ("[Error] compat_mjc_ioctl() can't allocate user sapce");
- return -EFAULT;
- }
- err = compat_get_mjc_write_reg(data32, data);
- if (err) {
- MJCDBG
- ("[Error] compat_mjc_ioctl(), compat_get_mjc_write_reg() error");
- return err;
- }
- ret =
- pfile->f_op->unlocked_ioctl(pfile, MJC_WRITE_REG, (unsigned long)data);
- }
- break;
- case COMPAT_MJC_REG_INFO:
- {
- compat_MJC_IOCTL_REG_INFO_T __user *data32;
- MJC_IOCTL_REG_INFO_T __user *data;
- int err;
- data32 = compat_ptr(u4arg);
- data = compat_alloc_user_space(sizeof(*data));
- if (data == NULL) {
- MJCDBG
- ("[Error] compat_mjc_ioctl() can't allocate user sapce");
- return -EFAULT;
- }
- err = compat_get_mjc_reg_info(data32, data);
- if (err) {
- MJCDBG
- ("[Error] compat_mjc_ioctl(), compat_get_mjc_reg_info() error");
- return err;
- }
- ret = pfile->f_op->unlocked_ioctl(pfile, MJC_REG_INFO, (unsigned long)data);
- err = compat_put_mjc_reg_info(data32, data);
- if (err) {
- MJCDBG
- ("[Error] compat_mjc_ioctl(), compat_put_mjc_reg_info() error");
- return err;
- }
- }
- break;
- case MJC_LOCKHW:
- case MJC_WAITISR:
- case MJC_WRITE_REG_TBL:
- case MJC_CLEAR_REG_TBL:
- case MJC_SOURCE_CLK:
- {
- ret =
- pfile->f_op->unlocked_ioctl(pfile, u4cmd,
- (unsigned long)compat_ptr(u4arg));
- }
- break;
- default:
- MJCDBG("[ERROR] compat_mjc_ioctl() No such command 0x%x!!\n", u4cmd);
- break;
- }
- return ret;
- }
|