]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] cmap annotations
authorAlexander Viro <viro@www.linux.org.uk>
Thu, 29 Jul 2004 15:48:53 +0000 (08:48 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Thu, 29 Jul 2004 15:48:53 +0000 (08:48 -0700)
fb_set_cmap() and fb_copy_cmap() split into kernel and userland versions.
fb_cmap, fb_image and fb_cursor split and annotated.
fixed bug in sbuslib.c that used to call "userland" version of fb_set_cmap()
when kernel one was need (RGB data was already copied into kernel space).

Signed-off-by: Al Viro <viro@parcelfarce.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
14 files changed:
drivers/video/aty/aty128fb.c
drivers/video/aty/radeon_pm.c
drivers/video/console/fbcon.c
drivers/video/fbcmap.c
drivers/video/fbmem.c
drivers/video/offb.c
drivers/video/pxafb.c
drivers/video/sa1100fb.c
drivers/video/sbuslib.c
drivers/video/sis/sis_main.c
drivers/video/softcursor.c
drivers/video/tdfxfb.c
fs/compat_ioctl.c
include/linux/fb.h

index f2f45501d50f3320b69e957d4fc295208d89ec27..bd907297c4614106201455819e5800fd09a8ca9f 100644 (file)
@@ -2419,7 +2419,7 @@ static int aty128_pci_resume(struct pci_dev *pdev)
        wait_for_idle(par);
        aty128fb_set_par(info);
        fb_pan_display(info, &info->var);
-       fb_set_cmap(&info->cmap, 1, info);
+       fb_set_cmap(&info->cmap, info);
 
        /* Refresh */
        fb_set_suspend(info, 0);
index 9ab6811279f9348a70130a2da4cbf6d20115e4dd..c26f43c04155b92bafbcb4997dbf4e2f49d79a73 100644 (file)
@@ -922,7 +922,7 @@ int radeonfb_pci_resume(struct pci_dev *pdev)
        /* Restore display & engine */
        radeonfb_set_par(info);
        fb_pan_display(info, &info->var);
-       fb_set_cmap(&info->cmap, 1, info);
+       fb_set_cmap(&info->cmap, info);
 
        /* Refresh */
        fb_set_suspend(info, 0);
index 3077b7792d30495a2b4c6c61defe672b4b205b00..2fcb51a57381fffe6e271c6efa8942256b7819ba 100644 (file)
@@ -2310,7 +2310,7 @@ static int fbcon_set_palette(struct vc_data *vc, unsigned char *table)
        else
                palette_cmap.len = 16;
        palette_cmap.start = 0;
-       return fb_set_cmap(&palette_cmap, 1, info);
+       return fb_set_cmap(&palette_cmap, info);
 }
 
 static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
index 482693db18a066dedfd5f09e2f3c0d58d9ece265..c51f8fb5c1de50c6b61ffad823165eea0d27d96e 100644 (file)
@@ -111,7 +111,7 @@ int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp)
     }
     cmap->start = 0;
     cmap->len = len;
-    fb_copy_cmap(fb_default_cmap(len), cmap, 0);
+    fb_copy_cmap(fb_default_cmap(len), cmap);
     return 0;
 
 fail:
@@ -143,53 +143,50 @@ void fb_dealloc_cmap(struct fb_cmap *cmap)
  *     fb_copy_cmap - copy a colormap
  *     @from: frame buffer colormap structure
  *     @to: frame buffer colormap structure
- *     @fsfromto: determine copy method
  *
  *     Copy contents of colormap from @from to @to.
- *
- *     @fsfromto accepts the following integer parameters:
- *     0: memcpy function
- *     1: copy_from_user() function to copy from userspace
- *     2: copy_to_user() function to copy to userspace
- *
  */
 
-int fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto)
+int fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to)
 {
-    int tooff = 0, fromoff = 0;
-    int size;
-    
-    if (to->start > from->start)
-       fromoff = to->start-from->start;
-    else
-       tooff = from->start-to->start;
-    size = to->len-tooff;
-    if (size > (int) (from->len - fromoff))
-       size = from->len-fromoff;
-    if (size <= 0)
-       return -EINVAL;
-    size *= sizeof(u16);
-    
-    switch (fsfromto) {
-    case 0:
+       int tooff = 0, fromoff = 0;
+       int size;
+
+       if (to->start > from->start)
+               fromoff = to->start - from->start;
+       else
+               tooff = from->start - to->start;
+       size = to->len - tooff;
+       if (size > (int) (from->len - fromoff))
+               size = from->len - fromoff;
+       if (size <= 0)
+               return -EINVAL;
+       size *= sizeof(u16);
+
        memcpy(to->red+tooff, from->red+fromoff, size);
        memcpy(to->green+tooff, from->green+fromoff, size);
        memcpy(to->blue+tooff, from->blue+fromoff, size);
        if (from->transp && to->transp)
-           memcpy(to->transp+tooff, from->transp+fromoff, size);
-        break;
-    case 1:
-       if (copy_from_user(to->red+tooff, from->red+fromoff, size))
-               return -EFAULT;
-       if (copy_from_user(to->green+tooff, from->green+fromoff, size))
-               return -EFAULT; 
-       if (copy_from_user(to->blue+tooff, from->blue+fromoff, size))
-               return -EFAULT;
-       if (from->transp && to->transp)
-            if (copy_from_user(to->transp+tooff, from->transp+fromoff, size))
-                   return -EFAULT;     
-       break;
-    case 2:
+               memcpy(to->transp+tooff, from->transp+fromoff, size);
+       return 0;
+}
+
+int fb_cmap_to_user(struct fb_cmap *from, struct fb_cmap_user *to)
+{
+       int tooff = 0, fromoff = 0;
+       int size;
+
+       if (to->start > from->start)
+               fromoff = to->start - from->start;
+       else
+               tooff = from->start - to->start;
+       size = to->len - tooff;
+       if (size > (int) (from->len - fromoff))
+               size = from->len - fromoff;
+       if (size <= 0)
+               return -EINVAL;
+       size *= sizeof(u16);
+
        if (copy_to_user(to->red+tooff, from->red+fromoff, size))
                return -EFAULT;
        if (copy_to_user(to->green+tooff, from->green+fromoff, size))
@@ -199,15 +196,12 @@ int fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto)
        if (from->transp && to->transp)
                if (copy_to_user(to->transp+tooff, from->transp+fromoff, size))
                        return -EFAULT;
-       break;
-    }
-    return 0;
+       return 0;
 }
 
 /**
  *     fb_set_cmap - set the colormap
  *     @cmap: frame buffer colormap structure
- *     @kspc: boolean, 1 copy local, 0 get_user() function
  *     @info: frame buffer info structure
  *
  *     Sets the colormap @cmap for a screen of device @info.
@@ -216,46 +210,63 @@ int fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto)
  *
  */
 
-int fb_set_cmap(struct fb_cmap *cmap, int kspc, struct fb_info *info)
+int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info)
 {
-    int i, start;
-    u16 *red, *green, *blue, *transp;
-    u_int hred, hgreen, hblue, htransp;
-
-    red = cmap->red;
-    green = cmap->green;
-    blue = cmap->blue;
-    transp = cmap->transp;
-    start = cmap->start;
-
-    if (start < 0 || !info->fbops->fb_setcolreg)
-       return -EINVAL;
-    for (i = 0; i < cmap->len; i++) {
-       if (kspc) {
-           hred = *red;
-           hgreen = *green;
-           hblue = *blue;
-           htransp = transp ? *transp : 0xffff;
-       } else {
-           get_user(hred, red);
-           get_user(hgreen, green);
-           get_user(hblue, blue);
-           if (transp)
-               get_user(htransp, transp);
-           else
-               htransp = 0xffff;
+       int i, start;
+       u16 *red, *green, *blue, *transp;
+       u_int hred, hgreen, hblue, htransp = 0xffff;
+
+       red = cmap->red;
+       green = cmap->green;
+       blue = cmap->blue;
+       transp = cmap->transp;
+       start = cmap->start;
+
+       if (start < 0 || !info->fbops->fb_setcolreg)
+               return -EINVAL;
+       for (i = 0; i < cmap->len; i++) {
+               hred = *red++;
+               hgreen = *green++;
+               hblue = *blue++;
+               if (transp)
+                       htransp = *transp++;
+               if (info->fbops->fb_setcolreg(start++,
+                                             hred, hgreen, hblue, htransp,
+                                             info))
+                       break;
        }
-       red++;
-       green++;
-       blue++;
-       if (transp)
-           transp++;
-       if (info->fbops->fb_setcolreg(start++, hred, hgreen, hblue, htransp, info))
-           return 0;
-    }
-    return 0;
+       return 0;
 }
 
+int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info)
+{
+       int i, start;
+       u16 __user *red, *green, *blue, *transp;
+       u_int hred, hgreen, hblue, htransp = 0xffff;
+
+       red = cmap->red;
+       green = cmap->green;
+       blue = cmap->blue;
+       transp = cmap->transp;
+       start = cmap->start;
+
+       if (start < 0 || !info->fbops->fb_setcolreg)
+               return -EINVAL;
+       for (i = 0; i < cmap->len; i++, red++, blue++, green++) {
+               if (get_user(hred, red) ||
+                   get_user(hgreen, green) ||
+                   get_user(hblue, blue) ||
+                   (transp && get_user(htransp, transp)))
+                       return -EFAULT;
+               if (info->fbops->fb_setcolreg(start++,
+                                             hred, hgreen, hblue, htransp,
+                                             info))
+                       return 0;
+               if (transp)
+                       transp++;
+       }
+       return 0;
+}
 
 /**
  *     fb_default_cmap - get default colormap
index 6fea22049a794f792baf743dbde29884407cb8f1..2a55e5dbf326b5a00a165db1258f5780c434f9a7 100644 (file)
@@ -593,7 +593,7 @@ static void fb_set_logocmap(struct fb_info *info,
                        palette_cmap.blue[j] = clut[2] << 8 | clut[2];
                        clut += 3;
                }
-               fb_set_cmap(&palette_cmap, 1, info);
+               fb_set_cmap(&palette_cmap, info);
        }
 }
 
@@ -938,9 +938,9 @@ fb_load_cursor_image(struct fb_info *info)
 }
 
 int
-fb_cursor(struct fb_info *info, struct fb_cursor __user *sprite)
+fb_cursor(struct fb_info *info, struct fb_cursor_user __user *sprite)
 {
-       struct fb_cursor cursor_user;
+       struct fb_cursor_user cursor_user;
        struct fb_cursor cursor;
        char *data = NULL, *mask = NULL;
        u16 *red = NULL, *green = NULL, *blue = NULL, *transp = NULL;
@@ -1073,7 +1073,7 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
 
                        fb_pan_display(info, &info->var);
 
-                       fb_set_cmap(&info->cmap, 1, info);
+                       fb_set_cmap(&info->cmap, info);
 
                        if (info->flags & FBINFO_MISC_MODECHANGEUSER) {
                                info->flags &= ~FBINFO_MISC_MODECHANGEUSER;
@@ -1102,7 +1102,7 @@ fb_blank(struct fb_info *info, int blank)
                cmap.len = info->cmap.len;
        } else
                cmap = info->cmap;
-       return fb_set_cmap(&cmap, 1, info);
+       return fb_set_cmap(&cmap, info);
 }
 
 static int 
@@ -1117,7 +1117,7 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 #ifdef CONFIG_FRAMEBUFFER_CONSOLE
        struct fb_con2fbmap con2fb;
 #endif
-       struct fb_cmap cmap;
+       struct fb_cmap_user cmap;
        void __user *argp = (void __user *)arg;
        int i;
        
@@ -1145,11 +1145,11 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        case FBIOPUTCMAP:
                if (copy_from_user(&cmap, argp, sizeof(cmap)))
                        return -EFAULT;
-               return (fb_set_cmap(&cmap, 0, info));
+               return (fb_set_user_cmap(&cmap, info));
        case FBIOGETCMAP:
                if (copy_from_user(&cmap, argp, sizeof(cmap)))
                        return -EFAULT;
-               return (fb_copy_cmap(&info->cmap, &cmap, 2));
+               return fb_cmap_to_user(&info->cmap, &cmap);
        case FBIOPAN_DISPLAY:
                if (copy_from_user(&var, argp, sizeof(var)))
                        return -EFAULT;
index e1715ef972b82d281b44b99a8d39634c2f2a11ef..99c2e6322ebb05fc9a74a4ca627a8f3282fef19d 100644 (file)
@@ -235,7 +235,7 @@ static int offb_blank(int blank, struct fb_info *info)
                                break;
                        }
        } else
-               fb_set_cmap(&info->cmap, 1, info);
+               fb_set_cmap(&info->cmap, info);
        return 0;
 }
 
index aaac77f2c7cd25cbdddd0657621dfbba70b80cb3..0a860dd8879c6ded6e33f1aa317560822b4e1d58 100644 (file)
@@ -386,7 +386,7 @@ static int pxafb_blank(int blank, struct fb_info *info)
                //TODO if (pxafb_blank_helper) pxafb_blank_helper(blank);
                if (fbi->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR ||
                    fbi->fb.fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
-                       fb_set_cmap(&fbi->fb.cmap, 1, info);
+                       fb_set_cmap(&fbi->fb.cmap, info);
                pxafb_schedule_work(fbi, C_ENABLE);
        }
        return 0;
index 1bca4cd1f71b1d485af99296626343c03c8e8718..a15f0c4302aa2d4d8aba315292c4d5d5d8719968 100644 (file)
@@ -1074,7 +1074,7 @@ static int sa1100fb_blank(int blank, struct fb_info *info)
        case VESA_NO_BLANKING:
                if (fbi->fb.fix.visual == FB_VISUAL_PSEUDOCOLOR ||
                    fbi->fb.fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
-                       fb_set_cmap(&fbi->fb.cmap, 1, info);
+                       fb_set_cmap(&fbi->fb.cmap, info);
                sa1100fb_schedule_work(fbi, C_ENABLE);
        }
        return 0;
index c1ab754d38c6241ad778830b0e84d555644e0a47..eeeb462d3376a93bb80439c97b6bd1115a0e734d 100644 (file)
@@ -132,7 +132,7 @@ int sbusfb_ioctl_helper(unsigned long cmd, unsigned long arg,
                                return -EFAULT;
 
                        cmap.start = index + i;
-                       err = fb_set_cmap(&cmap, 0, info);
+                       err = fb_set_cmap(&cmap, info);
                        if (err)
                                return err;
                }
index aa1f313232e9589411a23f6fedf7f839777abc1f..9ad218d6a05f75b1529c13f0a386cc86b966cd40 100644 (file)
@@ -1566,10 +1566,10 @@ sisfb_do_install_cmap(int con, struct fb_info *info)
         if(con != ivideo->currcon) return;
 
         if(fb_display[con].cmap.len) {
-               fb_set_cmap(&fb_display[con].cmap, 1, sisfb_setcolreg, info);
+               fb_set_cmap(&fb_display[con].cmap, sisfb_setcolreg, info);
         } else {
                int size = sisfb_get_cmap_len(&fb_display[con].var);
-               fb_set_cmap(fb_default_cmap(size), 1, sisfb_setcolreg, info);
+               fb_set_cmap(fb_default_cmap(size), sisfb_setcolreg, info);
        }
 }
 
index f38575924095856d30ae3a8cfaf99db976f87b52..a953b467b28252564277540beded52874ec0d6b2 100644 (file)
@@ -43,7 +43,7 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
                        info->cursor.image.fg_color = cursor->image.fg_color;
                } else {
                        if (cursor->image.cmap.len)
-                               fb_copy_cmap(&cursor->image.cmap, &info->cursor.image.cmap, 0);
+                               fb_copy_cmap(&cursor->image.cmap, &info->cursor.image.cmap);
                }
                info->cursor.image.depth = cursor->image.depth;
        }       
index f3aa37ea05962c6ba5550ece54822af0f9c2e9c4..2873877622e3388b71161301725cf60a200f635c 100644 (file)
@@ -1050,7 +1050,7 @@ static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
                bg_color = ((cmap.red[cmap.start+1] << 16) |
                            (cmap.green[cmap.start+1] << 8) |
                            (cmap.blue[cmap.start+1]));
-               fb_copy_cmap(&cmap, &info->cursor.image.cmap, 0);
+               fb_copy_cmap(&cmap, &info->cursor.image.cmap);
                spin_lock_irqsave(&par->DAClock, flags);
                banshee_make_room(par, 2);
                tdfx_outl(par, HWCURC0, bg_color);
index 145e974ce882d1c1c1b7199a212e0c9405cfe167..dc1a2d2c41d5ed8ec0ca73dbbeea801b5fdb7fd5 100644 (file)
@@ -851,7 +851,7 @@ struct fb_cmap32 {
 
 static int fb_getput_cmap(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-       struct fb_cmap __user *cmap;
+       struct fb_cmap_user __user *cmap;
        struct fb_cmap32 __user *cmap32;
        __u32 data;
        int err;
index afcdc664ddc48010f93e121cdaa18019b844a995..9186883fcb0f765ce03b3146b571da43a4d35ce7 100644 (file)
 #define FBIOGETCMAP            0x4604
 #define FBIOPUTCMAP            0x4605
 #define FBIOPAN_DISPLAY                0x4606
+#ifdef __KERNEL__
+#define FBIO_CURSOR            _IOWR('F', 0x08, struct fb_cursor_user)
+#else
 #define FBIO_CURSOR            _IOWR('F', 0x08, struct fb_cursor)
+#endif
 /* 0x4607-0x460B are defined below */
 /* #define FBIOGET_MONITORSPEC 0x460C */
 /* #define FBIOPUT_MONITORSPEC 0x460D */
@@ -397,6 +401,36 @@ struct fb_info;
 struct device;
 struct file;
 
+struct fb_cmap_user {
+       __u32 start;                    /* First entry  */
+       __u32 len;                      /* Number of entries */
+       __u16 __user *red;              /* Red values   */
+       __u16 __user *green;
+       __u16 __user *blue;
+       __u16 __user *transp;           /* transparency, can be NULL */
+};
+
+struct fb_image_user {
+       __u32 dx;                       /* Where to place image */
+       __u32 dy;
+       __u32 width;                    /* Size of image */
+       __u32 height;
+       __u32 fg_color;                 /* Only used when a mono bitmap */
+       __u32 bg_color;
+       __u8  depth;                    /* Depth of the image */
+       const char __user *data;        /* Pointer to image data */
+       struct fb_cmap_user cmap;       /* color map info */
+};
+
+struct fb_cursor_user {
+       __u16 set;                      /* what to set */
+       __u16 enable;                   /* cursor on/off */
+       __u16 rop;                      /* bitop operation */
+       const char __user *mask;        /* cursor mask bits */
+       struct fbcurpos hot;            /* cursor hot spot */
+       struct fb_image_user image;     /* Cursor image */
+};
+
 /*
  * Register/unregister for framebuffer events
  */
@@ -696,8 +730,10 @@ extern const struct fb_videomode vesa_modes[];
 /* drivers/video/fbcmap.c */
 extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp);
 extern void fb_dealloc_cmap(struct fb_cmap *cmap);
-extern int fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto);
-extern int fb_set_cmap(struct fb_cmap *cmap, int kspc, struct fb_info *fb_info);
+extern int fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to);
+extern int fb_cmap_to_user(struct fb_cmap *from, struct fb_cmap_user *to);
+extern int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *fb_info);
+extern int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *fb_info);
 extern struct fb_cmap *fb_default_cmap(int len);
 extern void fb_invert_cmaps(void);