static void send_netdump_msg(struct netpoll *np, const char *msg, unsigned int msg_len, reply_t *reply);
static void send_netdump_mem(struct netpoll *np, req_t *req);
static void netdump_startup_handshake(struct netpoll *np);
-static asmlinkage void netpoll_netdump(struct pt_regs *regs, void *arg);
+static void netpoll_netdump(struct pt_regs *regs);
static void netpoll_start_netdump(struct pt_regs *regs);
static int nr_req = 0;
static LIST_HEAD(request_list);
-static unsigned long long t0, jiffy_cycles = 1000 * (1000000/HZ);
+static unsigned long long t0, jiffy_cycles;
void *netdump_stack;
static inline void print_status (req_t *req)
{
static int count = 0;
- static unsigned long prev_jiffies = 0;
+ static int prev_jiffies = 0;
if (jiffies/HZ != prev_jiffies/HZ) {
prev_jiffies = jiffies;
count++;
switch (count & 3) {
- case 0: printk("%d(%lu)/\r", nr_req, jiffies); break;
- case 1: printk("%d(%lu)|\r", nr_req, jiffies); break;
- case 2: printk("%d(%lu)\\\r", nr_req, jiffies); break;
- case 3: printk("%d(%lu)-\r", nr_req, jiffies); break;
+ case 0: printk("%d(%ld)/\r", nr_req, jiffies); break;
+ case 1: printk("%d(%ld)|\r", nr_req, jiffies); break;
+ case 2: printk("%d(%ld)\\\r", nr_req, jiffies); break;
+ case 3: printk("%d(%ld)-\r", nr_req, jiffies); break;
}
}
}
return;
}
+ req->magic = ntohl(__req->magic);
req->command = ntohl(__req->command);
req->from = ntohl(__req->from);
req->to = ntohl(__req->to);
req->nr = ntohl(__req->nr);
+ Dprintk("... netdump magic: %08Lx.\n", req->magic);
Dprintk("... netdump command: %08x.\n", req->command);
Dprintk("... netdump from: %08x.\n", req->from);
Dprintk("... netdump to: %08x.\n", req->to);
#define MAX_MSG_LEN HEADER_LEN + 1024
-static unsigned char effective_version = NETDUMP_VERSION;
-
static void send_netdump_msg(struct netpoll *np, const char *msg, unsigned int msg_len, reply_t *reply)
{
/* max len should be 1024 + HEADER_LEN */
/* NOTREACHED */
}
- netpoll_msg[0] = effective_version;
+ netpoll_msg[0] = NETDUMP_VERSION;
put_unaligned(htonl(reply->nr), (u32 *) (&netpoll_msg[1]));
put_unaligned(htonl(reply->code), (u32 *) (&netpoll_msg[5]));
put_unaligned(htonl(reply->info), (u32 *) (&netpoll_msg[9]));
int i;
char *kaddr;
char str[1024];
- struct page *page = NULL;
+ struct page *page;
unsigned long nr = req->from;
int nr_chunks = PAGE_SIZE/1024;
reply_t reply;
send_netdump_msg(np, str, strlen(str), &reply);
return;
}
- if (platform_page_is_ram(nr)) {
+ if (page_is_ram(nr))
page = pfn_to_page(nr);
- if (page_to_pfn(page) != nr)
- page = NULL;
- }
- if (!page) {
- reply.code = REPLY_RESERVED;
- reply.info = platform_next_available(nr);
- send_netdump_msg(np, str, 0, &reply);
- return;
- }
+ else
+ page = ZERO_PAGE(0);
- kaddr = (char *)kmap_atomic(page, KM_CRASHDUMP);
+ kaddr = (char *)kmap_atomic(page, KM_NETDUMP);
for (i = 0; i < nr_chunks; i++) {
unsigned int offset = i*1024;
Dprintk(" ... send_netdump_mem: sent message\n");
}
- kunmap_atomic(kaddr, KM_CRASHDUMP);
+ kunmap_atomic(kaddr, KM_NETDUMP);
Dprintk(" ... send_netdump_mem: returning\n");
}
int i;
repeat:
- sprintf(tmp,
- "task_struct:0x%lx page_offset:0x%llx netdump_magic:0x%llx\n",
- (unsigned long)current, (unsigned long long)PAGE_OFFSET,
- (unsigned long long)netdump_magic);
+ sprintf(tmp, "NETDUMP start, waiting for start-ACK.\n");
reply.code = REPLY_START_NETDUMP;
- reply.nr = platform_machine_type();
- reply.info = NETDUMP_VERSION_MAX;
+ reply.nr = 0;
+ reply.info = 0;
send_netdump_msg(np, tmp, strlen(tmp), &reply);
kfree(req);
goto repeat;
}
-
- /*
- * Negotiate an effective version that works with the server.
- */
- if ((effective_version = platform_effective_version(req)) == 0) {
- printk(KERN_ERR
- "netdump: server cannot handle this client -- rebooting.\n");
- netdump_mdelay(3000);
- machine_restart(NULL);
- }
-
kfree(req);
printk("NETDUMP START!\n");
static void freeze_cpu (void * dummy)
{
cpus_frozen[smp_processor_id()] = 1;
- platform_freeze_cpu();
+ for (;;) local_irq_disable();
}
static void netpoll_start_netdump(struct pt_regs *regs)
if (netdump_mode) {
printk(KERN_ERR
"netpoll_start_netdump: called recursively. rebooting.\n");
- netdump_mdelay(3000);
+ mdelay(3000);
machine_restart(NULL);
}
netdump_mode = 1;
preempt_disable();
smp_call_function(freeze_cpu, NULL, 1, -1);
- netdump_mdelay(3000);
+ mdelay(3000);
for (i = 0; i < NR_CPUS; i++) {
if (cpus_frozen[i])
printk("CPU#%d is frozen.\n", i);
/*
* Some platforms may want to execute netdump on its own stack.
*/
- platform_start_crashdump(netdump_stack, netpoll_netdump, regs);
+ platform_start_netdump(netdump_stack, regs);
preempt_enable_no_resched();
local_irq_restore(flags);
return;
}
-static char command_tmp[1024];
-
-static asmlinkage void netpoll_netdump(struct pt_regs *regs, void *platform_arg)
+static void netpoll_netdump(struct pt_regs *regs)
{
reply_t reply;
- char *tmp = command_tmp;
- extern unsigned long totalram_pages;
+ char tmp[200];
struct pt_regs myregs;
req_t *req;
case COMM_REBOOT:
Dprintk("got REBOOT command.\n");
printk("netdump: rebooting in 3 seconds.\n");
- netdump_mdelay(3000);
+ mdelay(3000);
machine_restart(NULL);
break;
break;
case COMM_GET_REGS:
+ {
+ char *tmp2 = tmp;
+ elf_gregset_t elf_regs;
+
reply.code = REPLY_REGS;
reply.nr = req->nr;
- reply.info = (u32)totalram_pages;
- send_netdump_msg(&np, tmp,
- platform_get_regs(tmp, &myregs), &reply);
+ reply.info = platform_max_pfn();
+ tmp2 = tmp + sprintf(tmp, "Sending register info.\n");
+ ELF_CORE_COPY_REGS(elf_regs, (&myregs));
+ memcpy(tmp2, &elf_regs, sizeof(elf_regs));
+ Dprintk("netdump: sending regs\n");
+ send_netdump_msg(&np, tmp,
+ strlen(tmp) + sizeof(elf_regs), &reply);
+ Dprintk("netdump: sent regs\n");
break;
+ }
case COMM_GET_NR_PAGES:
reply.code = REPLY_NR_PAGES;
*/
platform_init_stack(&netdump_stack);
- platform_jiffy_cycles(&jiffy_cycles);
-
printk(KERN_INFO "netdump: network crash dump enabled\n");
return 0;
}