aboutsummaryrefslogtreecommitdiff
path: root/external
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2017-05-26 12:54:22 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-06-06 17:59:45 +1000
commit63e4b8884579db64205b1d6cf1f659a1a2c8cb4a (patch)
tree7ebe49611778aa1442c8c4bec688c4a9748826cc /external
parent05dd64a57788a44df406a4553a75ee57c2b7cd82 (diff)
downloadskiboot-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')
-rw-r--r--external/opal-prd/opal-prd.c95
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) {