aboutsummaryrefslogtreecommitdiffstats
path: root/fs/pstore/ram.c
diff options
context:
space:
mode:
authorAnton Vorontsov <anton.vorontsov@linaro.org>2012-05-26 09:20:21 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-06-13 19:59:28 -0400
commitf4c5d2423c64266ba0daa9cc803d1d5ba469fe36 (patch)
tree2c963e35f84f0603c2d1f228116b86fcac1b246b /fs/pstore/ram.c
parentcac2eb7b580c95e3871a71276c99e2bd751a1624 (diff)
pstore/ram: Factor dmesg przs initialization out of probe()
This will help make code clearer when we'll add support for other message types. This also makes probe() much shorter and understandable, plus makes mem/record size checking a bit easier. Implementation detail: we now use a paddr pointer, this will be used for allocating persistent ram zones for other message types. Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org> Acked-by: Kees Cook <keescook@chromium.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/pstore/ram.c')
-rw-r--r--fs/pstore/ram.c99
1 files changed, 62 insertions, 37 deletions
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 9b274b98bf3b..6b7676738493 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -202,13 +202,65 @@ static struct ramoops_context oops_cxt = {
202 }, 202 },
203}; 203};
204 204
205static void ramoops_free_przs(struct ramoops_context *cxt)
206{
207 int i;
208
209 if (!cxt->przs)
210 return;
211
212 for (i = 0; cxt->przs[i]; i++)
213 persistent_ram_free(cxt->przs[i]);
214 kfree(cxt->przs);
215}
216
217static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt,
218 phys_addr_t *paddr, size_t dump_mem_sz)
219{
220 int err = -ENOMEM;
221 int i;
222
223 if (!cxt->record_size)
224 return 0;
225
226 cxt->max_dump_cnt = dump_mem_sz / cxt->record_size;
227 if (!cxt->max_dump_cnt)
228 return -ENOMEM;
229
230 cxt->przs = kzalloc(sizeof(*cxt->przs) * cxt->max_dump_cnt,
231 GFP_KERNEL);
232 if (!cxt->przs) {
233 dev_err(dev, "failed to initialize a prz array for dumps\n");
234 return -ENOMEM;
235 }
236
237 for (i = 0; i < cxt->max_dump_cnt; i++) {
238 size_t sz = cxt->record_size;
239
240 cxt->przs[i] = persistent_ram_new(*paddr, sz, cxt->ecc);
241 if (IS_ERR(cxt->przs[i])) {
242 err = PTR_ERR(cxt->przs[i]);
243 dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n",
244 sz, (unsigned long long)*paddr, err);
245 goto fail_prz;
246 }
247 *paddr += sz;
248 }
249
250 return 0;
251fail_prz:
252 ramoops_free_przs(cxt);
253 return err;
254}
255
205static int __init ramoops_probe(struct platform_device *pdev) 256static int __init ramoops_probe(struct platform_device *pdev)
206{ 257{
207 struct device *dev = &pdev->dev; 258 struct device *dev = &pdev->dev;
208 struct ramoops_platform_data *pdata = pdev->dev.platform_data; 259 struct ramoops_platform_data *pdata = pdev->dev.platform_data;
209 struct ramoops_context *cxt = &oops_cxt; 260 struct ramoops_context *cxt = &oops_cxt;
261 size_t dump_mem_sz;
262 phys_addr_t paddr;
210 int err = -EINVAL; 263 int err = -EINVAL;
211 int i;
212 264
213 /* Only a single ramoops area allowed at a time, so fail extra 265 /* Only a single ramoops area allowed at a time, so fail extra
214 * probes. 266 * probes.
@@ -225,21 +277,6 @@ static int __init ramoops_probe(struct platform_device *pdev)
225 pdata->mem_size = rounddown_pow_of_two(pdata->mem_size); 277 pdata->mem_size = rounddown_pow_of_two(pdata->mem_size);
226 pdata->record_size = rounddown_pow_of_two(pdata->record_size); 278 pdata->record_size = rounddown_pow_of_two(pdata->record_size);
227 279
228 /* Check for the minimum memory size */
229 if (pdata->mem_size < MIN_MEM_SIZE &&
230 pdata->record_size < MIN_MEM_SIZE) {
231 pr_err("memory size too small, minimum is %lu\n",
232 MIN_MEM_SIZE);
233 goto fail_out;
234 }
235
236 if (pdata->mem_size < pdata->record_size) {
237 pr_err("The memory size must be larger than the "
238 "records size\n");
239 goto fail_out;
240 }
241
242 cxt->max_dump_cnt = pdata->mem_size / pdata->record_size;
243 cxt->dump_read_cnt = 0; 280 cxt->dump_read_cnt = 0;
244 cxt->size = pdata->mem_size; 281 cxt->size = pdata->mem_size;
245 cxt->phys_addr = pdata->mem_address; 282 cxt->phys_addr = pdata->mem_address;
@@ -247,24 +284,14 @@ static int __init ramoops_probe(struct platform_device *pdev)
247 cxt->dump_oops = pdata->dump_oops; 284 cxt->dump_oops = pdata->dump_oops;
248 cxt->ecc = pdata->ecc; 285 cxt->ecc = pdata->ecc;
249 286
250 cxt->przs = kzalloc(sizeof(*cxt->przs) * cxt->max_dump_cnt, GFP_KERNEL); 287 paddr = cxt->phys_addr;
251 if (!cxt->przs) {
252 err = -ENOMEM;
253 dev_err(dev, "failed to initialize a prz array\n");
254 goto fail_out;
255 }
256
257 for (i = 0; i < cxt->max_dump_cnt; i++) {
258 size_t sz = cxt->record_size;
259 phys_addr_t start = cxt->phys_addr + sz * i;
260 288
261 cxt->przs[i] = persistent_ram_new(start, sz, cxt->ecc); 289 dump_mem_sz = cxt->size;
262 if (IS_ERR(cxt->przs[i])) { 290 err = ramoops_init_przs(dev, cxt, &paddr, dump_mem_sz);
263 err = PTR_ERR(cxt->przs[i]); 291 if (err) {
264 dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n", 292 pr_err("memory size too small, minimum is %lu\n",
265 sz, (unsigned long long)start, err); 293 cxt->record_size);
266 goto fail_przs; 294 goto fail_count;
267 }
268 } 295 }
269 296
270 cxt->pstore.data = cxt; 297 cxt->pstore.data = cxt;
@@ -303,10 +330,8 @@ fail_buf:
303fail_clear: 330fail_clear:
304 cxt->pstore.bufsize = 0; 331 cxt->pstore.bufsize = 0;
305 cxt->max_dump_cnt = 0; 332 cxt->max_dump_cnt = 0;
306fail_przs: 333fail_count:
307 for (i = 0; cxt->przs[i]; i++) 334 ramoops_free_przs(cxt);
308 persistent_ram_free(cxt->przs[i]);
309 kfree(cxt->przs);
310fail_out: 335fail_out:
311 return err; 336 return err;
312} 337}