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; }
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; }