/* * This funcion reads the *physical* memory. The f_pos points directly to the * memory location. */ static ssize_t read_mem(struct file * file, char __user * buf, size_t count, loff_t *ppos) { unsigned long p = *ppos; ssize_t read; if (!valid_phys_addr_range(p, &count)) return -EFAULT; read = 0; #if defined(__sparc__) || (defined(__mc68000__) && defined(CONFIG_MMU)) /* we don't have page 0 mapped on sparc and m68k.. */ if (p < PAGE_SIZE) { unsigned long sz = PAGE_SIZE-p; if (sz > count) sz = count; if (sz > 0) { if (clear_user(buf, sz)) return -EFAULT; buf += sz; p += sz; count -= sz; read += sz; } } #endif if (copy_to_user(buf, __va(p), count)) return -EFAULT; read += count; *ppos += read; return read; }
static ssize_t write_mem(struct file * file, const char __user * buf, size_t count, loff_t *ppos) { unsigned long p = *ppos; if (!valid_phys_addr_range(p, &count)) return -EFAULT; return do_write_mem(__va(p), p, buf, count, ppos); }
/* * This funcion reads the *physical* memory. The f_pos points directly to the * memory location. */ static ssize_t read_mem(struct file * file, char __user * buf, size_t count, loff_t *ppos) { unsigned long p = *ppos; ssize_t read, sz; char *ptr; if (!valid_phys_addr_range(p, &count)) return -EFAULT; read = 0; #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED /* we don't have page 0 mapped on sparc and m68k.. */ if (p < PAGE_SIZE) { sz = PAGE_SIZE - p; if (sz > count) sz = count; if (sz > 0) { if (clear_user(buf, sz)) return -EFAULT; buf += sz; p += sz; count -= sz; read += sz; } } #endif while (count > 0) { /* * Handle first page in case it's not aligned */ if (-p & (PAGE_SIZE - 1)) sz = -p & (PAGE_SIZE - 1); else sz = PAGE_SIZE; sz = min_t(unsigned long, sz, count); /* * On ia64 if a page has been mapped somewhere as * uncached, then it must also be accessed uncached * by the kernel or data corruption may occur */ ptr = xlate_dev_mem_ptr(p); if (copy_to_user(buf, ptr, sz)) return -EFAULT; buf += sz; p += sz; count -= sz; read += sz; } *ppos += read; return read; }
static int log_buf_open(struct inode *inode, struct file *filp) { void *base; /* determine the ram area is valid or not. */ if (!valid_phys_addr_range(log_start, log_size) || !memblock_is_region_reserved(log_start, log_size)) { pr_err("%s: check memory range failed!\n", __func__); return -EINVAL; } base = ioremap(log_start, log_size); filp->private_data = base; if (!base) { pr_err("%s: remap error!\n", __func__); return -ENOMEM; } return 0; }
static ssize_t write_mem(struct file * file, const char __user * buf, size_t count, loff_t *ppos) { unsigned long p = *ppos; ssize_t written, sz; unsigned long copied; void *ptr; if (!valid_phys_addr_range(p, &count)) return -EFAULT; written = 0; #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED /* we don't have page 0 mapped on sparc and m68k.. */ if (p < PAGE_SIZE) { unsigned long sz = PAGE_SIZE - p; if (sz > count) sz = count; /* Hmm. Do something? */ buf += sz; p += sz; count -= sz; written += sz; } #endif while (count > 0) { /* * Handle first page in case it's not aligned */ if (-p & (PAGE_SIZE - 1)) sz = -p & (PAGE_SIZE - 1); else sz = PAGE_SIZE; sz = min_t(unsigned long, sz, count); /* * On ia64 if a page has been mapped somewhere as * uncached, then it must also be accessed uncached * by the kernel or data corruption may occur */ ptr = xlate_dev_mem_ptr(p); copied = copy_from_user(ptr, buf, sz); if (copied) { ssize_t ret; ret = written + (sz - copied); if (ret) return ret; return -EFAULT; } buf += sz; p += sz; count -= sz; written += sz; } *ppos += written; return written; }