aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/apei
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2011-06-23 20:20:51 +0000
committerNicholas Bellinger <nab@linux-iscsi.org>2011-06-23 20:20:51 +0000
commit74d83b7eedab14e4b963a2220ff76f98fa6d4cb8 (patch)
treeff4b10ebd9cf1a057c4b1a703732858a539faff7 /drivers/acpi/apei
parent[SCSI] target: Convert TASK_ATTR to scsi_tcq.h definitions (diff)
parentLinux 3.0-rc4 (diff)
downloadlinux-dev-74d83b7eedab14e4b963a2220ff76f98fa6d4cb8.tar.xz
linux-dev-74d83b7eedab14e4b963a2220ff76f98fa6d4cb8.zip
Merge tag 'v3.0-rc4' of /pub/scm/linux/kernel/git/torvalds/linux-2.6 into for-linus
Diffstat (limited to 'drivers/acpi/apei')
-rw-r--r--drivers/acpi/apei/Kconfig1
-rw-r--r--drivers/acpi/apei/einj.c8
-rw-r--r--drivers/acpi/apei/erst.c61
3 files changed, 54 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 @@
config ACPI_APEI
bool "ACPI Platform Error Interface (APEI)"
+ select MISC_FILESYSTEMS
select PSTORE
depends on X86
help
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c
index 096aebfe7f32..f74b2ea11f21 100644
--- a/drivers/acpi/apei/einj.c
+++ b/drivers/acpi/apei/einj.c
@@ -101,6 +101,14 @@ static DEFINE_MUTEX(einj_mutex);
static struct einj_parameter *einj_param;
+#ifndef writeq
+static inline void writeq(__u64 val, volatile void __iomem *addr)
+{
+ writel(val, addr);
+ writel(val >> 32, addr+4);
+}
+#endif
+
static void einj_exec_ctx_init(struct apei_exec_context *ctx)
{
apei_exec_ctx_init(ctx, einj_ins_type, ARRAY_SIZE(einj_ins_type),
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)
return 0;
}
-static size_t erst_reader(u64 *id, enum pstore_type_id *type,
+static int erst_open_pstore(struct pstore_info *psi);
+static int erst_close_pstore(struct pstore_info *psi);
+static ssize_t erst_reader(u64 *id, enum pstore_type_id *type,
struct timespec *time);
static u64 erst_writer(enum pstore_type_id type, size_t size);
static struct pstore_info erst_info = {
.owner = THIS_MODULE,
.name = "erst",
+ .open = erst_open_pstore,
+ .close = erst_close_pstore,
.read = erst_reader,
.write = erst_writer,
.erase = erst_clear
@@ -957,12 +961,32 @@ struct cper_pstore_record {
char data[];
} __packed;
-static size_t erst_reader(u64 *id, enum pstore_type_id *type,
+static int reader_pos;
+
+static int erst_open_pstore(struct pstore_info *psi)
+{
+ int rc;
+
+ if (erst_disable)
+ return -ENODEV;
+
+ rc = erst_get_record_id_begin(&reader_pos);
+
+ return rc;
+}
+
+static int erst_close_pstore(struct pstore_info *psi)
+{
+ erst_get_record_id_end();
+
+ return 0;
+}
+
+static ssize_t erst_reader(u64 *id, enum pstore_type_id *type,
struct timespec *time)
{
int rc;
- ssize_t len;
- unsigned long flags;
+ ssize_t len = 0;
u64 record_id;
struct cper_pstore_record *rcd = (struct cper_pstore_record *)
(erst_info.buf - sizeof(*rcd));
@@ -970,24 +994,28 @@ static size_t erst_reader(u64 *id, enum pstore_type_id *type,
if (erst_disable)
return -ENODEV;
- raw_spin_lock_irqsave(&erst_lock, flags);
skip:
- rc = __erst_get_next_record_id(&record_id);
- if (rc) {
- raw_spin_unlock_irqrestore(&erst_lock, flags);
- return rc;
- }
+ rc = erst_get_record_id_next(&reader_pos, &record_id);
+ if (rc)
+ goto out;
+
/* no more record */
if (record_id == APEI_ERST_INVALID_RECORD_ID) {
- raw_spin_unlock_irqrestore(&erst_lock, flags);
- return 0;
+ rc = -1;
+ goto out;
}
- len = __erst_read(record_id, &rcd->hdr, sizeof(*rcd) +
- erst_erange.size);
+ len = erst_read(record_id, &rcd->hdr, sizeof(*rcd) +
+ erst_info.bufsize);
+ /* The record may be cleared by others, try read next record */
+ if (len == -ENOENT)
+ goto skip;
+ else if (len < 0) {
+ rc = -1;
+ goto out;
+ }
if (uuid_le_cmp(rcd->hdr.creator_id, CPER_CREATOR_PSTORE) != 0)
goto skip;
- raw_spin_unlock_irqrestore(&erst_lock, flags);
*id = record_id;
if (uuid_le_cmp(rcd->sec_hdr.section_type,
@@ -1005,7 +1033,8 @@ skip:
time->tv_sec = 0;
time->tv_nsec = 0;
- return len - sizeof(*rcd);
+out:
+ return (rc < 0) ? rc : (len - sizeof(*rcd));
}
static u64 erst_writer(enum pstore_type_id type, size_t size)