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