コード例 #1
0
ファイル: esif_ipc_os_lin.c プロジェクト: naitaku/dptf
/* IOCTL */
static ssize_t esif_file_ipc(
	struct file *fp,
	char __user *buf,
	size_t count,
	loff_t *ppos
	)
{
	u32 len = 0;
	struct esif_ipc *ipc_req_ptr = esif_ipc_user_to_kernel(
			(struct esif_ipc *)buf);
	struct esif_ipc *ipc_rsp_ptr = NULL;

	if (count < sizeof(struct esif_ipc))
		return -EINVAL;

	if (NULL == ipc_req_ptr)
		return -ENOMEM;

	ESIF_TRACE_DYN_IPC("linux_%s: user %p kernel %p count %d\n",
			   __func__, buf, ipc_req_ptr, (int)count);

	ipc_rsp_ptr = esif_ipc_process(ipc_req_ptr);

	if (NULL != ipc_rsp_ptr) {
		len = esif_ipc_kernel_to_user((struct esif_ipc *)buf,
						ipc_rsp_ptr);
		ESIF_TRACE_DYN_IPC("linux_%s: user %p kernel %p count = %d\n",
				   __func__, buf, ipc_rsp_ptr, (int)count);

		if (ipc_req_ptr != ipc_rsp_ptr)
			esif_ipc_free(ipc_rsp_ptr);
	}
	esif_ccb_free(ipc_req_ptr);
	return len;
}
コード例 #2
0
ファイル: esif_ipc_os_lin.c プロジェクト: naitaku/dptf
/* IOCTL Operation */
static long esif_ioctl(
	struct file *filp_ptr,
	u_int cmd,
	u_long arg
	)
{
	int rc = -EINVAL;

	ESIF_TRACE_DYN_IPC("linux_%s: ioctl cmd %x\n", __func__, cmd);
	switch (cmd) {
	case ESIF_IOCTL_IPC_NOOP:
		ESIF_TRACE_DYN_IPC("linux_%s: NOOP cmd=%x\n", __func__, cmd);
		break;

	case ESIF_IOCTL_IPC:
		ESIF_TRACE_DYN_IPC("linux_%s: ESIF_IOCTL_IPC\n", __func__);
		rc = esif_ipc_ioctl((struct esif_ipc *)arg);
		break;

	default:
		ESIF_TRACE_DYN_IPC("linux_%s: NOT IMPLEMENTED %x\n",
				   __func__,
				   cmd);
		break;
	}
	return rc;
}
コード例 #3
0
ファイル: esif_ipc_os_lin.c プロジェクト: naitaku/dptf
/* IOCTL */
static int esif_ipc_ioctl(struct esif_ipc *ipc_user_ptr)
{
	int rc = 0;
	struct esif_ipc *ipc_req_ptr = esif_ipc_user_to_kernel(ipc_user_ptr);
	struct esif_ipc *ipc_rsp_ptr = NULL;

	if (NULL == ipc_req_ptr)
		return -ENOMEM;

	ESIF_TRACE_DYN_IPC("linux_%s: user %p kernel %p\n",
			   __func__,
			   ipc_user_ptr,
			   ipc_req_ptr);
	ipc_rsp_ptr = esif_ipc_process(ipc_req_ptr);

	if (NULL != ipc_rsp_ptr) {
		esif_ipc_kernel_to_user((struct esif_ipc *)ipc_user_ptr,
					ipc_rsp_ptr);
		ESIF_TRACE_DYN_IPC("linux_%s: user %p kernel %p\n",
				   __func__,
				   ipc_user_ptr,
				   ipc_rsp_ptr);
		if (ipc_req_ptr != ipc_rsp_ptr)
			esif_ipc_free(ipc_rsp_ptr);
	} else {
		rc = -EINVAL;
	}
	esif_ccb_free(ipc_req_ptr);
	return rc;
}
コード例 #4
0
ファイル: esif_ipc_os_lin.c プロジェクト: naitaku/dptf
/* Translate Kernel IPC To User Space */
static int esif_ipc_kernel_to_user(
	struct esif_ipc *ipc_user_ptr,
	struct esif_ipc *ipc_kernel_ptr
	)
{
	u32 len = 0;
	if (NULL == ipc_user_ptr || NULL == ipc_kernel_ptr)
		return -EINVAL;

	len = ipc_kernel_ptr->data_len + sizeof(struct esif_ipc);

	ESIF_TRACE_DYN_IPC(
		"linux_%s: ipc version=%d, type=%d, len = %d, "
		"data_len=%d, rc=%d\n",
		__func__,
		ipc_kernel_ptr->version,
		ipc_kernel_ptr->type,
		(int)len,
		(int)ipc_kernel_ptr->data_len,
		ipc_kernel_ptr->return_code);

	/* TODO Check For Fit When Possible */
	if (copy_to_user(ipc_user_ptr, ipc_kernel_ptr, len) > 0)
		return -ENOMEM;

	return len;
}
コード例 #5
0
ファイル: esif_ipc_os_lin.c プロジェクト: naitaku/dptf
/* Translate User Space IPC to Kernel */
static struct esif_ipc *esif_ipc_user_to_kernel(struct esif_ipc *ipc_user_ptr)
{
	int ipc_len = 0;
	struct esif_ipc ipc_hdr  = {0};
	struct esif_ipc *ipc_ptr = NULL;

	if (NULL == ipc_user_ptr)
		return NULL;

	/* Copy from user an error indicates how many bytes copied. */
	if (copy_from_user(&ipc_hdr, ipc_user_ptr,
			   sizeof(struct esif_ipc)) > 0) {
		return NULL;
	}

	/* Sanity Check */
	if (ESIF_IPC_VERSION != ipc_hdr.version)
		return NULL;

	ESIF_TRACE_DYN_IPC(
		"linux_%s: ipc version=%d, type=%d, data_len=%d, rc=%d\n",
		__func__,
		ipc_hdr.version,
		ipc_hdr.type,
		(int)ipc_hdr.data_len,
		(int)ipc_hdr.return_code);

	ipc_len = ipc_hdr.data_len + sizeof(struct esif_ipc);
	ipc_ptr = esif_ccb_malloc(ipc_len);
	if (NULL == ipc_ptr)
		return NULL;

	/* Copy from user an error indicates how many bytes copied. */
	if (copy_from_user(ipc_ptr, ipc_user_ptr, ipc_len) > 0) {
		esif_ccb_free(ipc_ptr);
		return NULL;
	}
	return ipc_ptr;
}
コード例 #6
0
ファイル: esif_ipc.c プロジェクト: hoangt/dptf
/* Process IPC */
struct esif_ipc *esif_ipc_process(
	struct esif_ipc *ipc_ptr
	)
{
	struct esif_ipc *ipc_ret_ptr = ipc_ptr;
	struct esif_ipc_command *cmd_ptr = NULL;
	struct esif_ipc_primitive *prim_ptr = NULL;

	ESIF_TRACE_DYN_IPC("START ipc %p\n", ipc_ptr);

	if (NULL == ipc_ptr)
		goto exit;

	/*
	 * 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("COMMAND Received\n");
		cmd_ptr = (struct esif_ipc_command *)(ipc_ptr + 1);
		if ((ipc_ptr->data_len < sizeof(*cmd_ptr)) ||
		    (ipc_ptr->data_len < (esif_ipc_command_get_data_len(cmd_ptr) + sizeof(*cmd_ptr))))
			ipc_ptr->return_code = ESIF_E_IPC_DATA_INVALID;
		else 
			
			esif_execute_ipc_command(cmd_ptr);
		break;

	/* Retrieve A Signaled Event Or Check Event Queue */
	case ESIF_IPC_TYPE_EVENT:
		ESIF_TRACE_DYN_IPC("EVENT Received\n");
		if (ipc_ptr->data_len < sizeof(struct esif_ipc_event))
			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("PRIMITIVE Received\n");
		prim_ptr = (struct esif_ipc_primitive *)(ipc_ptr + 1);
		if ((ipc_ptr->data_len < sizeof(*prim_ptr)) ||
		    (ipc_ptr->data_len < (esif_ipc_primitive_get_data_len(prim_ptr) + sizeof(*prim_ptr))))
			ipc_ptr->return_code = ESIF_E_IPC_DATA_INVALID;
		else
			esif_execute_ipc_primitive(prim_ptr);
		break;

	/* NOOP For Testing */
	case ESIF_IPC_TYPE_NOOP:
		ESIF_TRACE_DYN_IPC("NOOP Received\n");
		ipc_ret_ptr = NULL;
		break;

	/* Unsupported or Unknown IPC Type Received */
	default:
		ESIF_TRACE_DYN_IPC("Unknown IPC Type Received type=%u\n",
			ipc_ptr->type);
		ipc_ptr->return_code = ESIF_E_IPC_DATA_INVALID;
		break;
	}
	ESIF_TRACE_DYN_IPC("FINISH return result: %s(%u)\n",
		esif_rc_str(ipc_ptr->return_code),
		ipc_ptr->return_code);
exit:
	return ipc_ret_ptr;
}
コード例 #7
0
ファイル: esif_ipc_os_lin.c プロジェクト: naitaku/dptf
/* Release */
static int esif_release(struct inode *inode, struct file *filp)
{
	ESIF_TRACE_DYN_IPC("linux_%s: %s Device Closed\n", __func__,
			   IPC_DEVICE);
	return 0;
}