2 * The file has the common/generic dump execution code
4 * Started: Oct 2002 - Suparna Bhattacharya <suparna@in.ibm.com>
5 * Split and rewrote high level dump execute code to make use
6 * of dump method interfaces.
8 * Derived from original code in dump_base.c created by
9 * Matt Robinson <yakker@sourceforge.net>)
11 * Copyright (C) 1999 - 2002 Silicon Graphics, Inc. All rights reserved.
12 * Copyright (C) 2001 - 2002 Matt D. Robinson. All rights reserved.
13 * Copyright (C) 2002 International Business Machines Corp.
15 * Assumes dumper and dump config settings are in place
16 * (invokes corresponding dumper specific routines as applicable)
18 * This code is released under version 2 of the GNU GPL.
20 #include <linux/kernel.h>
21 #include <linux/notifier.h>
22 #include <linux/dump.h>
23 #include <linux/delay.h>
24 #include <linux/reboot.h>
25 #include "dump_methods.h"
27 struct notifier_block *dump_notifier_list; /* dump started/ended callback */
29 extern int panic_timeout;
31 /* Dump progress indicator */
35 static const char twiddle[4] = { '|', '\\', '-', '/' };
36 printk("%c\b", twiddle[i&3]);
39 /* Make the device ready and write out the header */
44 /* dump_dev = dump_config.dumper->dev; */
46 if ((err = dump_dev_silence())) {
47 /* quiesce failed, can't risk continuing */
48 /* Todo/Future: switch to alternate dump scheme if possible */
49 printk("dump silence dev failed ! error %d\n", err);
53 pr_debug("Writing dump header\n");
54 if ((err = dump_update_header())) {
55 printk("dump update header failed ! error %d\n", err);
60 dump_config.dumper->curr_offset = DUMP_BUFFER_SIZE;
66 * Write the dump terminator, a final header update and let go of
67 * exclusive use of the device for dump.
69 int dump_complete(void)
73 if (dump_config.level != DUMP_LEVEL_HEADER) {
74 if ((ret = dump_update_end_marker())) {
75 printk("dump update end marker error %d\n", ret);
77 if ((ret = dump_update_header())) {
78 printk("dump update header error %d\n", ret);
81 ret = dump_dev_resume();
83 if ((panic_timeout > 0) && (!(dump_config.flags & (DUMP_FLAGS_SOFTBOOT | DUMP_FLAGS_NONDISRUPT)))) {
84 printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout);
88 mdelay(panic_timeout * 1000);
89 machine_restart(NULL);
95 /* Saves all dump data */
96 int dump_execute_savedump(void)
100 if ((ret = dump_begin())) {
104 if (dump_config.level != DUMP_LEVEL_HEADER) {
105 ret = dump_sequencer();
107 if ((err = dump_complete())) {
108 printk("Dump complete failed. Error %d\n", err);
114 extern void dump_calc_bootmap_pages(void);
116 /* Does all the real work: Capture and save state */
117 int dump_generic_execute(const char *panic_str, const struct pt_regs *regs)
121 if ((ret = dump_configure_header(panic_str, regs))) {
122 printk("dump config header failed ! error %d\n", ret);
126 dump_calc_bootmap_pages();
127 /* tell interested parties that a dump is about to start */
128 notifier_call_chain(&dump_notifier_list, DUMP_BEGIN,
129 &dump_config.dump_device);
131 if (dump_config.level != DUMP_LEVEL_NONE)
132 ret = dump_execute_savedump();
134 pr_debug("dumped %ld blocks of %d bytes each\n",
135 dump_config.dumper->count, DUMP_BUFFER_SIZE);
137 /* tell interested parties that a dump has completed */
138 notifier_call_chain(&dump_notifier_list, DUMP_END,
139 &dump_config.dump_device);