blob: ede75391b737498fc73fe0d5a12b2310727682c6 [file] [log] [blame]
/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/interrupt.h>
#include <mach/msm_smem.h>
#include "vidc_hfi_helper.h"
#include "vidc_hfi_io.h"
#include "msm_vidc_debug.h"
#include "vidc_hfi.h"
static enum vidc_status hfi_map_err_status(int hfi_err)
{
enum vidc_status vidc_err;
switch (hfi_err) {
case HFI_ERR_NONE:
case HFI_ERR_SESSION_SAME_STATE_OPERATION:
vidc_err = VIDC_ERR_NONE;
break;
case HFI_ERR_SYS_FATAL:
vidc_err = VIDC_ERR_HW_FATAL;
break;
case HFI_ERR_SYS_VERSION_MISMATCH:
case HFI_ERR_SYS_INVALID_PARAMETER:
case HFI_ERR_SYS_SESSION_ID_OUT_OF_RANGE:
case HFI_ERR_SESSION_INVALID_PARAMETER:
case HFI_ERR_SESSION_INVALID_SESSION_ID:
case HFI_ERR_SESSION_INVALID_STREAM_ID:
vidc_err = VIDC_ERR_BAD_PARAM;
break;
case HFI_ERR_SYS_INSUFFICIENT_RESOURCES:
case HFI_ERR_SYS_UNSUPPORTED_DOMAIN:
case HFI_ERR_SYS_UNSUPPORTED_CODEC:
case HFI_ERR_SESSION_UNSUPPORTED_PROPERTY:
case HFI_ERR_SESSION_UNSUPPORTED_SETTING:
case HFI_ERR_SESSION_INSUFFICIENT_RESOURCES:
case HFI_ERR_SESSION_UNSUPPORTED_STREAM:
vidc_err = VIDC_ERR_NOT_SUPPORTED;
break;
case HFI_ERR_SYS_MAX_SESSIONS_REACHED:
vidc_err = VIDC_ERR_MAX_CLIENT;
break;
case HFI_ERR_SYS_SESSION_IN_USE:
vidc_err = VIDC_ERR_CLIENT_PRESENT;
break;
case HFI_ERR_SESSION_FATAL:
vidc_err = VIDC_ERR_CLIENT_FATAL;
break;
case HFI_ERR_SESSION_BAD_POINTER:
vidc_err = VIDC_ERR_BAD_PARAM;
break;
case HFI_ERR_SESSION_INCORRECT_STATE_OPERATION:
vidc_err = VIDC_ERR_BAD_STATE;
break;
case HFI_ERR_SESSION_STREAM_CORRUPT:
case HFI_ERR_SESSION_STREAM_CORRUPT_OUTPUT_STALLED:
vidc_err = VIDC_ERR_BITSTREAM_ERR;
break;
case HFI_ERR_SESSION_SYNC_FRAME_NOT_DETECTED:
vidc_err = VIDC_ERR_IFRAME_EXPECTED;
break;
case HFI_ERR_SESSION_EMPTY_BUFFER_DONE_OUTPUT_PENDING:
default:
vidc_err = VIDC_ERR_FAIL;
break;
}
return vidc_err;
}
static int validate_session_pkt(struct list_head *sessions,
struct hal_session *sess, struct mutex *session_lock)
{
struct hal_session *session;
int invalid = 1;
if (session_lock) {
mutex_lock(session_lock);
list_for_each_entry(session, sessions, list) {
if (session == sess) {
invalid = 0;
break;
}
}
mutex_unlock(session_lock);
}
if (invalid)
dprintk(VIDC_WARN, "Invalid session from FW: %p\n", sess);
return invalid;
}
static void hfi_process_sess_evt_seq_changed(
msm_vidc_callback callback, u32 device_id,
struct hfi_msg_event_notify_packet *pkt)
{
struct msm_vidc_cb_cmd_done cmd_done;
struct msm_vidc_cb_event event_notify;
int num_properties_changed;
struct hfi_frame_size frame_sz;
u8 *data_ptr;
int prop_id;
dprintk(VIDC_DBG, "RECEIVED:EVENT_NOTIFY");
if (sizeof(struct hfi_msg_event_notify_packet)
> pkt->size) {
dprintk(VIDC_ERR, "hal_process_session_init_done:bad_pkt_size");
return;
}
memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
memset(&event_notify, 0, sizeof(struct
msm_vidc_cb_event));
cmd_done.device_id = device_id;
cmd_done.session_id = ((struct hal_session *) pkt->session_id)->
session_id;
cmd_done.status = VIDC_ERR_NONE;
cmd_done.size = sizeof(struct msm_vidc_cb_event);
num_properties_changed = pkt->event_data2;
switch (pkt->event_data1) {
case HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUFFER_RESOURCES:
event_notify.hal_event_type =
HAL_EVENT_SEQ_CHANGED_SUFFICIENT_RESOURCES;
break;
case HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUFFER_RESOURCES:
event_notify.hal_event_type =
HAL_EVENT_SEQ_CHANGED_INSUFFICIENT_RESOURCES;
break;
default:
break;
}
if (num_properties_changed) {
data_ptr = (u8 *) &pkt->rg_ext_event_data[0];
do {
prop_id = (int) *((u32 *)data_ptr);
switch (prop_id) {
case HFI_PROPERTY_PARAM_FRAME_SIZE:
frame_sz.buffer_type =
(int) *((((u32 *)data_ptr)+1));
frame_sz.width =
event_notify.width =
*((((u32 *)data_ptr)+2));
frame_sz.height =
event_notify.height =
*((((u32 *)data_ptr)+3));
data_ptr += 4;
break;
default:
break;
}
num_properties_changed--;
} while (num_properties_changed > 0);
}
cmd_done.data = &event_notify;
callback(VIDC_EVENT_CHANGE, &cmd_done);
}
static void hfi_process_evt_release_buffer_ref(
msm_vidc_callback callback, u32 device_id,
struct hfi_msg_event_notify_packet *pkt)
{
struct msm_vidc_cb_cmd_done cmd_done = {0};
struct msm_vidc_cb_event event_notify = {0};
struct hfi_msg_release_buffer_ref_event_packet *data;
dprintk(VIDC_DBG, "RECEIVED:EVENT_NOTIFY - release_buffer_reference");
if (sizeof(struct hfi_msg_event_notify_packet)
> pkt->size) {
dprintk(VIDC_ERR, "hal_process_session_init_done:bad_pkt_size");
return;
}
data = (struct hfi_msg_release_buffer_ref_event_packet *)
pkt->rg_ext_event_data;
cmd_done.device_id = device_id;
cmd_done.session_id =
((struct hal_session *)data->output_tag)->session_id;
cmd_done.status = VIDC_ERR_NONE;
cmd_done.size = sizeof(struct msm_vidc_cb_event);
event_notify.hal_event_type = HAL_EVENT_RELEASE_BUFFER_REFERENCE;
event_notify.packet_buffer = data->packet_buffer;
event_notify.exra_data_buffer = data->exra_data_buffer;
cmd_done.data = &event_notify;
callback(VIDC_EVENT_CHANGE, &cmd_done);
}
static void hfi_process_sys_error(
msm_vidc_callback callback, u32 device_id)
{
struct msm_vidc_cb_cmd_done cmd_done;
memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
cmd_done.device_id = device_id;
callback(SYS_ERROR, &cmd_done);
}
static void hfi_process_session_error(
msm_vidc_callback callback, u32 device_id,
struct hfi_msg_event_notify_packet *pkt)
{
struct msm_vidc_cb_cmd_done cmd_done;
memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
cmd_done.device_id = device_id;
cmd_done.session_id = ((struct hal_session *) pkt->session_id)->
session_id;
callback(SESSION_ERROR, &cmd_done);
}
static void hfi_process_event_notify(
msm_vidc_callback callback, u32 device_id,
struct hfi_msg_event_notify_packet *pkt,
struct list_head *sessions, struct mutex *session_lock)
{
struct hal_session *sess = NULL;
dprintk(VIDC_DBG, "RECVD:EVENT_NOTIFY");
if (!callback || !pkt ||
pkt->size < sizeof(struct hfi_msg_event_notify_packet)) {
dprintk(VIDC_ERR, "Invalid Params");
return;
}
sess = (struct hal_session *)pkt->session_id;
switch (pkt->event_id) {
case HFI_EVENT_SYS_ERROR:
dprintk(VIDC_ERR, "HFI_EVENT_SYS_ERROR: %d, 0x%x\n",
pkt->event_data1, pkt->event_data2);
hfi_process_sys_error(callback, device_id);
break;
case HFI_EVENT_SESSION_ERROR:
dprintk(VIDC_ERR, "HFI_EVENT_SESSION_ERROR");
if (!validate_session_pkt(sessions, sess, session_lock))
hfi_process_session_error(callback, device_id, pkt);
break;
case HFI_EVENT_SESSION_SEQUENCE_CHANGED:
dprintk(VIDC_INFO, "HFI_EVENT_SESSION_SEQUENCE_CHANGED");
if (!validate_session_pkt(sessions, sess, session_lock))
hfi_process_sess_evt_seq_changed(callback,
device_id, pkt);
break;
case HFI_EVENT_SESSION_PROPERTY_CHANGED:
dprintk(VIDC_INFO, "HFI_EVENT_SESSION_PROPERTY_CHANGED");
break;
case HFI_EVENT_RELEASE_BUFFER_REFERENCE:
dprintk(VIDC_INFO, "HFI_EVENT_RELEASE_BUFFER_REFERENCE\n");
hfi_process_evt_release_buffer_ref(callback, device_id, pkt);
break;
default:
dprintk(VIDC_WARN, "hal_process_event_notify:unkown_event_id");
break;
}
}
static void hfi_process_sys_init_done(
msm_vidc_callback callback, u32 device_id,
struct hfi_msg_sys_init_done_packet *pkt)
{
struct msm_vidc_cb_cmd_done cmd_done;
struct vidc_hal_sys_init_done sys_init_done;
u32 rem_bytes, bytes_read = 0, num_properties;
u8 *data_ptr;
int prop_id;
enum vidc_status status = VIDC_ERR_NONE;
dprintk(VIDC_DBG, "RECEIVED:SYS_INIT_DONE");
if (sizeof(struct hfi_msg_sys_init_done_packet) > pkt->size) {
dprintk(VIDC_ERR, "hal_process_sys_init_done:bad_pkt_size: %d",
pkt->size);
return;
}
status = hfi_map_err_status((u32)pkt->error_type);
if (!status) {
if (pkt->num_properties == 0) {
dprintk(VIDC_ERR, "hal_process_sys_init_done:"
"no_properties");
status = VIDC_ERR_FAIL;
goto err_no_prop;
}
rem_bytes = pkt->size - sizeof(struct
hfi_msg_sys_init_done_packet) + sizeof(u32);
if (rem_bytes == 0) {
dprintk(VIDC_ERR, "hal_process_sys_init_done:"
"missing_prop_info");
status = VIDC_ERR_FAIL;
goto err_no_prop;
}
memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
memset(&sys_init_done, 0, sizeof(struct
vidc_hal_sys_init_done));
data_ptr = (u8 *) &pkt->rg_property_data[0];
num_properties = pkt->num_properties;
while ((num_properties != 0) && (rem_bytes >= sizeof(u32))) {
prop_id = *((u32 *)data_ptr);
data_ptr = data_ptr + 4;
switch (prop_id) {
case HFI_PROPERTY_PARAM_CODEC_SUPPORTED:
{
struct hfi_codec_supported *prop =
(struct hfi_codec_supported *) data_ptr;
if (rem_bytes < sizeof(struct
hfi_codec_supported)) {
status = VIDC_ERR_BAD_PARAM;
break;
}
sys_init_done.dec_codec_supported =
prop->decoder_codec_supported;
sys_init_done.enc_codec_supported =
prop->encoder_codec_supported;
break;
}
default:
dprintk(VIDC_ERR, "hal_process_sys_init_done:"
"bad_prop_id");
status = VIDC_ERR_BAD_PARAM;
break;
}
if (!status) {
rem_bytes -= bytes_read;
data_ptr += bytes_read;
num_properties--;
}
}
}
err_no_prop:
cmd_done.device_id = device_id;
cmd_done.session_id = 0;
cmd_done.status = (u32) status;
cmd_done.size = sizeof(struct vidc_hal_sys_init_done);
cmd_done.data = (void *) &sys_init_done;
callback(SYS_INIT_DONE, &cmd_done);
}
static void hfi_process_sys_rel_resource_done(
msm_vidc_callback callback, u32 device_id,
struct hfi_msg_sys_release_resource_done_packet *pkt)
{
struct msm_vidc_cb_cmd_done cmd_done;
enum vidc_status status = VIDC_ERR_NONE;
u32 pkt_size;
memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
dprintk(VIDC_DBG, "RECEIVED:SYS_RELEASE_RESOURCE_DONE");
pkt_size = sizeof(struct hfi_msg_sys_release_resource_done_packet);
if (pkt_size > pkt->size) {
dprintk(VIDC_ERR,
"hal_process_sys_rel_resource_done:bad size:%d",
pkt->size);
return;
}
status = hfi_map_err_status((u32)pkt->error_type);
cmd_done.device_id = device_id;
cmd_done.session_id = 0;
cmd_done.status = (u32) status;
cmd_done.size = 0;
cmd_done.data = NULL;
callback(RELEASE_RESOURCE_DONE, &cmd_done);
}
static inline void copy_cap_prop(
struct hfi_capability_supported *in,
struct vidc_hal_session_init_done *sess_init_done)
{
struct hal_capability_supported *out = NULL;
switch (in->capability_type) {
case HFI_CAPABILITY_FRAME_WIDTH:
out = &sess_init_done->width;
break;
case HFI_CAPABILITY_FRAME_HEIGHT:
out = &sess_init_done->height;
break;
case HFI_CAPABILITY_MBS_PER_FRAME:
out = &sess_init_done->mbs_per_frame;
break;
case HFI_CAPABILITY_MBS_PER_SECOND:
out = &sess_init_done->mbs_per_sec;
break;
case HFI_CAPABILITY_FRAMERATE:
out = &sess_init_done->frame_rate;
break;
case HFI_CAPABILITY_SCALE_X:
out = &sess_init_done->scale_x;
break;
case HFI_CAPABILITY_SCALE_Y:
out = &sess_init_done->scale_y;
break;
case HFI_CAPABILITY_BITRATE:
out = &sess_init_done->bitrate;
break;
case HFI_CAPABILITY_HIER_P_NUM_ENH_LAYERS:
out = &sess_init_done->hier_p;
break;
}
if (in && out) {
out->capability_type =
(enum hal_capability)in->capability_type;
out->min = in->min;
out->max = in->max;
out->step_size = in->step_size;
}
}
enum vidc_status hfi_process_sess_init_done_prop_read(
struct hfi_msg_sys_session_init_done_packet *pkt,
struct vidc_hal_session_init_done *sess_init_done)
{
u32 rem_bytes, num_properties;
u8 *data_ptr;
u32 status = VIDC_ERR_NONE;
u32 prop_id, next_offset = 0;
rem_bytes = pkt->size - sizeof(struct
hfi_msg_sys_session_init_done_packet) + sizeof(u32);
if (rem_bytes == 0) {
dprintk(VIDC_ERR,
"hfi_msg_sys_session_init_done:missing_prop_info");
return VIDC_ERR_FAIL;
}
status = hfi_map_err_status((u32)pkt->error_type);
if (status)
return status;
data_ptr = (u8 *) &pkt->rg_property_data[0];
num_properties = pkt->num_properties;
while ((status == VIDC_ERR_NONE) && num_properties &&
(rem_bytes >= sizeof(u32))) {
prop_id = *((u32 *)data_ptr);
next_offset = sizeof(u32);
switch (prop_id) {
case HFI_PROPERTY_PARAM_CAPABILITY_SUPPORTED:
{
struct hfi_capability_supported_info *prop =
(struct hfi_capability_supported_info *)
(data_ptr + next_offset);
u32 num_capabilities;
struct hfi_capability_supported *cap_ptr;
if ((rem_bytes - next_offset) < sizeof(*cap_ptr)) {
status = VIDC_ERR_BAD_PARAM;
break;
}
num_capabilities = prop->num_capabilities;
cap_ptr = &prop->rg_data[0];
next_offset += sizeof(u32);
while (num_capabilities &&
((rem_bytes - next_offset) >= sizeof(u32))) {
copy_cap_prop(cap_ptr, sess_init_done);
cap_ptr++;
next_offset += sizeof(*cap_ptr);
num_capabilities--;
}
num_properties--;
break;
}
case HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SUPPORTED:
{
struct hfi_uncompressed_format_supported *prop =
(struct hfi_uncompressed_format_supported *)
(data_ptr + next_offset);
u32 num_format_entries;
char *fmt_ptr;
struct hfi_uncompressed_plane_info *plane_info;
if ((rem_bytes - next_offset) < sizeof(*prop)) {
status = VIDC_ERR_BAD_PARAM;
break;
}
num_format_entries = prop->format_entries;
next_offset = sizeof(*prop) - sizeof(u32);
fmt_ptr = (char *)&prop->rg_format_info[0];
while (num_format_entries) {
u32 bytes_to_skip;
plane_info =
(struct hfi_uncompressed_plane_info *) fmt_ptr;
if ((rem_bytes - next_offset) <
sizeof(*plane_info)) {
status = VIDC_ERR_BAD_PARAM;
break;
}
bytes_to_skip = sizeof(*plane_info) -
sizeof(struct
hfi_uncompressed_plane_constraints) +
plane_info->num_planes *
sizeof(struct
hfi_uncompressed_plane_constraints);
fmt_ptr += bytes_to_skip;
next_offset += bytes_to_skip;
num_format_entries--;
}
num_properties--;
break;
}
case HFI_PROPERTY_PARAM_PROPERTIES_SUPPORTED:
{
struct hfi_properties_supported *prop =
(struct hfi_properties_supported *)
(data_ptr + next_offset);
next_offset += sizeof(*prop) - sizeof(u32)
+ prop->num_properties * sizeof(u32);
num_properties--;
break;
}
case HFI_PROPERTY_PARAM_PROFILE_LEVEL_SUPPORTED:
{
struct hfi_profile_level_supported *prop =
(struct hfi_profile_level_supported *)
(data_ptr + next_offset);
next_offset += sizeof(*prop) -
sizeof(struct hfi_profile_level) +
prop->profile_count *
sizeof(struct hfi_profile_level);
num_properties--;
break;
}
case HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SUPPORTED:
{
next_offset +=
sizeof(struct hfi_nal_stream_format_supported);
num_properties--;
break;
}
case HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT:
{
next_offset += sizeof(u32);
num_properties--;
break;
}
case HFI_PROPERTY_PARAM_MAX_SEQUENCE_HEADER_SIZE:
{
next_offset += sizeof(u32);
num_properties--;
break;
}
case HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH:
{
next_offset +=
sizeof(struct hfi_intra_refresh);
num_properties--;
break;
}
case HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE_SUPPORTED:
{
struct hfi_buffer_alloc_mode_supported *prop =
(struct hfi_buffer_alloc_mode_supported *)
(data_ptr + next_offset);
int i;
if (prop->buffer_type == HFI_BUFFER_OUTPUT ||
prop->buffer_type == HFI_BUFFER_OUTPUT2) {
sess_init_done->alloc_mode_out = 0;
for (i = 0; i < prop->num_entries; i++) {
switch (prop->rg_data[i]) {
case HFI_BUFFER_MODE_STATIC:
sess_init_done->alloc_mode_out
|= HAL_BUFFER_MODE_STATIC;
break;
case HFI_BUFFER_MODE_DYNAMIC:
sess_init_done->alloc_mode_out
|= HAL_BUFFER_MODE_DYNAMIC;
break;
}
}
}
next_offset += sizeof(*prop) -
sizeof(u32) + prop->num_entries * sizeof(u32);
num_properties--;
break;
}
default:
dprintk(VIDC_DBG,
"%s default case - 0x%x", __func__, prop_id);
}
rem_bytes -= next_offset;
data_ptr += next_offset;
}
return status;
}
static void hfi_process_sess_get_prop_buf_req(
struct hfi_msg_session_property_info_packet *prop,
struct buffer_requirements *buffreq)
{
struct hfi_buffer_requirements *hfi_buf_req;
u32 req_bytes;
dprintk(VIDC_DBG, "Entered ");
if (!prop) {
dprintk(VIDC_ERR,
"hal_process_sess_get_prop_buf_req:bad_prop: %p",
prop);
return;
}
req_bytes = prop->size - sizeof(
struct hfi_msg_session_property_info_packet);
if (!req_bytes || (req_bytes % sizeof(
struct hfi_buffer_requirements)) ||
(!prop->rg_property_data[1])) {
dprintk(VIDC_ERR,
"hal_process_sess_get_prop_buf_req:bad_pkt: %d",
req_bytes);
return;
}
hfi_buf_req = (struct hfi_buffer_requirements *)
&prop->rg_property_data[1];
while (req_bytes) {
if ((hfi_buf_req->buffer_size) &&
((hfi_buf_req->buffer_count_min > hfi_buf_req->
buffer_count_actual)))
dprintk(VIDC_WARN,
"hal_process_sess_get_prop_buf_req:"
"bad_buf_req");
dprintk(VIDC_DBG, "got buffer requirements for: %d",
hfi_buf_req->buffer_type);
switch (hfi_buf_req->buffer_type) {
case HFI_BUFFER_INPUT:
memcpy(&buffreq->buffer[0], hfi_buf_req,
sizeof(struct hfi_buffer_requirements));
buffreq->buffer[0].buffer_type = HAL_BUFFER_INPUT;
break;
case HFI_BUFFER_OUTPUT:
memcpy(&buffreq->buffer[1], hfi_buf_req,
sizeof(struct hfi_buffer_requirements));
buffreq->buffer[1].buffer_type = HAL_BUFFER_OUTPUT;
break;
case HFI_BUFFER_OUTPUT2:
memcpy(&buffreq->buffer[2], hfi_buf_req,
sizeof(struct hfi_buffer_requirements));
buffreq->buffer[2].buffer_type = HAL_BUFFER_OUTPUT2;
break;
case HFI_BUFFER_EXTRADATA_INPUT:
memcpy(&buffreq->buffer[3], hfi_buf_req,
sizeof(struct hfi_buffer_requirements));
buffreq->buffer[3].buffer_type =
HAL_BUFFER_EXTRADATA_INPUT;
break;
case HFI_BUFFER_EXTRADATA_OUTPUT:
memcpy(&buffreq->buffer[4], hfi_buf_req,
sizeof(struct hfi_buffer_requirements));
buffreq->buffer[4].buffer_type =
HAL_BUFFER_EXTRADATA_OUTPUT;
break;
case HFI_BUFFER_EXTRADATA_OUTPUT2:
memcpy(&buffreq->buffer[5], hfi_buf_req,
sizeof(struct hfi_buffer_requirements));
buffreq->buffer[5].buffer_type =
HAL_BUFFER_EXTRADATA_OUTPUT2;
break;
case HFI_BUFFER_INTERNAL_SCRATCH:
memcpy(&buffreq->buffer[6], hfi_buf_req,
sizeof(struct hfi_buffer_requirements));
buffreq->buffer[6].buffer_type =
HAL_BUFFER_INTERNAL_SCRATCH;
break;
case HFI_BUFFER_INTERNAL_SCRATCH_1:
memcpy(&buffreq->buffer[7], hfi_buf_req,
sizeof(struct hfi_buffer_requirements));
buffreq->buffer[7].buffer_type =
HAL_BUFFER_INTERNAL_SCRATCH_1;
break;
case HFI_BUFFER_INTERNAL_SCRATCH_2:
memcpy(&buffreq->buffer[8], hfi_buf_req,
sizeof(struct hfi_buffer_requirements));
buffreq->buffer[8].buffer_type =
HAL_BUFFER_INTERNAL_SCRATCH_2;
break;
case HFI_BUFFER_INTERNAL_PERSIST:
memcpy(&buffreq->buffer[9], hfi_buf_req,
sizeof(struct hfi_buffer_requirements));
buffreq->buffer[9].buffer_type =
HAL_BUFFER_INTERNAL_PERSIST;
break;
case HFI_BUFFER_INTERNAL_PERSIST_1:
memcpy(&buffreq->buffer[10], hfi_buf_req,
sizeof(struct hfi_buffer_requirements));
buffreq->buffer[10].buffer_type =
HAL_BUFFER_INTERNAL_PERSIST_1;
break;
default:
dprintk(VIDC_ERR,
"hal_process_sess_get_prop_buf_req: bad_buffer_type: %d",
hfi_buf_req->buffer_type);
break;
}
req_bytes -= sizeof(struct hfi_buffer_requirements);
hfi_buf_req++;
}
}
static void hfi_process_session_prop_info(
msm_vidc_callback callback, u32 device_id,
struct hfi_msg_session_property_info_packet *pkt)
{
struct msm_vidc_cb_cmd_done cmd_done;
struct buffer_requirements buff_req;
dprintk(VIDC_DBG, "Received SESSION_PROPERTY_INFO");
if (pkt->size < sizeof(struct hfi_msg_session_property_info_packet)) {
dprintk(VIDC_ERR, "hal_process_session_prop_info:bad_pkt_size");
return;
}
if (pkt->num_properties == 0) {
dprintk(VIDC_ERR,
"hal_process_session_prop_info:no_properties");
return;
}
memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
memset(&buff_req, 0, sizeof(struct buffer_requirements));
switch (pkt->rg_property_data[0]) {
case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
hfi_process_sess_get_prop_buf_req(pkt, &buff_req);
cmd_done.device_id = device_id;
cmd_done.session_id =
((struct hal_session *) pkt->session_id)->session_id;
cmd_done.status = VIDC_ERR_NONE;
cmd_done.data = &buff_req;
cmd_done.size = sizeof(struct buffer_requirements);
callback(SESSION_PROPERTY_INFO, &cmd_done);
break;
default:
dprintk(VIDC_ERR, "hal_process_session_prop_info:"
"unknown_prop_id: %d",
pkt->rg_property_data[0]);
break;
}
}
static void hfi_process_session_init_done(
msm_vidc_callback callback, u32 device_id,
struct hfi_msg_sys_session_init_done_packet *pkt)
{
struct msm_vidc_cb_cmd_done cmd_done;
struct vidc_hal_session_init_done session_init_done;
struct hal_session *sess_close = NULL;
dprintk(VIDC_DBG, "RECEIVED:SESSION_INIT_DONE");
if (sizeof(struct hfi_msg_sys_session_init_done_packet)
> pkt->size) {
dprintk(VIDC_ERR, "hal_process_session_init_done:bad_pkt_size");
return;
}
memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
memset(&session_init_done, 0, sizeof(struct
vidc_hal_session_init_done));
cmd_done.device_id = device_id;
cmd_done.session_id =
((struct hal_session *) pkt->session_id)->session_id;
cmd_done.status = hfi_map_err_status((u32)pkt->error_type);
cmd_done.data = &session_init_done;
if (!cmd_done.status) {
cmd_done.status = hfi_process_sess_init_done_prop_read(
pkt, &session_init_done);
} else {
sess_close = (struct hal_session *)pkt->session_id;
if (sess_close) {
dprintk(VIDC_INFO,
"Sess init failed: Deleting session: 0x%x 0x%p",
sess_close->session_id, sess_close);
list_del(&sess_close->list);
kfree(sess_close);
sess_close = NULL;
}
}
cmd_done.size = sizeof(struct vidc_hal_session_init_done);
callback(SESSION_INIT_DONE, &cmd_done);
}
static void hfi_process_session_load_res_done(
msm_vidc_callback callback, u32 device_id,
struct hfi_msg_session_load_resources_done_packet *pkt)
{
struct msm_vidc_cb_cmd_done cmd_done;
dprintk(VIDC_DBG, "RECEIVED:SESSION_LOAD_RESOURCES_DONE");
if (sizeof(struct hfi_msg_session_load_resources_done_packet) !=
pkt->size) {
dprintk(VIDC_ERR, "hal_process_session_load_res_done:"
" bad packet size: %d", pkt->size);
return;
}
memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
cmd_done.device_id = device_id;
cmd_done.session_id =
((struct hal_session *) pkt->session_id)->session_id;
cmd_done.status = hfi_map_err_status((u32)pkt->error_type);
cmd_done.data = NULL;
cmd_done.size = 0;
callback(SESSION_LOAD_RESOURCE_DONE, &cmd_done);
}
static void hfi_process_session_flush_done(
msm_vidc_callback callback, u32 device_id,
struct hfi_msg_session_flush_done_packet *pkt)
{
struct msm_vidc_cb_cmd_done cmd_done;
dprintk(VIDC_DBG, "RECEIVED:SESSION_FLUSH_DONE");
if (sizeof(struct hfi_msg_session_flush_done_packet) != pkt->size) {
dprintk(VIDC_ERR, "hal_process_session_flush_done: "
"bad packet size: %d", pkt->size);
return;
}
memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
cmd_done.device_id = device_id;
cmd_done.session_id =
((struct hal_session *) pkt->session_id)->session_id;
cmd_done.status = hfi_map_err_status((u32)pkt->error_type);
cmd_done.data = (void *) pkt->flush_type;
cmd_done.size = sizeof(u32);
callback(SESSION_FLUSH_DONE, &cmd_done);
}
static void hfi_process_session_etb_done(
msm_vidc_callback callback, u32 device_id,
struct hfi_msg_session_empty_buffer_done_packet *pkt)
{
struct msm_vidc_cb_data_done data_done;
dprintk(VIDC_DBG, "RECEIVED:SESSION_ETB_DONE");
if (!pkt || pkt->size <
sizeof(struct hfi_msg_session_empty_buffer_done_packet)) {
dprintk(VIDC_ERR, "hal_process_session_etb_done:bad_pkt_size");
return;
}
memset(&data_done, 0, sizeof(struct msm_vidc_cb_data_done));
data_done.device_id = device_id;
data_done.session_id =
((struct hal_session *) pkt->session_id)->session_id;
data_done.status = hfi_map_err_status((u32) pkt->error_type);
data_done.size = sizeof(struct msm_vidc_cb_data_done);
data_done.clnt_data = (void *)pkt->input_tag;
data_done.input_done.offset = pkt->offset;
data_done.input_done.filled_len = pkt->filled_len;
data_done.input_done.packet_buffer = pkt->packet_buffer;
data_done.input_done.status =
hfi_map_err_status((u32) pkt->error_type);
callback(SESSION_ETB_DONE, &data_done);
}
static void hfi_process_session_ftb_done(
msm_vidc_callback callback, u32 device_id,
void *msg_hdr)
{
struct msm_vidc_cb_data_done data_done;
struct hfi_msg_session_fill_buffer_done_compressed_packet *pack =
(struct hfi_msg_session_fill_buffer_done_compressed_packet *) msg_hdr;
u32 is_decoder = ((struct hal_session *)pack->session_id)->is_decoder;
struct hal_session *session;
if (!msg_hdr) {
dprintk(VIDC_ERR, "Invalid Params");
return;
}
session = (struct hal_session *)
((struct hal_session *) pack->session_id)->session_id;
dprintk(VIDC_DBG, "RECEIVED:SESSION_FTB_DONE");
memset(&data_done, 0, sizeof(struct msm_vidc_cb_data_done));
if (is_decoder == 0) {
struct hfi_msg_session_fill_buffer_done_compressed_packet *pkt =
(struct hfi_msg_session_fill_buffer_done_compressed_packet *)
msg_hdr;
if (sizeof(struct
hfi_msg_session_fill_buffer_done_compressed_packet)
> pkt->size) {
dprintk(VIDC_ERR,
"hal_process_session_ftb_done: bad_pkt_size");
return;
} else if (pkt->error_type != HFI_ERR_NONE) {
dprintk(VIDC_ERR,
"got buffer back with error %x",
pkt->error_type);
/* Proceed with the FBD */
}
data_done.device_id = device_id;
data_done.session_id = (u32) session;
data_done.status = hfi_map_err_status((u32)
pkt->error_type);
data_done.size = sizeof(struct msm_vidc_cb_data_done);
data_done.clnt_data = (void *) pkt->input_tag;
data_done.output_done.timestamp_hi = pkt->time_stamp_hi;
data_done.output_done.timestamp_lo = pkt->time_stamp_lo;
data_done.output_done.flags1 = pkt->flags;
data_done.output_done.mark_target = pkt->mark_target;
data_done.output_done.mark_data = pkt->mark_data;
data_done.output_done.stats = pkt->stats;
data_done.output_done.offset1 = pkt->offset;
data_done.output_done.alloc_len1 = pkt->alloc_len;
data_done.output_done.filled_len1 = pkt->filled_len;
data_done.output_done.picture_type = pkt->picture_type;
data_done.output_done.packet_buffer1 = pkt->packet_buffer;
data_done.output_done.extra_data_buffer =
pkt->extra_data_buffer;
dprintk(VIDC_DBG, "FBD: Received buf: %p, of len: %d\n",
pkt->packet_buffer, pkt->filled_len);
} else if (is_decoder == 1) {
struct hfi_msg_session_fbd_uncompressed_plane0_packet *pkt =
(struct hfi_msg_session_fbd_uncompressed_plane0_packet *)
msg_hdr;
if (sizeof(struct
hfi_msg_session_fbd_uncompressed_plane0_packet)
> pkt->size) {
dprintk(VIDC_ERR, "hal_process_session_ftb_done:"
"bad_pkt_size");
return;
}
data_done.device_id = device_id;
data_done.session_id = (u32) session;
data_done.status = hfi_map_err_status((u32)
pkt->error_type);
data_done.size = sizeof(struct msm_vidc_cb_data_done);
data_done.clnt_data = (void *)pkt->input_tag;
data_done.output_done.stream_id = pkt->stream_id;
data_done.output_done.view_id = pkt->view_id;
data_done.output_done.timestamp_hi = pkt->time_stamp_hi;
data_done.output_done.timestamp_lo = pkt->time_stamp_lo;
data_done.output_done.flags1 = pkt->flags;
data_done.output_done.mark_target = pkt->mark_target;
data_done.output_done.mark_data = pkt->mark_data;
data_done.output_done.stats = pkt->stats;
data_done.output_done.alloc_len1 = pkt->alloc_len;
data_done.output_done.filled_len1 = pkt->filled_len;
data_done.output_done.offset1 = pkt->offset;
data_done.output_done.frame_width = pkt->frame_width;
data_done.output_done.frame_height = pkt->frame_height;
data_done.output_done.start_x_coord = pkt->start_x_coord;
data_done.output_done.start_y_coord = pkt->start_y_coord;
data_done.output_done.input_tag1 = pkt->input_tag;
data_done.output_done.picture_type = pkt->picture_type;
data_done.output_done.packet_buffer1 = pkt->packet_buffer;
data_done.output_done.extra_data_buffer =
pkt->extra_data_buffer;
if (pkt->stream_id == 0)
data_done.output_done.buffer_type = HAL_BUFFER_OUTPUT;
else if (pkt->stream_id == 1)
data_done.output_done.buffer_type = HAL_BUFFER_OUTPUT2;
}
callback(SESSION_FTB_DONE, &data_done);
}
static void hfi_process_session_start_done(
msm_vidc_callback callback, u32 device_id,
struct hfi_msg_session_start_done_packet *pkt)
{
struct msm_vidc_cb_cmd_done cmd_done;
dprintk(VIDC_DBG, "RECEIVED:SESSION_START_DONE");
if (!pkt || pkt->size !=
sizeof(struct hfi_msg_session_start_done_packet)) {
dprintk(VIDC_ERR, "hal_process_session_start_done:"
"bad packet/packet size: %d", pkt->size);
return;
}
memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
cmd_done.device_id = device_id;
cmd_done.session_id =
((struct hal_session *) pkt->session_id)->session_id;
cmd_done.status = hfi_map_err_status((u32)pkt->error_type);
cmd_done.data = NULL;
cmd_done.size = 0;
callback(SESSION_START_DONE, &cmd_done);
}
static void hfi_process_session_stop_done(
msm_vidc_callback callback, u32 device_id,
struct hfi_msg_session_stop_done_packet *pkt)
{
struct msm_vidc_cb_cmd_done cmd_done;
dprintk(VIDC_DBG, "RECEIVED:SESSION_STOP_DONE");
if (!pkt || pkt->size !=
sizeof(struct hfi_msg_session_stop_done_packet)) {
dprintk(VIDC_ERR, "hal_process_session_stop_done:"
"bad packet/packet size: %d", pkt->size);
return;
}
memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
cmd_done.device_id = device_id;
cmd_done.session_id =
((struct hal_session *) pkt->session_id)->session_id;
cmd_done.status = hfi_map_err_status((u32)pkt->error_type);
cmd_done.data = NULL;
cmd_done.size = 0;
callback(SESSION_STOP_DONE, &cmd_done);
}
static void hfi_process_session_rel_res_done(
msm_vidc_callback callback, u32 device_id,
struct hfi_msg_session_release_resources_done_packet *pkt)
{
struct msm_vidc_cb_cmd_done cmd_done;
dprintk(VIDC_DBG, "RECEIVED:SESSION_RELEASE_RESOURCES_DONE");
if (!pkt || pkt->size !=
sizeof(struct hfi_msg_session_release_resources_done_packet)) {
dprintk(VIDC_ERR, "hal_process_session_rel_res_done:"
"bad packet/packet size: %d", pkt->size);
return;
}
memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
cmd_done.device_id = device_id;
cmd_done.session_id =
((struct hal_session *) pkt->session_id)->session_id;
cmd_done.status = hfi_map_err_status((u32)pkt->error_type);
cmd_done.data = NULL;
cmd_done.size = 0;
callback(SESSION_RELEASE_RESOURCE_DONE, &cmd_done);
}
static void hfi_process_session_rel_buf_done(
msm_vidc_callback callback, u32 device_id,
struct hfi_msg_session_release_buffers_done_packet *pkt)
{
struct msm_vidc_cb_cmd_done cmd_done;
if (!pkt || pkt->size !=
sizeof(struct
hfi_msg_session_release_buffers_done_packet)) {
dprintk(VIDC_ERR, "bad packet/packet size: %d", pkt->size);
return;
}
memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
cmd_done.device_id = device_id;
cmd_done.size = sizeof(struct msm_vidc_cb_cmd_done);
cmd_done.session_id =
((struct hal_session *) pkt->session_id)->session_id;
cmd_done.status = hfi_map_err_status((u32)pkt->error_type);
if (pkt->rg_buffer_info) {
cmd_done.data = (void *) &pkt->rg_buffer_info;
cmd_done.size = sizeof(struct hfi_buffer_info);
} else {
dprintk(VIDC_ERR, "invalid payload in rel_buff_done\n");
}
callback(SESSION_RELEASE_BUFFER_DONE, &cmd_done);
}
static void hfi_process_session_end_done(
msm_vidc_callback callback, u32 device_id,
struct hfi_msg_sys_session_end_done_packet *pkt)
{
struct msm_vidc_cb_cmd_done cmd_done;
dprintk(VIDC_DBG, "RECEIVED:SESSION_END_DONE");
if (!pkt || pkt->size !=
sizeof(struct hfi_msg_sys_session_end_done_packet)) {
dprintk(VIDC_ERR, "hal_process_session_end_done: "
"bad packet/packet size: %d", pkt->size);
return;
}
memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
cmd_done.device_id = device_id;
cmd_done.session_id =
((struct hal_session *) pkt->session_id)->session_id;
cmd_done.status = hfi_map_err_status((u32)pkt->error_type);
cmd_done.data = NULL;
cmd_done.size = 0;
callback(SESSION_END_DONE, &cmd_done);
}
static void hfi_process_session_abort_done(
msm_vidc_callback callback, u32 device_id,
struct hfi_msg_sys_session_abort_done_packet *pkt)
{
struct msm_vidc_cb_cmd_done cmd_done;
dprintk(VIDC_DBG, "RECEIVED:SESSION_ABORT_DONE");
if (!pkt || pkt->size !=
sizeof(struct hfi_msg_sys_session_abort_done_packet)) {
dprintk(VIDC_ERR, "%s: bad packet/packet size: %d",
__func__, pkt ? pkt->size : 0);
return;
}
memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
cmd_done.device_id = device_id;
cmd_done.session_id =
((struct hal_session *) pkt->session_id)->session_id;
cmd_done.status = hfi_map_err_status((u32)pkt->error_type);
cmd_done.data = NULL;
cmd_done.size = 0;
callback(SESSION_ABORT_DONE, &cmd_done);
}
static void hfi_process_session_get_seq_hdr_done(
msm_vidc_callback callback, u32 device_id,
struct hfi_msg_session_get_sequence_header_done_packet *pkt)
{
struct msm_vidc_cb_data_done data_done;
if (!pkt || pkt->size !=
sizeof(struct
hfi_msg_session_get_sequence_header_done_packet)) {
dprintk(VIDC_ERR, "bad packet/packet size: %d", pkt->size);
return;
}
memset(&data_done, 0, sizeof(struct msm_vidc_cb_data_done));
data_done.device_id = device_id;
data_done.size = sizeof(struct msm_vidc_cb_data_done);
data_done.session_id =
((struct hal_session *) pkt->session_id)->session_id;
data_done.status = hfi_map_err_status((u32)pkt->error_type);
data_done.output_done.packet_buffer1 = pkt->sequence_header;
data_done.output_done.filled_len1 = pkt->header_len;
dprintk(VIDC_INFO, "seq_hdr: %p, Length: %d",
pkt->sequence_header, pkt->header_len);
callback(SESSION_GET_SEQ_HDR_DONE, &data_done);
}
void hfi_process_sys_property_info(
struct hfi_property_sys_image_version_info_type *pkt)
{
int i = 0;
u32 smem_block_size = 0;
u8 *smem_table_ptr;
char version[256];
const u32 smem_image_index_venus = 14 * 128;
if (!pkt || !pkt->string_size) {
dprintk(VIDC_ERR, "%s: invalid param\n", __func__);
return;
}
if (pkt->string_size < sizeof(version)) {
/*
* The version string returned by firmware includes null
* characters at the start and in between. Replace the null
* characters with space, to print the version info.
*/
for (i = 0; i < pkt->string_size; i++) {
if (pkt->str_image_version[i] != '\0')
version[i] = pkt->str_image_version[i];
else
version[i] = ' ';
}
version[i] = '\0';
dprintk(VIDC_INFO, "F/W version: %s\n", version);
}
smem_table_ptr = smem_get_entry(SMEM_IMAGE_VERSION_TABLE,
&smem_block_size);
if (smem_table_ptr &&
((smem_image_index_venus + 128) <= smem_block_size))
memcpy(smem_table_ptr + smem_image_index_venus,
(u8 *)pkt->str_image_version, 128);
}
u32 hfi_process_msg_packet(
msm_vidc_callback callback, u32 device_id,
struct vidc_hal_msg_pkt_hdr *msg_hdr,
struct list_head *sessions, struct mutex *session_lock)
{
u32 rc = 0;
struct hal_session *sess = NULL;
if (!callback || !msg_hdr || msg_hdr->size <
VIDC_IFACEQ_MIN_PKT_SIZE) {
dprintk(VIDC_ERR, "hal_process_msg_packet:bad"
"packet/packet size: %d", msg_hdr->size);
rc = -EINVAL;
return rc;
}
dprintk(VIDC_INFO, "Received: 0x%x in ", msg_hdr->packet);
rc = (u32) msg_hdr->packet;
sess = (struct hal_session *)((struct
vidc_hal_session_cmd_pkt*) msg_hdr)->session_id;
switch (msg_hdr->packet) {
case HFI_MSG_EVENT_NOTIFY:
hfi_process_event_notify(callback, device_id,
(struct hfi_msg_event_notify_packet *) msg_hdr,
sessions, session_lock);
break;
case HFI_MSG_SYS_INIT_DONE:
hfi_process_sys_init_done(callback, device_id,
(struct hfi_msg_sys_init_done_packet *)
msg_hdr);
break;
case HFI_MSG_SYS_IDLE:
break;
case HFI_MSG_SYS_SESSION_INIT_DONE:
if (!validate_session_pkt(sessions, sess, session_lock))
hfi_process_session_init_done(callback, device_id,
(struct hfi_msg_sys_session_init_done_packet *)
msg_hdr);
break;
case HFI_MSG_SYS_PROPERTY_INFO:
hfi_process_sys_property_info(
(struct hfi_property_sys_image_version_info_type *)
msg_hdr);
break;
case HFI_MSG_SYS_SESSION_END_DONE:
if (!validate_session_pkt(sessions, sess, session_lock))
hfi_process_session_end_done(callback, device_id,
(struct hfi_msg_sys_session_end_done_packet *)
msg_hdr);
break;
case HFI_MSG_SESSION_LOAD_RESOURCES_DONE:
if (!validate_session_pkt(sessions, sess, session_lock))
hfi_process_session_load_res_done(callback, device_id,
(struct hfi_msg_session_load_resources_done_packet *)
msg_hdr);
break;
case HFI_MSG_SESSION_START_DONE:
if (!validate_session_pkt(sessions, sess, session_lock))
hfi_process_session_start_done(callback, device_id,
(struct hfi_msg_session_start_done_packet *)
msg_hdr);
break;
case HFI_MSG_SESSION_STOP_DONE:
if (!validate_session_pkt(sessions, sess, session_lock))
hfi_process_session_stop_done(callback, device_id,
(struct hfi_msg_session_stop_done_packet *)
msg_hdr);
break;
case HFI_MSG_SESSION_EMPTY_BUFFER_DONE:
if (!validate_session_pkt(sessions, sess, session_lock))
hfi_process_session_etb_done(callback, device_id,
(struct hfi_msg_session_empty_buffer_done_packet *)
msg_hdr);
break;
case HFI_MSG_SESSION_FILL_BUFFER_DONE:
if (!validate_session_pkt(sessions, sess, session_lock))
hfi_process_session_ftb_done(callback, device_id,
msg_hdr);
break;
case HFI_MSG_SESSION_FLUSH_DONE:
if (!validate_session_pkt(sessions, sess, session_lock))
hfi_process_session_flush_done(callback, device_id,
(struct hfi_msg_session_flush_done_packet *)
msg_hdr);
break;
case HFI_MSG_SESSION_PROPERTY_INFO:
if (!validate_session_pkt(sessions, sess, session_lock))
hfi_process_session_prop_info(callback, device_id,
(struct hfi_msg_session_property_info_packet *)
msg_hdr);
break;
case HFI_MSG_SESSION_RELEASE_RESOURCES_DONE:
if (!validate_session_pkt(sessions, sess, session_lock))
hfi_process_session_rel_res_done(callback, device_id,
(struct hfi_msg_session_release_resources_done_packet *)
msg_hdr);
break;
case HFI_MSG_SYS_RELEASE_RESOURCE:
hfi_process_sys_rel_resource_done(callback, device_id,
(struct hfi_msg_sys_release_resource_done_packet *)
msg_hdr);
break;
case HFI_MSG_SESSION_GET_SEQUENCE_HEADER_DONE:
if (!validate_session_pkt(sessions, sess, session_lock))
hfi_process_session_get_seq_hdr_done(
callback, device_id, (struct
hfi_msg_session_get_sequence_header_done_packet*)
msg_hdr);
break;
case HFI_MSG_SESSION_RELEASE_BUFFERS_DONE:
if (!validate_session_pkt(sessions, sess, session_lock))
hfi_process_session_rel_buf_done(callback, device_id,
(struct hfi_msg_session_release_buffers_done_packet *)
msg_hdr);
break;
case HFI_MSG_SYS_SESSION_ABORT_DONE:
if (!validate_session_pkt(sessions, sess, session_lock))
hfi_process_session_abort_done(callback, device_id,
(struct hfi_msg_sys_session_abort_done_packet *)
msg_hdr);
break;
default:
dprintk(VIDC_DBG, "UNKNOWN_MSG_TYPE : %d", msg_hdr->packet);
break;
}
return rc;
}