Skip to content

Commit

Permalink
[PATCH] fbdev: move ioctl32 code to fbmem.c
Browse files Browse the repository at this point in the history
The frame buffer layer already had some code dealing with compat ioctls, this
patch moves over the remaining code from fs/compat_ioctl.c

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Arnd Bergmann authored and Linus Torvalds committed Nov 9, 2005
1 parent 01a16fa commit c7f82d9
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 155 deletions.
147 changes: 142 additions & 5 deletions drivers/video/fbmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <linux/config.h>
#include <linux/module.h>

#include <linux/compat.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/sched.h>
Expand Down Expand Up @@ -933,18 +934,154 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
}

#ifdef CONFIG_COMPAT
struct fb_fix_screeninfo32 {
char id[16];
compat_caddr_t smem_start;
u32 smem_len;
u32 type;
u32 type_aux;
u32 visual;
u16 xpanstep;
u16 ypanstep;
u16 ywrapstep;
u32 line_length;
compat_caddr_t mmio_start;
u32 mmio_len;
u32 accel;
u16 reserved[3];
};

struct fb_cmap32 {
u32 start;
u32 len;
compat_caddr_t red;
compat_caddr_t green;
compat_caddr_t blue;
compat_caddr_t transp;
};

static int fb_getput_cmap(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct fb_cmap_user __user *cmap;
struct fb_cmap32 __user *cmap32;
__u32 data;
int err;

cmap = compat_alloc_user_space(sizeof(*cmap));
cmap32 = compat_ptr(arg);

if (copy_in_user(&cmap->start, &cmap32->start, 2 * sizeof(__u32)))
return -EFAULT;

if (get_user(data, &cmap32->red) ||
put_user(compat_ptr(data), &cmap->red) ||
get_user(data, &cmap32->green) ||
put_user(compat_ptr(data), &cmap->green) ||
get_user(data, &cmap32->blue) ||
put_user(compat_ptr(data), &cmap->blue) ||
get_user(data, &cmap32->transp) ||
put_user(compat_ptr(data), &cmap->transp))
return -EFAULT;

err = fb_ioctl(inode, file, cmd, (unsigned long) cmap);

if (!err) {
if (copy_in_user(&cmap32->start,
&cmap->start,
2 * sizeof(__u32)))
err = -EFAULT;
}
return err;
}

static int do_fscreeninfo_to_user(struct fb_fix_screeninfo *fix,
struct fb_fix_screeninfo32 __user *fix32)
{
__u32 data;
int err;

err = copy_to_user(&fix32->id, &fix->id, sizeof(fix32->id));

data = (__u32) (unsigned long) fix->smem_start;
err |= put_user(data, &fix32->smem_start);

err |= put_user(fix->smem_len, &fix32->smem_len);
err |= put_user(fix->type, &fix32->type);
err |= put_user(fix->type_aux, &fix32->type_aux);
err |= put_user(fix->visual, &fix32->visual);
err |= put_user(fix->xpanstep, &fix32->xpanstep);
err |= put_user(fix->ypanstep, &fix32->ypanstep);
err |= put_user(fix->ywrapstep, &fix32->ywrapstep);
err |= put_user(fix->line_length, &fix32->line_length);

data = (__u32) (unsigned long) fix->mmio_start;
err |= put_user(data, &fix32->mmio_start);

err |= put_user(fix->mmio_len, &fix32->mmio_len);
err |= put_user(fix->accel, &fix32->accel);
err |= copy_to_user(fix32->reserved, fix->reserved,
sizeof(fix->reserved));

return err;
}

static int fb_get_fscreeninfo(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
mm_segment_t old_fs;
struct fb_fix_screeninfo fix;
struct fb_fix_screeninfo32 __user *fix32;
int err;

fix32 = compat_ptr(arg);

old_fs = get_fs();
set_fs(KERNEL_DS);
err = fb_ioctl(inode, file, cmd, (unsigned long) &fix);
set_fs(old_fs);

if (!err)
err = do_fscreeninfo_to_user(&fix, fix32);

return err;
}

static long
fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
int fbidx = iminor(file->f_dentry->d_inode);
struct inode *inode = file->f_dentry->d_inode;
int fbidx = iminor(inode);
struct fb_info *info = registered_fb[fbidx];
struct fb_ops *fb = info->fbops;
long ret;
long ret = -ENOIOCTLCMD;

if (fb->fb_compat_ioctl == NULL)
return -ENOIOCTLCMD;
lock_kernel();
ret = fb->fb_compat_ioctl(file, cmd, arg, info);
switch(cmd) {
case FBIOGET_VSCREENINFO:
case FBIOPUT_VSCREENINFO:
case FBIOPAN_DISPLAY:
case FBIOGET_CON2FBMAP:
case FBIOPUT_CON2FBMAP:
arg = (unsigned long) compat_ptr(arg);
case FBIOBLANK:
ret = fb_ioctl(inode, file, cmd, arg);
break;

case FBIOGET_FSCREENINFO:
ret = fb_get_fscreeninfo(inode, file, cmd, arg);
break;

case FBIOGETCMAP:
case FBIOPUTCMAP:
ret = fb_getput_cmap(inode, file, cmd, arg);
break;

default:
if (fb->fb_compat_ioctl)
ret = fb->fb_compat_ioctl(file, cmd, arg, info);
break;
}
unlock_kernel();
return ret;
}
Expand Down
143 changes: 0 additions & 143 deletions fs/compat_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -840,146 +840,6 @@ static int hdio_getgeo(unsigned int fd, unsigned int cmd, unsigned long arg)
return err ? -EFAULT : 0;
}

struct fb_fix_screeninfo32 {
char id[16];
compat_caddr_t smem_start;
u32 smem_len;
u32 type;
u32 type_aux;
u32 visual;
u16 xpanstep;
u16 ypanstep;
u16 ywrapstep;
u32 line_length;
compat_caddr_t mmio_start;
u32 mmio_len;
u32 accel;
u16 reserved[3];
};

struct fb_cmap32 {
u32 start;
u32 len;
compat_caddr_t red;
compat_caddr_t green;
compat_caddr_t blue;
compat_caddr_t transp;
};

static int fb_getput_cmap(unsigned int fd, unsigned int cmd, unsigned long arg)
{
struct fb_cmap_user __user *cmap;
struct fb_cmap32 __user *cmap32;
__u32 data;
int err;

cmap = compat_alloc_user_space(sizeof(*cmap));
cmap32 = compat_ptr(arg);

if (copy_in_user(&cmap->start, &cmap32->start, 2 * sizeof(__u32)))
return -EFAULT;

if (get_user(data, &cmap32->red) ||
put_user(compat_ptr(data), &cmap->red) ||
get_user(data, &cmap32->green) ||
put_user(compat_ptr(data), &cmap->green) ||
get_user(data, &cmap32->blue) ||
put_user(compat_ptr(data), &cmap->blue) ||
get_user(data, &cmap32->transp) ||
put_user(compat_ptr(data), &cmap->transp))
return -EFAULT;

err = sys_ioctl(fd, cmd, (unsigned long) cmap);

if (!err) {
if (copy_in_user(&cmap32->start,
&cmap->start,
2 * sizeof(__u32)))
err = -EFAULT;
}
return err;
}

static int do_fscreeninfo_to_user(struct fb_fix_screeninfo *fix,
struct fb_fix_screeninfo32 __user *fix32)
{
__u32 data;
int err;

err = copy_to_user(&fix32->id, &fix->id, sizeof(fix32->id));

data = (__u32) (unsigned long) fix->smem_start;
err |= put_user(data, &fix32->smem_start);

err |= put_user(fix->smem_len, &fix32->smem_len);
err |= put_user(fix->type, &fix32->type);
err |= put_user(fix->type_aux, &fix32->type_aux);
err |= put_user(fix->visual, &fix32->visual);
err |= put_user(fix->xpanstep, &fix32->xpanstep);
err |= put_user(fix->ypanstep, &fix32->ypanstep);
err |= put_user(fix->ywrapstep, &fix32->ywrapstep);
err |= put_user(fix->line_length, &fix32->line_length);

data = (__u32) (unsigned long) fix->mmio_start;
err |= put_user(data, &fix32->mmio_start);

err |= put_user(fix->mmio_len, &fix32->mmio_len);
err |= put_user(fix->accel, &fix32->accel);
err |= copy_to_user(fix32->reserved, fix->reserved,
sizeof(fix->reserved));

return err;
}

static int fb_get_fscreeninfo(unsigned int fd, unsigned int cmd, unsigned long arg)
{
mm_segment_t old_fs;
struct fb_fix_screeninfo fix;
struct fb_fix_screeninfo32 __user *fix32;
int err;

fix32 = compat_ptr(arg);

old_fs = get_fs();
set_fs(KERNEL_DS);
err = sys_ioctl(fd, cmd, (unsigned long) &fix);
set_fs(old_fs);

if (!err)
err = do_fscreeninfo_to_user(&fix, fix32);

return err;
}

static int fb_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
{
int err;

switch (cmd) {
case FBIOGET_FSCREENINFO:
err = fb_get_fscreeninfo(fd,cmd, arg);
break;

case FBIOGETCMAP:
case FBIOPUTCMAP:
err = fb_getput_cmap(fd, cmd, arg);
break;

default:
do {
static int count;
if (++count <= 20)
printk("%s: Unknown fb ioctl cmd fd(%d) "
"cmd(%08x) arg(%08lx)\n",
__FUNCTION__, fd, cmd, arg);
} while(0);
err = -ENOSYS;
break;
};

return err;
}

static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
{
mm_segment_t old_fs = get_fs();
Expand Down Expand Up @@ -2953,10 +2813,7 @@ HANDLE_IOCTL(BLKGETSIZE, w_long)
HANDLE_IOCTL(0x1260, broken_blkgetsize)
HANDLE_IOCTL(BLKFRAGET, w_long)
HANDLE_IOCTL(BLKSECTGET, w_long)
HANDLE_IOCTL(FBIOGET_FSCREENINFO, fb_ioctl_trans)
HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans)
HANDLE_IOCTL(FBIOGETCMAP, fb_ioctl_trans)
HANDLE_IOCTL(FBIOPUTCMAP, fb_ioctl_trans)
HANDLE_IOCTL(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans)
HANDLE_IOCTL(HDIO_GET_UNMASKINTR, hdio_ioctl_trans)
HANDLE_IOCTL(HDIO_GET_DMA, hdio_ioctl_trans)
Expand Down
7 changes: 0 additions & 7 deletions include/linux/compat_ioctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,6 @@ ULONG_IOCTL(TIOCSCTTY)
COMPATIBLE_IOCTL(TIOCGPTN)
COMPATIBLE_IOCTL(TIOCSPTLCK)
COMPATIBLE_IOCTL(TIOCSERGETLSR)
/* Big F */
COMPATIBLE_IOCTL(FBIOBLANK)
COMPATIBLE_IOCTL(FBIOGET_VSCREENINFO)
COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO)
COMPATIBLE_IOCTL(FBIOPAN_DISPLAY)
COMPATIBLE_IOCTL(FBIOGET_CON2FBMAP)
COMPATIBLE_IOCTL(FBIOPUT_CON2FBMAP)
/* Little f */
COMPATIBLE_IOCTL(FIOCLEX)
COMPATIBLE_IOCTL(FIONCLEX)
Expand Down

0 comments on commit c7f82d9

Please sign in to comment.