Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2004-02-14 17:32:00 -0800
committerLinus Torvalds <torvalds@home.osdl.org>2004-02-14 17:32:00 -0800
commit29d6f8c42d8137f1c1206aa3342df537f5100e41 (patch)
treefaab74715ac717c3788ae244c474ba955903d226
parentca3f481da292d16461268fad5bbb3c0ecf1a7af6 (diff)
[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..
-rw-r--r--drivers/video/console/fbcon.c7
-rw-r--r--drivers/video/fbmem.c20
2 files changed, 20 insertions, 7 deletions
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 11422933cf15..50fe17ea95dd 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -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);
}
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index bff474679be9..4dea35376d2c 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -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;