1 /* $NetBSD: mkdevsw.c,v 1.5 2007/12/12 00:03:33 lukem 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 autogen_comment(fp, "devsw.c"); 91 92 fputs("#include <sys/param.h>\n" 93 "#include <sys/conf.h>\n" 94 "\n#define\tDEVSW_ARRAY_SIZE(x)\t" 95 "(sizeof((x))/sizeof((x)[0]))\n", fp); 96 } 97 98 /* 99 * Emit device switch table for character/block device. 100 */ 101 static void 102 emitdevm(FILE *fp) 103 { 104 struct devm *dm; 105 char mstr[16]; 106 int i; 107 108 fputs("\n/* device switch table for block device */\n", fp); 109 110 for (i = 0 ; i <= maxbdevm ; i++) { 111 (void)snprintf(mstr, sizeof(mstr), "%d", i); 112 if ((dm = ht_lookup(bdevmtab, intern(mstr))) == NULL) 113 continue; 114 115 fprintf(fp, "extern const struct bdevsw %s_bdevsw;\n", 116 dm->dm_name); 117 } 118 119 fputs("\nconst struct bdevsw *bdevsw0[] = {\n", fp); 120 121 for (i = 0 ; i <= maxbdevm ; i++) { 122 (void)snprintf(mstr, sizeof(mstr), "%d", i); 123 if ((dm = ht_lookup(bdevmtab, intern(mstr))) == NULL) { 124 fprintf(fp, "\tNULL,\n"); 125 } else { 126 fprintf(fp, "\t&%s_bdevsw,\n", dm->dm_name); 127 } 128 } 129 130 fputs("};\n\nconst struct bdevsw **bdevsw = bdevsw0;\n", fp); 131 132 fputs("const int sys_bdevsws = DEVSW_ARRAY_SIZE(bdevsw0);\n" 133 "int max_bdevsws = DEVSW_ARRAY_SIZE(bdevsw0);\n", fp); 134 135 fputs("\n/* device switch table for character device */\n", fp); 136 137 for (i = 0 ; i <= maxcdevm ; i++) { 138 (void)snprintf(mstr, sizeof(mstr), "%d", i); 139 if ((dm = ht_lookup(cdevmtab, intern(mstr))) == NULL) 140 continue; 141 142 fprintf(fp, "extern const struct cdevsw %s_cdevsw;\n", 143 dm->dm_name); 144 } 145 146 fputs("\nconst struct cdevsw *cdevsw0[] = {\n", fp); 147 148 for (i = 0 ; i <= maxcdevm ; i++) { 149 (void)snprintf(mstr, sizeof(mstr), "%d", i); 150 if ((dm = ht_lookup(cdevmtab, intern(mstr))) == NULL) { 151 fprintf(fp, "\tNULL,\n"); 152 } else { 153 fprintf(fp, "\t&%s_cdevsw,\n", dm->dm_name); 154 } 155 } 156 157 fputs("};\n\nconst struct cdevsw **cdevsw = cdevsw0;\n", fp); 158 159 fputs("const int sys_cdevsws = DEVSW_ARRAY_SIZE(cdevsw0);\n" 160 "int max_cdevsws = DEVSW_ARRAY_SIZE(cdevsw0);\n", fp); 161 } 162 163 /* 164 * Emit device major conversion table. 165 */ 166 static void 167 emitconv(FILE *fp) 168 { 169 struct devm *dm; 170 171 fputs("\n/* device conversion table */\n" 172 "struct devsw_conv devsw_conv0[] = {\n", fp); 173 TAILQ_FOREACH(dm, &alldevms, dm_next) { 174 fprintf(fp, "\t{ \"%s\", %d, %d },\n", dm->dm_name, 175 dm->dm_bmajor, dm->dm_cmajor); 176 } 177 fputs("};\n\n" 178 "struct devsw_conv *devsw_conv = devsw_conv0;\n" 179 "int max_devsw_convs = DEVSW_ARRAY_SIZE(devsw_conv0);\n", 180 fp); 181 } 182 183 /* 184 * Emit specific device major informations. 185 */ 186 static void 187 emitdev(FILE *fp) 188 { 189 struct devm *dm; 190 char mstr[16]; 191 192 fputs("\n", fp); 193 194 (void)strlcpy(mstr, "swap", sizeof(mstr)); 195 if ((dm = ht_lookup(bdevmtab, intern(mstr))) != NULL) { 196 fprintf(fp, "const dev_t swapdev = makedev(%d, 0);\n", 197 dm->dm_bmajor); 198 } 199 200 (void)strlcpy(mstr, "mem", sizeof(mstr)); 201 if ((dm = ht_lookup(cdevmtab, intern(mstr))) == NULL) 202 panic("memory device is not configured"); 203 fprintf(fp, "const dev_t zerodev = makedev(%d, DEV_ZERO);\n", 204 dm->dm_cmajor); 205 206 fputs("\n/* mem_no is only used in iskmemdev() */\n", fp); 207 fprintf(fp, "const int mem_no = %d;\n", dm->dm_cmajor); 208 } 209