connector: Provide the sender's credentials to the callback
[safe/jmp/linux-2.6] / drivers / video / uvesafb.c
index d1d6c0f..aa7cd95 100644 (file)
@@ -43,9 +43,9 @@ static struct fb_fix_screeninfo uvesafb_fix __devinitdata = {
 };
 
 static int mtrr                __devinitdata = 3; /* enable mtrr by default */
-static int blank       __devinitdata = 1; /* enable blanking by default */
-static int ypan                __devinitdata = 1; /* 0: scroll, 1: ypan, 2: ywrap */
-static int pmi_setpal  __devinitdata = 1; /* use PMI for palette changes */
+static int blank       = 1;               /* enable blanking by default */
+static int ypan                = 1;             /* 0: scroll, 1: ypan, 2: ywrap */
+static bool pmi_setpal __devinitdata = true; /* use PMI for palette changes */
 static int nocrtc      __devinitdata; /* ignore CRTC settings */
 static int noedid      __devinitdata; /* don't try DDC transfers */
 static int vram_remap  __devinitdata; /* set amt. of memory to be used */
@@ -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);
@@ -66,9 +67,8 @@ static DEFINE_MUTEX(uvfb_lock);
  * find the kernel part of the task struct, copy the registers and
  * the buffer contents and then complete the task.
  */
-static void uvesafb_cn_callback(void *data)
+static void uvesafb_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
 {
-       struct cn_msg *msg = data;
        struct uvesafb_task *utask;
        struct uvesafb_ktask *task;
 
@@ -181,14 +181,15 @@ static int uvesafb_exec(struct uvesafb_ktask *task)
        /* If all slots are taken -- bail out. */
        if (uvfb_tasks[seq]) {
                mutex_unlock(&uvfb_lock);
-               return -EBUSY;
+               err = -EBUSY;
+               goto out;
        }
 
        /* Save a pointer to the kernel part of the task struct. */
        uvfb_tasks[seq] = task;
        mutex_unlock(&uvfb_lock);
 
-       err = cn_netlink_send(m, 0, gfp_any());
+       err = cn_netlink_send(m, 0, GFP_KERNEL);
        if (err == -ESRCH) {
                /*
                 * Try to start the userspace helper if sending
@@ -203,9 +204,11 @@ static int uvesafb_exec(struct uvesafb_ktask *task)
                } else {
                        v86d_started = 1;
                        err = cn_netlink_send(m, 0, gfp_any());
+                       if (err == -ENOBUFS)
+                               err = 0;
                }
-       }
-       kfree(m);
+       } else if (err == -ENOBUFS)
+               err = 0;
 
        if (!err && !(task->t.flags & TF_EXIT))
                err = !wait_for_completion_timeout(task->done,
@@ -218,7 +221,8 @@ static int uvesafb_exec(struct uvesafb_ktask *task)
        seq++;
        if (seq >= UVESAFB_TASKS_MAX)
                seq = 0;
-
+out:
+       kfree(m);
        return err;
 }
 
@@ -299,22 +303,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;
        }
 }
 
@@ -515,10 +507,12 @@ static int __devinit uvesafb_vbe_getmodes(struct uvesafb_ktask *task,
 
                err = uvesafb_exec(task);
                if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
-                       printk(KERN_ERR "uvesafb: Getting mode info block "
+                       printk(KERN_WARNING "uvesafb: Getting mode info block "
                                "for mode 0x%x failed (eax=0x%x, err=%d)\n",
                                *mode, (u32)task->t.regs.eax, err);
-                       return -EINVAL;
+                       mode++;
+                       par->vbe_modes_cnt--;
+                       continue;
                }
 
                mib = task->buf;
@@ -547,7 +541,10 @@ static int __devinit uvesafb_vbe_getmodes(struct uvesafb_ktask *task,
                        mib->depth = mib->bits_per_pixel;
        }
 
-       return 0;
+       if (par->vbe_modes_cnt > 0)
+               return 0;
+       else
+               return -EINVAL;
 }
 
 /*
@@ -841,14 +838,16 @@ static int __devinit uvesafb_vbe_init_mode(struct fb_info *info)
        if (vbemode) {
                for (i = 0; i < par->vbe_modes_cnt; i++) {
                        if (par->vbe_modes[i].mode_id == vbemode) {
+                               modeid = i;
+                               uvesafb_setup_var(&info->var, info,
+                                               &par->vbe_modes[modeid]);
                                fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60,
-                                                       &info->var, info);
+                                               &info->var, info);
                                /*
                                 * With pixclock set to 0, the default BIOS
                                 * timings will be used in set_par().
                                 */
                                info->var.pixclock = 0;
-                               modeid = i;
                                goto gotmode;
                        }
                }
@@ -885,7 +884,7 @@ static int __devinit uvesafb_vbe_init_mode(struct fb_info *info)
        }
 
        /* fb_find_mode() failed */
-       if (i == 0 || i >= 3) {
+       if (i == 0) {
                info->var.xres = 640;
                info->var.yres = 480;
                mode = (struct fb_videomode *)
@@ -895,8 +894,11 @@ static int __devinit uvesafb_vbe_init_mode(struct fb_info *info)
                        fb_videomode_to_var(&info->var, mode);
                } else {
                        modeid = par->vbe_modes[0].mode_id;
+                       uvesafb_setup_var(&info->var, info,
+                                       &par->vbe_modes[modeid]);
                        fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60,
-                                   &info->var, info);
+                                       &info->var, info);
+
                        goto gotmode;
                }
        }
@@ -908,9 +910,9 @@ static int __devinit uvesafb_vbe_init_mode(struct fb_info *info)
        if (modeid == -1)
                return -EINVAL;
 
-gotmode:
        uvesafb_setup_var(&info->var, info, &par->vbe_modes[modeid]);
 
+gotmode:
        /*
         * If we are not VBE3.0+ compliant, we're done -- the BIOS will
         * ignore our timings anyway.
@@ -992,7 +994,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)
@@ -1041,7 +1043,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) {
@@ -1303,13 +1305,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;
                }
        }
 
@@ -1543,13 +1541,13 @@ static void __devinit uvesafb_init_info(struct fb_info *info,
        }
 
        info->flags = FBINFO_FLAG_DEFAULT |
-                       (par->ypan) ? FBINFO_HWACCEL_YPAN : 0;
+                       (par->ypan ? FBINFO_HWACCEL_YPAN : 0);
 
        if (!par->ypan)
                info->fbops->fb_pan_display = NULL;
 }
 
-static void uvesafb_init_mtrr(struct fb_info *info)
+static void __devinit uvesafb_init_mtrr(struct fb_info *info)
 {
 #ifdef CONFIG_MTRR
        if (mtrr && !(info->fix.smem_start & (PAGE_SIZE - 1))) {
@@ -2003,12 +2001,8 @@ static void __devexit uvesafb_exit(void)
 
 module_exit(uvesafb_exit);
 
-static inline int param_get_scroll(char *buffer, struct kernel_param *kp)
-{
-       return 0;
-}
-
-static inline int param_set_scroll(const char *val, struct kernel_param *kp)
+#define param_get_scroll NULL
+static int param_set_scroll(const char *val, struct kernel_param *kp)
 {
        ypan = 0;
 
@@ -2018,15 +2012,17 @@ static inline int param_set_scroll(const char *val, struct kernel_param *kp)
                ypan = 1;
        else if (!strcmp(val, "ywrap"))
                ypan = 2;
+       else
+               return -EINVAL;
 
        return 0;
 }
 
-#define param_check_scroll(name, p) __param_check(name, p, void);
+#define param_check_scroll(name, p) __param_check(name, p, void)
 
 module_param_named(scroll, ypan, scroll, 0);
 MODULE_PARM_DESC(scroll,
-       "Scrolling mode, set to 'redraw', ''ypan' or 'ywrap'");
+       "Scrolling mode, set to 'redraw', 'ypan', or 'ywrap'");
 module_param_named(vgapal, pmi_setpal, invbool, 0);
 MODULE_PARM_DESC(vgapal, "Set palette using VGA registers");
 module_param_named(pmipal, pmi_setpal, bool, 0);
@@ -2053,8 +2049,8 @@ MODULE_PARM_DESC(maxhf,
 module_param(maxvf, ushort, 0);
 MODULE_PARM_DESC(maxvf,
        "Maximum vertical frequency [Hz], overrides EDID data");
-module_param_named(mode, mode_option, charp, 0);
-MODULE_PARM_DESC(mode,
+module_param(mode_option, charp, 0);
+MODULE_PARM_DESC(mode_option,
        "Specify initial video mode as \"<xres>x<yres>[-<bpp>][@<refresh>]\"");
 module_param(vbemode, ushort, 0);
 MODULE_PARM_DESC(vbemode,