File Index
Files and directories
Sign in
FILE

fb_sys_fops.c

File preview with syntax highlighting.

linux-6.19.14/drivers/video/fbdev/core/fb_sys_fops.c C
  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
 13#include <linux/export.h>
 14#include <linux/fb.h>
 15#include <linux/module.h>
 16#include <linux/uaccess.h>
 17
 18ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count,
 19		    loff_t *ppos)
 20{
 21	unsigned long p = *ppos;
 22	void *src;
 23	int err = 0;
 24	unsigned long total_size, c;
 25	ssize_t ret;
 26
 27	if (!(info->flags & FBINFO_VIRTFB))
 28		fb_warn_once(info, "Framebuffer is not in virtual address space.");
 29
 30	if (!info->screen_buffer)
 31		return -ENODEV;
 32
 33	total_size = info->screen_size;
 34
 35	if (total_size == 0)
 36		total_size = info->fix.smem_len;
 37
 38	if (p >= total_size)
 39		return 0;
 40
 41	if (count >= total_size)
 42		count = total_size;
 43
 44	if (count + p > total_size)
 45		count = total_size - p;
 46
 47	src = info->screen_buffer + p;
 48
 49	if (info->fbops->fb_sync)
 50		info->fbops->fb_sync(info);
 51
 52	c = copy_to_user(buf, src, count);
 53	if (c)
 54		err = -EFAULT;
 55	ret = count - c;
 56
 57	*ppos += ret;
 58
 59	return ret ? ret : err;
 60}
 61EXPORT_SYMBOL_GPL(fb_sys_read);
 62
 63ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
 64		     size_t count, loff_t *ppos)
 65{
 66	unsigned long p = *ppos;
 67	void *dst;
 68	int err = 0;
 69	unsigned long total_size, c;
 70	size_t ret;
 71
 72	if (!(info->flags & FBINFO_VIRTFB))
 73		fb_warn_once(info, "Framebuffer is not in virtual address space.");
 74
 75	if (!info->screen_buffer)
 76		return -ENODEV;
 77
 78	total_size = info->screen_size;
 79
 80	if (total_size == 0)
 81		total_size = info->fix.smem_len;
 82
 83	if (p > total_size)
 84		return -EFBIG;
 85
 86	if (count > total_size) {
 87		err = -EFBIG;
 88		count = total_size;
 89	}
 90
 91	if (count + p > total_size) {
 92		if (!err)
 93			err = -ENOSPC;
 94
 95		count = total_size - p;
 96	}
 97
 98	dst = info->screen_buffer + p;
 99
100	if (info->fbops->fb_sync)
101		info->fbops->fb_sync(info);
102
103	c = copy_from_user(dst, buf, count);
104	if (c)
105		err = -EFAULT;
106	ret = count - c;
107
108	*ppos += ret;
109
110	return ret ? ret : err;
111}
112EXPORT_SYMBOL_GPL(fb_sys_write);
113
114MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
115MODULE_DESCRIPTION("Generic file read (fb in system RAM)");
116MODULE_LICENSE("GPL");
~/ Read-only file preview.