aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/ia64/kernel/vmlinux.lds.S1
-rw-r--r--arch/ia64/oprofile/backtrace.c2
-rw-r--r--drivers/acpi/apei/Kconfig1
-rw-r--r--drivers/acpi/apei/erst.c61
-rw-r--r--fs/pstore/platform.c12
-rw-r--r--include/linux/pstore.h4
6 files changed, 60 insertions, 21 deletions
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index 787de4a77d82..53c0ba004e9e 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -209,6 +209,7 @@ SECTIONS {
209 data : { 209 data : {
210 } :data 210 } :data
211 .data : AT(ADDR(.data) - LOAD_OFFSET) { 211 .data : AT(ADDR(.data) - LOAD_OFFSET) {
212 _sdata = .;
212 INIT_TASK_DATA(PAGE_SIZE) 213 INIT_TASK_DATA(PAGE_SIZE)
213 CACHELINE_ALIGNED_DATA(SMP_CACHE_BYTES) 214 CACHELINE_ALIGNED_DATA(SMP_CACHE_BYTES)
214 READ_MOSTLY_DATA(SMP_CACHE_BYTES) 215 READ_MOSTLY_DATA(SMP_CACHE_BYTES)
diff --git a/arch/ia64/oprofile/backtrace.c b/arch/ia64/oprofile/backtrace.c
index 5cdd7e4a597c..f7b798993cea 100644
--- a/arch/ia64/oprofile/backtrace.c
+++ b/arch/ia64/oprofile/backtrace.c
@@ -29,7 +29,7 @@ typedef struct
29 unsigned int depth; 29 unsigned int depth;
30 struct pt_regs *regs; 30 struct pt_regs *regs;
31 struct unw_frame_info frame; 31 struct unw_frame_info frame;
32 u64 *prev_pfs_loc; /* state for WAR for old spinlock ool code */ 32 unsigned long *prev_pfs_loc; /* state for WAR for old spinlock ool code */
33} ia64_backtrace_t; 33} ia64_backtrace_t;
34 34
35/* Returns non-zero if the PC is in the Interrupt Vector Table */ 35/* Returns non-zero if the PC is in the Interrupt Vector Table */
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)
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index f835a25625ff..f2c3ff20ea68 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -152,21 +152,27 @@ EXPORT_SYMBOL_GPL(pstore_register);
152void pstore_get_records(void) 152void pstore_get_records(void)
153{ 153{
154 struct pstore_info *psi = psinfo; 154 struct pstore_info *psi = psinfo;
155 size_t size; 155 ssize_t size;
156 u64 id; 156 u64 id;
157 enum pstore_type_id type; 157 enum pstore_type_id type;
158 struct timespec time; 158 struct timespec time;
159 int failed = 0; 159 int failed = 0, rc;
160 160
161 if (!psi) 161 if (!psi)
162 return; 162 return;
163 163
164 mutex_lock(&psinfo->buf_mutex); 164 mutex_lock(&psinfo->buf_mutex);
165 rc = psi->open(psi);
166 if (rc)
167 goto out;
168
165 while ((size = psi->read(&id, &type, &time)) > 0) { 169 while ((size = psi->read(&id, &type, &time)) > 0) {
166 if (pstore_mkfile(type, psi->name, id, psi->buf, size, 170 if (pstore_mkfile(type, psi->name, id, psi->buf, (size_t)size,
167 time, psi->erase)) 171 time, psi->erase))
168 failed++; 172 failed++;
169 } 173 }
174 psi->close(psi);
175out:
170 mutex_unlock(&psinfo->buf_mutex); 176 mutex_unlock(&psinfo->buf_mutex);
171 177
172 if (failed) 178 if (failed)
diff --git a/include/linux/pstore.h b/include/linux/pstore.h
index 41977737bb7d..2455ef2683f0 100644
--- a/include/linux/pstore.h
+++ b/include/linux/pstore.h
@@ -35,7 +35,9 @@ struct pstore_info {
35 struct mutex buf_mutex; /* serialize access to 'buf' */ 35 struct mutex buf_mutex; /* serialize access to 'buf' */
36 char *buf; 36 char *buf;
37 size_t bufsize; 37 size_t bufsize;
38 size_t (*read)(u64 *id, enum pstore_type_id *type, 38 int (*open)(struct pstore_info *psi);
39 int (*close)(struct pstore_info *psi);
40 ssize_t (*read)(u64 *id, enum pstore_type_id *type,
39 struct timespec *time); 41 struct timespec *time);
40 u64 (*write)(enum pstore_type_id type, size_t size); 42 u64 (*write)(enum pstore_type_id type, size_t size);
41 int (*erase)(u64 id); 43 int (*erase)(u64 id);