diff options
-rw-r--r-- | hw/fsp/fsp-elog-read.c | 18 | ||||
-rw-r--r-- | hw/fsp/fsp-elog-write.c | 3 |
2 files changed, 18 insertions, 3 deletions
diff --git a/hw/fsp/fsp-elog-read.c b/hw/fsp/fsp-elog-read.c index b606236..4f0bf16 100644 --- a/hw/fsp/fsp-elog-read.c +++ b/hw/fsp/fsp-elog-read.c @@ -416,21 +416,33 @@ static int64_t fsp_opal_elog_ack(uint64_t ack_id) return rc; } lock(&elog_read_lock); - list_for_each_safe(&elog_read_pending, record, next_record, link) { + list_for_each_safe(&elog_read_processed, record, next_record, link) { if (record->log_id != ack_id) continue; list_del(&record->link); list_add(&elog_read_free, &record->link); + unlock(&elog_read_lock); + return rc; } - list_for_each_safe(&elog_read_processed, record, next_record, link) { + list_for_each_safe(&elog_read_pending, record, next_record, link) { if (record->log_id != ack_id) continue; + /* It means host has sent ACK without reading actual data. + * Because of this elog_read_from_fsp_head_state may be + * stuck in wrong state (ELOG_STATE_HOST_INFO) and not able + * to send remaining ELOGs to host. Hence reset ELOG state + * and start sending remaining ELOGs. + */ list_del(&record->link); list_add(&elog_read_free, &record->link); + elog_reject_head(); + unlock(&elog_read_lock); + fsp_elog_check_and_fetch_head(); + return rc; } unlock(&elog_read_lock); - return rc; + return OPAL_PARAMETER; } /* diff --git a/hw/fsp/fsp-elog-write.c b/hw/fsp/fsp-elog-write.c index 80a0a39..b78bc20 100644 --- a/hw/fsp/fsp-elog-write.c +++ b/hw/fsp/fsp-elog-write.c @@ -248,6 +248,9 @@ bool opal_elog_ack(uint64_t ack_id) list_del(&record->link); opal_elog_complete(record, true); rc = true; + unlock(&elog_write_to_host_lock); + opal_commit_elog_in_host(); + return rc; } } unlock(&elog_write_to_host_lock); |