Пример #1
0
static int handle_msg_attn(struct opal_prd_ctx *ctx, struct opal_prd_msg *msg)
{
	uint64_t proc, ipoll_mask, ipoll_status;
	int rc;

	proc = be64toh(msg->attn.proc);
	ipoll_status = be64toh(msg->attn.ipoll_status);
	ipoll_mask = be64toh(msg->attn.ipoll_mask);

	if (!hservice_runtime->handle_attns) {
		pr_log_nocall("handle_attns");
		return -1;
	}

	rc = call_handle_attns(proc, ipoll_status, ipoll_mask);
	if (rc) {
		pr_log(LOG_ERR, "HBRT: handle_attns(%lx,%lx,%lx) failed, rc %d",
				proc, ipoll_status, ipoll_mask, rc);
		return -1;
	}

	/* send the response */
	msg->hdr.type = OPAL_PRD_MSG_TYPE_ATTN_ACK;
	msg->hdr.size = htobe16(sizeof(*msg));
	msg->attn_ack.proc = htobe64(proc);
	msg->attn_ack.ipoll_ack = htobe64(ipoll_status);
	rc = write(ctx->fd, msg, sizeof(*msg));

	if (rc != sizeof(*msg)) {
		pr_log(LOG_WARNING, "FW: Failed to send ATTN_ACK message: %m");
		return -1;
	}

	return 0;
}
Пример #2
0
static void handle_prd_control_occ_reset(struct control_msg *msg)
{
	if (!hservice_runtime->process_occ_reset) {
		pr_log_nocall("process_occ_reset");
		return;
	}

	pr_debug("CTRL: calling process_occ_reset(0)");
	call_process_occ_reset(0);
	msg->data_len = 0;
	msg->response = 0;
}
Пример #3
0
static void handle_prd_control_attr_override(struct control_msg *send_msg,
					     struct control_msg *recv_msg)
{
	if (!hservice_runtime->apply_attr_override) {
		pr_log_nocall("apply_attr_override");
		return;
	}

	pr_debug("CTRL: calling apply_attr_override");
	send_msg->response = call_apply_attr_override(
			recv_msg->data, recv_msg->data_len);
	send_msg->data_len = 0;
}
Пример #4
0
static void handle_prd_control_occ_actuation(struct control_msg *msg,
					     bool enable)
{
	if (!hservice_runtime->enable_occ_actuation) {
		pr_log_nocall("enable_occ_actuation");
		return;
	}

	pr_debug("CTRL: calling enable_occ_actuation(%s)",
			enable ? "true" : "false");
	msg->data_len = 0;
	msg->response = call_enable_occ_actuation(enable);
}
Пример #5
0
static void handle_prd_control_run_cmd(struct control_msg *send_msg,
				       struct control_msg *recv_msg)
{
	char *runcmd_output, *s;
	const char **argv;
	int i, argc;
	size_t size;

	if (!hservice_runtime->run_command) {
		pr_log_nocall("run_command");
		return;
	}

	argc = recv_msg->argc;
	pr_debug("CTRL: run_command, argc:%d\n", argc);

	argv = malloc(argc * sizeof(*argv));
	if (!argv) {
		pr_log(LOG_ERR, "CTRL: argv buffer malloc failed: %m");
		return;
	}

	s = (char *)recv_msg->data;
	size = 0;
	for (i = 0; i < argc; i++) {
		argv[i] = (char *)htobe64((uint64_t)&s[size]);
		size += (strlen(&s[size]) + 1);
	}

	/* Call HBRT */
	send_msg->response = call_run_command(argc, argv, &runcmd_output);
	runcmd_output = (char *)be64toh((uint64_t)runcmd_output);
	free(argv);

	s = (char *)send_msg->data;
	if (runcmd_output) {
		size = strlen(runcmd_output);
		if (size >= MAX_CONTROL_MSG_BUF) {
			pr_log(LOG_WARNING, "CTRL: output message truncated");
			runcmd_output[MAX_CONTROL_MSG_BUF] = '\0';
			size = MAX_CONTROL_MSG_BUF;
		}

		strcpy(s, runcmd_output);
		send_msg->data_len = size + 1;
		free(runcmd_output);
	} else {
		strcpy(s, "Null");
		send_msg->data_len = strlen("Null") + 1;
	}
}
Пример #6
0
static int handle_msg_occ_reset(struct opal_prd_ctx *ctx,
		struct opal_prd_msg *msg)
{
	uint32_t proc;

	proc = be64toh(msg->occ_reset.chip);

	if (!hservice_runtime->process_occ_reset) {
		pr_log_nocall("process_occ_reset");
		return -1;
	}

	call_process_occ_reset(proc);
	return 0;
}
Пример #7
0
static int handle_msg_occ_reset(struct opal_prd_ctx *ctx,
		struct opal_prd_msg *msg)
{
	uint32_t proc;

	proc = be64toh(msg->occ_reset.chip);

	pr_debug("FW: firmware requested OCC reset for proc 0x%x", proc);

	if (!hservice_runtime->process_occ_reset) {
		pr_log_nocall("process_occ_reset");
		return -1;
	}

	call_process_occ_reset(proc);
	return 0;
}
Пример #8
0
static int handle_msg_occ_error(struct opal_prd_ctx *ctx,
		struct opal_prd_msg *msg)
{
	uint32_t proc;

	proc = be64toh(msg->occ_error.chip);

	pr_debug("FW: firmware signalled OCC error for proc 0x%x", proc);

	if (!hservice_runtime->process_occ_error) {
		pr_log_nocall("process_occ_error");
		return -1;
	}

	call_process_occ_error(proc);
	return 0;
}
Пример #9
0
static void handle_prd_control_htmgt_passthru(struct control_msg *send_msg,
					      struct control_msg *recv_msg)
{
	uint16_t rsp_len;

	if (!hservice_runtime->mfg_htmgt_pass_thru) {
		pr_log_nocall("mfg_htmgt_pass_thru");
		return;
	}

	pr_debug("CTRL: calling mfg_htmgt_pass_thru");
	send_msg->response = call_mfg_htmgt_pass_thru(recv_msg->data_len,
						      recv_msg->data, &rsp_len,
						      send_msg->data);
	send_msg->data_len = be16toh(rsp_len);
	if (send_msg->data_len > MAX_CONTROL_MSG_BUF) {
		pr_log(LOG_ERR, "CTRL: response buffer overrun, data len: %d",
				send_msg->data_len);
		send_msg->data_len = MAX_CONTROL_MSG_BUF;
	}
}
Пример #10
0
static int handle_prd_control(struct opal_prd_ctx *ctx, int fd)
{
	struct control_msg msg;
	bool enabled;
	int rc;

	rc = recv(fd, &msg, sizeof(msg), MSG_TRUNC);
	if (rc != sizeof(msg)) {
		pr_log(LOG_WARNING, "CTRL: failed to receive "
				"control message: %m");
		return -1;
	}

	enabled = false;
	rc = -1;

	switch (msg.type) {
	case CONTROL_MSG_ENABLE_OCCS:
		enabled = true;
		/* fall through */
	case CONTROL_MSG_DISABLE_OCCS:
		if (!hservice_runtime->enable_occ_actuation) {
			pr_log_nocall("enable_occ_actuation");
		} else {
			pr_debug("CTRL: calling enable_occ_actuation(%s)",
					enabled ? "true" : "false");
			rc = call_enable_occ_actuation(enabled);
			pr_debug("CTRL:  -> %d", rc);
		}
		break;
	case CONTROL_MSG_TEMP_OCC_RESET:
		if (hservice_runtime->process_occ_reset) {
			pr_debug("CTRL: calling process_occ_reset(0)");
			call_process_occ_reset(0);
			rc = 0;
		} else {
			pr_log_nocall("process_occ_reset");
		}
		break;
	case CONTROL_MSG_TEMP_OCC_ERROR:
		if (hservice_runtime->process_occ_error) {
			pr_debug("CTRL: calling process_occ_error(0)");
			call_process_occ_error(0);
			rc = 0;
		} else {
			pr_log_nocall("process_occ_error");
		}
		break;
	default:
		pr_log(LOG_WARNING, "CTRL: Unknown control message action %d",
				msg.type);
	}

	/* send a response */
	msg.response = rc;
	rc = send(fd, &msg, sizeof(msg), MSG_DONTWAIT | MSG_NOSIGNAL);
	if (rc && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EPIPE))
		pr_debug("CTRL: control send() returned %d, ignoring failure",
				rc);
	else if (rc != sizeof(msg))
		pr_log(LOG_NOTICE, "CTRL: Failed to send control response: %m");

	return 0;
}