diff options
author | Huang Ying <ying.huang@intel.com> | 2011-02-21 00:54:41 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2011-03-21 22:59:06 -0400 |
commit | 885b976fada5bc6595a9fd3e67e3cb1a3d11f50b (patch) | |
tree | 8b598bd3b265c0bbe8237e129410fdc80fe7847a /drivers/acpi/apei/erst-dbg.c | |
parent | dd9c1549edef02290edced639f67b54a25abbe0e (diff) |
ACPI, APEI, Add ERST record ID cache
APEI ERST firmware interface and implementation has no multiple users
in mind. For example, if there is four records in storage with ID: 1,
2, 3 and 4, if two ERST readers enumerate the records via
GET_NEXT_RECORD_ID as follow,
reader 1 reader 2
1
2
3
4
-1
-1
where -1 signals there is no more record ID.
Reader 1 has no chance to check record 2 and 4, while reader 2 has no
chance to check record 1 and 3. And any other GET_NEXT_RECORD_ID will
return -1, that is, other readers will has no chance to check any
record even they are not cleared by anyone.
This makes raw GET_NEXT_RECORD_ID not suitable for used by multiple
users.
To solve the issue, an in-memory ERST record ID cache is designed and
implemented. When enumerating record ID, the ID returned by
GET_NEXT_RECORD_ID is added into cache in addition to be returned to
caller. So other readers can check the cache to get all record ID
available.
Signed-off-by: Huang Ying <ying.huang@intel.com>
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/apei/erst-dbg.c')
-rw-r--r-- | drivers/acpi/apei/erst-dbg.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/drivers/acpi/apei/erst-dbg.c b/drivers/acpi/apei/erst-dbg.c index de73caf3cebc..a4cfb64c86a1 100644 --- a/drivers/acpi/apei/erst-dbg.c +++ b/drivers/acpi/apei/erst-dbg.c | |||
@@ -43,12 +43,27 @@ static DEFINE_MUTEX(erst_dbg_mutex); | |||
43 | 43 | ||
44 | static int erst_dbg_open(struct inode *inode, struct file *file) | 44 | static int erst_dbg_open(struct inode *inode, struct file *file) |
45 | { | 45 | { |
46 | int rc, *pos; | ||
47 | |||
46 | if (erst_disable) | 48 | if (erst_disable) |
47 | return -ENODEV; | 49 | return -ENODEV; |
48 | 50 | ||
51 | pos = (int *)&file->private_data; | ||
52 | |||
53 | rc = erst_get_record_id_begin(pos); | ||
54 | if (rc) | ||
55 | return rc; | ||
56 | |||
49 | return nonseekable_open(inode, file); | 57 | return nonseekable_open(inode, file); |
50 | } | 58 | } |
51 | 59 | ||
60 | static int erst_dbg_release(struct inode *inode, struct file *file) | ||
61 | { | ||
62 | erst_get_record_id_end(); | ||
63 | |||
64 | return 0; | ||
65 | } | ||
66 | |||
52 | static long erst_dbg_ioctl(struct file *f, unsigned int cmd, unsigned long arg) | 67 | static long erst_dbg_ioctl(struct file *f, unsigned int cmd, unsigned long arg) |
53 | { | 68 | { |
54 | int rc; | 69 | int rc; |
@@ -79,18 +94,20 @@ static long erst_dbg_ioctl(struct file *f, unsigned int cmd, unsigned long arg) | |||
79 | static ssize_t erst_dbg_read(struct file *filp, char __user *ubuf, | 94 | static ssize_t erst_dbg_read(struct file *filp, char __user *ubuf, |
80 | size_t usize, loff_t *off) | 95 | size_t usize, loff_t *off) |
81 | { | 96 | { |
82 | int rc; | 97 | int rc, *pos; |
83 | ssize_t len = 0; | 98 | ssize_t len = 0; |
84 | u64 id; | 99 | u64 id; |
85 | 100 | ||
86 | if (*off != 0) | 101 | if (*off) |
87 | return -EINVAL; | 102 | return -EINVAL; |
88 | 103 | ||
89 | if (mutex_lock_interruptible(&erst_dbg_mutex) != 0) | 104 | if (mutex_lock_interruptible(&erst_dbg_mutex) != 0) |
90 | return -EINTR; | 105 | return -EINTR; |
91 | 106 | ||
107 | pos = (int *)&filp->private_data; | ||
108 | |||
92 | retry_next: | 109 | retry_next: |
93 | rc = erst_get_next_record_id(&id); | 110 | rc = erst_get_record_id_next(pos, &id); |
94 | if (rc) | 111 | if (rc) |
95 | goto out; | 112 | goto out; |
96 | /* no more record */ | 113 | /* no more record */ |
@@ -181,6 +198,7 @@ out: | |||
181 | static const struct file_operations erst_dbg_ops = { | 198 | static const struct file_operations erst_dbg_ops = { |
182 | .owner = THIS_MODULE, | 199 | .owner = THIS_MODULE, |
183 | .open = erst_dbg_open, | 200 | .open = erst_dbg_open, |
201 | .release = erst_dbg_release, | ||
184 | .read = erst_dbg_read, | 202 | .read = erst_dbg_read, |
185 | .write = erst_dbg_write, | 203 | .write = erst_dbg_write, |
186 | .unlocked_ioctl = erst_dbg_ioctl, | 204 | .unlocked_ioctl = erst_dbg_ioctl, |