324 lines
9.1 KiB
C
324 lines
9.1 KiB
C
/*******************************************************************************
|
|
** This file is provided under a dual BSD/GPLv2 license. When using or
|
|
** redistributing this file, you may do so under either license.
|
|
**
|
|
** GPL LICENSE SUMMARY
|
|
**
|
|
** Copyright (c) 2013 Intel Corporation All Rights Reserved
|
|
**
|
|
** This program is free software; you can redistribute it and/or modify it under
|
|
** the terms of version 2 of the GNU General Public License 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.
|
|
**
|
|
** You should have received a copy of the GNU General Public License along with
|
|
** this program; if not, write to the Free Software Foundation, Inc.,
|
|
** 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
|
** The full GNU General Public License is included in this distribution in the
|
|
** file called LICENSE.GPL.
|
|
**
|
|
** BSD LICENSE
|
|
**
|
|
** Copyright (c) 2013 Intel Corporation All Rights Reserved
|
|
**
|
|
** Redistribution and use in source and binary forms, with or without
|
|
** modification, are permitted provided that the following conditions are met:
|
|
**
|
|
** * Redistributions of source code must retain the above copyright notice, this
|
|
** list of conditions and the following disclaimer.
|
|
** * Redistributions in binary form must reproduce the above copyright notice,
|
|
** this list of conditions and the following disclaimer in the documentation
|
|
** and/or other materials provided with the distribution.
|
|
** * Neither the name of Intel Corporation nor the names of its contributors may
|
|
** be used to endorse or promote products derived from this software without
|
|
** specific prior written permission.
|
|
**
|
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
** POSSIBILITY OF SUCH DAMAGE.
|
|
**
|
|
*******************************************************************************/
|
|
|
|
#ifdef ESIF_ATTR_USER
|
|
# define ESIF_TRACE_ID ESIF_TRACEMODULE_IPC
|
|
#endif
|
|
|
|
#include "esif_ipc.h"
|
|
#include "esif_primitive.h"
|
|
#include "esif_debug.h"
|
|
|
|
#ifdef ESIF_ATTR_OS_WINDOWS
|
|
/*
|
|
*
|
|
* The Windows banned-API check header must be included after all other headers,
|
|
* or issues can be identified
|
|
* against Windows SDK/DDK included headers which we have no control over.
|
|
*
|
|
*/
|
|
#define _SDL_BANNED_RECOMMENDED
|
|
#include "win\banned.h"
|
|
#endif
|
|
|
|
#ifdef ESIF_ATTR_KERNEL
|
|
|
|
#define ESIF_DEBUG_MODULE ESIF_DEBUG_MOD_IPC
|
|
|
|
/* Debug Logging Defintions */
|
|
#define RESERVED0 0 /* Used By OS Version */
|
|
#define RESERVED1 1 /* Used By OS Version */
|
|
#define RESERVED2 2 /* Used By OS Version */
|
|
#define RESERVED4 3 /* Used By OS Version */
|
|
#define INIT_DEBUG 4 /* Init Debug */
|
|
#define IPC_DEBUG 5 /* IPC Debug */
|
|
#define RESERVED20 6 /* Reserved */
|
|
#define RESERVED40 7 /* Reserved */
|
|
|
|
#define ESIF_TRACE_DYN_INIT(format, ...) \
|
|
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_IPC, INIT_DEBUG, format, ##__VA_ARGS__)
|
|
#define ESIF_TRACE_DYN_IPC(format, ...) \
|
|
ESIF_TRACE_DYN(ESIF_DEBUG_MOD_IPC, IPC_DEBUG, format, ##__VA_ARGS__)
|
|
|
|
/*
|
|
* Kernel Implementation
|
|
*/
|
|
|
|
/*
|
|
******************************************************************************
|
|
* PUBLIC
|
|
******************************************************************************
|
|
*/
|
|
|
|
/* Process IPC */
|
|
struct esif_ipc *esif_ipc_process(
|
|
struct esif_ipc *ipc_ptr
|
|
)
|
|
{
|
|
struct esif_ipc *ipc_ret_ptr = ipc_ptr;
|
|
ESIF_TRACE_DYN_IPC("%s: START ipc %p\n", ESIF_FUNC, ipc_ptr);
|
|
|
|
/*
|
|
* If we got this far we are guaranteed to have a valid IPC
|
|
* header now we need to check to see if we hav enough data
|
|
* for the type specified if so process it if not return to
|
|
* avoid what would surely result in undesired behavior.
|
|
*/
|
|
|
|
switch (ipc_ptr->type) {
|
|
/* Command e.g. Get Participants, Etc. */
|
|
case ESIF_IPC_TYPE_COMMAND:
|
|
ESIF_TRACE_DYN_IPC("%s: COMMAND Received\n", ESIF_FUNC);
|
|
if (ipc_ptr->data_len < sizeof(struct esif_ipc_command))
|
|
ipc_ptr->return_code = ESIF_E_IPC_DATA_INVALID;
|
|
else
|
|
ipc_ret_ptr = esif_execute_ipc_command(ipc_ptr);
|
|
break;
|
|
|
|
/* Retireve A Signaled Event Or Check Event Queue */
|
|
case ESIF_IPC_TYPE_EVENT:
|
|
ESIF_TRACE_DYN_IPC("%s: EVENT Received\n", ESIF_FUNC);
|
|
if (ipc_ptr->data_len < sizeof(struct esif_ipc_event_header))
|
|
ipc_ptr->return_code = ESIF_E_IPC_DATA_INVALID;
|
|
else
|
|
ipc_ret_ptr = esif_event_queue_pull();
|
|
break;
|
|
|
|
/* Execute Primitive e.g. GET_TEMPERATURE */
|
|
case ESIF_IPC_TYPE_PRIMITIVE:
|
|
ESIF_TRACE_DYN_IPC("%s: PRIMITIVE Received\n", ESIF_FUNC);
|
|
if (ipc_ptr->data_len < sizeof(struct esif_ipc_primitive))
|
|
ipc_ptr->return_code = ESIF_E_IPC_DATA_INVALID;
|
|
else
|
|
ipc_ret_ptr = esif_execute_ipc_primitive(ipc_ptr);
|
|
break;
|
|
|
|
/* NOOP For Testing */
|
|
case ESIF_IPC_TYPE_NOOP:
|
|
ESIF_TRACE_DYN_IPC("%s: NOOP Received\n", ESIF_FUNC);
|
|
ipc_ret_ptr = NULL;
|
|
break;
|
|
|
|
/* Unsupported or Unknown IPC Type Received */
|
|
default:
|
|
ESIF_TRACE_DYN_IPC("%s: Unknown IPC Type Received type=%u\n",
|
|
ESIF_FUNC,
|
|
ipc_ptr->type);
|
|
ipc_ptr->return_code = ESIF_E_IPC_DATA_INVALID;
|
|
break;
|
|
}
|
|
ESIF_TRACE_DYN_IPC("%s: FINISH return result: %s(%u)\n",
|
|
ESIF_FUNC,
|
|
esif_rc_str(ipc_ptr->return_code),
|
|
ipc_ptr->return_code);
|
|
return ipc_ret_ptr;
|
|
}
|
|
|
|
|
|
/* Init */
|
|
enum esif_rc esif_ipc_init(
|
|
esif_device_t device
|
|
)
|
|
{
|
|
ESIF_TRACE_DYN_INIT("%s: Initialize IPC\n", ESIF_FUNC);
|
|
|
|
return esif_os_ipc_init(device);
|
|
}
|
|
|
|
|
|
/* Exit */
|
|
void esif_ipc_exit(
|
|
esif_device_t device
|
|
)
|
|
{
|
|
esif_os_ipc_exit(device);
|
|
|
|
ESIF_TRACE_DYN_INIT("%s: Exit IPC\n", ESIF_FUNC);
|
|
}
|
|
|
|
|
|
#endif /* ESIF_ATTR_KERNEL */
|
|
#ifdef ESIF_ATTR_USER
|
|
|
|
/*
|
|
** User Implementation
|
|
*/
|
|
|
|
/* IPC Connect */
|
|
esif_handle_t esif_ipc_connect(
|
|
esif_string session_id
|
|
)
|
|
{
|
|
ESIF_TRACE_DEBUG("%s: IPC session_id = %s\n",
|
|
ESIF_FUNC, session_id);
|
|
return esif_os_ipc_connect(session_id);
|
|
}
|
|
|
|
|
|
/* IPC Disconnect */
|
|
void esif_ipc_disconnect(
|
|
esif_handle_t handle
|
|
)
|
|
{
|
|
ESIF_TRACE_DEBUG("%s: IPC handle = %d\n",
|
|
ESIF_FUNC, handle);
|
|
esif_os_ipc_disconnect(handle);
|
|
}
|
|
|
|
|
|
/* IPC Execute */
|
|
enum esif_rc esif_ipc_execute(
|
|
esif_handle_t handle,
|
|
struct esif_ipc *ipc_ptr
|
|
)
|
|
{
|
|
ESIF_TRACE_DEBUG("%s: handle = %d, IPC = %p\n",
|
|
ESIF_FUNC, handle, ipc_ptr);
|
|
return esif_os_ipc_execute(handle, ipc_ptr);
|
|
}
|
|
|
|
|
|
#endif /* ESIF_ATTR_USER */
|
|
|
|
|
|
/*
|
|
** Agnostic Implementation
|
|
*/
|
|
|
|
/* Allocate IPC */
|
|
struct esif_ipc *esif_ipc_alloc(
|
|
enum esif_ipc_type type,
|
|
u32 data_len
|
|
)
|
|
{
|
|
u32 ipc_size = data_len + sizeof(struct esif_ipc);
|
|
struct esif_ipc *ipc_ptr = (struct esif_ipc *)esif_ccb_malloc(ipc_size);
|
|
if (NULL == ipc_ptr)
|
|
return NULL;
|
|
|
|
ipc_ptr->version = ESIF_IPC_VERSION;
|
|
ipc_ptr->type = type;
|
|
ipc_ptr->data_len = data_len;
|
|
ipc_ptr->return_code = ESIF_OK;
|
|
|
|
#ifdef ESIF_ATTR_HMAC
|
|
esif_ccb_memcpy(ipc->hmac, x, ESIF_HMAC_LEN);
|
|
#endif
|
|
ESIF_TRACE_DEBUG("%s: ipc = %p, type = %d, size = %d data_len = %d\n",
|
|
ESIF_FUNC, ipc_ptr, type, (int)ipc_size,
|
|
(int)data_len);
|
|
return ipc_ptr;
|
|
}
|
|
|
|
|
|
/* Allocate Command IPC */
|
|
struct esif_ipc *esif_ipc_alloc_command(
|
|
struct esif_ipc_command **command_ptr_ptr,
|
|
u32 data_len
|
|
)
|
|
{
|
|
struct esif_ipc *ipc_ptr = NULL;
|
|
|
|
ipc_ptr = esif_ipc_alloc(ESIF_IPC_TYPE_COMMAND,
|
|
data_len + sizeof(struct esif_ipc_command));
|
|
|
|
if (NULL == ipc_ptr) {
|
|
*command_ptr_ptr = NULL;
|
|
} else {
|
|
struct esif_ipc_command *command_ptr = NULL;
|
|
command_ptr = (struct esif_ipc_command *)(ipc_ptr + 1);
|
|
|
|
command_ptr->version = ESIF_COMMAND_VERSION;
|
|
command_ptr->priority = ESIF_COMMAND_PRIORITY_NORMAL;
|
|
command_ptr->payload_len = data_len;
|
|
*command_ptr_ptr = command_ptr;
|
|
}
|
|
return ipc_ptr;
|
|
}
|
|
|
|
|
|
/* Allocate Primitive IPC */
|
|
struct esif_ipc *esif_ipc_alloc_primitive(
|
|
struct esif_ipc_primitive **primitive_ptr_ptr,
|
|
u32 data_len
|
|
)
|
|
{
|
|
struct esif_ipc *ipc_ptr = NULL;
|
|
ipc_ptr = esif_ipc_alloc(ESIF_IPC_TYPE_PRIMITIVE,
|
|
data_len + sizeof(struct esif_ipc_primitive));
|
|
|
|
if (NULL == ipc_ptr) {
|
|
*primitive_ptr_ptr = NULL;
|
|
} else {
|
|
struct esif_ipc_primitive *primitive_ptr = NULL;
|
|
primitive_ptr = (struct esif_ipc_primitive *)(ipc_ptr + 1);
|
|
|
|
primitive_ptr->version = ESIF_PRIMITIVE_VERSION;
|
|
primitive_ptr->payload_len = data_len;
|
|
*primitive_ptr_ptr = primitive_ptr;
|
|
}
|
|
return ipc_ptr;
|
|
}
|
|
|
|
|
|
/* Free IPC */
|
|
void esif_ipc_free(struct esif_ipc *ipc_ptr)
|
|
{
|
|
ESIF_TRACE_DEBUG("%s: ipc = %p\n", ESIF_FUNC, ipc_ptr);
|
|
esif_ccb_free(ipc_ptr);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/*****************************************************************************/
|
|
/*****************************************************************************/
|