aboutsummaryrefslogtreecommitdiffstats
path: root/fs/pstore/ram.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-03 10:06:37 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-03 10:06:37 -0400
commit00fdffb5131125dce0702bf61e24a806ec3aed80 (patch)
tree1cf855601ce34630b487f8555cf7df2e96efb506 /fs/pstore/ram.c
parentce857229e0c3adc211944a13a5579ef84fd7b4af (diff)
parentbd08ec33b5c23833581e5a36b2a69ccae6b39a28 (diff)
Merge tag 'for-v3.10' of git://git.infradead.org/users/cbou/linux-pstore
Pull pstore update from Anton Vorontsov: - A new platform data parameter to specify ECC configuration; - Rounding fixup to not waste memory in ecc_blocks; - Restore ECC information printouts; - A small code cleanup: use kmemdup where appropriate. * tag 'for-v3.10' of git://git.infradead.org/users/cbou/linux-pstore: pstore/ram: Restore ecc information block pstore/ram: Allow specifying ecc parameters in platform data pstore/ram: Include ecc_size when calculating ecc_block pstore: Replace calls to kmalloc and memcpy with kmemdup
Diffstat (limited to 'fs/pstore/ram.c')
-rw-r--r--fs/pstore/ram.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 288f068740f6..32cbd7c8a90c 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -83,7 +83,7 @@ struct ramoops_context {
83 size_t console_size; 83 size_t console_size;
84 size_t ftrace_size; 84 size_t ftrace_size;
85 int dump_oops; 85 int dump_oops;
86 int ecc_size; 86 struct persistent_ram_ecc_info ecc_info;
87 unsigned int max_dump_cnt; 87 unsigned int max_dump_cnt;
88 unsigned int dump_write_cnt; 88 unsigned int dump_write_cnt;
89 unsigned int dump_read_cnt; 89 unsigned int dump_read_cnt;
@@ -136,6 +136,7 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
136 char **buf, struct pstore_info *psi) 136 char **buf, struct pstore_info *psi)
137{ 137{
138 ssize_t size; 138 ssize_t size;
139 ssize_t ecc_notice_size;
139 struct ramoops_context *cxt = psi->data; 140 struct ramoops_context *cxt = psi->data;
140 struct persistent_ram_zone *prz; 141 struct persistent_ram_zone *prz;
141 142
@@ -156,12 +157,18 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
156 time->tv_nsec = 0; 157 time->tv_nsec = 0;
157 158
158 size = persistent_ram_old_size(prz); 159 size = persistent_ram_old_size(prz);
159 *buf = kmalloc(size, GFP_KERNEL); 160
161 /* ECC correction notice */
162 ecc_notice_size = persistent_ram_ecc_string(prz, NULL, 0);
163
164 *buf = kmalloc(size + ecc_notice_size + 1, GFP_KERNEL);
160 if (*buf == NULL) 165 if (*buf == NULL)
161 return -ENOMEM; 166 return -ENOMEM;
167
162 memcpy(*buf, persistent_ram_old(prz), size); 168 memcpy(*buf, persistent_ram_old(prz), size);
169 persistent_ram_ecc_string(prz, *buf + size, ecc_notice_size + 1);
163 170
164 return size; 171 return size + ecc_notice_size;
165} 172}
166 173
167static size_t ramoops_write_kmsg_hdr(struct persistent_ram_zone *prz) 174static size_t ramoops_write_kmsg_hdr(struct persistent_ram_zone *prz)
@@ -323,7 +330,8 @@ static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt,
323 for (i = 0; i < cxt->max_dump_cnt; i++) { 330 for (i = 0; i < cxt->max_dump_cnt; i++) {
324 size_t sz = cxt->record_size; 331 size_t sz = cxt->record_size;
325 332
326 cxt->przs[i] = persistent_ram_new(*paddr, sz, 0, cxt->ecc_size); 333 cxt->przs[i] = persistent_ram_new(*paddr, sz, 0,
334 &cxt->ecc_info);
327 if (IS_ERR(cxt->przs[i])) { 335 if (IS_ERR(cxt->przs[i])) {
328 err = PTR_ERR(cxt->przs[i]); 336 err = PTR_ERR(cxt->przs[i]);
329 dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n", 337 dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n",
@@ -353,7 +361,7 @@ static int ramoops_init_prz(struct device *dev, struct ramoops_context *cxt,
353 return -ENOMEM; 361 return -ENOMEM;
354 } 362 }
355 363
356 *prz = persistent_ram_new(*paddr, sz, sig, cxt->ecc_size); 364 *prz = persistent_ram_new(*paddr, sz, sig, &cxt->ecc_info);
357 if (IS_ERR(*prz)) { 365 if (IS_ERR(*prz)) {
358 int err = PTR_ERR(*prz); 366 int err = PTR_ERR(*prz);
359 367
@@ -407,7 +415,7 @@ static int ramoops_probe(struct platform_device *pdev)
407 cxt->console_size = pdata->console_size; 415 cxt->console_size = pdata->console_size;
408 cxt->ftrace_size = pdata->ftrace_size; 416 cxt->ftrace_size = pdata->ftrace_size;
409 cxt->dump_oops = pdata->dump_oops; 417 cxt->dump_oops = pdata->dump_oops;
410 cxt->ecc_size = pdata->ecc_size; 418 cxt->ecc_info = pdata->ecc_info;
411 419
412 paddr = cxt->phys_addr; 420 paddr = cxt->phys_addr;
413 421
@@ -465,9 +473,9 @@ static int ramoops_probe(struct platform_device *pdev)
465 record_size = pdata->record_size; 473 record_size = pdata->record_size;
466 dump_oops = pdata->dump_oops; 474 dump_oops = pdata->dump_oops;
467 475
468 pr_info("attached 0x%lx@0x%llx, ecc: %d\n", 476 pr_info("attached 0x%lx@0x%llx, ecc: %d/%d\n",
469 cxt->size, (unsigned long long)cxt->phys_addr, 477 cxt->size, (unsigned long long)cxt->phys_addr,
470 cxt->ecc_size); 478 cxt->ecc_info.ecc_size, cxt->ecc_info.block_size);
471 479
472 return 0; 480 return 0;
473 481
@@ -539,7 +547,7 @@ static void ramoops_register_dummy(void)
539 * For backwards compatibility ramoops.ecc=1 means 16 bytes ECC 547 * For backwards compatibility ramoops.ecc=1 means 16 bytes ECC
540 * (using 1 byte for ECC isn't much of use anyway). 548 * (using 1 byte for ECC isn't much of use anyway).
541 */ 549 */
542 dummy_data->ecc_size = ramoops_ecc == 1 ? 16 : ramoops_ecc; 550 dummy_data->ecc_info.ecc_size = ramoops_ecc == 1 ? 16 : ramoops_ecc;
543 551
544 dummy = platform_device_register_data(NULL, "ramoops", -1, 552 dummy = platform_device_register_data(NULL, "ramoops", -1,
545 dummy_data, sizeof(struct ramoops_platform_data)); 553 dummy_data, sizeof(struct ramoops_platform_data));