From 78a2da4ca3b5362b7b9ba5632e6d4287a3c3263e Mon Sep 17 00:00:00 2001 From: Alistair Popple Date: Tue, 9 Sep 2014 15:57:28 +1000 Subject: bt/ipmi: Convert to using asynchronous messaging Previously we were doing synchronous messaging and cranking the bt state machine from within OPAL. This was not ideal as it could potentially take control away from the OS for long periods of time if the BMC is busy. This patch solves the problem using the opal_poll api to do asynchronous messaging. Signed-off-by: Alistair Popple Signed-off-by: Benjamin Herrenschmidt --- hw/ipmi/ipmi-power.c | 2 +- hw/ipmi/ipmi-rtc.c | 39 +++++++++++++++++++++++++++++---------- 2 files changed, 30 insertions(+), 11 deletions(-) (limited to 'hw/ipmi') diff --git a/hw/ipmi/ipmi-power.c b/hw/ipmi/ipmi-power.c index ac37d14..c8589c1 100644 --- a/hw/ipmi/ipmi-power.c +++ b/hw/ipmi/ipmi-power.c @@ -36,5 +36,5 @@ int64_t ipmi_opal_chassis_control(uint64_t request) prlog(PR_INFO, "IPMI: sending chassis control request %llu\n", request); - return ipmi_sync_queue_msg(msg); + return ipmi_queue_msg(msg); } diff --git a/hw/ipmi/ipmi-rtc.c b/hw/ipmi/ipmi-rtc.c index 5ddfced..7ac33ff 100644 --- a/hw/ipmi/ipmi-rtc.c +++ b/hw/ipmi/ipmi-rtc.c @@ -24,15 +24,17 @@ /* Sane default (2014/01/01) */ static time_t time = 1388494800; +static enum {idle, waiting, updated} time_status; + static void get_sel_time_complete(struct ipmi_msg *msg) { uint32_t result; memcpy(&result, msg->data, 4); time = le32_to_cpu(result); + time_status = updated; } - static int64_t ipmi_get_sel_time(void) { struct ipmi_msg *msg; @@ -42,7 +44,7 @@ static int64_t ipmi_get_sel_time(void) if (!msg) return OPAL_HARDWARE; - return ipmi_sync_queue_msg(msg); + return ipmi_queue_msg(msg); } static int64_t ipmi_set_sel_time(uint32_t tv) @@ -54,20 +56,37 @@ static int64_t ipmi_set_sel_time(uint32_t tv) if (!msg) return OPAL_HARDWARE; - return ipmi_sync_queue_msg(msg); + return ipmi_queue_msg(msg); } +void bt_poll(void *data __unused); static int64_t ipmi_opal_rtc_read(uint32_t *y_m_d, uint64_t *h_m_s_m) { struct tm tm; - - if (ipmi_get_sel_time() < 0) - return OPAL_HARDWARE; - - gmtime_r(&time, &tm); - tm_to_datetime(&tm, y_m_d, h_m_s_m); - return OPAL_SUCCESS; + int ret = 0; + + switch(time_status) { + case idle: + if (ipmi_get_sel_time() < 0) + return OPAL_HARDWARE; + time_status = waiting; + ret = OPAL_BUSY_EVENT; + break; + + case waiting: + ret = OPAL_BUSY_EVENT; + break; + + case updated: + gmtime_r(&time, &tm); + tm_to_datetime(&tm, y_m_d, h_m_s_m); + time_status = idle; + ret = OPAL_SUCCESS; + break; + } + + return ret; } static int64_t ipmi_opal_rtc_write(uint32_t year_month_day, -- cgit v1.1