Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / video / amifb.c
index 95ea71c..3033c72 100644 (file)
@@ -590,6 +590,8 @@ static u_short maxfmode, chipset;
 #define highw(x)       ((u_long)(x)>>16 & 0xffff)
 #define loww(x)                ((u_long)(x) & 0xffff)
 
+#define custom         amiga_custom
+
 #define VBlankOn()     custom.intena = IF_SETCLR|IF_COPER
 #define VBlankOff()    custom.intena = IF_COPER
 
@@ -1129,9 +1131,7 @@ static void amifb_copyarea(struct fb_info *info,
                           const struct fb_copyarea *region);
 static void amifb_imageblit(struct fb_info *info,
                            const struct fb_image *image);
-static int amifb_ioctl(struct inode *inode, struct file *file,
-                      unsigned int cmd, unsigned long arg,
-                      struct fb_info *info);
+static int amifb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg);
 
 
        /*
@@ -1164,8 +1164,8 @@ static void ami_update_display(void);
 static void ami_init_display(void);
 static void ami_do_blank(void);
 static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix);
-static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data);
-static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data);
+static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data);
+static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data);
 static int ami_get_cursorstate(struct fb_cursorstate *state);
 static int ami_set_cursorstate(struct fb_cursorstate *state);
 static void ami_set_sprite(void);
@@ -1185,7 +1185,6 @@ static struct fb_ops amifb_ops = {
        .fb_fillrect    = amifb_fillrect,
        .fb_copyarea    = amifb_copyarea,
        .fb_imageblit   = amifb_imageblit,
-       .fb_cursor      = soft_cursor,
        .fb_ioctl       = amifb_ioctl,
 };
 
@@ -1239,8 +1238,6 @@ int __init amifb_setup(char *options)
                if (!strcmp(this_opt, "inverse")) {
                        amifb_inverse = 1;
                        fb_invert_cmaps();
-               } else if (!strcmp(this_opt, "off")) {
-                       amifb_video_off();
                } else if (!strcmp(this_opt, "ilbm"))
                        amifb_ilbm = 1;
                else if (!strncmp(this_opt, "monitorcap:", 11))
@@ -1307,6 +1304,8 @@ static int amifb_set_par(struct fb_info *info)
                info->fix.ywrapstep = 1;
                info->fix.xpanstep = 0;
                info->fix.ypanstep = 0;
+               info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YWRAP |
+                   FBINFO_READS_FAST; /* override SCROLL_REDRAW */
        } else {
                info->fix.ywrapstep = 0;
                if (par->vmode & FB_VMODE_SMOOTH_XPAN)
@@ -1314,6 +1313,7 @@ static int amifb_set_par(struct fb_info *info)
                else
                        info->fix.xpanstep = 16<<maxfmode;
                info->fix.ypanstep = 1;
+               info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
        }
        return 0;
 }
@@ -2170,15 +2170,15 @@ static void amifb_imageblit(struct fb_info *info, const struct fb_image *image)
         * Amiga Frame Buffer Specific ioctls
         */
 
-static int amifb_ioctl(struct inode *inode, struct file *file,
-                      unsigned int cmd, unsigned long arg,
-                      struct fb_info *info)
+static int amifb_ioctl(struct fb_info *info,
+                      unsigned int cmd, unsigned long arg)
 {
        union {
                struct fb_fix_cursorinfo fix;
                struct fb_var_cursorinfo var;
                struct fb_cursorstate state;
        } crsr;
+       void __user *argp = (void __user *)arg;
        int i;
 
        switch (cmd) {
@@ -2186,33 +2186,32 @@ static int amifb_ioctl(struct inode *inode, struct file *file,
                        i = ami_get_fix_cursorinfo(&crsr.fix);
                        if (i)
                                return i;
-                       return copy_to_user((void *)arg, &crsr.fix,
+                       return copy_to_user(argp, &crsr.fix,
                                            sizeof(crsr.fix)) ? -EFAULT : 0;
 
                case FBIOGET_VCURSORINFO:
                        i = ami_get_var_cursorinfo(&crsr.var,
-                               ((struct fb_var_cursorinfo *)arg)->data);
+                               ((struct fb_var_cursorinfo __user *)arg)->data);
                        if (i)
                                return i;
-                       return copy_to_user((void *)arg, &crsr.var,
+                       return copy_to_user(argp, &crsr.var,
                                            sizeof(crsr.var)) ? -EFAULT : 0;
 
                case FBIOPUT_VCURSORINFO:
-                       if (copy_from_user(&crsr.var, (void *)arg,
-                                          sizeof(crsr.var)))
+                       if (copy_from_user(&crsr.var, argp, sizeof(crsr.var)))
                                return -EFAULT;
                        return ami_set_var_cursorinfo(&crsr.var,
-                               ((struct fb_var_cursorinfo *)arg)->data);
+                               ((struct fb_var_cursorinfo __user *)arg)->data);
 
                case FBIOGET_CURSORSTATE:
                        i = ami_get_cursorstate(&crsr.state);
                        if (i)
                                return i;
-                       return copy_to_user((void *)arg, &crsr.state,
+                       return copy_to_user(argp, &crsr.state,
                                            sizeof(crsr.state)) ? -EFAULT : 0;
 
                case FBIOPUT_CURSORSTATE:
-                       if (copy_from_user(&crsr.state, (void *)arg,
+                       if (copy_from_user(&crsr.state, argp,
                                           sizeof(crsr.state)))
                                return -EFAULT;
                        return ami_set_cursorstate(&crsr.state);
@@ -2254,21 +2253,17 @@ int __init amifb_init(void)
        u_long chipptr;
        u_int defmode;
 
-       if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_VIDEO))
-               return -ENXIO;
-
-       /*
-        * TODO: where should we put this? The DMI Resolver doesn't have a
-        *       frame buffer accessible by the CPU
-        */
+#ifndef MODULE
+       char *option = NULL;
 
-#ifdef CONFIG_GSP_RESOLVER
-       if (amifb_resolver){
-               custom.dmacon = DMAF_MASTER | DMAF_RASTER | DMAF_COPPER |
-                               DMAF_BLITTER | DMAF_SPRITE;
-               return 0;
+       if (fb_get_options("amifb", &option)) {
+               amifb_video_off();
+               return -ENODEV;
        }
+       amifb_setup(option);
 #endif
+       if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_VIDEO))
+               return -ENXIO;
 
        /*
         * We request all registers starting from bplpt[0]
@@ -2382,7 +2377,7 @@ default_chipset:
 
        fb_info.fbops = &amifb_ops;
        fb_info.par = &currentpar;
-       fb_info.flags = FBINFO_FLAG_DEFAULT;
+       fb_info.flags = FBINFO_DEFAULT;
 
        if (!fb_find_mode(&fb_info.var, &fb_info, mode_option, ami_modedb,
                          NUM_TOTAL_MODES, &ami_modedb[defmode], 4)) {
@@ -2472,6 +2467,7 @@ static void amifb_deinit(void)
 static int amifb_blank(int blank, struct fb_info *info)
 {
        do_blank = blank ? blank : -1;
+
        return 0;
 }
 
@@ -2946,21 +2942,11 @@ static int ami_encode_var(struct fb_var_screeninfo *var,
        var->bits_per_pixel = par->bpp;
        var->grayscale = 0;
 
-       if (IS_AGA) {
-               var->red.offset = 0;
-               var->red.length = 8;
-               var->red.msb_right = 0;
-       } else {
-               if (clk_shift == TAG_SHRES) {
-                       var->red.offset = 0;
-                       var->red.length = 2;
-                       var->red.msb_right = 0;
-               } else {
-                       var->red.offset = 0;
-                       var->red.length = 4;
-                       var->red.msb_right = 0;
-               }
-       }
+       var->red.offset = 0;
+       var->red.msb_right = 0;
+       var->red.length = par->bpp;
+       if (par->bplcon0 & BPC0_HAM)
+           var->red.length -= 2;
        var->blue = var->green = var->red;
        var->transp.offset = 0;
        var->transp.length = 0;
@@ -3260,20 +3246,20 @@ static void ami_do_blank(void)
                custom.dmacon = DMAF_RASTER | DMAF_SPRITE;
                red = green = blue = 0;
                if (!IS_OCS && do_blank > 1) {
-                       switch (do_blank-1) {
-                               case VESA_VSYNC_SUSPEND:
+                       switch (do_blank) {
+                               case FB_BLANK_VSYNC_SUSPEND:
                                        custom.hsstrt = hsstrt2hw(par->hsstrt);
                                        custom.hsstop = hsstop2hw(par->hsstop);
                                        custom.vsstrt = vsstrt2hw(par->vtotal+4);
                                        custom.vsstop = vsstop2hw(par->vtotal+4);
                                        break;
-                               case VESA_HSYNC_SUSPEND:
+                               case FB_BLANK_HSYNC_SUSPEND:
                                        custom.hsstrt = hsstrt2hw(par->htotal+16);
                                        custom.hsstop = hsstop2hw(par->htotal+16);
                                        custom.vsstrt = vsstrt2hw(par->vsstrt);
                                        custom.vsstop = vsstrt2hw(par->vsstop);
                                        break;
-                               case VESA_POWERDOWN:
+                               case FB_BLANK_POWERDOWN:
                                        custom.hsstrt = hsstrt2hw(par->htotal+16);
                                        custom.hsstop = hsstop2hw(par->htotal+16);
                                        custom.vsstrt = vsstrt2hw(par->vtotal+4);
@@ -3338,7 +3324,7 @@ static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix)
        return 0;
 }
 
-static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data)
+static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data)
 {
        struct amifb_par *par = &currentpar;
        register u_short *lspr, *sspr;
@@ -3350,7 +3336,7 @@ static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data)
        register short delta;
        register u_char color;
        short height, width, bits, words;
-       int i, size, alloc;
+       int size, alloc;
 
        size = par->crsr.height*par->crsr.width;
        alloc = var->height*var->width;
@@ -3360,14 +3346,14 @@ static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data)
        var->yspot = par->crsr.spot_y;
        if (size > var->height*var->width)
                return -ENAMETOOLONG;
-       if ((i = verify_area(VERIFY_WRITE, (void *)data, size)))
-               return i;
+       if (!access_ok(VERIFY_WRITE, data, size))
+               return -EFAULT;
        delta = 1<<par->crsr.fmode;
        lspr = lofsprite + (delta<<1);
        if (par->bplcon0 & BPC0_LACE)
                sspr = shfsprite + (delta<<1);
        else
-               sspr = 0;
+               sspr = NULL;
        for (height = (short)var->height-1; height >= 0; height--) {
                bits = 0; words = delta; datawords = 0;
                for (width = (short)var->width-1; width >= 0; width--) {
@@ -3413,7 +3399,7 @@ static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data)
        return 0;
 }
 
-static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data)
+static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data)
 {
        struct amifb_par *par = &currentpar;
        register u_short *lspr, *sspr;
@@ -3425,7 +3411,6 @@ static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data)
        register short delta;
        u_short fmode;
        short height, width, bits, words;
-       int i;
 
        if (!var->width)
                return -EINVAL;
@@ -3441,8 +3426,8 @@ static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data)
                return -EINVAL;
        if (!var->height)
                return -EINVAL;
-       if ((i = verify_area(VERIFY_READ, (void *)data, var->width*var->height)))
-               return i;
+       if (!access_ok(VERIFY_READ, data, var->width*var->height))
+               return -EFAULT;
        delta = 1<<fmode;
        lofsprite = shfsprite = (u_short *)spritememory;
        lspr = lofsprite + (delta<<1);
@@ -3456,13 +3441,13 @@ static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data)
                if (((var->height+2)<<fmode<<2) > SPRITEMEMSIZE)
                        return -EINVAL;
                memset(lspr, 0, (var->height+2)<<fmode<<2);
-               sspr = 0;
+               sspr = NULL;
        }
        for (height = (short)var->height-1; height >= 0; height--) {
                bits = 16; words = delta; datawords = 0;
                for (width = (short)var->width-1; width >= 0; width--) {
                        unsigned long tdata = 0;
-                       get_user(tdata, (char *)data);
+                       get_user(tdata, data);
                        data++;
 #ifdef __mc68000__
                        asm volatile (
@@ -3811,14 +3796,11 @@ static void ami_rebuild_copper(void)
 }
 
 
+module_init(amifb_init);
+
 #ifdef MODULE
 MODULE_LICENSE("GPL");
 
-int init_module(void)
-{
-       return amifb_init();
-}
-
 void cleanup_module(void)
 {
        unregister_framebuffer(&fb_info);