diff options
author | Jaya Kumar <jayakumar.lkml@gmail.com> | 2008-04-28 02:15:37 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-28 08:58:41 -0700 |
commit | 963654a9c919d18f8b9137f8ffd9d2d30a139269 (patch) | |
tree | 737e3ba0a3a7f824b71750e5dded33ad8d9a20d0 /drivers/video/hecubafb.c | |
parent | 555514fabc1c24fac69ff46feac384180828182c (diff) | |
download | linux-963654a9c919d18f8b9137f8ffd9d2d30a139269.tar.gz linux-963654a9c919d18f8b9137f8ffd9d2d30a139269.tar.bz2 linux-963654a9c919d18f8b9137f8ffd9d2d30a139269.zip |
fbdev: hecubafb bugfix
This patch is a bugfix for hecubafb_write which would return an incorrect
error value for the bytecount from framebuffer writes.
Signed-off-by: Jaya Kumar <jayakumar.lkml@gmail.com>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/hecubafb.c')
-rw-r--r-- | drivers/video/hecubafb.c | 52 |
1 files changed, 27 insertions, 25 deletions
diff --git a/drivers/video/hecubafb.c b/drivers/video/hecubafb.c index 94e0df8a6f60..b77d033665da 100644 --- a/drivers/video/hecubafb.c +++ b/drivers/video/hecubafb.c @@ -270,41 +270,43 @@ static void hecubafb_imageblit(struct fb_info *info, static ssize_t hecubafb_write(struct fb_info *info, const char __user *buf, size_t count, loff_t *ppos) { - unsigned long p; - int err=-EINVAL; - struct hecubafb_par *par; - unsigned int xres; - unsigned int fbmemlength; + struct hecubafb_par *par = info->par; + unsigned long p = *ppos; + void *dst; + int err = 0; + unsigned long total_size; - p = *ppos; - par = info->par; - xres = info->var.xres; - fbmemlength = (xres * info->var.yres)/8; + if (info->state != FBINFO_STATE_RUNNING) + return -EPERM; - if (p > fbmemlength) - return -ENOSPC; + total_size = info->fix.smem_len; - err = 0; - if ((count + p) > fbmemlength) { - count = fbmemlength - p; - err = -ENOSPC; + if (p > total_size) + return -EFBIG; + + if (count > total_size) { + err = -EFBIG; + count = total_size; } - if (count) { - char *base_addr; + if (count + p > total_size) { + if (!err) + err = -ENOSPC; - base_addr = (char __force *)info->screen_base; - count -= copy_from_user(base_addr + p, buf, count); - *ppos += count; - err = -EFAULT; + count = total_size - p; } - hecubafb_dpy_update(par); + dst = (void __force *) (info->screen_base + p); + + if (copy_from_user(dst, buf, count)) + err = -EFAULT; - if (count) - return count; + if (!err) + *ppos += count; + + hecubafb_dpy_update(par); - return err; + return (err) ? err : count; } static struct fb_ops hecubafb_ops = { |