1 /* $NetBSD: prephandlers.c,v 1.1 2007/03/01 16:49:48 garbled Exp $ */
4 * Copyright (c) 2006 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/types.h>
33 #include <sys/ioctl.h>
42 #include <machine/nvram.h>
46 extern char *path_prepnvram
;
50 static char err_str
[BUFSIZE
];
52 static void prep_notsupp(struct extabent
*, struct pnviocdesc
*, char *);
56 * This file needs a recalc checksum routine, and a routine to call a
57 * write back to nvram. The prep NVRAM is stored in RAM after boot, to
58 * prevent horrific bitbanging on the NVRAM chip, we read and write into RAM
59 * until a save operation is called. At that time we write the ram-based
60 * NVRAM back to the physical NVRAM. This is a fairly expensive operation.
65 * There are several known fields that I either don't know how to
66 * deal with or require special treatment.
68 static struct extabent prepextab
[] = {
71 #define BARF(str1, str2) { \
72 snprintf(err_str, sizeof err_str, "%s: %s", (str1), (str2)); \
78 prep_action(char *keyword
, char *arg
)
82 if ((cp
= prep_handler(keyword
, arg
)) != NULL
)
88 prep_handler(char *keyword
, char *arg
)
90 struct pnviocdesc nvio
;
92 char nvio_buf
[BUFSIZE
];
95 if ((fd
= open(path_prepnvram
, arg
? O_RDWR
: O_RDONLY
, 0640)) < 0)
96 BARF(path_prepnvram
, strerror(errno
));
98 /* Check to see if it's a special-case keyword. */
99 for (ex
= prepextab
; ex
->ex_keyword
!= NULL
; ++ex
)
100 if (strcmp(ex
->ex_keyword
, keyword
) == 0)
103 memset(&nvio_buf
[0], 0, sizeof(nvio_buf
));
104 memset(&nvio
, 0, sizeof(nvio
));
105 nvio
.pnv_name
= keyword
;
106 nvio
.pnv_namelen
= strlen(nvio
.pnv_name
);
112 nvio
.pnv_buf
= &nvio_buf
[0];
113 nvio
.pnv_buflen
= sizeof(nvio_buf
);
114 if (ioctl(fd
, PNVIOCGET
, (char *) &nvio
) < 0)
115 BARF("PNVIOCGET", strerror(errno
));
117 if (nvio
.pnv_buflen
<= 0) {
118 printf("nothing available for %s\n", keyword
);
121 if (ex
->ex_keyword
!= NULL
)
122 (*ex
->ex_handler
) (ex
, &nvio
, NULL
);
124 printf("%s\n", nvio
.pnv_buf
);
127 if (ex
->ex_keyword
!= NULL
)
128 (*ex
->ex_handler
) (ex
, &nvio
, arg
);
131 nvio
.pnv_buflen
= strlen(arg
);
134 if (ioctl(fd
, PNVIOCSET
, (char *) &nvio
) < 0)
135 BARF("invalid keyword", keyword
);
139 if (ex
->ex_keyword
!= NULL
)
140 (*ex
->ex_handler
) (ex
, &nvio
, NULL
);
142 printf("%s\n", nvio
.pnv_buf
);
145 nvio
.pnv_buf
= &nvio_buf
[0];
146 nvio
.pnv_buflen
= sizeof(nvio_buf
);
147 if (ioctl(fd
, PNVIOCGET
, (char *) &nvio
) < 0)
148 BARF("PNVIOCGET", strerror(errno
));
150 if (nvio
.pnv_buflen
<= 0) {
151 (void) snprintf(err_str
, sizeof err_str
,
152 "nothing available for %s", keyword
);
155 if (ex
->ex_keyword
!= NULL
)
156 (*ex
->ex_handler
) (ex
, &nvio
, NULL
);
158 printf("%s=%s\n", keyword
, nvio
.pnv_buf
);
166 prep_notsupp(struct extabent
* exent
, struct pnviocdesc
* nviop
, char *arg
)
169 warnx("property `%s' not yet supported", exent
->ex_keyword
);
172 * Derrived from op_dump(). This should dump the contents of the PReP
179 struct pnviocdesc nvio1
, nvio2
;
180 char buf1
[BUFSIZE
], buf2
[BUFSIZE
], buf3
[BUFSIZE
], buf4
[BUFSIZE
];
181 int fd
, optnode
, nrofvars
;
183 if ((fd
= open(path_prepnvram
, O_RDONLY
, 0640)) < 0)
184 err(1, "open: %s", path_prepnvram
);
186 memset(&nvio1
, 0, sizeof(nvio1
));
188 if (ioctl(fd
, PNVIOCGETNUMGE
, (char *) &nvio1
) < 0)
189 err(1, "PNVIOCGETNUMGE");
191 nrofvars
= nvio1
.pnv_num
;
193 err(1, "PNVIOCGETNUMGE");
195 memset(&nvio1
, 0, sizeof(nvio1
));
196 memset(buf1
, 0, sizeof(buf1
));
197 memset(buf2
, 0, sizeof(buf2
));
198 memset(buf3
, 0, sizeof(buf3
));
199 memset(buf4
, 0, sizeof(buf4
));
200 nvio1
.pnv_name
= NULL
;
201 nvio1
.pnv_buf
= buf2
;
202 nvio2
.pnv_name
= buf3
;
203 nvio2
.pnv_buf
= buf4
;
204 for (optnode
= 0; optnode
< nrofvars
; optnode
++) {
205 nvio1
.pnv_buflen
= sizeof(buf2
);
207 if (ioctl(fd
, PNVIOCGETNEXTNAME
, (char *) &nvio1
) < 0)
208 err(1, "PNVIOCGETNEXTNAME");
211 nvio1
.pnv_name
= buf1
;
213 /* the property name is now stored in nvio1.pnv_buf */
214 strcpy(nvio2
.pnv_name
, nvio1
.pnv_buf
); /* safe */
215 nvio2
.pnv_namelen
= strlen(nvio2
.pnv_name
);
217 if (nvio2
.pnv_namelen
== 0) {
221 memset(nvio2
.pnv_buf
, 0, sizeof(buf4
));
222 nvio2
.pnv_buflen
= sizeof(buf4
);
224 if (ioctl(fd
, PNVIOCGET
, (char *) &nvio2
) < 0)
227 printf("%s=%s\n", nvio1
.pnv_buf
, nvio2
.pnv_buf
);
229 /* now clean out the buffers for the next loop */
231 memset(nvio1
.pnv_name
, 0, sizeof(buf1
));
232 memset(nvio1
.pnv_buf
, 0, sizeof(buf2
));
233 strcpy(nvio1
.pnv_name
, nvio2
.pnv_name
); /* safe */
234 nvio1
.pnv_namelen
= strlen(nvio1
.pnv_name
);