xref: /openbmc/phosphor-mboxd/mboxd.c (revision 8fe809ee683866d9451b84f1b1d47408a14825b7)
14fe996c2SAndrew Jeffery // SPDX-License-Identifier: Apache-2.0
24fe996c2SAndrew Jeffery // Copyright (C) 2018 IBM Corp.
3c85e34d1SCyril Bur 
4e39c9163SSuraj Jitindar Singh #define _GNU_SOURCE
5c85e34d1SCyril Bur #include <assert.h>
6c85e34d1SCyril Bur #include <errno.h>
7c85e34d1SCyril Bur #include <fcntl.h>
8c85e34d1SCyril Bur #include <getopt.h>
9c85e34d1SCyril Bur #include <limits.h>
10c85e34d1SCyril Bur #include <poll.h>
11c85e34d1SCyril Bur #include <stdbool.h>
12c85e34d1SCyril Bur #include <stdint.h>
13c85e34d1SCyril Bur #include <stdio.h>
14c85e34d1SCyril Bur #include <stdlib.h>
15c85e34d1SCyril Bur #include <string.h>
16c85e34d1SCyril Bur #include <syslog.h>
17899ebacaSMichael Neuling #include <signal.h>
18c85e34d1SCyril Bur #include <sys/ioctl.h>
19c85e34d1SCyril Bur #include <sys/mman.h>
20c85e34d1SCyril Bur #include <sys/stat.h>
21c85e34d1SCyril Bur #include <sys/timerfd.h>
22c85e34d1SCyril Bur #include <sys/types.h>
23e39c9163SSuraj Jitindar Singh #include <sys/signalfd.h>
24c85e34d1SCyril Bur #include <time.h>
25c85e34d1SCyril Bur #include <unistd.h>
2678210b9bSAndrew Jeffery #include <inttypes.h>
27e39c9163SSuraj Jitindar Singh #include <systemd/sd-bus.h>
28c85e34d1SCyril Bur 
298d65bb44SSuraj Jitindar Singh #include "config.h"
30c85e34d1SCyril Bur #include "mbox.h"
31c85e34d1SCyril Bur #include "common.h"
32e39c9163SSuraj Jitindar Singh #include "dbus.h"
33e39c9163SSuraj Jitindar Singh #include "mboxd_dbus.h"
34e39c9163SSuraj Jitindar Singh #include "mboxd_flash.h"
35e39c9163SSuraj Jitindar Singh #include "mboxd_lpc.h"
36e39c9163SSuraj Jitindar Singh #include "mboxd_msg.h"
37e39c9163SSuraj Jitindar Singh #include "mboxd_windows.h"
3853c21aaaSAndrew Jeffery #include "vpnor/mboxd_pnor_partition_table.h"
39c85e34d1SCyril Bur 
40e39c9163SSuraj Jitindar Singh #define USAGE \
41e39c9163SSuraj Jitindar Singh "\nUsage: %s [-V | --version] [-h | --help] [-v[v] | --verbose] [-s | --syslog]\n" \
42c29172e1SSuraj Jitindar Singh "\t\t[-n | --window-num <num>]\n" \
43c29172e1SSuraj Jitindar Singh "\t\t[-w | --window-size <size>M]\n" \
44e39c9163SSuraj Jitindar Singh "\t\t-f | --flash <size>[K|M]\n\n" \
45e39c9163SSuraj Jitindar Singh "\t-v | --verbose\t\tBe [more] verbose\n" \
46e39c9163SSuraj Jitindar Singh "\t-s | --syslog\t\tLog output to syslog (pointless without -v)\n" \
47e39c9163SSuraj Jitindar Singh "\t-n | --window-num\tThe number of windows\n" \
48c29172e1SSuraj Jitindar Singh "\t\t\t\t(default: fill the reserved memory region)\n" \
49e39c9163SSuraj Jitindar Singh "\t-w | --window-size\tThe window size (power of 2) in MB\n" \
50c29172e1SSuraj Jitindar Singh "\t\t\t\t(default: 1MB)\n" \
51e39c9163SSuraj Jitindar Singh "\t-f | --flash\t\tSize of flash in [K|M] bytes\n\n"
52c85e34d1SCyril Bur 
poll_loop(struct mbox_context * context)53e39c9163SSuraj Jitindar Singh static int poll_loop(struct mbox_context *context)
54c85e34d1SCyril Bur {
55e39c9163SSuraj Jitindar Singh 	int rc = 0, i;
5646233678SCyril Bur 
57e39c9163SSuraj Jitindar Singh 	/* Set POLLIN on polling file descriptors */
58e39c9163SSuraj Jitindar Singh 	for (i = 0; i < POLL_FDS; i++) {
59e39c9163SSuraj Jitindar Singh 		context->fds[i].events = POLLIN;
6046233678SCyril Bur 	}
6146233678SCyril Bur 
62e39c9163SSuraj Jitindar Singh 	while (1) {
63e39c9163SSuraj Jitindar Singh 		rc = poll(context->fds, POLL_FDS, -1);
64e39c9163SSuraj Jitindar Singh 
65e39c9163SSuraj Jitindar Singh 		if (rc < 0) { /* Error */
66e39c9163SSuraj Jitindar Singh 			MSG_ERR("Error from poll(): %s\n", strerror(errno));
67e39c9163SSuraj Jitindar Singh 			break; /* This should mean we clean up nicely */
68c85e34d1SCyril Bur 		}
69c85e34d1SCyril Bur 
70e39c9163SSuraj Jitindar Singh 		/* Event on Polled File Descriptor - Handle It */
71e39c9163SSuraj Jitindar Singh 		if (context->fds[SIG_FD].revents & POLLIN) { /* Signal */
72e39c9163SSuraj Jitindar Singh 			struct signalfd_siginfo info = { 0 };
73c85e34d1SCyril Bur 
74e39c9163SSuraj Jitindar Singh 			rc = read(context->fds[SIG_FD].fd, (void *) &info,
75e39c9163SSuraj Jitindar Singh 				  sizeof(info));
76e39c9163SSuraj Jitindar Singh 			if (rc != sizeof(info)) {
77e39c9163SSuraj Jitindar Singh 				MSG_ERR("Error reading signal event: %s\n",
78c85e34d1SCyril Bur 					strerror(errno));
79c85e34d1SCyril Bur 			}
80e39c9163SSuraj Jitindar Singh 
8128519598SSuraj Jitindar Singh 			MSG_DBG("Received signal: %d\n", info.ssi_signo);
82e39c9163SSuraj Jitindar Singh 			switch (info.ssi_signo) {
83e39c9163SSuraj Jitindar Singh 			case SIGINT:
84e39c9163SSuraj Jitindar Singh 			case SIGTERM:
8528519598SSuraj Jitindar Singh 				MSG_INFO("Caught Signal - Exiting...\n");
86e39c9163SSuraj Jitindar Singh 				context->terminate = true;
87c85e34d1SCyril Bur 				break;
88e39c9163SSuraj Jitindar Singh 			case SIGHUP:
89e39c9163SSuraj Jitindar Singh 				/* Host didn't request reset -> Notify it */
90e39c9163SSuraj Jitindar Singh 				reset_all_windows(context, SET_BMC_EVENT);
91017e45c3SDeepak Kodihalli 				rc = reset_lpc(context);
92e39c9163SSuraj Jitindar Singh 				if (rc < 0) {
93e39c9163SSuraj Jitindar Singh 					MSG_ERR("WARNING: Failed to point the "
94e39c9163SSuraj Jitindar Singh 						"LPC bus back to flash on "
95e39c9163SSuraj Jitindar Singh 						"SIGHUP\nIf the host requires "
96e39c9163SSuraj Jitindar Singh 						"this expect problems...\n");
97e39c9163SSuraj Jitindar Singh 				}
98c85e34d1SCyril Bur 				break;
99c85e34d1SCyril Bur 			default:
100e39c9163SSuraj Jitindar Singh 				MSG_ERR("Unhandled Signal: %d\n",
101e39c9163SSuraj Jitindar Singh 					info.ssi_signo);
102e39c9163SSuraj Jitindar Singh 				break;
103e39c9163SSuraj Jitindar Singh 			}
104e39c9163SSuraj Jitindar Singh 		}
105e39c9163SSuraj Jitindar Singh 		if (context->fds[DBUS_FD].revents & POLLIN) { /* DBUS */
10628519598SSuraj Jitindar Singh 			while ((rc = sd_bus_process(context->bus, NULL)) > 0) {
10728519598SSuraj Jitindar Singh 				MSG_DBG("DBUS Event\n");
10828519598SSuraj Jitindar Singh 			}
109e39c9163SSuraj Jitindar Singh 			if (rc < 0) {
110e39c9163SSuraj Jitindar Singh 				MSG_ERR("Error handling DBUS event: %s\n",
111e39c9163SSuraj Jitindar Singh 						strerror(-rc));
112e39c9163SSuraj Jitindar Singh 			}
113e39c9163SSuraj Jitindar Singh 		}
114e39c9163SSuraj Jitindar Singh 		if (context->terminate) {
115e39c9163SSuraj Jitindar Singh 			break; /* This should mean we clean up nicely */
116e39c9163SSuraj Jitindar Singh 		}
117e39c9163SSuraj Jitindar Singh 		if (context->fds[MBOX_FD].revents & POLLIN) { /* MBOX */
11828519598SSuraj Jitindar Singh 			MSG_DBG("MBOX Event\n");
119e39c9163SSuraj Jitindar Singh 			rc = dispatch_mbox(context);
120e39c9163SSuraj Jitindar Singh 			if (rc < 0) {
121e39c9163SSuraj Jitindar Singh 				MSG_ERR("Error handling MBOX event\n");
122e39c9163SSuraj Jitindar Singh 			}
123e39c9163SSuraj Jitindar Singh 		}
124c85e34d1SCyril Bur 	}
125c85e34d1SCyril Bur 
126017e45c3SDeepak Kodihalli 	/* Best to reset windows and the lpc mapping for safety */
127e39c9163SSuraj Jitindar Singh 	/* Host didn't request reset -> Notify it */
128e39c9163SSuraj Jitindar Singh 	reset_all_windows(context, SET_BMC_EVENT);
129017e45c3SDeepak Kodihalli 	rc = reset_lpc(context);
130e39c9163SSuraj Jitindar Singh 	/* Not much we can do if this fails */
131e39c9163SSuraj Jitindar Singh 	if (rc < 0) {
132e39c9163SSuraj Jitindar Singh 		MSG_ERR("WARNING: Failed to point the LPC bus back to flash\n"
133e39c9163SSuraj Jitindar Singh 			"If the host requires this expect problems...\n");
134c85e34d1SCyril Bur 	}
135c85e34d1SCyril Bur 
136e39c9163SSuraj Jitindar Singh 	return rc;
137c85e34d1SCyril Bur }
138c85e34d1SCyril Bur 
init_signals(struct mbox_context * context,sigset_t * set)139e39c9163SSuraj Jitindar Singh static int init_signals(struct mbox_context *context, sigset_t *set)
140899ebacaSMichael Neuling {
141e39c9163SSuraj Jitindar Singh 	int rc;
142899ebacaSMichael Neuling 
143e39c9163SSuraj Jitindar Singh 	/* Block SIGHUPs, SIGTERMs and SIGINTs */
144e39c9163SSuraj Jitindar Singh 	sigemptyset(set);
145e39c9163SSuraj Jitindar Singh 	sigaddset(set, SIGHUP);
146e39c9163SSuraj Jitindar Singh 	sigaddset(set, SIGINT);
147e39c9163SSuraj Jitindar Singh 	sigaddset(set, SIGTERM);
148e39c9163SSuraj Jitindar Singh 	rc = sigprocmask(SIG_BLOCK, set, NULL);
149e39c9163SSuraj Jitindar Singh 	if (rc < 0) {
150e39c9163SSuraj Jitindar Singh 		MSG_ERR("Failed to set SIG_BLOCK mask %s\n", strerror(errno));
151e39c9163SSuraj Jitindar Singh 		return rc;
152899ebacaSMichael Neuling 	}
153e39c9163SSuraj Jitindar Singh 
154e39c9163SSuraj Jitindar Singh 	/* Get Signal File Descriptor */
155e39c9163SSuraj Jitindar Singh 	rc = signalfd(-1, set, SFD_NONBLOCK);
156e39c9163SSuraj Jitindar Singh 	if (rc < 0) {
157e39c9163SSuraj Jitindar Singh 		MSG_ERR("Failed to get signalfd %s\n", strerror(errno));
158e39c9163SSuraj Jitindar Singh 		return rc;
159899ebacaSMichael Neuling 	}
160e39c9163SSuraj Jitindar Singh 
161e39c9163SSuraj Jitindar Singh 	context->fds[SIG_FD].fd = rc;
162899ebacaSMichael Neuling 	return 0;
163899ebacaSMichael Neuling }
164899ebacaSMichael Neuling 
usage(const char * name)165c85e34d1SCyril Bur static void usage(const char *name)
166c85e34d1SCyril Bur {
167e39c9163SSuraj Jitindar Singh 	printf(USAGE, name);
168c85e34d1SCyril Bur }
169c85e34d1SCyril Bur 
parse_cmdline(int argc,char ** argv,struct mbox_context * context)170e39c9163SSuraj Jitindar Singh static bool parse_cmdline(int argc, char **argv,
171e39c9163SSuraj Jitindar Singh 			  struct mbox_context *context)
172c85e34d1SCyril Bur {
173e8f2de1fSCyril Bur 	char *endptr;
174c29172e1SSuraj Jitindar Singh 	int opt;
175c85e34d1SCyril Bur 
176c85e34d1SCyril Bur 	static const struct option long_options[] = {
177e8f2de1fSCyril Bur 		{ "flash",		required_argument,	0, 'f' },
178e39c9163SSuraj Jitindar Singh 		{ "window-size",	optional_argument,	0, 'w' },
179e39c9163SSuraj Jitindar Singh 		{ "window-num",		optional_argument,	0, 'n' },
180c85e34d1SCyril Bur 		{ "verbose",		no_argument,		0, 'v' },
181c85e34d1SCyril Bur 		{ "syslog",		no_argument,		0, 's' },
182e39c9163SSuraj Jitindar Singh 		{ "version",		no_argument,		0, 'V' },
183e39c9163SSuraj Jitindar Singh 		{ "help",		no_argument,		0, 'h' },
184c85e34d1SCyril Bur 		{ 0,			0,			0, 0   }
185c85e34d1SCyril Bur 	};
186c85e34d1SCyril Bur 
187e39c9163SSuraj Jitindar Singh 	verbosity = MBOX_LOG_NONE;
188c85e34d1SCyril Bur 	mbox_vlog = &mbox_log_console;
189e39c9163SSuraj Jitindar Singh 
190e39c9163SSuraj Jitindar Singh 	context->current = NULL; /* No current window */
191e39c9163SSuraj Jitindar Singh 
192e39c9163SSuraj Jitindar Singh 	while ((opt = getopt_long(argc, argv, "f:w::n::vsVh", long_options, NULL))
193e39c9163SSuraj Jitindar Singh 			!= -1) {
194c85e34d1SCyril Bur 		switch (opt) {
195c85e34d1SCyril Bur 		case 0:
196c85e34d1SCyril Bur 			break;
197e8f2de1fSCyril Bur 		case 'f':
198e39c9163SSuraj Jitindar Singh 			context->flash_size = strtol(optarg, &endptr, 10);
199e8f2de1fSCyril Bur 			if (optarg == endptr) {
200e8f2de1fSCyril Bur 				fprintf(stderr, "Unparseable flash size\n");
201e39c9163SSuraj Jitindar Singh 				return false;
202e8f2de1fSCyril Bur 			}
203e39c9163SSuraj Jitindar Singh 			switch (*endptr) {
204e39c9163SSuraj Jitindar Singh 			case '\0':
205e39c9163SSuraj Jitindar Singh 				break;
206e39c9163SSuraj Jitindar Singh 			case 'M':
207e8f2de1fSCyril Bur 				context->flash_size <<= 10;
208e39c9163SSuraj Jitindar Singh 			case 'K':
209e39c9163SSuraj Jitindar Singh 				context->flash_size <<= 10;
210e39c9163SSuraj Jitindar Singh 				break;
211e39c9163SSuraj Jitindar Singh 			default:
212e39c9163SSuraj Jitindar Singh 				fprintf(stderr, "Unknown units '%c'\n",
213e39c9163SSuraj Jitindar Singh 					*endptr);
214e39c9163SSuraj Jitindar Singh 				return false;
215e39c9163SSuraj Jitindar Singh 			}
216e39c9163SSuraj Jitindar Singh 			break;
217e39c9163SSuraj Jitindar Singh 		case 'n':
218e39c9163SSuraj Jitindar Singh 			context->windows.num = strtol(argv[optind], &endptr,
219e39c9163SSuraj Jitindar Singh 						      10);
220e39c9163SSuraj Jitindar Singh 			if (optarg == endptr || *endptr != '\0') {
221e39c9163SSuraj Jitindar Singh 				fprintf(stderr, "Unparseable window num\n");
222e39c9163SSuraj Jitindar Singh 				return false;
223e39c9163SSuraj Jitindar Singh 			}
224e39c9163SSuraj Jitindar Singh 			break;
225e39c9163SSuraj Jitindar Singh 		case 'w':
226e39c9163SSuraj Jitindar Singh 			context->windows.default_size = strtol(argv[optind],
227e39c9163SSuraj Jitindar Singh 							       &endptr, 10);
228e39c9163SSuraj Jitindar Singh 			context->windows.default_size <<= 20; /* Given in MB */
229e39c9163SSuraj Jitindar Singh 			if (optarg == endptr || (*endptr != '\0' &&
230e39c9163SSuraj Jitindar Singh 						 *endptr != 'M')) {
231e39c9163SSuraj Jitindar Singh 				fprintf(stderr, "Unparseable window size\n");
232e39c9163SSuraj Jitindar Singh 				return false;
233e8f2de1fSCyril Bur 			}
2340aff80c0SSuraj Jitindar Singh 			if (!is_power_of_2(context->windows.default_size)) {
2350aff80c0SSuraj Jitindar Singh 				fprintf(stderr, "Window size not power of 2\n");
2360aff80c0SSuraj Jitindar Singh 				return false;
2370aff80c0SSuraj Jitindar Singh 			}
238e8f2de1fSCyril Bur 			break;
239c85e34d1SCyril Bur 		case 'v':
240c85e34d1SCyril Bur 			verbosity++;
241c85e34d1SCyril Bur 			break;
242c85e34d1SCyril Bur 		case 's':
243c85e34d1SCyril Bur 			/* Avoid a double openlog() */
244c85e34d1SCyril Bur 			if (mbox_vlog != &vsyslog) {
245c85e34d1SCyril Bur 				openlog(PREFIX, LOG_ODELAY, LOG_DAEMON);
246c85e34d1SCyril Bur 				mbox_vlog = &vsyslog;
247c85e34d1SCyril Bur 			}
248c85e34d1SCyril Bur 			break;
249e39c9163SSuraj Jitindar Singh 		case 'V':
2508d65bb44SSuraj Jitindar Singh 			printf("%s V%s\n", THIS_NAME, PACKAGE_VERSION);
251e39c9163SSuraj Jitindar Singh 			exit(0);
252e39c9163SSuraj Jitindar Singh 		case 'h':
253e39c9163SSuraj Jitindar Singh 			return false; /* This will print the usage message */
254c85e34d1SCyril Bur 		default:
255e39c9163SSuraj Jitindar Singh 			return false;
256c85e34d1SCyril Bur 		}
257c85e34d1SCyril Bur 	}
258c85e34d1SCyril Bur 
259e39c9163SSuraj Jitindar Singh 	if (!context->flash_size) {
260e8f2de1fSCyril Bur 		fprintf(stderr, "Must specify a non-zero flash size\n");
261e39c9163SSuraj Jitindar Singh 		return false;
262e8f2de1fSCyril Bur 	}
263e8f2de1fSCyril Bur 
26428519598SSuraj Jitindar Singh 	MSG_INFO("Flash size: 0x%.8x\n", context->flash_size);
265c85e34d1SCyril Bur 
266e39c9163SSuraj Jitindar Singh 	if (verbosity) {
26728519598SSuraj Jitindar Singh 		MSG_INFO("%s logging\n", verbosity == MBOX_LOG_DEBUG ? "Debug" :
268e39c9163SSuraj Jitindar Singh 					"Verbose");
269e39c9163SSuraj Jitindar Singh 	}
270e39c9163SSuraj Jitindar Singh 
271e39c9163SSuraj Jitindar Singh 	return true;
272e39c9163SSuraj Jitindar Singh }
273e39c9163SSuraj Jitindar Singh 
main(int argc,char ** argv)274e39c9163SSuraj Jitindar Singh int main(int argc, char **argv)
275e39c9163SSuraj Jitindar Singh {
276e39c9163SSuraj Jitindar Singh 	struct mbox_context *context;
277e39c9163SSuraj Jitindar Singh 	char *name = argv[0];
278e39c9163SSuraj Jitindar Singh 	sigset_t set;
279e39c9163SSuraj Jitindar Singh 	int rc, i;
280e39c9163SSuraj Jitindar Singh 
281e39c9163SSuraj Jitindar Singh 	context = calloc(1, sizeof(*context));
282e39c9163SSuraj Jitindar Singh 	if (!context) {
283e39c9163SSuraj Jitindar Singh 		fprintf(stderr, "Memory allocation failed\n");
284e39c9163SSuraj Jitindar Singh 		exit(1);
285e39c9163SSuraj Jitindar Singh 	}
286e39c9163SSuraj Jitindar Singh 
287e39c9163SSuraj Jitindar Singh 	if (!parse_cmdline(argc, argv, context)) {
288e39c9163SSuraj Jitindar Singh 		usage(name);
289e39c9163SSuraj Jitindar Singh 		free(context);
290e39c9163SSuraj Jitindar Singh 		exit(0);
291e39c9163SSuraj Jitindar Singh 	}
292e39c9163SSuraj Jitindar Singh 
293e39c9163SSuraj Jitindar Singh 	for (i = 0; i < TOTAL_FDS; i++) {
294e39c9163SSuraj Jitindar Singh 		context->fds[i].fd = -1;
295e39c9163SSuraj Jitindar Singh 	}
296e39c9163SSuraj Jitindar Singh 
29728519598SSuraj Jitindar Singh 	MSG_INFO("Starting Daemon\n");
298e39c9163SSuraj Jitindar Singh 
299e39c9163SSuraj Jitindar Singh 	rc = init_signals(context, &set);
300e39c9163SSuraj Jitindar Singh 	if (rc) {
301c85e34d1SCyril Bur 		goto finish;
302c85e34d1SCyril Bur 	}
303c85e34d1SCyril Bur 
304e39c9163SSuraj Jitindar Singh 	rc = init_mbox_dev(context);
305e39c9163SSuraj Jitindar Singh 	if (rc) {
306c85e34d1SCyril Bur 		goto finish;
307c85e34d1SCyril Bur 	}
308c85e34d1SCyril Bur 
309e39c9163SSuraj Jitindar Singh 	rc = init_lpc_dev(context);
310e39c9163SSuraj Jitindar Singh 	if (rc) {
311c85e34d1SCyril Bur 		goto finish;
312c85e34d1SCyril Bur 	}
313c85e34d1SCyril Bur 
314e39c9163SSuraj Jitindar Singh 	/* We've found the reserved memory region -> we can assign to windows */
315c29172e1SSuraj Jitindar Singh 	rc = init_windows(context);
316e39c9163SSuraj Jitindar Singh 	if (rc) {
317c85e34d1SCyril Bur 		goto finish;
318c85e34d1SCyril Bur 	}
319c85e34d1SCyril Bur 
320e39c9163SSuraj Jitindar Singh 	rc = init_flash_dev(context);
321e39c9163SSuraj Jitindar Singh 	if (rc) {
322c85e34d1SCyril Bur 		goto finish;
323c85e34d1SCyril Bur 	}
324c85e34d1SCyril Bur 
325e39c9163SSuraj Jitindar Singh 	rc = init_mboxd_dbus(context);
326e39c9163SSuraj Jitindar Singh 	if (rc) {
327c85e34d1SCyril Bur 		goto finish;
328c85e34d1SCyril Bur 	}
329c85e34d1SCyril Bur 
330017e45c3SDeepak Kodihalli #ifdef VIRTUAL_PNOR_ENABLED
33164ec3e45SDeepak Kodihalli 	init_vpnor(context);
332017e45c3SDeepak Kodihalli #endif
333017e45c3SDeepak Kodihalli 
334017e45c3SDeepak Kodihalli 	/* Set the LPC bus mapping */
335017e45c3SDeepak Kodihalli 	rc = reset_lpc(context);
336e39c9163SSuraj Jitindar Singh 	if (rc) {
337*8fe809eeSAndrew Jeffery 		MSG_ERR("LPC configuration failed, RESET required: %d\n", rc);
338d8f6d7a4SCyril Bur 	}
339d8f6d7a4SCyril Bur 
340e39c9163SSuraj Jitindar Singh 	rc = set_bmc_events(context, BMC_EVENT_DAEMON_READY, SET_BMC_EVENT);
341e39c9163SSuraj Jitindar Singh 	if (rc) {
342899ebacaSMichael Neuling 		goto finish;
343899ebacaSMichael Neuling 	}
344c85e34d1SCyril Bur 
34528519598SSuraj Jitindar Singh 	MSG_INFO("Entering Polling Loop\n");
346e39c9163SSuraj Jitindar Singh 	rc = poll_loop(context);
347e39c9163SSuraj Jitindar Singh 
34828519598SSuraj Jitindar Singh 	MSG_INFO("Exiting Poll Loop: %d\n", rc);
349c85e34d1SCyril Bur 
350c85e34d1SCyril Bur finish:
35128519598SSuraj Jitindar Singh 	MSG_INFO("Daemon Exiting...\n");
352e39c9163SSuraj Jitindar Singh 	clr_bmc_events(context, BMC_EVENT_DAEMON_READY, SET_BMC_EVENT);
353c85e34d1SCyril Bur 
354e39c9163SSuraj Jitindar Singh 	free_mboxd_dbus(context);
355e39c9163SSuraj Jitindar Singh 	free_flash_dev(context);
356e39c9163SSuraj Jitindar Singh 	free_lpc_dev(context);
357e39c9163SSuraj Jitindar Singh 	free_mbox_dev(context);
358c29172e1SSuraj Jitindar Singh 	free_windows(context);
3596c2fa90dSDeepak Kodihalli #ifdef VIRTUAL_PNOR_ENABLED
36064ec3e45SDeepak Kodihalli 	destroy_vpnor(context);
3616c2fa90dSDeepak Kodihalli #endif
362c85e34d1SCyril Bur 	free(context);
363c85e34d1SCyril Bur 
364e39c9163SSuraj Jitindar Singh 	return rc;
365c85e34d1SCyril Bur }
366