Loading drivers/media/platform/msm/cvp/msm_cvp.c +108 −3 Original line number Diff line number Diff line Loading @@ -364,7 +364,8 @@ static bool _cvp_msg_pending(struct msm_cvp_inst *inst, bool result = false; spin_lock(&sq->lock); if (!kref_read(&inst->kref)) { if (!kref_read(&inst->kref) || sq->state != QUEUE_ACTIVE) { /* The session is being deleted */ spin_unlock(&sq->lock); *msg = NULL; Loading @@ -388,6 +389,8 @@ static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst, unsigned long wait_time; struct session_msg *msg = NULL; struct cvp_session_queue *sq; struct cvp_kmd_session_control *sc; int rc; if (!inst) { dprintk(CVP_ERR, "%s invalid session\n", __func__); Loading @@ -395,6 +398,7 @@ static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst, } sq = &inst->session_queue; sc = (struct cvp_kmd_session_control *)out_pkt; wait_time = msecs_to_jiffies(CVP_MAX_WAIT_TIME); Loading @@ -405,8 +409,20 @@ static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst, } if (msg == NULL) { dprintk(CVP_ERR, "%s: session is deleted, no msg\n", __func__); return -EINVAL; dprintk(CVP_DBG, "%s: session deleted, queue state %d, msg cnt %d\n", __func__, inst->session_queue.state, inst->session_queue.msg_count); spin_lock(&sq->lock); if (sq->msg_count) { sc->ctrl_data[0] = sq->msg_count; rc = -EUCLEAN; } else { rc = -ENOLINK; } spin_unlock(&sq->lock); return rc; } memcpy(out_pkt, &msg->pkt, sizeof(struct hfi_msg_session_hdr)); Loading @@ -426,11 +442,22 @@ static int msm_cvp_session_process_hfi( struct msm_cvp_internal_buffer *cbuf = NULL; struct buf_desc *buf_ptr; unsigned int offset, buf_num, signal; struct cvp_session_queue *sq; if (!inst || !inst->core || !in_pkt) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); return -EINVAL; } sq = &inst->session_queue; spin_lock(&sq->lock); if (sq->state != QUEUE_ACTIVE) { spin_unlock(&sq->lock); dprintk(CVP_ERR, "%s: invalid queue state\n", __func__); return -EINVAL; } spin_unlock(&sq->lock); hdev = inst->core->device; pkt_idx = get_pkt_index((struct cvp_hal_session_cmd_pkt *)in_pkt); Loading Loading @@ -856,6 +883,81 @@ static int msm_cvp_unregister_buffer(struct msm_cvp_inst *inst, return msm_cvp_unmap_buf_dsp(inst, buf); } static int msm_cvp_session_start(struct msm_cvp_inst *inst, struct cvp_kmd_arg *arg) { struct cvp_session_queue *sq; sq = &inst->session_queue; spin_lock(&sq->lock); if (sq->msg_count) { dprintk(CVP_ERR, "session start failed queue not empty%d\n", sq->msg_count); spin_unlock(&sq->lock); return -EINVAL; } sq->state = QUEUE_ACTIVE; spin_unlock(&sq->lock); return 0; } static int msm_cvp_session_stop(struct msm_cvp_inst *inst, struct cvp_kmd_arg *arg) { struct cvp_session_queue *sq; struct cvp_kmd_session_control *sc = &arg->data.session_ctrl; sq = &inst->session_queue; spin_lock(&sq->lock); if (sq->msg_count) { dprintk(CVP_ERR, "session stop incorrect: queue not empty%d\n", sq->msg_count); sc->ctrl_data[0] = sq->msg_count; spin_unlock(&sq->lock); return -EUCLEAN; } sq->state = QUEUE_STOP; spin_unlock(&sq->lock); wake_up_all(&inst->session_queue.wq); return 0; } static int msm_cvp_session_ctrl(struct msm_cvp_inst *inst, struct cvp_kmd_arg *arg) { struct cvp_kmd_session_control *ctrl = &arg->data.session_ctrl; int rc = 0; if (!inst) { dprintk(CVP_ERR, "%s invalid session\n", __func__); return -EINVAL; } switch (ctrl->ctrl_type) { case SESSION_STOP: rc = msm_cvp_session_stop(inst, arg); break; case SESSION_START: rc = msm_cvp_session_start(inst, arg); break; case SESSION_CREATE: case SESSION_DELETE: case SESSION_INFO: default: dprintk(CVP_ERR, "%s Unsupported session ctrl%d\n", __func__, ctrl->ctrl_type); rc = -EINVAL; } return rc; } int msm_cvp_handle_syscall(struct msm_cvp_inst *inst, struct cvp_kmd_arg *arg) { int rc = 0; Loading Loading @@ -957,6 +1059,9 @@ int msm_cvp_handle_syscall(struct msm_cvp_inst *inst, struct cvp_kmd_arg *arg) rc = msm_cvp_session_process_hfi_fence(inst, arg); break; } case CVP_KMD_SESSION_CONTROL: rc = msm_cvp_session_ctrl(inst, arg); break; default: dprintk(CVP_ERR, "%s: unknown arg type 0x%x\n", __func__, arg->type); Loading drivers/media/platform/msm/cvp/msm_cvp_core.c +1 −0 Original line number Diff line number Diff line Loading @@ -84,6 +84,7 @@ static int _init_session_queue(struct msm_cvp_inst *inst) dprintk(CVP_ERR, "Failed to allocate msg quque\n"); return -ENOMEM; } inst->session_queue.state = QUEUE_ACTIVE; return 0; } Loading drivers/media/platform/msm/cvp/msm_cvp_internal.h +8 −0 Original line number Diff line number Diff line Loading @@ -297,8 +297,16 @@ struct session_msg { struct hfi_msg_session_hdr pkt; }; enum queue_state { QUEUE_INIT, QUEUE_ACTIVE = 1, QUEUE_STOP = 2, QUEUE_INVALID, }; struct cvp_session_queue { spinlock_t lock; enum queue_state state; unsigned int msg_count; struct list_head msgs; wait_queue_head_t wq; Loading drivers/media/platform/msm/cvp/msm_v4l2_private.c +49 −1 Original line number Diff line number Diff line Loading @@ -166,6 +166,34 @@ static void print_hfi_short(struct cvp_kmd_arg __user *up) words[0], words[1], words[2], words[3], words[4]); } static int _copy_session_ctrl_to_user( struct cvp_kmd_session_control *k, struct cvp_kmd_session_control *u) { int i; if (put_user(k->ctrl_type, &u->ctrl_type)) return -EFAULT; for (i = 0; i < 8; i++) if (put_user(k->ctrl_data[i], &u->ctrl_data[i])) return -EFAULT; return 0; } static int _get_session_ctrl_from_user( struct cvp_kmd_session_control *k, struct cvp_kmd_session_control *u) { int i; if (get_user(k->ctrl_type, &u->ctrl_type)) return -EFAULT; for (i = 0; i < 8; i++) if (get_user(k->ctrl_data[i], &u->ctrl_data[i])) return -EFAULT; return 0; } static int convert_from_user(struct cvp_kmd_arg *kp, unsigned long arg, Loading Loading @@ -306,6 +334,17 @@ static int convert_from_user(struct cvp_kmd_arg *kp, case CVP_KMD_HFI_PERSIST_CMD_RESPONSE: case CVP_KMD_RECEIVE_MSG_PKT: break; case CVP_KMD_SESSION_CONTROL: { struct cvp_kmd_session_control *k, *u; k = &kp->data.session_ctrl; u = &up->data.session_ctrl; rc = _get_session_ctrl_from_user(k, u); break; } default: dprintk(CVP_ERR, "%s: unknown cmd type 0x%x\n", __func__, kp->type); Loading Loading @@ -455,6 +494,15 @@ static int convert_to_user(struct cvp_kmd_arg *kp, unsigned long arg) rc = _copy_fence_pkt_to_user(kp, up, (pkt_hdr.size >> 2)); break; } case CVP_KMD_SESSION_CONTROL: { struct cvp_kmd_session_control *k, *u; k = &kp->data.session_ctrl; u = &up->data.session_ctrl; rc = _copy_session_ctrl_to_user(k, u); break; } default: dprintk(CVP_ERR, "%s: unknown cmd type 0x%x\n", __func__, kp->type); Loading Loading @@ -492,7 +540,7 @@ static long cvp_ioctl(struct msm_cvp_inst *inst, if (rc) { dprintk(CVP_ERR, "%s: failed cmd type %x\n", __func__, karg.type); return -EINVAL; return rc; } if (convert_to_user(&karg, arg)) { Loading Loading
drivers/media/platform/msm/cvp/msm_cvp.c +108 −3 Original line number Diff line number Diff line Loading @@ -364,7 +364,8 @@ static bool _cvp_msg_pending(struct msm_cvp_inst *inst, bool result = false; spin_lock(&sq->lock); if (!kref_read(&inst->kref)) { if (!kref_read(&inst->kref) || sq->state != QUEUE_ACTIVE) { /* The session is being deleted */ spin_unlock(&sq->lock); *msg = NULL; Loading @@ -388,6 +389,8 @@ static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst, unsigned long wait_time; struct session_msg *msg = NULL; struct cvp_session_queue *sq; struct cvp_kmd_session_control *sc; int rc; if (!inst) { dprintk(CVP_ERR, "%s invalid session\n", __func__); Loading @@ -395,6 +398,7 @@ static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst, } sq = &inst->session_queue; sc = (struct cvp_kmd_session_control *)out_pkt; wait_time = msecs_to_jiffies(CVP_MAX_WAIT_TIME); Loading @@ -405,8 +409,20 @@ static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst, } if (msg == NULL) { dprintk(CVP_ERR, "%s: session is deleted, no msg\n", __func__); return -EINVAL; dprintk(CVP_DBG, "%s: session deleted, queue state %d, msg cnt %d\n", __func__, inst->session_queue.state, inst->session_queue.msg_count); spin_lock(&sq->lock); if (sq->msg_count) { sc->ctrl_data[0] = sq->msg_count; rc = -EUCLEAN; } else { rc = -ENOLINK; } spin_unlock(&sq->lock); return rc; } memcpy(out_pkt, &msg->pkt, sizeof(struct hfi_msg_session_hdr)); Loading @@ -426,11 +442,22 @@ static int msm_cvp_session_process_hfi( struct msm_cvp_internal_buffer *cbuf = NULL; struct buf_desc *buf_ptr; unsigned int offset, buf_num, signal; struct cvp_session_queue *sq; if (!inst || !inst->core || !in_pkt) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); return -EINVAL; } sq = &inst->session_queue; spin_lock(&sq->lock); if (sq->state != QUEUE_ACTIVE) { spin_unlock(&sq->lock); dprintk(CVP_ERR, "%s: invalid queue state\n", __func__); return -EINVAL; } spin_unlock(&sq->lock); hdev = inst->core->device; pkt_idx = get_pkt_index((struct cvp_hal_session_cmd_pkt *)in_pkt); Loading Loading @@ -856,6 +883,81 @@ static int msm_cvp_unregister_buffer(struct msm_cvp_inst *inst, return msm_cvp_unmap_buf_dsp(inst, buf); } static int msm_cvp_session_start(struct msm_cvp_inst *inst, struct cvp_kmd_arg *arg) { struct cvp_session_queue *sq; sq = &inst->session_queue; spin_lock(&sq->lock); if (sq->msg_count) { dprintk(CVP_ERR, "session start failed queue not empty%d\n", sq->msg_count); spin_unlock(&sq->lock); return -EINVAL; } sq->state = QUEUE_ACTIVE; spin_unlock(&sq->lock); return 0; } static int msm_cvp_session_stop(struct msm_cvp_inst *inst, struct cvp_kmd_arg *arg) { struct cvp_session_queue *sq; struct cvp_kmd_session_control *sc = &arg->data.session_ctrl; sq = &inst->session_queue; spin_lock(&sq->lock); if (sq->msg_count) { dprintk(CVP_ERR, "session stop incorrect: queue not empty%d\n", sq->msg_count); sc->ctrl_data[0] = sq->msg_count; spin_unlock(&sq->lock); return -EUCLEAN; } sq->state = QUEUE_STOP; spin_unlock(&sq->lock); wake_up_all(&inst->session_queue.wq); return 0; } static int msm_cvp_session_ctrl(struct msm_cvp_inst *inst, struct cvp_kmd_arg *arg) { struct cvp_kmd_session_control *ctrl = &arg->data.session_ctrl; int rc = 0; if (!inst) { dprintk(CVP_ERR, "%s invalid session\n", __func__); return -EINVAL; } switch (ctrl->ctrl_type) { case SESSION_STOP: rc = msm_cvp_session_stop(inst, arg); break; case SESSION_START: rc = msm_cvp_session_start(inst, arg); break; case SESSION_CREATE: case SESSION_DELETE: case SESSION_INFO: default: dprintk(CVP_ERR, "%s Unsupported session ctrl%d\n", __func__, ctrl->ctrl_type); rc = -EINVAL; } return rc; } int msm_cvp_handle_syscall(struct msm_cvp_inst *inst, struct cvp_kmd_arg *arg) { int rc = 0; Loading Loading @@ -957,6 +1059,9 @@ int msm_cvp_handle_syscall(struct msm_cvp_inst *inst, struct cvp_kmd_arg *arg) rc = msm_cvp_session_process_hfi_fence(inst, arg); break; } case CVP_KMD_SESSION_CONTROL: rc = msm_cvp_session_ctrl(inst, arg); break; default: dprintk(CVP_ERR, "%s: unknown arg type 0x%x\n", __func__, arg->type); Loading
drivers/media/platform/msm/cvp/msm_cvp_core.c +1 −0 Original line number Diff line number Diff line Loading @@ -84,6 +84,7 @@ static int _init_session_queue(struct msm_cvp_inst *inst) dprintk(CVP_ERR, "Failed to allocate msg quque\n"); return -ENOMEM; } inst->session_queue.state = QUEUE_ACTIVE; return 0; } Loading
drivers/media/platform/msm/cvp/msm_cvp_internal.h +8 −0 Original line number Diff line number Diff line Loading @@ -297,8 +297,16 @@ struct session_msg { struct hfi_msg_session_hdr pkt; }; enum queue_state { QUEUE_INIT, QUEUE_ACTIVE = 1, QUEUE_STOP = 2, QUEUE_INVALID, }; struct cvp_session_queue { spinlock_t lock; enum queue_state state; unsigned int msg_count; struct list_head msgs; wait_queue_head_t wq; Loading
drivers/media/platform/msm/cvp/msm_v4l2_private.c +49 −1 Original line number Diff line number Diff line Loading @@ -166,6 +166,34 @@ static void print_hfi_short(struct cvp_kmd_arg __user *up) words[0], words[1], words[2], words[3], words[4]); } static int _copy_session_ctrl_to_user( struct cvp_kmd_session_control *k, struct cvp_kmd_session_control *u) { int i; if (put_user(k->ctrl_type, &u->ctrl_type)) return -EFAULT; for (i = 0; i < 8; i++) if (put_user(k->ctrl_data[i], &u->ctrl_data[i])) return -EFAULT; return 0; } static int _get_session_ctrl_from_user( struct cvp_kmd_session_control *k, struct cvp_kmd_session_control *u) { int i; if (get_user(k->ctrl_type, &u->ctrl_type)) return -EFAULT; for (i = 0; i < 8; i++) if (get_user(k->ctrl_data[i], &u->ctrl_data[i])) return -EFAULT; return 0; } static int convert_from_user(struct cvp_kmd_arg *kp, unsigned long arg, Loading Loading @@ -306,6 +334,17 @@ static int convert_from_user(struct cvp_kmd_arg *kp, case CVP_KMD_HFI_PERSIST_CMD_RESPONSE: case CVP_KMD_RECEIVE_MSG_PKT: break; case CVP_KMD_SESSION_CONTROL: { struct cvp_kmd_session_control *k, *u; k = &kp->data.session_ctrl; u = &up->data.session_ctrl; rc = _get_session_ctrl_from_user(k, u); break; } default: dprintk(CVP_ERR, "%s: unknown cmd type 0x%x\n", __func__, kp->type); Loading Loading @@ -455,6 +494,15 @@ static int convert_to_user(struct cvp_kmd_arg *kp, unsigned long arg) rc = _copy_fence_pkt_to_user(kp, up, (pkt_hdr.size >> 2)); break; } case CVP_KMD_SESSION_CONTROL: { struct cvp_kmd_session_control *k, *u; k = &kp->data.session_ctrl; u = &up->data.session_ctrl; rc = _copy_session_ctrl_to_user(k, u); break; } default: dprintk(CVP_ERR, "%s: unknown cmd type 0x%x\n", __func__, kp->type); Loading Loading @@ -492,7 +540,7 @@ static long cvp_ioctl(struct msm_cvp_inst *inst, if (rc) { dprintk(CVP_ERR, "%s: failed cmd type %x\n", __func__, karg.type); return -EINVAL; return rc; } if (convert_to_user(&karg, arg)) { Loading