Ejemplo n.º 1
0
int fimg2d_add_command(struct fimg2d_control *info, struct fimg2d_context *ctx,
			struct fimg2d_blit __user *u)
{
	struct fimg2d_bltcmd *cmd;

#ifdef CONFIG_VIDEO_FIMG2D_DEBUG
	fimg2d_print_params(u);
#endif

	if (info->err) {
		printk(KERN_ERR "[%s] device error, do sw fallback\n", __func__);
		return -EFAULT;
	}

	if (fimg2d_check_params(u))
		return -EINVAL;

	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
	if (!cmd) {
		printk(KERN_ERR "[%s] failed to create bitblt command\n", __func__);
		return -ENOMEM;
	}

	cmd->ctx = ctx;
	cmd->seq_no = u->seq_no;

	cmd->op = u->op;
	cmd->premult = u->premult;
	cmd->g_alpha = u->g_alpha;
	cmd->dither = u->dither;
	cmd->rotate = u->rotate;
	cmd->solid_color = u->solid_color;

	if (u->scaling && u->scaling->mode) {
		if (copy_from_user(&cmd->scaling, u->scaling, sizeof(cmd->scaling)))
			goto err_user;
	}

	if (u->repeat && u->repeat->mode) {
		if (copy_from_user(&cmd->repeat, u->repeat, sizeof(cmd->repeat)))
			goto err_user;
	}

	if (u->bluscr && u->bluscr->mode) {
		if (copy_from_user(&cmd->bluscr, u->bluscr, sizeof(cmd->bluscr)))
			goto err_user;
	}

	if (u->clipping && u->clipping->enable) {
		if (copy_from_user(&cmd->clipping, u->clipping, sizeof(cmd->clipping)))
			goto err_user;
	}

	if (u->src) {
		cmd->srcen = true;
		if (copy_from_user(&cmd->src, u->src, sizeof(cmd->src)))
			goto err_user;
	}

	if (u->dst) {
		cmd->dsten = true;
		if (copy_from_user(&cmd->dst, u->dst, sizeof(cmd->dst)))
			goto err_user;
	}

	if (u->msk) {
		cmd->msken = true;
		if (copy_from_user(&cmd->msk, u->msk, sizeof(cmd->msk)))
			goto err_user;
	}

	if (u->src_rect) {
		if (copy_from_user(&cmd->src_rect, u->src_rect, sizeof(cmd->src_rect)))
			goto err_user;
	}

	if (u->dst_rect) {
		if (copy_from_user(&cmd->dst_rect, u->dst_rect, sizeof(cmd->dst_rect)))
			goto err_user;
	}

	if (u->msk_rect) {
		if (copy_from_user(&cmd->msk_rect, u->msk_rect, sizeof(cmd->msk_rect)))
			goto err_user;
	}

	fimg2d_fixup_params(cmd);

	if (fimg2d_check_dma_sync(cmd))
		goto err_user;

	/* add command node and increase ncmd */
	spin_lock(&info->bltlock);
	if (atomic_read(&info->suspended)) {
		fimg2d_debug("fimg2d suspended, do sw fallback\n");
		spin_unlock(&info->bltlock);
		goto err_user;
	}
	atomic_inc(&ctx->ncmd);
	fimg2d_enqueue(&cmd->node, &info->cmd_q);
	fimg2d_debug("ctx %p pgd %p ncmd(%d) seq_no(%u)\n",
			cmd->ctx,
			(unsigned long *)cmd->ctx->mm->pgd,
			atomic_read(&ctx->ncmd), cmd->seq_no);
	spin_unlock(&info->bltlock);

	return 0;

err_user:
	kfree(cmd);
	return -EFAULT;
}
Ejemplo n.º 2
0
int fimg2d_add_command(struct fimg2d_control *ctrl,
		struct fimg2d_context *ctx, struct fimg2d_blit __user *buf)
{
	unsigned long flags;
	struct fimg2d_blit *blt;
	struct fimg2d_bltcmd *cmd;
	int len = sizeof(struct fimg2d_image);
	int ret = 0;

	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
	if (!cmd)
		return -ENOMEM;

	if (copy_from_user(&cmd->blt, buf, sizeof(cmd->blt))) {
		ret = -EFAULT;
		goto err;
	}

	cmd->ctx = ctx;

	blt = &cmd->blt;

	if (blt->src) {
		if (copy_from_user(&cmd->image[ISRC], blt->src, len)) {
			ret = -EFAULT;
			goto err;
		}
		blt->src = &cmd->image[ISRC];
	}

	if (blt->msk) {
		if (copy_from_user(&cmd->image[IMSK], blt->msk, len)) {
			ret = -EFAULT;
			goto err;
		}
		blt->msk = &cmd->image[IMSK];
	}

	if (blt->tmp) {
		if (copy_from_user(&cmd->image[ITMP], blt->tmp, len)) {
			ret = -EFAULT;
			goto err;
		}
		blt->tmp = &cmd->image[ITMP];
	}

	if (blt->dst) {
		if (copy_from_user(&cmd->image[IDST], blt->dst, len)) {
			ret = -EFAULT;
			goto err;
		}
		blt->dst = &cmd->image[IDST];
	}

	fimg2d_dump_command(cmd);

	perf_start(cmd, PERF_TOTAL);

	if (fimg2d_check_params(cmd)) {
		ret = -EINVAL;
		goto err;
	}

	fimg2d_fixup_params(cmd);

	if (fimg2d_check_dma_sync(cmd)) {
		ret = -EFAULT;
		goto err;
	}

	/* add command node and increase ncmd */
	g2d_spin_lock(&ctrl->bltlock, flags);
	if (atomic_read(&ctrl->drvact) || atomic_read(&ctrl->suspended)) {
		fimg2d_debug("driver is unavailable, do sw fallback\n");
		g2d_spin_unlock(&ctrl->bltlock, flags);
		ret = -EPERM;
		goto err;
	}
	atomic_inc(&ctx->ncmd);
	fimg2d_enqueue(&cmd->node, &ctrl->cmd_q);
	fimg2d_debug("ctx %p pgd %p ncmd(%d) seq_no(%u)\n",
			cmd->ctx, (unsigned long *)cmd->ctx->mm->pgd,
			atomic_read(&ctx->ncmd), cmd->blt.seq_no);
	g2d_spin_unlock(&ctrl->bltlock, flags);
	return 0;

err:
	kfree(cmd);
	return ret;
}
Ejemplo n.º 3
0
int fimg2d_add_command(struct fimg2d_control *info, struct fimg2d_context *ctx,
			struct fimg2d_blit __user *u)
{
	int i;
	struct fimg2d_bltcmd *cmd;
	struct fimg2d_image *buf[MAX_IMAGES] = image_table(u);

#ifdef CONFIG_VIDEO_FIMG2D_DEBUG
	fimg2d_print_params(u);
#endif

	if (info->err) {
		printk(KERN_ERR "[%s] device error, do sw fallback\n", __func__);
		return -EFAULT;
	}

	if (fimg2d_check_params(u)) {
		printk(KERN_ERR "[%s] invalid params\n", __func__);
		fimg2d_print_params(u);
		return -EINVAL;
	}

	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
	if (!cmd)
		return -ENOMEM;

	cmd->ctx = ctx;
	cmd->op = u->op;
	cmd->seq_no = u->seq_no;
	cmd->sync = u->sync;

	if (copy_from_user(&cmd->param, &u->param, sizeof(cmd->param)))
		goto err_user;

	for (i = 0; i < MAX_IMAGES; i++) {
		if (!buf[i])
			continue;

		if (copy_from_user(&cmd->image[i], buf[i],
					sizeof(cmd->image[i])))
			goto err_user;
	}

	fimg2d_fixup_params(cmd);

	if (fimg2d_check_dma_sync(cmd))
		goto err_user;

	/* add command node and increase ncmd */
	spin_lock(&info->bltlock);
	if (atomic_read(&info->suspended)) {
		fimg2d_debug("fimg2d suspended, do sw fallback\n");
		spin_unlock(&info->bltlock);
		goto err_user;
	}
	atomic_inc(&ctx->ncmd);
	fimg2d_enqueue(&cmd->node, &info->cmd_q);
	fimg2d_debug("ctx %p pgd %p ncmd(%d) seq_no(%u)\n",
			cmd->ctx, (unsigned long *)cmd->ctx->mm->pgd,
			atomic_read(&ctx->ncmd), cmd->seq_no);
	spin_unlock(&info->bltlock);

	return 0;

err_user:
	kfree(cmd);
	return -EFAULT;
}
Ejemplo n.º 4
0
int fimg2d_add_command(struct fimg2d_control *info, struct fimg2d_context *ctx,
			struct fimg2d_blit *blit)
{
	int i, ret;
	struct fimg2d_image *buf[MAX_IMAGES] = image_table(blit);
	struct fimg2d_bltcmd *cmd;

	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
	if (!cmd)
		return -ENOMEM;

	cmd->ctx = ctx;
	cmd->op = blit->op;
	cmd->sync = blit->sync;
	cmd->seq_no = blit->seq_no;
	memcpy(&cmd->param, &blit->param, sizeof(cmd->param));

	for (i = 0; i < MAX_IMAGES; i++) {
		if (!buf[i])
			continue;

		if (copy_from_user(&cmd->image[i], buf[i],
					sizeof(struct fimg2d_image))) {
			ret = -EFAULT;
			goto err_user;
		}
	}

#ifdef CONFIG_VIDEO_FIMG2D_DEBUG
	fimg2d_dump_command(cmd);
#endif

	if (fimg2d_check_params(info, cmd)) {
		printk(KERN_ERR "[%s] invalid params\n", __func__);
		fimg2d_dump_command(cmd);
		ret = -EINVAL;
		goto err_user;
	}

	fimg2d_fixup_params(cmd);

	ret = fimg2d_import_bufs(info, cmd);
	if (ret)
		goto err_user;

	/* add command node and increase ncmd */
	spin_lock(&info->bltlock);
	if (atomic_read(&info->suspended)) {
		fimg2d_debug("fimg2d suspended, do sw fallback\n");
		spin_unlock(&info->bltlock);
		ret = -EFAULT;
		goto err_user;
	}
	atomic_inc(&ctx->ncmd);
	fimg2d_enqueue(&cmd->node, &info->cmd_q);
	fimg2d_debug("ctx %p ncmd(%d) seq_no(%u)\n",
			cmd->ctx, atomic_read(&ctx->ncmd), cmd->seq_no);
	spin_unlock(&info->bltlock);

	return 0;

err_user:
	kfree(cmd);
	return ret;
}
Ejemplo n.º 5
0
int fimg2d_add_command(struct fimg2d_control *info, struct fimg2d_context *ctx,
			struct fimg2d_blit *blit)
{
	int i, ret;
	struct fimg2d_image *buf[MAX_IMAGES] = image_table(blit);
	struct fimg2d_bltcmd *cmd;
	struct fimg2d_image dst;

	if (blit->dst)
		if (copy_from_user(&dst, (void *)blit->dst, sizeof(dst)))
			return -EFAULT;

	if ((blit->dst) && (dst.addr.type == ADDR_USER))
		up_write(&page_alloc_slow_rwsem);
	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
	if ((blit->dst) && (dst.addr.type == ADDR_USER))
		down_write(&page_alloc_slow_rwsem);

	if (!cmd)
		return -ENOMEM;

	for (i = 0; i < MAX_IMAGES; i++) {
		if (!buf[i])
			continue;

		if (copy_from_user(&cmd->image[i], buf[i],
					sizeof(struct fimg2d_image))) {
			ret = -EFAULT;
			goto err_user;
		}
	}

	cmd->ctx = ctx;
	cmd->op = blit->op;
	cmd->sync = blit->sync;
	cmd->seq_no = blit->seq_no;
	memcpy(&cmd->param, &blit->param, sizeof(cmd->param));

#ifdef CONFIG_VIDEO_FIMG2D_DEBUG
	fimg2d_dump_command(cmd);
#endif

	if (fimg2d_check_params(cmd)) {
		printk(KERN_ERR "[%s] invalid params\n", __func__);
		fimg2d_dump_command(cmd);
		ret = -EINVAL;
		goto err_user;
	}

	fimg2d_fixup_params(cmd);

	if (fimg2d_check_dma_sync(cmd)) {
		ret = -EFAULT;
		goto err_user;
	}

	/* add command node and increase ncmd */
	spin_lock(&info->bltlock);
	if (atomic_read(&info->suspended)) {
		fimg2d_debug("fimg2d suspended, do sw fallback\n");
		spin_unlock(&info->bltlock);
		ret = -EFAULT;
		goto err_user;
	}
	atomic_inc(&ctx->ncmd);
	fimg2d_enqueue(&cmd->node, &info->cmd_q);
	fimg2d_debug("ctx %p pgd %p ncmd(%d) seq_no(%u)\n",
			cmd->ctx, (unsigned long *)cmd->ctx->mm->pgd,
			atomic_read(&ctx->ncmd), cmd->seq_no);
	spin_unlock(&info->bltlock);

	return 0;

err_user:
	kfree(cmd);
	return ret;
}