summaryrefslogtreecommitdiffstats
path: root/control.c
blob: 7eae29c156460acb44241e3f582f88eb5b477f1e (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
// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2018 IBM Corp.
#include <errno.h>
#include <stdlib.h>

#include "common.h"
#include "dbus.h"
#include "mboxd.h"
#include "flash.h"
#include "lpc.h"
#include "transport_mbox.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)
{
	int rc;

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

	/*
	 * 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.
	 */
	if (windows_reset_all(context)) {
		rc = protocol_events_set(context, BMC_EVENT_WINDOW_RESET);
		if (rc < 0) {
			return rc;
		}
	}
	rc = lpc_reset(context);
	if (rc < 0) {
		return rc;
	}

	return 0;
}

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 */
	flash_set_bytemap(context, 0, context->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;
}
OpenPOWER on IntegriCloud