From: "Antonino A. Daplas" Make fb_read() and fb_write() return 0 (EOF) instead of -ENOSPC if reading at or past the end of the framebuffer. This fixes user space apps hanging if info->fix.smem_len == 0. Whitespace changes. Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton --- drivers/video/fbmem.c | 32 ++++++++++++++++++++------------ 1 files changed, 20 insertions(+), 12 deletions(-) diff -puN drivers/video/fbmem.c~fbdev-fix-return-code-of-fb_read-and-fb_write drivers/video/fbmem.c --- devel/drivers/video/fbmem.c~fbdev-fix-return-code-of-fb_read-and-fb_write 2006-01-03 20:00:04.000000000 -0800 +++ devel-akpm/drivers/video/fbmem.c 2006-01-03 20:00:04.000000000 -0800 @@ -589,17 +589,19 @@ fb_read(struct file *file, char __user * return info->fbops->fb_read(file, buf, count, ppos); total_size = info->screen_size; + if (total_size == 0) total_size = info->fix.smem_len; if (p >= total_size) - return 0; + return 0; + if (count >= total_size) - count = total_size; + count = total_size; + if (count + p > total_size) count = total_size - p; - cnt = 0; buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL); if (!buffer) @@ -636,6 +638,7 @@ fb_read(struct file *file, char __user * } kfree(buffer); + return (err) ? err : cnt; } @@ -648,7 +651,7 @@ fb_write(struct file *file, const char _ struct fb_info *info = registered_fb[fbidx]; u32 *buffer, *src; u32 __iomem *dst; - int c, i, cnt = 0, err; + int c, i, cnt = 0, err = 0; unsigned long total_size; if (!info || !info->screen_base) @@ -661,19 +664,19 @@ fb_write(struct file *file, const char _ return info->fbops->fb_write(file, buf, count, ppos); total_size = info->screen_size; + if (total_size == 0) total_size = info->fix.smem_len; if (p > total_size) - return -ENOSPC; + return 0; + if (count >= total_size) - count = total_size; - err = 0; - if (count + p > total_size) { - count = total_size - p; - err = -ENOSPC; - } - cnt = 0; + count = total_size; + + if (count + p > total_size) + count = total_size - p; + buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL); if (!buffer) @@ -687,12 +690,15 @@ fb_write(struct file *file, const char _ while (count) { c = (count > PAGE_SIZE) ? PAGE_SIZE : count; src = buffer; + if (copy_from_user(src, buf, c)) { err = -EFAULT; break; } + for (i = c >> 2; i--; ) fb_writel(*src++, dst++); + if (c & 3) { u8 *src8 = (u8 *) src; u8 __iomem *dst8 = (u8 __iomem *) dst; @@ -702,11 +708,13 @@ fb_write(struct file *file, const char _ dst = (u32 __iomem *) dst8; } + *ppos += c; buf += c; cnt += c; count -= c; } + kfree(buffer); return (err) ? err : cnt; _