From 0453aa4c8a7861ad405532b5f0f21a0e3206342e Mon Sep 17 00:00:00 2001 From: Andrew Jeffery Date: Tue, 21 Aug 2018 08:25:46 +0930 Subject: transport: Rework BMC event handling Change-Id: I99b13eca8f25d9855aac2af0a9ec46dfe5390834 Signed-off-by: Andrew Jeffery --- protocol.c | 33 ++++++++++++++++++++++----------- transport_dbus.c | 36 ++++++++++++++++++++---------------- transport_mbox.c | 3 ++- 3 files changed, 44 insertions(+), 28 deletions(-) diff --git a/protocol.c b/protocol.c index 82c1ca7..2c97f92 100644 --- a/protocol.c +++ b/protocol.c @@ -13,6 +13,15 @@ #define BLOCK_SIZE_SHIFT_V1 12 /* 4K */ +static inline uint8_t protocol_get_bmc_event_mask(struct mbox_context *context) +{ + if (context->version == API_VERSION_1) { + return BMC_EVENT_V1_MASK; + } + + return BMC_EVENT_V2_MASK; +} + /* * protocol_events_set() - Set BMC events * @context: The mbox context pointer @@ -22,16 +31,14 @@ */ int protocol_events_set(struct mbox_context *context, uint8_t bmc_event) { - uint8_t mask = 0x00; - - switch (context->version) { - case API_VERSION_1: - mask = BMC_EVENT_V1_MASK; - break; - default: - mask = BMC_EVENT_V2_MASK; - break; - } + const uint8_t mask = protocol_get_bmc_event_mask(context); + + /* + * Store the raw value, as we may up- or down- grade the protocol + * version and subsequently need to flush the appropriate set. Instead + * we pass the masked value through to the transport + */ + context->bmc_events |= bmc_event; return context->transport->set_events(context, (bmc_event & mask)); } @@ -45,7 +52,11 @@ int protocol_events_set(struct mbox_context *context, uint8_t bmc_event) */ int protocol_events_clear(struct mbox_context *context, uint8_t bmc_event) { - return context->transport->clear_events(context, bmc_event); + const uint8_t mask = protocol_get_bmc_event_mask(context); + + context->bmc_events &= ~bmc_event; + + return context->transport->clear_events(context, (bmc_event & mask)); } int protocol_v1_reset(struct mbox_context *context) diff --git a/transport_dbus.c b/transport_dbus.c index 14fdc24..c1b78e3 100644 --- a/transport_dbus.c +++ b/transport_dbus.c @@ -13,12 +13,12 @@ #include "protocol.h" #include "transport.h" -static int transport_dbus_flush_events(struct mbox_context *context, - uint8_t events) +static int transport_dbus_property_update(struct mbox_context *context, + uint8_t events) { + /* Two properties plus a terminating NULL */ char *props[3] = { 0 }; int i = 0; - int rc; if (events & BMC_EVENT_FLASH_CTRL_LOST) { props[i++] = "FlashControlLost"; @@ -28,15 +28,27 @@ static int transport_dbus_flush_events(struct mbox_context *context, props[i++] = "DaemonReady"; } - rc = sd_bus_emit_properties_changed_strv(context->bus, + return sd_bus_emit_properties_changed_strv(context->bus, MBOX_DBUS_OBJECT, /* FIXME: Hard-coding v2 */ MBOX_DBUS_PROTOCOL_IFACE_V2, props); +} + +static int transport_dbus_set_events(struct mbox_context *context, + uint8_t events) +{ + int rc; + + rc = transport_dbus_property_update(context, events); if (rc < 0) { return rc; } + /* + * Handle signals - edge triggered, only necessary when they're + * asserted + */ if (events & BMC_EVENT_WINDOW_RESET) { sd_bus_message *m = NULL; @@ -76,20 +88,11 @@ static int transport_dbus_flush_events(struct mbox_context *context, return 0; } -static int transport_dbus_set_events(struct mbox_context *context, - uint8_t events) -{ - context->bmc_events |= events; - - return transport_dbus_flush_events(context, events); -} - static int transport_dbus_clear_events(struct mbox_context *context, uint8_t events) { - context->bmc_events &= ~events; - - return transport_dbus_flush_events(context, events); + /* No need to emit signals for ackable events on clear */ + return transport_dbus_property_update(context, events); } static const struct transport_ops transport_dbus_ops = { @@ -123,7 +126,8 @@ 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; - transport_dbus_flush_events(context, context->bmc_events); + /* A bit messy, but we need the correct event mask */ + protocol_events_set(context, context->bmc_events); rc = sd_bus_message_new_method_return(m, &n); if (rc < 0) { diff --git a/transport_mbox.c b/transport_mbox.c index 671e1c4..340a526 100644 --- a/transport_mbox.c +++ b/transport_mbox.c @@ -591,7 +591,8 @@ static int handle_mbox_req(struct mbox_context *context, union mbox_regs *req) if (context->transport != old_transport && context->transport == &transport_mbox_ops) { - transport_mbox_flush_events(context); + /* A bit messy, but we need the correct event mask */ + protocol_events_set(context, context->bmc_events); } return rc; -- cgit v1.2.1