static int vfs_read_write(int op, int helper_pid, void *data, int fd, int count, unsigned *pos) { struct expressos_venus_proc *proc; struct file *file; mm_segment_t fs_save; int ret; loff_t p = *pos; if (!(proc = expressos_venus_find_proc(helper_pid))) return -EINVAL; if (!(file = expressos_venus_fget(proc, fd))) return -EBADF; fs_save = get_fs(); set_fs(get_ds()); if (op == VFS_OP_READ) ret = vfs_read(file, data, count, &p); else ret = vfs_write(file, data, count, &p); *pos = p; set_fs(fs_save); fput(file); return ret; }
int expressos_ipc_ioctl(int helper_pid, int fd, unsigned cmd, int arg0) { int ret; mm_segment_t fs_save; struct expressos_venus_proc *proc; struct file *file; switch (cmd) { case FIONREAD: arg0 = (int)expressos_ipc_shm_buf; break; default: return -ENOTTY; } if (!(proc = expressos_venus_find_proc(helper_pid))) return -EINVAL; if (!(file = expressos_venus_fget(proc, fd))) return -EBADF; fs_save = get_fs(); set_fs(get_ds()); ret = do_vfs_ioctl(file, -1, cmd, arg0); set_fs(fs_save); fput(file); return ret; }
int expressos_ipc_scatter_write_page_async(int helper_pid, int fd, int page_count, const void *data) { struct expressos_venus_proc *proc; struct file *file; mm_segment_t fs_save; int ret, i; const int *pg_offs = (const int*)data; const char *blob = (const char*)(pg_offs + page_count); if (!expressos_ipc_valid_ptr(pg_offs) || !expressos_ipc_valid_trunk(blob, page_count * PAGE_SIZE)) return -EFAULT; if (!(proc = expressos_venus_find_proc(helper_pid))) return -EINVAL; if (!(file = expressos_venus_fget(proc, fd))) return -EBADF; fs_save = get_fs(); set_fs(get_ds()); i = 0; while (i < page_count) { int j = i + 1; loff_t pos = pg_offs[i] * PAGE_SIZE; /* * Consolidate write requests. */ while (j < page_count && pg_offs[j] == pg_offs[i] + (j - i)) ++j; ret = vfs_write(file, blob + i * PAGE_SIZE, (j - i) * PAGE_SIZE, &pos); if (ret < 0) printk(KERN_WARNING "expressos_ipc_flush_pages_async:" "failed to write to pgoffset %d, fd=%d, ret=%d\n", pg_offs[i], fd, ret); i = j; } set_fs(fs_save); fput(file); return 0; }
int expressos_ipc_ashmem_ioctl(int helper_pid, int fd, unsigned cmd, int arg0) { int ret; mm_segment_t fs_save; struct expressos_venus_proc *proc; struct file *file; switch (cmd) { case ASHMEM_PIN: case ASHMEM_UNPIN: case ASHMEM_SET_NAME: case ASHMEM_GET_NAME: arg0 = (int)expressos_ipc_shm_buf; break; case ASHMEM_SET_SIZE: case ASHMEM_GET_SIZE: case ASHMEM_SET_PROT_MASK: case ASHMEM_GET_PROT_MASK: case ASHMEM_GET_PIN_STATUS: case ASHMEM_PURGE_ALL_CACHES: break; default: return -ENOSYS; } if (!(proc = expressos_venus_find_proc(helper_pid))) return -EINVAL; if (!(file = expressos_venus_fget(proc, fd))) return -EBADF; fs_save = get_fs(); set_fs(get_ds()); ret = do_vfs_ioctl(file, -1, cmd, arg0); set_fs(fs_save); fput(file); return ret; }
int expressos_ipc_fcntl64(int helper_pid, int fd, int cmd, int arg0) { int ret; mm_segment_t fs_save; struct expressos_venus_proc *proc; struct file *file; if (!(proc = expressos_venus_find_proc(helper_pid))) return -EINVAL; if (!(file = expressos_venus_fget(proc, fd))) return -EBADF; fs_save = get_fs(); set_fs(get_ds()); ret = do_fcntl(-1, cmd, arg0, file); set_fs(fs_save); fput(file); return ret; }