diff options
author | Antonino A. Daplas <adaplas@gmail.com> | 2006-01-09 23:53:37 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-10 11:01:50 -0500 |
commit | 0a484a3af905a256cbdd7079defceac62b39e8fa (patch) | |
tree | a7349d0d7d774abca668ce52a58b845958fa79c8 | |
parent | 244ab72d84a04d40bd270da604161e02af73fb11 (diff) |
[PATCH] fbdev: Fix return code of fb_read and fb_write
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 <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | drivers/video/fbmem.c | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 10dfdf035264..83e259413115 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -589,17 +589,19 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
589 | return info->fbops->fb_read(file, buf, count, ppos); | 589 | return info->fbops->fb_read(file, buf, count, ppos); |
590 | 590 | ||
591 | total_size = info->screen_size; | 591 | total_size = info->screen_size; |
592 | |||
592 | if (total_size == 0) | 593 | if (total_size == 0) |
593 | total_size = info->fix.smem_len; | 594 | total_size = info->fix.smem_len; |
594 | 595 | ||
595 | if (p >= total_size) | 596 | if (p >= total_size) |
596 | return 0; | 597 | return 0; |
598 | |||
597 | if (count >= total_size) | 599 | if (count >= total_size) |
598 | count = total_size; | 600 | count = total_size; |
601 | |||
599 | if (count + p > total_size) | 602 | if (count + p > total_size) |
600 | count = total_size - p; | 603 | count = total_size - p; |
601 | 604 | ||
602 | cnt = 0; | ||
603 | buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, | 605 | buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, |
604 | GFP_KERNEL); | 606 | GFP_KERNEL); |
605 | if (!buffer) | 607 | if (!buffer) |
@@ -636,6 +638,7 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
636 | } | 638 | } |
637 | 639 | ||
638 | kfree(buffer); | 640 | kfree(buffer); |
641 | |||
639 | return (err) ? err : cnt; | 642 | return (err) ? err : cnt; |
640 | } | 643 | } |
641 | 644 | ||
@@ -648,7 +651,7 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
648 | struct fb_info *info = registered_fb[fbidx]; | 651 | struct fb_info *info = registered_fb[fbidx]; |
649 | u32 *buffer, *src; | 652 | u32 *buffer, *src; |
650 | u32 __iomem *dst; | 653 | u32 __iomem *dst; |
651 | int c, i, cnt = 0, err; | 654 | int c, i, cnt = 0, err = 0; |
652 | unsigned long total_size; | 655 | unsigned long total_size; |
653 | 656 | ||
654 | if (!info || !info->screen_base) | 657 | if (!info || !info->screen_base) |
@@ -661,19 +664,19 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
661 | return info->fbops->fb_write(file, buf, count, ppos); | 664 | return info->fbops->fb_write(file, buf, count, ppos); |
662 | 665 | ||
663 | total_size = info->screen_size; | 666 | total_size = info->screen_size; |
667 | |||
664 | if (total_size == 0) | 668 | if (total_size == 0) |
665 | total_size = info->fix.smem_len; | 669 | total_size = info->fix.smem_len; |
666 | 670 | ||
667 | if (p > total_size) | 671 | if (p > total_size) |
668 | return -ENOSPC; | 672 | return 0; |
673 | |||
669 | if (count >= total_size) | 674 | if (count >= total_size) |
670 | count = total_size; | 675 | count = total_size; |
671 | err = 0; | 676 | |
672 | if (count + p > total_size) { | 677 | if (count + p > total_size) |
673 | count = total_size - p; | 678 | count = total_size - p; |
674 | err = -ENOSPC; | 679 | |
675 | } | ||
676 | cnt = 0; | ||
677 | buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, | 680 | buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, |
678 | GFP_KERNEL); | 681 | GFP_KERNEL); |
679 | if (!buffer) | 682 | if (!buffer) |
@@ -687,12 +690,15 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
687 | while (count) { | 690 | while (count) { |
688 | c = (count > PAGE_SIZE) ? PAGE_SIZE : count; | 691 | c = (count > PAGE_SIZE) ? PAGE_SIZE : count; |
689 | src = buffer; | 692 | src = buffer; |
693 | |||
690 | if (copy_from_user(src, buf, c)) { | 694 | if (copy_from_user(src, buf, c)) { |
691 | err = -EFAULT; | 695 | err = -EFAULT; |
692 | break; | 696 | break; |
693 | } | 697 | } |
698 | |||
694 | for (i = c >> 2; i--; ) | 699 | for (i = c >> 2; i--; ) |
695 | fb_writel(*src++, dst++); | 700 | fb_writel(*src++, dst++); |
701 | |||
696 | if (c & 3) { | 702 | if (c & 3) { |
697 | u8 *src8 = (u8 *) src; | 703 | u8 *src8 = (u8 *) src; |
698 | u8 __iomem *dst8 = (u8 __iomem *) dst; | 704 | u8 __iomem *dst8 = (u8 __iomem *) dst; |
@@ -702,11 +708,13 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
702 | 708 | ||
703 | dst = (u32 __iomem *) dst8; | 709 | dst = (u32 __iomem *) dst8; |
704 | } | 710 | } |
711 | |||
705 | *ppos += c; | 712 | *ppos += c; |
706 | buf += c; | 713 | buf += c; |
707 | cnt += c; | 714 | cnt += c; |
708 | count -= c; | 715 | count -= c; |
709 | } | 716 | } |
717 | |||
710 | kfree(buffer); | 718 | kfree(buffer); |
711 | 719 | ||
712 | return (err) ? err : cnt; | 720 | return (err) ? err : cnt; |