1 1.15 tsutsui /* $NetBSD: devopen.c,v 1.15 2024/05/09 15:11:11 tsutsui Exp $ */ 2 1.2 thorpej 3 1.2 thorpej /*- 4 1.2 thorpej * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. 5 1.2 thorpej * All rights reserved. 6 1.2 thorpej * 7 1.2 thorpej * This code is derived from software contributed to The NetBSD Foundation 8 1.2 thorpej * by Jason R. Thorpe. 9 1.2 thorpej * 10 1.2 thorpej * Redistribution and use in source and binary forms, with or without 11 1.2 thorpej * modification, are permitted provided that the following conditions 12 1.2 thorpej * are met: 13 1.2 thorpej * 1. Redistributions of source code must retain the above copyright 14 1.2 thorpej * notice, this list of conditions and the following disclaimer. 15 1.2 thorpej * 2. Redistributions in binary form must reproduce the above copyright 16 1.2 thorpej * notice, this list of conditions and the following disclaimer in the 17 1.2 thorpej * documentation and/or other materials provided with the distribution. 18 1.2 thorpej * 19 1.2 thorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.2 thorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.2 thorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.2 thorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.2 thorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.2 thorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.2 thorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.2 thorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.2 thorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.2 thorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.2 thorpej * POSSIBILITY OF SUCH DAMAGE. 30 1.2 thorpej */ 31 1.1 thorpej 32 1.1 thorpej /*- 33 1.1 thorpej * Copyright (c) 1993 John Brezak 34 1.1 thorpej * All rights reserved. 35 1.14 tsutsui * 36 1.1 thorpej * Redistribution and use in source and binary forms, with or without 37 1.1 thorpej * modification, are permitted provided that the following conditions 38 1.1 thorpej * are met: 39 1.1 thorpej * 1. Redistributions of source code must retain the above copyright 40 1.1 thorpej * notice, this list of conditions and the following disclaimer. 41 1.1 thorpej * 2. Redistributions in binary form must reproduce the above copyright 42 1.1 thorpej * notice, this list of conditions and the following disclaimer in the 43 1.1 thorpej * documentation and/or other materials provided with the distribution. 44 1.1 thorpej * 3. The name of the author may not be used to endorse or promote products 45 1.1 thorpej * derived from this software without specific prior written permission. 46 1.14 tsutsui * 47 1.1 thorpej * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR 48 1.1 thorpej * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 49 1.1 thorpej * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 50 1.1 thorpej * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 51 1.1 thorpej * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 52 1.1 thorpej * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 53 1.1 thorpej * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 54 1.1 thorpej * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 55 1.1 thorpej * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 56 1.1 thorpej * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 57 1.1 thorpej * POSSIBILITY OF SUCH DAMAGE. 58 1.1 thorpej */ 59 1.1 thorpej 60 1.1 thorpej #include <sys/param.h> 61 1.1 thorpej #include <sys/reboot.h> 62 1.3 gmcgarry 63 1.3 gmcgarry #include <lib/libkern/libkern.h> 64 1.1 thorpej 65 1.1 thorpej #include <lib/libsa/stand.h> 66 1.13 tsutsui #include <hp300/stand/common/conf.h> 67 1.1 thorpej #include <hp300/stand/common/samachdep.h> 68 1.1 thorpej 69 1.1 thorpej u_int opendev; 70 1.1 thorpej 71 1.1 thorpej #define ispart(c) ((c) >= 'a' && (c) <= 'h') 72 1.1 thorpej 73 1.6 tsutsui static void usage(void); 74 1.6 tsutsui static int devlookup(const char * ,int); 75 1.6 tsutsui static int devparse(const char *, int *, int*, int*, int*, int*, char **); 76 1.6 tsutsui 77 1.6 tsutsui void 78 1.6 tsutsui usage(void) 79 1.1 thorpej { 80 1.6 tsutsui 81 1.6 tsutsui printf("Usage: device(adaptor, controller, drive, partition)file\n" 82 1.6 tsutsui " <device><unit><partitionletter>:file\n"); 83 1.1 thorpej } 84 1.1 thorpej 85 1.6 tsutsui static int 86 1.7 tsutsui devlookup(const char *d, int len) 87 1.1 thorpej { 88 1.6 tsutsui struct devsw *dp = devsw; 89 1.6 tsutsui int i; 90 1.14 tsutsui 91 1.6 tsutsui for (i = 0; i < ndevs; i++, dp++) { 92 1.6 tsutsui if (dp->dv_name && strncmp(dp->dv_name, d, len) == 0) { 93 1.6 tsutsui /* 94 1.6 tsutsui * Set the filesystem and startup up according to 95 1.6 tsutsui * the device being opened. 96 1.6 tsutsui */ 97 1.6 tsutsui switch (i) { 98 1.6 tsutsui case 0: /* ct */ 99 1.6 tsutsui memcpy(file_system, file_system_rawfs, 100 1.13 tsutsui sizeof(file_system_rawfs)); 101 1.13 tsutsui nfsys = 1; 102 1.6 tsutsui break; 103 1.6 tsutsui 104 1.6 tsutsui case 2: /* rd */ 105 1.6 tsutsui case 4: /* sd */ 106 1.6 tsutsui memcpy(file_system, file_system_ufs, 107 1.13 tsutsui sizeof(file_system_ufs)); 108 1.15 tsutsui nfsys = NFSYS_FS; 109 1.6 tsutsui break; 110 1.6 tsutsui 111 1.6 tsutsui case 6: /* le */ 112 1.6 tsutsui memcpy(file_system, file_system_nfs, 113 1.13 tsutsui sizeof(file_system_nfs)); 114 1.13 tsutsui nfsys = 1; 115 1.6 tsutsui break; 116 1.6 tsutsui 117 1.6 tsutsui default: 118 1.6 tsutsui /* Agh! What happened?! */ 119 1.6 tsutsui goto bad; 120 1.6 tsutsui } 121 1.6 tsutsui return i; 122 1.6 tsutsui } 123 1.1 thorpej } 124 1.1 thorpej 125 1.1 thorpej bad: 126 1.6 tsutsui printf("No such device - Configured devices are:\n"); 127 1.6 tsutsui for (dp = devsw, i = 0; i < ndevs; i++, dp++) 128 1.6 tsutsui if (dp->dv_name) 129 1.6 tsutsui printf(" %s", dp->dv_name); 130 1.6 tsutsui printf("\n"); 131 1.6 tsutsui errno = ENODEV; 132 1.6 tsutsui return -1; 133 1.1 thorpej } 134 1.1 thorpej 135 1.1 thorpej /* 136 1.1 thorpej * Parse a device spec in one of two forms. 137 1.1 thorpej * 138 1.1 thorpej * dev(adapt, ctlr, unit, part)file 139 1.1 thorpej * [A-Za-z]*[0-9]*[A-Za-z]:file 140 1.1 thorpej * dev unit part 141 1.1 thorpej */ 142 1.6 tsutsui static int 143 1.7 tsutsui devparse(const char *fname, int *dev, int *adapt, int *ctlr, int *unit, 144 1.7 tsutsui int *part, char **file) 145 1.1 thorpej { 146 1.6 tsutsui int i; 147 1.6 tsutsui char *s, *args[4]; 148 1.5 tsutsui 149 1.6 tsutsui /* get device name */ 150 1.6 tsutsui for (s = (char *)fname; *s && *s != '/' && *s != ':' && *s != '('; s++) 151 1.12 mrg continue; 152 1.6 tsutsui 153 1.6 tsutsui /* first form */ 154 1.6 tsutsui if (*s == '(') { 155 1.6 tsutsui /* lookup device and get index */ 156 1.6 tsutsui if ((*dev = devlookup(fname, s - fname)) < 0) 157 1.6 tsutsui goto baddev; 158 1.6 tsutsui 159 1.6 tsutsui /* tokenize device ident */ 160 1.6 tsutsui args[0] = ++s; 161 1.6 tsutsui for (args[0] = s, i = 1; *s && *s != ')'; s++) { 162 1.6 tsutsui if (*s == ',') 163 1.6 tsutsui args[i++] = ++s; 164 1.6 tsutsui } 165 1.6 tsutsui switch(i) { 166 1.6 tsutsui case 4: 167 1.6 tsutsui *adapt = atoi(args[0]); 168 1.6 tsutsui *ctlr = atoi(args[1]); 169 1.6 tsutsui *unit = atoi(args[2]); 170 1.6 tsutsui *part = atoi(args[3]); 171 1.6 tsutsui break; 172 1.6 tsutsui case 3: 173 1.6 tsutsui *ctlr = atoi(args[0]); 174 1.6 tsutsui *unit = atoi(args[1]); 175 1.6 tsutsui *part = atoi(args[2]); 176 1.6 tsutsui break; 177 1.6 tsutsui case 2: 178 1.6 tsutsui *unit = atoi(args[0]); 179 1.6 tsutsui *part = atoi(args[1]); 180 1.6 tsutsui break; 181 1.6 tsutsui case 1: 182 1.6 tsutsui *part = atoi(args[0]); 183 1.6 tsutsui break; 184 1.6 tsutsui case 0: 185 1.6 tsutsui break; 186 1.6 tsutsui } 187 1.6 tsutsui *file = ++s; 188 1.1 thorpej } 189 1.1 thorpej 190 1.6 tsutsui /* second form */ 191 1.6 tsutsui else if (*s == ':') { 192 1.6 tsutsui int temp; 193 1.1 thorpej 194 1.6 tsutsui /* isolate device */ 195 1.12 mrg for (s = (char *)fname; *s != ':' && !isdigit(*s); s++) 196 1.12 mrg continue; 197 1.14 tsutsui 198 1.12 mrg /* lookup device and get index */ 199 1.12 mrg if ((*dev = devlookup(fname, s - fname)) < 0) 200 1.12 mrg goto baddev; 201 1.6 tsutsui 202 1.6 tsutsui /* isolate unit */ 203 1.6 tsutsui if ((temp = atoi(s)) > 255) 204 1.6 tsutsui goto bad; 205 1.6 tsutsui *adapt = temp / 8; 206 1.6 tsutsui *ctlr = temp % 8; 207 1.6 tsutsui for (; isdigit(*s); s++) 208 1.12 mrg continue; 209 1.14 tsutsui 210 1.6 tsutsui /* translate partition */ 211 1.6 tsutsui if (!ispart(*s)) 212 1.6 tsutsui goto bad; 213 1.14 tsutsui 214 1.6 tsutsui *part = *s++ - 'a'; 215 1.6 tsutsui if (*s != ':') 216 1.6 tsutsui goto bad; 217 1.6 tsutsui *file = ++s; 218 1.6 tsutsui } 219 1.6 tsutsui 220 1.6 tsutsui /* no device present */ 221 1.6 tsutsui else 222 1.6 tsutsui *file = (char *)fname; 223 1.14 tsutsui 224 1.6 tsutsui /* return the remaining unparsed part as the file to boot */ 225 1.6 tsutsui return 0; 226 1.14 tsutsui 227 1.1 thorpej bad: 228 1.6 tsutsui usage(); 229 1.1 thorpej 230 1.1 thorpej baddev: 231 1.6 tsutsui return -1; 232 1.14 tsutsui } 233 1.1 thorpej 234 1.1 thorpej 235 1.6 tsutsui int 236 1.7 tsutsui devopen(struct open_file *f, const char *fname, char **file) 237 1.1 thorpej { 238 1.6 tsutsui int error; 239 1.1 thorpej int dev, adapt, ctlr, unit, part; 240 1.1 thorpej struct devsw *dp = &devsw[0]; 241 1.1 thorpej 242 1.1 thorpej dev = B_TYPE(bootdev); 243 1.1 thorpej adapt = B_ADAPTOR(bootdev); 244 1.1 thorpej ctlr = B_CONTROLLER(bootdev); 245 1.1 thorpej unit = B_UNIT(bootdev); 246 1.1 thorpej part = B_PARTITION(bootdev); 247 1.1 thorpej 248 1.6 tsutsui if ((error = devparse(fname, &dev, &adapt, &ctlr, &unit, &part, file)) 249 1.6 tsutsui != 0) 250 1.6 tsutsui return error; 251 1.1 thorpej 252 1.1 thorpej /* 253 1.1 thorpej * Set up filesystem type based on what device we're opening. 254 1.1 thorpej */ 255 1.1 thorpej switch (dev) { 256 1.1 thorpej case 0: /* ct */ 257 1.13 tsutsui memcpy(file_system, file_system_rawfs, 258 1.13 tsutsui sizeof(file_system_rawfs)); 259 1.13 tsutsui nfsys = 1; 260 1.1 thorpej break; 261 1.1 thorpej 262 1.1 thorpej case 2: /* rd */ 263 1.1 thorpej case 4: /* sd */ 264 1.13 tsutsui memcpy(file_system, file_system_ufs, 265 1.13 tsutsui sizeof(file_system_ufs)); 266 1.15 tsutsui nfsys = NFSYS_FS; 267 1.14 tsutsui break; 268 1.1 thorpej 269 1.1 thorpej case 6: /* le */ 270 1.13 tsutsui memcpy(file_system, file_system_nfs, 271 1.13 tsutsui sizeof(file_system_nfs)); 272 1.13 tsutsui nfsys = 1; 273 1.1 thorpej break; 274 1.1 thorpej 275 1.1 thorpej default: 276 1.1 thorpej /* XXX what else should we do here? */ 277 1.1 thorpej printf("WARNING: BOGUS BOOT DEV TYPE 0x%x!\n", dev); 278 1.6 tsutsui return EIO; 279 1.1 thorpej } 280 1.1 thorpej 281 1.1 thorpej dp = &devsw[dev]; 282 1.14 tsutsui 283 1.1 thorpej if (!dp->dv_open) 284 1.6 tsutsui return ENODEV; 285 1.1 thorpej 286 1.1 thorpej f->f_dev = dp; 287 1.1 thorpej 288 1.1 thorpej if ((error = (*dp->dv_open)(f, adapt, ctlr, part)) == 0) { 289 1.1 thorpej if ((error = 290 1.1 thorpej (*punitsw[dev].p_punit)(adapt, ctlr, &unit)) != 0) { 291 1.1 thorpej goto bad; 292 1.1 thorpej } 293 1.1 thorpej opendev = MAKEBOOTDEV(dev, adapt, ctlr, unit, part); 294 1.6 tsutsui return 0; 295 1.1 thorpej } 296 1.1 thorpej 297 1.1 thorpej bad: 298 1.1 thorpej printf("%s(%d,%d,%d,%d): %s\n", devsw[dev].dv_name, 299 1.1 thorpej adapt, ctlr, unit, part, strerror(error)); 300 1.1 thorpej 301 1.6 tsutsui return error; 302 1.1 thorpej } 303