xref: /netbsd-src/usr.bin/config/mkdevsw.c (revision 7fa608457b817eca6e0977b37f758ae064f3c99c)
1 /*	$NetBSD: mkdevsw.c,v 1.4 2007/01/13 23:47:36 christos Exp $	*/
2 
3 /*
4  * Copyright (c) 2002 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by MAEKAWA Masahide (gehenna@NetBSD.org).
9  *
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.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *	  This product includes software developed by the NetBSD
21  *	  Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 #if HAVE_NBTOOL_CONFIG_H
40 #include "nbtool_config.h"
41 #endif
42 
43 #include <stdio.h>
44 #include <string.h>
45 #include <errno.h>
46 #include <err.h>
47 
48 #include "defs.h"
49 
50 static void emitconv(FILE *);
51 static void emitdev(FILE *);
52 static void emitdevm(FILE *);
53 static void emitheader(FILE *);
54 
55 int
56 mkdevsw(void)
57 {
58 	FILE *fp;
59 
60 	if ((fp = fopen("devsw.c.tmp", "w")) == NULL) {
61 		warn("cannot create devsw.c");
62 		return (1);
63 	}
64 
65 	emitheader(fp);
66 	emitdevm(fp);
67 	emitconv(fp);
68 	emitdev(fp);
69 
70 	fflush(fp);
71 	if (ferror(fp)) {
72 		warn("error writing devsw.c");
73 		fclose(fp);
74 		return 1;
75 	}
76 
77 	(void)fclose(fp);
78 
79 	if (moveifchanged("devsw.c.tmp", "devsw.c") != 0) {
80 		warn("error renaming devsw.c");
81 		return (1);
82 	}
83 
84 	return (0);
85 }
86 
87 static void
88 emitheader(FILE *fp)
89 {
90 	fprintf(fp, "/*\n * MACHINE GENERATED: DO NOT EDIT\n *\n"
91 		    " * devsw.c, from \"%s\"\n */\n\n", conffile);
92 
93 	fputs("#include <sys/param.h>\n"
94 		  "#include <sys/conf.h>\n"
95 		  "\n#define\tDEVSW_ARRAY_SIZE(x)\t"
96 		  "(sizeof((x))/sizeof((x)[0]))\n", fp);
97 }
98 
99 /*
100  * Emit device switch table for character/block device.
101  */
102 static void
103 emitdevm(FILE *fp)
104 {
105 	struct devm *dm;
106 	char mstr[16];
107 	int i;
108 
109 	fputs("\n/* device switch table for block device */\n", fp);
110 
111 	for (i = 0 ; i <= maxbdevm ; i++) {
112 		(void)snprintf(mstr, sizeof(mstr), "%d", i);
113 		if ((dm = ht_lookup(bdevmtab, intern(mstr))) == NULL)
114 			continue;
115 
116 		fprintf(fp, "extern const struct bdevsw %s_bdevsw;\n",
117 			    dm->dm_name);
118 	}
119 
120 	fputs("\nconst struct bdevsw *bdevsw0[] = {\n", fp);
121 
122 	for (i = 0 ; i <= maxbdevm ; i++) {
123 		(void)snprintf(mstr, sizeof(mstr), "%d", i);
124 		if ((dm = ht_lookup(bdevmtab, intern(mstr))) == NULL) {
125 			fprintf(fp, "\tNULL,\n");
126 		} else {
127 			fprintf(fp, "\t&%s_bdevsw,\n", dm->dm_name);
128 		}
129 	}
130 
131 	fputs("};\n\nconst struct bdevsw **bdevsw = bdevsw0;\n", fp);
132 
133 	fputs("const int sys_bdevsws = DEVSW_ARRAY_SIZE(bdevsw0);\n"
134 		  "int max_bdevsws = DEVSW_ARRAY_SIZE(bdevsw0);\n", fp);
135 
136 	fputs("\n/* device switch table for character device */\n", fp);
137 
138 	for (i = 0 ; i <= maxcdevm ; i++) {
139 		(void)snprintf(mstr, sizeof(mstr), "%d", i);
140 		if ((dm = ht_lookup(cdevmtab, intern(mstr))) == NULL)
141 			continue;
142 
143 		fprintf(fp, "extern const struct cdevsw %s_cdevsw;\n",
144 			    dm->dm_name);
145 	}
146 
147 	fputs("\nconst struct cdevsw *cdevsw0[] = {\n", fp);
148 
149 	for (i = 0 ; i <= maxcdevm ; i++) {
150 		(void)snprintf(mstr, sizeof(mstr), "%d", i);
151 		if ((dm = ht_lookup(cdevmtab, intern(mstr))) == NULL) {
152 			fprintf(fp, "\tNULL,\n");
153 		} else {
154 			fprintf(fp, "\t&%s_cdevsw,\n", dm->dm_name);
155 		}
156 	}
157 
158 	fputs("};\n\nconst struct cdevsw **cdevsw = cdevsw0;\n", fp);
159 
160 	fputs("const int sys_cdevsws = DEVSW_ARRAY_SIZE(cdevsw0);\n"
161 		  "int max_cdevsws = DEVSW_ARRAY_SIZE(cdevsw0);\n", fp);
162 }
163 
164 /*
165  * Emit device major conversion table.
166  */
167 static void
168 emitconv(FILE *fp)
169 {
170 	struct devm *dm;
171 
172 	fputs("\n/* device conversion table */\n"
173 		  "struct devsw_conv devsw_conv0[] = {\n", fp);
174 	TAILQ_FOREACH(dm, &alldevms, dm_next) {
175 		fprintf(fp, "\t{ \"%s\", %d, %d },\n", dm->dm_name,
176 			    dm->dm_bmajor, dm->dm_cmajor);
177 	}
178 	fputs("};\n\n"
179 		  "struct devsw_conv *devsw_conv = devsw_conv0;\n"
180 		  "int max_devsw_convs = DEVSW_ARRAY_SIZE(devsw_conv0);\n",
181 		  fp);
182 }
183 
184 /*
185  * Emit specific device major informations.
186  */
187 static void
188 emitdev(FILE *fp)
189 {
190 	struct devm *dm;
191 	char mstr[16];
192 
193 	fputs("\n", fp);
194 
195 	(void)strlcpy(mstr, "swap", sizeof(mstr));
196 	if ((dm = ht_lookup(bdevmtab, intern(mstr))) != NULL) {
197 		fprintf(fp, "const dev_t swapdev = makedev(%d, 0);\n",
198 			    dm->dm_bmajor);
199 	}
200 
201 	(void)strlcpy(mstr, "mem", sizeof(mstr));
202 	if ((dm = ht_lookup(cdevmtab, intern(mstr))) == NULL)
203 		panic("memory device is not configured");
204 	fprintf(fp, "const dev_t zerodev = makedev(%d, DEV_ZERO);\n",
205 		    dm->dm_cmajor);
206 
207 	fputs("\n/* mem_no is only used in iskmemdev() */\n", fp);
208 	fprintf(fp, "const int mem_no = %d;\n", dm->dm_cmajor);
209 }
210