#define FASTRPC_MAX_CRCLIST 64
#define FASTRPC_PHYS(p) ((p) & 0xffffffff)
#define FASTRPC_CTX_MAX (256)
+#define FASTRPC_INIT_HANDLE 1
#define FASTRPC_CTXID_MASK (0xFF0)
+#define INIT_FILELEN_MAX (2 * 1024 * 1024)
+#define INIT_MEMLEN_MAX (8 * 1024 * 1024)
#define FASTRPC_DEVICE_NAME "fastrpc"
/* Retrives number of input buffers from the scalars parameter */
#define FASTRPC_SCALARS(method, in, out) \
FASTRPC_BUILD_SCALARS(0, method, in, out, 0, 0)
+#define FASTRPC_CREATE_PROCESS_NARGS 6
+/* Remote Method id table */
+#define FASTRPC_RMID_INIT_ATTACH 0
+#define FASTRPC_RMID_INIT_RELEASE 1
+#define FASTRPC_RMID_INIT_CREATE 6
+#define FASTRPC_RMID_INIT_CREATE_ATTR 7
+#define FASTRPC_RMID_INIT_CREATE_STATIC 8
+
#define miscdev_to_cctx(d) container_of(d, struct fastrpc_channel_ctx, miscdev)
static const char *domains[FASTRPC_DEV_MAX] = { "adsp", "mdsp",
return err;
}
+static int fastrpc_init_create_process(struct fastrpc_user *fl,
+ char __user *argp)
+{
+ struct fastrpc_init_create init;
+ struct fastrpc_invoke_args *args;
+ struct fastrpc_phy_page pages[1];
+ struct fastrpc_map *map = NULL;
+ struct fastrpc_buf *imem = NULL;
+ int memlen;
+ int err;
+ struct {
+ int pgid;
+ u32 namelen;
+ u32 filelen;
+ u32 pageslen;
+ u32 attrs;
+ u32 siglen;
+ } inbuf;
+ u32 sc;
+
+ args = kcalloc(FASTRPC_CREATE_PROCESS_NARGS, sizeof(*args), GFP_KERNEL);
+ if (!args)
+ return -ENOMEM;
+
+ if (copy_from_user(&init, argp, sizeof(init))) {
+ err = -EFAULT;
+ goto bail;
+ }
+
+ if (init.filelen > INIT_FILELEN_MAX) {
+ err = -EINVAL;
+ goto bail;
+ }
+
+ inbuf.pgid = fl->tgid;
+ inbuf.namelen = strlen(current->comm) + 1;
+ inbuf.filelen = init.filelen;
+ inbuf.pageslen = 1;
+ inbuf.attrs = init.attrs;
+ inbuf.siglen = init.siglen;
+ fl->pd = 1;
+
+ if (init.filelen && init.filefd) {
+ err = fastrpc_map_create(fl, init.filefd, init.filelen, &map);
+ if (err)
+ goto bail;
+ }
+
+ memlen = ALIGN(max(INIT_FILELEN_MAX, (int)init.filelen * 4),
+ 1024 * 1024);
+ err = fastrpc_buf_alloc(fl, fl->sctx->dev, memlen,
+ &imem);
+ if (err) {
+ fastrpc_map_put(map);
+ goto bail;
+ }
+
+ fl->init_mem = imem;
+ args[0].ptr = (u64)(uintptr_t)&inbuf;
+ args[0].length = sizeof(inbuf);
+ args[0].fd = -1;
+
+ args[1].ptr = (u64)(uintptr_t)current->comm;
+ args[1].length = inbuf.namelen;
+ args[1].fd = -1;
+
+ args[2].ptr = (u64) init.file;
+ args[2].length = inbuf.filelen;
+ args[2].fd = init.filefd;
+
+ pages[0].addr = imem->phys;
+ pages[0].size = imem->size;
+
+ args[3].ptr = (u64)(uintptr_t) pages;
+ args[3].length = 1 * sizeof(*pages);
+ args[3].fd = -1;
+
+ args[4].ptr = (u64)(uintptr_t)&inbuf.attrs;
+ args[4].length = sizeof(inbuf.attrs);
+ args[4].fd = -1;
+
+ args[5].ptr = (u64)(uintptr_t) &inbuf.siglen;
+ args[5].length = sizeof(inbuf.siglen);
+ args[5].fd = -1;
+
+ sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE, 4, 0);
+ if (init.attrs)
+ sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE_ATTR, 6, 0);
+
+ err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE,
+ sc, args);
+
+ if (err) {
+ fastrpc_map_put(map);
+ fastrpc_buf_free(imem);
+ }
+
+bail:
+ kfree(args);
+
+ return err;
+}
+
static struct fastrpc_session_ctx *fastrpc_session_alloc(
struct fastrpc_channel_ctx *cctx)
{
spin_unlock(&cctx->lock);
}
+static int fastrpc_release_current_dsp_process(struct fastrpc_user *fl)
+{
+ struct fastrpc_invoke_args args[1];
+ int tgid = 0;
+ u32 sc;
+
+ tgid = fl->tgid;
+ args[0].ptr = (u64)(uintptr_t) &tgid;
+ args[0].length = sizeof(tgid);
+ args[0].fd = -1;
+ args[0].reserved = 0;
+ sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_RELEASE, 1, 0);
+
+ return fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE,
+ sc, &args[0]);
+}
+
static int fastrpc_device_release(struct inode *inode, struct file *file)
{
struct fastrpc_user *fl = (struct fastrpc_user *)file->private_data;
struct fastrpc_invoke_ctx *ctx, *n;
struct fastrpc_map *map, *m;
+ fastrpc_release_current_dsp_process(fl);
+
spin_lock(&cctx->lock);
list_del(&fl->user);
spin_unlock(&cctx->lock);
return 0;
}
+static int fastrpc_init_attach(struct fastrpc_user *fl)
+{
+ struct fastrpc_invoke_args args[1];
+ int tgid = fl->tgid;
+ u32 sc;
+
+ args[0].ptr = (u64)(uintptr_t) &tgid;
+ args[0].length = sizeof(tgid);
+ args[0].fd = -1;
+ args[0].reserved = 0;
+ sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_ATTACH, 1, 0);
+ fl->pd = 0;
+
+ return fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE,
+ sc, &args[0]);
+}
+
static int fastrpc_invoke(struct fastrpc_user *fl, char __user *argp)
{
struct fastrpc_invoke_args *args = NULL;
case FASTRPC_IOCTL_INVOKE:
err = fastrpc_invoke(fl, argp);
break;
+ case FASTRPC_IOCTL_INIT_ATTACH:
+ err = fastrpc_init_attach(fl);
+ break;
+ case FASTRPC_IOCTL_INIT_CREATE:
+ err = fastrpc_init_create_process(fl, argp);
+ break;
default:
err = -ENOTTY;
break;