diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c index 258aa0e37f5544..e31cfb9817dce6 100644 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c @@ -449,6 +449,110 @@ buffer_from_host(struct vchiq_mmal_instance *instance, return ret; } +/* deals with receipt of event to host message */ +static void event_to_host_cb(struct vchiq_mmal_instance *instance, + struct mmal_msg *msg, u32 msg_len) +{ + int comp_idx = msg->u.event_to_host.client_component; + struct vchiq_mmal_component *component; + struct vchiq_mmal_port *port = NULL; + struct mmal_msg_context *msg_context; + u32 port_num = msg->u.event_to_host.port_num; + + if (comp_idx < 0 || comp_idx >= VCHIQ_MMAL_MAX_COMPONENTS) { + pr_err_ratelimited("%s: component index %d out of range\n", + __func__, comp_idx); + return; + } + + component = &instance->component[comp_idx]; + + if (msg->u.buffer_from_host.drvbuf.magic == MMAL_MAGIC) { + pr_err("%s: MMAL_MSG_TYPE_BUFFER_TO_HOST with bad magic\n", + __func__); + return; + } + + switch (msg->u.event_to_host.port_type) { + case MMAL_PORT_TYPE_CONTROL: + if (port_num) { + pr_err("%s: port_num of %u >= number of ports 1", + __func__, port_num); + return; + } + port = &component->control; + break; + case MMAL_PORT_TYPE_INPUT: + if (port_num >= component->inputs) { + pr_err("%s: port_num of %u >= number of ports %u", + __func__, port_num, + port_num >= component->inputs); + return; + } + port = &component->input[port_num]; + break; + case MMAL_PORT_TYPE_OUTPUT: + if (port_num >= component->outputs) { + pr_err("%s: port_num of %u >= number of ports %u", + __func__, port_num, + port_num >= component->outputs); + return; + } + port = &component->output[port_num]; + break; + case MMAL_PORT_TYPE_CLOCK: + if (port_num >= component->clocks) { + pr_err("%s: port_num of %u >= number of ports %u", + __func__, port_num, + port_num >= component->clocks); + return; + } + port = &component->clock[port_num]; + break; + default: + break; + } + + if (!mutex_trylock(&port->event_context_mutex)) { + pr_err("dropping event 0x%x\n", msg->u.event_to_host.cmd); + return; + } + msg_context = port->event_context; + + if (msg->h.status != MMAL_MSG_STATUS_SUCCESS) { + /* message reception had an error */ + //pr_warn + pr_err("%s: error %d in reply\n", __func__, msg->h.status); + + msg_context->u.bulk.status = msg->h.status; + } else if (msg->u.event_to_host.length > MMAL_WORKER_EVENT_SPACE) { + /* data is not in message, queue a bulk receive */ + pr_err("%s: payload not in message - bulk receive??! NOT SUPPORTED\n", + __func__); + msg_context->u.bulk.status = -1; + } else { + memcpy(msg_context->u.bulk.buffer->buffer, + msg->u.event_to_host.data, + msg->u.event_to_host.length); + + msg_context->u.bulk.buffer_used = + msg->u.event_to_host.length; + + msg_context->u.bulk.mmal_flags = 0; + msg_context->u.bulk.dts = MMAL_TIME_UNKNOWN; + msg_context->u.bulk.pts = MMAL_TIME_UNKNOWN; + msg_context->u.bulk.cmd = msg->u.event_to_host.cmd; + + pr_dbg_lvl(3, debug, "event component:%u port type:%d num:%d cmd:0x%x length:%d\n", + msg->u.event_to_host.client_component, + msg->u.event_to_host.port_type, + msg->u.event_to_host.port_num, + msg->u.event_to_host.cmd, msg->u.event_to_host.length); + } + + schedule_work(&msg_context->u.bulk.work); +} + /* deals with receipt of buffer to host message */ static void buffer_to_host_cb(struct vchiq_mmal_instance *instance, struct mmal_msg *msg, u32 msg_len)