Commit 29d6f8c4 authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Linus Torvalds

[PATCH] shield fbdev operations with console semaphore

This fixes the fbdev ioctl's and fbcon cursor management with the
console semaphore, which is the best we can do at this point in 2.6,
thus fixing a bunch of races where we could have, for example, tried to
blit while changing mode, etc..
parent ca3f481d
......@@ -198,8 +198,10 @@ static void fb_flashcursor(void *private)
/* Test to see if the cursor is erased but still on */
if (!info || (info->cursor.rop == ROP_COPY))
return;
acquire_console_sem();
info->cursor.enable ^= 1;
info->fbops->fb_cursor(info, &info->cursor);
release_console_sem();
}
#if (defined(__arm__) && defined(IRQ_VSYNCPULSE)) || defined(CONFIG_ATARI) || defined(CONFIG_MAC)
......@@ -226,8 +228,7 @@ static void cursor_timer_handler(unsigned long dev_addr)
struct fb_info *info = (struct fb_info *) dev_addr;
schedule_work(&info->queue);
cursor_timer.expires = jiffies + HZ / 5;
add_timer(&cursor_timer);
mod_timer(&cursor_timer, jiffies + HZ/5);
}
int __init fb_console_setup(char *this_opt)
......@@ -676,7 +677,7 @@ static const char *fbcon_startup(void)
if (!info->queue.func) {
INIT_WORK(&info->queue, fb_flashcursor, info);
cursor_timer.expires = jiffies + HZ / 50;
cursor_timer.expires = jiffies + HZ / 5;
cursor_timer.data = (unsigned long ) info;
add_timer(&cursor_timer);
}
......
......@@ -27,6 +27,7 @@
#include <linux/init.h>
#include <linux/linux_logo.h>
#include <linux/proc_fs.h>
#include <linux/console.h>
#ifdef CONFIG_KMOD
#include <linux/kmod.h>
#endif
......@@ -979,7 +980,7 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
struct fb_con2fbmap con2fb;
#endif
struct fb_cmap cmap;
int i;
int i, rc;
if (!fb)
return -ENODEV;
......@@ -990,7 +991,9 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
case FBIOPUT_VSCREENINFO:
if (copy_from_user(&var, (void *) arg, sizeof(var)))
return -EFAULT;
acquire_console_sem();
i = fb_set_var(info, &var);
release_console_sem();
if (i) return i;
if (copy_to_user((void *) arg, &var, sizeof(var)))
return -EFAULT;
......@@ -1009,13 +1012,19 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
case FBIOPAN_DISPLAY:
if (copy_from_user(&var, (void *) arg, sizeof(var)))
return -EFAULT;
if ((i = fb_pan_display(info, &var)))
acquire_console_sem();
i = fb_pan_display(info, &var);
release_console_sem();
if (i)
return i;
if (copy_to_user((void *) arg, &var, sizeof(var)))
return -EFAULT;
return 0;
case FBIO_CURSOR:
return (fb_cursor(info, (struct fb_cursor *) arg));
acquire_console_sem();
rc = fb_cursor(info, (struct fb_cursor *) arg);
release_console_sem();
return rc;
#ifdef CONFIG_FRAMEBUFFER_CONSOLE
case FBIOGET_CON2FBMAP:
if (copy_from_user(&con2fb, (void *)arg, sizeof(con2fb)))
......@@ -1045,7 +1054,10 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
return 0;
#endif /* CONFIG_FRAMEBUFFER_CONSOLE */
case FBIOBLANK:
return fb_blank(info, arg);
acquire_console_sem();
i = fb_blank(info, arg);
release_console_sem();
return i;
default:
if (fb->fb_ioctl == NULL)
return -EINVAL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment