aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/apei/Kconfig1
-rw-r--r--drivers/acpi/apei/erst.c61
2 files changed, 46 insertions, 16 deletions
diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig
index 66a03caa2ad9..f739a70b1c70 100644
--- a/drivers/acpi/apei/Kconfig
+++ b/drivers/acpi/apei/Kconfig
@@ -1,5 +1,6 @@
1config ACPI_APEI 1config ACPI_APEI
2 bool "ACPI Platform Error Interface (APEI)" 2 bool "ACPI Platform Error Interface (APEI)"
3 select MISC_FILESYSTEMS
3 select PSTORE 4 select PSTORE
4 depends on X86 5 depends on X86
5 help 6 help
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c
index d6cb0ff6988e..e6cef8e1b534 100644
--- a/drivers/acpi/apei/erst.c
+++ b/drivers/acpi/apei/erst.c
@@ -929,13 +929,17 @@ static int erst_check_table(struct acpi_table_erst *erst_tab)
929 return 0; 929 return 0;
930} 930}
931 931
932static size_t erst_reader(u64 *id, enum pstore_type_id *type, 932static int erst_open_pstore(struct pstore_info *psi);
933static int erst_close_pstore(struct pstore_info *psi);
934static ssize_t erst_reader(u64 *id, enum pstore_type_id *type,
933 struct timespec *time); 935 struct timespec *time);
934static u64 erst_writer(enum pstore_type_id type, size_t size); 936static u64 erst_writer(enum pstore_type_id type, size_t size);
935 937
936static struct pstore_info erst_info = { 938static struct pstore_info erst_info = {
937 .owner = THIS_MODULE, 939 .owner = THIS_MODULE,
938 .name = "erst", 940 .name = "erst",
941 .open = erst_open_pstore,
942 .close = erst_close_pstore,
939 .read = erst_reader, 943 .read = erst_reader,
940 .write = erst_writer, 944 .write = erst_writer,
941 .erase = erst_clear 945 .erase = erst_clear
@@ -957,12 +961,32 @@ struct cper_pstore_record {
957 char data[]; 961 char data[];
958} __packed; 962} __packed;
959 963
960static size_t erst_reader(u64 *id, enum pstore_type_id *type, 964static int reader_pos;
965
966static int erst_open_pstore(struct pstore_info *psi)
967{
968 int rc;
969
970 if (erst_disable)
971 return -ENODEV;
972
973 rc = erst_get_record_id_begin(&reader_pos);
974
975 return rc;
976}
977
978static int erst_close_pstore(struct pstore_info *psi)
979{
980 erst_get_record_id_end();
981
982 return 0;
983}
984
985static ssize_t erst_reader(u64 *id, enum pstore_type_id *type,
961 struct timespec *time) 986 struct timespec *time)
962{ 987{
963 int rc; 988 int rc;
964 ssize_t len; 989 ssize_t len = 0;
965 unsigned long flags;
966 u64 record_id; 990 u64 record_id;
967 struct cper_pstore_record *rcd = (struct cper_pstore_record *) 991 struct cper_pstore_record *rcd = (struct cper_pstore_record *)
968 (erst_info.buf - sizeof(*rcd)); 992 (erst_info.buf - sizeof(*rcd));
@@ -970,24 +994,28 @@ static size_t erst_reader(u64 *id, enum pstore_type_id *type,
970 if (erst_disable) 994 if (erst_disable)
971 return -ENODEV; 995 return -ENODEV;
972 996
973 raw_spin_lock_irqsave(&erst_lock, flags);
974skip: 997skip:
975 rc = __erst_get_next_record_id(&record_id); 998 rc = erst_get_record_id_next(&reader_pos, &record_id);
976 if (rc) { 999 if (rc)
977 raw_spin_unlock_irqrestore(&erst_lock, flags); 1000 goto out;
978 return rc; 1001
979 }
980 /* no more record */ 1002 /* no more record */
981 if (record_id == APEI_ERST_INVALID_RECORD_ID) { 1003 if (record_id == APEI_ERST_INVALID_RECORD_ID) {
982 raw_spin_unlock_irqrestore(&erst_lock, flags); 1004 rc = -1;
983 return 0; 1005 goto out;
984 } 1006 }
985 1007
986 len = __erst_read(record_id, &rcd->hdr, sizeof(*rcd) + 1008 len = erst_read(record_id, &rcd->hdr, sizeof(*rcd) +
987 erst_erange.size); 1009 erst_info.bufsize);
1010 /* The record may be cleared by others, try read next record */
1011 if (len == -ENOENT)
1012 goto skip;
1013 else if (len < 0) {
1014 rc = -1;
1015 goto out;
1016 }
988 if (uuid_le_cmp(rcd->hdr.creator_id, CPER_CREATOR_PSTORE) != 0) 1017 if (uuid_le_cmp(rcd->hdr.creator_id, CPER_CREATOR_PSTORE) != 0)
989 goto skip; 1018 goto skip;
990 raw_spin_unlock_irqrestore(&erst_lock, flags);
991 1019
992 *id = record_id; 1020 *id = record_id;
993 if (uuid_le_cmp(rcd->sec_hdr.section_type, 1021 if (uuid_le_cmp(rcd->sec_hdr.section_type,
@@ -1005,7 +1033,8 @@ skip:
1005 time->tv_sec = 0; 1033 time->tv_sec = 0;
1006 time->tv_nsec = 0; 1034 time->tv_nsec = 0;
1007 1035
1008 return len - sizeof(*rcd); 1036out:
1037 return (rc < 0) ? rc : (len - sizeof(*rcd));
1009} 1038}
1010 1039
1011static u64 erst_writer(enum pstore_type_id type, size_t size) 1040static u64 erst_writer(enum pstore_type_id type, size_t size)