Home | History | Annotate | Line # | Download | only in eeprom
eehandlers.c revision 1.11
      1  1.11  christos /*	$NetBSD: eehandlers.c,v 1.11 2006/11/17 22:13:08 christos Exp $	*/
      2   1.1   thorpej 
      3   1.2   thorpej /*-
      4   1.2   thorpej  * Copyright (c) 1996 The NetBSD Foundation, Inc.
      5   1.1   thorpej  * All rights reserved.
      6   1.1   thorpej  *
      7   1.2   thorpej  * This code is derived from software contributed to The NetBSD Foundation
      8   1.2   thorpej  * by Jason R. Thorpe.
      9   1.2   thorpej  *
     10   1.1   thorpej  * Redistribution and use in source and binary forms, with or without
     11   1.1   thorpej  * modification, are permitted provided that the following conditions
     12   1.1   thorpej  * are met:
     13   1.1   thorpej  * 1. Redistributions of source code must retain the above copyright
     14   1.1   thorpej  *    notice, this list of conditions and the following disclaimer.
     15   1.1   thorpej  * 2. Redistributions in binary form must reproduce the above copyright
     16   1.1   thorpej  *    notice, this list of conditions and the following disclaimer in the
     17   1.1   thorpej  *    documentation and/or other materials provided with the distribution.
     18   1.1   thorpej  * 3. All advertising materials mentioning features or use of this software
     19   1.1   thorpej  *    must display the following acknowledgement:
     20   1.2   thorpej  *        This product includes software developed by the NetBSD
     21   1.2   thorpej  *        Foundation, Inc. and its contributors.
     22   1.2   thorpej  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23   1.2   thorpej  *    contributors may be used to endorse or promote products derived
     24   1.2   thorpej  *    from this software without specific prior written permission.
     25   1.1   thorpej  *
     26   1.2   thorpej  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27   1.2   thorpej  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28   1.2   thorpej  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29   1.5       jtc  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30   1.5       jtc  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31   1.2   thorpej  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32   1.2   thorpej  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33   1.2   thorpej  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34   1.2   thorpej  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35   1.2   thorpej  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36   1.2   thorpej  * POSSIBILITY OF SUCH DAMAGE.
     37   1.1   thorpej  */
     38   1.1   thorpej 
     39   1.1   thorpej #include <sys/types.h>
     40   1.1   thorpej #include <ctype.h>
     41   1.1   thorpej #include <err.h>
     42   1.1   thorpej #include <errno.h>
     43   1.1   thorpej #include <fcntl.h>
     44   1.1   thorpej #include <string.h>
     45   1.1   thorpej #include <stdio.h>
     46   1.1   thorpej #include <stdlib.h>
     47   1.1   thorpej #include <string.h>
     48   1.1   thorpej #include <time.h>
     49   1.1   thorpej #include <unistd.h>
     50  1.11  christos #include <util.h>
     51   1.1   thorpej 
     52   1.1   thorpej #include <machine/eeprom.h>
     53   1.1   thorpej #ifdef __sparc__
     54   1.1   thorpej #include <machine/openpromio.h>
     55   1.1   thorpej #endif /* __sparc__ */
     56   1.1   thorpej 
     57   1.1   thorpej #include "defs.h"
     58   1.1   thorpej 
     59   1.1   thorpej extern	char *path_eeprom;
     60   1.1   thorpej extern	int eval;
     61   1.1   thorpej extern	int update_checksums;
     62   1.1   thorpej extern	int ignore_checksum;
     63   1.1   thorpej extern	int fix_checksum;
     64   1.1   thorpej extern	int cksumfail;
     65   1.1   thorpej extern	u_short writecount;
     66   1.1   thorpej 
     67   1.1   thorpej static	char err_str[BUFSIZE];
     68   1.1   thorpej 
     69   1.8       mrg static	void badval (struct keytabent *, char *);
     70   1.8       mrg static	int doio (struct keytabent *, u_char *, ssize_t, int);
     71   1.1   thorpej 
     72   1.9       mrg struct	keytabent eekeytab[] = {
     73   1.9       mrg 	{ "hwupdate",		0x10,	ee_hwupdate },
     74   1.9       mrg 	{ "memsize",		0x14,	ee_num8 },
     75   1.9       mrg 	{ "memtest",		0x15,	ee_num8 },
     76   1.9       mrg 	{ "scrsize",		0x16,	ee_screensize },
     77   1.9       mrg 	{ "watchdog_reboot",	0x17,	ee_truefalse },
     78   1.9       mrg 	{ "default_boot",	0x18,	ee_truefalse },
     79   1.9       mrg 	{ "bootdev",		0x19,	ee_bootdev },
     80   1.9       mrg 	{ "kbdtype",		0x1e,	ee_kbdtype },
     81   1.9       mrg 	{ "console",		0x1f,	ee_constype },
     82   1.9       mrg 	{ "keyclick",		0x21,	ee_truefalse },
     83   1.9       mrg 	{ "diagdev",		0x22,	ee_bootdev },
     84   1.9       mrg 	{ "diagpath",		0x28,	ee_diagpath },
     85   1.9       mrg 	{ "columns",		0x50,	ee_num8 },
     86   1.9       mrg 	{ "rows",		0x51,	ee_num8 },
     87   1.9       mrg 	{ "ttya_use_baud",	0x58,	ee_truefalse },
     88   1.9       mrg 	{ "ttya_baud",		0x59,	ee_num16 },
     89   1.9       mrg 	{ "ttya_no_rtsdtr",	0x5b,	ee_truefalse },
     90   1.9       mrg 	{ "ttyb_use_baud",	0x60,	ee_truefalse },
     91   1.9       mrg 	{ "ttyb_baud",		0x61,	ee_num16 },
     92   1.9       mrg 	{ "ttyb_no_rtsdtr",	0x63,	ee_truefalse },
     93   1.9       mrg 	{ "banner",		0x68,	ee_banner },
     94   1.9       mrg 	{ "secure",		0,	ee_notsupp },
     95   1.9       mrg 	{ "bad_login",		0,	ee_notsupp },
     96   1.9       mrg 	{ "password",		0,	ee_notsupp },
     97   1.9       mrg 	{ NULL,			0,	ee_notsupp },
     98   1.9       mrg };
     99   1.9       mrg 
    100   1.1   thorpej #define BARF(kt) {							\
    101   1.1   thorpej 	badval((kt), arg);						\
    102   1.1   thorpej 	++eval;								\
    103   1.1   thorpej 	return;								\
    104   1.1   thorpej }
    105   1.1   thorpej 
    106   1.1   thorpej #define FAILEDREAD(kt) {						\
    107   1.7    itojun 	warnx("%s", err_str);						\
    108   1.1   thorpej 	warnx("failed to read field `%s'", (kt)->kt_keyword);		\
    109   1.1   thorpej 	++eval;								\
    110   1.1   thorpej 	return;								\
    111   1.1   thorpej }
    112   1.1   thorpej 
    113   1.1   thorpej #define FAILEDWRITE(kt) {						\
    114   1.7    itojun 	warnx("%s", err_str);						\
    115   1.1   thorpej 	warnx("failed to update field `%s'", (kt)->kt_keyword);		\
    116   1.1   thorpej 	++eval;								\
    117   1.1   thorpej 	return;								\
    118   1.9       mrg }
    119   1.9       mrg 
    120   1.9       mrg void
    121   1.9       mrg ee_action(keyword, arg)
    122   1.9       mrg 	char *keyword, *arg;
    123   1.9       mrg {
    124   1.9       mrg 	struct keytabent *ktent;
    125   1.9       mrg 
    126   1.9       mrg 	for (ktent = eekeytab; ktent->kt_keyword != NULL; ++ktent) {
    127   1.9       mrg 		if (strcmp(ktent->kt_keyword, keyword) == 0) {
    128   1.9       mrg 			(*ktent->kt_handler)(ktent, arg);
    129   1.9       mrg 			return;
    130   1.9       mrg 		}
    131   1.9       mrg 	}
    132   1.9       mrg 
    133   1.9       mrg 	warnx("unknown keyword %s", keyword);
    134   1.9       mrg 	++eval;
    135   1.9       mrg }
    136   1.9       mrg 
    137   1.9       mrg void
    138   1.9       mrg ee_dump()
    139   1.9       mrg {
    140   1.9       mrg 	struct keytabent *ktent;
    141   1.9       mrg 
    142   1.9       mrg 	for (ktent = eekeytab; ktent->kt_keyword != NULL; ++ktent)
    143   1.9       mrg 		(*ktent->kt_handler)(ktent, NULL);
    144   1.1   thorpej }
    145   1.1   thorpej 
    146   1.1   thorpej void
    147   1.1   thorpej ee_hwupdate(ktent, arg)
    148   1.1   thorpej 	struct keytabent *ktent;
    149   1.1   thorpej 	char *arg;
    150   1.1   thorpej {
    151   1.1   thorpej 	time_t t;
    152   1.1   thorpej 	char *cp, *cp2;
    153   1.1   thorpej 
    154   1.1   thorpej 	if (arg) {
    155   1.1   thorpej 		if ((strcmp(arg, "now") == 0) ||
    156   1.1   thorpej 		    (strcmp(arg, "today") == 0)) {
    157   1.1   thorpej 			if ((t = time(NULL)) == (time_t)(-1)) {
    158   1.1   thorpej 				warnx("can't get current time");
    159   1.1   thorpej 				++eval;
    160   1.1   thorpej 				return;
    161   1.1   thorpej 			}
    162   1.1   thorpej 		} else
    163  1.11  christos 			if ((t = getdate(arg, NULL, NULL)) == (time_t)(-1))
    164   1.1   thorpej 				BARF(ktent);
    165   1.1   thorpej 
    166   1.1   thorpej 		if (doio(ktent, (u_char *)&t, sizeof(t), IO_WRITE))
    167   1.1   thorpej 			FAILEDWRITE(ktent);
    168   1.1   thorpej 	} else
    169   1.1   thorpej 		if (doio(ktent, (u_char *)&t, sizeof(t), IO_READ))
    170   1.1   thorpej 			FAILEDREAD(ktent);
    171   1.1   thorpej 
    172   1.1   thorpej 	cp = ctime(&t);
    173   1.1   thorpej 	if ((cp2 = strrchr(cp, '\n')) != NULL)
    174   1.1   thorpej 		*cp2 = '\0';
    175   1.1   thorpej 
    176   1.4   thorpej 	printf("%s=%ld (%s)\n", ktent->kt_keyword, (long)t, cp);
    177   1.1   thorpej }
    178   1.1   thorpej 
    179   1.1   thorpej void
    180   1.1   thorpej ee_num8(ktent, arg)
    181   1.1   thorpej 	struct keytabent *ktent;
    182   1.1   thorpej 	char *arg;
    183   1.1   thorpej {
    184   1.1   thorpej 	u_char num8 = 0;
    185   1.1   thorpej 	u_int num32;
    186   1.1   thorpej 	int i;
    187   1.1   thorpej 
    188   1.1   thorpej 	if (arg) {
    189   1.1   thorpej 		for (i = 0; i < (strlen(arg) - 1); ++i)
    190  1.10       dsl 			if (!isdigit((unsigned char)arg[i]))
    191   1.1   thorpej 				BARF(ktent);
    192   1.1   thorpej 		num32 = atoi(arg);
    193   1.1   thorpej 		if (num32 > 0xff)
    194   1.1   thorpej 			BARF(ktent);
    195   1.1   thorpej 		num8 += num32;
    196   1.1   thorpej 		if (doio(ktent, &num8, sizeof(num8), IO_WRITE))
    197   1.1   thorpej 			FAILEDWRITE(ktent);
    198   1.1   thorpej 	} else
    199   1.1   thorpej 		if (doio(ktent, &num8, sizeof(num8), IO_READ))
    200   1.1   thorpej 			FAILEDREAD(ktent);
    201   1.1   thorpej 
    202   1.1   thorpej 	printf("%s=%d\n", ktent->kt_keyword, num8);
    203   1.1   thorpej }
    204   1.1   thorpej 
    205   1.1   thorpej void
    206   1.1   thorpej ee_num16(ktent, arg)
    207   1.1   thorpej 	struct keytabent *ktent;
    208   1.1   thorpej 	char *arg;
    209   1.1   thorpej {
    210   1.1   thorpej 	u_int16_t num16 = 0;
    211   1.1   thorpej 	u_int num32;
    212   1.1   thorpej 	int i;
    213   1.1   thorpej 
    214   1.1   thorpej 	if (arg) {
    215   1.1   thorpej 		for (i = 0; i < (strlen(arg) - 1); ++i)
    216  1.10       dsl 			if (!isdigit((unsigned char)arg[i]))
    217   1.1   thorpej 				BARF(ktent);
    218   1.1   thorpej 		num32 = atoi(arg);
    219   1.1   thorpej 		if (num32 > 0xffff)
    220   1.1   thorpej 			BARF(ktent);
    221   1.1   thorpej 		num16 += num32;
    222   1.1   thorpej 		if (doio(ktent, (u_char *)&num16, sizeof(num16), IO_WRITE))
    223   1.1   thorpej 			FAILEDWRITE(ktent);
    224   1.1   thorpej 	} else
    225   1.1   thorpej 		if (doio(ktent, (u_char *)&num16, sizeof(num16), IO_READ))
    226   1.1   thorpej 			FAILEDREAD(ktent);
    227   1.1   thorpej 
    228   1.1   thorpej 	printf("%s=%d\n", ktent->kt_keyword, num16);
    229   1.1   thorpej }
    230   1.1   thorpej 
    231   1.1   thorpej static	struct strvaltabent scrsizetab[] = {
    232   1.1   thorpej 	{ "1152x900",		EE_SCR_1152X900 },
    233   1.1   thorpej 	{ "1024x1024",		EE_SCR_1024X1024 },
    234   1.1   thorpej 	{ "1600x1280",		EE_SCR_1600X1280 },
    235   1.1   thorpej 	{ "1440x1440",		EE_SCR_1440X1440 },
    236   1.1   thorpej 	{ NULL,			0 },
    237   1.1   thorpej };
    238   1.1   thorpej 
    239   1.1   thorpej void
    240   1.1   thorpej ee_screensize(ktent, arg)
    241   1.1   thorpej 	struct keytabent *ktent;
    242   1.1   thorpej 	char *arg;
    243   1.1   thorpej {
    244   1.1   thorpej 	struct strvaltabent *svp;
    245   1.1   thorpej 	u_char scsize;
    246   1.1   thorpej 
    247   1.1   thorpej 	if (arg) {
    248   1.1   thorpej 		for (svp = scrsizetab; svp->sv_str != NULL; ++svp)
    249   1.1   thorpej 			if (strcmp(svp->sv_str, arg) == 0)
    250   1.1   thorpej 				break;
    251   1.1   thorpej 		if (svp->sv_str == NULL)
    252   1.1   thorpej 			BARF(ktent);
    253   1.1   thorpej 
    254   1.1   thorpej 		scsize = svp->sv_val;
    255   1.1   thorpej 		if (doio(ktent, &scsize, sizeof(scsize), IO_WRITE))
    256   1.1   thorpej 			FAILEDWRITE(ktent);
    257   1.1   thorpej 	} else {
    258   1.1   thorpej 		if (doio(ktent, &scsize, sizeof(scsize), IO_READ))
    259   1.1   thorpej 			FAILEDREAD(ktent);
    260   1.1   thorpej 
    261   1.1   thorpej 		for (svp = scrsizetab; svp->sv_str != NULL; ++svp)
    262   1.1   thorpej 			if (svp->sv_val == scsize)
    263   1.1   thorpej 				break;
    264   1.1   thorpej 		if (svp->sv_str == NULL) {
    265   1.1   thorpej 			warnx("unknown %s value %d", ktent->kt_keyword,
    266   1.1   thorpej 			    scsize);
    267   1.1   thorpej 			return;
    268   1.1   thorpej 		}
    269   1.1   thorpej 	}
    270   1.1   thorpej 	printf("%s=%s\n", ktent->kt_keyword, svp->sv_str);
    271   1.1   thorpej }
    272   1.1   thorpej 
    273   1.1   thorpej static	struct strvaltabent truthtab[] = {
    274   1.1   thorpej 	{ "true",		EE_TRUE },
    275   1.1   thorpej 	{ "false",		EE_FALSE },
    276   1.1   thorpej 	{ NULL,			0 },
    277   1.1   thorpej };
    278   1.1   thorpej 
    279   1.1   thorpej void
    280   1.1   thorpej ee_truefalse(ktent, arg)
    281   1.1   thorpej 	struct keytabent *ktent;
    282   1.1   thorpej 	char *arg;
    283   1.1   thorpej {
    284   1.1   thorpej 	struct strvaltabent *svp;
    285   1.1   thorpej 	u_char truth;
    286   1.1   thorpej 
    287   1.1   thorpej 	if (arg) {
    288   1.1   thorpej 		for (svp = truthtab; svp->sv_str != NULL; ++svp)
    289   1.1   thorpej 			if (strcmp(svp->sv_str, arg) == 0)
    290   1.1   thorpej 				break;
    291   1.1   thorpej 		if (svp->sv_str == NULL)
    292   1.1   thorpej 			BARF(ktent);
    293   1.1   thorpej 
    294   1.1   thorpej 		truth = svp->sv_val;
    295   1.1   thorpej 		if (doio(ktent, &truth, sizeof(truth), IO_WRITE))
    296   1.1   thorpej 			FAILEDWRITE(ktent);
    297   1.1   thorpej 	} else {
    298   1.1   thorpej 		if (doio(ktent, &truth, sizeof(truth), IO_READ))
    299   1.1   thorpej 			FAILEDREAD(ktent);
    300   1.1   thorpej 
    301   1.1   thorpej 		for (svp = truthtab; svp->sv_str != NULL; ++svp)
    302   1.1   thorpej 			if (svp->sv_val == truth)
    303   1.1   thorpej 				break;
    304   1.1   thorpej 		if (svp->sv_str == NULL) {
    305   1.1   thorpej 			warnx("unknown truth value 0x%x for %s", truth,
    306   1.1   thorpej 			    ktent->kt_keyword);
    307   1.1   thorpej 			return;
    308   1.1   thorpej 		}
    309   1.1   thorpej 	}
    310   1.1   thorpej 	printf("%s=%s\n", ktent->kt_keyword, svp->sv_str);
    311   1.1   thorpej }
    312   1.1   thorpej 
    313   1.1   thorpej void
    314   1.1   thorpej ee_bootdev(ktent, arg)
    315   1.1   thorpej 	struct keytabent *ktent;
    316   1.1   thorpej 	char *arg;
    317   1.1   thorpej {
    318   1.1   thorpej 	u_char dev[5];
    319   1.1   thorpej 	int i;
    320   1.1   thorpej 	size_t arglen;
    321   1.1   thorpej 	char *cp;
    322   1.1   thorpej 
    323   1.1   thorpej 	if (arg) {
    324   1.1   thorpej 		/*
    325   1.1   thorpej 		 * The format of the string we accept is the following:
    326   1.1   thorpej 		 *	cc(n,n,n)
    327   1.1   thorpej 		 * where:
    328   1.1   thorpej 		 *	c -- an alphabetical character [a-z]
    329   1.1   thorpej 		 *	n -- a number in hexadecimal, between 0 and ff,
    330   1.1   thorpej 		 *	     with no leading `0x'.
    331   1.1   thorpej 		 */
    332   1.1   thorpej 		arglen = strlen(arg);
    333   1.1   thorpej 		if (arglen < 9 || arglen > 12 || arg[2] != '(' ||
    334   1.1   thorpej 		     arg[arglen - 1] != ')')
    335   1.1   thorpej 			BARF(ktent);
    336   1.1   thorpej 
    337   1.1   thorpej 		/* Handle the first 2 letters. */
    338   1.1   thorpej 		for (i = 0; i < 2; ++i) {
    339   1.1   thorpej 			if (arg[i] < 'a' || arg[i] > 'z')
    340   1.1   thorpej 				BARF(ktent);
    341   1.1   thorpej 			dev[i] = (u_char)arg[i];
    342   1.1   thorpej 		}
    343   1.1   thorpej 
    344   1.1   thorpej 		/* Handle the 3 `0x'-less hex values. */
    345   1.1   thorpej 		cp = &arg[3];
    346   1.1   thorpej 		for (i = 2; i < 5; ++i) {
    347   1.1   thorpej 			if (*cp == '\0')
    348   1.1   thorpej 				BARF(ktent);
    349   1.1   thorpej 
    350   1.1   thorpej 			if (*cp >= '0' && *cp <= '9')
    351   1.1   thorpej 				dev[i] = *cp++ - '0';
    352   1.1   thorpej 			else if (*cp >= 'a' && *cp <= 'f')
    353   1.1   thorpej 				dev[i] = 10 + (*cp++ - 'a');
    354   1.1   thorpej 			else
    355   1.1   thorpej 				BARF(ktent);
    356   1.1   thorpej 
    357   1.1   thorpej 			/* Deal with a second digit. */
    358   1.1   thorpej 			if (*cp >= '0' && *cp <= '9') {
    359   1.1   thorpej 				dev[i] <<= 4;
    360   1.1   thorpej 				dev[i] &= 0xf0;
    361   1.1   thorpej 				dev[i] += *cp++ - '0';
    362   1.1   thorpej 			} else if (*cp >= 'a' && *cp <= 'f') {
    363   1.1   thorpej 				dev[i] <<= 4;
    364   1.1   thorpej 				dev[i] &= 0xf0;
    365   1.1   thorpej 				dev[i] += 10 + (*cp++ - 'a');
    366   1.1   thorpej 			}
    367   1.1   thorpej 
    368   1.1   thorpej 			/* Ensure we have the correct delimiter. */
    369   1.1   thorpej 			if ((*cp == ',' && i < 4) || (*cp == ')' && i == 4)) {
    370   1.1   thorpej 				++cp;
    371   1.1   thorpej 				continue;
    372   1.1   thorpej 			} else
    373   1.1   thorpej 				BARF(ktent);
    374   1.1   thorpej 		}
    375   1.1   thorpej 		if (doio(ktent, (u_char *)&dev[0], sizeof(dev), IO_WRITE))
    376   1.1   thorpej 			FAILEDWRITE(ktent);
    377   1.1   thorpej 	} else
    378   1.1   thorpej 		if (doio(ktent, (u_char *)&dev[0], sizeof(dev), IO_READ))
    379   1.1   thorpej 			FAILEDREAD(ktent);
    380   1.1   thorpej 
    381   1.1   thorpej 	printf("%s=%c%c(%x,%x,%x)\n", ktent->kt_keyword, dev[0],
    382   1.1   thorpej 	     dev[1], dev[2], dev[3], dev[4]);
    383   1.1   thorpej }
    384   1.1   thorpej 
    385   1.1   thorpej void
    386   1.1   thorpej ee_kbdtype(ktent, arg)
    387   1.1   thorpej 	struct keytabent *ktent;
    388   1.1   thorpej 	char *arg;
    389   1.1   thorpej {
    390   1.1   thorpej 	u_char kbd = 0;
    391   1.1   thorpej 	u_int kbd2;
    392   1.1   thorpej 	int i;
    393   1.1   thorpej 
    394   1.1   thorpej 	if (arg) {
    395   1.1   thorpej 		for (i = 0; i < (strlen(arg) - 1); ++i)
    396  1.10       dsl 			if (!isdigit((unsigned char)arg[i]))
    397   1.1   thorpej 				BARF(ktent);
    398   1.1   thorpej 		kbd2 = atoi(arg);
    399   1.1   thorpej 		if (kbd2 > 0xff)
    400   1.1   thorpej 			BARF(ktent);
    401   1.1   thorpej 		kbd += kbd2;
    402   1.1   thorpej 		if (doio(ktent, &kbd, sizeof(kbd), IO_WRITE))
    403   1.1   thorpej 			FAILEDWRITE(ktent);
    404   1.1   thorpej 	} else
    405   1.1   thorpej 		if (doio(ktent, &kbd, sizeof(kbd), IO_READ))
    406   1.1   thorpej 			FAILEDREAD(ktent);
    407   1.1   thorpej 
    408   1.1   thorpej 	printf("%s=%d (%s)\n", ktent->kt_keyword, kbd, kbd ? "other" : "Sun");
    409   1.1   thorpej }
    410   1.1   thorpej 
    411   1.1   thorpej static	struct strvaltabent constab[] = {
    412   1.1   thorpej 	{ "b&w",		EE_CONS_BW },
    413   1.1   thorpej 	{ "ttya",		EE_CONS_TTYA },
    414   1.1   thorpej 	{ "ttyb",		EE_CONS_TTYB },
    415   1.1   thorpej 	{ "color",		EE_CONS_COLOR },
    416   1.1   thorpej 	{ "p4opt",		EE_CONS_P4OPT },
    417   1.1   thorpej 	{ NULL,			0 },
    418   1.1   thorpej };
    419   1.1   thorpej 
    420   1.1   thorpej void
    421   1.1   thorpej ee_constype(ktent, arg)
    422   1.1   thorpej 	struct keytabent *ktent;
    423   1.1   thorpej 	char *arg;
    424   1.1   thorpej {
    425   1.1   thorpej 	struct strvaltabent *svp;
    426   1.1   thorpej 	u_char cons;
    427   1.1   thorpej 
    428   1.1   thorpej 	if (arg) {
    429   1.1   thorpej 		for (svp = constab; svp->sv_str != NULL; ++svp)
    430   1.1   thorpej 			if (strcmp(svp->sv_str, arg) == 0)
    431   1.1   thorpej 				break;
    432   1.1   thorpej 		if (svp->sv_str == NULL)
    433   1.1   thorpej 			BARF(ktent);
    434   1.1   thorpej 
    435   1.1   thorpej 		cons = svp->sv_val;
    436   1.1   thorpej 		if (doio(ktent, &cons, sizeof(cons), IO_WRITE))
    437   1.1   thorpej 			FAILEDWRITE(ktent);
    438   1.1   thorpej 	} else {
    439   1.1   thorpej 		if (doio(ktent, &cons, sizeof(cons), IO_READ))
    440   1.1   thorpej 			FAILEDREAD(ktent);
    441   1.1   thorpej 
    442   1.1   thorpej 		for (svp = constab; svp->sv_str != NULL; ++svp)
    443   1.1   thorpej 			if (svp->sv_val == cons)
    444   1.1   thorpej 				break;
    445   1.1   thorpej 		if (svp->sv_str == NULL) {
    446   1.1   thorpej 			warnx("unknown type 0x%x for %s", cons,
    447   1.1   thorpej 			    ktent->kt_keyword);
    448   1.1   thorpej 			return;
    449   1.1   thorpej 		}
    450   1.1   thorpej 	}
    451   1.1   thorpej 	printf("%s=%s\n", ktent->kt_keyword, svp->sv_str);
    452   1.1   thorpej 
    453   1.1   thorpej }
    454   1.1   thorpej 
    455   1.1   thorpej void
    456   1.1   thorpej ee_diagpath(ktent, arg)
    457   1.1   thorpej 	struct keytabent *ktent;
    458   1.1   thorpej 	char *arg;
    459   1.1   thorpej {
    460   1.1   thorpej 	char path[40];
    461   1.1   thorpej 
    462   1.6     lukem 	memset(path, 0, sizeof(path));
    463   1.1   thorpej 	if (arg) {
    464   1.1   thorpej 		if (strlen(arg) > sizeof(path))
    465   1.1   thorpej 			BARF(ktent);
    466   1.3       mrg 		memcpy(path, arg, sizeof path);
    467   1.1   thorpej 		if (doio(ktent, (u_char *)&path[0], sizeof(path), IO_WRITE))
    468   1.1   thorpej 			FAILEDWRITE(ktent);
    469   1.1   thorpej 	} else
    470   1.1   thorpej 		if (doio(ktent, (u_char *)&path[0], sizeof(path), IO_READ))
    471   1.1   thorpej 			FAILEDREAD(ktent);
    472   1.1   thorpej 
    473   1.1   thorpej 	printf("%s=%s\n", ktent->kt_keyword, path);
    474   1.1   thorpej }
    475   1.1   thorpej 
    476   1.1   thorpej void
    477   1.1   thorpej ee_banner(ktent, arg)
    478   1.1   thorpej 	struct keytabent *ktent;
    479   1.1   thorpej 	char *arg;
    480   1.1   thorpej {
    481   1.1   thorpej 	char string[80];
    482   1.1   thorpej 	u_char enable;
    483   1.1   thorpej 	struct keytabent kt;
    484   1.1   thorpej 
    485   1.1   thorpej 	kt.kt_keyword = "enable_banner";
    486   1.1   thorpej 	kt.kt_offset = EE_BANNER_ENABLE_LOC;
    487   1.1   thorpej 	kt.kt_handler = ee_notsupp;
    488   1.1   thorpej 
    489   1.3       mrg 	memset(string, '\0', sizeof(string));
    490   1.1   thorpej 	if (arg) {
    491   1.1   thorpej 		if (strlen(arg) > sizeof(string))
    492   1.1   thorpej 			BARF(ktent);
    493   1.1   thorpej 		if (*arg != '\0') {
    494   1.1   thorpej 			enable = EE_TRUE;
    495   1.3       mrg 			memcpy(string, arg, sizeof string);
    496   1.1   thorpej 			if (doio(ktent, (u_char *)string,
    497   1.1   thorpej 			    sizeof(string), IO_WRITE))
    498   1.1   thorpej 				FAILEDWRITE(ktent);
    499   1.1   thorpej 		} else {
    500   1.1   thorpej 			enable = EE_FALSE;
    501   1.1   thorpej 			if (doio(ktent, (u_char *)string,
    502   1.1   thorpej 			    sizeof(string), IO_READ))
    503   1.1   thorpej 				FAILEDREAD(ktent);
    504   1.1   thorpej 		}
    505   1.1   thorpej 
    506   1.1   thorpej 		if (doio(&kt, &enable, sizeof(enable), IO_WRITE))
    507   1.1   thorpej 			FAILEDWRITE(&kt);
    508   1.1   thorpej 	} else {
    509   1.1   thorpej 		if (doio(ktent, (u_char *)string, sizeof(string), IO_READ))
    510   1.1   thorpej 			FAILEDREAD(ktent);
    511   1.1   thorpej 		if (doio(&kt, &enable, sizeof(enable), IO_READ))
    512   1.1   thorpej 			FAILEDREAD(&kt);
    513   1.1   thorpej 	}
    514   1.1   thorpej 	printf("%s=%s (%s)\n", ktent->kt_keyword, string,
    515   1.1   thorpej 	    enable == EE_TRUE ? "enabled" : "disabled");
    516   1.1   thorpej }
    517   1.1   thorpej 
    518   1.1   thorpej /* ARGSUSED */
    519   1.1   thorpej void
    520   1.1   thorpej ee_notsupp(ktent, arg)
    521   1.1   thorpej 	struct keytabent *ktent;
    522   1.1   thorpej 	char *arg;
    523   1.1   thorpej {
    524   1.1   thorpej 
    525   1.1   thorpej 	warnx("field `%s' not yet supported", ktent->kt_keyword);
    526   1.1   thorpej }
    527   1.1   thorpej 
    528   1.1   thorpej static void
    529   1.1   thorpej badval(ktent, arg)
    530   1.1   thorpej 	struct keytabent *ktent;
    531   1.1   thorpej 	char *arg;
    532   1.1   thorpej {
    533   1.1   thorpej 
    534   1.1   thorpej 	warnx("inappropriate value `%s' for field `%s'", arg,
    535   1.1   thorpej 	    ktent->kt_keyword);
    536   1.1   thorpej }
    537   1.1   thorpej 
    538   1.1   thorpej static int
    539   1.1   thorpej doio(ktent, buf, len, wr)
    540   1.1   thorpej 	struct keytabent *ktent;
    541   1.1   thorpej 	u_char *buf;
    542   1.1   thorpej 	ssize_t len;
    543   1.1   thorpej 	int wr;
    544   1.1   thorpej {
    545   1.1   thorpej 	int fd, rval = 0;
    546   1.1   thorpej 	u_char *buf2;
    547   1.1   thorpej 
    548   1.1   thorpej 	buf2 = (u_char *)calloc(1, len);
    549   1.1   thorpej 	if (buf2 == NULL) {
    550   1.3       mrg 		memcpy(err_str, "memory allocation failed", sizeof err_str);
    551   1.1   thorpej 		return (1);
    552   1.1   thorpej 	}
    553   1.1   thorpej 
    554   1.1   thorpej 	fd = open(path_eeprom, wr == IO_WRITE ? O_RDWR : O_RDONLY, 0640);
    555   1.1   thorpej 	if (fd < 0) {
    556   1.3       mrg 		(void)snprintf(err_str, sizeof err_str, "open: %s: %s", path_eeprom,
    557   1.1   thorpej 		    strerror(errno));
    558   1.1   thorpej 		free(buf2);
    559   1.1   thorpej 		return (1);
    560   1.1   thorpej 	}
    561   1.1   thorpej 
    562   1.1   thorpej 	if (lseek(fd, (off_t)ktent->kt_offset, SEEK_SET) < (off_t)0) {
    563   1.4   thorpej 		(void)snprintf(err_str, sizeof err_str, "lseek: %s: %s",
    564   1.3       mrg 		    path_eeprom, strerror(errno));
    565   1.1   thorpej 		rval = 1;
    566   1.1   thorpej 		goto done;
    567   1.1   thorpej 	}
    568   1.1   thorpej 
    569   1.1   thorpej 	if (read(fd, buf2, len) != len) {
    570   1.3       mrg 		(void)snprintf(err_str, sizeof err_str, "read: %s: %s",
    571   1.3       mrg 		    path_eeprom, strerror(errno));
    572   1.1   thorpej 		return (1);
    573   1.1   thorpej 	}
    574   1.1   thorpej 
    575   1.1   thorpej 	if (wr == IO_WRITE) {
    576   1.6     lukem 		if (memcmp(buf, buf2, len) == 0)
    577   1.1   thorpej 			goto done;
    578   1.1   thorpej 
    579   1.1   thorpej 		if (lseek(fd, (off_t)ktent->kt_offset, SEEK_SET) < (off_t)0) {
    580   1.3       mrg 			(void)snprintf(err_str, sizeof err_str, "lseek: %s: %s",
    581   1.3       mrg 			    path_eeprom, strerror(errno));
    582   1.1   thorpej 			rval = 1;
    583   1.1   thorpej 			goto done;
    584   1.1   thorpej 		}
    585   1.1   thorpej 
    586   1.1   thorpej 		++update_checksums;
    587   1.1   thorpej 		if (write(fd, buf, len) < 0) {
    588   1.3       mrg 			(void)snprintf(err_str, sizeof err_str, "write: %s: %s",
    589   1.3       mrg 			    path_eeprom, strerror(errno));
    590   1.1   thorpej 			rval = 1;
    591   1.1   thorpej 			goto done;
    592   1.1   thorpej 		}
    593   1.1   thorpej 	} else
    594   1.6     lukem 		memmove(buf, buf2, len);
    595   1.1   thorpej 
    596   1.1   thorpej  done:
    597   1.1   thorpej 	free(buf2);
    598   1.1   thorpej 	(void)close(fd);
    599   1.1   thorpej 	return (rval);
    600   1.1   thorpej }
    601   1.1   thorpej 
    602   1.1   thorpej /*
    603   1.1   thorpej  * Read from eeLastHwUpdate to just before eeReserved.  Calculate
    604   1.1   thorpej  * a checksum, and deposit 3 copies of it sequentially starting at
    605   1.1   thorpej  * eeChecksum[0].  Increment the write count, and deposit 3 copies
    606   1.1   thorpej  * of it sequentially starting at eeWriteCount[0].
    607   1.1   thorpej  */
    608   1.1   thorpej void
    609   1.1   thorpej ee_updatechecksums()
    610   1.1   thorpej {
    611   1.1   thorpej 	struct keytabent kt;
    612   1.1   thorpej 	u_char checkme[EE_SIZE - EE_HWUPDATE_LOC];
    613   1.1   thorpej 	u_char checksum;
    614   1.1   thorpej 	int i;
    615   1.1   thorpej 
    616   1.1   thorpej 	kt.kt_keyword = "eeprom contents";
    617   1.1   thorpej 	kt.kt_offset = EE_HWUPDATE_LOC;
    618   1.1   thorpej 	kt.kt_handler = ee_notsupp;
    619   1.1   thorpej 
    620   1.1   thorpej 	if (doio(&kt, checkme, sizeof(checkme), IO_READ)) {
    621   1.1   thorpej 		cksumfail = 1;
    622   1.1   thorpej 		FAILEDREAD(&kt);
    623   1.1   thorpej 	}
    624   1.1   thorpej 
    625   1.1   thorpej 	checksum = ee_checksum(checkme, sizeof(checkme));
    626   1.1   thorpej 
    627   1.1   thorpej 	kt.kt_keyword = "eeprom checksum";
    628   1.1   thorpej 	for (i = 0; i < 4; ++i) {
    629   1.1   thorpej 		kt.kt_offset = EE_CKSUM_LOC + (i * sizeof(checksum));
    630   1.1   thorpej 		if (doio(&kt, &checksum, sizeof(checksum), IO_WRITE)) {
    631   1.1   thorpej 			cksumfail = 1;
    632   1.1   thorpej 			FAILEDWRITE(&kt);
    633   1.1   thorpej 		}
    634   1.1   thorpej 	}
    635   1.1   thorpej 
    636   1.1   thorpej 	kt.kt_keyword = "eeprom writecount";
    637   1.1   thorpej 	for (i = 0; i < 4; ++i) {
    638   1.1   thorpej 		kt.kt_offset = EE_WC_LOC + (i * sizeof(writecount));
    639   1.1   thorpej 		if (doio(&kt, (u_char *)&writecount, sizeof(writecount),
    640   1.1   thorpej 		    IO_WRITE)) {
    641   1.1   thorpej 			cksumfail = 1;
    642   1.1   thorpej 			FAILEDWRITE(&kt);
    643   1.1   thorpej 		}
    644   1.1   thorpej 	}
    645   1.1   thorpej }
    646   1.1   thorpej 
    647   1.1   thorpej void
    648   1.1   thorpej ee_verifychecksums()
    649   1.1   thorpej {
    650   1.1   thorpej 	struct keytabent kt;
    651   1.1   thorpej 	u_char checkme[EE_SIZE - EE_HWUPDATE_LOC];
    652   1.1   thorpej 	u_char checksum, ochecksum[3];
    653   1.1   thorpej 	u_short owritecount[3];
    654   1.1   thorpej 
    655   1.1   thorpej 	/*
    656   1.1   thorpej 	 * Verify that the EEPROM's write counts match, and update the
    657   1.1   thorpej 	 * global copy for use later.
    658   1.1   thorpej 	 */
    659   1.1   thorpej 	kt.kt_keyword = "eeprom writecount";
    660   1.1   thorpej 	kt.kt_offset = EE_WC_LOC;
    661   1.1   thorpej 	kt.kt_handler = ee_notsupp;
    662   1.1   thorpej 
    663   1.1   thorpej 	if (doio(&kt, (u_char *)&owritecount, sizeof(owritecount), IO_READ)) {
    664   1.1   thorpej 		cksumfail = 1;
    665   1.1   thorpej 		FAILEDREAD(&kt);
    666   1.1   thorpej 	}
    667   1.1   thorpej 
    668   1.1   thorpej 	if (owritecount[0] != owritecount[1] ||
    669   1.1   thorpej 	    owritecount[0] != owritecount[2]) {
    670   1.1   thorpej 		warnx("eeprom writecount mismatch %s",
    671   1.1   thorpej 		    ignore_checksum ? "(ignoring)" :
    672   1.1   thorpej 		    (fix_checksum ? "(fixing)" : ""));
    673   1.1   thorpej 
    674   1.1   thorpej 		if (!ignore_checksum && !fix_checksum) {
    675   1.1   thorpej 			cksumfail = 1;
    676   1.1   thorpej 			return;
    677   1.1   thorpej 		}
    678   1.1   thorpej 
    679   1.1   thorpej 		writecount = MAXIMUM(owritecount[0], owritecount[1]);
    680   1.1   thorpej 		writecount = MAXIMUM(writecount, owritecount[2]);
    681   1.1   thorpej 	} else
    682   1.1   thorpej 		writecount = owritecount[0];
    683   1.1   thorpej 
    684   1.1   thorpej 	/*
    685   1.1   thorpej 	 * Verify that the EEPROM's checksums match and are correct.
    686   1.1   thorpej 	 */
    687   1.1   thorpej 	kt.kt_keyword = "eeprom checksum";
    688   1.1   thorpej 	kt.kt_offset = EE_CKSUM_LOC;
    689   1.1   thorpej 
    690   1.1   thorpej 	if (doio(&kt, ochecksum, sizeof(ochecksum), IO_READ)) {
    691   1.1   thorpej 		cksumfail = 1;
    692   1.1   thorpej 		FAILEDREAD(&kt);
    693   1.1   thorpej 	}
    694   1.1   thorpej 
    695   1.1   thorpej 	if (ochecksum[0] != ochecksum[1] ||
    696   1.1   thorpej 	    ochecksum[0] != ochecksum[2]) {
    697   1.1   thorpej 		warnx("eeprom checksum mismatch %s",
    698   1.1   thorpej 		    ignore_checksum ? "(ignoring)" :
    699   1.1   thorpej 		    (fix_checksum ? "(fixing)" : ""));
    700   1.1   thorpej 
    701   1.1   thorpej 		if (!ignore_checksum && !fix_checksum) {
    702   1.1   thorpej 			cksumfail = 1;
    703   1.1   thorpej 			return;
    704   1.1   thorpej 		}
    705   1.1   thorpej 	}
    706   1.1   thorpej 
    707   1.1   thorpej 	kt.kt_keyword = "eeprom contents";
    708   1.1   thorpej 	kt.kt_offset = EE_HWUPDATE_LOC;
    709   1.1   thorpej 
    710   1.1   thorpej 	if (doio(&kt, checkme, sizeof(checkme), IO_READ)) {
    711   1.1   thorpej 		cksumfail = 1;
    712   1.1   thorpej 		FAILEDREAD(&kt);
    713   1.1   thorpej 	}
    714   1.1   thorpej 
    715   1.1   thorpej 	checksum = ee_checksum(checkme, sizeof(checkme));
    716   1.1   thorpej 
    717   1.1   thorpej 	if (ochecksum[0] != checksum) {
    718   1.1   thorpej 		warnx("eeprom checksum incorrect %s",
    719   1.1   thorpej 		    ignore_checksum ? "(ignoring)" :
    720   1.1   thorpej 		    (fix_checksum ? "(fixing)" : ""));
    721   1.1   thorpej 
    722   1.1   thorpej 		if (!ignore_checksum && !fix_checksum) {
    723   1.1   thorpej 			cksumfail = 1;
    724   1.1   thorpej 			return;
    725   1.1   thorpej 		}
    726   1.1   thorpej 	}
    727   1.1   thorpej 
    728   1.1   thorpej 	if (fix_checksum)
    729   1.1   thorpej 		ee_updatechecksums();
    730   1.1   thorpej }
    731   1.1   thorpej 
    732   1.1   thorpej u_char
    733   1.1   thorpej ee_checksum(area, len)
    734   1.1   thorpej 	u_char *area;
    735   1.1   thorpej 	size_t len;
    736   1.1   thorpej {
    737   1.1   thorpej 	u_char sum = 0;
    738   1.1   thorpej 
    739   1.1   thorpej 	while (len--)
    740   1.1   thorpej 		sum += *area++;
    741   1.1   thorpej 
    742   1.1   thorpej 	return (0x100 - sum);
    743   1.1   thorpej }
    744