11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * linux/arch/alpha/kernel/err_common.c 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2000 Jeff Wiedemeier (Compaq Computer Corporation) 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Error handling code supporting Alpha systems 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/sched.h> 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h> 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/hwrpb.h> 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/smp.h> 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/err_common.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "err_impl.h" 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "proto.h" 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * err_print_prefix -- error handling print routines should prefix 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * all prints with this 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldschar *err_print_prefix = KERN_NOTICE; 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Generic 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmchk_dump_mem(void *data, size_t length, char **annotation) 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long *ldata = data; 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size_t i; 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; (i * sizeof(*ldata)) < length; i++) { 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (annotation && !annotation[i]) 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds annotation = NULL; 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("%s %08x: %016lx %s\n", 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err_print_prefix, 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (unsigned)(i * sizeof(*ldata)), ldata[i], 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds annotation ? annotation[i] : ""); 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmchk_dump_logout_frame(struct el_common *mchk_header) 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("%s -- Frame Header --\n" 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " Frame Size: %d (0x%x) bytes\n" 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " Flags: %s%s\n" 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " MCHK Code: 0x%x\n" 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " Frame Rev: %d\n" 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " Proc Offset: 0x%08x\n" 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " Sys Offset: 0x%08x\n" 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " -- Processor Region --\n", 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err_print_prefix, 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchk_header->size, mchk_header->size, 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchk_header->retry ? "RETRY " : "", 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchk_header->err2 ? "SECOND_ERR " : "", 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchk_header->code, 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchk_header->frame_rev, 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchk_header->proc_offset, 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchk_header->sys_offset); 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchk_dump_mem((void *) 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((unsigned long)mchk_header + mchk_header->proc_offset), 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchk_header->sys_offset - mchk_header->proc_offset, 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL); 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("%s -- System Region --\n", err_print_prefix); 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchk_dump_mem((void *) 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((unsigned long)mchk_header + mchk_header->sys_offset), 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchk_header->size - mchk_header->sys_offset, 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL); 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("%s -- End of Frame --\n", err_print_prefix); 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Console Data Log 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Data */ 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct el_subpacket_handler *subpacket_handler_list = NULL; 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct el_subpacket_annotation *subpacket_annotation_list = NULL; 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct el_subpacket * 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsel_process_header_subpacket(struct el_subpacket *header) 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds union el_timestamp timestamp; 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *name = "UNKNOWN EVENT"; 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int packet_count = 0; 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int length = 0; 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (header->class != EL_CLASS__HEADER) { 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("%s** Unexpected header CLASS %d TYPE %d, aborting\n", 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err_print_prefix, 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds header->class, header->type); 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(header->type) { 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case EL_TYPE__HEADER__SYSTEM_ERROR_FRAME: 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds name = "SYSTEM ERROR"; 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds length = header->by_type.sys_err.frame_length; 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds packet_count = 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds header->by_type.sys_err.frame_packet_count; 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds timestamp.as_int = 0; 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case EL_TYPE__HEADER__SYSTEM_EVENT_FRAME: 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds name = "SYSTEM EVENT"; 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds length = header->by_type.sys_event.frame_length; 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds packet_count = 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds header->by_type.sys_event.frame_packet_count; 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds timestamp = header->by_type.sys_event.timestamp; 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case EL_TYPE__HEADER__HALT_FRAME: 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds name = "ERROR HALT"; 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds length = header->by_type.err_halt.frame_length; 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds packet_count = 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds header->by_type.err_halt.frame_packet_count; 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds timestamp = header->by_type.err_halt.timestamp; 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case EL_TYPE__HEADER__LOGOUT_FRAME: 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds name = "LOGOUT FRAME"; 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds length = header->by_type.logout_header.frame_length; 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds packet_count = 1; 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds timestamp.as_int = 0; 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: /* Unknown */ 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("%s** Unknown header - CLASS %d TYPE %d, aborting\n", 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err_print_prefix, 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds header->class, header->type); 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("%s*** %s:\n" 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " CLASS %d, TYPE %d\n", 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err_print_prefix, 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds name, 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds header->class, header->type); 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds el_print_timestamp(×tamp); 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Process the subpackets 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds el_process_subpackets(header, packet_count); 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* return the next header */ 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds header = (struct el_subpacket *) 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((unsigned long)header + header->length + length); 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return header; 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct el_subpacket * 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsel_process_subpacket_reg(struct el_subpacket *header) 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct el_subpacket *next = NULL; 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct el_subpacket_handler *h = subpacket_handler_list; 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (; h && h->class != header->class; h = h->next); 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (h) next = h->handler(header); 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return next; 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsel_print_timestamp(union el_timestamp *timestamp) 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (timestamp->as_int) 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("%s TIMESTAMP: %d/%d/%02d %d:%02d:%0d\n", 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err_print_prefix, 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds timestamp->b.month, timestamp->b.day, 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds timestamp->b.year, timestamp->b.hour, 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds timestamp->b.minute, timestamp->b.second); 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsel_process_subpackets(struct el_subpacket *header, int packet_count) 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct el_subpacket *subpacket; 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds subpacket = (struct el_subpacket *) 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((unsigned long)header + header->length); 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; subpacket && i < packet_count; i++) { 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("%sPROCESSING SUBPACKET %d\n", err_print_prefix, i); 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds subpacket = el_process_subpacket(subpacket); 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct el_subpacket * 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsel_process_subpacket(struct el_subpacket *header) 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct el_subpacket *next = NULL; 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(header->class) { 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case EL_CLASS__TERMINATION: 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Termination packet, there are no more */ 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case EL_CLASS__HEADER: 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds next = el_process_header_subpacket(header); 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (NULL == (next = el_process_subpacket_reg(header))) { 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("%s** Unexpected header CLASS %d TYPE %d" 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " -- aborting.\n", 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err_print_prefix, 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds header->class, header->type); 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return next; 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsel_annotate_subpacket(struct el_subpacket *header) 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct el_subpacket_annotation *a; 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char **annotation = NULL; 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (a = subpacket_annotation_list; a; a = a->next) { 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (a->class == header->class && 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds a->type == header->type && 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds a->revision == header->revision) { 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We found the annotation 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds annotation = a->annotation; 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("%s %s\n", err_print_prefix, a->description); 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchk_dump_mem(header, header->length, annotation); 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __init 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldscdl_process_console_data_log(int cpu, struct percpu_struct *pcpu) 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct el_subpacket *header = (struct el_subpacket *) 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (IDENT_ADDR | pcpu->console_data_log_pa); 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("%s******* CONSOLE DATA LOG FOR CPU %d. *******\n" 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "*** Error(s) were logged on a previous boot\n", 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err_print_prefix, cpu); 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (err = 0; header && (header->class != EL_CLASS__TERMINATION); err++) 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds header = el_process_subpacket(header); 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* let the console know it's ok to clear the error(s) at restart */ 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pcpu->console_data_log_pa = 0; 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("%s*** %d total error(s) logged\n" 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "**** END OF CONSOLE DATA LOG FOR CPU %d ****\n", 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err_print_prefix, err, cpu); 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid __init 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldscdl_check_console_data_log(void) 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct percpu_struct *pcpu; 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long cpu; 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (cpu = 0; cpu < hwrpb->nr_processors; cpu++) { 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pcpu = (struct percpu_struct *) 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((unsigned long)hwrpb + hwrpb->processor_offset 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds + cpu * hwrpb->processor_size); 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pcpu->console_data_log_pa) 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cdl_process_console_data_log(cpu, pcpu); 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint __init 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldscdl_register_subpacket_annotation(struct el_subpacket_annotation *new) 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct el_subpacket_annotation *a = subpacket_annotation_list; 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (a == NULL) subpacket_annotation_list = new; 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (; a->next != NULL; a = a->next) { 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((a->class == new->class && a->type == new->type) || 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds a == new) { 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("Attempted to re-register " 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "subpacket annotation\n"); 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds a->next = new; 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new->next = NULL; 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint __init 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldscdl_register_subpacket_handler(struct el_subpacket_handler *new) 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct el_subpacket_handler *h = subpacket_handler_list; 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (h == NULL) subpacket_handler_list = new; 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (; h->next != NULL; h = h->next) { 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (h->class == new->class || h == new) { 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("Attempted to re-register " 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "subpacket handler\n"); 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds h->next = new; 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new->next = NULL; 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 321