fb_sys_fops.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /*
  2. * linux/drivers/video/fb_sys_read.c - Generic file operations where
  3. * framebuffer is in system RAM
  4. *
  5. * Copyright (C) 2007 Antonino Daplas <adaplas@pol.net>
  6. *
  7. * This file is subject to the terms and conditions of the GNU General Public
  8. * License. See the file COPYING in the main directory of this archive
  9. * for more details.
  10. *
  11. */
  12. #include <linux/fb.h>
  13. #include <linux/module.h>
  14. #include <linux/uaccess.h>
  15. ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count,
  16. loff_t *ppos)
  17. {
  18. unsigned long p = *ppos;
  19. void *src;
  20. int err = 0;
  21. unsigned long total_size;
  22. if (info->state != FBINFO_STATE_RUNNING)
  23. return -EPERM;
  24. total_size = info->screen_size;
  25. if (total_size == 0)
  26. total_size = info->fix.smem_len;
  27. if (p >= total_size)
  28. return 0;
  29. if (count >= total_size)
  30. count = total_size;
  31. if (count + p > total_size)
  32. count = total_size - p;
  33. src = (void __force *)(info->screen_base + p);
  34. if (info->fbops->fb_sync)
  35. info->fbops->fb_sync(info);
  36. if (copy_to_user(buf, src, count))
  37. err = -EFAULT;
  38. if (!err)
  39. *ppos += count;
  40. return (err) ? err : count;
  41. }
  42. EXPORT_SYMBOL_GPL(fb_sys_read);
  43. ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
  44. size_t count, loff_t *ppos)
  45. {
  46. unsigned long p = *ppos;
  47. void *dst;
  48. int err = 0;
  49. unsigned long total_size;
  50. if (info->state != FBINFO_STATE_RUNNING)
  51. return -EPERM;
  52. total_size = info->screen_size;
  53. if (total_size == 0)
  54. total_size = info->fix.smem_len;
  55. if (p > total_size)
  56. return -EFBIG;
  57. if (count > total_size) {
  58. err = -EFBIG;
  59. count = total_size;
  60. }
  61. if (count + p > total_size) {
  62. if (!err)
  63. err = -ENOSPC;
  64. count = total_size - p;
  65. }
  66. dst = (void __force *) (info->screen_base + p);
  67. if (info->fbops->fb_sync)
  68. info->fbops->fb_sync(info);
  69. if (copy_from_user(dst, buf, count))
  70. err = -EFAULT;
  71. if (!err)
  72. *ppos += count;
  73. return (err) ? err : count;
  74. }
  75. EXPORT_SYMBOL_GPL(fb_sys_write);
  76. MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
  77. MODULE_DESCRIPTION("Generic file read (fb in system RAM)");
  78. MODULE_LICENSE("GPL");