summaryrefslogtreecommitdiff
path: root/usr.sbin/eeprom
diff options
context:
space:
mode:
authorFederico G. Schwindt <fgsch@cvs.openbsd.org>2007-09-04 23:28:27 +0000
committerFederico G. Schwindt <fgsch@cvs.openbsd.org>2007-09-04 23:28:27 +0000
commited2c81c020cc88cbbf163e0b0ea1b6bca2fbf8cb (patch)
treef435763744f8a6a4ceb1ebccde900efde544e88d /usr.sbin/eeprom
parent47466b70b139eca58302a1af773a0e76c0a280a0 (diff)
add support to print the derivated tree from the OpenPROM (alas devinfo or
prtconf); ok kettenis@. thanks to the various people who helped me test in different sparc* machines.
Diffstat (limited to 'usr.sbin/eeprom')
-rw-r--r--usr.sbin/eeprom/Makefile4
-rw-r--r--usr.sbin/eeprom/defs.h5
-rw-r--r--usr.sbin/eeprom/eeprom.88
-rw-r--r--usr.sbin/eeprom/main.c22
-rw-r--r--usr.sbin/eeprom/ophandlers.c3
-rw-r--r--usr.sbin/eeprom/optree.c156
6 files changed, 185 insertions, 13 deletions
diff --git a/usr.sbin/eeprom/Makefile b/usr.sbin/eeprom/Makefile
index 76b385eba42..cf17a23d638 100644
--- a/usr.sbin/eeprom/Makefile
+++ b/usr.sbin/eeprom/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.9 2002/12/31 16:22:26 miod Exp $
+# $OpenBSD: Makefile,v 1.10 2007/09/04 23:28:26 fgsch Exp $
.if ${MACHINE} == "sparc" || ${MACHINE} == "sparc64"
PROG= eeprom
@@ -9,7 +9,7 @@ BINMODE=2555
SRCS= eehandlers.c getdate.c main.c
. if ${MACHINE} == "sparc" || ${MACHINE} == "sparc64"
-SRCS+= ophandlers.c
+SRCS+= ophandlers.c optree.c
. endif
CLEANFILES+=getdate.c y.tab.h
diff --git a/usr.sbin/eeprom/defs.h b/usr.sbin/eeprom/defs.h
index 8be7394133a..a5c629e95bb 100644
--- a/usr.sbin/eeprom/defs.h
+++ b/usr.sbin/eeprom/defs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: defs.h,v 1.4 2002/02/17 19:42:36 millert Exp $ */
+/* $OpenBSD: defs.h,v 1.5 2007/09/04 23:28:26 fgsch Exp $ */
/* $NetBSD: defs.h,v 1.2 1996/02/28 01:13:20 thorpej Exp $ */
/*-
@@ -109,5 +109,6 @@ void ee_verifychecksums(void);
#ifdef __sparc__
/* Sparc Openprom handlers. */
char *op_handler(char *, char *);
-void op_dump(void);
+void op_dump(void);
+void op_tree(void);
#endif /* __sparc__ */
diff --git a/usr.sbin/eeprom/eeprom.8 b/usr.sbin/eeprom/eeprom.8
index 7c827113c4a..13ce63875a2 100644
--- a/usr.sbin/eeprom/eeprom.8
+++ b/usr.sbin/eeprom/eeprom.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: eeprom.8,v 1.16 2007/05/31 19:20:23 jmc Exp $
+.\" $OpenBSD: eeprom.8,v 1.17 2007/09/04 23:28:26 fgsch Exp $
.\" $NetBSD: eeprom.8,v 1.2 1996/02/28 01:13:24 thorpej Exp $
.\"
.\" Copyright (c) 1996 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: May 31 2007 $
+.Dd $Mdocdate: September 4 2007 $
.Dt EEPROM 8
.Os
.Sh NAME
@@ -47,6 +47,7 @@
.Op Fl c
.Op Fl f Ar device
.Op Fl i
+.Op Fl p
.Op Fl v
.Op Fl N Ar system
.Oo
@@ -90,6 +91,9 @@ If checksum values are incorrect,
.Nm eeprom
will ignore them and continue after displaying a warning.
This flag is quietly ignored on systems with an OpenPROM.
+.It Fl p
+On systems with an OpenPROM, display the tree derivated from it and exit.
+This flag is quietly ignored on systems with an EEPROM.
.It Fl v
On systems with an OpenPROM, be verbose when setting a value.
Systems with an EEPROM are always verbose.
diff --git a/usr.sbin/eeprom/main.c b/usr.sbin/eeprom/main.c
index 3fdcf072cd6..5b458f66814 100644
--- a/usr.sbin/eeprom/main.c
+++ b/usr.sbin/eeprom/main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: main.c,v 1.13 2005/05/02 02:29:27 djm Exp $ */
+/* $OpenBSD: main.c,v 1.14 2007/09/04 23:28:26 fgsch Exp $ */
/* $NetBSD: main.c,v 1.3 1996/05/16 16:00:55 thorpej Exp $ */
/*-
@@ -41,6 +41,7 @@
#include <err.h>
#include <string.h>
#include <stdio.h>
+#include <stdlib.h>
#include <unistd.h>
#ifdef __sparc__
@@ -51,7 +52,7 @@
#include <machine/openpromio.h>
-static char *system = NULL;
+static char *nlistf = NULL;
#endif /* __sparc__ */
#include <machine/eeprom.h>
@@ -110,6 +111,7 @@ int cksumfail = 0;
u_short writecount;
int eval = 0;
int use_openprom = 0;
+int print_tree = 0;
int verbose = 0;
extern char *__progname;
@@ -121,7 +123,7 @@ main(int argc, char *argv[])
char *cp, line[BUFSIZE];
#ifdef __sparc__
gid_t gid;
- char *optstring = "cf:ivN:-";
+ char *optstring = "cf:ipvN:-";
#else
char *optstring = "cf:i-";
#endif /* __sparc__ */
@@ -144,12 +146,16 @@ main(int argc, char *argv[])
ignore_checksum = 1;
break;
#ifdef __sparc__
+ case 'p':
+ print_tree = 1;
+ break;
+
case 'v':
verbose = 1;
break;
case 'N':
- system = optarg;
+ nlistf = optarg;
break;
#endif /* __sparc__ */
@@ -162,13 +168,17 @@ main(int argc, char *argv[])
argv += optind;
#ifdef __sparc__
- if (system != NULL) {
+ if (nlistf != NULL) {
gid = getgid();
if (setresgid(gid, gid, gid) == -1)
err(1, "setresgid");
}
if (getcputype() != CPU_SUN4)
use_openprom = 1;
+ if (print_tree && use_openprom) {
+ op_tree();
+ exit(0);
+ }
#endif /* __sparc__ */
if (use_openprom == 0) {
@@ -293,7 +303,7 @@ usage(void)
#ifdef __sparc__
fprintf(stderr, "usage: %s %s %s\n", __progname,
- "[-] [-c] [-f device] [-i] [-v]",
+ "[-] [-c] [-f device] [-i] [-p] [-v]",
"[-N system] [field[=value] ...]");
#else
fprintf(stderr, "usage: %s %s\n", __progname,
diff --git a/usr.sbin/eeprom/ophandlers.c b/usr.sbin/eeprom/ophandlers.c
index ec8cddcd218..3fb666d7cbb 100644
--- a/usr.sbin/eeprom/ophandlers.c
+++ b/usr.sbin/eeprom/ophandlers.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ophandlers.c,v 1.9 2005/03/06 16:12:48 miod Exp $ */
+/* $OpenBSD: ophandlers.c,v 1.10 2007/09/04 23:28:26 fgsch Exp $ */
/* $NetBSD: ophandlers.c,v 1.2 1996/02/28 01:13:30 thorpej Exp $ */
/*-
@@ -46,6 +46,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include <vis.h>
#include <machine/eeprom.h>
diff --git a/usr.sbin/eeprom/optree.c b/usr.sbin/eeprom/optree.c
new file mode 100644
index 00000000000..3930fbaddc7
--- /dev/null
+++ b/usr.sbin/eeprom/optree.c
@@ -0,0 +1,156 @@
+/* $OpenBSD: optree.c,v 1.1 2007/09/04 23:28:26 fgsch Exp $ */
+
+/*
+ * Copyright (c) 2007 Federico G. Schwindt <fgsch@openbsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <machine/openpromio.h>
+#include <sys/ioctl.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+extern char *path_openprom;
+
+static void
+op_print(struct opiocdesc *opio, int depth)
+{
+ char *p;
+ int i, special;
+
+ opio->op_name[opio->op_namelen] = '\0';
+ printf("%*s%s: ", depth * 4, " ", opio->op_name);
+ if (opio->op_buflen > 0) {
+ opio->op_buf[opio->op_buflen] = '\0';
+ special = 0;
+
+ for (i = 0; i < opio->op_buflen; i++) {
+ p = &opio->op_buf[i];
+ if ((*p < ' ' || *p > '~') && (*p != '\0' ||
+ (i + 1 < opio->op_buflen &&
+ (*++p < ' ' || *p > '~')))) {
+ special = 1;
+ break;
+ }
+ }
+
+ if (special) {
+ for (i = 0; opio->op_buflen - i >= sizeof(int);
+ i += sizeof(int)) {
+ if (i)
+ printf(".");
+ printf("%08x", *(int *)(long)&opio->op_buf[i]);
+ }
+ if (i < opio->op_buflen) {
+ printf(".");
+ for (; i < opio->op_buflen; i++) {
+ printf("%02x",
+ *(u_char *)&opio->op_buf[i]);
+ }
+ }
+ } else {
+ for (i = 0; i < opio->op_buflen;
+ i += strlen(&opio->op_buf[i]) + 1) {
+ if (i)
+ printf(" + ");
+ printf("'%s'", &opio->op_buf[i]);
+ }
+ }
+ }
+ printf("\n");
+}
+
+void
+op_nodes(int fd, int node, int depth)
+{
+ char op_buf[BUFSIZ * 4];
+ char op_name[BUFSIZ];
+ struct opiocdesc opio;
+
+ opio.op_nodeid = node;
+ opio.op_buf = op_buf;
+ opio.op_name = op_name;
+
+ if (!node) {
+ if (ioctl(fd, OPIOCGETNEXT, &opio) < 0)
+ err(1, "OPIOCGETNEXT");
+ node = opio.op_nodeid;
+ } else
+ printf("\n%*s", depth * 4, " ");
+
+ printf("Node 0x%x\n", node);
+
+ for (;;) {
+ opio.op_buflen = sizeof(op_buf);
+ opio.op_namelen = sizeof(op_name);
+
+ /* Get the next property. */
+ if (ioctl(fd, OPIOCNEXTPROP, &opio) < 0)
+ err(1, "OPIOCNEXTPROP");
+
+ op_buf[opio.op_buflen] = '\0';
+ (void)strlcpy(op_name, op_buf, sizeof(op_name));
+ opio.op_namelen = strlen(op_name);
+
+ /* If it's the last, punt. */
+ if (opio.op_namelen == 0)
+ break;
+
+ bzero(op_buf, sizeof(op_buf));
+ opio.op_buflen = sizeof(op_buf);
+
+ /* And its value. */
+ if (ioctl(fd, OPIOCGET, &opio) < 0)
+ err(1, "OPIOCGET");
+
+ op_print(&opio, depth + 1);
+ }
+
+ /* Get next child. */
+ if (ioctl(fd, OPIOCGETCHILD, &opio) < 0)
+ err(1, "OPIOCGETCHILD");
+ if (opio.op_nodeid)
+ op_nodes(fd, opio.op_nodeid, depth + 1);
+
+ /* Get next node/sibling. */
+ opio.op_nodeid = node;
+ if (ioctl(fd, OPIOCGETNEXT, &opio) < 0)
+ err(1, "OPIOCGETNEXT");
+ if (opio.op_nodeid)
+ op_nodes(fd, opio.op_nodeid, depth);
+}
+
+void
+op_tree(void)
+{
+ int fd;
+
+ if ((fd = open(path_openprom, O_RDONLY, 0640)) < 0)
+ err(1, "open: %s", path_openprom);
+ op_nodes(fd, 0, 0);
+ (void)close(fd);
+}