xref: /openbmc/hiomapd/control_legacy.c (revision 55f4d6f9117f692a71d5bdd51a48dc3b4e553b84)
168023074SAndrew Jeffery // SPDX-License-Identifier: Apache-2.0
268023074SAndrew Jeffery // Copyright (C) 2018 IBM Corp.
368023074SAndrew Jeffery #include <errno.h>
468023074SAndrew Jeffery #include <stdlib.h>
568023074SAndrew Jeffery 
668023074SAndrew Jeffery #include "common.h"
768023074SAndrew Jeffery #include "dbus.h"
8*55f4d6f9SAndrew Jeffery #include "control_dbus.h"
968023074SAndrew Jeffery #include "mbox.h"
1068023074SAndrew Jeffery 
1168023074SAndrew Jeffery /*
1268023074SAndrew Jeffery  * Command: DBUS Ping
1368023074SAndrew Jeffery  * Ping the daemon
1468023074SAndrew Jeffery  *
1568023074SAndrew Jeffery  * Args: NONE
1668023074SAndrew Jeffery  * Resp: NONE
1768023074SAndrew Jeffery  */
1868023074SAndrew Jeffery static int control_legacy_ping(struct mbox_context *context,
1968023074SAndrew Jeffery 			   struct mbox_dbus_msg *req,
2068023074SAndrew Jeffery 			   struct mbox_dbus_msg *resp)
2168023074SAndrew Jeffery {
2268023074SAndrew Jeffery 	return control_ping(context);
2368023074SAndrew Jeffery }
2468023074SAndrew Jeffery 
2568023074SAndrew Jeffery /*
2668023074SAndrew Jeffery  * Command: DBUS Status
2768023074SAndrew Jeffery  * Get the status of the daemon
2868023074SAndrew Jeffery  *
2968023074SAndrew Jeffery  * Args: NONE
3068023074SAndrew Jeffery  * Resp[0]: Status Code
3168023074SAndrew Jeffery  */
3268023074SAndrew Jeffery static int control_legacy_daemon_state(struct mbox_context *context,
3368023074SAndrew Jeffery 					  struct mbox_dbus_msg *req,
3468023074SAndrew Jeffery 					  struct mbox_dbus_msg *resp)
3568023074SAndrew Jeffery {
3668023074SAndrew Jeffery 	resp->num_args = DAEMON_STATE_NUM_ARGS;
3768023074SAndrew Jeffery 	resp->args = calloc(resp->num_args, sizeof(*resp->args));
3868023074SAndrew Jeffery 	resp->args[0] = control_daemon_state(context);
3968023074SAndrew Jeffery 
4068023074SAndrew Jeffery 	return 0;
4168023074SAndrew Jeffery }
4268023074SAndrew Jeffery 
4368023074SAndrew Jeffery /*
4468023074SAndrew Jeffery  * Command: DBUS LPC State
4568023074SAndrew Jeffery  * Get the state of the lpc bus mapping (whether it points to memory or flash
4668023074SAndrew Jeffery  *
4768023074SAndrew Jeffery  * Args: NONE
4868023074SAndrew Jeffery  * Resp[0]: LPC Bus State Code
4968023074SAndrew Jeffery  */
5068023074SAndrew Jeffery static int control_legacy_lpc_state(struct mbox_context *context,
5168023074SAndrew Jeffery 				       struct mbox_dbus_msg *req,
5268023074SAndrew Jeffery 				       struct mbox_dbus_msg *resp)
5368023074SAndrew Jeffery {
5468023074SAndrew Jeffery 	resp->num_args = LPC_STATE_NUM_ARGS;
5568023074SAndrew Jeffery 	resp->args = calloc(resp->num_args, sizeof(*resp->args));
5668023074SAndrew Jeffery 	resp->args[0] = control_lpc_state(context);
5768023074SAndrew Jeffery 
5868023074SAndrew Jeffery 	return 0;
5968023074SAndrew Jeffery }
6068023074SAndrew Jeffery 
6168023074SAndrew Jeffery /*
6268023074SAndrew Jeffery  * Command: DBUS Reset
6368023074SAndrew Jeffery  * Reset the daemon state, final operation TBA.
6468023074SAndrew Jeffery  * For now we just point the lpc mapping back at the flash.
6568023074SAndrew Jeffery  *
6668023074SAndrew Jeffery  * Args: NONE
6768023074SAndrew Jeffery  * Resp: NONE
6868023074SAndrew Jeffery  */
6968023074SAndrew Jeffery static int control_legacy_reset(struct mbox_context *context,
7068023074SAndrew Jeffery 				   struct mbox_dbus_msg *req,
7168023074SAndrew Jeffery 				   struct mbox_dbus_msg *resp)
7268023074SAndrew Jeffery {
7368023074SAndrew Jeffery 	int rc;
7468023074SAndrew Jeffery 
7568023074SAndrew Jeffery 	rc = control_reset(context);
7668023074SAndrew Jeffery 
7768023074SAndrew Jeffery 	/* Map return codes for compatibility */
7868023074SAndrew Jeffery 	if (rc == -EBUSY) {
7968023074SAndrew Jeffery 		return -E_DBUS_REJECTED;
8068023074SAndrew Jeffery 	} else if (rc < 0) {
8168023074SAndrew Jeffery 		return -E_DBUS_HARDWARE;
8268023074SAndrew Jeffery 	}
8368023074SAndrew Jeffery 
8468023074SAndrew Jeffery 	return rc;
8568023074SAndrew Jeffery }
8668023074SAndrew Jeffery 
8768023074SAndrew Jeffery /*
8868023074SAndrew Jeffery  * Command: DBUS Kill
8968023074SAndrew Jeffery  * Stop the daemon
9068023074SAndrew Jeffery  *
9168023074SAndrew Jeffery  * Args: NONE
9268023074SAndrew Jeffery  * Resp: NONE
9368023074SAndrew Jeffery  */
9468023074SAndrew Jeffery static int control_legacy_kill(struct mbox_context *context,
9568023074SAndrew Jeffery 				  struct mbox_dbus_msg *req,
9668023074SAndrew Jeffery 				  struct mbox_dbus_msg *resp)
9768023074SAndrew Jeffery {
9868023074SAndrew Jeffery 	return control_kill(context);
9968023074SAndrew Jeffery }
10068023074SAndrew Jeffery 
10168023074SAndrew Jeffery /*
10268023074SAndrew Jeffery  * Command: DBUS Flash Modified
10368023074SAndrew Jeffery  * Used to notify the daemon that the flash has been modified out from under
10468023074SAndrew Jeffery  * it - We need to reset all out windows to ensure flash will be reloaded
10568023074SAndrew Jeffery  * when a new window is opened.
10668023074SAndrew Jeffery  * Note: We don't flush any previously opened windows
10768023074SAndrew Jeffery  *
10868023074SAndrew Jeffery  * Args: NONE
10968023074SAndrew Jeffery  * Resp: NONE
11068023074SAndrew Jeffery  */
11168023074SAndrew Jeffery static int control_legacy_modified(struct mbox_context *context,
11268023074SAndrew Jeffery 				      struct mbox_dbus_msg *req,
11368023074SAndrew Jeffery 				      struct mbox_dbus_msg *resp)
11468023074SAndrew Jeffery {
11568023074SAndrew Jeffery 	return control_modified(context);
11668023074SAndrew Jeffery }
11768023074SAndrew Jeffery 
11868023074SAndrew Jeffery /*
11968023074SAndrew Jeffery  * Command: DBUS Suspend
12068023074SAndrew Jeffery  * Suspend the daemon to inhibit it from performing flash accesses.
12168023074SAndrew Jeffery  * This is used to synchronise access to the flash between the daemon and
12268023074SAndrew Jeffery  * directly from the BMC.
12368023074SAndrew Jeffery  *
12468023074SAndrew Jeffery  * Args: NONE
12568023074SAndrew Jeffery  * Resp: NONE
12668023074SAndrew Jeffery  */
12768023074SAndrew Jeffery static int control_legacy_suspend(struct mbox_context *context,
12868023074SAndrew Jeffery 				     struct mbox_dbus_msg *req,
12968023074SAndrew Jeffery 				     struct mbox_dbus_msg *resp)
13068023074SAndrew Jeffery {
13168023074SAndrew Jeffery 	int rc;
13268023074SAndrew Jeffery 
13368023074SAndrew Jeffery 	rc = control_suspend(context);
13468023074SAndrew Jeffery 	if (rc < 0) {
13568023074SAndrew Jeffery 		/* Map return codes for compatibility */
13668023074SAndrew Jeffery 		return -E_DBUS_HARDWARE;
13768023074SAndrew Jeffery 	}
13868023074SAndrew Jeffery 
13968023074SAndrew Jeffery 	return rc;
14068023074SAndrew Jeffery }
14168023074SAndrew Jeffery 
14268023074SAndrew Jeffery /*
14368023074SAndrew Jeffery  * Command: DBUS Resume
14468023074SAndrew Jeffery  * Resume the daemon to let it perform flash accesses again.
14568023074SAndrew Jeffery  *
14668023074SAndrew Jeffery  * Args[0]: Flash Modified (0 - no | 1 - yes)
14768023074SAndrew Jeffery  * Resp: NONE
14868023074SAndrew Jeffery  */
14968023074SAndrew Jeffery static int control_legacy_resume(struct mbox_context *context,
15068023074SAndrew Jeffery 				    struct mbox_dbus_msg *req,
15168023074SAndrew Jeffery 				    struct mbox_dbus_msg *resp)
15268023074SAndrew Jeffery {
15368023074SAndrew Jeffery 	int rc;
15468023074SAndrew Jeffery 
15568023074SAndrew Jeffery 	if (req->num_args != 1) {
15668023074SAndrew Jeffery 		return -E_DBUS_INVAL;
15768023074SAndrew Jeffery 	}
15868023074SAndrew Jeffery 
15968023074SAndrew Jeffery 	rc = control_resume(context, req->args[0] == RESUME_FLASH_MODIFIED);
16068023074SAndrew Jeffery 	if (rc < 0) {
16168023074SAndrew Jeffery 		/* Map return codes for compatibility */
16268023074SAndrew Jeffery 		rc = -E_DBUS_HARDWARE;
16368023074SAndrew Jeffery 	}
16468023074SAndrew Jeffery 
16568023074SAndrew Jeffery 	return rc;
16668023074SAndrew Jeffery }
16768023074SAndrew Jeffery 
16868023074SAndrew Jeffery typedef int (*control_action)(struct mbox_context *context,
16968023074SAndrew Jeffery 				 struct mbox_dbus_msg *req,
17068023074SAndrew Jeffery 				 struct mbox_dbus_msg *resp);
17168023074SAndrew Jeffery static const control_action dbus_handlers[NUM_DBUS_CMDS] = {
17268023074SAndrew Jeffery 	control_legacy_ping,
17368023074SAndrew Jeffery 	control_legacy_daemon_state,
17468023074SAndrew Jeffery 	control_legacy_reset,
17568023074SAndrew Jeffery 	control_legacy_suspend,
17668023074SAndrew Jeffery 	control_legacy_resume,
17768023074SAndrew Jeffery 	control_legacy_modified,
17868023074SAndrew Jeffery 	control_legacy_kill,
17968023074SAndrew Jeffery 	control_legacy_lpc_state
18068023074SAndrew Jeffery };
18168023074SAndrew Jeffery 
18268023074SAndrew Jeffery static int method_cmd(sd_bus_message *m, void *userdata,
18368023074SAndrew Jeffery 		      sd_bus_error *ret_error)
18468023074SAndrew Jeffery {
18568023074SAndrew Jeffery 	struct mbox_dbus_msg req = { 0 }, resp = { 0 };
18668023074SAndrew Jeffery 	struct mbox_context *context;
18768023074SAndrew Jeffery 	sd_bus_message *n;
18868023074SAndrew Jeffery 	int rc, i;
18968023074SAndrew Jeffery 
19068023074SAndrew Jeffery 	context = (struct mbox_context *) userdata;
19168023074SAndrew Jeffery 	if (!context) {
19268023074SAndrew Jeffery 		MSG_ERR("DBUS Internal Error\n");
19368023074SAndrew Jeffery 		rc = -E_DBUS_INTERNAL;
19468023074SAndrew Jeffery 		goto out;
19568023074SAndrew Jeffery 	}
19668023074SAndrew Jeffery 
19768023074SAndrew Jeffery 	/* Read the command */
19868023074SAndrew Jeffery 	rc = sd_bus_message_read(m, "y", &req.cmd);
19968023074SAndrew Jeffery 	if (rc < 0) {
20068023074SAndrew Jeffery 		MSG_ERR("DBUS error reading message: %s\n", strerror(-rc));
20168023074SAndrew Jeffery 		rc = -E_DBUS_INTERNAL;
20268023074SAndrew Jeffery 		goto out;
20368023074SAndrew Jeffery 	}
20468023074SAndrew Jeffery 	MSG_DBG("DBUS request: %u\n", req.cmd);
20568023074SAndrew Jeffery 
20668023074SAndrew Jeffery 	/* Read the args */
20768023074SAndrew Jeffery 	rc = sd_bus_message_read_array(m, 'y', (const void **) &req.args,
20868023074SAndrew Jeffery 				       &req.num_args);
20968023074SAndrew Jeffery 	if (rc < 0) {
21068023074SAndrew Jeffery 		MSG_ERR("DBUS error reading message: %s\n", strerror(-rc));
21168023074SAndrew Jeffery 		rc = -E_DBUS_INTERNAL;
21268023074SAndrew Jeffery 		goto out;
21368023074SAndrew Jeffery 	}
21468023074SAndrew Jeffery 	MSG_DBG("DBUS num_args: %u\n", (unsigned) req.num_args);
21568023074SAndrew Jeffery 	for (i = 0; i < req.num_args; i++) {
21668023074SAndrew Jeffery 		MSG_DBG("DBUS arg[%d]: %u\n", i, req.args[i]);
21768023074SAndrew Jeffery 	}
21868023074SAndrew Jeffery 
21968023074SAndrew Jeffery 	/* Handle the command */
22068023074SAndrew Jeffery 	if (req.cmd >= NUM_DBUS_CMDS) {
22168023074SAndrew Jeffery 		rc = -E_DBUS_INVAL;
22268023074SAndrew Jeffery 		MSG_ERR("Received unknown dbus cmd: %d\n", req.cmd);
22368023074SAndrew Jeffery 	} else {
22468023074SAndrew Jeffery 		rc = dbus_handlers[req.cmd](context, &req, &resp);
22568023074SAndrew Jeffery 	}
22668023074SAndrew Jeffery 
22768023074SAndrew Jeffery out:
22868023074SAndrew Jeffery 	if (rc < 0) {
22968023074SAndrew Jeffery 		resp.cmd = -rc;
23068023074SAndrew Jeffery 	}
23168023074SAndrew Jeffery 	rc = sd_bus_message_new_method_return(m, &n); /* Generate response */
23268023074SAndrew Jeffery 	if (rc < 0) {
23368023074SAndrew Jeffery 		MSG_ERR("sd_bus_message_new_method_return failed: %d\n", rc);
23468023074SAndrew Jeffery 		goto cleanup;
23568023074SAndrew Jeffery 	}
23668023074SAndrew Jeffery 
23768023074SAndrew Jeffery 	rc = sd_bus_message_append(n, "y", resp.cmd); /* Set return code */
23868023074SAndrew Jeffery 	if (rc < 0) {
23968023074SAndrew Jeffery 		MSG_ERR("sd_bus_message_append failed: %d\n", rc);
24068023074SAndrew Jeffery 		goto cleanup;
24168023074SAndrew Jeffery 	}
24268023074SAndrew Jeffery 
24368023074SAndrew Jeffery 	rc = sd_bus_message_append_array(n, 'y', resp.args, resp.num_args);
24468023074SAndrew Jeffery 	if (rc < 0) {
24568023074SAndrew Jeffery 		MSG_ERR("sd_bus_message_append_array failed: %d\n", rc);
24668023074SAndrew Jeffery 		goto cleanup;
24768023074SAndrew Jeffery 	}
24868023074SAndrew Jeffery 
24968023074SAndrew Jeffery 	MSG_DBG("DBUS response: %u\n", resp.cmd);
25068023074SAndrew Jeffery 	MSG_DBG("DBUS num_args: %u\n", (unsigned) resp.num_args);
25168023074SAndrew Jeffery 	for (i = 0; i < resp.num_args; i++) {
25268023074SAndrew Jeffery 		MSG_DBG("DBUS arg[%d]: %u\n", i, resp.args[i]);
25368023074SAndrew Jeffery 	}
25468023074SAndrew Jeffery 
25568023074SAndrew Jeffery 	rc = sd_bus_send(NULL, n, NULL); /* Send response */
25668023074SAndrew Jeffery 	if (rc < 0)
25768023074SAndrew Jeffery 		MSG_ERR("sd_bus_send failed: %d\n", rc);
25868023074SAndrew Jeffery 
25968023074SAndrew Jeffery cleanup:
26068023074SAndrew Jeffery 	free(resp.args);
26168023074SAndrew Jeffery 	return rc;
26268023074SAndrew Jeffery }
26368023074SAndrew Jeffery 
26468023074SAndrew Jeffery static const sd_bus_vtable control_legacy_vtable[] = {
26568023074SAndrew Jeffery 	SD_BUS_VTABLE_START(0),
26668023074SAndrew Jeffery 	SD_BUS_METHOD("cmd", "yay", "yay", &method_cmd,
26768023074SAndrew Jeffery 		      SD_BUS_VTABLE_UNPRIVILEGED),
26868023074SAndrew Jeffery 	SD_BUS_VTABLE_END
26968023074SAndrew Jeffery };
27068023074SAndrew Jeffery 
27168023074SAndrew Jeffery int control_legacy_init(struct mbox_context *context)
27268023074SAndrew Jeffery {
27368023074SAndrew Jeffery 	int rc;
27468023074SAndrew Jeffery 
27568023074SAndrew Jeffery 	rc = sd_bus_add_object_vtable(context->bus, NULL,
27668023074SAndrew Jeffery 				      MBOX_DBUS_LEGACY_OBJECT,
27768023074SAndrew Jeffery 				      MBOX_DBUS_LEGACY_NAME,
27868023074SAndrew Jeffery 				      control_legacy_vtable, context);
27968023074SAndrew Jeffery 	if (rc < 0) {
28068023074SAndrew Jeffery 		MSG_ERR("Failed to register vtable: %s\n", strerror(-rc));
28168023074SAndrew Jeffery 		return rc;
28268023074SAndrew Jeffery 	}
28368023074SAndrew Jeffery 
28468023074SAndrew Jeffery 	return sd_bus_request_name(context->bus, MBOX_DBUS_LEGACY_NAME,
28568023074SAndrew Jeffery 				 SD_BUS_NAME_ALLOW_REPLACEMENT |
28668023074SAndrew Jeffery 				 SD_BUS_NAME_REPLACE_EXISTING);
28768023074SAndrew Jeffery }
28868023074SAndrew Jeffery 
28968023074SAndrew Jeffery void control_legacy_free(struct mbox_context *context __attribute__((unused)))
29068023074SAndrew Jeffery {
29168023074SAndrew Jeffery 	return;
29268023074SAndrew Jeffery }
293