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