Home | History | Annotate | Download | only in common
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License, Version 1.0 only
      6  * (the "License").  You may not use this file except in compliance
      7  * with the License.
      8  *
      9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  * or http://www.opensolaris.org/os/licensing.
     11  * See the License for the specific language governing permissions
     12  * and limitations under the License.
     13  *
     14  * When distributing Covered Code, include this CDDL HEADER in each
     15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  * If applicable, add the following below this CDDL HEADER, with the
     17  * fields enclosed by brackets "[]" replaced with your own identifying
     18  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  *
     20  * CDDL HEADER END
     21  */
     22 /*
     23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     28 
     29 #include <stdio.h>
     30 #include <stdlib.h>
     31 #include <ctype.h>
     32 #include <string.h>
     33 #include <sys/param.h>
     34 #include <sys/types.h>
     35 #include <sys/utsname.h>
     36 #include <stdarg.h>
     37 #include <syslog.h>
     38 #include <sys/openpromio.h>
     39 #include <libintl.h>
     40 #include "pdevinfo.h"
     41 #include "display.h"
     42 
     43 #if !defined(TEXT_DOMAIN)
     44 #define	TEXT_DOMAIN	"SYS_TEST"
     45 #endif
     46 
     47 /*
     48  * external data
     49  */
     50 extern int	print_flag;
     51 extern int	logging;
     52 
     53 /*
     54  * The following macros for dealing with raw output from the Mostek 48T02
     55  * were borrowed from the kernel. Openboot passes the raw Mostek data
     56  * thru the device tree, and there are no library routines to deal with
     57  * this data.
     58  */
     59 
     60 /*
     61  * Tables to convert a single byte from binary-coded decimal (BCD).
     62  */
     63 static uchar_t bcd_to_byte[256] = {		/* CSTYLED */
     64 	 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  0,  0,  0,  0,  0,  0,
     65 	10, 11, 12, 13, 14, 15, 16, 17, 18, 19,  0,  0,  0,  0,  0,  0,
     66 	20, 21, 22, 23, 24, 25, 26, 27, 28, 29,  0,  0,  0,  0,  0,  0,
     67 	30, 31, 32, 33, 34, 35, 36, 37, 38, 39,  0,  0,  0,  0,  0,  0,
     68 	40, 41, 42, 43, 44, 45, 46, 47, 48, 49,  0,  0,  0,  0,  0,  0,
     69 	50, 51, 52, 53, 54, 55, 56, 57, 58, 59,  0,  0,  0,  0,  0,  0,
     70 	60, 61, 62, 63, 64, 65, 66, 67, 68, 69,  0,  0,  0,  0,  0,  0,
     71 	70, 71, 72, 73, 74, 75, 76, 77, 78, 79,  0,  0,  0,  0,  0,  0,
     72 	80, 81, 82, 83, 84, 85, 86, 87, 88, 89,  0,  0,  0,  0,  0,  0,
     73 	90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
     74 };
     75 
     76 #define	BCD_TO_BYTE(x)	bcd_to_byte[(x) & 0xff]
     77 #define	YRBASE	68
     78 
     79 static int days_thru_month[64] = {
     80 	0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366, 0, 0,
     81 	0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, 0, 0,
     82 	0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, 0, 0,
     83 	0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, 0, 0,
     84 };
     85 
     86 /*
     87  * This function takes the raw Mostek data from the device tree translates
     88  * it into UNIXC time (secs since Jan 1, 1970) and returns a string from
     89  * ctime(3c).
     90  */
     91 char *
     92 get_time(uchar_t *mostek)
     93 {
     94 	time_t utc;
     95 	int sec, min, hour, day, month, year;
     96 
     97 	year	= BCD_TO_BYTE(mostek[6]) + YRBASE;
     98 	month	= BCD_TO_BYTE(mostek[5] & 0x1f) + ((year & 3) << 4);
     99 	day	= BCD_TO_BYTE(mostek[4] & 0x3f);
    100 	hour	= BCD_TO_BYTE(mostek[2] & 0x3f);
    101 	min	= BCD_TO_BYTE(mostek[1] & 0x7f);
    102 	sec	= BCD_TO_BYTE(mostek[0] & 0x7f);
    103 
    104 	utc = (year - 70);		/* next 3 lines: utc = 365y + y/4 */
    105 	utc += (utc << 3) + (utc << 6);
    106 	utc += (utc << 2) + ((year - 69) >> 2);
    107 	utc += days_thru_month[month] + day - 1;
    108 	utc = (utc << 3) + (utc << 4) + hour;	/* 24 * day + hour */
    109 	utc = (utc << 6) - (utc << 2) + min;	/* 60 * hour + min */
    110 	utc = (utc << 6) - (utc << 2) + sec;	/* 60 * min + sec */
    111 
    112 	return (ctime((time_t *)&utc));
    113 }
    114 
    115 void
    116 disp_powerfail(Prom_node *root)
    117 {
    118 	Prom_node *pnode;
    119 	char *option_str = "options";
    120 	char *pf_str = "powerfail-time";
    121 	char *value_str;
    122 	time_t value;
    123 
    124 	pnode = dev_find_node(root, option_str);
    125 	if (pnode == NULL) {
    126 		return;
    127 	}
    128 
    129 	value_str = get_prop_val(find_prop(pnode, pf_str));
    130 	if (value_str == NULL) {
    131 		return;
    132 	}
    133 
    134 	value = (time_t)atoi(value_str);
    135 	if (value == 0)
    136 		return;
    137 
    138 	(void) log_printf(
    139 		dgettext(TEXT_DOMAIN,
    140 			"Most recent AC Power Failure:\n"));
    141 	(void) log_printf("=============================\n");
    142 	(void) log_printf("%s", ctime(&value));
    143 	(void) log_printf("\n");
    144 }
    145 
    146 
    147 /*VARARGS1*/
    148 void
    149 log_printf(char *fmt, ...)
    150 {
    151 	va_list ap;
    152 	int len;
    153 	static char bigbuf[4096];
    154 	char buffer[1024];
    155 
    156 	if (print_flag == 0) {
    157 		return;
    158 	}
    159 
    160 	va_start(ap, fmt);
    161 	if (logging != 0) {
    162 		len = vsprintf(buffer, fmt, ap);
    163 		(void) strcat(bigbuf, buffer);
    164 
    165 		/* we only call to syslog when we get the entire line. */
    166 		if (buffer[len-1] == '\n') {
    167 			syslog(LOG_DAEMON|LOG_NOTICE, bigbuf);
    168 			bigbuf[0] = 0;
    169 		}
    170 
    171 	} else {
    172 		(void) vprintf(fmt, ap);
    173 	}
    174 	va_end(ap);
    175 }
    176 
    177 void
    178 print_header(int board)
    179 {
    180 	log_printf("\n");
    181 	log_printf(dgettext(TEXT_DOMAIN,
    182 		"Analysis for Board %d\n"), board, 0);
    183 	log_printf("--------------------\n", 0);
    184 }
    185