diff options
author | Jeremy Kerr <jk@ozlabs.org> | 2017-05-26 12:54:22 +1000 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2017-06-06 17:59:45 +1000 |
commit | 63e4b8884579db64205b1d6cf1f659a1a2c8cb4a (patch) | |
tree | 7ebe49611778aa1442c8c4bec688c4a9748826cc /external/opal-prd | |
parent | 05dd64a57788a44df406a4553a75ee57c2b7cd82 (diff) | |
download | skiboot-63e4b8884579db64205b1d6cf1f659a1a2c8cb4a.zip skiboot-63e4b8884579db64205b1d6cf1f659a1a2c8cb4a.tar.gz skiboot-63e4b8884579db64205b1d6cf1f659a1a2c8cb4a.tar.bz2 |
opal-prd: allow different chips for occ control actions
The `occ reset` and `occ error` actions can both take a chip id
argument, but we're currently just using zero. This change changes the
control message format to pass the chip ID from the control process to
the opal-prd daemon.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Reviewed-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'external/opal-prd')
-rw-r--r-- | external/opal-prd/opal-prd.c | 95 |
1 files changed, 68 insertions, 27 deletions
diff --git a/external/opal-prd/opal-prd.c b/external/opal-prd/opal-prd.c index 5e8f798..3588e9b 100644 --- a/external/opal-prd/opal-prd.c +++ b/external/opal-prd/opal-prd.c @@ -100,6 +100,12 @@ struct control_msg { struct { unsigned int argc; } run_cmd; + struct { + uint64_t chip; + } occ_reset; + struct { + uint64_t chip; + } occ_error; }; unsigned int data_len; unsigned char data[]; @@ -1255,30 +1261,51 @@ static int handle_prd_msg(struct opal_prd_ctx *ctx) return 0; } -static void handle_prd_control_occ_error(struct control_msg *msg) +static void handle_prd_control_occ_error(struct control_msg *send_msg, + struct control_msg *recv_msg) { + uint64_t chip; + if (!hservice_runtime->process_occ_error) { pr_log_nocall("process_occ_error"); return; } - pr_debug("CTRL: calling process_occ_error(0)"); - call_process_occ_error(0); - msg->data_len = 0; - msg->response = 0; + chip = recv_msg->occ_error.chip; + + pr_debug("CTRL: calling process_occ_error(%lu)", chip); + call_process_occ_error(chip); + + send_msg->data_len = 0; + send_msg->response = 0; } -static void handle_prd_control_occ_reset(struct control_msg *msg) +static void handle_prd_control_occ_reset(struct control_msg *send_msg, + struct control_msg *msg) { + struct opal_prd_msg omsg; + uint64_t chip; + int rc; + + /* notify OPAL of the impending reset */ + memset(&omsg, 0, sizeof(omsg)); + omsg.hdr.type = OPAL_PRD_MSG_TYPE_OCC_RESET_NOTIFY; + omsg.hdr.size = htobe16(sizeof(omsg)); + rc = write(ctx->fd, &omsg, sizeof(omsg)); + if (rc != sizeof(omsg)) + pr_log(LOG_WARNING, "FW: Failed to send OCC_RESET message: %m"); + 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; + chip = msg->occ_reset.chip; + + pr_debug("CTRL: calling process_occ_reset(%ld)", chip); + call_process_occ_reset(chip); + send_msg->data_len = 0; + send_msg->response = 0; } static void handle_prd_control_occ_actuation(struct control_msg *msg, @@ -1386,7 +1413,6 @@ static void handle_prd_control_run_cmd(struct control_msg *send_msg, static void handle_prd_control(struct opal_prd_ctx *ctx, int fd) { struct control_msg msg, *recv_msg, *send_msg; - struct opal_prd_msg omsg; bool enabled = false; int rc, size; @@ -1439,15 +1465,10 @@ static void handle_prd_control(struct opal_prd_ctx *ctx, int fd) handle_prd_control_occ_actuation(send_msg, enabled); break; case CONTROL_MSG_TEMP_OCC_RESET: - omsg.hdr.type = OPAL_PRD_MSG_TYPE_OCC_RESET_NOTIFY; - omsg.hdr.size = htobe16(sizeof(omsg)); - rc = write(ctx->fd, &omsg, sizeof(omsg)); - if (rc != sizeof(omsg)) - pr_log(LOG_WARNING, "FW: Failed to send OCC_RESET message: %m"); - handle_prd_control_occ_reset(send_msg); + handle_prd_control_occ_reset(send_msg, recv_msg); break; case CONTROL_MSG_TEMP_OCC_ERROR: - handle_prd_control_occ_error(send_msg); + handle_prd_control_occ_error(send_msg, recv_msg); break; case CONTROL_MSG_ATTR_OVERRIDE: handle_prd_control_attr_override(send_msg, recv_msg); @@ -1743,30 +1764,50 @@ out_close: return rc; } -static int send_occ_control(struct opal_prd_ctx *ctx, const char *str) +static int send_occ_control(struct opal_prd_ctx *ctx, int argc, char *argv[]) { struct control_msg send_msg, *recv_msg = NULL; + unsigned long chip = 0; + const char *op; int rc; + assert(argc >= 1); + op = argv[0]; + + /* some commands accept a 'chip' argument, so parse it here */ + if (argc > 1) { + char *arg, *end; + arg = argv[1]; + chip = strtoul(arg, &end, 0); + if (end == arg) { + pr_log(LOG_ERR, "CTRL: invalid argument %s", arg); + return -1; + } + } + memset(&send_msg, 0, sizeof(send_msg)); - if (!strcmp(str, "enable")) + if (!strcmp(op, "enable")) send_msg.type = CONTROL_MSG_ENABLE_OCCS; - else if (!strcmp(str, "disable")) + else if (!strcmp(op, "disable")) send_msg.type = CONTROL_MSG_DISABLE_OCCS; - else if (!strcmp(str, "reset")) + + else if (!strcmp(op, "reset")) { send_msg.type = CONTROL_MSG_TEMP_OCC_RESET; - else if (!strcmp(str, "process-error")) + send_msg.occ_reset.chip = (uint64_t)chip; + + } else if (!strcmp(op, "process-error")) { send_msg.type = CONTROL_MSG_TEMP_OCC_ERROR; - else { - pr_log(LOG_ERR, "CTRL: Invalid OCC action '%s'", str); + send_msg.occ_error.chip = (uint64_t)chip; + } else { + pr_log(LOG_ERR, "CTRL: Invalid OCC action '%s'", op); return -1; } rc = send_prd_control(&send_msg, &recv_msg); if (recv_msg) { if (recv_msg->response || ctx->debug) - pr_debug("CTRL: OCC action %s returned status %d", str, + pr_debug("CTRL: OCC action %s returned status %d", op, recv_msg->response); free(recv_msg); } @@ -2069,7 +2110,7 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } - rc = send_occ_control(ctx, argv[optind]); + rc = send_occ_control(ctx, argc - optind, &argv[optind]); break; case ACTION_ATTR_OVERRIDE: if (optind >= argc) { |