summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/hecubafb.c52
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 = {