summaryrefslogtreecommitdiffstats
path: root/control.c
blob: 4b73efafadbf40badd7014cc4e3941283af70a07 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2018 IBM Corp.
#include <errno.h>
#include <stdlib.h>

#include "backend.h"
#include "common.h"
#include "dbus.h"
#include "lpc.h"
#include "mboxd.h"
#include "protocol.h"
#include "windows.h"

int control_ping(struct mbox_context *context)
{
	return 0;
}

int control_daemon_state(struct mbox_context *context)
{
	return (context->state & STATE_SUSPENDED) ?
		DAEMON_STATE_SUSPENDED : DAEMON_STATE_ACTIVE;
}

int control_lpc_state(struct mbox_context *context)
{
	if ((context->state & MAPS_MEM) && !(context->state & MAPS_FLASH)) {
		return LPC_STATE_MEM;
	} else if (!(context->state & MAPS_MEM) &&
		   (context->state & MAPS_FLASH)) {
		return LPC_STATE_FLASH;
	}

	return LPC_STATE_INVALID;
}

int control_reset(struct mbox_context *context)
{
	/* We don't let the host access flash if the daemon is suspened */
	if (context->state & STATE_SUSPENDED) {
		return -EBUSY;
	}

	/* FIXME: Comment below is wrong: windows_reset_all() does not flush! */
	/*
	 * This will close (and flush) the current window and reset the lpc bus
	 * mapping back to flash, or memory in case we're using a virtual pnor.
	 * Better set the bmc event to notify the host of this.
	 */
	return protocol_reset(context);
}

int control_kill(struct mbox_context *context)
{
	context->terminate = 1;

	MSG_INFO("DBUS Kill - Exiting...\n");

	return 0;
}

int control_modified(struct mbox_context *context)
{
	/* Flash has been modified - can no longer trust our erased bytemap */
	backend_set_bytemap(&context->backend, 0, context->backend.flash_size,
			    FLASH_DIRTY);

	/* Force daemon to reload all windows -> Set BMC event to notify host */
	if (windows_reset_all(context)) {
		protocol_events_set(context, BMC_EVENT_WINDOW_RESET);
	}

	return 0;
}

int control_suspend(struct mbox_context *context)
{
	int rc;

	if (context->state & STATE_SUSPENDED) {
		/* Already Suspended */
		return 0;
	}

	/* Nothing to check - Just set the bit to notify the host */
	rc = protocol_events_set(context, BMC_EVENT_FLASH_CTRL_LOST);
	if (rc < 0) {
		return rc;
	}

	context->state |= STATE_SUSPENDED;

	return rc;
}

int control_resume(struct mbox_context *context, bool modified)
{
	int rc;

	if (!(context->state & STATE_SUSPENDED)) {
		/* We weren't suspended... */
		return 0;
	}

	if (modified) {
		/* Call the flash modified handler */
		control_modified(context);
	}

	/* Clear the bit and send the BMC Event to the host */
	rc = protocol_events_clear(context, BMC_EVENT_FLASH_CTRL_LOST);
	if (rc < 0) {
		return rc;
	}
	context->state &= ~STATE_SUSPENDED;

	return rc;
}

int control_set_backend(struct mbox_context *context, struct backend *backend,
			void *data)
{
	int rc;

	if (context->state & STATE_SUSPENDED)
		return -EINVAL;

	rc = protocol_events_clear(context, BMC_EVENT_DAEMON_READY);
	if (rc < 0)
		return rc;

	backend_free(&context->backend);

	rc = backend_init(&context->backend, backend, data);
	if (rc < 0)
		return rc;

	rc = __protocol_reset(context);
	if (rc < 0)
		return rc;

	return protocol_events_set(context,
			BMC_EVENT_DAEMON_READY | BMC_EVENT_PROTOCOL_RESET);
}
OpenPOWER on IntegriCloud