diff options
author | Aruna Balakrishnaiah <aruna@linux.vnet.ibm.com> | 2013-06-05 14:52:10 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2013-06-20 03:04:59 -0400 |
commit | f33f748c964f6a6ee272b1c794b52f54f4da1d04 (patch) | |
tree | cb755efb8c8fa22fed3e2e537e1854468ff5d612 | |
parent | edf38465a32c2820350da45a2231d2c53ad2d3c0 (diff) |
powerpc/pseries: Read of-config partition via pstore
This patch set exploits the pstore subsystem to read details of
of-config partition in NVRAM to a separate file in /dev/pstore.
For instance, of-config partition details will be stored in a
file named [of-nvram-5].
Signed-off-by: Aruna Balakrishnaiah <aruna@linux.vnet.ibm.com>
Reviewed-by: Jim Keniston <jkenisto@us.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r-- | arch/powerpc/platforms/pseries/nvram.c | 55 | ||||
-rw-r--r-- | fs/pstore/inode.c | 3 | ||||
-rw-r--r-- | include/linux/pstore.h | 1 |
3 files changed, 50 insertions, 9 deletions
diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c index 714ed8ac7d59..f7392f6ea7b3 100644 --- a/arch/powerpc/platforms/pseries/nvram.c +++ b/arch/powerpc/platforms/pseries/nvram.c | |||
@@ -132,9 +132,16 @@ static size_t oops_data_sz; | |||
132 | static struct z_stream_s stream; | 132 | static struct z_stream_s stream; |
133 | 133 | ||
134 | #ifdef CONFIG_PSTORE | 134 | #ifdef CONFIG_PSTORE |
135 | static struct nvram_os_partition of_config_partition = { | ||
136 | .name = "of-config", | ||
137 | .index = -1, | ||
138 | .os_partition = false | ||
139 | }; | ||
140 | |||
135 | static enum pstore_type_id nvram_type_ids[] = { | 141 | static enum pstore_type_id nvram_type_ids[] = { |
136 | PSTORE_TYPE_DMESG, | 142 | PSTORE_TYPE_DMESG, |
137 | PSTORE_TYPE_PPC_RTAS, | 143 | PSTORE_TYPE_PPC_RTAS, |
144 | PSTORE_TYPE_PPC_OF, | ||
138 | -1 | 145 | -1 |
139 | }; | 146 | }; |
140 | static int read_type; | 147 | static int read_type; |
@@ -332,10 +339,15 @@ int nvram_read_partition(struct nvram_os_partition *part, char *buff, | |||
332 | 339 | ||
333 | tmp_index = part->index; | 340 | tmp_index = part->index; |
334 | 341 | ||
335 | rc = ppc_md.nvram_read((char *)&info, sizeof(struct err_log_info), &tmp_index); | 342 | if (part->os_partition) { |
336 | if (rc <= 0) { | 343 | rc = ppc_md.nvram_read((char *)&info, |
337 | pr_err("%s: Failed nvram_read (%d)\n", __FUNCTION__, rc); | 344 | sizeof(struct err_log_info), |
338 | return rc; | 345 | &tmp_index); |
346 | if (rc <= 0) { | ||
347 | pr_err("%s: Failed nvram_read (%d)\n", __FUNCTION__, | ||
348 | rc); | ||
349 | return rc; | ||
350 | } | ||
339 | } | 351 | } |
340 | 352 | ||
341 | rc = ppc_md.nvram_read(buff, length, &tmp_index); | 353 | rc = ppc_md.nvram_read(buff, length, &tmp_index); |
@@ -344,8 +356,10 @@ int nvram_read_partition(struct nvram_os_partition *part, char *buff, | |||
344 | return rc; | 356 | return rc; |
345 | } | 357 | } |
346 | 358 | ||
347 | *error_log_cnt = info.seq_num; | 359 | if (part->os_partition) { |
348 | *err_type = info.error_type; | 360 | *error_log_cnt = info.seq_num; |
361 | *err_type = info.error_type; | ||
362 | } | ||
349 | 363 | ||
350 | return 0; | 364 | return 0; |
351 | } | 365 | } |
@@ -516,7 +530,7 @@ static int nvram_pstore_write(enum pstore_type_id type, | |||
516 | } | 530 | } |
517 | 531 | ||
518 | /* | 532 | /* |
519 | * Reads the oops/panic report and ibm,rtas-log partition. | 533 | * Reads the oops/panic report, rtas and of-config partition. |
520 | * Returns the length of the data we read from each partition. | 534 | * Returns the length of the data we read from each partition. |
521 | * Returns 0 if we've been called before. | 535 | * Returns 0 if we've been called before. |
522 | */ | 536 | */ |
@@ -525,9 +539,11 @@ static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type, | |||
525 | struct pstore_info *psi) | 539 | struct pstore_info *psi) |
526 | { | 540 | { |
527 | struct oops_log_info *oops_hdr; | 541 | struct oops_log_info *oops_hdr; |
528 | unsigned int err_type, id_no; | 542 | unsigned int err_type, id_no, size = 0; |
529 | struct nvram_os_partition *part = NULL; | 543 | struct nvram_os_partition *part = NULL; |
530 | char *buff = NULL; | 544 | char *buff = NULL; |
545 | int sig = 0; | ||
546 | loff_t p; | ||
531 | 547 | ||
532 | read_type++; | 548 | read_type++; |
533 | 549 | ||
@@ -542,10 +558,29 @@ static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type, | |||
542 | time->tv_sec = last_rtas_event; | 558 | time->tv_sec = last_rtas_event; |
543 | time->tv_nsec = 0; | 559 | time->tv_nsec = 0; |
544 | break; | 560 | break; |
561 | case PSTORE_TYPE_PPC_OF: | ||
562 | sig = NVRAM_SIG_OF; | ||
563 | part = &of_config_partition; | ||
564 | *type = PSTORE_TYPE_PPC_OF; | ||
565 | *id = PSTORE_TYPE_PPC_OF; | ||
566 | time->tv_sec = 0; | ||
567 | time->tv_nsec = 0; | ||
568 | break; | ||
545 | default: | 569 | default: |
546 | return 0; | 570 | return 0; |
547 | } | 571 | } |
548 | 572 | ||
573 | if (!part->os_partition) { | ||
574 | p = nvram_find_partition(part->name, sig, &size); | ||
575 | if (p <= 0) { | ||
576 | pr_err("nvram: Failed to find partition %s, " | ||
577 | "err %d\n", part->name, (int)p); | ||
578 | return 0; | ||
579 | } | ||
580 | part->index = p; | ||
581 | part->size = size; | ||
582 | } | ||
583 | |||
549 | buff = kmalloc(part->size, GFP_KERNEL); | 584 | buff = kmalloc(part->size, GFP_KERNEL); |
550 | 585 | ||
551 | if (!buff) | 586 | if (!buff) |
@@ -557,7 +592,9 @@ static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type, | |||
557 | } | 592 | } |
558 | 593 | ||
559 | *count = 0; | 594 | *count = 0; |
560 | *id = id_no; | 595 | |
596 | if (part->os_partition) | ||
597 | *id = id_no; | ||
561 | 598 | ||
562 | if (nvram_type_ids[read_type] == PSTORE_TYPE_DMESG) { | 599 | if (nvram_type_ids[read_type] == PSTORE_TYPE_DMESG) { |
563 | oops_hdr = (struct oops_log_info *)buff; | 600 | oops_hdr = (struct oops_log_info *)buff; |
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c index ec24f9ceb5ed..73148aef9e31 100644 --- a/fs/pstore/inode.c +++ b/fs/pstore/inode.c | |||
@@ -327,6 +327,9 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id, int count, | |||
327 | case PSTORE_TYPE_PPC_RTAS: | 327 | case PSTORE_TYPE_PPC_RTAS: |
328 | sprintf(name, "rtas-%s-%lld", psname, id); | 328 | sprintf(name, "rtas-%s-%lld", psname, id); |
329 | break; | 329 | break; |
330 | case PSTORE_TYPE_PPC_OF: | ||
331 | sprintf(name, "powerpc-ofw-%s-%lld", psname, id); | ||
332 | break; | ||
330 | case PSTORE_TYPE_UNKNOWN: | 333 | case PSTORE_TYPE_UNKNOWN: |
331 | sprintf(name, "unknown-%s-%lld", psname, id); | 334 | sprintf(name, "unknown-%s-%lld", psname, id); |
332 | break; | 335 | break; |
diff --git a/include/linux/pstore.h b/include/linux/pstore.h index d7a8fe938c0f..615dc18638b8 100644 --- a/include/linux/pstore.h +++ b/include/linux/pstore.h | |||
@@ -37,6 +37,7 @@ enum pstore_type_id { | |||
37 | PSTORE_TYPE_FTRACE = 3, | 37 | PSTORE_TYPE_FTRACE = 3, |
38 | /* PPC64 partition types */ | 38 | /* PPC64 partition types */ |
39 | PSTORE_TYPE_PPC_RTAS = 4, | 39 | PSTORE_TYPE_PPC_RTAS = 4, |
40 | PSTORE_TYPE_PPC_OF = 5, | ||
40 | PSTORE_TYPE_UNKNOWN = 255 | 41 | PSTORE_TYPE_UNKNOWN = 255 |
41 | }; | 42 | }; |
42 | 43 | ||