No empty .Rs/.Re
[netbsd-mini2440.git] / usr.sbin / memswitch / methods.c
blob730f30a5cd498245db6cce99c0731e07a3b151d0
1 /* $NetBSD: methods.c,v 1.5 2002/06/08 17:24:09 yamt Exp $ */
3 /*-
4 * Copyright (c) 1999 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Minoura Makoto.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
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 <stdio.h>
33 #include <string.h>
34 #include <err.h>
35 #include <sys/types.h>
37 #include "memswitch.h"
38 #include "methods.h"
40 int
41 atoi_ (p)
42 const char **p;
44 const char *p1 = *p;
45 int v = 0;
46 int first = 1;
48 while (*p1 == ' ' || *p1 == '\t')
49 p1++;
51 if (*p1 == 0) {
52 *p = 0;
53 return 0;
55 if (strlen (p1) >= 2 && strncasecmp ("0x", p1, 2) == 0) {
56 p1 += 2;
57 while (1) {
58 if (*p1 >= '0' && *p1 <= '9') {
59 v *= 16;
60 v += *p1 - '0';
61 first = 0;
62 } else if (*p1 >= 'A' && *p1 <= 'F') {
63 v *= 16;
64 v += *p1 - 'A' + 10;
65 first = 0;
66 } else if (*p1 >= 'a' && *p1 <= 'f') {
67 v *= 16;
68 v += *p1 - 'a' + 10;
69 first = 0;
70 } else {
71 break;
73 p1++;
75 } else {
76 while (1) {
77 if (*p1 >= '0' && *p1 <= '9') {
78 v *= 10;
79 v += *p1 - '0';
80 first = 0;
81 } else {
82 break;
84 p1++;
88 if (first) {
89 *p = 0;
90 return 0;
93 while (*p1 == ' ' || *p1 == '\t') p1++;
94 *p = p1;
95 return v;
98 int
99 fill_uchar (prop)
100 struct property *prop;
102 if (current_values == 0)
103 alloc_current_values ();
105 prop->current_value.byte[0] = current_values[prop->offset];
106 prop->current_value.byte[1] = 0;
107 prop->current_value.byte[2] = 0;
108 prop->current_value.byte[3] = 0;
109 prop->value_valid = 1;
111 return 0;
115 fill_ushort (prop)
116 struct property *prop;
118 if (current_values == 0)
119 alloc_current_values ();
121 prop->current_value.byte[0] = current_values[prop->offset];
122 prop->current_value.byte[1] = current_values[prop->offset+1];
123 prop->current_value.byte[2] = 0;
124 prop->current_value.byte[3] = 0;
125 prop->value_valid = 1;
127 return 0;
131 fill_ulong (prop)
132 struct property *prop;
134 if (current_values == 0)
135 alloc_current_values ();
137 prop->current_value.byte[0] = current_values[prop->offset];
138 prop->current_value.byte[1] = current_values[prop->offset+1];
139 prop->current_value.byte[2] = current_values[prop->offset+2];
140 prop->current_value.byte[3] = current_values[prop->offset+3];
141 prop->value_valid = 1;
143 return 0;
147 flush_uchar (prop)
148 struct property *prop;
150 if (!prop->modified)
151 return 0;
153 if (modified_values == 0)
154 alloc_modified_values ();
156 modified_values[prop->offset] = prop->modified_value.byte[0];
158 return 0;
162 flush_ushort (prop)
163 struct property *prop;
165 if (!prop->modified)
166 return 0;
168 if (modified_values == 0)
169 alloc_modified_values ();
171 modified_values[prop->offset] = prop->modified_value.byte[0];
172 modified_values[prop->offset+1] = prop->modified_value.byte[1];
174 return 0;
178 flush_ulong (prop)
179 struct property *prop;
181 if (!prop->modified)
182 return 0;
184 if (modified_values == 0)
185 alloc_modified_values ();
187 modified_values[prop->offset] = prop->modified_value.byte[0];
188 modified_values[prop->offset+1] = prop->modified_value.byte[1];
189 modified_values[prop->offset+2] = prop->modified_value.byte[2];
190 modified_values[prop->offset+3] = prop->modified_value.byte[3];
192 return 0;
196 flush_dummy (prop)
197 struct property *prop;
199 return 0;
203 parse_dummy (prop, value)
204 struct property *prop;
205 const char *value;
207 warnx ("Cannot modify %s.%s", prop->class, prop->node);
209 return -1;
213 parse_byte (prop, value)
214 struct property *prop;
215 const char *value;
217 const char *p = value;
218 int v;
220 v = atoi_ (&p);
221 if (p == 0) {
222 warnx ("%s: Invalid value", value);
223 return -1;
226 if (strcasecmp ("MB", p) == 0)
227 v *= 1024 * 1024;
228 else if (strcasecmp ("KB", p) == 0)
229 v *= 1024;
230 else if (*p != 0 &&
231 strcasecmp ("B", p) != 0) {
232 warnx ("%s: Invalid value", value);
233 return -1;
236 if (v < prop->min) {
237 warnx ("%s: Too small", value);
238 return -1;
239 } else if (v > prop->max) {
240 warnx ("%s: Too large", value);
241 return -1;
244 prop->modified = 1;
245 prop->modified_value.longword = v;
247 return 0;
251 parse_uchar (prop, value)
252 struct property *prop;
253 const char *value;
255 const char *p = value;
256 int v;
258 v = atoi_ (&p);
259 if (p == 0) {
260 warnx ("%s: Invalid value", value);
261 return -1;
264 if (v < prop->min) {
265 warnx ("%s: Too small", value);
266 return -1;
267 } else if (v > prop->max) {
268 warnx ("%s: Too large", value);
269 return -1;
272 prop->modified = 1;
273 prop->modified_value.byte[0] = v;
275 return 0;
279 parse_ulong (prop, value)
280 struct property *prop;
281 const char *value;
283 const char *p = value;
284 int v;
286 v = atoi_ (&p);
287 if (p == 0) {
288 warnx ("%s: Invalid value", value);
289 return -1;
292 if (v < prop->min) {
293 warnx ("%s: Too small", value);
294 return -1;
295 } else if (v > prop->max) {
296 warnx ("%s: Too large", value);
297 return -1;
300 prop->modified = 1;
301 prop->modified_value.longword = v;
303 return 0;
307 parse_ushort (prop, value)
308 struct property *prop;
309 const char *value;
311 const char *p = value;
312 int v;
314 v = atoi_ (&p);
315 if (p == 0) {
316 warnx ("%s: Invalid value", value);
317 return -1;
320 if (v < prop->min) {
321 warnx ("%s: Too small", value);
322 return -1;
323 } else if (v > prop->max) {
324 warnx ("%s: Too large", value);
325 return -1;
328 prop->modified = 1;
329 prop->modified_value.word[0] = v;
331 return 0;
335 parse_time (prop, value)
336 struct property *prop;
337 const char *value;
339 const char *p = value;
340 int v;
342 while (*p == ' ' || *p == '\t') p++;
343 if (*p == '-') {
344 p++;
345 v = -atoi_ (&p);
346 } else
347 v = atoi_ (&p);
348 if (p == 0) {
349 warnx ("%s: Invalid value", value);
350 return -1;
353 if (strcasecmp ("hours", p) == 0 || strcasecmp ("hour", p) == 0)
354 v *= 60 * 60;
355 else if (strcasecmp ("minutes", p) == 0 ||
356 strcasecmp ("minute", p) == 0)
357 v *= 60;
358 else if (*p != 0 &&
359 strcasecmp ("second", p) != 0 &&
360 strcasecmp ("seconds", p) != 0) {
361 warnx ("%s: Invalid value", value);
362 return -1;
365 if (v < prop->min) {
366 warnx ("%s: Too small", value);
367 return -1;
368 } else if (v > prop->max) {
369 warnx ("%s: Too large", value);
370 return -1;
373 prop->modified = 1;
374 prop->modified_value.longword = v;
376 return 0;
380 parse_bootdev (prop, value)
381 struct property *prop;
382 const char *value;
384 const char *p = value;
385 int v;
386 char expr_scsi[32];
388 while (*p == ' ' || *p == '\t') p++;
390 if (strcasecmp ("STD", p) == 0)
391 v = 0;
392 else if (strcasecmp ("ROM", p) == 0)
393 v = 0xa000;
394 else if (strcasecmp ("RAM", p) == 0)
395 v = 0xb000;
396 else if (strncasecmp ("HD", p, 2) == 0) {
397 p += 2;
398 v = atoi_ (&p);
399 if (p == 0 || v < 0 || v > 15) {
400 warnx ("%s: Invalid value", value);
401 return -1;
403 v *= 0x0100;
404 v += 0x8000;
405 } else if (strncasecmp ("FD", p, 2) == 0) {
406 p += 2;
407 v = atoi_ (&p);
408 if (p == 0 || v < 0 || v > 3) {
409 warnx ("%s: Invalid value", value);
410 return -1;
412 v *= 0x0100;
413 v += 0x9070;
414 } else if (strncasecmp ("INSCSI", p, 6) == 0 ||
415 strncasecmp ("EXSCSI", p, 6) == 0) {
416 int isin = strncasecmp ("EXSCSI", p, 6);
418 p += 6;
419 v = atoi_ (&p);
420 if (p == 0 || v < 0 || v > 7) {
421 warnx ("%s: Invalid value", value);
422 return -1;
425 /* change boot.romaddr */
426 sprintf(expr_scsi, "boot.romaddr=0x%06x",
427 (isin ? 0xfc0000 : 0xea0020) + v * 4);
428 modify_single(expr_scsi);
430 /* boot.device again */
431 v = 0xa000;
432 } else {
433 warnx ("%s: Invalid value", value);
434 return -1;
437 prop->modified = 1;
438 prop->modified_value.word[0] = v;
440 return 0;
444 parse_serial (prop, value)
445 struct property *prop;
446 const char *value;
447 #define NEXTSPEC while (*p == ' ' || *p == '\t') p++; \
448 if (*p++ != ',') { \
449 warnx ("%s: Invalid value", value); \
450 return -1; \
452 while (*p == ' ' || *p == '\t') p++;
454 const char *p = value;
455 const char *q;
456 int baud, bit, parity, stop, flow;
457 static const int bauds[] = {75, 150, 300, 600, 1200, 2400, 4800, 9600,
458 17361, 0};
459 static const char parities[] = "noe";
460 int i;
462 while (*p == ' ' || *p == '\t') p++;
464 /* speed */
465 baud = atoi_ (&p);
466 if (p == 0) {
467 warnx ("%s: Invalid value", value);
468 return -1;
470 for (i = 0; bauds[i]; i++)
471 if (baud == bauds[i])
472 break;
473 if (bauds[i] == 0) {
474 warnx ("%d: Invalid speed", baud);
475 return -1;
477 baud = i;
479 NEXTSPEC;
481 /* bit size */
482 if (*p < '5' || *p > '8') {
483 warnx ("%c: Invalid bit size", *p);
484 return -1;
486 bit = *p++ - '5';
488 NEXTSPEC;
490 /* parity */
491 q = strchr(parities, *p++);
492 if (q == 0) {
493 warnx ("%c: Invalid parity spec", *p);
494 return -1;
496 parity = q - parities;
498 NEXTSPEC;
500 /* stop bit */
501 if (strncmp (p, "1.5", 3) == 0) {
502 stop = 2;
503 p += 3;
504 } else if (strncmp (p, "2", 1) == 0) {
505 stop = 0;
506 p++;
507 } else if (strncmp (p, "1", 1) == 0) {
508 stop = 1;
509 p++;
510 } else {
511 warnx ("%s: Invalid value", value);
512 return -1;
515 NEXTSPEC;
517 /* flow */
518 if (*p == '-')
519 flow = 0;
520 else if (*p == 's')
521 flow = 1;
522 else {
523 warnx ("%s: Invalid value", value);
524 return -1;
527 p++;
528 while (*p == ' ' || *p == '\t') p++;
529 if (*p != 0) {
530 warnx ("%s: Invalid value", value);
531 return -1;
534 prop->modified = 1;
535 prop->modified_value.word[0] = ((stop << 14) +
536 (parity << 12) +
537 (bit << 10) +
538 (flow << 9) +
539 baud);
541 return 0;
543 #undef NEXTSPEC
546 parse_srammode (prop, value)
547 struct property *prop;
548 const char *value;
550 static const char *const sramstrs[] = {"unused", "SRAMDISK", "program"};
551 int i;
553 for (i = 0; i <= 2; i++) {
554 if (strcasecmp (value, sramstrs[i]) == 0)
555 break;
557 if (i > 2) {
558 warnx ("%s: Invalid value", value);
559 return -1;
562 prop->modified = 1;
563 prop->modified_value.byte[0] = i;
565 return 0;
569 print_uchar (prop, str)
570 struct property *prop;
571 char *str;
573 if (prop->modified)
574 snprintf (str, MAXVALUELEN,
575 "%d", prop->modified_value.byte[0]);
576 else {
577 if (!prop->value_valid)
578 prop->fill (prop);
579 snprintf (str, MAXVALUELEN, "%d",
580 prop->current_value.byte[0]);
583 return 0;
587 print_ucharh (prop, str)
588 struct property *prop;
589 char *str;
591 if (prop->modified)
592 snprintf (str, MAXVALUELEN,
593 "0x%4.4x", prop->modified_value.byte[0]);
594 else {
595 if (!prop->value_valid)
596 prop->fill (prop);
597 snprintf (str, MAXVALUELEN,
598 "0x%4.4x", prop->current_value.byte[0]);
601 return 0;
605 print_ushorth (prop, str)
606 struct property *prop;
607 char *str;
609 if (prop->modified)
610 snprintf (str, MAXVALUELEN,
611 "0x%4.4x", prop->modified_value.word[0]);
612 else {
613 if (!prop->value_valid)
614 prop->fill (prop);
615 snprintf (str, MAXVALUELEN,
616 "0x%4.4x", prop->current_value.word[0]);
619 return 0;
623 print_ulong (prop, str)
624 struct property *prop;
625 char *str;
627 if (prop->modified)
628 snprintf (str, MAXVALUELEN,
629 "%ld", prop->modified_value.longword);
630 else {
631 if (!prop->value_valid)
632 prop->fill (prop);
633 snprintf (str, MAXVALUELEN,
634 "%ld", prop->current_value.longword);
637 return 0;
641 print_ulongh (prop, str)
642 struct property *prop;
643 char *str;
645 if (prop->modified)
646 snprintf (str, MAXVALUELEN,
647 "0x%8.8lx", prop->modified_value.longword);
648 else {
649 if (!prop->value_valid)
650 prop->fill (prop);
651 snprintf (str, MAXVALUELEN,
652 "0x%8.8lx", prop->current_value.longword);
655 return 0;
659 print_magic (prop, str)
660 struct property *prop;
661 char *str;
663 if (!prop->value_valid)
664 prop->fill (prop);
665 snprintf (str, MAXVALUELEN, "%c%c%c%c",
666 prop->current_value.byte[0],
667 prop->current_value.byte[1],
668 prop->current_value.byte[2],
669 prop->current_value.byte[3]);
671 return 0;
675 print_timesec (prop, str)
676 struct property *prop;
677 char *str;
679 if (prop->modified)
680 snprintf (str, MAXVALUELEN,
681 "%ld second", prop->modified_value.longword);
682 else {
683 if (!prop->value_valid)
684 prop->fill (prop);
685 snprintf (str, MAXVALUELEN,
686 "%ld second", prop->current_value.longword);
689 return 0;
693 print_bootdev (prop, str)
694 struct property *prop;
695 char *str;
697 unsigned int v;
699 if (prop->modified)
700 v = prop->modified_value.word[0];
701 else {
702 if (!prop->value_valid)
703 prop->fill (prop);
704 v = prop->current_value.word[0];
707 if (v == 0)
708 strcpy (str, "STD");
709 else if (v == 0xa000)
710 strcpy (str, "ROM");
711 else if (v == 0xb000)
712 strcpy (str, "RAM");
713 else if (v >= 0x8000 && v < 0x9000)
714 snprintf (str, MAXVALUELEN, "HD%d", (v & 0x0f00) >> 8);
715 else if (v >= 0x9000 && v < 0xa000)
716 snprintf (str, MAXVALUELEN, "FD%d", (v & 0x0f00) >> 8);
717 else
718 snprintf (str, MAXVALUELEN, "%8.8x", v);
720 return 0;
724 print_serial (prop, str)
725 struct property *prop;
726 char *str;
728 unsigned int v;
729 const char *baud, *stop;
730 char bit, parity, flow;
731 static const char *const bauds[] = {"75", "150", "300", "600", "1200",
732 "2400", "4800", "9600", "17361"};
733 static const char bits[] = "5678";
734 static const char parities[] = "noen";
735 static const char *const stops[] = {"2", "1", "1.5", "2"};
736 static const char flows[] = "-s";
738 if (prop->modified)
739 v = prop->modified_value.word[0];
740 else {
741 if (!prop->value_valid)
742 prop->fill (prop);
743 v = prop->current_value.word[0];
746 baud = bauds[v & 0x000f];
747 bit = bits[(v & 0x0c00) >> 10];
748 parity = parities[(v & 0x3000) >> 12];
749 stop = stops[(v & 0xe000) >> 14];
750 flow = flows[(v & 0x0200) >> 9];
751 sprintf (str, "%s,%c,%c,%s,%c", baud, bit, parity, stop, flow);
753 return 0;
757 print_srammode (prop, str)
758 struct property *prop;
759 char *str;
761 int v;
762 static const char *const sramstrs[] = {"unused", "SRAMDISK", "program"};
764 if (prop->modified)
765 v = prop->modified_value.byte[0];
766 else {
767 if (!prop->value_valid)
768 prop->fill (prop);
769 v = prop->current_value.byte[0];
772 if (v < 0 || v > 2)
773 strcpy (str, "INVALID");
774 else
775 strcpy (str, sramstrs[v]);
777 return 0;