]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] shield fbdev operations with console semaphore
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Sun, 15 Feb 2004 01:32:00 +0000 (17:32 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Sun, 15 Feb 2004 01:32:00 +0000 (17:32 -0800)
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..

drivers/video/console/fbcon.c
drivers/video/fbmem.c

index 11422933cf1506b7f9307f299791ba122cab4961..50fe17ea95dd21676da845aeb12cdc7742291f9a 100644 (file)
@@ -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);
        }
index bff474679be9d14a63fe5d913d16ff606fa90a78..4dea35376d2c20f08131730142f285ff0d4bce01 100644 (file)
@@ -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;