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; }
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; }
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; }
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); }
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; } }
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; }
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; }
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; }
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; } }
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; }