blob: c7f7d33c0585e4c09a28f3e90dcbcde3f37e672d [file] [log] [blame]
Andrew Jeffery4fe996c2018-02-27 12:16:48 +10301// SPDX-License-Identifier: Apache-2.0
2// Copyright (C) 2018 IBM Corp.
Cyril Burc85e34d2016-11-15 11:50:41 +11003
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +11004#define _GNU_SOURCE
Cyril Burc85e34d2016-11-15 11:50:41 +11005#include <assert.h>
6#include <errno.h>
7#include <fcntl.h>
8#include <getopt.h>
9#include <limits.h>
10#include <poll.h>
11#include <stdbool.h>
12#include <stdint.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <syslog.h>
Michael Neuling899ebac2017-01-14 11:20:26 -060017#include <signal.h>
Cyril Burc85e34d2016-11-15 11:50:41 +110018#include <sys/ioctl.h>
19#include <sys/mman.h>
20#include <sys/stat.h>
21#include <sys/timerfd.h>
22#include <sys/types.h>
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +110023#include <sys/signalfd.h>
Cyril Burc85e34d2016-11-15 11:50:41 +110024#include <time.h>
25#include <unistd.h>
Andrew Jeffery78210b92017-01-13 13:06:09 +103026#include <inttypes.h>
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +110027#include <systemd/sd-bus.h>
Cyril Burc85e34d2016-11-15 11:50:41 +110028
Suraj Jitindar Singh8d65bb42017-05-01 16:05:17 +100029#include "config.h"
Andrew Jeffery26558db2018-08-10 00:22:38 +093030#include "mboxd.h"
Cyril Burc85e34d2016-11-15 11:50:41 +110031#include "common.h"
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +110032#include "dbus.h"
Andrew Jeffery55f4d6f2018-08-06 12:26:44 +093033#include "control_dbus.h"
Evan Lojewskif1e547c2019-03-14 14:34:33 +103034#include "backend.h"
Andrew Jefferycd186112018-08-08 10:47:55 +093035#include "lpc.h"
Andrew Jeffery457a6e52018-08-08 11:21:08 +093036#include "transport_mbox.h"
Andrew Jeffery23140be2018-09-05 14:15:07 +093037#include "transport_dbus.h"
Andrew Jefferyf593b1b2018-08-08 11:01:04 +093038#include "windows.h"
Andrew Jefferyf4bc3352019-03-18 12:09:48 +103039#include "vpnor/backend.h"
Cyril Burc85e34d2016-11-15 11:50:41 +110040
Evan Lojewskia0429782019-03-13 15:25:44 +103041const char* USAGE =
42 "\nUsage: %s [-V | --version] [-h | --help] [-v[v] | --verbose] [-s | --syslog]\n"
43 "\t\t[-n | --window-num <num>]\n"
44 "\t\t[-w | --window-size <size>M]\n"
45 "\t\t-f | --flash <size>[K|M]\n"
46#ifdef VIRTUAL_PNOR_ENABLED
Andrew Jeffery5320f6e2019-03-15 12:40:41 +103047 "\t\t-b | --backend <vpnor|mtd[:PATH]|file:PATH>\n"
Evan Lojewskia0429782019-03-13 15:25:44 +103048#else
Andrew Jeffery5320f6e2019-03-15 12:40:41 +103049 "\t\t-b | --backend <mtd[:PATH]|file:PATH>\n"
Evan Lojewskia0429782019-03-13 15:25:44 +103050#endif
51 "\t-v | --verbose\t\tBe [more] verbose\n"
52 "\t-s | --syslog\t\tLog output to syslog (pointless without -v)\n"
53 "\t-n | --window-num\tThe number of windows\n"
54 "\t\t\t\t(default: fill the reserved memory region)\n"
55 "\t-w | --window-size\tThe window size (power of 2) in MB\n"
56 "\t\t\t\t(default: 1MB)\n"
Stewart Smithef0c8362018-11-19 13:49:46 +110057 "\t-f | --flash\t\tSize of flash in [K|M] bytes\n\n"
58 "\t-t | --trace\t\tFile to write trace data to (in blktrace format)\n\n";
Cyril Burc85e34d2016-11-15 11:50:41 +110059
Andrew Jefferyfe0c9e82018-11-01 14:02:17 +103060static int dbus_init(struct mbox_context *context,
61 const struct transport_ops **ops)
Andrew Jefferyef9e62d2018-08-08 15:48:27 +093062{
63 int rc;
64
65 rc = sd_bus_default_system(&context->bus);
66 if (rc < 0) {
67 MSG_ERR("Failed to connect to the system bus: %s\n",
68 strerror(-rc));
69 return rc;
70 }
71
72 rc = control_legacy_init(context);
73 if (rc < 0) {
74 MSG_ERR("Failed to initialise legacy DBus interface: %s\n",
75 strerror(-rc));
76 return rc;
77 }
78
79 rc = control_dbus_init(context);
80 if (rc < 0) {
81 MSG_ERR("Failed to initialise DBus control interface: %s\n",
82 strerror(-rc));
83 return rc;
84 }
85
Andrew Jefferyfe0c9e82018-11-01 14:02:17 +103086 rc = transport_dbus_init(context, ops);
Andrew Jeffery23140be2018-09-05 14:15:07 +093087 if (rc < 0) {
88 MSG_ERR("Failed to initialise DBus protocol interface: %s\n",
89 strerror(-rc));
90 return rc;
91 }
92
Andrew Jefferyef9e62d2018-08-08 15:48:27 +093093 rc = sd_bus_request_name(context->bus, MBOX_DBUS_NAME,
94 SD_BUS_NAME_ALLOW_REPLACEMENT |
95 SD_BUS_NAME_REPLACE_EXISTING);
96 if (rc < 0) {
Andrew Jeffery23140be2018-09-05 14:15:07 +093097 MSG_ERR("Failed to request DBus name: %s\n", strerror(-rc));
Andrew Jefferyef9e62d2018-08-08 15:48:27 +093098 return rc;
99 }
100
101 rc = sd_bus_get_fd(context->bus);
102 if (rc < 0) {
103 MSG_ERR("Failed to get bus fd: %s\n", strerror(-rc));
104 return rc;
105 }
106
107 context->fds[DBUS_FD].fd = rc;
108
109 return 0;
110}
111
112static void dbus_free(struct mbox_context *context)
113{
Andrew Jeffery23140be2018-09-05 14:15:07 +0930114 transport_dbus_free(context);
Andrew Jefferyef9e62d2018-08-08 15:48:27 +0930115 control_dbus_free(context);
116 control_legacy_free(context);
117 sd_bus_unref(context->bus);
118}
Andrew Jeffery55f4d6f2018-08-06 12:26:44 +0930119
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100120static int poll_loop(struct mbox_context *context)
Cyril Burc85e34d2016-11-15 11:50:41 +1100121{
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100122 int rc = 0, i;
Cyril Bur46233672017-01-16 13:33:26 +1100123
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100124 /* Set POLLIN on polling file descriptors */
125 for (i = 0; i < POLL_FDS; i++) {
126 context->fds[i].events = POLLIN;
Cyril Bur46233672017-01-16 13:33:26 +1100127 }
128
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100129 while (1) {
130 rc = poll(context->fds, POLL_FDS, -1);
131
132 if (rc < 0) { /* Error */
133 MSG_ERR("Error from poll(): %s\n", strerror(errno));
134 break; /* This should mean we clean up nicely */
135 }
136
137 /* Event on Polled File Descriptor - Handle It */
138 if (context->fds[SIG_FD].revents & POLLIN) { /* Signal */
139 struct signalfd_siginfo info = { 0 };
140
141 rc = read(context->fds[SIG_FD].fd, (void *) &info,
142 sizeof(info));
143 if (rc != sizeof(info)) {
144 MSG_ERR("Error reading signal event: %s\n",
145 strerror(errno));
146 }
147
Suraj Jitindar Singh28519592017-04-27 14:48:58 +1000148 MSG_DBG("Received signal: %d\n", info.ssi_signo);
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100149 switch (info.ssi_signo) {
150 case SIGINT:
151 case SIGTERM:
Suraj Jitindar Singh28519592017-04-27 14:48:58 +1000152 MSG_INFO("Caught Signal - Exiting...\n");
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100153 context->terminate = true;
154 break;
155 case SIGHUP:
Andrew Jefferyf69760d2019-03-14 16:54:13 +1030156 rc = protocol_reset(context);
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100157 if (rc < 0) {
Andrew Jefferyf69760d2019-03-14 16:54:13 +1030158 MSG_ERR("Failed to reset on SIGHUP\n");
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100159 }
160 break;
161 default:
162 MSG_ERR("Unhandled Signal: %d\n",
163 info.ssi_signo);
164 break;
165 }
166 }
167 if (context->fds[DBUS_FD].revents & POLLIN) { /* DBUS */
Suraj Jitindar Singh28519592017-04-27 14:48:58 +1000168 while ((rc = sd_bus_process(context->bus, NULL)) > 0) {
169 MSG_DBG("DBUS Event\n");
170 }
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100171 if (rc < 0) {
172 MSG_ERR("Error handling DBUS event: %s\n",
173 strerror(-rc));
174 }
175 }
176 if (context->terminate) {
177 break; /* This should mean we clean up nicely */
178 }
179 if (context->fds[MBOX_FD].revents & POLLIN) { /* MBOX */
Suraj Jitindar Singh28519592017-04-27 14:48:58 +1000180 MSG_DBG("MBOX Event\n");
Andrew Jefferyd86141b2018-08-09 14:58:53 +0930181 rc = transport_mbox_dispatch(context);
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100182 if (rc < 0) {
183 MSG_ERR("Error handling MBOX event\n");
184 }
185 }
186 }
187
Andrew Jefferyf69760d2019-03-14 16:54:13 +1030188 rc = protocol_reset(context);
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100189 if (rc < 0) {
Andrew Jefferyf69760d2019-03-14 16:54:13 +1030190 MSG_ERR("Failed to reset during poll loop cleanup\n");
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100191 }
192
193 return rc;
Cyril Burc85e34d2016-11-15 11:50:41 +1100194}
195
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100196static int init_signals(struct mbox_context *context, sigset_t *set)
Cyril Burc85e34d2016-11-15 11:50:41 +1100197{
198 int rc;
Cyril Burc85e34d2016-11-15 11:50:41 +1100199
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100200 /* Block SIGHUPs, SIGTERMs and SIGINTs */
201 sigemptyset(set);
202 sigaddset(set, SIGHUP);
203 sigaddset(set, SIGINT);
204 sigaddset(set, SIGTERM);
205 rc = sigprocmask(SIG_BLOCK, set, NULL);
206 if (rc < 0) {
207 MSG_ERR("Failed to set SIG_BLOCK mask %s\n", strerror(errno));
208 return rc;
Cyril Burc85e34d2016-11-15 11:50:41 +1100209 }
210
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100211 /* Get Signal File Descriptor */
212 rc = signalfd(-1, set, SFD_NONBLOCK);
213 if (rc < 0) {
214 MSG_ERR("Failed to get signalfd %s\n", strerror(errno));
215 return rc;
Cyril Burc85e34d2016-11-15 11:50:41 +1100216 }
217
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100218 context->fds[SIG_FD].fd = rc;
Cyril Burc85e34d2016-11-15 11:50:41 +1100219 return 0;
220}
221
Cyril Burc85e34d2016-11-15 11:50:41 +1100222static void usage(const char *name)
223{
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100224 printf(USAGE, name);
Cyril Burc85e34d2016-11-15 11:50:41 +1100225}
226
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100227static bool parse_cmdline(int argc, char **argv,
228 struct mbox_context *context)
Cyril Burc85e34d2016-11-15 11:50:41 +1100229{
Cyril Bure8f2de12017-01-17 16:56:02 +1100230 char *endptr;
Suraj Jitindar Singhc29172e2017-04-12 14:26:47 +1000231 int opt;
Cyril Burc85e34d2016-11-15 11:50:41 +1100232
233 static const struct option long_options[] = {
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100234 { "flash", required_argument, 0, 'f' },
Evan Lojewskia0429782019-03-13 15:25:44 +1030235 { "backend", required_argument, 0, 'b' },
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100236 { "window-size", optional_argument, 0, 'w' },
237 { "window-num", optional_argument, 0, 'n' },
238 { "verbose", no_argument, 0, 'v' },
239 { "syslog", no_argument, 0, 's' },
Stewart Smithef0c8362018-11-19 13:49:46 +1100240 { "trace", optional_argument, 0, 't' },
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100241 { "version", no_argument, 0, 'V' },
242 { "help", no_argument, 0, 'h' },
243 { 0, 0, 0, 0 }
Cyril Burc85e34d2016-11-15 11:50:41 +1100244 };
245
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100246 verbosity = MBOX_LOG_NONE;
Cyril Burc85e34d2016-11-15 11:50:41 +1100247 mbox_vlog = &mbox_log_console;
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100248
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100249 context->current = NULL; /* No current window */
250
Stewart Smithef0c8362018-11-19 13:49:46 +1100251 while ((opt = getopt_long(argc, argv, "f:b:w::n::vst::Vh", long_options, NULL))
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100252 != -1) {
Cyril Burc85e34d2016-11-15 11:50:41 +1100253 switch (opt) {
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100254 case 0:
255 break;
256 case 'f':
Evan Lojewskif1e547c2019-03-14 14:34:33 +1030257 context->backend.flash_size = strtol(optarg, &endptr, 10);
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100258 if (optarg == endptr) {
259 fprintf(stderr, "Unparseable flash size\n");
260 return false;
261 }
262 switch (*endptr) {
263 case '\0':
Cyril Burc85e34d2016-11-15 11:50:41 +1100264 break;
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100265 case 'M':
Evan Lojewskif1e547c2019-03-14 14:34:33 +1030266 context->backend.flash_size <<= 10;
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100267 case 'K':
Evan Lojewskif1e547c2019-03-14 14:34:33 +1030268 context->backend.flash_size <<= 10;
Cyril Burc85e34d2016-11-15 11:50:41 +1100269 break;
270 default:
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100271 fprintf(stderr, "Unknown units '%c'\n",
272 *endptr);
273 return false;
274 }
275 break;
Evan Lojewskia0429782019-03-13 15:25:44 +1030276 case 'b':
Andrew Jeffery5320f6e2019-03-15 12:40:41 +1030277 context->source = optarg;
Evan Lojewskia0429782019-03-13 15:25:44 +1030278 break;
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100279 case 'n':
280 context->windows.num = strtol(argv[optind], &endptr,
281 10);
282 if (optarg == endptr || *endptr != '\0') {
283 fprintf(stderr, "Unparseable window num\n");
284 return false;
285 }
286 break;
287 case 'w':
288 context->windows.default_size = strtol(argv[optind],
289 &endptr, 10);
290 context->windows.default_size <<= 20; /* Given in MB */
291 if (optarg == endptr || (*endptr != '\0' &&
292 *endptr != 'M')) {
293 fprintf(stderr, "Unparseable window size\n");
294 return false;
295 }
Suraj Jitindar Singh0aff80c2017-04-12 14:37:24 +1000296 if (!is_power_of_2(context->windows.default_size)) {
297 fprintf(stderr, "Window size not power of 2\n");
298 return false;
299 }
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100300 break;
301 case 'v':
302 verbosity++;
303 break;
304 case 's':
305 /* Avoid a double openlog() */
306 if (mbox_vlog != &vsyslog) {
307 openlog(PREFIX, LOG_ODELAY, LOG_DAEMON);
308 mbox_vlog = &vsyslog;
309 }
310 break;
311 case 'V':
Suraj Jitindar Singh8d65bb42017-05-01 16:05:17 +1000312 printf("%s V%s\n", THIS_NAME, PACKAGE_VERSION);
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100313 exit(0);
Stewart Smithef0c8362018-11-19 13:49:46 +1100314 case 't':
315 context->blktracefd = open(argv[optind],
316 O_CREAT|O_TRUNC|O_WRONLY,
317 0666);
318 printf("Recording blktrace output to %s\n",
319 argv[optind]);
320 if (context->blktracefd == -1) {
321 perror("Couldn't open blktrace file for writing");
322 exit(2);
323 }
324 break;
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100325 case 'h':
326 return false; /* This will print the usage message */
327 default:
328 return false;
Cyril Burc85e34d2016-11-15 11:50:41 +1100329 }
330 }
331
Evan Lojewskif1e547c2019-03-14 14:34:33 +1030332 if (!context->backend.flash_size) {
Cyril Bure8f2de12017-01-17 16:56:02 +1100333 fprintf(stderr, "Must specify a non-zero flash size\n");
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100334 return false;
Cyril Bure8f2de12017-01-17 16:56:02 +1100335 }
336
Evan Lojewskif1e547c2019-03-14 14:34:33 +1030337 MSG_INFO("Flash size: 0x%.8x\n", context->backend.flash_size);
Cyril Burc85e34d2016-11-15 11:50:41 +1100338
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100339 if (verbosity) {
Suraj Jitindar Singh28519592017-04-27 14:48:58 +1000340 MSG_INFO("%s logging\n", verbosity == MBOX_LOG_DEBUG ? "Debug" :
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100341 "Verbose");
Cyril Burc85e34d2016-11-15 11:50:41 +1100342 }
343
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100344 return true;
Cyril Burc85e34d2016-11-15 11:50:41 +1100345}
346
Evan Lojewskif1e547c2019-03-14 14:34:33 +1030347static int mboxd_backend_init(struct mbox_context *context)
348{
Andrew Jeffery5320f6e2019-03-15 12:40:41 +1030349 const char *delim;
350 const char *path;
Evan Lojewskif1e547c2019-03-14 14:34:33 +1030351 int rc;
352
Andrew Jeffery5320f6e2019-03-15 12:40:41 +1030353 if (!context->source) {
354 struct vpnor_partition_paths paths;
355 vpnor_default_paths(&paths);
Evan Lojewskif1e547c2019-03-14 14:34:33 +1030356
Andrew Jeffery5320f6e2019-03-15 12:40:41 +1030357 rc = backend_probe_vpnor(&context->backend, &paths);
358 if(rc < 0)
359 rc = backend_probe_mtd(&context->backend, NULL);
360
361 return rc;
Evan Lojewskif1e547c2019-03-14 14:34:33 +1030362 }
363
Andrew Jeffery5320f6e2019-03-15 12:40:41 +1030364 delim = strchr(context->source, ':');
365 path = delim ? delim + 1 : NULL;
366
367 if (!strncmp(context->source, "vpnor", strlen("vpnor"))) {
368 struct vpnor_partition_paths paths;
369
370 if (path) {
371 rc = -EINVAL;
372 } else {
373 vpnor_default_paths(&paths);
374 rc = backend_probe_vpnor(&context->backend, &paths);
375 }
376 } else if (!strncmp(context->source, "mtd", strlen("mtd"))) {
377 rc = backend_probe_mtd(&context->backend, path);
378 } else if (!strncmp(context->source, "file", strlen("file"))) {
379 rc = backend_probe_file(&context->backend, path);
380 } else {
381 rc = -EINVAL;
382 }
383
384 if (rc < 0)
385 MSG_ERR("Invalid backend argument: %s\n", context->source);
386
Evan Lojewskif1e547c2019-03-14 14:34:33 +1030387 return rc;
388}
389
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100390int main(int argc, char **argv)
391{
Andrew Jefferyfe0c9e82018-11-01 14:02:17 +1030392 const struct transport_ops *mbox_ops, *dbus_ops;
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100393 struct mbox_context *context;
Andrew Jeffery4b8203d2019-05-06 14:36:16 +0930394 bool have_transport_mbox;
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100395 char *name = argv[0];
396 sigset_t set;
397 int rc, i;
398
399 context = calloc(1, sizeof(*context));
400 if (!context) {
401 fprintf(stderr, "Memory allocation failed\n");
402 exit(1);
403 }
404
405 if (!parse_cmdline(argc, argv, context)) {
406 usage(name);
407 free(context);
408 exit(0);
409 }
410
411 for (i = 0; i < TOTAL_FDS; i++) {
412 context->fds[i].fd = -1;
413 }
414
Suraj Jitindar Singh28519592017-04-27 14:48:58 +1000415 MSG_INFO("Starting Daemon\n");
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100416
417 rc = init_signals(context, &set);
418 if (rc) {
Andrew Jeffery4ef0c132019-03-19 15:14:13 +1030419 goto cleanup_context;
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100420 }
421
Evan Lojewskif1e547c2019-03-14 14:34:33 +1030422 rc = mboxd_backend_init(context);
423 if (rc) {
Andrew Jeffery4ef0c132019-03-19 15:14:13 +1030424 goto cleanup_context;
Evan Lojewskif1e547c2019-03-14 14:34:33 +1030425 }
426
Andrew Jeffery1e531af2018-08-07 13:32:57 +0930427 rc = protocol_init(context);
428 if (rc) {
Andrew Jeffery4ef0c132019-03-19 15:14:13 +1030429 goto cleanup_backend;
Andrew Jeffery1e531af2018-08-07 13:32:57 +0930430 }
431
Andrew Jefferyfe0c9e82018-11-01 14:02:17 +1030432 rc = transport_mbox_init(context, &mbox_ops);
Andrew Jeffery4b8203d2019-05-06 14:36:16 +0930433 /* TODO: Think about whether we could use a less branch-y strategy */
434 have_transport_mbox = rc == 0;
435 if (!have_transport_mbox) {
436 /* Disable MBOX for poll()ing purposes */
437 context->fds[MBOX_FD].fd = -1;
438 MSG_DBG("Failed to initialise MBOX transport: %d\n", rc);
439 MSG_INFO("MBOX transport unavailable\n");
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100440 }
441
Andrew Jefferycb9b2102018-08-08 16:31:07 +0930442 rc = lpc_dev_init(context);
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100443 if (rc) {
Andrew Jeffery4ef0c132019-03-19 15:14:13 +1030444 goto cleanup_mbox;
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100445 }
446
447 /* We've found the reserved memory region -> we can assign to windows */
Andrew Jefferyc1a67fa2018-08-08 17:07:38 +0930448 rc = windows_init(context);
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100449 if (rc) {
Andrew Jeffery4ef0c132019-03-19 15:14:13 +1030450 goto cleanup_lpc;
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100451 }
452
Andrew Jefferyfe0c9e82018-11-01 14:02:17 +1030453 rc = dbus_init(context, &dbus_ops);
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100454 if (rc) {
Andrew Jeffery4ef0c132019-03-19 15:14:13 +1030455 goto cleanup_windows;
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100456 }
457
Deepak Kodihalli017e45c2017-07-12 01:06:30 -0500458 /* Set the LPC bus mapping */
Andrew Jefferyf69760d2019-03-14 16:54:13 +1030459 __protocol_reset(context);
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100460
Andrew Jefferyfe0c9e82018-11-01 14:02:17 +1030461 /* We're ready to go, alert the host */
462 context->bmc_events |= BMC_EVENT_DAEMON_READY;
Andrew Jeffery4c15bb12018-12-05 14:15:28 +1030463 context->bmc_events |= BMC_EVENT_PROTOCOL_RESET;
Andrew Jefferyfe0c9e82018-11-01 14:02:17 +1030464
Andrew Jeffery4b8203d2019-05-06 14:36:16 +0930465 /* Alert on all supported transports, as required */
466 if (have_transport_mbox) {
467 rc = protocol_events_put(context, mbox_ops);
468 if (rc) {
469 goto cleanup;
470 }
Andrew Jefferyfe0c9e82018-11-01 14:02:17 +1030471 }
472
473 rc = protocol_events_put(context, dbus_ops);
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100474 if (rc) {
Andrew Jeffery4ef0c132019-03-19 15:14:13 +1030475 goto cleanup;
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100476 }
477
Suraj Jitindar Singh28519592017-04-27 14:48:58 +1000478 MSG_INFO("Entering Polling Loop\n");
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100479 rc = poll_loop(context);
480
Suraj Jitindar Singh28519592017-04-27 14:48:58 +1000481 MSG_INFO("Exiting Poll Loop: %d\n", rc);
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100482
Suraj Jitindar Singh28519592017-04-27 14:48:58 +1000483 MSG_INFO("Daemon Exiting...\n");
Andrew Jefferyfe0c9e82018-11-01 14:02:17 +1030484 context->bmc_events &= ~BMC_EVENT_DAEMON_READY;
Andrew Jefferyfab672b2018-11-01 17:12:09 +1030485 context->bmc_events |= BMC_EVENT_PROTOCOL_RESET;
Andrew Jefferyfe0c9e82018-11-01 14:02:17 +1030486
Andrew Jeffery4b8203d2019-05-06 14:36:16 +0930487 /* Alert on all supported transports, as required */
488 if (have_transport_mbox) {
489 protocol_events_put(context, mbox_ops);
490 }
491
Andrew Jefferyfe0c9e82018-11-01 14:02:17 +1030492 protocol_events_put(context, dbus_ops);
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100493
Andrew Jeffery4ef0c132019-03-19 15:14:13 +1030494cleanup:
Andrew Jefferyef9e62d2018-08-08 15:48:27 +0930495 dbus_free(context);
Andrew Jeffery4ef0c132019-03-19 15:14:13 +1030496cleanup_windows:
Andrew Jefferyf5f51422018-08-08 17:08:33 +0930497 windows_free(context);
Andrew Jeffery4ef0c132019-03-19 15:14:13 +1030498cleanup_lpc:
499 lpc_dev_free(context);
500cleanup_mbox:
Andrew Jeffery4b8203d2019-05-06 14:36:16 +0930501 if (have_transport_mbox) {
502 transport_mbox_free(context);
503 }
Andrew Jeffery1e531af2018-08-07 13:32:57 +0930504 protocol_free(context);
Andrew Jeffery4ef0c132019-03-19 15:14:13 +1030505cleanup_backend:
506 backend_free(&context->backend);
507cleanup_context:
Stewart Smithef0c8362018-11-19 13:49:46 +1100508 if (context->blktracefd)
509 close(context->blktracefd);
510
Suraj Jitindar Singhe39c9162017-03-28 10:47:43 +1100511 free(context);
512
513 return rc;
514}