diff options
author | Anton Vorontsov <anton.vorontsov@linaro.org> | 2012-05-26 09:20:21 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-06-13 19:59:28 -0400 |
commit | f4c5d2423c64266ba0daa9cc803d1d5ba469fe36 (patch) | |
tree | 2c963e35f84f0603c2d1f228116b86fcac1b246b /fs/pstore/ram.c | |
parent | cac2eb7b580c95e3871a71276c99e2bd751a1624 (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.c | 99 |
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 | ||
205 | static 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 | |||
217 | static 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; | ||
251 | fail_prz: | ||
252 | ramoops_free_przs(cxt); | ||
253 | return err; | ||
254 | } | ||
255 | |||
205 | static int __init ramoops_probe(struct platform_device *pdev) | 256 | static 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: | |||
303 | fail_clear: | 330 | fail_clear: |
304 | cxt->pstore.bufsize = 0; | 331 | cxt->pstore.bufsize = 0; |
305 | cxt->max_dump_cnt = 0; | 332 | cxt->max_dump_cnt = 0; |
306 | fail_przs: | 333 | fail_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); | ||
310 | fail_out: | 335 | fail_out: |
311 | return err; | 336 | return err; |
312 | } | 337 | } |