uvesafb: fix color component length for pseudocolor modes
authorMichal Januszewski <spock@gentoo.org>
Mon, 13 Apr 2009 21:39:43 +0000 (14:39 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 13 Apr 2009 22:04:29 +0000 (15:04 -0700)
uvesafb incorrectly sets the length of the color fields to 6 bits for
PSEUDOCOLOR modes, even though 8 bits are always used per pixel.  Fix this
by setting the length to 8.

The switch of the DAC width from the default 6 bits to 8 bits is retained
and tracked internally in the driver, but never exposed to userspace.

Signed-off-by: Michal Januszewski <spock@gentoo.org>
Acked-by: Krzysztof Helt <krzysztof.h1@poczta.fm>
Cc: <syrjala@sci.fi>
Cc: Geert Uytterhoeven <geert.uytterhoeven@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/video/uvesafb.c

index 0b370aebdbfd24d528cab7442d1983801b36b7c5..421770b5e6abb7bcb99cf7d86a0fc5786d7ad2ea 100644 (file)
@@ -55,6 +55,7 @@ static u16 maxvf      __devinitdata; /* maximum vertical frequency */
 static u16 maxhf       __devinitdata; /* maximum horizontal frequency */
 static u16 vbemode     __devinitdata; /* force use of a specific VBE mode */
 static char *mode_option __devinitdata;
+static u8  dac_width   = 6;
 
 static struct uvesafb_ktask *uvfb_tasks[UVESAFB_TASKS_MAX];
 static DEFINE_MUTEX(uvfb_lock);
@@ -303,22 +304,10 @@ static void uvesafb_setup_var(struct fb_var_screeninfo *var,
                var->blue.offset   = 0;
                var->transp.offset = 0;
 
-               /*
-                * We're assuming that we can switch the DAC to 8 bits. If
-                * this proves to be incorrect, we'll update the fields
-                * later in set_par().
-                */
-               if (par->vbe_ib.capabilities & VBE_CAP_CAN_SWITCH_DAC) {
-                       var->red.length    = 8;
-                       var->green.length  = 8;
-                       var->blue.length   = 8;
-                       var->transp.length = 0;
-               } else {
-                       var->red.length    = 6;
-                       var->green.length  = 6;
-                       var->blue.length   = 6;
-                       var->transp.length = 0;
-               }
+               var->red.length    = 8;
+               var->green.length  = 8;
+               var->blue.length   = 8;
+               var->transp.length = 0;
        }
 }
 
@@ -1006,7 +995,7 @@ static int uvesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
                struct fb_info *info)
 {
        struct uvesafb_pal_entry entry;
-       int shift = 16 - info->var.green.length;
+       int shift = 16 - dac_width;
        int err = 0;
 
        if (regno >= info->cmap.len)
@@ -1055,7 +1044,7 @@ static int uvesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
 static int uvesafb_setcmap(struct fb_cmap *cmap, struct fb_info *info)
 {
        struct uvesafb_pal_entry *entries;
-       int shift = 16 - info->var.green.length;
+       int shift = 16 - dac_width;
        int i, err = 0;
 
        if (info->var.bits_per_pixel == 8) {
@@ -1317,13 +1306,9 @@ setmode:
                err = uvesafb_exec(task);
                if (err || (task->t.regs.eax & 0xffff) != 0x004f ||
                    ((task->t.regs.ebx & 0xff00) >> 8) != 8) {
-                       /*
-                        * We've failed to set the DAC palette format -
-                        * time to correct var.
-                        */
-                       info->var.red.length    = 6;
-                       info->var.green.length  = 6;
-                       info->var.blue.length   = 6;
+                       dac_width = 6;
+               } else {
+                       dac_width = 8;
                }
        }