Bug Summary

File:kern/subr_userconf.c
Warning:line 1002, column 3
Value stored to 'i' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name subr_userconf.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -target-feature +retpoline-external-thunk -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/llvm16/lib/clang/16 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/legacy-dpm -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu13 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/inc -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc/pmfw_if -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D SUSPEND -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /home/ben/Projects/scan/2024-01-11-110808-61670-1 -x c /usr/src/sys/kern/subr_userconf.c
1/* $OpenBSD: subr_userconf.c,v 1.48 2022/08/14 01:58:28 jsg Exp $ */
2
3/*
4 * Copyright (c) 1996-2001 Mats O Jansson <moj@stacken.kth.se>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
17 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <sys/param.h>
30#include <sys/systm.h>
31#include <sys/device.h>
32#include <sys/malloc.h>
33
34#include <dev/cons.h>
35
36extern char *locnames[];
37extern short locnamp[];
38extern short cfroots[];
39extern int cfroots_size;
40extern int pv_size;
41extern short pv[];
42extern char *pdevnames[];
43extern int pdevnames_size;
44extern struct pdevinit pdevinit[];
45
46int userconf_base = 16; /* Base for "large" numbers */
47int userconf_maxdev = -1; /* # of used device slots */
48int userconf_totdev = -1; /* # of device slots */
49int userconf_maxlocnames = -1; /* # of locnames */
50int userconf_cnt = -1; /* Line counter for ... */
51int userconf_lines = 12; /* ... # of lines per page */
52int userconf_histlen = 0;
53int userconf_histcur = 0;
54char userconf_history[1024];
55int userconf_histsz = sizeof(userconf_history);
56char userconf_argbuf[40]; /* Additional input */
57char userconf_cmdbuf[40]; /* Command line */
58char userconf_histbuf[40];
59
60void userconf_init(void);
61int userconf_more(void);
62void userconf_modify(char *, long *, long);
63void userconf_hist_cmd(char);
64void userconf_hist_int(long);
65void userconf_hist_eoc(void);
66void userconf_pnum(long);
67void userconf_pdevnam(short);
68void userconf_pdev(short);
69int userconf_number(char *, long *, long);
70int userconf_device(char *, long *, short *, short *);
71int userconf_attr(char *, long *);
72void userconf_change(int);
73void userconf_disable(int);
74void userconf_enable(int);
75void userconf_help(void);
76void userconf_list(void);
77void userconf_show(void);
78void userconf_common_attr_val(short, long *, char);
79void userconf_show_attr(char *);
80void userconf_common_dev(char *, int, short, short, char);
81void userconf_common_attr(char *, int, char);
82void userconf_add_read(char *, char, char *, int, long *);
83void userconf_add(char *, int, short, short);
84int userconf_parse(char *);
85
86#define UC_CHANGE'c' 'c'
87#define UC_DISABLE'd' 'd'
88#define UC_ENABLE'e' 'e'
89#define UC_FIND'f' 'f'
90#define UC_SHOW's' 's'
91
92char *userconf_cmds[] = {
93 "add", "a",
94 "base", "b",
95 "change", "c",
96#if defined(DDB1)
97 "ddb", "D",
98#endif
99 "disable", "d",
100 "enable", "e",
101 "exit", "q",
102 "find", "f",
103 "help", "h",
104 "list", "l",
105 "lines", "L",
106 "quit", "q",
107 "show", "s",
108 "verbose", "v",
109 "?", "h",
110 "", "",
111};
112
113void
114userconf_init(void)
115{
116 int i = 0;
117 struct cfdata *cd;
118 int ln;
119
120 while (cfdata[i].cf_attach != NULL((void *)0)) {
121 userconf_maxdev = i;
122 userconf_totdev = i;
123
124 cd = &cfdata[i];
125 ln = cd->cf_locnames;
126 while (locnamp[ln] != -1) {
127 if (locnamp[ln] > userconf_maxlocnames)
128 userconf_maxlocnames = locnamp[ln];
129 ln++;
130 }
131 i++;
132 }
133
134 while (cfdata[i].cf_attach == NULL((void *)0)) {
135 userconf_totdev = i;
136 i++;
137 }
138 userconf_totdev = userconf_totdev - 1;
139}
140
141int
142userconf_more(void)
143{
144 int quit = 0;
145 char c = '\0';
146
147 if (userconf_cnt != -1) {
148 if (userconf_cnt == userconf_lines) {
149 printf("--- more ---");
150 c = cngetc();
151 userconf_cnt = 0;
152 printf("\r \r");
153 }
154 userconf_cnt++;
155 if (c == 'q' || c == 'Q')
156 quit = 1;
157 }
158 return (quit);
159}
160
161void
162userconf_hist_cmd(char cmd)
163{
164 userconf_histcur = userconf_histlen;
165 if (userconf_histcur < userconf_histsz) {
166 userconf_history[userconf_histcur] = cmd;
167 userconf_histcur++;
168 }
169}
170
171void
172userconf_hist_int(long val)
173{
174 snprintf(userconf_histbuf, sizeof userconf_histbuf, " %ld", val);
175 if (userconf_histcur + strlen(userconf_histbuf) < userconf_histsz) {
176 bcopy(userconf_histbuf,
177 &userconf_history[userconf_histcur],
178 strlen(userconf_histbuf));
179 userconf_histcur = userconf_histcur + strlen(userconf_histbuf);
180 }
181}
182
183void
184userconf_hist_eoc(void)
185{
186 if (userconf_histcur < userconf_histsz) {
187 userconf_history[userconf_histcur] = '\n';
188 userconf_histcur++;
189 userconf_histlen = userconf_histcur;
190 }
191}
192
193void
194userconf_pnum(long val)
195{
196 if (val > -2 && val < 16) {
197 printf("%ld",val);
198 return;
199 }
200
201 switch (userconf_base) {
202 case 8:
203 printf("0%lo",val);
204 break;
205 case 10:
206 printf("%ld",val);
207 break;
208 case 16:
209 default:
210 printf("0x%lx",val);
211 break;
212 }
213}
214
215void
216userconf_pdevnam(short dev)
217{
218 struct cfdata *cd;
219
220 cd = &cfdata[dev];
221 printf("%s", cd->cf_driver->cd_name);
222 switch (cd->cf_fstate) {
223 case FSTATE_NOTFOUND0:
224 case FSTATE_DNOTFOUND3:
225 printf("%d", cd->cf_unit);
226 break;
227 case FSTATE_FOUND1:
228 printf("*FOUND*");
229 break;
230 case FSTATE_STAR2:
231 case FSTATE_DSTAR4:
232 printf("*");
233 break;
234 default:
235 printf("*UNKNOWN*");
236 break;
237 }
238}
239
240void
241userconf_pdev(short devno)
242{
243 struct cfdata *cd;
244 short *p;
245 long *l;
246 int ln;
247 char c;
248
249 if (devno > userconf_maxdev && devno <= userconf_totdev) {
250 printf("%3d free slot (for add)\n", devno);
251 return;
252 }
253
254 if (devno > userconf_totdev &&
255 devno <= userconf_totdev+pdevnames_size) {
256 printf("%3d %s count %d", devno,
257 pdevnames[devno-userconf_totdev-1],
258 abs(pdevinit[devno-userconf_totdev-1].pdev_count));
259 if (pdevinit[devno-userconf_totdev-1].pdev_count < 1)
260 printf(" disable");
261 printf(" (pseudo device)\n");
262 return;
263 }
264
265 if (devno > userconf_maxdev) {
266 printf("Unknown devno (max is %d)\n", userconf_maxdev);
267 return;
268 }
269
270 cd = &cfdata[devno];
271
272 printf("%3d ", devno);
273 userconf_pdevnam(devno);
274 printf(" at");
275 c = ' ';
276 p = cd->cf_parents;
277 if (*p == -1)
278 printf(" root");
279 while (*p != -1) {
280 printf("%c", c);
281 userconf_pdevnam(*p++);
282 c = '|';
283 }
284 switch (cd->cf_fstate) {
285 case FSTATE_NOTFOUND0:
286 case FSTATE_FOUND1:
287 case FSTATE_STAR2:
288 break;
289 case FSTATE_DNOTFOUND3:
290 case FSTATE_DSTAR4:
291 printf(" disable");
292 break;
293 default:
294 printf(" ???");
295 break;
296 }
297 l = cd->cf_loc;
298 ln = cd->cf_locnames;
299 while (locnamp[ln] != -1) {
300 printf(" %s ", locnames[locnamp[ln]]);
301 ln++;
302 userconf_pnum(*l++);
303 }
304 printf(" flags 0x%x\n", cd->cf_flags);
305}
306
307int
308userconf_number(char *c, long *val, long limit)
309{
310 u_long num = 0;
311 int neg = 0;
312 int base = 10;
313
314 if (*c == '-') {
315 neg = 1;
316 c++;
317 }
318 if (*c == '0') {
319 base = 8;
320 c++;
321 if (*c == 'x' || *c == 'X') {
322 base = 16;
323 c++;
324 }
325 }
326 while (*c != '\n' && *c != '\t' && *c != ' ' && *c != '\0') {
327 u_char cc = *c;
328
329 if (cc >= '0' && cc <= '9')
330 cc = cc - '0';
331 else if (cc >= 'a' && cc <= 'f')
332 cc = cc - 'a' + 10;
333 else if (cc >= 'A' && cc <= 'F')
334 cc = cc - 'A' + 10;
335 else
336 return (-1);
337
338 if (cc > base)
339 return (-1);
340 num = num * base + cc;
341 c++;
342 }
343
344 if (neg && num > limit) /* overflow */
345 return (1);
346 *val = neg ? - num : num;
347 return (0);
348}
349
350int
351userconf_device(char *cmd, long *len, short *unit, short *state)
352{
353 short u = 0, s = FSTATE_FOUND1;
354 int l = 0;
355 char *c;
356
357 c = cmd;
358 while (*c >= 'a' && *c <= 'z') {
359 l++;
360 c++;
361 }
362 if (*c == '*') {
363 s = FSTATE_STAR2;
364 c++;
365 } else {
366 while (*c >= '0' && *c <= '9') {
367 s = FSTATE_NOTFOUND0;
368 u = u*10 + *c - '0';
369 c++;
370 }
371 }
372 while (*c == ' ' || *c == '\t' || *c == '\n')
373 c++;
374
375 if (*c == '\0') {
376 *len = l;
377 *unit = u;
378 *state = s;
379 return(0);
380 }
381
382 return(-1);
383}
384
385int
386userconf_attr(char *cmd, long *val)
387{
388 char *c;
389 short attr = -1, i = 0, l = 0;
390
391 c = cmd;
392 while (*c != ' ' && *c != '\t' && *c != '\n' && *c != '\0') {
393 c++;
394 l++;
395 }
396
397 while (i <= userconf_maxlocnames) {
398 if (strlen(locnames[i]) == l) {
399 if (strncasecmp(cmd, locnames[i], l) == 0)
400 attr = i;
401 }
402 i++;
403 }
404
405 if (attr == -1) {
406 return (-1);
407 }
408
409 *val = attr;
410
411 return(0);
412}
413
414void
415userconf_modify(char *item, long *val, long limit)
416{
417 int ok = 0;
418 long a;
419 char *c;
420 int i;
421
422 while (!ok) {
423 printf("%s [", item);
424 userconf_pnum(*val);
425 printf("] ? ");
426
427 i = getsn(userconf_argbuf, sizeof(userconf_argbuf));
428
429 c = userconf_argbuf;
430 while (*c == ' ' || *c == '\t' || *c == '\n') c++;
431
432 if (*c != '\0') {
433 if (userconf_number(c, &a, limit) == 0) {
434 *val = a;
435 ok = 1;
436 } else {
437 printf("Unknown argument\n");
438 }
439 } else {
440 ok = 1;
441 }
442 }
443}
444
445void
446userconf_change(int devno)
447{
448 struct cfdata *cd;
449 char c = '\0';
450 long *l, tmp;
451 int ln;
452
453 if (devno <= userconf_maxdev) {
454 userconf_pdev(devno);
455
456 while (c != 'y' && c != 'Y' && c != 'n' && c != 'N') {
457 printf("change (y/n) ?");
458 c = cngetc();
459 printf("\n");
460 }
461
462 if (c == 'y' || c == 'Y') {
463 int share = 0, i, lklen;
464 long *lk;
465
466 /* XXX add cmd 'c' <devno> */
467 userconf_hist_cmd('c');
468 userconf_hist_int(devno);
469
470 cd = &cfdata[devno];
471 l = cd->cf_loc;
472 ln = cd->cf_locnames;
473
474 /*
475 * Search for some other driver sharing this
476 * locator table. if one does, we may need to
477 * replace the locators with a malloc'd copy.
478 */
479 for (i = 0; cfdata[i].cf_driver; i++)
480 if (i != devno && cfdata[i].cf_loc == l)
481 share = 1;
482 if (share) {
483 for (i = 0; locnamp[ln+i] != -1 ; i++)
484 ;
485 lk = l = mallocarray(i, sizeof(long),
486 M_TEMP127, M_NOWAIT0x0002);
487 if (lk == NULL((void *)0)) {
488 printf("out of memory.\n");
489 return;
490 }
491 lklen = i * sizeof(long);
492 bcopy(cd->cf_loc, l, lklen);
493 }
494
495 while (locnamp[ln] != -1) {
496 userconf_modify(locnames[locnamp[ln]], l,
497 LONG_MAX0x7fffffffffffffffL);
498
499 /* XXX add *l */
500 userconf_hist_int(*l);
501
502 ln++;
503 l++;
504 }
505 tmp = cd->cf_flags;
506 userconf_modify("flags", &tmp, INT_MAX0x7fffffff);
507 userconf_hist_int(tmp);
508 cd->cf_flags = tmp;
509
510 if (share) {
511 if (memcmp(cd->cf_loc, lk, lklen)__builtin_memcmp((cd->cf_loc), (lk), (lklen)))
512 cd->cf_loc = lk;
513 else
514 free(lk, M_TEMP127, lklen);
515 }
516
517 printf("%3d ", devno);
518 userconf_pdevnam(devno);
519 printf(" changed\n");
520 userconf_pdev(devno);
521 }
522 return;
523 }
524
525 if (devno > userconf_maxdev && devno <= userconf_totdev) {
526 printf("%3d can't change free slot\n", devno);
527 return;
528 }
529
530 if (devno > userconf_totdev &&
531 devno <= userconf_totdev+pdevnames_size) {
532 userconf_pdev(devno);
533 while (c != 'y' && c != 'Y' && c != 'n' && c != 'N') {
534 printf("change (y/n) ?");
535 c = cngetc();
536 printf("\n");
537 }
538
539 if (c == 'y' || c == 'Y') {
540 /* XXX add cmd 'c' <devno> */
541 userconf_hist_cmd('c');
542 userconf_hist_int(devno);
543
544 tmp = pdevinit[devno-userconf_totdev-1].pdev_count;
545 userconf_modify("count", &tmp, INT_MAX0x7fffffff);
546 userconf_hist_int(tmp);
547 pdevinit[devno-userconf_totdev-1].pdev_count = tmp;
548
549 printf("%3d %s changed\n", devno,
550 pdevnames[devno-userconf_totdev-1]);
551 userconf_pdev(devno);
552
553 /* XXX add eoc */
554 userconf_hist_eoc();
555 }
556 return;
557 }
558
559 printf("Unknown devno (max is %d)\n", userconf_totdev+pdevnames_size);
560}
561
562void
563userconf_disable(int devno)
564{
565 int done = 0;
566
567 if (devno <= userconf_maxdev) {
568 switch (cfdata[devno].cf_fstate) {
569 case FSTATE_NOTFOUND0:
570 cfdata[devno].cf_fstate = FSTATE_DNOTFOUND3;
571 break;
572 case FSTATE_STAR2:
573 cfdata[devno].cf_fstate = FSTATE_DSTAR4;
574 break;
575 case FSTATE_DNOTFOUND3:
576 case FSTATE_DSTAR4:
577 done = 1;
578 break;
579 default:
580 printf("Error unknown state\n");
581 break;
582 }
583
584 printf("%3d ", devno);
585 userconf_pdevnam(devno);
586 if (done) {
587 printf(" already");
588 } else {
589 /* XXX add cmd 'd' <devno> eoc */
590 userconf_hist_cmd('d');
591 userconf_hist_int(devno);
592 userconf_hist_eoc();
593 }
594 printf(" disabled\n");
595
596 return;
597 }
598
599 if (devno > userconf_maxdev && devno <= userconf_totdev) {
600 printf("%3d can't disable free slot\n", devno);
601 return;
602 }
603
604 if (devno > userconf_totdev &&
605 devno <= userconf_totdev+pdevnames_size) {
606 printf("%3d %s", devno, pdevnames[devno-userconf_totdev-1]);
607 if (pdevinit[devno-userconf_totdev-1].pdev_count < 1) {
608 printf(" already ");
609 } else {
610 pdevinit[devno-userconf_totdev-1].pdev_count *= -1;
611 /* XXX add cmd 'd' <devno> eoc */
612 userconf_hist_cmd('d');
613 userconf_hist_int(devno);
614 userconf_hist_eoc();
615 }
616 printf(" disabled\n");
617 return;
618 }
619
620 printf("Unknown devno (max is %d)\n", userconf_totdev+pdevnames_size);
621}
622
623void
624userconf_enable(int devno)
625{
626 int done = 0;
627
628 if (devno <= userconf_maxdev) {
629 switch (cfdata[devno].cf_fstate) {
630 case FSTATE_DNOTFOUND3:
631 cfdata[devno].cf_fstate = FSTATE_NOTFOUND0;
632 break;
633 case FSTATE_DSTAR4:
634 cfdata[devno].cf_fstate = FSTATE_STAR2;
635 break;
636 case FSTATE_NOTFOUND0:
637 case FSTATE_STAR2:
638 done = 1;
639 break;
640 default:
641 printf("Error unknown state\n");
642 break;
643 }
644
645 printf("%3d ", devno);
646 userconf_pdevnam(devno);
647 if (done) {
648 printf(" already");
649 } else {
650 /* XXX add cmd 'e' <devno> eoc */
651 userconf_hist_cmd('e');
652 userconf_hist_int(devno);
653 userconf_hist_eoc();
654 }
655 printf(" enabled\n");
656 return;
657 }
658
659 if (devno > userconf_maxdev && devno <= userconf_totdev) {
660 printf("%3d can't enable free slot\n", devno);
661 return;
662 }
663
664 if (devno > userconf_totdev &&
665 devno <= userconf_totdev+pdevnames_size) {
666 printf("%3d %s", devno, pdevnames[devno-userconf_totdev-1]);
667 if (pdevinit[devno-userconf_totdev-1].pdev_count > 0) {
668 printf(" already");
669 } else {
670 pdevinit[devno-userconf_totdev-1].pdev_count *= -1;
671 /* XXX add cmd 'e' <devno> eoc */
672 userconf_hist_cmd('e');
673 userconf_hist_int(devno);
674 userconf_hist_eoc();
675 }
676 printf(" enabled\n");
677 return;
678 }
679
680 printf("Unknown devno (max is %d)\n", userconf_totdev+pdevnames_size);
681}
682
683void
684userconf_help(void)
685{
686 int j = 0, k;
687
688 printf("command args description\n");
689 while (*userconf_cmds[j] != '\0') {
690 printf("%s", userconf_cmds[j]);
691 k = strlen(userconf_cmds[j]);
692 while (k < 10) {
693 printf(" ");
694 k++;
695 }
696 switch (*userconf_cmds[j+1]) {
697 case 'L':
698 printf("[count] number of lines before more");
699 break;
700 case 'a':
701 printf("dev add a device");
702 break;
703 case 'b':
704 printf("8|10|16 base on large numbers");
705 break;
706 case 'c':
707 printf("devno|dev change devices");
708 break;
709#if defined(DDB1)
710 case 'D':
711 printf(" enter ddb");
712 break;
713#endif
714 case 'd':
715 printf("attr val|devno|dev disable devices");
716 break;
717 case 'e':
718 printf("attr val|devno|dev enable devices");
719 break;
720 case 'f':
721 printf("devno|dev find devices");
722 break;
723 case 'h':
724 printf(" this message");
725 break;
726 case 'l':
727 printf(" list configuration");
728 break;
729 case 'q':
730 printf(" leave UKC");
731 break;
732 case 's':
733 printf("[attr [val]] "
734 "show attributes (or devices with an attribute)");
735 break;
736 case 'v':
737 printf(" toggle verbose booting");
738 break;
739 default:
740 printf(" don't know");
741 break;
742 }
743 printf("\n");
744 j += 2;
745 }
746}
747
748void
749userconf_list(void)
750{
751 int i = 0;
752
753 userconf_cnt = 0;
754
755 while (i <= (userconf_totdev+pdevnames_size)) {
756 if (userconf_more())
757 break;
758 userconf_pdev(i++);
759 }
760
761 userconf_cnt = -1;
762}
763
764void
765userconf_show(void)
766{
767 int i = 0;
768
769 userconf_cnt = 0;
770
771 while (i <= userconf_maxlocnames) {
772 if (userconf_more())
773 break;
774 printf("%s\n", locnames[i++]);
775 }
776
777 userconf_cnt = -1;
778}
779
780void
781userconf_common_attr_val(short attr, long *val, char routine)
782{
783 struct cfdata *cd;
784 long *l;
785 int ln;
786 int i = 0, quit = 0;
787
788 userconf_cnt = 0;
789
790 while (i <= userconf_maxdev) {
791 cd = &cfdata[i];
792 l = cd->cf_loc;
793 ln = cd->cf_locnames;
794 while (locnamp[ln] != -1) {
795 if (locnamp[ln] == attr) {
796 if (val == NULL((void *)0)) {
797 quit = userconf_more();
798 userconf_pdev(i);
799 } else {
800 if (*val == *l) {
801 quit = userconf_more();
802 switch (routine) {
803 case UC_ENABLE'e':
804 userconf_enable(i);
805 break;
806 case UC_DISABLE'd':
807 userconf_disable(i);
808 break;
809 case UC_SHOW's':
810 userconf_pdev(i);
811 break;
812 default:
813 printf("Unknown routine /%c/\n",
814 routine);
815 break;
816 }
817 }
818 }
819 }
820 if (quit)
821 break;
822 ln++;
823 l++;
824 }
825 if (quit)
826 break;
827 i++;
828 }
829
830 userconf_cnt = -1;
831}
832
833void
834userconf_show_attr(char *cmd)
835{
836 char *c;
837 short attr = -1, i = 0, l = 0;
838 long a;
839
840 c = cmd;
841 while (*c != ' ' && *c != '\t' && *c != '\n' && *c != '\0') {
842 c++;
843 l++;
844 }
845 while (*c == ' ' || *c == '\t' || *c == '\n') {
846 c++;
847 }
848 while (i <= userconf_maxlocnames) {
849 if (strlen(locnames[i]) == l) {
850 if (strncasecmp(cmd, locnames[i], l) == 0) {
851 attr = i;
852 }
853 }
854 i++;
855 }
856
857 if (attr == -1) {
858 printf("Unknown attribute\n");
859 return;
860 }
861
862 if (*c == '\0') {
863 userconf_common_attr_val(attr, NULL((void *)0), UC_SHOW's');
864 } else {
865 if (userconf_number(c, &a, INT_MAX0x7fffffff) == 0) {
866 userconf_common_attr_val(attr, &a, UC_SHOW's');
867 } else {
868 printf("Unknown argument\n");
869 }
870 }
871}
872
873void
874userconf_common_dev(char *dev, int len, short unit, short state, char routine)
875{
876 int i = 0;
877
878 switch (routine) {
879 case UC_CHANGE'c':
880 break;
881 default:
882 userconf_cnt = 0;
883 break;
884 }
885
886 while (cfdata[i].cf_attach != NULL((void *)0)) {
887 if (strlen(cfdata[i].cf_driver->cd_name) == len) {
888
889 /*
890 * Ok, if device name is correct
891 * If state == FSTATE_FOUND, look for "dev"
892 * If state == FSTATE_STAR, look for "dev*"
893 * If state == FSTATE_NOTFOUND, look for "dev0"
894 */
895 if (strncasecmp(dev, cfdata[i].cf_driver->cd_name,
896 len) == 0 &&
897 (state == FSTATE_FOUND1 ||
898 (state == FSTATE_STAR2 &&
899 (cfdata[i].cf_fstate == FSTATE_STAR2 ||
900 cfdata[i].cf_fstate == FSTATE_DSTAR4)) ||
901 (state == FSTATE_NOTFOUND0 &&
902 cfdata[i].cf_unit == unit &&
903 (cfdata[i].cf_fstate == FSTATE_NOTFOUND0 ||
904 cfdata[i].cf_fstate == FSTATE_DNOTFOUND3)))) {
905 if (userconf_more())
906 break;
907 switch (routine) {
908 case UC_CHANGE'c':
909 userconf_change(i);
910 break;
911 case UC_ENABLE'e':
912 userconf_enable(i);
913 break;
914 case UC_DISABLE'd':
915 userconf_disable(i);
916 break;
917 case UC_FIND'f':
918 userconf_pdev(i);
919 break;
920 default:
921 printf("Unknown routine /%c/\n",
922 routine);
923 break;
924 }
925 }
926 }
927 i++;
928 }
929
930 for (i = 0; i < pdevnames_size; i++) {
931 if (strncasecmp(dev, pdevnames[i], len) == 0 &&
932 state == FSTATE_FOUND1) {
933 switch(routine) {
934 case UC_CHANGE'c':
935 userconf_change(userconf_totdev+1+i);
936 break;
937 case UC_ENABLE'e':
938 userconf_enable(userconf_totdev+1+i);
939 break;
940 case UC_DISABLE'd':
941 userconf_disable(userconf_totdev+1+i);
942 break;
943 case UC_FIND'f':
944 userconf_pdev(userconf_totdev+1+i);
945 break;
946 default:
947 printf("Unknown pseudo routine /%c/\n",routine);
948 break;
949 }
950 }
951 }
952
953 switch (routine) {
954 case UC_CHANGE'c':
955 break;
956 default:
957 userconf_cnt = -1;
958 break;
959 }
960}
961
962void
963userconf_common_attr(char *cmd, int attr, char routine)
964{
965 char *c;
966 short l = 0;
967 long a;
968
969 c = cmd;
970 while (*c != ' ' && *c != '\t' && *c != '\n' && *c != '\0') {
971 c++;
972 l++;
973 }
974 while (*c == ' ' || *c == '\t' || *c == '\n')
975 c++;
976
977 if (*c == '\0') {
978 printf("Value missing for attribute\n");
979 return;
980 }
981
982 if (userconf_number(c, &a, INT_MAX0x7fffffff) == 0) {
983 userconf_common_attr_val(attr, &a, routine);
984 } else {
985 printf("Unknown argument\n");
986 }
987}
988
989void
990userconf_add_read(char *prompt, char field, char *dev, int len, long *val)
991{
992 int ok = 0;
993 long a;
994 char *c;
995 int i;
996
997 *val = -1;
998
999 while (!ok) {
1000 printf("%s ? ", prompt);
1001
1002 i = getsn(userconf_argbuf, sizeof(userconf_argbuf));
Value stored to 'i' is never read
1003
1004 c = userconf_argbuf;
1005 while (*c == ' ' || *c == '\t' || *c == '\n')
1006 c++;
1007
1008 if (*c != '\0') {
1009 if (userconf_number(c, &a, INT_MAX0x7fffffff) == 0) {
1010 if (a > userconf_maxdev) {
1011 printf("Unknown devno (max is %d)\n",
1012 userconf_maxdev);
1013 } else if (strncasecmp(dev,
1014 cfdata[a].cf_driver->cd_name, len) != 0 &&
1015 field == 'a') {
1016 printf("Not same device type\n");
1017 } else {
1018 *val = a;
1019 ok = 1;
1020 }
1021 } else if (*c == '?') {
1022 userconf_common_dev(dev, len, 0,
1023 FSTATE_FOUND1, UC_FIND'f');
1024 } else if (*c == 'q' || *c == 'Q') {
1025 ok = 1;
1026 } else {
1027 printf("Unknown argument\n");
1028 }
1029 } else {
1030 ok = 1;
1031 }
1032 }
1033}
1034
1035void
1036userconf_add(char *dev, int len, short unit, short state)
1037{
1038 int found = 0;
1039 struct cfdata new;
1040 int max_unit, star_unit;
1041 long i = 0, val, orig;
1042
1043 memset(&new, 0, sizeof(struct cfdata))__builtin_memset((&new), (0), (sizeof(struct cfdata)));
1044
1045 if (userconf_maxdev == userconf_totdev) {
1046 printf("No more space for new devices.\n");
1047 return;
1048 }
1049
1050 if (state == FSTATE_FOUND1) {
1051 printf("Device not complete number or * is missing\n");
1052 return;
1053 }
1054
1055 for (i = 0; cfdata[i].cf_driver; i++)
1056 if (strlen(cfdata[i].cf_driver->cd_name) == len &&
1057 strncasecmp(dev, cfdata[i].cf_driver->cd_name, len) == 0)
1058 found = 1;
1059
1060 if (!found) {
1061 printf("No device of this type exists.\n");
1062 return;
1063 }
1064
1065 userconf_add_read("Clone Device (DevNo, 'q' or '?')",
1066 'a', dev, len, &val);
1067
1068 if (val != -1) {
1069 orig = val;
1070 new = cfdata[val];
1071 new.cf_unit = unit;
1072 new.cf_fstate = state;
1073 userconf_add_read("Insert before Device (DevNo, 'q' or '?')",
1074 'i', dev, len, &val);
1075 }
1076
1077 if (val != -1) {
1078 /* XXX add cmd 'a' <orig> <val> eoc */
1079 userconf_hist_cmd('a');
1080 userconf_hist_int(orig);
1081 userconf_hist_int(unit);
1082 userconf_hist_int(state);
1083 userconf_hist_int(val);
1084 userconf_hist_eoc();
1085
1086 /* Insert the new record */
1087 for (i = userconf_maxdev; val <= i; i--)
1088 cfdata[i+1] = cfdata[i];
1089 cfdata[val] = new;
1090
1091 /* Fix indexs in pv */
1092 for (i = 0; i < pv_size; i++) {
1093 if (pv[i] != -1 && pv[i] >= val)
1094 pv[i]++;
1095 }
1096
1097 /* Fix indexs in cfroots */
1098 for (i = 0; i < cfroots_size; i++) {
1099 if (cfroots[i] != -1 && cfroots[i] >= val)
1100 cfroots[i]++;
1101 }
1102
1103 userconf_maxdev++;
1104
1105 max_unit = -1;
1106
1107 /* Find max unit number of the device type */
1108
1109 i = 0;
1110 while (cfdata[i].cf_attach != NULL((void *)0)) {
1111 if (strlen(cfdata[i].cf_driver->cd_name) == len &&
1112 strncasecmp(dev, cfdata[i].cf_driver->cd_name,
1113 len) == 0) {
1114 switch (cfdata[i].cf_fstate) {
1115 case FSTATE_NOTFOUND0:
1116 case FSTATE_DNOTFOUND3:
1117 if (cfdata[i].cf_unit > max_unit)
1118 max_unit = cfdata[i].cf_unit;
1119 break;
1120 default:
1121 break;
1122 }
1123 }
1124 i++;
1125 }
1126
1127 /*
1128 * For all * entries set unit number to max+1, and update
1129 * cf_starunit1 if necessary.
1130 */
1131 max_unit++;
1132 star_unit = -1;
1133
1134 i = 0;
1135 while (cfdata[i].cf_attach != NULL((void *)0)) {
1136 if (strlen(cfdata[i].cf_driver->cd_name) == len &&
1137 strncasecmp(dev, cfdata[i].cf_driver->cd_name,
1138 len) == 0) {
1139 switch (cfdata[i].cf_fstate) {
1140 case FSTATE_NOTFOUND0:
1141 case FSTATE_DNOTFOUND3:
1142 if (cfdata[i].cf_unit > star_unit)
1143 star_unit = cfdata[i].cf_unit;
1144 break;
1145 default:
1146 break;
1147 }
1148 }
1149 i++;
1150 }
1151 star_unit++;
1152
1153 i = 0;
1154 while (cfdata[i].cf_attach != NULL((void *)0)) {
1155 if (strlen(cfdata[i].cf_driver->cd_name) == len &&
1156 strncasecmp(dev, cfdata[i].cf_driver->cd_name,
1157 len) == 0) {
1158 switch (cfdata[i].cf_fstate) {
1159 case FSTATE_STAR2:
1160 case FSTATE_DSTAR4:
1161 cfdata[i].cf_unit = max_unit;
1162 if (cfdata[i].cf_starunit1 < star_unit)
1163 cfdata[i].cf_starunit1 =
1164 star_unit;
1165 break;
1166 default:
1167 break;
1168 }
1169 }
1170 i++;
1171 }
1172 userconf_pdev(val);
1173 }
1174
1175 /* cf_attach, cf_driver, cf_unit, cf_fstate, cf_loc, cf_flags,
1176 cf_parents, cf_locnames, and cf_locnames */
1177}
1178
1179int
1180userconf_parse(char *cmd)
1181{
1182 char *c, *v;
1183 int i = 0, j = 0, k;
1184 long a;
1185 short unit, state;
1186
1187 c = cmd;
1188 while (*c == ' ' || *c == '\t')
1189 c++;
1190 v = c;
1191 while (*c != ' ' && *c != '\t' && *c != '\n' && *c != '\0') {
1192 c++;
1193 i++;
1194 }
1195
1196 k = -1;
1197 while (*userconf_cmds[j] != '\0') {
1198 if (strlen(userconf_cmds[j]) == i) {
1199 if (strncasecmp(v, userconf_cmds[j], i) == 0)
1200 k = j;
1201 }
1202 j += 2;
1203 }
1204
1205 while (*c == ' ' || *c == '\t' || *c == '\n')
1206 c++;
1207
1208 if (k == -1) {
1209 if (*v != '\n')
1210 printf("Unknown command, try help\n");
1211 } else {
1212 switch (*userconf_cmds[k+1]) {
1213 case 'L':
1214 if (*c == '\0')
1215 printf("Argument expected\n");
1216 else if (userconf_number(c, &a, INT_MAX0x7fffffff) == 0)
1217 userconf_lines = a;
1218 else
1219 printf("Unknown argument\n");
1220 break;
1221 case 'a':
1222 if (*c == '\0')
1223 printf("Dev expected\n");
1224 else if (userconf_device(c, &a, &unit, &state) == 0)
1225 userconf_add(c, a, unit, state);
1226 else
1227 printf("Unknown argument\n");
1228 break;
1229 case 'b':
1230 if (*c == '\0')
1231 printf("8|10|16 expected\n");
1232 else if (userconf_number(c, &a, INT_MAX0x7fffffff) == 0) {
1233 if (a == 8 || a == 10 || a == 16) {
1234 userconf_base = a;
1235 } else {
1236 printf("8|10|16 expected\n");
1237 }
1238 } else
1239 printf("Unknown argument\n");
1240 break;
1241 case 'c':
1242 if (*c == '\0')
1243 printf("DevNo or Dev expected\n");
1244 else if (userconf_number(c, &a, INT_MAX0x7fffffff) == 0)
1245 userconf_change(a);
1246 else if (userconf_device(c, &a, &unit, &state) == 0)
1247 userconf_common_dev(c, a, unit, state, UC_CHANGE'c');
1248 else
1249 printf("Unknown argument\n");
1250 break;
1251#if defined(DDB1)
1252 case 'D':
1253 db_enter();
1254 break;
1255#endif
1256 case 'd':
1257 if (*c == '\0')
1258 printf("Attr, DevNo or Dev expected\n");
1259 else if (userconf_attr(c, &a) == 0)
1260 userconf_common_attr(c, a, UC_DISABLE'd');
1261 else if (userconf_number(c, &a, INT_MAX0x7fffffff) == 0)
1262 userconf_disable(a);
1263 else if (userconf_device(c, &a, &unit, &state) == 0)
1264 userconf_common_dev(c, a, unit, state, UC_DISABLE'd');
1265 else
1266 printf("Unknown argument\n");
1267 break;
1268 case 'e':
1269 if (*c == '\0')
1270 printf("Attr, DevNo or Dev expected\n");
1271 else if (userconf_attr(c, &a) == 0)
1272 userconf_common_attr(c, a, UC_ENABLE'e');
1273 else if (userconf_number(c, &a, INT_MAX0x7fffffff) == 0)
1274 userconf_enable(a);
1275 else if (userconf_device(c, &a, &unit, &state) == 0)
1276 userconf_common_dev(c, a, unit, state, UC_ENABLE'e');
1277 else
1278 printf("Unknown argument\n");
1279 break;
1280 case 'f':
1281 if (*c == '\0')
1282 printf("DevNo or Dev expected\n");
1283 else if (userconf_number(c, &a, INT_MAX0x7fffffff) == 0)
1284 userconf_pdev(a);
1285 else if (userconf_device(c, &a, &unit, &state) == 0)
1286 userconf_common_dev(c, a, unit, state, UC_FIND'f');
1287 else
1288 printf("Unknown argument\n");
1289 break;
1290 case 'h':
1291 userconf_help();
1292 break;
1293 case 'l':
1294 if (*c == '\0')
1295 userconf_list();
1296 else
1297 printf("Unknown argument\n");
1298 break;
1299 case 'q':
1300 /* XXX add cmd 'q' eoc */
1301 userconf_hist_cmd('q');
1302 userconf_hist_eoc();
1303 return(-1);
1304 break;
1305 case 's':
1306 if (*c == '\0')
1307 userconf_show();
1308 else
1309 userconf_show_attr(c);
1310 break;
1311 case 'v':
1312 autoconf_verbose = !autoconf_verbose;
1313 printf("autoconf verbose %sabled\n",
1314 autoconf_verbose ? "en" : "dis");
1315 break;
1316 default:
1317 printf("Unknown command\n");
1318 break;
1319 }
1320 }
1321 return(0);
1322}
1323
1324void
1325user_config(void)
1326{
1327 userconf_init();
1328 printf("User Kernel Config\n");
1329
1330 cnpollc(1);
1331 while (1) {
1332 printf("UKC> ");
1333 if (getsn(userconf_cmdbuf, sizeof(userconf_cmdbuf)) > 0 &&
1334 userconf_parse(userconf_cmdbuf))
1335 break;
1336 }
1337 cnpollc(0);
1338
1339 printf("Continuing...\n");
1340}