summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: c6157c1)
raw | patch | inline | side by side (parent: c6157c1)
author | vwan@ti.com <vwan@ti.com> | |
Wed, 29 May 2013 00:22:09 +0000 (17:22 -0700) | ||
committer | Chris Ring <cring@ti.com> | |
Thu, 30 May 2013 19:26:11 +0000 (12:26 -0700) |
Signed-off-by: VW <vwan@ti.com>
diff --git a/qnx/src/ipc3x_dev/ti/syslink/build/Qnx/resmgr/syslink_main.c b/qnx/src/ipc3x_dev/ti/syslink/build/Qnx/resmgr/syslink_main.c
index 3ad63e0ce0d4b3a14262eaf17b2bc2421ed6be39..7269814b719e32fd9882641df349c399b719f81c 100644 (file)
extern int rpmsg_resmgr_setup (void);
extern void rpmsg_resmgr_destroy (void);
-extern Int rpmsg_dce_setup (Void);
-extern Void rpmsg_dce_destroy (Void);
extern Int rpmsg_rpc_setup (Void);
extern Void rpmsg_rpc_destroy (Void);
extern Void GateHWSpinlock_LeaveLockForPID(int pid);
if (status < 0)
goto resmgrsetup_fail;
- /* Set up rpmsg_dce */
- status = rpmsg_dce_setup();
- if (status < 0)
- goto dcesetup_fail;
-
/* Set up rpmsg_mq */
status = ti_ipc_setup();
if (status < 0)
rpcsetup_fail:
ti_ipc_destroy(recover);
tiipcsetup_fail:
- rpmsg_dce_destroy();
-dcesetup_fail:
rpmsg_resmgr_destroy();
resmgrsetup_fail:
for (i-=1; i >= 0; i--) {
ti_ipc_destroy(recover);
- rpmsg_dce_destroy();
-
rpmsg_resmgr_destroy();
for (i = 0; i < MultiProc_MAXPROCESSORS; i++) {
diff --git a/qnx/src/ipc3x_dev/ti/syslink/rpmsg-dce/hlos/knl/Qnx/rpmsg-dcedrv.c b/qnx/src/ipc3x_dev/ti/syslink/rpmsg-dce/hlos/knl/Qnx/rpmsg-dcedrv.c
+++ /dev/null
@@ -1,2053 +0,0 @@
-/*
- * @file rpmsg-dcedrv.c
- *
- * @brief fileops handler for dCE component.
- *
- *
- * @ver 02.00.00.46_alpha1
- *
- * ============================================================================
- *
- * Copyright (c) 2010-2011, Texas Instruments Incorporated
- *
- * 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 Texas Instruments Incorporated 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.
- * Contact information for paper mail:
- * Texas Instruments
- * Post Office Box 655303
- * Dallas, Texas 75265
- * Contact information:
- * http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
- * DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
- * ============================================================================
- *
- */
-
-
-/* Standard headers */
-#include <ti/syslink/Std.h>
-
-/* OSAL & Utils headers */
-#include <ti/syslink/utils/List.h>
-#include <ti/syslink/utils/String.h>
-#include <ti/syslink/utils/Trace.h>
-#include <ti/syslink/utils/Memory.h>
-#include <ti/syslink/utils/IGateProvider.h>
-#include <ti/syslink/utils/GateSpinlock.h>
-#include <_MultiProc.h>
-
-/*QNX specific header include */
-#include <errno.h>
-#include <unistd.h>
-#include <sys/iofunc.h>
-#include <sys/dispatch.h>
-#include <sys/netmgr.h>
-#include <devctl.h>
-
-/* Module headers */
-#include <ti/ipc/rpmsg_dce.h>
-#include <ti/ipc/MessageQCopy.h>
-#include <_MessageQCopy.h>
-#include <_MessageQCopyDefs.h>
-#include "OsalSemaphore.h"
-#include "std_qnx.h"
-#include <pthread.h>
-
-#include "rpmsg-dcedrv.h"
-
-#define PRIORITY_REALTIME_LOW 29
-
-/* structure to hold rpmsg-dce device information */
-typedef struct named_device {
- iofunc_mount_t mattr;
- iofunc_attr_t cattr;
- int resmgr_id;
- pthread_mutex_t mutex;
- iofunc_funcs_t mfuncs;
- resmgr_connect_funcs_t cfuncs;
- resmgr_io_funcs_t iofuncs;
- char device_name[_POSIX_PATH_MAX];
-} named_device_t;
-
-/* rpmsg-dce device structure */
-typedef struct rpmsg_dce_dev {
- dispatch_t * dpp;
- thread_pool_t * tpool;
- named_device_t rpmsg_dce;
-} rpmsg_dce_dev_t;
-
-
-typedef enum {
- DCE_CONN_REQ,
- DCE_DISCON_REQ
-}dce_conn_req_type;
-
-typedef struct {
- UInt32 type;
- UInt32 addr;
-} dce_conn_req;
-
-/*!
- * @brief Remote connection object
- */
-typedef struct rpmsg_dce_conn_object {
- rpmsg_dce_dev_t * dev;
- MessageQCopy_Handle mq;
- UInt32 addr;
- UInt16 procId;
-} rpmsg_dce_conn_object;
-
-/*!
- * @brief dce instance object
- */
-typedef struct rpmsg_dce_object_tag {
- MessageQCopy_Handle mq;
- rpmsg_dce_conn_object * conn;
- UInt32 addr;
- UInt32 remoteAddr;
- UInt16 procId;
- pid_t pid;
- iofunc_notify_t notify[3];
-} rpmsg_dce_object;
-
-/*!
- * @brief Structure of Event callback argument passed to register fucntion.
- */
-typedef struct rpmsg_dce_EventCbck_tag {
- List_Elem element;
- /*!< List element header */
- rpmsg_dce_object * dce;
- /*!< User ch info pointer. Passed back to user callback function */
-} rpmsg_dce_EventCbck ;
-
-/*!
- * @brief Keeps the information related to Event.
- */
-typedef struct rpmsg_dce_EventState_tag {
- List_Handle bufList;
- /*!< Head of received event list. */
- rpmsg_dce_object *dce;
- /*!< dce instacne. */
- UInt32 refCount;
- /*!< Reference count, used when multiple Notify_registerEvent are called
- from same process space (multi threads/processes). */
- WaitingReaders_t * head;
- /*!< Waiting readers head. */
- WaitingReaders_t * tail;
- /*!< Waiting readers tail. */
-} rpmsg_dce_EventState;
-
-/*!
- * @brief Per-connection information
- */
-typedef struct rpmsg_dce_ocb {
- iofunc_ocb_t hdr;
- pid_t pid;
- rpmsg_dce_object * dce;
-} rpmsg_dce_ocb_t;
-
-/*!
- * @brief rpmsg-dce Module state object
- */
-typedef struct rpmsg_dce_ModuleObject_tag {
- Bool isSetup;
- /*!< Indicates whether the module has been already setup */
- Bool openRefCount;
- /*!< Open reference count. */
- IGateProvider_Handle gateHandle;
- /*!< Handle of gate to be used for local thread safety */
- rpmsg_dce_EventState eventState [MAX_PROCESSES];
- /*!< List for all user processes registered. */
- rpmsg_dce_conn_object * objects [MultiProc_MAXPROCESSORS];
- /*!< List of all remote connections. */
- MessageQCopy_Handle mqHandle;
- /*!< Local mq handle associated with this module */
- UInt32 endpoint;
- /*!< Local endpoint associated with the mq handle */
- MessageQCopy_Handle conn_handle;
- /*!< Local mq conn handle associated with this module */
- UInt32 conn_endpoint;
- /*!< Local endpoint associated with the mq conn handle*/
- UInt32 conn_remote_endpoint;
- /*!< Remote endpoint associated with the mq conn handle*/
- OsalSemaphore_Handle sem;
- /*!< Handle to semaphore used for dce instance connection notifications */
- pthread_t nt;
- /*!< notifier thread */
- pthread_mutex_t lock;
- /*!< protection between notifier and event */
- pthread_cond_t cond;
- /*!< protection between notifier and event */
- MsgList_t *head;
- /*!< list head */
- MsgList_t *tail;
- /*!< list tail */
- int run;
- /*!< notifier thread must keep running */
-} rpmsg_dce_ModuleObject;
-
-/*!
- * @brief Structure of Event Packet read from notify kernel-side.
- */
-typedef struct rpmsg_dce_EventPacket_tag {
- List_Elem element;
- /*!< List element header */
- UInt32 pid;
- /* Processor identifier */
- rpmsg_dce_object * obj;
- /*!< Pointer to the channel associated with this callback */
- UInt32 len;
- /*!< Length of the data associated with event. */
- UInt8 data[MessageQCopy_BUFSIZE];
- /*!< Data associated with event. */
- UInt32 src;
- /*!< Src endpoint associated with event. */
- struct rpmsg_dce_EventPacket * next;
- struct rpmsg_dce_EventPacket * prev;
-} rpmsg_dce_EventPacket ;
-
-
-/** ============================================================================
- * Globals
- * ============================================================================
- */
-/*!
- * @var rpmsg_dce_state
- *
- * @brief rpmsg-dce state object variable
- */
-static rpmsg_dce_ModuleObject rpmsg_dce_state =
-{
- .gateHandle = NULL,
- .isSetup = FALSE,
- .openRefCount = 0,
- .nt = 0,
- .lock = PTHREAD_MUTEX_INITIALIZER,
- .cond = PTHREAD_COND_INITIALIZER,
- .head = NULL,
- .tail = NULL,
- .run = 0
-};
-
-static MsgList_t *nl_cache;
-static int num_nl = 0;
-static WaitingReaders_t *wr_cache;
-static int num_wr = 0;
-
-extern dispatch_t * syslink_dpp;
-
-
-/** ============================================================================
- * Internal functions
- * ============================================================================
- */
-
-/*
- * Instead of constantly allocating and freeing the uBuf structures
- * we just cache a few of them, and recycle them instead.
- * The cache count is set with CACHE_NUM in rpmsg-omxdrv.h.
- */
-static rpmsg_dce_EventPacket *uBuf_cache;
-static int num_uBuf = 0;
-
-static void flush_uBuf()
-{
- rpmsg_dce_EventPacket *uBuf = NULL;
-
- while(uBuf_cache) {
- num_uBuf--;
- uBuf = uBuf_cache;
- uBuf_cache = (rpmsg_dce_EventPacket *)uBuf_cache->next;
- Memory_free(NULL, uBuf, sizeof(*uBuf));
- }
-}
-
-static rpmsg_dce_EventPacket *get_uBuf()
-{
- rpmsg_dce_EventPacket *uBuf;
- uBuf = uBuf_cache;
- if (uBuf != NULL) {
- uBuf_cache = (rpmsg_dce_EventPacket *)uBuf_cache->next;
- num_uBuf--;
- } else {
- uBuf = Memory_alloc(NULL, sizeof(rpmsg_dce_EventPacket), 0, NULL);
- }
- return(uBuf);
-}
-
-static void put_uBuf(rpmsg_dce_EventPacket * uBuf)
-{
- if (num_uBuf >= CACHE_NUM) {
- Memory_free(NULL, uBuf, sizeof(*uBuf));
- } else {
- uBuf->next = (struct rpmsg_dce_EventPacket *)uBuf_cache;
- uBuf_cache = uBuf;
- num_uBuf++;
- }
- return;
-}
-
-/*
- * Instead of constantly allocating and freeing the notifier structures
- * we just cache a few of them, and recycle them instead.
- * The cache count is set with CACHE_NUM in rpmsg-dcedrv.h.
- */
-
-static MsgList_t *get_nl()
-{
- MsgList_t *item;
- item = nl_cache;
- if (item != NULL) {
- nl_cache = nl_cache->next;
- num_nl--;
- } else {
- item = Memory_alloc(NULL, sizeof(MsgList_t), 0, NULL);
- }
- return(item);
-}
-
-static void put_nl(MsgList_t *item)
-{
- if (num_nl >= CACHE_NUM) {
- Memory_free(NULL, item, sizeof(*item));
- } else {
- item->next = nl_cache;
- nl_cache = item;
- num_nl++;
- }
- return;
-}
-
-static WaitingReaders_t *get_wr()
-{
- WaitingReaders_t *item;
- item = wr_cache;
- if (item != NULL) {
- wr_cache = wr_cache->next;
- num_wr--;
- } else {
- item = Memory_alloc(NULL, sizeof(WaitingReaders_t), 0, NULL);
- }
- return(item);
-}
-
-static void put_wr(WaitingReaders_t *item)
-{
- if (num_wr >= CACHE_NUM) {
- Memory_free(NULL, item, sizeof(*item));
- } else {
- item->next = wr_cache;
- wr_cache = item;
- num_wr++;
- }
- return;
-}
-/* The following functions are used for list/waiting reader management */
-static MsgList_t *find_nl(int index)
-{
- MsgList_t *item=NULL;
- item = rpmsg_dce_state.head;
- while (item) {
- if (item->index == index)
- return(item);
- item = item->next;
- }
- return(item);
-}
-
-/* we have the right locks when calling this function */
-/*!
- * @brief Function to enqueue a notify list item.
- *
- * @param index Index of the client process associated with the item.
- *
- * @sa find_nl
- * get_nl
- */
-static int enqueue_notify_list(int index)
-{
- MsgList_t *item;
- item = find_nl(index);
- if (item == NULL) {
- item = get_nl();
- if (item == NULL) {
- return(-1);
- }
- item->next = NULL;
- item->index = index;
- item->num_events=1;
- if (rpmsg_dce_state.head == NULL) {
- rpmsg_dce_state.head = item;
- rpmsg_dce_state.tail = item;
- item->prev = NULL;
- }
- else {
- item->prev = rpmsg_dce_state.tail;
- rpmsg_dce_state.tail->next = item;
- rpmsg_dce_state.tail = item;
- }
- }
- else {
- item->num_events++;
- }
- return(0);
-}
-
-/* we have the right locks when calling this function */
-/*!
- * @brief Function to dequeue a notify list item.
- *
- * @param item The item to remove.
- *
- * @sa put_nl
- */
-static inline int dequeue_notify_list_item(MsgList_t *item)
-{
- int index;
- if (item == NULL) {
- return(-1);
- }
- index = item->index;
- item->num_events--;
- if (item->num_events > 0) {
- return(index);
- }
- if (rpmsg_dce_state.head == item) {
- // removing head
- rpmsg_dce_state.head = item->next;
- if (rpmsg_dce_state.head != NULL) {
- rpmsg_dce_state.head->prev = NULL;
- }
- else {
- // removing head and tail
- rpmsg_dce_state.tail = NULL;
- }
- }
- else {
- item->prev->next = item->next;
- if (item->next != NULL) {
- item->next->prev = item->prev;
- }
- else {
- // removing tail
- rpmsg_dce_state.tail = item->prev;
- }
- }
- put_nl(item);
- return(index);
-}
-
-/* we have the right locks when calling this function */
-/*!
- * @brief Function to add a waiting reader to the list.
- *
- * @param index Index of the client process waiting reader to add.
- * @param rcvid Receive ID of the client process that was passed
- * when the client called read().
- *
- * @sa None
- */
-static int enqueue_waiting_reader(int index, int rcvid)
-{
- WaitingReaders_t *item;
- item = get_wr();
- if (item == NULL) {
- return(-1);
- }
- item->rcvid = rcvid;
- item->next = NULL;
- if (rpmsg_dce_state.eventState [index].head == NULL) {
- rpmsg_dce_state.eventState [index].head = item;
- rpmsg_dce_state.eventState [index].tail = item;
- }
- else {
- rpmsg_dce_state.eventState [index].tail->next = item;
- rpmsg_dce_state.eventState [index].tail = item;
- }
- return(EOK);
-}
-
-/* we have the right locks when calling this function */
-/* caller frees item */
-/*!
- * @brief Function to remove a waiting reader from the list.
- *
- * @param index Index of the client process waiting reader to dequeue.
- *
- * @sa None
- */
-static WaitingReaders_t *dequeue_waiting_reader(int index)
-{
- WaitingReaders_t *item = NULL;
- if (rpmsg_dce_state.eventState [index].head) {
- item = rpmsg_dce_state.eventState [index].head;
- rpmsg_dce_state.eventState [index].head = rpmsg_dce_state.eventState [index].head->next;
- if (rpmsg_dce_state.eventState [index].head == NULL) {
- rpmsg_dce_state.eventState [index].tail = NULL;
- }
- }
- return(item);
-}
-
-/*!
- * @brief Function find a specified waiting reader.
- *
- * @param index Index of the client process waiting for the message.
- * @param rcvid Receive ID of the client process that was passed
- * when the client called read().
- *
- * @sa None
- */
-
-static WaitingReaders_t *find_waiting_reader(int index, int rcvid)
-{
- WaitingReaders_t *item = NULL;
- WaitingReaders_t *prev = NULL;
- if (rpmsg_dce_state.eventState [index].head) {
- item = rpmsg_dce_state.eventState [index].head;
- while (item) {
- if (item->rcvid == rcvid) {
- /* remove item from list */
- if (prev)
- prev->next = item->next;
- if (item == rpmsg_dce_state.eventState [index].head)
- rpmsg_dce_state.eventState [index].head = item->next;
- break;
- }
- else {
- prev = item;
- item = item->next;
- }
- }
- }
- return item;
-}
-
-/*!
- * @brief Function used to check if there is a waiting reader with an
- * event (message) ready to be delivered.
- *
- * @param index Index of the client process waiting for the message.
- * @param item Pointer to the waiting reader.
- *
- * @sa dequeue_notify_list_item
- * dequeue_waiting_reader
- */
-
-static int find_available_reader_and_event(int *index, WaitingReaders_t **item)
-{
- MsgList_t *temp;
- if (rpmsg_dce_state.head == NULL) {
- return(0);
- }
- temp = rpmsg_dce_state.head;
- while (temp) {
- if (rpmsg_dce_state.eventState [temp->index].head) {
- // event and reader found
- if (dequeue_notify_list_item(temp) >= 0) {
- *index = temp->index;
- *item = dequeue_waiting_reader(temp->index);
- }
- else {
- /* error occurred, return 0 as item has not been set */
- return(0);
- }
- return(1);
- }
- temp = temp->next;
- }
- return(0);
-}
-
-/*!
- * @brief Function used to deliver the notification to the client that
- * it has received a message.
- *
- * @param index Index of the client process receiving hte message.
- * @param rcvid Receive ID of the client process that was passed
- * when the client called read().
- *
- * @sa put_uBuf
- */
-
-static void deliver_notification(int index, int rcvid)
-{
- int err = EOK;
- rpmsg_dce_EventPacket * uBuf = NULL;
- struct omx_msg_hdr * hdr = NULL;
-
- uBuf = (rpmsg_dce_EventPacket *) List_get (rpmsg_dce_state.eventState [index].bufList);
- hdr = (struct omx_msg_hdr *)uBuf->data;
-
- /* Let the check remain at run-time. */
- if (uBuf != NULL) {
- err = MsgReply(rcvid, hdr->len, hdr->data, hdr->len);
- if (err == -1)
- perror("deliver_notification: MsgReply");
- /* Free the processed event callback packet. */
- put_uBuf(uBuf);
- }
- else {
- MsgReply(rcvid, EOK, NULL, 0);
- }
- return;
-}
-
-/*!
- * @brief Thread used for notifying waiting readers of messages.
- *
- * @param arg Thread-specific private arg.
- *
- * @sa find_available_reader_and_event
- * deliver_notification
- * put_wr
- */
-static void *notifier_thread(void *arg)
-{
- int status;
- int index;
- WaitingReaders_t *item = NULL;
- pthread_mutex_lock(&rpmsg_dce_state.lock);
- while (rpmsg_dce_state.run) {
- status = find_available_reader_and_event(&index, &item);
- if ( (status == 0) || (item == NULL) ) {
- status = pthread_cond_wait(&rpmsg_dce_state.cond, &rpmsg_dce_state.lock);
- if ((status != EOK) && (status != EINTR)) {
- // false wakeup
- break;
- }
- status = find_available_reader_and_event(&index, &item);
- if ( (status == 0) || (item == NULL) ) {
- continue;
- }
- }
- pthread_mutex_unlock(&rpmsg_dce_state.lock);
- // we have unlocked, and now we have an event to deliver
- // we deliver one event at a time, relock, check and continue
- deliver_notification(index, item->rcvid);
- pthread_mutex_lock(&rpmsg_dce_state.lock);
- put_wr(item);
- }
- pthread_mutex_unlock(&rpmsg_dce_state.lock);
- return(NULL);
-}
-
-
-/*!
- * @brief Attach a process to rpmsg-dce user support framework.
- *
- * @param pid Process identifier
- *
- * @sa _rpmsg_dce_detach
- */
-static
-Int
-_rpmsg_dce_attach (rpmsg_dce_object *dce)
-{
- Int32 status = EOK;
- Bool flag = FALSE;
- Bool isInit = FALSE;
- List_Object * bufList = NULL;
- IArg key = 0;
- List_Params listparams;
- UInt32 i;
-
- GT_1trace (curTrace, GT_ENTER, "_rpmsg_dce_attach", dce);
-
- key = IGateProvider_enter (rpmsg_dce_state.gateHandle);
- for (i = 0 ; (i < MAX_PROCESSES) ; i++) {
- if (rpmsg_dce_state.eventState [i].dce == dce) {
- rpmsg_dce_state.eventState [i].refCount++;
- isInit = TRUE;
- status = EOK;
- break;
- }
- }
-
- if (isInit == FALSE) {
- List_Params_init (&listparams);
- bufList = List_create (&listparams) ;
- /* Search for an available slot for user process. */
- for (i = 0 ; i < MAX_PROCESSES ; i++) {
- if (rpmsg_dce_state.eventState [i].dce == NULL) {
- rpmsg_dce_state.eventState [i].dce = dce;
- rpmsg_dce_state.eventState [i].refCount = 1;
- rpmsg_dce_state.eventState [i].bufList = bufList;
- flag = TRUE;
- break;
- }
- }
-
- /* No free slots found. Let this check remain at run-time,
- * since it is dependent on user environment.
- */
- if (flag != TRUE) {
- /*! @retval Notify_E_RESOURCE Maximum number of
- supported user clients have already been registered. */
- status = -ENOMEM;
- GT_setFailureReason (curTrace,
- GT_4CLASS,
- "rpmsgDrv_attach",
- status,
- "Maximum number of supported user"
- " clients have already been "
- "registered.");
- if (bufList != NULL) {
- List_delete (&bufList);
- }
- }
- }
- IGateProvider_leave (rpmsg_dce_state.gateHandle, key);
-
- GT_1trace (curTrace, GT_LEAVE, "rpmsgDrv_attach", status);
-
- /*! @retval Notify_S_SUCCESS Operation successfully completed. */
- return status ;
-}
-
-
- /*!
- * @brief This function adds a data to a registered process.
- *
- * @param dce Dce object associated with the client
- * @param src Source address (endpoint) sending the data
- * @param pid Process ID associated with the client
- * @param data Data to be added
- * @param len Length of data to be added
- *
- * @sa
- */
-Int
-_rpmsg_dce_addBufByPid (rpmsg_dce_object *dce,
- UInt32 src,
- UInt32 pid,
- void * data,
- UInt32 len)
-{
- Int32 status = EOK;
- Bool flag = FALSE;
- rpmsg_dce_EventPacket * uBuf = NULL;
- IArg key;
- UInt32 i;
- WaitingReaders_t *item;
- MsgList_t *msgItem;
-
- GT_5trace (curTrace,
- GT_ENTER,
- "_rpmsg_dce_addBufByPid",
- dce,
- src,
- pid,
- data,
- len);
-
- GT_assert (curTrace, (rpmsg_dce_state.isSetup == TRUE));
-
- key = IGateProvider_enter (rpmsg_dce_state.gateHandle);
- /* Find the registration for this callback */
- for (i = 0 ; i < MAX_PROCESSES ; i++) {
- if (rpmsg_dce_state.eventState [i].dce == dce) {
- flag = TRUE;
- break;
- }
- }
- IGateProvider_leave (rpmsg_dce_state.gateHandle, key);
-
-#if !defined(SYSLINK_BUILD_OPTIMIZE)
- if (flag != TRUE) {
- /*! @retval ENOMEM Could not find a registered handler
- for this process. */
- status = -ENOMEM;
- GT_setFailureReason (curTrace,
- GT_4CLASS,
- "_rpmsgDrv_addBufByPid",
- status,
- "Could not find a registered handler "
- "for this process.!");
- }
- else {
-#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
- /* Allocate memory for the buf */
- pthread_mutex_lock(&rpmsg_dce_state.lock);
- uBuf = get_uBuf();
- pthread_mutex_unlock(&rpmsg_dce_state.lock);
-
-#if !defined(SYSLINK_BUILD_OPTIMIZE)
- if (uBuf == NULL) {
- /*! @retval Notify_E_MEMORY Failed to allocate memory for event
- packet for received callback. */
- status = -ENOMEM;
- GT_setFailureReason (curTrace,
- GT_4CLASS,
- "_rpmsgDrv_addBufByPid",
- status,
- "Failed to allocate memory for event"
- " packet for received callback.!");
- }
- else {
-#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
- List_elemClear (&(uBuf->element));
- GT_assert (curTrace,
- (rpmsg_dce_state.eventState [i].bufList != NULL));
-
- if (data) {
- Memory_copy(uBuf->data, data, len);
- }
- uBuf->len = len;
-
- List_put (rpmsg_dce_state.eventState [i].bufList,
- &(uBuf->element));
- pthread_mutex_lock(&rpmsg_dce_state.lock);
- item = dequeue_waiting_reader(i);
- if (item) {
- // there is a waiting reader
- deliver_notification(i, item->rcvid);
- put_wr(item);
- pthread_mutex_unlock(&rpmsg_dce_state.lock);
- status = EOK;
- }
- else {
- if (enqueue_notify_list(i) < 0) {
- pthread_mutex_unlock(&rpmsg_dce_state.lock);
- status = -ENOMEM;
- GT_setFailureReason (curTrace,
- GT_4CLASS,
- "_rpmsgDrv_addBufByPid",
- status,
- "Failed to allocate memory for notifier");
- }
- else {
- msgItem = find_nl(i);
- /* TODO: dce could be NULL in some cases */
- if (dce && msgItem) {
- if (IOFUNC_NOTIFY_INPUT_CHECK(dce->notify, msgItem->num_events, 0)) {
- iofunc_notify_trigger(dce->notify, msgItem->num_events, IOFUNC_NOTIFY_INPUT);
- }
- }
- status = EOK;
- pthread_cond_signal(&rpmsg_dce_state.cond);
- pthread_mutex_unlock(&rpmsg_dce_state.lock);
- }
- }
-#if !defined(SYSLINK_BUILD_OPTIMIZE)
- }
- }
-#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
-
- GT_1trace (curTrace, GT_LEAVE, "_rpmsgDrv_addBufByPid", status);
-
- return status;
-}
-
-
-/*!
- * @brief This function implements the callback registered with
- * MessageQCopy_create for each client. This function
- * adds the message from the remote proc to a list
- * where it is routed to the appropriate waiting reader.
- *
- * @param procId processor Id from which interrupt is received
- * @param lineId Interrupt line ID to be used
- * @param eventId eventId registered
- * @param arg argument to call back
- * @param payload payload received
- *
- * @sa
- */
-Void
-_rpmsg_dce_cb (MessageQCopy_Handle handle, void * data, int len, void * priv, UInt32 src, UInt16 srcProc)
-{
-#if !defined(SYSLINK_BUILD_OPTIMIZE)
- Int32 status = 0;
-#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
- rpmsg_dce_object * dce = NULL;
- struct omx_msg_hdr * msg_hdr = NULL;
-
- GT_6trace (curTrace,
- GT_ENTER,
- "_rpmsg_dce_cb",
- handle,
- data,
- len,
- priv,
- src,
- srcProc);
-
- dce = (rpmsg_dce_object *) priv;
- msg_hdr = (struct omx_msg_hdr *)data;
-
- switch (msg_hdr->type) {
- case OMX_RAW_MSG:
-#if !defined(SYSLINK_BUILD_OPTIMIZE)
- status =
-#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
- _rpmsg_dce_addBufByPid (dce,
- src,
- dce->pid,
- data,
- len);
-#if !defined(SYSLINK_BUILD_OPTIMIZE)
- if (status < 0) {
- GT_setFailureReason (curTrace,
- GT_4CLASS,
- "_rpmsg_dce_cb",
- status,
- "Failed to add callback packet for pid");
- }
-#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
- break;
- default:
- break;
- }
-
- GT_0trace (curTrace, GT_LEAVE, "_rpmsg_dce_cb");
-}
-
- /**
- * Handler for ocb_calloc() requests.
- *
- * Special handler for ocb_calloc() requests that we export for control. An
- * open request from the client will result in a call to our special ocb_calloc
- * handler. This function attaches the client's pid using _rpmsg_dce_attach
- * and allocates client-specific information. This function creates an
- * endpoint for the client to communicate with the dCE server on the
- * remote core also.
- *
- * \param ctp Thread's associated context information.
- * \param device Device attributes structure.
- *
- * \return Pointer to an iofunc_ocb_t OCB structure.
- */
-
-IOFUNC_OCB_T *
-rpmsg_dce_ocb_calloc (resmgr_context_t * ctp, IOFUNC_ATTR_T * device)
-{
- rpmsg_dce_ocb_t *ocb = NULL;
- rpmsg_dce_object *obj = NULL;
- struct _msg_info cl_info;
- rpmsg_dce_dev_t * dev = NULL;
- int i = 0;
- Bool found = FALSE;
- char path1[20];
- char path2[20];
- Char data[MessageQCopy_BUFSIZE];
- dce_conn_req *req = (dce_conn_req *)data;
- Int status = 0;
-
- GT_2trace (curTrace, GT_ENTER, "rpmsg_dce_ocb_calloc",
- ctp, device);
-
- /* Allocate the OCB */
- ocb = (rpmsg_dce_ocb_t *) calloc (1, sizeof (rpmsg_dce_ocb_t));
- if (ocb == NULL){
- errno = ENOMEM;
- return (NULL);
- }
-
- ocb->pid = ctp->info.pid;
-
- /* Allocate memory for the rpmsg object. */
- obj = Memory_calloc (NULL, sizeof (rpmsg_dce_object), 0u, NULL);
- if (obj == NULL) {
- errno = ENOMEM;
- free(ocb);
- return (NULL);
- }
- else {
- ocb->dce = obj;
- IOFUNC_NOTIFY_INIT(obj->notify);
- /* determine conn and procId for communication based on which device was opened */
- MsgInfo(ctp->rcvid, &cl_info);
- resmgr_pathname(ctp->id, 0, path1, sizeof(path1));
- for (i = 0; i < MultiProc_MAXPROCESSORS; i++) {
- if (rpmsg_dce_state.objects[i] != NULL) {
- dev = rpmsg_dce_state.objects[i]->dev;
- resmgr_pathname(dev->rpmsg_dce.resmgr_id, 0, path2, sizeof(path2));
- if (!strcmp(path1, path2)) {
- found = TRUE;
- break;
- }
- }
- }
- if (found) {
- obj->conn = rpmsg_dce_state.objects[i];
- obj->procId = obj->conn->procId;
- obj->pid = ctp->info.pid;
- obj->mq = MessageQCopy_create (MessageQCopy_ADDRANY, NULL, _rpmsg_dce_cb, obj, &obj->addr);
- if (obj->mq == NULL) {
- errno = ENOMEM;
- free(obj);
- free(ocb);
- return (NULL);
- }
- else {
- if (_rpmsg_dce_attach (obj) < 0) {
- errno = ENOMEM;
- MessageQCopy_delete (&obj->mq);
- free(obj);
- free(ocb);
- return (NULL);
- }
- else {
- req->type = DCE_CONN_REQ;
- req->addr = obj->addr;
- status = MessageQCopy_send(obj->procId, MultiProc_self(),
- rpmsg_dce_state.conn_remote_endpoint,
- rpmsg_dce_state.conn_endpoint, req,
- sizeof(dce_conn_req), TRUE);
- if (status < 0) {
- errno = ENOMEM;
- MessageQCopy_delete (&obj->mq);
- free(obj);
- free(ocb);
- return (NULL);
- }
- else {
- status = OsalSemaphore_pend(rpmsg_dce_state.sem, 5000);
- if (status < 0) {
- errno = ENOMEM;
- MessageQCopy_delete (&obj->mq);
- free(obj);
- free(ocb);
- return (NULL);
- }
- }
- }
- }
- }
- }
-
- GT_1trace (curTrace, GT_LEAVE, "rpmsg_dce_ocb_calloc", ocb);
-
- return (IOFUNC_OCB_T *)(ocb);
-}
-
-
-/*!
- * @brief Detach a process from rpmsg-dce user support framework.
- *
- * @param pid Process identifier
- *
- * @sa _rpmsg_dce_attach
- */
-static
-Int
-_rpmsg_dce_detach (rpmsg_dce_object *dce, Bool force)
-{
- Int32 status = EOK;
- Int32 tmpStatus = EOK;
- Bool flag = FALSE;
- List_Object * bufList = NULL;
- UInt32 i;
- IArg key;
- MsgList_t * item;
- WaitingReaders_t * wr = NULL;
- struct _msg_info info;
-
- GT_1trace (curTrace, GT_ENTER, "rpmsg_dce_detach", dce);
-
- key = IGateProvider_enter (rpmsg_dce_state.gateHandle);
-
- for (i = 0 ; i < MAX_PROCESSES ; i++) {
- if (rpmsg_dce_state.eventState [i].dce == dce) {
- if (rpmsg_dce_state.eventState [i].refCount == 1) {
- rpmsg_dce_state.eventState [i].refCount = 0;
-
- flag = TRUE;
- break;
- }
- else {
- rpmsg_dce_state.eventState [i].refCount--;
- status = EOK;
- break;
- }
- }
- }
- IGateProvider_leave (rpmsg_dce_state.gateHandle, key);
-
- if (flag == TRUE) {
- key = IGateProvider_enter (rpmsg_dce_state.gateHandle);
- /* Last client being unregistered for this process. */
- rpmsg_dce_state.eventState [i].dce = NULL;
-
- /* Store in local variable to delete outside lock. */
- bufList = rpmsg_dce_state.eventState [i].bufList;
-
- rpmsg_dce_state.eventState [i].bufList = NULL;
-
- IGateProvider_leave (rpmsg_dce_state.gateHandle, key);
- }
-
- if (flag != TRUE) {
-#if !defined(SYSLINK_BUILD_OPTIMIZE)
- if (i == MAX_PROCESSES) {
- /*! @retval Notify_E_NOTFOUND The specified user process was
- not found registered with Notify Driver module. */
- status = -ENOMEM;
- GT_setFailureReason (curTrace,
- GT_4CLASS,
- "rpmsg_dce_detach",
- status,
- "The specified user process was not found"
- " registered with rpmsg Driver module.");
- }
-#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
- }
- else {
- if (bufList != NULL) {
- /* Dequeue waiting readers and reply to them */
- pthread_mutex_lock(&rpmsg_dce_state.lock);
- while ((wr = dequeue_waiting_reader(i)) != NULL) {
- /* Check if rcvid is still valid */
- if (MsgInfo(wr->rcvid, &info) != -1) {
- put_wr(wr);
- pthread_mutex_unlock(&rpmsg_dce_state.lock);
- MsgError(wr->rcvid, EINTR);
- pthread_mutex_lock(&rpmsg_dce_state.lock);
- }
- }
- /* Check for pending ionotify/select calls */
- if (dce) {
- if (IOFUNC_NOTIFY_INPUT_CHECK(dce->notify, 1, 0)) {
- iofunc_notify_trigger(dce->notify, 1, IOFUNC_NOTIFY_INPUT);
- }
- }
-
- /* Free event packets for any received but unprocessed events. */
- while ((item = find_nl(i)) != NULL) {
- if (dequeue_notify_list_item(item) >= 0) {
- rpmsg_dce_EventPacket * uBuf = NULL;
-
- uBuf = (rpmsg_dce_EventPacket *) List_get (bufList);
-
- /* Let the check remain at run-time. */
- if (uBuf != NULL) {
- put_uBuf(uBuf);
- }
- }
- }
- pthread_mutex_unlock(&rpmsg_dce_state.lock);
-
- /* Last client being unregistered with Notify module. */
- List_delete (&bufList);
- }
-
-#if !defined(SYSLINK_BUILD_OPTIMIZE)
- if ((tmpStatus < 0) && (status >= 0)) {
- status = tmpStatus;
- GT_setFailureReason (curTrace,
- GT_4CLASS,
- "rpmsg_dce_detach",
- status,
- "Failed to delete termination semaphore!");
- }
-#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
- }
-
- GT_1trace (curTrace, GT_LEAVE, "rpmsg_dce_detach", status);
-
- /*! @retval Notify_S_SUCCESS Operation successfully completed */
- return status;
-}
-
- /**
- * Handler for ocb_free() requests.
- *
- * Special handler for ocb_free() requests that we export for control. A
- * close request from the client will result in a call to our special ocb_free
- * handler. This function detaches the client's pid using _rpmsg_dce_detach
- * and frees any client-specific information that was allocated.
- *
- * \param i_ocb OCB associated with client's session.
- *
- * \return POSIX errno value.
- *
- * \retval None.
- */
-
-void
-rpmsg_dce_ocb_free (IOFUNC_OCB_T * i_ocb)
-{
- rpmsg_dce_ocb_t * ocb = (rpmsg_dce_ocb_t *)i_ocb;
- rpmsg_dce_object *obj;
- Char data[MessageQCopy_BUFSIZE];
- dce_conn_req *req = (dce_conn_req *)data;
- Int status = 0;
-
- if (ocb && ocb->dce) {
- obj = ocb->dce;
- req->type = DCE_DISCON_REQ;
- req->addr = obj->addr;
- status = MessageQCopy_send(obj->procId, MultiProc_self(),
- rpmsg_dce_state.conn_remote_endpoint,
- rpmsg_dce_state.conn_endpoint, req,
- sizeof(dce_conn_req), TRUE);
- if (status < 0) {
- GT_setFailureReason (curTrace,
- GT_4CLASS,
- "rpmsg_dce_ocb_free",
- status,
- "Failed to send disconnect msg!");
- }
- _rpmsg_dce_detach(ocb->dce, FALSE);
- if (obj->mq) {
- MessageQCopy_delete (&obj->mq);
- obj->mq = NULL;
- }
- free (obj);
- free (ocb);
- }
-}
-
- /**
- * Handler for close_ocb() requests.
- *
- * This function removes the notification entries associated with the current
- * client.
- *
- * \param ctp Thread's associated context information.
- * \param reserved This argument must be NULL.
- * \param ocb OCB associated with client's session.
- *
- * \return POSIX errno value.
- *
- * \retval EOK Success.
- */
-
-Int
-rpmsg_dce_close_ocb (resmgr_context_t *ctp, void *reserved, RESMGR_OCB_T *ocb)
-{
- rpmsg_dce_ocb_t * dce_ocb = (rpmsg_dce_ocb_t *)ocb;
- iofunc_notify_remove(ctp, dce_ocb->dce->notify);
- return (iofunc_close_ocb_default(ctp, reserved, ocb));
-}
-
- /**
- * Handler for read() requests.
- *
- * Handles special read() requests that we export for control. A read
- * request will get a message from the remote processor that is associated
- * with the client that is calling read().
- *
- * \param ctp Thread's associated context information.
- * \param msg The actual read() message.
- * \param ocb OCB associated with client's session.
- *
- * \return POSIX errno value.
- *
- * \retval EOK Success.
- * \retval EAGAIN Call is non-blocking and no messages available.
- * \retval ENOMEM Not enough memory to preform the read.
- */
-
-int rpmsg_dce_read(resmgr_context_t *ctp, io_read_t *msg, RESMGR_OCB_T *i_ocb)
-{
- Int status;
- Bool flag = FALSE;
- Int retVal = EOK;
- UInt32 i;
- MsgList_t * item;
- Int nonblock;
- rpmsg_dce_ocb_t * ocb = (rpmsg_dce_ocb_t *)i_ocb;
- rpmsg_dce_object * dce = ocb->dce;
-
- if ((status = iofunc_read_verify(ctp, msg, i_ocb, &nonblock)) != EOK)
- return (status);
-
- for (i = 0 ; i < MAX_PROCESSES ; i++) {
- if (rpmsg_dce_state.eventState [i].dce == dce) {
- flag = TRUE;
- break;
- }
- }
-
- /* Let the check remain at run-time. */
- if (flag == TRUE) {
- /* Let the check remain at run-time for handling any run-time
- * race conditions.
- */
- if (rpmsg_dce_state.eventState [i].bufList != NULL) {
- pthread_mutex_lock(&rpmsg_dce_state.lock);
- item = find_nl(i);
- if (dequeue_notify_list_item(item) < 0) {
- if (nonblock) {
- pthread_mutex_unlock(&rpmsg_dce_state.lock);
- return EAGAIN;
- }
- else {
- retVal = enqueue_waiting_reader(i, ctp->rcvid);
- if (retVal == EOK) {
- pthread_cond_signal(&rpmsg_dce_state.cond);
- pthread_mutex_unlock(&rpmsg_dce_state.lock);
- return(_RESMGR_NOREPLY);
- }
- retVal = ENOMEM;
- pthread_mutex_unlock(&rpmsg_dce_state.lock);
- }
- }
- else {
- deliver_notification(i, ctp->rcvid);
- pthread_mutex_unlock(&rpmsg_dce_state.lock);
- return(_RESMGR_NOREPLY);
- }
- }
- }
-
- /*! @retval Number-of-bytes-read Number of bytes read. */
- return retVal;
-}
-
- /**
- * Handler for write() requests.
- *
- * Handles special write() requests that we export for control. A write()
- * request will send a message to the remote processor which is associated with
- * the client.
- *
- * \param ctp Thread's associated context information.
- * \param msg The actual write() message.
- * \param io_ocb OCB associated with client's session.
- *
- * \return POSIX errno value.
- *
- * \retval EOK Success.
- * \retval ENOMEM Not enough memory to preform the write.
- * \retval EIO MessageQCopy_send failed.
- * \retval EINVAL msg->i.bytes is negative.
- */
-
-int
-rpmsg_dce_write(resmgr_context_t *ctp, io_write_t *msg, RESMGR_OCB_T *io_ocb)
-{
- int status;
- char *buf;
- int bytes;
- rpmsg_dce_ocb_t * ocb = (rpmsg_dce_ocb_t *)io_ocb;
- rpmsg_dce_object * dce = ocb->dce;
- struct omx_msg_hdr * msg_hdr = NULL;
-
- if ((status = iofunc_write_verify(ctp, msg, io_ocb, NULL)) != EOK) {
- return (status);
- }
-
- bytes = ((int64_t) msg->i.nbytes) + sizeof(struct omx_msg_hdr) > MessageQCopy_BUFSIZE ?
- MessageQCopy_BUFSIZE - sizeof(struct omx_msg_hdr) : msg->i.nbytes;
- if (bytes < 0) {
- return EINVAL;
- }
- _IO_SET_WRITE_NBYTES (ctp, bytes);
-
- buf = (char *) malloc(bytes + sizeof(struct omx_msg_hdr));
- if (buf == NULL) {
- return (ENOMEM);
- }
- msg_hdr = (struct omx_msg_hdr *)buf;
-
- status = resmgr_msgread(ctp, msg_hdr->data, bytes, sizeof(msg->i));
- if (status != bytes) {
- free(buf);
- return (errno);
- }
-
- msg_hdr->type = OMX_RAW_MSG;
- msg_hdr->len = bytes;
-
- status = MessageQCopy_send(dce->conn->procId, MultiProc_self(),
- dce->conn->addr, dce->addr, buf,
- bytes + sizeof(struct omx_msg_hdr), TRUE);
- if (status < 0) {
- free(buf);
- return (EIO);
- }
- free (buf);
-
- return(EOK);
-}
-
-static
-Int
-_rpmsg_dce_getaddr(resmgr_context_t *ctp, io_devctl_t *msg, rpmsg_dce_ocb_t *ocb)
-{
- Int status = EOK;
- UInt32 * cargs = (UInt32 *)(_DEVCTL_DATA (msg->o));
- rpmsg_dce_object * dce = ocb->dce;
-
- if (ctp->info.dstmsglen - sizeof(msg->o) < sizeof (UInt32)) {
- status = (EINVAL);
- }
-
- else {
- *cargs = dce->addr;
- msg->o.ret_val = EOK;
- status = (_RESMGR_PTR(ctp, &msg->o, sizeof(msg->o) + sizeof(UInt32)));
- }
-
- return status;
-}
-
-Int
-rpmsg_dce_devctl(resmgr_context_t *ctp, io_devctl_t *msg, IOFUNC_OCB_T *i_ocb)
-{
- Int status = 0;
- rpmsg_dce_ocb_t *ocb = (rpmsg_dce_ocb_t *)i_ocb;
-
- if ((status = iofunc_devctl_default(ctp, msg, &ocb->hdr)) != _RESMGR_DEFAULT)
- return(_RESMGR_ERRNO(status));
- status = 0;
-
- switch (msg->i.dcmd)
- {
- case DCE_IOCGETADDR:
- status = _rpmsg_dce_getaddr (ctp, msg, ocb);
- break;
- default:
- status = (ENOSYS);
- break;
- }
-
- return status;
-}
- /**
- * Unblock read calls
- *
- * This function checks if the client is blocked on a read call and if so,
- * unblocks the client.
- *
- * \param ctp Thread's associated context information.
- * \param msg The pulse message.
- * \param ocb OCB associated with client's session.
- *
- * \return POSIX errno value.
- *
- * \retval EINTR The client has been unblocked.
- * \retval other The client has not been unblocked or the client was not
- * blocked.
- */
-
-int rpmsg_dce_read_unblock(resmgr_context_t *ctp, io_pulse_t *msg, iofunc_ocb_t *i_ocb)
-{
- UInt32 i;
- Bool flag = FALSE;
- WaitingReaders_t * wr;
- rpmsg_dce_ocb_t * ocb = (rpmsg_dce_ocb_t *)i_ocb;
- rpmsg_dce_object * dce = ocb->dce;
-
- for (i = 0 ; i < MAX_PROCESSES ; i++) {
- if (rpmsg_dce_state.eventState [i].dce == dce) {
- flag = TRUE;
- break;
- }
- }
-
- /* Let the check remain at run-time. */
- if (flag == TRUE) {
- /* Let the check remain at run-time for handling any run-time
- * race conditions.
- */
- if (rpmsg_dce_state.eventState [i].bufList != NULL) {
- pthread_mutex_lock(&rpmsg_dce_state.lock);
- wr = find_waiting_reader(i, ctp->rcvid);
- if (wr) {
- put_wr(wr);
- pthread_mutex_unlock(&rpmsg_dce_state.lock);
- return (EINTR);
- }
- pthread_mutex_unlock(&rpmsg_dce_state.lock);
- }
- }
-
- return _RESMGR_NOREPLY;
-}
-
- /**
- * Handler for unblock() requests.
- *
- * Handles unblock request for the client which is requesting to no longer be
- * blocked on the rpmsg-dce driver.
- *
- * \param ctp Thread's associated context information.
- * \param msg The pulse message.
- * \param ocb OCB associated with client's session.
- *
- * \return POSIX errno value.
- *
- * \retval EINTR The rcvid has been unblocked.
- */
-
-int rpmsg_dce_unblock(resmgr_context_t *ctp, io_pulse_t *msg, RESMGR_OCB_T *ocb)
-{
- int status = _RESMGR_NOREPLY;
- struct _msg_info info;
-
- /*
- * Try to run the default unblock for this message.
- */
- if ((status = iofunc_unblock_default(ctp,msg, ocb)) != _RESMGR_DEFAULT) {
- return status;
- }
-
- /*
- * Check if rcvid is still valid and still has an unblock
- * request pending.
- */
- if (MsgInfo(ctp->rcvid, &info) == -1 ||
- !(info.flags & _NTO_MI_UNBLOCK_REQ)) {
- return _RESMGR_NOREPLY;
- }
-
- if (rpmsg_dce_read_unblock(ctp, msg, ocb) != _RESMGR_NOREPLY) {
- return _RESMGR_ERRNO(EINTR);
- }
-
- return _RESMGR_ERRNO(EINTR);
-}
-
- /**
- * Handler for notify() requests.
- *
- * Handles special notify() requests that we export for control. A notify
- * request results from the client calling select().
- *
- * \param ctp Thread's associated context information.
- * \param msg The actual notify() message.
- * \param ocb OCB associated with client's session.
- *
- * \return POSIX errno value.
- */
-
-Int rpmsg_dce_notify( resmgr_context_t *ctp, io_notify_t *msg, RESMGR_OCB_T *ocb)
-{
- rpmsg_dce_ocb_t * dce_ocb = (rpmsg_dce_ocb_t *)ocb;
- int trig;
- int i = 0;
- Bool flag = FALSE;
- MsgList_t * item = NULL;
- int status = EOK;
- rpmsg_dce_object * dce = dce_ocb->dce;
-
- trig = _NOTIFY_COND_OUTPUT; /* clients can give us data */
-
- for (i = 0 ; i < MAX_PROCESSES ; i++) {
- if (rpmsg_dce_state.eventState [i].dce == dce) {
- flag = TRUE;
- break;
- }
- }
-
- pthread_mutex_lock(&rpmsg_dce_state.lock);
- /* Let the check remain at run-time. */
- if (flag == TRUE) {
- /* Let the check remain at run-time for handling any run-time
- * race conditions.
- */
- if (rpmsg_dce_state.eventState [i].bufList != NULL) {
- item = find_nl(i);
- if (item && item->num_events > 0) {
- trig |= _NOTIFY_COND_INPUT;
- }
- }
- }
- status = iofunc_notify(ctp, msg, dce_ocb->dce->notify, trig, NULL, NULL);
- pthread_mutex_unlock(&rpmsg_dce_state.lock);
- return status;
-}
-
- /**
- * Detaches an rpmsg-dce resource manager device name.
- *
- * \param dev The device to detach.
- *
- * \return POSIX errno value.
- */
-
-static
-Void
-_deinit_rpmsg_dce_device (rpmsg_dce_dev_t * dev)
-{
- resmgr_detach(syslink_dpp, dev->rpmsg_dce.resmgr_id, 0);
-
- pthread_mutex_destroy(&dev->rpmsg_dce.mutex);
-
- free (dev);
-
- return;
-}
-
- /**
- * Initializes and attaches rpmsg-dce resource manager functions to an
- * rpmsg-dce device name.
- *
- * \param num The number to append to the end of the device name.
- *
- * \return Pointer to the created rpmsg_dce_dev_t device.
- */
-
-static
-rpmsg_dce_dev_t *
-_init_rpmsg_dce_device (int num)
-{
- iofunc_attr_t * attr;
- resmgr_attr_t resmgr_attr;
- rpmsg_dce_dev_t * dev = NULL;
-
- dev = malloc(sizeof(*dev));
- if (dev == NULL) {
- return NULL;
- }
-
- memset(&resmgr_attr, 0, sizeof resmgr_attr);
- resmgr_attr.nparts_max = 10;
- resmgr_attr.msg_max_size = 2048;
- memset(&dev->rpmsg_dce.mattr, 0, sizeof(iofunc_mount_t));
- dev->rpmsg_dce.mattr.flags = ST_NOSUID | ST_NOEXEC;
- dev->rpmsg_dce.mattr.conf = IOFUNC_PC_CHOWN_RESTRICTED |
- IOFUNC_PC_NO_TRUNC |
- IOFUNC_PC_SYNC_IO;
- dev->rpmsg_dce.mattr.funcs = &dev->rpmsg_dce.mfuncs;
- memset(&dev->rpmsg_dce.mfuncs, 0, sizeof(iofunc_funcs_t));
- dev->rpmsg_dce.mfuncs.nfuncs = _IOFUNC_NFUNCS;
- dev->rpmsg_dce.mfuncs.ocb_calloc = rpmsg_dce_ocb_calloc;
- dev->rpmsg_dce.mfuncs.ocb_free = rpmsg_dce_ocb_free;
- iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &dev->rpmsg_dce.cfuncs,
- _RESMGR_IO_NFUNCS, &dev->rpmsg_dce.iofuncs);
- iofunc_attr_init(attr = &dev->rpmsg_dce.cattr, S_IFCHR | 0777, NULL, NULL);
- dev->rpmsg_dce.iofuncs.unblock = rpmsg_dce_unblock;
- dev->rpmsg_dce.iofuncs.devctl = rpmsg_dce_devctl;
- dev->rpmsg_dce.iofuncs.notify = rpmsg_dce_notify;
- dev->rpmsg_dce.iofuncs.close_ocb = rpmsg_dce_close_ocb;
- dev->rpmsg_dce.iofuncs.read = rpmsg_dce_read;
- dev->rpmsg_dce.iofuncs.write = rpmsg_dce_write;
- attr->mount = &dev->rpmsg_dce.mattr;
- iofunc_time_update(attr);
- pthread_mutex_init(&dev->rpmsg_dce.mutex, NULL);
-
- snprintf (dev->rpmsg_dce.device_name, _POSIX_PATH_MAX, "/dev/rpmsg-dce%d", num);
- if (-1 == (dev->rpmsg_dce.resmgr_id =
- resmgr_attach(syslink_dpp, &resmgr_attr,
- dev->rpmsg_dce.device_name, _FTYPE_ANY, 0,
- &dev->rpmsg_dce.cfuncs,
- &dev->rpmsg_dce.iofuncs, attr))) {
- pthread_mutex_destroy(&dev->rpmsg_dce.mutex);
- free(dev);
- return(NULL);
- }
-
- return(dev);
-}
-
-/**
- * Callback passed to MessageQCopy_registerNotify.
- *
- * This callback is called when a remote processor creates a MessageQCopy
- * handle with the same name as the local MessageQCopy handle and then
- * calls NameMap_register to notify the HOST of the handle.
- *
- * \param handle The remote handle.
- * \param procId The remote proc ID of the remote handle.
- * \param endpoint The endpoint address of the remote handle.
- *
- * \return None.
- */
-
-static
-Void
-_rpmsg_dce_notify_cb (MessageQCopy_Handle handle, UInt16 procId,
- UInt32 endpoint, Char * desc, Bool create)
-{
- Int i = 0;
- Bool found = FALSE;
- rpmsg_dce_conn_object * obj = NULL;
-
- for (i = 0; i < MultiProc_MAXPROCESSORS; i++) {
- if (rpmsg_dce_state.objects[i] == NULL) {
- found = TRUE;
- break;
- }
- }
-
- if (found) {
- /* found a space to save this mq handle, allocate memory */
- obj = Memory_calloc (NULL, sizeof (rpmsg_dce_conn_object), 0x0, NULL);
- if (obj) {
- /* store the object in the module info */
- rpmsg_dce_state.objects[i] = obj;
-
- /* store the mq info in the object */
- obj->mq = handle;
- obj->procId = procId;
- obj->addr = endpoint;
-
- /* create a /dev/rpmsg-dce instance for users to open */
- obj->dev = _init_rpmsg_dce_device(i);
- if (obj->dev == NULL) {
- Osal_printf("Failed to create rpmsg-dce%d", i);
- Memory_free(NULL, obj, sizeof(rpmsg_dce_object));
- }
- }
- }
-}
-
-static
-Void
-_rpmsg_dce_conn_notify_cb (MessageQCopy_Handle handle, UInt16 procId,
- UInt32 endpoint, Char * desc, Bool create)
-{
- rpmsg_dce_state.conn_remote_endpoint = endpoint;
-}
-
- /**
- * Callback passed to MessageQCopy_create for the module.
- *
- * This callback is called when a message is received for the rpmsg-dce
- * module. This callback will never be called, since each client connection
- * gets it's own endpoint for message passing.
- *
- * \param handle The local MessageQCopy handle.
- * \param data Data message
- * \param len Length of data message
- * \param priv Private information for the endpoint
- * \param src Remote endpoint sending this message
- * \param srcProc Remote proc ID sending this message
- *
- * \return None.
- */
-
-static
-Void
-_rpmsg_dce_module_cb (MessageQCopy_Handle handle, void * data, int len,
- void * priv, UInt32 src, UInt16 srcProc)
-{
- Osal_printf ("_rpmsg_dce_module_cb callback");
-}
-
-/**
- * Callback passed to MessageQCopy_create for the module conn handler.
- *
- * This callback is called when a message is received for the rpmsg-dce
- * conn addr. This callback will never be called, since the remote endpoint
- * never sends a response.
- *
- * \param handle The local MessageQCopy handle.
- * \param data Data message
- * \param len Length of data message
- * \param priv Private information for the endpoint
- * \param src Remote endpoint sending this message
- * \param srcProc Remote proc ID sending this message
- *
- * \return None.
- */static
-Void
-_rpmsg_dce_conn_cb (MessageQCopy_Handle handle, void * data, int len,
- void * priv, UInt32 src, UInt16 srcProc)
-{
- Osal_printf ("_rpmsg_dce_conn_cb callback");
- OsalSemaphore_post(rpmsg_dce_state.sem);
-}
-
-/*!
- * @brief Module setup function.
- *
- * @sa rpmsg_dce_destroy
- */
-Int
-rpmsg_dce_setup (Void)
-{
- UInt16 i;
- List_Params listparams;
- Int status = 0;
- Error_Block eb;
- pthread_attr_t thread_attr;
- struct sched_param sched_param;
-
- GT_0trace (curTrace, GT_ENTER, "rpmsg_dce_setup");
-
- Error_init(&eb);
-
- List_Params_init (&listparams);
- rpmsg_dce_state.gateHandle = (IGateProvider_Handle)
- GateSpinlock_create ((GateSpinlock_Handle) NULL, &eb);
-#if !defined(SYSLINK_BUILD_OPTIMIZE)
- if (rpmsg_dce_state.gateHandle == NULL) {
- status = -ENOMEM;
- GT_setFailureReason (curTrace,
- GT_4CLASS,
- "_rpmsg_dce_setup",
- status,
- "Failed to create spinlock gate!");
- }
- else {
-#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
- for (i = 0 ; i < MAX_PROCESSES ; i++) {
- rpmsg_dce_state.eventState [i].bufList = NULL;
- rpmsg_dce_state.eventState [i].dce = NULL;
- rpmsg_dce_state.eventState [i].refCount = 0;
- rpmsg_dce_state.eventState [i].head = NULL;
- rpmsg_dce_state.eventState [i].tail = NULL;
- }
-
- pthread_attr_init(&thread_attr );
- sched_param.sched_priority = PRIORITY_REALTIME_LOW;
- pthread_attr_setinheritsched(&thread_attr, PTHREAD_EXPLICIT_SCHED);
- pthread_attr_setschedpolicy(&thread_attr, SCHED_RR);
- pthread_attr_setschedparam(&thread_attr, &sched_param);
-
- rpmsg_dce_state.run = TRUE;
- if (pthread_create(&rpmsg_dce_state.nt, &thread_attr, notifier_thread, NULL) == EOK) {
- pthread_setname_np(rpmsg_dce_state.nt, "rpmsg-dce-notifier");
- /* Initialize the driver mapping array. */
- Memory_set (&rpmsg_dce_state.objects,
- 0,
- (sizeof (rpmsg_dce_conn_object *)
- * MultiProc_MAXPROCESSORS));
-
- /* create a local handle and register for notifications with MessageQCopy */
- rpmsg_dce_state.mqHandle = MessageQCopy_create (
- MessageQCopy_ADDRANY,
- "dCE",
- _rpmsg_dce_module_cb,
- NULL,
- &rpmsg_dce_state.endpoint);
- if (rpmsg_dce_state.mqHandle == NULL) {
- /*! @retval DCE_FAIL Failed to create MessageQCopy handle! */
- status = -ENOMEM;
- GT_setFailureReason (curTrace,
- GT_4CLASS,
- "rpmsg_dce_setup",
- status,
- "Failed to create MessageQCopy handle!");
- }
- else {
- /* TBD: This could be replaced with a messageqcopy_open type call, one for
- * each core */
- status = MessageQCopy_registerNotify (rpmsg_dce_state.mqHandle,
- _rpmsg_dce_notify_cb);
- if (status < 0) {
- MessageQCopy_delete (&rpmsg_dce_state.mqHandle);
- /*! @retval DCE_FAIL Failed to register MQCopy handle! */
- status = -ENOMEM;
- GT_setFailureReason (curTrace,
- GT_4CLASS,
- "rpmsg_dce_setup",
- status,
- "Failed to register MQCopy handle!");
- }
- else {
- rpmsg_dce_state.conn_handle = MessageQCopy_create (
- MessageQCopy_ADDRANY,
- "dCE_conn",
- _rpmsg_dce_conn_cb,
- NULL,
- &rpmsg_dce_state.conn_endpoint);
- if (rpmsg_dce_state.conn_handle == NULL) {
- /*! @retval DCE_FAIL Failed to create MessageQCopy handle! */
- status = -ENOMEM;
- GT_setFailureReason (curTrace,
- GT_4CLASS,
- "rpmsg_dce_setup",
- status,
- "Failed to create MessageQCopy conn handle!");
- }
- else {
- status = MessageQCopy_registerNotify (rpmsg_dce_state.conn_handle,
- _rpmsg_dce_conn_notify_cb);
- if (status < 0) {
- MessageQCopy_delete (&rpmsg_dce_state.conn_handle);
- MessageQCopy_delete (&rpmsg_dce_state.mqHandle);
- /*! @retval DCE_FAIL Failed to register MQCopy handle! */
- status = -ENOMEM;
- GT_setFailureReason (curTrace,
- GT_4CLASS,
- "rpmsg_dce_setup",
- status,
- "Failed to register MQCopy conn handle!");
- }
- else {
- rpmsg_dce_state.sem = OsalSemaphore_create(OsalSemaphore_Type_Binary);
- if (rpmsg_dce_state.sem == NULL) {
- //MessageQCopy_unregisterNotify();
- MessageQCopy_delete (&rpmsg_dce_state.conn_handle);
- //MessageQCopy_unregisterNotify();
- MessageQCopy_delete (&rpmsg_dce_state.mqHandle);
- /*! @retval DCE_FAIL Failed to register MQCopy handle! */
- status = -ENOMEM;
- GT_setFailureReason (curTrace,
- GT_4CLASS,
- "rpmsg_dce_setup",
- status,
- "Failed to register MQCopy handle!");
- }
- }
- }
- }
- }
- if (status >= 0) {
- rpmsg_dce_state.isSetup = TRUE;
- }
- else {
- rpmsg_dce_state.run = FALSE;
- }
- }
- else {
- rpmsg_dce_state.run = FALSE;
- }
- pthread_attr_destroy(&thread_attr);
-#if !defined(SYSLINK_BUILD_OPTIMIZE)
- }
-#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
-
- GT_0trace (curTrace, GT_LEAVE, "rpmsg_dce_setup");
- return status;
-}
-
-
-/*!
- * @brief Module destroy function.
- *
- * @sa rpmsg_dce_setup
- */
-Void
-rpmsg_dce_destroy (Void)
-{
- rpmsg_dce_EventPacket * packet;
- UInt32 i;
- List_Handle bufList;
- rpmsg_dce_object * dce = NULL;
- WaitingReaders_t * wr = NULL;
- struct _msg_info info;
-
- GT_0trace (curTrace, GT_ENTER, "_rpmsg_dce_destroy");
-
- for (i = 0; i < MultiProc_MAXPROCESSORS; i++) {
- if (rpmsg_dce_state.objects[i]) {
- rpmsg_dce_conn_object * obj = rpmsg_dce_state.objects[i];
- _deinit_rpmsg_dce_device(obj->dev);
- Memory_free(NULL, obj, sizeof(rpmsg_dce_conn_object));
- rpmsg_dce_state.objects[i] = NULL;
- }
- }
-
- for (i = 0 ; i < MAX_PROCESSES ; i++) {
- dce = NULL;
- if (rpmsg_dce_state.eventState [i].dce != NULL) {
- /* This is recovery. Need to mark dce structures as invalid */
- dce = rpmsg_dce_state.eventState[i].dce;
- MessageQCopy_delete(&dce->mq);
- dce->mq = NULL;
- }
- bufList = rpmsg_dce_state.eventState [i].bufList;
-
- rpmsg_dce_state.eventState [i].bufList = NULL;
- rpmsg_dce_state.eventState [i].dce = NULL;
- rpmsg_dce_state.eventState [i].refCount = 0;
- if (bufList != NULL) {
- /* Dequeue waiting readers and reply to them */
- pthread_mutex_lock(&rpmsg_dce_state.lock);
- while ((wr = dequeue_waiting_reader(i)) != NULL) {
- /* Check if rcvid is still valid */
- if (MsgInfo(wr->rcvid, &info) != -1) {
- put_wr(wr);
- pthread_mutex_unlock(&rpmsg_dce_state.lock);
- MsgError(wr->rcvid, EINTR);
- pthread_mutex_lock(&rpmsg_dce_state.lock);
- }
- }
- /* Check for pending ionotify/select calls */
- if (dce) {
- if (IOFUNC_NOTIFY_INPUT_CHECK(dce->notify, 1, 0)) {
- iofunc_notify_trigger(dce->notify, 1, IOFUNC_NOTIFY_INPUT);
- }
- }
- pthread_mutex_unlock(&rpmsg_dce_state.lock);
-
- /* Free event packets for any received but unprocessed events. */
- while (List_empty (bufList) != TRUE){
- packet = (rpmsg_dce_EventPacket *)
- List_get (bufList);
- if (packet != NULL){
- Memory_free (NULL, packet, sizeof(*packet));
- }
- }
- List_delete (&(bufList));
- }
- }
-
- /* Free the cached list */
- pthread_mutex_lock(&rpmsg_dce_state.lock);
- flush_uBuf();
- pthread_mutex_unlock(&rpmsg_dce_state.lock);
-
- if (rpmsg_dce_state.sem) {
- OsalSemaphore_delete(&rpmsg_dce_state.sem);
- }
-
- //MessageQCopy_unregisterNotify();
- MessageQCopy_delete(&rpmsg_dce_state.conn_handle);
-
- //MessageQCopy_unregisterNotify();
- MessageQCopy_delete(&rpmsg_dce_state.mqHandle);
-
- if (rpmsg_dce_state.gateHandle != NULL) {
- GateSpinlock_delete ((GateSpinlock_Handle *)
- &(rpmsg_dce_state.gateHandle));
- }
-
- rpmsg_dce_state.isSetup = FALSE ;
- rpmsg_dce_state.run = FALSE;
- // run through and destroy the thread, and all outstanding
- // notify structures
- pthread_mutex_lock(&rpmsg_dce_state.lock);
- pthread_cond_signal(&rpmsg_dce_state.cond);
- pthread_mutex_unlock(&rpmsg_dce_state.lock);
- pthread_join(rpmsg_dce_state.nt, NULL);
- pthread_mutex_lock(&rpmsg_dce_state.lock);
- while (rpmsg_dce_state.head != NULL) {
- int index;
- WaitingReaders_t *item;
- index = dequeue_notify_list_item(rpmsg_dce_state.head);
- if (index < 0)
- break;
- item = dequeue_waiting_reader(index);
- while (item) {
- put_wr(item);
- item = dequeue_waiting_reader(index);
- }
- }
- rpmsg_dce_state.head = NULL ;
- rpmsg_dce_state.tail = NULL ;
- pthread_mutex_unlock(&rpmsg_dce_state.lock);
-
- GT_0trace (curTrace, GT_LEAVE, "_rpmsgDrv_destroy");
-}
-
-
-/** ============================================================================
- * Internal functions
- * ============================================================================
- */
-
-
-
diff --git a/qnx/src/ipc3x_dev/ti/syslink/rpmsg-dce/hlos/knl/Qnx/rpmsg-dcedrv.h b/qnx/src/ipc3x_dev/ti/syslink/rpmsg-dce/hlos/knl/Qnx/rpmsg-dcedrv.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/**
- * @file rpmsg-dcedrv.h
- *
- * @brief Definitions of rpmsg-dcedrv internal types and structures.
- *
- *
- * @ver 02.00.00.46_alpha1
- *
- * ============================================================================
- *
- * Copyright (c) 2011-2012, Texas Instruments Incorporated
- *
- * 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 Texas Instruments Incorporated 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.
- * Contact information for paper mail:
- * Texas Instruments
- * Post Office Box 655303
- * Dallas, Texas 75265
- * Contact information:
- * http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
- * DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
- * ============================================================================
- *
- */
-
-
-#ifndef RPMSGDCE_DRV_H_0xf2ba
-#define RPMSGDCE_DRV_H_0xf2ba
-
-
-#if defined (__cplusplus)
-extern "C" {
-#endif
-
-
-/* =============================================================================
- * Macros and types
- * =============================================================================
- */
-/*!
- * @brief Max number of user processes supported
- */
-#define MAX_PROCESSES 256u
-
-/*!
- * @brief Number of event entries to cache
- */
-#define CACHE_NUM 10
-
-/*!
- * @brief Structure that defines the MsgList elem
- */
-typedef struct MsgList {
- int index;
- int num_events;
- struct MsgList *next;
- struct MsgList *prev;
-} MsgList_t;
-
-/*!
- * @brief Structure that defines the Waiting Readers list element
- */
-typedef struct WaitingReaders {
- int rcvid;
- struct WaitingReaders *next;
-} WaitingReaders_t;
-
-
-#if defined (__cplusplus)
-}
-#endif /* defined (__cplusplus) */
-
-
-#endif /* RPMSGDCE_DRV_H_0xf2ba */