Commit 5335f093 authored by Andrew Jeffery's avatar Andrew Jeffery
Browse files

protocol: Provide abstraction over event notification


How this works will be transport-dependent. Move the event notification
helpers into the protocol abstraction and call-back through the
registered flush handler as necessary.

Change-Id: I29e3a9a9785b92de46a2b2750257fb7f8480a184
Signed-off-by: Andrew Jeffery's avatarAndrew Jeffery <andrew@aj.id.au>
parent c48d0702
......@@ -47,7 +47,7 @@ int control_reset(struct mbox_context *context)
* 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.
*/
windows_reset_all(context, SET_BMC_EVENT);
windows_reset_all(context, EVENT_TRIGGER);
rc = lpc_reset(context);
if (rc < 0) {
return rc;
......@@ -71,7 +71,7 @@ int control_modified(struct mbox_context *context)
flash_set_bytemap(context, 0, context->flash_size, FLASH_DIRTY);
/* Force daemon to reload all windows -> Set BMC event to notify host */
windows_reset_all(context, SET_BMC_EVENT);
windows_reset_all(context, EVENT_TRIGGER);
return 0;
}
......@@ -86,7 +86,7 @@ int control_suspend(struct mbox_context *context)
}
/* Nothing to check - Just set the bit to notify the host */
rc = set_bmc_events(context, BMC_EVENT_FLASH_CTRL_LOST, SET_BMC_EVENT);
rc = protocol_events_set(context, BMC_EVENT_FLASH_CTRL_LOST, EVENT_TRIGGER);
if (rc < 0) {
return rc;
}
......@@ -111,7 +111,7 @@ int control_resume(struct mbox_context *context, bool modified)
}
/* Clear the bit and send the BMC Event to the host */
rc = clr_bmc_events(context, BMC_EVENT_FLASH_CTRL_LOST, SET_BMC_EVENT);
rc = protocol_events_clear(context, BMC_EVENT_FLASH_CTRL_LOST, EVENT_TRIGGER);
if (rc < 0) {
return rc;
}
......
......@@ -10,6 +10,7 @@
#include <stdbool.h>
#include "protocol.h"
#include "transport.h"
#include "vpnor/mboxd_pnor_partition_table.h"
enum api_version {
......@@ -134,12 +135,10 @@ union mbox_regs {
struct mbox_context;
typedef int (*mboxd_mbox_handler)(struct mbox_context *, union mbox_regs *,
struct mbox_msg *);
struct mbox_context {
enum api_version version;
const struct protocol_ops *protocol;
const struct transport_ops *transport;
/* System State */
enum mbox_state state;
......@@ -149,9 +148,6 @@ struct mbox_context {
uint8_t bmc_events;
uint8_t prev_seq;
/* Command Dispatch */
const mboxd_mbox_handler *handlers;
/* Window State */
/* The window list struct containing all current "windows" */
struct window_list windows;
......
......@@ -139,7 +139,7 @@ static int poll_loop(struct mbox_context *context)
break;
case SIGHUP:
/* Host didn't request reset -> Notify it */
windows_reset_all(context, SET_BMC_EVENT);
windows_reset_all(context, EVENT_TRIGGER);
rc = lpc_reset(context);
if (rc < 0) {
MSG_ERR("WARNING: Failed to point the "
......@@ -177,7 +177,7 @@ static int poll_loop(struct mbox_context *context)
/* Best to reset windows and the lpc mapping for safety */
/* Host didn't request reset -> Notify it */
windows_reset_all(context, SET_BMC_EVENT);
windows_reset_all(context, EVENT_TRIGGER);
rc = lpc_reset(context);
/* Not much we can do if this fails */
if (rc < 0) {
......@@ -394,7 +394,7 @@ int main(int argc, char **argv)
MSG_ERR("LPC configuration failed, RESET required: %d\n", rc);
}
rc = set_bmc_events(context, BMC_EVENT_DAEMON_READY, SET_BMC_EVENT);
rc = protocol_events_set(context, BMC_EVENT_DAEMON_READY, EVENT_TRIGGER);
if (rc) {
goto finish;
}
......@@ -406,7 +406,7 @@ int main(int argc, char **argv)
finish:
MSG_INFO("Daemon Exiting...\n");
clr_bmc_events(context, BMC_EVENT_DAEMON_READY, SET_BMC_EVENT);
protocol_events_clear(context, BMC_EVENT_DAEMON_READY, EVENT_TRIGGER);
#ifdef VIRTUAL_PNOR_ENABLED
destroy_vpnor(context);
......
......@@ -5,16 +5,61 @@
#include <errno.h>
#include <stdint.h>
#include "common.h"
#include "flash.h"
#include "mbox.h"
#include "lpc.h"
#include "transport_mbox.h" /* TODO: Remove dependency on transport_mbox.h */
#include "windows.h"
/*
* protocol_events_set() - Set BMC events
* @context: The mbox context pointer
* @bmc_event: The bits to set
* @write_back: Whether to write back to the register -> will interrupt host
*
* Return: 0 on success otherwise negative error code
*/
int protocol_events_set(struct mbox_context *context, uint8_t bmc_event,
bool write_back)
{
uint8_t mask = 0x00;
switch (context->version) {
case API_VERSION_1:
mask = BMC_EVENT_V1_MASK;
break;
default:
mask = BMC_EVENT_V2_MASK;
break;
}
context->bmc_events |= (bmc_event & mask);
MSG_DBG("BMC Events set to: 0x%.2x\n", context->bmc_events);
return write_back ? context->transport->flush_events(context) : 0;
}
/*
* protocol_events_clear() - Clear BMC events
* @context: The mbox context pointer
* @bmc_event: The bits to clear
* @write_back: Whether to write back to the register -> will interrupt host
*
* Return: 0 on success otherwise negative error code
*/
int protocol_events_clear(struct mbox_context *context, uint8_t bmc_event,
bool write_back)
{
context->bmc_events &= ~bmc_event;
MSG_DBG("BMC Events clear to: 0x%.2x\n", context->bmc_events);
return write_back ? context->transport->flush_events(context) : 0;
}
int protocol_v1_reset(struct mbox_context *context)
{
/* Host requested it -> No BMC Event */
windows_reset_all(context, NO_BMC_EVENT);
windows_reset_all(context, EVENT_SUPPRESS);
return lpc_reset(context);
}
......@@ -31,7 +76,7 @@ int protocol_v1_get_info(struct mbox_context *context,
/* Do the {up,down}grade if necessary*/
if (rc != old_version) {
windows_reset_all(context, SET_BMC_EVENT);
windows_reset_all(context, EVENT_TRIGGER);
return context->protocol->get_info(context, io);
}
......@@ -104,7 +149,7 @@ int protocol_v1_create_window(struct mbox_context *context,
return rc;
}
}
windows_close_current(context, NO_BMC_EVENT, FLAGS_NONE);
windows_close_current(context, EVENT_SUPPRESS, FLAGS_NONE);
}
/* Offset the host has requested */
......@@ -284,15 +329,15 @@ int protocol_v1_close(struct mbox_context *context, struct protocol_close *io)
}
/* Host asked for it -> Don't set the BMC Event */
windows_close_current(context, NO_BMC_EVENT, io->req.flags);
windows_close_current(context, EVENT_SUPPRESS, io->req.flags);
return 0;
}
int protocol_v1_ack(struct mbox_context *context, struct protocol_ack *io)
{
return clr_bmc_events(context, (io->req.flags & BMC_EVENT_ACK_MASK),
SET_BMC_EVENT);
return protocol_events_clear(context, (io->req.flags & BMC_EVENT_ACK_MASK),
EVENT_TRIGGER);
}
/*
......@@ -327,7 +372,7 @@ int protocol_v2_get_info(struct mbox_context *context,
/* Do the {up,down}grade if necessary*/
if (rc != old_version) {
windows_reset_all(context, SET_BMC_EVENT);
windows_reset_all(context, EVENT_TRIGGER);
return context->protocol->get_info(context, io);
}
......@@ -449,7 +494,7 @@ int protocol_v2_close(struct mbox_context *context, struct protocol_close *io)
}
/* Host asked for it -> Don't set the BMC Event */
windows_close_current(context, NO_BMC_EVENT, io->req.flags);
windows_close_current(context, EVENT_SUPPRESS, io->req.flags);
return 0;
}
......
......@@ -120,6 +120,14 @@ void protocol_free(struct mbox_context *context);
int protocol_negotiate_version(struct mbox_context *context, uint8_t requested);
#define EVENT_SUPPRESS false
#define EVENT_TRIGGER true
int protocol_events_set(struct mbox_context *context, uint8_t bmc_event,
bool write_back);
int protocol_events_clear(struct mbox_context *context, uint8_t bmc_event,
bool write_back);
/* Protocol v1 */
int protocol_v1_reset(struct mbox_context *context);
int protocol_v1_get_info(struct mbox_context *context,
......
......@@ -49,7 +49,7 @@ int main(void)
rc = mbox_command_dispatch(ctx, get_info, sizeof(get_info));
assert(rc == 1);
set_bmc_events(ctx, FLAGS, SET_BMC_EVENT);
protocol_events_set(ctx, FLAGS, EVENT_TRIGGER);
rc = mbox_command_dispatch(ctx, command, sizeof(command));
assert(rc == 1);
......
/* SPDX-License-Identifier: Apache-2.0 */
/* Copyright (C) 2018 IBM Corp. */
#ifndef TRANSPORT_H
#define TRANSPORT_H
#include "mbox.h"
struct transport_ops {
int (*flush_events)(struct mbox_context *context);
};
#endif /* TRANSPORT_H */
......@@ -84,12 +84,13 @@ static inline int mbox_xlate_errno(struct mbox_context *context,
}
/*
* write_bmc_event_reg() - Write to the BMC controlled status register (reg 15)
* transport_mbox_flush_events() - Write to the BMC controlled status register
* (reg 15)
* @context: The mbox context pointer
*
* Return: 0 on success otherwise negative error code
*/
static int write_bmc_event_reg(struct mbox_context *context)
static int transport_mbox_flush_events(struct mbox_context *context)
{
int rc;
......@@ -98,7 +99,7 @@ static int write_bmc_event_reg(struct mbox_context *context)
if (rc != MBOX_BMC_EVENT) {
MSG_ERR("Couldn't lseek mbox to byte %d: %s\n", MBOX_BMC_EVENT,
strerror(errno));
return -MBOX_R_SYSTEM_ERROR;
return -errno;
}
/* Write to mbox status register */
......@@ -106,7 +107,7 @@ static int write_bmc_event_reg(struct mbox_context *context)
if (rc != 1) {
MSG_ERR("Couldn't write to BMC status reg: %s\n",
strerror(errno));
return -MBOX_R_SYSTEM_ERROR;
return -errno;
}
/* Reset to start */
......@@ -114,57 +115,12 @@ static int write_bmc_event_reg(struct mbox_context *context)
if (rc) {
MSG_ERR("Couldn't reset MBOX offset to zero: %s\n",
strerror(errno));
return -MBOX_R_SYSTEM_ERROR;
return -errno;
}
return 0;
}
/*
* set_bmc_events() - Set BMC events
* @context: The mbox context pointer
* @bmc_event: The bits to set
* @write_back: Whether to write back to the register -> will interrupt host
*
* Return: 0 on success otherwise negative error code
*/
int set_bmc_events(struct mbox_context *context, uint8_t bmc_event,
bool write_back)
{
uint8_t mask = 0x00;
switch (context->version) {
case API_VERSION_1:
mask = BMC_EVENT_V1_MASK;
break;
default:
mask = BMC_EVENT_V2_MASK;
break;
}
context->bmc_events |= (bmc_event & mask);
MSG_DBG("BMC Events set to: 0x%.2x\n", context->bmc_events);
return write_back ? write_bmc_event_reg(context) : 0;
}
/*
* clr_bmc_events() - Clear BMC events
* @context: The mbox context pointer
* @bmc_event: The bits to clear
* @write_back: Whether to write back to the register -> will interrupt host
*
* Return: 0 on success otherwise negative error code
*/
int clr_bmc_events(struct mbox_context *context, uint8_t bmc_event,
bool write_back)
{
context->bmc_events &= ~bmc_event;
MSG_DBG("BMC Events clear to: 0x%.2x\n", context->bmc_events);
return write_back ? write_bmc_event_reg(context) : 0;
}
/* Command Handlers */
/*
......@@ -532,7 +488,10 @@ static int check_req_valid(struct mbox_context *context, union mbox_regs *req)
return 0;
}
static const mboxd_mbox_handler mbox_handlers[] = {
typedef int (*mboxd_mbox_handler)(struct mbox_context *, union mbox_regs *,
struct mbox_msg *);
static const mboxd_mbox_handler transport_mbox_handlers[] = {
mbox_handle_reset,
mbox_handle_mbox_info,
mbox_handle_flash_info,
......@@ -565,9 +524,11 @@ static int handle_mbox_req(struct mbox_context *context, union mbox_regs *req)
MSG_INFO("Received MBOX command: %u\n", req->msg.command);
rc = check_req_valid(context, req);
if (!rc) {
mboxd_mbox_handler handler;
/* Commands start at 1 so we have to subtract 1 from the cmd */
mboxd_mbox_handler h = context->handlers[req->msg.command - 1];
rc = h(context, req, &resp);
handler = transport_mbox_handlers[req->msg.command - 1];
rc = handler(context, req, &resp);
if (rc < 0) {
MSG_ERR("Error handling mbox cmd: %d\n",
req->msg.command);
......@@ -645,11 +606,15 @@ int dispatch_mbox(struct mbox_context *context)
return handle_mbox_req(context, &req);
}
static const struct transport_ops transport_mbox_ops = {
.flush_events = transport_mbox_flush_events,
};
int __init_mbox_dev(struct mbox_context *context, const char *path)
{
int fd;
context->handlers = mbox_handlers;
context->transport = &transport_mbox_ops;
/* Open MBOX Device */
fd = open(path, O_RDWR | O_NONBLOCK);
......
......@@ -7,13 +7,6 @@
#include "common.h"
#include "mbox.h"
#define NO_BMC_EVENT false
#define SET_BMC_EVENT true
int set_bmc_events(struct mbox_context *context, uint8_t bmc_event,
bool write_back);
int clr_bmc_events(struct mbox_context *context, uint8_t bmc_event,
bool write_back);
int dispatch_mbox(struct mbox_context *context);
int init_mbox_dev(struct mbox_context *context);
void free_mbox_dev(struct mbox_context *context);
......
......@@ -394,7 +394,7 @@ void windows_close_current(struct mbox_context *context, bool set_bmc_event,
MSG_DBG("Close current window, flags: 0x%.2x\n", flags);
if (set_bmc_event) {
set_bmc_events(context, BMC_EVENT_WINDOW_RESET, SET_BMC_EVENT);
protocol_events_set(context, BMC_EVENT_WINDOW_RESET, EVENT_TRIGGER);
}
if (flags & FLAGS_SHORT_LIFETIME) {
......
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