/*
 * disp.c
 *
 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
 *
 * Node Dispatcher interface. Communicates with Resource Manager Server
 * (RMS) on DSP. Access to RMS is synchronized in NODE.
 *
 * Copyright (C) 2005-2006 Texas Instruments, Inc.
 *
 * This package is free software;  you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */
#include <linux/types.h>

/*  ----------------------------------- Host OS */
#include <dspbridge/host_os.h>

/*  ----------------------------------- DSP/BIOS Bridge */
#include <dspbridge/dbdefs.h>

/*  ----------------------------------- Trace & Debug */
#include <dspbridge/dbc.h>

/*  ----------------------------------- OS Adaptation Layer */
#include <dspbridge/sync.h>

/*  ----------------------------------- Link Driver */
#include <dspbridge/dspdefs.h>

/*  ----------------------------------- Platform Manager */
#include <dspbridge/dev.h>
#include <dspbridge/chnldefs.h>

/*  ----------------------------------- Resource Manager */
#include <dspbridge/nodedefs.h>
#include <dspbridge/nodepriv.h>
#include <dspbridge/rms_sh.h>

/*  ----------------------------------- This */
#include <dspbridge/disp.h>

/* Size of a reply from RMS */
#define REPLYSIZE (3 * sizeof(rms_word))

/* Reserved channel offsets for communication with RMS */
#define CHNLTORMSOFFSET       0
#define CHNLFROMRMSOFFSET     1

#define CHNLIOREQS      1

/*
 *  ======== disp_object ========
 */
struct disp_object {
	struct dev_object *hdev_obj;	/* Device for this processor */
	/* Function interface to Bridge driver */
	struct bridge_drv_interface *intf_fxns;
	struct chnl_mgr *hchnl_mgr;	/* Channel manager */
	struct chnl_object *chnl_to_dsp;	/* Chnl for commands to RMS */
	struct chnl_object *chnl_from_dsp;	/* Chnl for replies from RMS */
	u8 *pbuf;		/* Buffer for commands, replies */
	u32 ul_bufsize;		/* pbuf size in bytes */
	u32 ul_bufsize_rms;	/* pbuf size in RMS words */
	u32 char_size;		/* Size of DSP character */
	u32 word_size;		/* Size of DSP word */
	u32 data_mau_size;	/* Size of DSP Data MAU */
};

static u32 refs;

static void delete_disp(struct disp_object *disp_obj);
static int fill_stream_def(rms_word *pdw_buf, u32 *ptotal, u32 offset,
				  struct node_strmdef strm_def, u32 max,
				  u32 chars_in_rms_word);
static int send_message(struct disp_object *disp_obj, u32 timeout,
			       u32 ul_bytes, u32 *pdw_arg);

/*
 *  ======== disp_create ========
 *  Create a NODE Dispatcher object.
 */
int disp_create(struct disp_object **dispatch_obj,
		       struct dev_object *hdev_obj,
		       const struct disp_attr *disp_attrs)
{
	struct disp_object *disp_obj;
	struct bridge_drv_interface *intf_fxns;
	u32 ul_chnl_id;
	struct chnl_attr chnl_attr_obj;
	int status = 0;
	u8 dev_type;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(dispatch_obj != NULL);
	DBC_REQUIRE(disp_attrs != NULL);
	DBC_REQUIRE(hdev_obj != NULL);

	*dispatch_obj = NULL;

	/* Allocate Node Dispatcher object */
	disp_obj = kzalloc(sizeof(struct disp_object), GFP_KERNEL);
	if (disp_obj == NULL)
		status = -ENOMEM;
	else
		disp_obj->hdev_obj = hdev_obj;

	/* Get Channel manager and Bridge function interface */
	if (!status) {
		status = dev_get_chnl_mgr(hdev_obj, &(disp_obj->hchnl_mgr));
		if (!status) {
			(void)dev_get_intf_fxns(hdev_obj, &intf_fxns);
			disp_obj->intf_fxns = intf_fxns;
		}
	}

	/* check device type and decide if streams or messag'ing is used for
	 * RMS/EDS */
	if (status)
		goto func_cont;

	status = dev_get_dev_type(hdev_obj, &dev_type);

	if (status)
		goto func_cont;

	if (dev_type != DSP_UNIT) {
		status = -EPERM;
		goto func_cont;
	}

	disp_obj->char_size = DSPWORDSIZE;
	disp_obj->word_size = DSPWORDSIZE;
	disp_obj->data_mau_size = DSPWORDSIZE;
	/* Open channels for communicating with the RMS */
	chnl_attr_obj.uio_reqs = CHNLIOREQS;
	chnl_attr_obj.event_obj = NULL;
	ul_chnl_id = disp_attrs->ul_chnl_offset + CHNLTORMSOFFSET;
	status = (*intf_fxns->pfn_chnl_open) (&(disp_obj->chnl_to_dsp),
					      disp_obj->hchnl_mgr,
					      CHNL_MODETODSP, ul_chnl_id,
					      &chnl_attr_obj);

	if (!status) {
		ul_chnl_id = disp_attrs->ul_chnl_offset + CHNLFROMRMSOFFSET;
		status =
		    (*intf_fxns->pfn_chnl_open) (&(disp_obj->chnl_from_dsp),
						 disp_obj->hchnl_mgr,
						 CHNL_MODEFROMDSP, ul_chnl_id,
						 &chnl_attr_obj);
	}
	if (!status) {
		/* Allocate buffer for commands, replies */
		disp_obj->ul_bufsize = disp_attrs->ul_chnl_buf_size;
		disp_obj->ul_bufsize_rms = RMS_COMMANDBUFSIZE;
		disp_obj->pbuf = kzalloc(disp_obj->ul_bufsize, GFP_KERNEL);
		if (disp_obj->pbuf == NULL)
			status = -ENOMEM;
	}
func_cont:
	if (!status)
		*dispatch_obj = disp_obj;
	else
		delete_disp(disp_obj);

	DBC_ENSURE((status && *dispatch_obj == NULL) ||
				(!status && *dispatch_obj));
	return status;
}

/*
 *  ======== disp_delete ========
 *  Delete the NODE Dispatcher.
 */
void disp_delete(struct disp_object *disp_obj)
{
	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(disp_obj);

	delete_disp(disp_obj);
}

/*
 *  ======== disp_exit ========
 *  Discontinue usage of DISP module.
 */
void disp_exit(void)
{
	DBC_REQUIRE(refs > 0);

	refs--;

	DBC_ENSURE(refs >= 0);
}

/*
 *  ======== disp_init ========
 *  Initialize the DISP module.
 */
bool disp_init(void)
{
	bool ret = true;

	DBC_REQUIRE(refs >= 0);

	if (ret)
		refs++;

	DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
	return ret;
}

/*
 *  ======== disp_node_change_priority ========
 *  Change the priority of a node currently running on the target.
 */
int disp_node_change_priority(struct disp_object *disp_obj,
				     struct node_object *hnode,
				     u32 rms_fxn, nodeenv node_env, s32 prio)
{
	u32 dw_arg;
	struct rms_command *rms_cmd;
	int status = 0;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(disp_obj);
	DBC_REQUIRE(hnode != NULL);

	/* Send message to RMS to change priority */
	rms_cmd = (struct rms_command *)(disp_obj->pbuf);
	rms_cmd->fxn = (rms_word) (rms_fxn);
	rms_cmd->arg1 = (rms_word) node_env;
	rms_cmd->arg2 = prio;
	status = send_message(disp_obj, node_get_timeout(hnode),
			      sizeof(struct rms_command), &dw_arg);

	return status;
}

/*
 *  ======== disp_node_create ========
 *  Create a node on the DSP by remotely calling the node's create function.
 */
int disp_node_create(struct disp_object *disp_obj,
			    struct node_object *hnode, u32 rms_fxn,
			    u32 ul_create_fxn,
			    const struct node_createargs *pargs,
			    nodeenv *node_env)
{
	struct node_msgargs node_msg_args;
	struct node_taskargs task_arg_obj;
	struct rms_command *rms_cmd;
	struct rms_msg_args *pmsg_args;
	struct rms_more_task_args *more_task_args;
	enum node_type node_type;
	u32 dw_length;
	rms_word *pdw_buf = NULL;
	u32 ul_bytes;
	u32 i;
	u32 total;
	u32 chars_in_rms_word;
	s32 task_args_offset;
	s32 sio_in_def_offset;
	s32 sio_out_def_offset;
	s32 sio_defs_offset;
	s32 args_offset = -1;
	s32 offset;
	struct node_strmdef strm_def;
	u32 max;
	int status = 0;
	struct dsp_nodeinfo node_info;
	u8 dev_type;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(disp_obj);
	DBC_REQUIRE(hnode != NULL);
	DBC_REQUIRE(node_get_type(hnode) != NODE_DEVICE);
	DBC_REQUIRE(node_env != NULL);

	status = dev_get_dev_type(disp_obj->hdev_obj, &dev_type);

	if (status)
		goto func_end;

	if (dev_type != DSP_UNIT) {
		dev_dbg(bridge, "%s: unknown device type = 0x%x\n",
			__func__, dev_type);
		goto func_end;
	}
	DBC_REQUIRE(pargs != NULL);
	node_type = node_get_type(hnode);
	node_msg_args = pargs->asa.node_msg_args;
	max = disp_obj->ul_bufsize_rms;	/*Max # of RMS words that can be sent */
	DBC_ASSERT(max == RMS_COMMANDBUFSIZE);
	chars_in_rms_word = sizeof(rms_word) / disp_obj->char_size;
	/* Number of RMS words needed to hold arg data */
	dw_length =
	    (node_msg_args.arg_length + chars_in_rms_word -
	     1) / chars_in_rms_word;
	/* Make sure msg args and command fit in buffer */
	total = sizeof(struct rms_command) / sizeof(rms_word) +
	    sizeof(struct rms_msg_args)
	    / sizeof(rms_word) - 1 + dw_length;
	if (total >= max) {
		status = -EPERM;
		dev_dbg(bridge, "%s: Message args too large for buffer! size "
			"= %d, max = %d\n", __func__, total, max);
	}
	/*
	 *  Fill in buffer to send to RMS.
	 *  The buffer will have the following  format:
	 *
	 *  RMS command:
	 *      Address of RMS_CreateNode()
	 *      Address of node's create function
	 *      dummy argument
	 *      node type
	 *
	 *  Message Args:
	 *      max number of messages
	 *      segid for message buffer allocation
	 *      notification type to use when message is received
	 *      length of message arg data
	 *      message args data
	 *
	 *  Task Args (if task or socket node):
	 *      priority
	 *      stack size
	 *      system stack size
	 *      stack segment
	 *      misc
	 *      number of input streams
	 *      pSTRMInDef[] - offsets of STRM definitions for input streams
	 *      number of output streams
	 *      pSTRMOutDef[] - offsets of STRM definitions for output
	 *      streams
	 *      STRMInDef[] - array of STRM definitions for input streams
	 *      STRMOutDef[] - array of STRM definitions for output streams
	 *
	 *  Socket Args (if DAIS socket node):
	 *
	 */
	if (!status) {
		total = 0;	/* Total number of words in buffer so far */
		pdw_buf = (rms_word *) disp_obj->pbuf;
		rms_cmd = (struct rms_command *)pdw_buf;
		rms_cmd->fxn = (rms_word) (rms_fxn);
		rms_cmd->arg1 = (rms_word) (ul_create_fxn);
		if (node_get_load_type(hnode) == NLDR_DYNAMICLOAD) {
			/* Flush ICACHE on Load */
			rms_cmd->arg2 = 1;	/* dummy argument */
		} else {
			/* Do not flush ICACHE */
			rms_cmd->arg2 = 0;	/* dummy argument */
		}
		rms_cmd->data = node_get_type(hnode);
		/*
		 *  args_offset is the offset of the data field in struct
		 *  rms_command structure. We need this to calculate stream
		 *  definition offsets.
		 */
		args_offset = 3;
		total += sizeof(struct rms_command) / sizeof(rms_word);
		/* Message args */
		pmsg_args = (struct rms_msg_args *)(pdw_buf + total);
		pmsg_args->max_msgs = node_msg_args.max_msgs;
		pmsg_args->segid = node_msg_args.seg_id;
		pmsg_args->notify_type = node_msg_args.notify_type;
		pmsg_args->arg_length = node_msg_args.arg_length;
		total += sizeof(struct rms_msg_args) / sizeof(rms_word) - 1;
		memcpy(pdw_buf + total, node_msg_args.pdata,
		       node_msg_args.arg_length);
		total += dw_length;
	}
	if (status)
		goto func_end;

	/* If node is a task node, copy task create arguments into  buffer */
	if (node_type == NODE_TASK || node_type == NODE_DAISSOCKET) {
		task_arg_obj = pargs->asa.task_arg_obj;
		task_args_offset = total;
		total += sizeof(struct rms_more_task_args) / sizeof(rms_word) +
		    1 + task_arg_obj.num_inputs + task_arg_obj.num_outputs;
		/* Copy task arguments */
		if (total < max) {
			total = task_args_offset;
			more_task_args = (struct rms_more_task_args *)(pdw_buf +
								       total);
			/*
			 * Get some important info about the node. Note that we
			 * don't just reach into the hnode struct because
			 * that would break the node object's abstraction.
			 */
			get_node_info(hnode, &node_info);
			more_task_args->priority = node_info.execution_priority;
			more_task_args->stack_size = task_arg_obj.stack_size;
			more_task_args->sysstack_size =
			    task_arg_obj.sys_stack_size;
			more_task_args->stack_seg = task_arg_obj.stack_seg;
			more_task_args->heap_addr = task_arg_obj.udsp_heap_addr;
			more_task_args->heap_size = task_arg_obj.heap_size;
			more_task_args->misc = task_arg_obj.ul_dais_arg;
			more_task_args->num_input_streams =
			    task_arg_obj.num_inputs;
			total +=
			    sizeof(struct rms_more_task_args) /
			    sizeof(rms_word);
			dev_dbg(bridge, "%s: udsp_heap_addr %x, heap_size %x\n",
				__func__, task_arg_obj.udsp_heap_addr,
				task_arg_obj.heap_size);
			/* Keep track of pSIOInDef[] and pSIOOutDef[]
			 * positions in the buffer, since this needs to be
			 * filled in later. */
			sio_in_def_offset = total;
			total += task_arg_obj.num_inputs;
			pdw_buf[total++] = task_arg_obj.num_outputs;
			sio_out_def_offset = total;
			total += task_arg_obj.num_outputs;
			sio_defs_offset = total;
			/* Fill SIO defs and offsets */
			offset = sio_defs_offset;
			for (i = 0; i < task_arg_obj.num_inputs; i++) {
				if (status)
					break;

				pdw_buf[sio_in_def_offset + i] =
				    (offset - args_offset)
				    * (sizeof(rms_word) / DSPWORDSIZE);
				strm_def = task_arg_obj.strm_in_def[i];
				status =
				    fill_stream_def(pdw_buf, &total, offset,
						    strm_def, max,
						    chars_in_rms_word);
				offset = total;
			}
			for (i = 0; (i < task_arg_obj.num_outputs) &&
			     (!status); i++) {
				pdw_buf[sio_out_def_offset + i] =
				    (offset - args_offset)
				    * (sizeof(rms_word) / DSPWORDSIZE);
				strm_def = task_arg_obj.strm_out_def[i];
				status =
				    fill_stream_def(pdw_buf, &total, offset,
						    strm_def, max,
						    chars_in_rms_word);
				offset = total;
			}
		} else {
			/* Args won't fit */
			status = -EPERM;
		}
	}
	if (!status) {
		ul_bytes = total * sizeof(rms_word);
		DBC_ASSERT(ul_bytes < (RMS_COMMANDBUFSIZE * sizeof(rms_word)));
		status = send_message(disp_obj, node_get_timeout(hnode),
				      ul_bytes, node_env);
		if (status >= 0) {
			/*
			 * Message successfully received from RMS.
			 * Return the status of the Node's create function
			 * on the DSP-side
			 */
			status = (((rms_word *) (disp_obj->pbuf))[0]);
			if (status < 0)
				dev_dbg(bridge, "%s: DSP-side failed: 0x%x\n",
					__func__, status);
		}
	}
func_end:
	return status;
}

/*
 *  ======== disp_node_delete ========
 *  purpose:
 *      Delete a node on the DSP by remotely calling the node's delete function.
 *
 */
int disp_node_delete(struct disp_object *disp_obj,
			    struct node_object *hnode, u32 rms_fxn,
			    u32 ul_delete_fxn, nodeenv node_env)
{
	u32 dw_arg;
	struct rms_command *rms_cmd;
	int status = 0;
	u8 dev_type;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(disp_obj);
	DBC_REQUIRE(hnode != NULL);

	status = dev_get_dev_type(disp_obj->hdev_obj, &dev_type);

	if (!status) {

		if (dev_type == DSP_UNIT) {

			/*
			 *  Fill in buffer to send to RMS
			 */
			rms_cmd = (struct rms_command *)disp_obj->pbuf;
			rms_cmd->fxn = (rms_word) (rms_fxn);
			rms_cmd->arg1 = (rms_word) node_env;
			rms_cmd->arg2 = (rms_word) (ul_delete_fxn);
			rms_cmd->data = node_get_type(hnode);

			status = send_message(disp_obj, node_get_timeout(hnode),
					      sizeof(struct rms_command),
					      &dw_arg);
			if (status >= 0) {
				/*
				 * Message successfully received from RMS.
				 * Return the status of the Node's delete
				 * function on the DSP-side
				 */
				status = (((rms_word *) (disp_obj->pbuf))[0]);
				if (status < 0)
					dev_dbg(bridge, "%s: DSP-side failed: "
						"0x%x\n", __func__, status);
			}

		}
	}
	return status;
}

/*
 *  ======== disp_node_run ========
 *  purpose:
 *      Start execution of a node's execute phase, or resume execution of a node
 *      that has been suspended (via DISP_NodePause()) on the DSP.
 */
int disp_node_run(struct disp_object *disp_obj,
			 struct node_object *hnode, u32 rms_fxn,
			 u32 ul_execute_fxn, nodeenv node_env)
{
	u32 dw_arg;
	struct rms_command *rms_cmd;
	int status = 0;
	u8 dev_type;
	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(disp_obj);
	DBC_REQUIRE(hnode != NULL);

	status = dev_get_dev_type(disp_obj->hdev_obj, &dev_type);

	if (!status) {

		if (dev_type == DSP_UNIT) {

			/*
			 *  Fill in buffer to send to RMS.
			 */
			rms_cmd = (struct rms_command *)disp_obj->pbuf;
			rms_cmd->fxn = (rms_word) (rms_fxn);
			rms_cmd->arg1 = (rms_word) node_env;
			rms_cmd->arg2 = (rms_word) (ul_execute_fxn);
			rms_cmd->data = node_get_type(hnode);

			status = send_message(disp_obj, node_get_timeout(hnode),
					      sizeof(struct rms_command),
					      &dw_arg);
			if (status >= 0) {
				/*
				 * Message successfully received from RMS.
				 * Return the status of the Node's execute
				 * function on the DSP-side
				 */
				status = (((rms_word *) (disp_obj->pbuf))[0]);
				if (status < 0)
					dev_dbg(bridge, "%s: DSP-side failed: "
						"0x%x\n", __func__, status);
			}

		}
	}

	return status;
}

/*
 *  ======== delete_disp ========
 *  purpose:
 *      Frees the resources allocated for the dispatcher.
 */
static void delete_disp(struct disp_object *disp_obj)
{
	int status = 0;
	struct bridge_drv_interface *intf_fxns;

	if (disp_obj) {
		intf_fxns = disp_obj->intf_fxns;

		/* Free Node Dispatcher resources */
		if (disp_obj->chnl_from_dsp) {
			/* Channel close can fail only if the channel handle
			 * is invalid. */
			status = (*intf_fxns->pfn_chnl_close)
			    (disp_obj->chnl_from_dsp);
			if (status) {
				dev_dbg(bridge, "%s: Failed to close channel "
					"from RMS: 0x%x\n", __func__, status);
			}
		}
		if (disp_obj->chnl_to_dsp) {
			status =
			    (*intf_fxns->pfn_chnl_close) (disp_obj->
							  chnl_to_dsp);
			if (status) {
				dev_dbg(bridge, "%s: Failed to close channel to"
					" RMS: 0x%x\n", __func__, status);
			}
		}
		kfree(disp_obj->pbuf);

		kfree(disp_obj);
	}
}

/*
 *  ======== fill_stream_def ========
 *  purpose:
 *      Fills stream definitions.
 */
static int fill_stream_def(rms_word *pdw_buf, u32 *ptotal, u32 offset,
				  struct node_strmdef strm_def, u32 max,
				  u32 chars_in_rms_word)
{
	struct rms_strm_def *strm_def_obj;
	u32 total = *ptotal;
	u32 name_len;
	u32 dw_length;
	int status = 0;

	if (total + sizeof(struct rms_strm_def) / sizeof(rms_word) >= max) {
		status = -EPERM;
	} else {
		strm_def_obj = (struct rms_strm_def *)(pdw_buf + total);
		strm_def_obj->bufsize = strm_def.buf_size;
		strm_def_obj->nbufs = strm_def.num_bufs;
		strm_def_obj->segid = strm_def.seg_id;
		strm_def_obj->align = strm_def.buf_alignment;
		strm_def_obj->timeout = strm_def.utimeout;
	}

	if (!status) {
		/*
		 *  Since we haven't added the device name yet, subtract
		 *  1 from total.
		 */
		total += sizeof(struct rms_strm_def) / sizeof(rms_word) - 1;
		DBC_REQUIRE(strm_def.sz_device);
		dw_length = strlen(strm_def.sz_device) + 1;

		/* Number of RMS_WORDS needed to hold device name */
		name_len =
		    (dw_length + chars_in_rms_word - 1) / chars_in_rms_word;

		if (total + name_len >= max) {
			status = -EPERM;
		} else {
			/*
			 *  Zero out last word, since the device name may not
			 *  extend to completely fill this word.
			 */
			pdw_buf[total + name_len - 1] = 0;
			/** TODO USE SERVICES * */
			memcpy(pdw_buf + total, strm_def.sz_device, dw_length);
			total += name_len;
			*ptotal = total;
		}
	}

	return status;
}

/*
 *  ======== send_message ======
 *  Send command message to RMS, get reply from RMS.
 */
static int send_message(struct disp_object *disp_obj, u32 timeout,
			       u32 ul_bytes, u32 *pdw_arg)
{
	struct bridge_drv_interface *intf_fxns;
	struct chnl_object *chnl_obj;
	u32 dw_arg = 0;
	u8 *pbuf;
	struct chnl_ioc chnl_ioc_obj;
	int status = 0;

	DBC_REQUIRE(pdw_arg != NULL);

	*pdw_arg = (u32) NULL;
	intf_fxns = disp_obj->intf_fxns;
	chnl_obj = disp_obj->chnl_to_dsp;
	pbuf = disp_obj->pbuf;

	/* Send the command */
	status = (*intf_fxns->pfn_chnl_add_io_req) (chnl_obj, pbuf, ul_bytes, 0,
						    0L, dw_arg);
	if (status)
		goto func_end;

	status =
	    (*intf_fxns->pfn_chnl_get_ioc) (chnl_obj, timeout, &chnl_ioc_obj);
	if (!status) {
		if (!CHNL_IS_IO_COMPLETE(chnl_ioc_obj)) {
			if (CHNL_IS_TIMED_OUT(chnl_ioc_obj))
				status = -ETIME;
			else
				status = -EPERM;
		}
	}
	/* Get the reply */
	if (status)
		goto func_end;

	chnl_obj = disp_obj->chnl_from_dsp;
	ul_bytes = REPLYSIZE;
	status = (*intf_fxns->pfn_chnl_add_io_req) (chnl_obj, pbuf, ul_bytes,
						    0, 0L, dw_arg);
	if (status)
		goto func_end;

	status =
	    (*intf_fxns->pfn_chnl_get_ioc) (chnl_obj, timeout, &chnl_ioc_obj);
	if (!status) {
		if (CHNL_IS_TIMED_OUT(chnl_ioc_obj)) {
			status = -ETIME;
		} else if (chnl_ioc_obj.byte_size < ul_bytes) {
			/* Did not get all of the reply from the RMS */
			status = -EPERM;
		} else {
			if (CHNL_IS_IO_COMPLETE(chnl_ioc_obj)) {
				DBC_ASSERT(chnl_ioc_obj.pbuf == pbuf);
				status = (*((rms_word *) chnl_ioc_obj.pbuf));
				*pdw_arg =
				    (((rms_word *) (chnl_ioc_obj.pbuf))[1]);
			} else {
				status = -EPERM;
			}
		}
	}
func_end:
	return status;
}
