1 /*
2  * Copyright (c) 1992 Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Ralph Campbell, and Kazumasa Utashiro of Software Research
7  * Associates, Inc.
8  *
9  * %sccs.include.redist.c%
10  *
11  *	@(#)swapgeneric.c	7.3 (Berkeley) 03/09/93
12  */
13 
14 #include <sysparam.h>
15 #include <sysconf.h>
16 #include <sysbuf.h>
17 #include <syssystm.h>
18 #include <sysreboot.h>
19 
20 #ifdef CPU_DOUBLE
21 #include <news3400/iop/iopvar.h>
22 #else /* CPU_DOUBLE */
23 #include <news3400/hbdev/hbvar.h>
24 # define	iop	hb
25 
26 # define	idinit	hdinit
27 
28 # define	im_driver	hm_driver
29 # define	im_ctlr		hm_ctlr
30 # define	im_alive	hm_alive
31 # define	im_addr		hm_addr
32 # define	im_intr		hm_intr
33 # define	im_scnum	hm_scnum
34 # define	im_hd		hm_hd
35 # define	im_hbinfo	hm_hbinfo
36 # define	im_tab		hm_tab
37 
38 # define	ii_driver	hi_driver
39 # define	ii_unit		hi_unit
40 # define	ii_ctlr		hi_ctlr
41 # define	ii_slave	hi_slave
42 # define	ii_addr		hi_addr
43 # define	ii_intr		hi_intr
44 # define	ii_dk		hi_dk
45 # define	ii_flags	hi_flags
46 # define	ii_alive	hi_alive
47 # define	ii_type		hi_type
48 # define	ii_forw		hi_forw
49 # define	ii_mi		hi_mi
50 # define	ii_hd		hi_hd
51 
52 # define	id_probe	hd_probe
53 # define	id_slave	hd_slave
54 # define	id_attach	hd_attach
55 # define	id_dgo		hd_dgo
56 # define	id_dname	hd_dname
57 # define	id_dinfo	hd_dinfo
58 # define	id_mname	hd_mname
59 # define	id_minfo	hd_minfo
60 #endif /* CPU_DOUBLE */
61 
62 # include "sd.h"
63 # include "hd.h"
64 # include "fd.h"
65 # include "od.h"
66 
67 /*
68  * Generic configuration;  all in one
69  */
70 dev_t	rootdev = NODEV;
71 dev_t	argdev = NODEV;
72 dev_t	dumpdev = NODEV;
73 int	nswap;
74 struct	swdevt swdevt[] = {
75 	{ -1,	1,	0 },
76 	{ 0,	0,	0 },
77 };
78 int	dmmin, dmmax, dmtext;
79 
80 # if NSDC > 0
81 extern	struct iop/**/_driver sdcdriver;
82 # endif
83 # if NHC > 0
84 extern	struct iop/**/_driver hcdriver;
85 # endif
86 # if NFC > 0
87 extern	struct iop/**/_driver fcdriver;
88 # endif
89 # if NOC > 0
90 extern	struct iop/**/_driver ocdriver;
91 # endif
92 
93 struct	genericconf {
94 	caddr_t	gc_driver;
95 	char	*gc_name;
96 	dev_t	gc_root;
97 } genericconf[] = {
98 # if NSDC > 0
99 	{ (caddr_t)&sdcdriver,	"sd",	makedev(0, 0),	},
100 # endif
101 # if NHC > 0
102 	{ (caddr_t)&hcdriver,	"hd",	makedev(0, 0),	},
103 # endif
104 # if NFC > 0
105 	{ (caddr_t)&fcdriver,	"fh",	makedev(1, 0),	},
106 	{ (caddr_t)&fcdriver,	"fd",	makedev(1, 1),	},
107 # endif
108 # if NOC > 0
109 	{ (caddr_t)&ocdriver,	"od",	makedev(10, 0),	},
110 # endif
111 	{ 0 },
112 };
113 
114 setconf()
115 {
116 	register struct scsi_device *dp;
117 	register struct genericconf *gc;
118 	register char *cp, *gp;
119 	int unit, swaponroot = 0;
120 
121 	if (rootdev != NODEV)
122 		goto doswap;
123 	unit = 0;
124 	if (boothowto & RB_ASKNAME) {
125 		char name[128];
126 retry:
127 		printf("root device? ");
128 		gets(name);
129 		for (gc = genericconf; gc->gc_driver; gc++)
130 		    for (cp = name, gp = gc->gc_name; *cp == *gp; cp++)
131 			if (*++gp == 0)
132 				goto gotit;
133 		printf("use one of:");
134 		for (gc = genericconf; gc->gc_driver; gc++)
135 			printf(" %s%%d", gc->gc_name);
136 		printf("\n");
137 		goto retry;
138 gotit:
139 		if (*++cp < '0' || *cp > '9') {
140 			printf("bad/missing unit number\n");
141 			goto retry;
142 		}
143 		while (*cp >= '0' && *cp <= '9')
144 			unit = 10 * unit + *cp++ - '0';
145 		if (*cp == '*')
146 			swaponroot++;
147 		goto found;
148 	}
149 	for (gc = genericconf; gc->gc_driver; gc++) {
150 		for (dp = scsi_dinit; dp->sd_driver; dp++) {
151 			if (dp->sd_alive == 0)
152 				continue;
153 			if (dp->sd_unit == unit &&
154 			    dp->sd_driver == (struct driver *)gc->gc_driver) {
155 				printf("root on %s%d%c\n",
156 					dp->sd_driver->d_name, unit,
157 					"ab"[swaponroot]);
158 				goto found;
159 			}
160 		}
161 	}
162 	printf("no suitable root\n");
163 	goto retry;
164 found:
165 	gc->gc_root = makedev(major(gc->gc_root), unit*8);
166 	rootdev = gc->gc_root;
167 doswap:
168 	swdevt[0].sw_dev = argdev = dumpdev =
169 	    makedev(major(rootdev), minor(rootdev)+1);
170 	/* swap size and dumplo set during autoconfigure */
171 	if (swaponroot)
172 		rootdev = dumpdev;
173 }
174 
175 gets(cp)
176 	char *cp;
177 {
178 	register char *lp;
179 	register c;
180 	int s;
181 
182 	lp = cp;
183 	s = spltty();
184 	for (;;) {
185 		cnputc(c = cngetc());
186 		switch (c) {
187 		case '\r':
188 			cnputc('\n');
189 			*lp++ = '\0';
190 			break;
191 		case '\n':
192 			cnputc('\r');
193 			*lp++ = '\0';
194 			break;
195 		case '\b':
196 		case '\177':
197 			if (lp > cp) {
198 				lp--;
199 				cnputc(' ');
200 				cnputc('\b');
201 			}
202 			continue;
203 		case '#':
204 			lp--;
205 			if (lp < cp)
206 				lp = cp;
207 			continue;
208 		case '@':
209 		case 'u'&037:
210 			lp = cp;
211 			cnputc('\n');
212 			continue;
213 		default:
214 			*lp++ = c;
215 			continue;
216 		}
217 		break;
218 	}
219 	splx(s);
220 }
221