Commit be37f259 authored by Jonathan Currier's avatar Jonathan Currier

Migrate transport, and other mechanism away from poll, and to epoll.

This will easy the transition to making transports compile time
optional.

NOTE: this commit if unfinished and should eventually be rebased &
squashed.

specifically, the shutdown code no longer works correctly.
parent 200e3736
......@@ -5,11 +5,11 @@
#include "backend.h"
#include "common.h"
#include "dbus.h"
#include "lpc.h"
#include "mboxd.h"
#include "protocol.h"
#include "windows.h"
#include "hiomapd-state.h"
int control_ping(struct mbox_context *context)
{
......
......@@ -202,7 +202,7 @@ static int control_dbus_get_u8(sd_bus *bus, const char *path,
sd_bus_message *reply, void *userdata,
sd_bus_error *ret_error)
{
struct mbox_context *context = userdata;
struct mbox_context *context = dctx_to_mctx((struct transport_dbus_context*)userdata);
uint8_t value;
assert(!strcmp(MBOX_DBUS_OBJECT, path));
......@@ -242,12 +242,12 @@ static const sd_bus_vtable mboxd_vtable[] = {
SD_BUS_VTABLE_END
};
int control_dbus_init(struct mbox_context *context)
int control_dbus_init(struct transport_dbus_context *dctx)
{
return sd_bus_add_object_vtable(context->bus, NULL,
return sd_bus_add_object_vtable(dctx->bus, NULL,
MBOX_DBUS_OBJECT,
MBOX_DBUS_CONTROL_IFACE,
mboxd_vtable, context);
mboxd_vtable, dctx);
}
#define __unused __attribute__((unused))
......
......@@ -294,20 +294,19 @@ static const sd_bus_vtable control_legacy_vtable[] = {
SD_BUS_VTABLE_END
};
int control_legacy_init(struct mbox_context *context)
int control_legacy_init(struct transport_dbus_context *dctx)
{
int rc;
rc = sd_bus_add_object_vtable(context->bus, NULL,
rc = sd_bus_add_object_vtable(dctx->bus, NULL,
MBOX_DBUS_LEGACY_OBJECT,
MBOX_DBUS_LEGACY_NAME,
control_legacy_vtable, context);
control_legacy_vtable, dctx);
if (rc < 0) {
MSG_ERR("Failed to register vtable: %s\n", strerror(-rc));
return rc;
}
return sd_bus_request_name(context->bus, MBOX_DBUS_LEGACY_NAME,
return sd_bus_request_name(dctx->bus, MBOX_DBUS_LEGACY_NAME,
SD_BUS_NAME_ALLOW_REPLACEMENT |
SD_BUS_NAME_REPLACE_EXISTING);
}
......
......@@ -25,22 +25,24 @@
#define MBOX_DBUS_LEGACY_NAME "org.openbmc.mboxd"
#define MBOX_DBUS_LEGACY_OBJECT "/org/openbmc/mboxd"
/* Command Args */
/* Resume */
#define RESUME_NUM_ARGS 1
#define RESUME_NOT_MODIFIED 0x00
#define RESUME_FLASH_MODIFIED 0x01
/* Response Args */
/* Status */
#define DAEMON_STATE_NUM_ARGS 1
#define DAEMON_STATE_ACTIVE 0x00 /* Daemon Active */
#define DAEMON_STATE_SUSPENDED 0x01 /* Daemon Suspended */
/* LPC State */
#define LPC_STATE_NUM_ARGS 1
#define LPC_STATE_INVALID 0x00 /* Invalid State */
#define LPC_STATE_FLASH 0x01 /* LPC Maps Flash Directly */
#define LPC_STATE_MEM 0x02 /* LPC Maps Memory */
#include "hiomapd-state.h"
struct transport_dbus_context {
struct ops_container w;
struct mbox_context *context;
sd_bus *bus;
int dbus_fd;
};
static inline struct mbox_context *dctx_to_mctx(struct transport_dbus_context *dctx)
{
return dctx->context;
}
static inline struct transport_dbus_context *
container_to_dctx(struct ops_container *container)
{
return container_of(container, struct transport_dbus_context, w);
}
#endif /* MBOX_DBUS_H */
#ifndef HIOMAPD_STATE_H
#define HIOMAPD_STATE_H
/* Command Args */
/* Resume */
#define RESUME_NUM_ARGS 1
#define RESUME_NOT_MODIFIED 0x00
#define RESUME_FLASH_MODIFIED 0x01
/* Response Args */
/* Status */
#define DAEMON_STATE_NUM_ARGS 1
#define DAEMON_STATE_ACTIVE 0x00 /* Daemon Active */
#define DAEMON_STATE_SUSPENDED 0x01 /* Daemon Suspended */
/* LPC State */
#define LPC_STATE_NUM_ARGS 1
#define LPC_STATE_INVALID 0x00 /* Invalid State */
#define LPC_STATE_FLASH 0x01 /* LPC Maps Flash Directly */
#define LPC_STATE_MEM 0x02 /* LPC Maps Memory */
#endif
......@@ -32,6 +32,10 @@
#define LPC_CTRL_PATH "/dev/aspeed-lpc-ctrl"
struct host_lpc_link_context {
int lpcfd;
};
int __lpc_dev_init(struct mbox_context *context, const char *path)
{
struct aspeed_lpc_ctrl_mapping map = {
......@@ -43,6 +47,13 @@ int __lpc_dev_init(struct mbox_context *context, const char *path)
.size = 0
};
int fd;
struct host_lpc_link_context *lctx = calloc(1,sizeof(*lctx));
if (!lctx) {
MSG_ERR("Couldn't allocate lpc link context\n");
return -ENOMEM;
}
context->host_link_ctx = lctx;
/* Open LPC Device */
MSG_DBG("Opening %s\n", path);
......@@ -53,7 +64,7 @@ int __lpc_dev_init(struct mbox_context *context, const char *path)
return -errno;
}
context->fds[LPC_CTRL_FD].fd = fd;
lctx->lpcfd = fd;
/* Find Size of Reserved Memory Region */
MSG_DBG("Getting buffer size...\n");
......@@ -86,10 +97,11 @@ int lpc_dev_init(struct mbox_context *context)
void lpc_dev_free(struct mbox_context *context)
{
struct host_lpc_link_context *lctx = context->host_link_ctx;
if (context->mem) {
munmap(context->mem, context->mem_size);
}
close(context->fds[LPC_CTRL_FD].fd);
close(lctx->lpcfd);
}
/*
......@@ -100,6 +112,7 @@ void lpc_dev_free(struct mbox_context *context)
*/
int lpc_map_flash(struct mbox_context *context)
{
struct host_lpc_link_context *lctx = context->host_link_ctx;
struct aspeed_lpc_ctrl_mapping map = {
.window_type = ASPEED_LPC_CTRL_WINDOW_FLASH,
.window_id = 0, /* Theres only one */
......@@ -126,7 +139,7 @@ int lpc_map_flash(struct mbox_context *context)
MSG_INFO("Assuming %dMB of flash: HOST LPC 0x%08x\n",
context->backend.flash_size >> 20, map.addr);
if (ioctl(context->fds[LPC_CTRL_FD].fd, ASPEED_LPC_CTRL_IOCTL_MAP, &map)
if (ioctl(lctx->lpcfd, ASPEED_LPC_CTRL_IOCTL_MAP, &map)
== -1) {
MSG_ERR("Failed to point the LPC BUS at the actual flash: %s\n",
strerror(errno));
......@@ -150,6 +163,7 @@ int lpc_map_flash(struct mbox_context *context)
*/
int lpc_map_memory(struct mbox_context *context)
{
struct host_lpc_link_context *lctx = context->host_link_ctx;
struct aspeed_lpc_ctrl_mapping map = {
.window_type = ASPEED_LPC_CTRL_WINDOW_MEMORY,
.window_id = 0, /* There's only one */
......@@ -167,7 +181,7 @@ int lpc_map_memory(struct mbox_context *context)
context->mem, context->mem_size);
MSG_INFO("LPC address 0x%.8x\n", map.addr);
if (ioctl(context->fds[LPC_CTRL_FD].fd, ASPEED_LPC_CTRL_IOCTL_MAP,
if (ioctl(lctx->lpcfd, ASPEED_LPC_CTRL_IOCTL_MAP,
&map)) {
MSG_ERR("Failed to point the LPC BUS to memory: %s\n",
strerror(errno));
......
This diff is collapsed.
......@@ -7,7 +7,6 @@
#include <assert.h>
#include <linux/blktrace_api.h>
#include <mtd/mtd-abi.h>
#include <systemd/sd-bus.h>
#include <poll.h>
#include <stdbool.h>
......@@ -45,13 +44,6 @@ enum api_version {
BMC_EVENT_FLASH_CTRL_LOST | \
BMC_EVENT_DAEMON_READY)
/* Put polled file descriptors first */
#define DBUS_FD 0
#define MBOX_FD 1
#define SIG_FD 2
#define POLL_FDS 3 /* Number of FDs we poll on */
#define LPC_CTRL_FD 3
#define TOTAL_FDS 4
#define MAPS_FLASH (1 << 0)
#define MAPS_MEM (1 << 1)
......@@ -73,7 +65,8 @@ enum mbox_state {
struct mbox_context {
enum api_version version;
const struct protocol_ops *protocol;
const struct transport_ops *transport;
//const struct transport_ops *transport;
struct ops_container *transport;
struct backend backend;
/* Commandline parameters */
......@@ -81,8 +74,7 @@ struct mbox_context {
/* System State */
enum mbox_state state;
struct pollfd fds[TOTAL_FDS];
sd_bus *bus;
int epollfd;
bool terminate;
uint8_t bmc_events;
uint8_t prev_seq;
......@@ -102,6 +94,10 @@ struct mbox_context {
uint32_t mem_size;
/* LPC Bus Base Address (bytes) */
uint32_t lpc_base;
/* In this implementation it's the context for
* the lpc.c file, the details of which are unneeded
* for the rest of the code */
void *host_link_ctx;
/* Tracing */
int blktracefd;
......
......@@ -36,11 +36,11 @@ static inline uint8_t protocol_get_bmc_event_mask(struct mbox_context *context)
* Return: 0 on success otherwise negative error code
*/
int protocol_events_put(struct mbox_context *context,
const struct transport_ops *ops)
struct ops_container *container)
{
const uint8_t mask = protocol_get_bmc_event_mask(context);
return ops->put_events(context, mask);
return container->ops->put_events(container, mask);
}
/*
......@@ -61,7 +61,7 @@ int protocol_events_set(struct mbox_context *context, uint8_t bmc_event)
*/
context->bmc_events |= bmc_event;
return context->transport->set_events(context, bmc_event, mask);
return context->transport->ops->set_events(context->transport, bmc_event, mask);
}
/*
......@@ -78,7 +78,7 @@ int protocol_events_clear(struct mbox_context *context, uint8_t bmc_event)
context->bmc_events &= ~bmc_event;
return context->transport->clear_events(context, bmc_event, mask);
return context->transport->ops->clear_events(context->transport, bmc_event, mask);
}
static int protocol_negotiate_version(struct mbox_context *context,
......
......@@ -6,6 +6,7 @@
struct mbox_context;
struct transport_ops;
struct ops_container;
/*
* The GET_MBOX_INFO command is special as it can change the interface based on
......@@ -126,7 +127,7 @@ int __protocol_reset(struct mbox_context *context);
int protocol_reset(struct mbox_context *context);
int protocol_events_put(struct mbox_context *context,
const struct transport_ops *ops);
struct ops_container *container);
int protocol_events_set(struct mbox_context *context, uint8_t bmc_event);
int protocol_events_clear(struct mbox_context *context, uint8_t bmc_event);
......
......@@ -5,13 +5,48 @@
#define TRANSPORT_H
struct mbox_context;
struct ops_container;
struct epoll_event;
struct transport_ops {
int (*put_events)(struct mbox_context *context, uint8_t mask);
int (*set_events)(struct mbox_context *context, uint8_t events,
int (*init)(struct mbox_context *, struct transport_ops *);
int (*event)(struct ops_container *, struct epoll_event *);
int (*fini)(struct ops_container *);
int (*put_events)(struct ops_container *context, uint8_t mask);
int (*set_events)(struct ops_container *context, uint8_t events,
uint8_t mask);
int (*clear_events)(struct mbox_context *context, uint8_t events,
int (*clear_events)(struct ops_container *context, uint8_t events,
uint8_t mask);
};
#define DECLARE_TRANSPORT_OPS(name) \
static struct transport_ops name##_transport_ops; \
static const __attribute((section("ops_array"),used)) \
struct transport_ops *private_##name##_transport_ops_pointer = \
& name##_transport_ops; \
static struct transport_ops name##_transport_ops
/* this is used to have a generic pointer, even
* if it's embedded in a type other code may have no knowledge of.*/
struct ops_container {
struct transport_ops *ops;
};
#define container_of(ptr, type, member) ({ \
/* Store ptr in a var so it's not expanded multiple times, \
* if it's an expression*/ \
void *__l_ptr = (void*)(ptr); \
((type *)(__l_ptr - __builtin_offsetof(type, member))); })
/* We add EPOLLOUT so that the transport has a chance
* to do some late init*/
#define register_event_fd(fd, ctx, payload) \
({ \
struct epoll_event evt = { \
.events = EPOLLIN | EPOLLOUT, \
.data = { .ptr = payload, }, \
}; \
epoll_ctl(ctx->epollfd, EPOLL_CTL_ADD, fd, &evt); \
})
#endif /* TRANSPORT_H */
......@@ -6,6 +6,7 @@
#include <errno.h>
#include <string.h>
#include <systemd/sd-bus.h>
#include <sys/epoll.h>
#include "common.h"
#include "dbus.h"
......@@ -13,9 +14,13 @@
#include "protocol.h"
#include "transport.h"
static int transport_dbus_property_update(struct mbox_context *context,
static int dbus_init(struct mbox_context *context,
const struct transport_ops *ops);
static int transport_dbus_property_update(struct ops_container *container,
uint8_t events)
{
struct transport_dbus_context *dctx = container_to_dctx(container);
/* Two properties plus a terminating NULL */
char *props[5] = { 0 };
int i = 0;
......@@ -37,7 +42,7 @@ static int transport_dbus_property_update(struct mbox_context *context,
props[i++] = "ProtocolReset";
}
rc = sd_bus_emit_properties_changed_strv(context->bus,
rc = sd_bus_emit_properties_changed_strv(dctx->bus,
MBOX_DBUS_OBJECT,
/* FIXME: Hard-coding v2 */
MBOX_DBUS_PROTOCOL_IFACE_V2,
......@@ -47,24 +52,58 @@ static int transport_dbus_property_update(struct mbox_context *context,
}
static int transport_dbus_put_events(struct mbox_context *context, uint8_t mask)
static int transport_dbus_put_events(struct ops_container *context, uint8_t mask)
{
return transport_dbus_property_update(context, mask);
}
static int transport_dbus_set_events(struct mbox_context *context,
static int transport_dbus_set_events(struct ops_container *context,
uint8_t events, uint8_t mask)
{
return transport_dbus_property_update(context, events & mask);
}
static int transport_dbus_clear_events(struct mbox_context *context,
static int transport_dbus_clear_events(struct ops_container *context,
uint8_t events, uint8_t mask)
{
return transport_dbus_property_update(context, events & mask);
}
static const struct transport_ops transport_dbus_ops = {
static int transport_dbus_event(struct ops_container *container,
struct epoll_event *evt)
{
struct transport_dbus_context *dctx = container_to_dctx(container);
int rc;
if (!(evt->events & EPOLLIN))
return -EINVAL;
while ((rc = sd_bus_process(dctx->bus, NULL)) > 0) {
MSG_DBG("DBUS Event\n");
}
if (rc < 0) {
MSG_ERR("Error handling DBUS event: %s\n",
strerror(-rc));
}
return rc;
}
static void dbus_free(struct ops_container *container)
{
struct transport_dbus_context *dctx = container_to_dctx(container);
struct mbox_context *context = dctx_to_mctx(dctx);
transport_dbus_free(context);
control_dbus_free(context);
control_legacy_free(context);
sd_bus_unref(dctx->bus);
free(dctx);
}
DECLARE_TRANSPORT_OPS(dbus) = {
.init = dbus_init,
.event = transport_dbus_event,
.fini = dbus_free,
.put_events = transport_dbus_put_events,
.set_events = transport_dbus_set_events,
.clear_events = transport_dbus_clear_events,
......@@ -73,7 +112,7 @@ static const struct transport_ops transport_dbus_ops = {
static int transport_dbus_reset(sd_bus_message *m, void *userdata,
sd_bus_error *ret_error)
{
struct mbox_context *context = userdata;
struct mbox_context *context = dctx_to_mctx((struct transport_dbus_context*)userdata);
sd_bus_message *n;
int rc;
......@@ -101,7 +140,8 @@ static int transport_dbus_reset(sd_bus_message *m, void *userdata,
static int transport_dbus_get_info(sd_bus_message *m, void *userdata,
sd_bus_error *ret_error)
{
struct mbox_context *context = userdata;
struct transport_dbus_context *ctx = userdata;
struct mbox_context *context = dctx_to_mctx(dctx);
struct protocol_get_info io;
sd_bus_message *n;
int rc;
......@@ -123,7 +163,7 @@ static int transport_dbus_get_info(sd_bus_message *m, void *userdata,
}
/* Switch transport to DBus. This is fine as DBus signals are async */
context->transport = &transport_dbus_ops;
context->transport = &dctx->w;
/* A bit messy, but we need the correct event mask */
protocol_events_set(context, context->bmc_events);
......@@ -156,7 +196,7 @@ static int transport_dbus_get_info(sd_bus_message *m, void *userdata,
static int transport_dbus_get_flash_info(sd_bus_message *m, void *userdata,
sd_bus_error *ret_error)
{
struct mbox_context *context = userdata;
struct mbox_context *context = dctx_to_mctx((struct transport_dbus_context*)userdata);
struct protocol_get_flash_info io;
sd_bus_message *n;
int rc;
......@@ -239,7 +279,7 @@ static int transport_dbus_create_window(struct mbox_context *context,
static int transport_dbus_create_read_window(sd_bus_message *m, void *userdata,
sd_bus_error *ret_error)
{
struct mbox_context *context = userdata;
struct mbox_context *context = dctx_to_mctx((struct transport_dbus_context*)userdata);
return transport_dbus_create_window(context, true, m, ret_error);
}
......@@ -247,7 +287,7 @@ static int transport_dbus_create_read_window(sd_bus_message *m, void *userdata,
static int transport_dbus_create_write_window(sd_bus_message *m, void *userdata,
sd_bus_error *ret_error)
{
struct mbox_context *context = userdata;
struct mbox_context *context = dctx_to_mctx((struct transport_dbus_context*)userdata);
return transport_dbus_create_window(context, false, m, ret_error);
}
......@@ -255,7 +295,7 @@ static int transport_dbus_create_write_window(sd_bus_message *m, void *userdata,
static int transport_dbus_close_window(sd_bus_message *m, void *userdata,
sd_bus_error *ret_error)
{
struct mbox_context *context = userdata;
struct mbox_context *context = dctx_to_mctx((struct transport_dbus_context*)userdata);
struct protocol_close io;
sd_bus_message *n;
int rc;
......@@ -291,7 +331,7 @@ static int transport_dbus_close_window(sd_bus_message *m, void *userdata,
static int transport_dbus_mark_dirty(sd_bus_message *m, void *userdata,
sd_bus_error *ret_error)
{
struct mbox_context *context = userdata;
struct mbox_context *context = dctx_to_mctx((struct transport_dbus_context*)userdata);
struct protocol_mark_dirty io;
sd_bus_message *n;
int rc;
......@@ -326,7 +366,7 @@ static int transport_dbus_mark_dirty(sd_bus_message *m, void *userdata,
static int transport_dbus_write_flush(sd_bus_message *m, void *userdata,
sd_bus_error *ret_error)
{
struct mbox_context *context = userdata;
struct mbox_context *context = dctx_to_mctx((struct transport_dbus_context*)userdata);
sd_bus_message *n;
int rc;
......@@ -354,7 +394,7 @@ static int transport_dbus_write_flush(sd_bus_message *m, void *userdata,
static int transport_dbus_ack(sd_bus_message *m, void *userdata,
sd_bus_error *ret_error)
{
struct mbox_context *context = userdata;
struct mbox_context *context = dctx_to_mctx((struct transport_dbus_context*)userdata);
struct protocol_ack io;
sd_bus_message *n;
int rc;
......@@ -389,7 +429,7 @@ static int transport_dbus_ack(sd_bus_message *m, void *userdata,
static int transport_dbus_erase(sd_bus_message *m, void *userdata,
sd_bus_error *ret_error)
{
struct mbox_context *context = userdata;
struct mbox_context *context = dctx_to_mctx((struct transport_dbus_context*)userdata);
struct protocol_erase io;
sd_bus_message *n;
int rc;
......@@ -429,7 +469,7 @@ static int transport_dbus_get_property(sd_bus *bus,
void *userdata,
sd_bus_error *ret_error)
{
struct mbox_context *context = userdata;
struct mbox_context *context = dctx_to_mctx((struct transport_dbus_context*)userdata);
bool value;
assert(!strcmp(MBOX_DBUS_OBJECT, path));
......@@ -504,33 +544,30 @@ static const sd_bus_vtable protocol_v2_vtable[] = {
SD_BUS_VTABLE_END
};
int transport_dbus_init(struct mbox_context *context,
const struct transport_ops **ops)
int transport_dbus_init(struct transport_dbus_context* dctx,
const struct transport_ops *ops)
{
int rc;
struct mbox_context *context = dctx_to_mctx(dctx);
rc = sd_bus_add_object_vtable(context->bus, NULL,
rc = sd_bus_add_object_vtable(dctx->bus, NULL,
MBOX_DBUS_OBJECT,
MBOX_DBUS_PROTOCOL_IFACE,
protocol_unversioned_vtable,
context);
dctx);
if (rc < 0) {
return rc;
}
rc = sd_bus_add_object_vtable(context->bus, NULL,
rc = sd_bus_add_object_vtable(dctx->bus, NULL,
MBOX_DBUS_OBJECT,
MBOX_DBUS_PROTOCOL_IFACE_V2,
protocol_v2_vtable, context);
protocol_v2_vtable, dctx);
if (rc < 0) {
return rc;
}
context->transport = &transport_dbus_ops;
if (ops) {
*ops = &transport_dbus_ops;
}
context->transport = &dctx->w;
return 0;
}
......@@ -540,3 +577,67 @@ void transport_dbus_free(struct mbox_context *context __unused)
{
return;
}
static int dbus_init(struct mbox_context *context,
const struct transport_ops *ops)
{
int rc;
struct transport_dbus_context *dctx =
(struct transport_dbus_context *)calloc(1, sizeof(*dctx));
if (!dctx) {
rc = -ENOMEM;
MSG_ERR("Failed to allocate memory for dbus context\n");
return rc;
}
dctx->context = context;
dctx->w.ops = ops;
rc = sd_bus_default_system(&dctx->bus);
if (rc < 0) {
MSG_ERR("Failed to connect to the system bus: %s\n",
strerror(-rc));
return rc;
}
rc = control_legacy_init(dctx);
if (rc < 0) {
MSG_ERR("Failed to initialise legacy DBus interface: %s\n",
strerror(-rc));
return rc;
}
rc = control_dbus_init(dctx);
if (rc < 0) {
MSG_ERR("Failed to initialise DBus control interface: %s\n",
strerror(-rc));
return rc;
}
rc = transport_dbus_init(dctx, ops);
if (rc < 0) {
MSG_ERR("Failed to initialise DBus protocol interface: %s\n",
strerror(-rc));
return rc;
}
rc = sd_bus_request_name(dctx->bus, MBOX_DBUS_NAME,
SD_BUS_NAME_ALLOW_REPLACEMENT |
SD_BUS_NAME_REPLACE_EXISTING);
if (rc < 0) {
MSG_ERR("Failed to request DBus name: %s\n", strerror(-rc));
return rc;
}
rc = sd_bus_get_fd(dctx->bus);
if (rc < 0) {
MSG_ERR("Failed to get bus fd: %s\n", strerror(-rc));
return rc;
}
dctx->dbus_fd = rc;
register_event_fd(dctx->dbus_fd, context, &dctx->w);
return 0;
}
This diff is collapsed.
......@@ -52,9 +52,4 @@ union mbox_regs {
struct mbox_msg msg;
};
int transport_mbox_dispatch(struct mbox_context *context);
int transport_mbox_init(struct mbox_context *context,
const struct transport_ops **ops);
void transport_mbox_free(struct mbox_context *context);
#endif /* MBOXD_MSG_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment