mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 04:48:04 +09:00
dvb-core: compatile with 32bit in 64bit kernel [1/1]
PD#SWPL-3009 Problem: 32bit frontend app can't call ioctl in 64bit-kernel Solution: Add 32bit define in header and handle in dvb_frontend in 64bit-kernel Verify: Verify at android_p at R311 Change-Id: I63178803cfb1cf7d670e3c2b55f104e97f5afa63 Signed-off-by: Chuangcheng Peng <chuangcheng.peng@amlogic.com>
This commit is contained in:
committed by
Dongjin Kim
parent
b682325e08
commit
3411f700d2
@@ -1965,7 +1965,63 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
|
||||
|
||||
return r;
|
||||
}
|
||||
static void dtv_property_32to64(struct dtv_property *dest,
|
||||
struct dtv_property_32 *src)
|
||||
{
|
||||
int i = 0;
|
||||
long tmp = 0;
|
||||
|
||||
dest->cmd = src->cmd;
|
||||
// printk("%s cmd:%d\n",__func__,dest->cmd);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
dest->reserved[i] = src->reserved[i];
|
||||
|
||||
dest->u.data = src->u.data;
|
||||
dest->u.st.len = src->u.st.len;
|
||||
|
||||
for (i = 0; i < MAX_DTV_STATS; i++) {
|
||||
dest->u.st.stat[i].scale = src->u.st.stat[i].scale;
|
||||
dest->u.st.stat[i].uvalue = src->u.st.stat[i].uvalue;
|
||||
dest->u.st.stat[i].svalue = src->u.st.stat[i].svalue;
|
||||
}
|
||||
for (i = 0; i < 32; i++)
|
||||
dest->u.buffer.data[i] = src->u.buffer.data[i];
|
||||
dest->u.buffer.len = src->u.buffer.len;
|
||||
for (i = 0; i < 3; i++)
|
||||
dest->u.buffer.reserved1[i] = src->u.buffer.reserved1[i];
|
||||
tmp = (long)(src->u.buffer.reserved2);
|
||||
dest->u.buffer.reserved2 = (void *)tmp;
|
||||
dest->result = src->result;
|
||||
}
|
||||
|
||||
static void dtv_property_64to32(struct dtv_property_32 *dest,
|
||||
struct dtv_property *src)
|
||||
{
|
||||
int i = 0;
|
||||
long tmp = 0;
|
||||
|
||||
dest->cmd = src->cmd;
|
||||
// printk("%s cmd:%d\n",__func__,dest->cmd);
|
||||
for (i = 0; i < 3; i++)
|
||||
dest->reserved[i] = src->reserved[i];
|
||||
dest->u.data = src->u.data;
|
||||
// printk("%s data:%d\n",__func__,dest->u.data);
|
||||
dest->u.st.len = src->u.st.len;
|
||||
for (i = 0; i < MAX_DTV_STATS; i++) {
|
||||
dest->u.st.stat[i].scale = src->u.st.stat[i].scale;
|
||||
dest->u.st.stat[i].uvalue = src->u.st.stat[i].uvalue;
|
||||
dest->u.st.stat[i].svalue = src->u.st.stat[i].svalue;
|
||||
}
|
||||
for (i = 0; i < 32; i++)
|
||||
dest->u.buffer.data[i] = src->u.buffer.data[i];
|
||||
dest->u.buffer.len = src->u.buffer.len;
|
||||
for (i = 0; i < 3; i++)
|
||||
dest->u.buffer.reserved1[i] = src->u.buffer.reserved1[i];
|
||||
tmp = (long)(src->u.buffer.reserved2);
|
||||
dest->u.buffer.reserved2 = (__u32)tmp;
|
||||
dest->result = src->result;
|
||||
}
|
||||
static int dvb_frontend_ioctl(struct file *file,
|
||||
unsigned int cmd, void *parg)
|
||||
{
|
||||
@@ -1991,7 +2047,9 @@ static int dvb_frontend_ioctl(struct file *file,
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if ((cmd == FE_SET_PROPERTY) || (cmd == FE_GET_PROPERTY))
|
||||
if ((cmd == FE_SET_PROPERTY_32) || (cmd == FE_GET_PROPERTY_32)
|
||||
|| (cmd == FE_SET_PROPERTY_64)
|
||||
|| (cmd == FE_GET_PROPERTY_64))
|
||||
err = dvb_frontend_ioctl_properties(file, cmd, parg);
|
||||
else {
|
||||
c->state = DTV_UNDEFINED;
|
||||
@@ -2012,12 +2070,45 @@ static int dvb_frontend_ioctl_properties(struct file *file,
|
||||
int err = 0;
|
||||
|
||||
struct dtv_properties *tvps = parg;
|
||||
struct dtv_properties_32 *tvps_32_tmp = parg;
|
||||
struct dtv_properties tvps_tmp;
|
||||
struct dtv_property *tvp = NULL;
|
||||
struct dtv_property_32 *tvp_32 = NULL;
|
||||
int i;
|
||||
int prop = 0;
|
||||
int convert = 0;
|
||||
|
||||
dev_dbg(fe->dvb->device, "%s:\n", __func__);
|
||||
if ((cmd == FE_SET_PROPERTY_32) || (cmd == FE_SET_PROPERTY_64)
|
||||
|| (cmd == FE_GET_PROPERTY_32)
|
||||
|| (cmd == FE_GET_PROPERTY_64)) {
|
||||
prop = 1;
|
||||
|
||||
if (cmd == FE_SET_PROPERTY) {
|
||||
if ((cmd == FE_SET_PROPERTY_32) ||
|
||||
(cmd == FE_GET_PROPERTY_32)) {
|
||||
if (FE_SET_PROPERTY == FE_SET_PROPERTY_64)
|
||||
convert = 1;
|
||||
}
|
||||
}
|
||||
if (prop) {
|
||||
if (convert) {
|
||||
tvps_tmp.num = tvps_32_tmp->num;
|
||||
tvps_tmp.props = (struct dtv_property *)(long)(tvps_32_tmp->props);
|
||||
tvps = &tvps_tmp;
|
||||
|
||||
tvp_32 = memdup_user(tvps->props,
|
||||
tvps->num * sizeof(struct dtv_property_32));
|
||||
if (IS_ERR(tvp_32)) {
|
||||
err = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_COMPAT
|
||||
tvps->props = compat_ptr((unsigned long)tvps->props);
|
||||
#endif
|
||||
|
||||
if ((cmd == FE_SET_PROPERTY_32) || (cmd == FE_SET_PROPERTY_64)) {
|
||||
dev_dbg(fe->dvb->device, "%s: properties.num = %d\n", __func__, tvps->num);
|
||||
dev_dbg(fe->dvb->device, "%s: properties.props = %p\n", __func__, tvps->props);
|
||||
|
||||
@@ -2026,9 +2117,22 @@ static int dvb_frontend_ioctl_properties(struct file *file,
|
||||
if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS))
|
||||
return -EINVAL;
|
||||
|
||||
tvp = memdup_user(tvps->props, tvps->num * sizeof(*tvp));
|
||||
if (IS_ERR(tvp))
|
||||
return PTR_ERR(tvp);
|
||||
if (convert) {
|
||||
tvp = kmalloc_array(tvps->num,
|
||||
sizeof(*tvp), GFP_KERNEL);
|
||||
if (IS_ERR(tvp)) {
|
||||
err = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < tvps->num; i++)
|
||||
dtv_property_32to64(tvp + i, tvp_32+i);
|
||||
} else {
|
||||
tvp = memdup_user(tvps->props,
|
||||
tvps->num * sizeof(*tvp));
|
||||
if (IS_ERR(tvp))
|
||||
return PTR_ERR(tvp);
|
||||
}
|
||||
|
||||
for (i = 0; i < tvps->num; i++) {
|
||||
err = dtv_property_process_set(fe, tvp + i, file);
|
||||
@@ -2040,7 +2144,7 @@ static int dvb_frontend_ioctl_properties(struct file *file,
|
||||
if (c->state == DTV_TUNE)
|
||||
dev_dbg(fe->dvb->device, "%s: Property cache is full, tuning\n", __func__);
|
||||
|
||||
} else if (cmd == FE_GET_PROPERTY) {
|
||||
} else if ((cmd == FE_GET_PROPERTY_32) || (cmd == FE_GET_PROPERTY_64)) {
|
||||
struct dtv_frontend_properties getp = fe->dtv_property_cache;
|
||||
|
||||
dev_dbg(fe->dvb->device, "%s: properties.num = %d\n", __func__, tvps->num);
|
||||
@@ -2051,9 +2155,20 @@ static int dvb_frontend_ioctl_properties(struct file *file,
|
||||
if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS))
|
||||
return -EINVAL;
|
||||
|
||||
tvp = memdup_user(tvps->props, tvps->num * sizeof(*tvp));
|
||||
if (IS_ERR(tvp))
|
||||
return PTR_ERR(tvp);
|
||||
if (convert) {
|
||||
tvp = kmalloc_array(tvps->num,
|
||||
sizeof(*tvp), GFP_KERNEL);
|
||||
if (IS_ERR(tvp))
|
||||
return PTR_ERR(tvp);
|
||||
|
||||
for (i = 0; i < tvps->num; i++)
|
||||
dtv_property_32to64(tvp + i, tvp_32+i);
|
||||
} else {
|
||||
tvp = memdup_user(tvps->props,
|
||||
tvps->num * sizeof(*tvp));
|
||||
if (IS_ERR(tvp))
|
||||
return PTR_ERR(tvp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Let's use our own copy of property cache, in order to
|
||||
@@ -2073,16 +2188,28 @@ static int dvb_frontend_ioctl_properties(struct file *file,
|
||||
(tvp + i)->result = err;
|
||||
}
|
||||
|
||||
if (copy_to_user((void __user *)tvps->props, tvp,
|
||||
tvps->num * sizeof(struct dtv_property))) {
|
||||
err = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
if (convert) {
|
||||
for (i = 0; i < tvps->num; i++)
|
||||
dtv_property_64to32(tvp_32 + i,
|
||||
(struct dtv_property *)(tvp+i));
|
||||
|
||||
if (copy_to_user((void __user *)tvps->props, tvp_32,
|
||||
tvps->num * sizeof(struct dtv_property_32))) {
|
||||
err = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
if (copy_to_user((void __user *)tvps->props, tvp,
|
||||
tvps->num * sizeof(struct dtv_property))) {
|
||||
err = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
} else
|
||||
err = -EOPNOTSUPP;
|
||||
|
||||
out:
|
||||
kfree(tvp_32);
|
||||
kfree(tvp);
|
||||
return err;
|
||||
}
|
||||
@@ -2663,24 +2790,14 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
|
||||
static long dvb_frontend_compat_ioctl(struct file *filp,
|
||||
unsigned int cmd, unsigned long args)
|
||||
{
|
||||
unsigned long ret;
|
||||
struct dtv_properties tvps;
|
||||
long ret;
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
args = (unsigned long)compat_ptr(args);
|
||||
#endif
|
||||
if ((cmd == FE_SET_PROPERTY) || (cmd == FE_GET_PROPERTY)) {
|
||||
if (copy_from_user(&tvps, (void *)args,
|
||||
sizeof(struct dtv_properties)))
|
||||
return -EFAULT;
|
||||
#ifdef CONFIG_COMPAT
|
||||
tvps.props = compat_ptr((unsigned long)tvps.props);
|
||||
#endif
|
||||
if (copy_to_user((void *)args, (void *)&tvps,
|
||||
sizeof(struct dtv_properties)))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
ret = dvb_generic_ioctl(filp, cmd, args);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -541,16 +541,38 @@ struct dtv_property {
|
||||
__u32 reserved1[3];
|
||||
void *reserved2;
|
||||
} buffer;
|
||||
#if 0
|
||||
#ifdef CONFIG_AMLOGIC_DVB_COMPAT
|
||||
} u;
|
||||
int result;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct dtv_property_32 {
|
||||
__u32 cmd;
|
||||
__u32 reserved[3];
|
||||
union {
|
||||
__u32 data;
|
||||
struct dtv_fe_stats st;
|
||||
struct {
|
||||
__u8 data[32];
|
||||
__u32 len;
|
||||
__u32 reserved1[3];
|
||||
__u64 reserved;
|
||||
} reserved;
|
||||
#endif
|
||||
#endif
|
||||
__u32 reserved2;
|
||||
} buffer;
|
||||
} u;
|
||||
int result;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct dtv_property_64 {
|
||||
__u32 cmd;
|
||||
__u32 reserved[3];
|
||||
union {
|
||||
__u32 data;
|
||||
struct dtv_fe_stats st;
|
||||
struct {
|
||||
__u8 data[32];
|
||||
__u32 len;
|
||||
__u32 reserved1[3];
|
||||
__u64 reserved2;
|
||||
} buffer;
|
||||
} u;
|
||||
int result;
|
||||
} __attribute__ ((packed));
|
||||
@@ -560,14 +582,17 @@ struct dtv_property {
|
||||
|
||||
struct dtv_properties {
|
||||
__u32 num;
|
||||
#if 0 && defined(CONFIG_AMLOGIC_DVB_COMPAT)
|
||||
union {
|
||||
struct dtv_property *props;
|
||||
__u64 reserved;
|
||||
};
|
||||
#else
|
||||
struct dtv_property *props;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct dtv_properties_32 {
|
||||
__u32 num;
|
||||
__u32 props;
|
||||
};
|
||||
|
||||
struct dtv_properties_64 {
|
||||
__u32 num;
|
||||
__u64 props;
|
||||
};
|
||||
|
||||
#if defined(__DVB_CORE__) || !defined (__KERNEL__)
|
||||
@@ -722,6 +747,12 @@ struct dvbsx_blindscanevent {
|
||||
#define FE_SET_PROPERTY _IOW('o', 82, struct dtv_properties)
|
||||
#define FE_GET_PROPERTY _IOR('o', 83, struct dtv_properties)
|
||||
|
||||
#define FE_SET_PROPERTY_32 _IOW('o', 82, struct dtv_properties_32)
|
||||
#define FE_GET_PROPERTY_32 _IOR('o', 83, struct dtv_properties_32)
|
||||
|
||||
#define FE_SET_PROPERTY_64 _IOW('o', 82, struct dtv_properties_64)
|
||||
#define FE_GET_PROPERTY_64 _IOR('o', 83, struct dtv_properties_64)
|
||||
|
||||
#ifdef CONFIG_AMLOGIC_DVB_COMPAT
|
||||
/*for atv*/
|
||||
struct tuner_status_s {
|
||||
|
||||
Reference in New Issue
Block a user