Пример #1
0
static int rpmsg_func_test_kern_app_probe(struct rpmsg_channel *rpdev)
{
	int	err;
	int   uninit = 0;
	struct ept_cmd_data *ept_data;
	struct command *cmd;

	pr_err("\r\nFunc Test Suite Start! \r\n");

	/* Create endpoint for remote channel and register rx callabck */
	ept = rpmsg_create_ept(rpdev, rpmsg_func_test_default_rx_cb, 0,
				RPMSG_ADDR_ANY);

	if (!ept) {
		pr_err(" Endpoint creation for failed!\r\n");
		return -ENOMEM;
	}

	/* Send init message to complete the connection loop */
	err = rpmsg_send_offchannel(rpdev, ept->addr, rpdev->dst,
				init_msg, sizeof(init_msg));

	if (err) {
		pr_err(" Init message send failed!\r\n");
		return err;
	}

	/* Send a message to start tests */
	err = rpmsg_send_offchannel(rpdev, ept->addr, rpdev->dst,
				start_test, sizeof(start_test));

	if (err) {
		pr_err("Test start command failed!\r\n");
		return err;
	}


	while (1) {
		/* Wait till the data is echoed back. */
		wait_event_interruptible(wait_queue, flag != 0);
		flag = 0;

		cmd = (struct command *)r_buffer;

		if (cmd->comm_start == CMD_START) {
			unsigned int cm_code = cmd->comm_code;
			void *data = cmd->data;

			switch (cm_code) {
			case CREATE_EPT:
				ept_data = (struct ept_cmd_data *)data;
				rp_ept = rpmsg_create_ept(rpdev,
						rpmsg_func_test_ept_rx_cb,
						0, ept_data->dst);
				if (rp_ept)
					/* Send data back to ack. */
					rpmsg_send_offchannel(rpdev,
							ept->addr, rpdev->dst,
							r_buffer, data_length);
				break;
			case DELETE_EPT:
				rpmsg_destroy_ept(rp_ept);
				rpmsg_send_offchannel(rpdev, ept->addr,
							rpdev->dst,
							r_buffer, data_length);
				break;
			case CREATE_CHNL:
				break;
			case DELETE_CHNL:
				rpmsg_send_offchannel(rpdev, ept->addr,
							rpdev->dst,
							r_buffer, data_length);
				uninit = 1;
				break;
			case QUERY_FW_NAME:
				rpmsg_send_offchannel(rpdev, ept->addr,
						rpdev->dst,
						&firmware_name[0],
						strlen(firmware_name)+1);
				break;
			case PRINT_RESULT:
				pr_err("%s", data);
				rpmsg_send_offchannel(rpdev, ept->addr,
							rpdev->dst,
							r_buffer, data_length);
				break;
			default:
				rpmsg_send_offchannel(rpdev, ept->addr,
							rpdev->dst,
							r_buffer, data_length);
				break;
			}
		} else
			rpmsg_send_offchannel(rpdev, ept->addr, rpdev->dst,
						r_buffer, data_length);

		if (uninit)
			break;
	}

	call_usermodehelper(shutdown_argv[0], shutdown_argv, NULL, UMH_NO_WAIT);

	return 0;
}
int rpmsg_send_command(struct rpmsg_instance *instance, u32 cmd,
						u32 sub, u8 *in,
						u32 *out, u32 inlen,
						u32 outlen)
{
	int ret = 0;

	if (!instance) {
		pr_err("%s: Instance is NULL\n", __func__);
		return -EFAULT;
	}

	/* Hold global rpmsg lock */
	rpmsg_lock();

	mutex_lock(&instance->instance_lock);

	/* Prepare Tx buffer */
	instance->tx_msg->cmd = cmd;
	instance->tx_msg->sub = sub;
	instance->tx_msg->in = in;
	instance->tx_msg->out = out;
	instance->tx_msg->inlen = inlen;
	instance->tx_msg->outlen = outlen;

	/* Preapre Rx buffer */
	mutex_lock(&instance->rx_lock);
	instance->rx_msg->status = -1;
	mutex_unlock(&instance->rx_lock);
	INIT_COMPLETION(instance->reply_arrived);

	/* Send message to remote processor(SCU) using rpdev channel */
	ret = rpmsg_send_offchannel(
					instance->rpdev,
					instance->endpoint->addr,
					instance->rpdev->dst,
					instance->tx_msg,
					sizeof(*instance->tx_msg)
					);
	if (ret) {
		dev_err(&instance->rpdev->dev, "%s failed: %d\n",
						 __func__, ret);
		goto end;
	}

	if (0 == wait_for_completion_timeout(&instance->reply_arrived,
						RPMSG_TX_TIMEOUT)) {
		dev_err(&instance->rpdev->dev,
				"timeout: %d\n", ret);
		ret = -ETIMEDOUT;
		goto end;
	}

	mutex_lock(&instance->rx_lock);
	ret = instance->rx_msg->status;
	mutex_unlock(&instance->rx_lock);
end:
	mutex_unlock(&instance->instance_lock);
	rpmsg_unlock();

	return ret;
}
Пример #3
0
static void rpmsg_func_test_ept_rx_cb(struct rpmsg_channel *rpdev,
			void *data, int len, void *priv, u32 src)
{
	rpmsg_send_offchannel(rpdev, rp_ept->addr, src, data, len);
}
Пример #4
0
void rpmsg_read_ept_cb(struct rpmsg_channel *rp_chnl, void *data, int len,
		       void *priv, unsigned long src)
{
	rpmsg_send_offchannel(rp_chnl, rp_ept->addr, src, data, len);
}