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